mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-11-20 06:06:13 +00:00
Changed: #1307 Added undo/redo for editor and a little syntaxhighliter
This commit is contained in:
parent
4e6544c457
commit
72b338d6f4
6 changed files with 248 additions and 30 deletions
|
@ -7,11 +7,8 @@ ADD_SUBDIRECTORY(disp_sheet_id)
|
||||||
ADD_SUBDIRECTORY(object_viewer)
|
ADD_SUBDIRECTORY(object_viewer)
|
||||||
ADD_SUBDIRECTORY(zone_painter)
|
ADD_SUBDIRECTORY(zone_painter)
|
||||||
ADD_SUBDIRECTORY(georges_editor)
|
ADD_SUBDIRECTORY(georges_editor)
|
||||||
<<<<<<< local
|
|
||||||
ADD_SUBDIRECTORY(translation_manager)
|
ADD_SUBDIRECTORY(translation_manager)
|
||||||
=======
|
|
||||||
|
|
||||||
# Ryzom Specific Plugins
|
# Ryzom Specific Plugins
|
||||||
IF(WITH_RYZOM AND WITH_RYZOM_TOOLS)
|
IF(WITH_RYZOM AND WITH_RYZOM_TOOLS)
|
||||||
ADD_SUBDIRECTORY(mission_compiler)
|
ADD_SUBDIRECTORY(mission_compiler)
|
||||||
ENDIF(WITH_RYZOM AND WITH_RYZOM_TOOLS)>>>>>>> other
|
ENDIF(WITH_RYZOM AND WITH_RYZOM_TOOLS)
|
||||||
|
|
|
@ -91,9 +91,8 @@ const char * const DATA_PATH_SECTION = "DataPath";
|
||||||
const char * const SEARCH_PATHS = "SearchPaths";
|
const char * const SEARCH_PATHS = "SearchPaths";
|
||||||
const char * const RECURSIVE_SEARCH_PATHS = "RecursiveSearchPathes";
|
const char * const RECURSIVE_SEARCH_PATHS = "RecursiveSearchPathes";
|
||||||
const char * const LEVELDESIGN_PATH = "LevelDesignPath";
|
const char * const LEVELDESIGN_PATH = "LevelDesignPath";
|
||||||
const char * const PRIMITIVES_PATH = "D:/Ryzom/ryzom/code/ryzom/common/data_leveldesign/primitives";
|
|
||||||
const char * const ASSETS_PATH = "AssetsPath";
|
|
||||||
const char * const PRIMITIVES_PATH = "PrimitivesPath";
|
const char * const PRIMITIVES_PATH = "PrimitivesPath";
|
||||||
|
const char * const ASSETS_PATH = "AssetsPath";
|
||||||
const char * const LIGOCONFIG_FILE = "LigoConfigFile";
|
const char * const LIGOCONFIG_FILE = "LigoConfigFile";
|
||||||
const char * const REMAP_EXTENSIONS = "RemapExtensions";
|
const char * const REMAP_EXTENSIONS = "RemapExtensions";
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
#include <QtCore/qfileinfo.h>
|
#include <QtCore/qfileinfo.h>
|
||||||
#include <QtGui/QMessageBox>
|
#include <QtGui/QMessageBox>
|
||||||
#include <QtGui/QCloseEvent>
|
#include <QtGui/QCloseEvent>
|
||||||
|
#include <QtCore/QByteArray>
|
||||||
|
#include <QtCore/qtextcodec.h>
|
||||||
|
#include <QtGui/QTextCursor>
|
||||||
|
|
||||||
|
|
||||||
// Project includes
|
// Project includes
|
||||||
#include "editor_phrase.h"
|
#include "editor_phrase.h"
|
||||||
|
@ -38,19 +42,24 @@ void CEditorPhrase::open(QString filename)
|
||||||
vector<STRING_MANAGER::TPhrase> phrases;
|
vector<STRING_MANAGER::TPhrase> phrases;
|
||||||
if(readPhraseFile(filename.toStdString(), phrases, false))
|
if(readPhraseFile(filename.toStdString(), phrases, false))
|
||||||
{
|
{
|
||||||
text_edit = new QTextEdit();
|
text_edit = new QTextEdit(this);
|
||||||
|
SyntaxHighlighter *highlighter = new SyntaxHighlighter(text_edit);
|
||||||
|
text_edit->setUndoRedoEnabled(true);
|
||||||
|
text_edit->document()->setUndoRedoEnabled(true);
|
||||||
|
setWidget(text_edit);
|
||||||
// read the file content
|
// read the file content
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
QTextStream in(&file);
|
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
// set the file content to the text edit
|
// set the file content to the text edit
|
||||||
QString content = in.readAll();
|
QByteArray data = file.readAll();
|
||||||
text_edit->setText(content);
|
text_edit->append(data);
|
||||||
// window settings
|
// window settings
|
||||||
setCurrentFile(filename);
|
setCurrentFile(filename);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
setWidget(text_edit);
|
|
||||||
editor_type = Constants::ED_PHRASE;
|
editor_type = Constants::ED_PHRASE;
|
||||||
current_file = filename;
|
current_file = filename;
|
||||||
|
connect(text_edit->document(), SIGNAL(contentsChange(int, int, int)), this, SLOT(contentsChangeNow(int position, int charsRemoved, int charsAdded)));
|
||||||
|
connect(text_edit->document(), SIGNAL(contentsChanged()), this, SLOT(docContentsChanged()));
|
||||||
} else {
|
} else {
|
||||||
QErrorMessage error;
|
QErrorMessage error;
|
||||||
error.showMessage("This file is not a phrase file.");
|
error.showMessage("This file is not a phrase file.");
|
||||||
|
@ -58,6 +67,19 @@ void CEditorPhrase::open(QString filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEditorPhrase::contentsChangeNow(int position, int charsRemoved, int charsAdded)
|
||||||
|
{
|
||||||
|
if(charsRemoved > 0)
|
||||||
|
current_stack->push(new CUndoPhraseRemoveCommand(position-charsRemoved, charsRemoved, text_edit));
|
||||||
|
else if(charsAdded > 0)
|
||||||
|
current_stack->push(new CUndoPhraseInsertCommand(position, text_edit->toPlainText().right(charsAdded), text_edit));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEditorPhrase::docContentsChanged()
|
||||||
|
{
|
||||||
|
setWindowModified(true);
|
||||||
|
}
|
||||||
|
|
||||||
void CEditorPhrase::activateWindow()
|
void CEditorPhrase::activateWindow()
|
||||||
{
|
{
|
||||||
showMaximized();
|
showMaximized();
|
||||||
|
@ -66,6 +88,7 @@ void CEditorPhrase::activateWindow()
|
||||||
void CEditorPhrase::save()
|
void CEditorPhrase::save()
|
||||||
{
|
{
|
||||||
QFile file(current_file);
|
QFile file(current_file);
|
||||||
|
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
QTextStream out(&file);
|
QTextStream out(&file);
|
||||||
out<<text_edit->toPlainText();
|
out<<text_edit->toPlainText();
|
||||||
setCurrentFile(current_file);
|
setCurrentFile(current_file);
|
||||||
|
@ -74,12 +97,15 @@ void CEditorPhrase::save()
|
||||||
void CEditorPhrase::saveAs(QString filename)
|
void CEditorPhrase::saveAs(QString filename)
|
||||||
{
|
{
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
|
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
QTextStream out(&file);
|
QTextStream out(&file);
|
||||||
out<<text_edit->toPlainText();
|
out<<text_edit->toPlainText();
|
||||||
current_file = filename;
|
current_file = filename;
|
||||||
setCurrentFile(current_file);
|
setCurrentFile(current_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CEditorPhrase::closeEvent(QCloseEvent *event)
|
void CEditorPhrase::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
if(isWindowModified())
|
if(isWindowModified())
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <QtGui/QUndoCommand>
|
#include <QtGui/QUndoCommand>
|
||||||
#include <QtGui/QUndoStack>
|
#include <QtGui/QUndoStack>
|
||||||
#include <QtGui/QTextEdit>
|
#include <QtGui/QTextEdit>
|
||||||
|
#include <QtGui/QSyntaxHighlighter>
|
||||||
|
|
||||||
// Project includes
|
// Project includes
|
||||||
#include "translation_manager_editor.h"
|
#include "translation_manager_editor.h"
|
||||||
|
@ -37,7 +38,7 @@ namespace Plugin {
|
||||||
class CEditorPhrase : public CEditor
|
class CEditorPhrase : public CEditor
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
public:
|
||||||
QTextEdit *text_edit;
|
QTextEdit *text_edit;
|
||||||
public:
|
public:
|
||||||
CEditorPhrase(QMdiArea* parent) : CEditor(parent) {}
|
CEditorPhrase(QMdiArea* parent) : CEditor(parent) {}
|
||||||
|
@ -47,6 +48,181 @@ public:
|
||||||
void saveAs(QString filename);
|
void saveAs(QString filename);
|
||||||
void activateWindow();
|
void activateWindow();
|
||||||
void closeEvent(QCloseEvent *event);
|
void closeEvent(QCloseEvent *event);
|
||||||
|
public Q_SLOTS:
|
||||||
|
void contentsChangeNow(int, int, int);
|
||||||
|
void docContentsChanged();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class CUndoPhraseInsertCommand : public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CUndoPhraseInsertCommand(int index, const QString &chars, QTextEdit *document, QUndoCommand *parent = 0) : QUndoCommand("Insert characters", parent),
|
||||||
|
m_index(index),
|
||||||
|
m_chars(chars),
|
||||||
|
m_document(document)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void redo()
|
||||||
|
{
|
||||||
|
QString text = m_document->toPlainText();
|
||||||
|
text.insert(m_index, m_chars);
|
||||||
|
m_document->clear();
|
||||||
|
m_document->setPlainText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void undo()
|
||||||
|
{
|
||||||
|
QString text = m_document->toPlainText();
|
||||||
|
text.remove(m_index, m_chars.length());
|
||||||
|
m_document->clear();
|
||||||
|
m_document->setPlainText(text);
|
||||||
|
m_document->undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_index;
|
||||||
|
QString m_chars;
|
||||||
|
QTextEdit* m_document;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class CUndoPhraseRemoveCommand : public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CUndoPhraseRemoveCommand(int index, int count, QTextEdit *document, QUndoCommand *parent = 0) : QUndoCommand("Remove characters", parent),
|
||||||
|
m_index(index),
|
||||||
|
m_count(count),
|
||||||
|
m_document(document)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void redo()
|
||||||
|
{
|
||||||
|
QString text = m_document->toPlainText();
|
||||||
|
m_removedChars = text.mid(m_index, m_count);
|
||||||
|
text.remove(m_index, m_count);
|
||||||
|
m_document->clear();
|
||||||
|
m_document->setPlainText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void undo()
|
||||||
|
{
|
||||||
|
QString text = m_document->toPlainText();
|
||||||
|
text.insert(m_index, m_removedChars);
|
||||||
|
m_document->clear();
|
||||||
|
m_document->setPlainText(text);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int m_index;
|
||||||
|
int m_count;
|
||||||
|
QString m_removedChars;
|
||||||
|
QTextEdit* m_document;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class SyntaxHighlighter : public QSyntaxHighlighter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SyntaxHighlighter(QTextEdit *parent) : QSyntaxHighlighter(parent)
|
||||||
|
{
|
||||||
|
HighlightingRule rule;
|
||||||
|
|
||||||
|
keywordFormat.setForeground(Qt::darkBlue);
|
||||||
|
keywordFormat.setFontWeight(QFont::Bold);
|
||||||
|
QStringList keywordPatterns;
|
||||||
|
keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b"
|
||||||
|
<< "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b"
|
||||||
|
<< "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b"
|
||||||
|
<< "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b"
|
||||||
|
<< "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b"
|
||||||
|
<< "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b"
|
||||||
|
<< "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b"
|
||||||
|
<< "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b"
|
||||||
|
<< "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b"
|
||||||
|
<< "\\bvoid\\b" << "\\bvolatile\\b";
|
||||||
|
Q_FOREACH(const QString &pattern, keywordPatterns) {
|
||||||
|
rule.pattern = QRegExp(pattern);
|
||||||
|
rule.format = keywordFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
classFormat.setFontWeight(QFont::Bold);
|
||||||
|
classFormat.setForeground(Qt::darkMagenta);
|
||||||
|
rule.pattern = QRegExp("\\bQ[A-Za-z]+\\b");
|
||||||
|
rule.format = classFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
singleLineCommentFormat.setForeground(Qt::red);
|
||||||
|
rule.pattern = QRegExp("//[^\n]*");
|
||||||
|
rule.format = singleLineCommentFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
multiLineCommentFormat.setForeground(Qt::red);
|
||||||
|
|
||||||
|
quotationFormat.setForeground(Qt::darkGreen);
|
||||||
|
rule.pattern = QRegExp("\".*\"");
|
||||||
|
rule.format = quotationFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
functionFormat.setFontItalic(true);
|
||||||
|
functionFormat.setForeground(Qt::blue);
|
||||||
|
rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");
|
||||||
|
rule.format = functionFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
commentStartExpression = QRegExp("/\\*");
|
||||||
|
commentEndExpression = QRegExp("\\*/");
|
||||||
|
}
|
||||||
|
|
||||||
|
void highlightBlock(const QString &text)
|
||||||
|
{
|
||||||
|
Q_FOREACH(const HighlightingRule &rule, highlightingRules) {
|
||||||
|
QRegExp expression(rule.pattern);
|
||||||
|
int index = expression.indexIn(text);
|
||||||
|
while (index >= 0) {
|
||||||
|
int length = expression.matchedLength();
|
||||||
|
setFormat(index, length, rule.format);
|
||||||
|
index = expression.indexIn(text, index + length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentBlockState(0);
|
||||||
|
|
||||||
|
int startIndex = 0;
|
||||||
|
if (previousBlockState() != 1)
|
||||||
|
startIndex = commentStartExpression.indexIn(text);
|
||||||
|
|
||||||
|
while (startIndex >= 0) {
|
||||||
|
int endIndex = commentEndExpression.indexIn(text, startIndex);
|
||||||
|
int commentLength;
|
||||||
|
if (endIndex == -1) {
|
||||||
|
setCurrentBlockState(1);
|
||||||
|
commentLength = text.length() - startIndex;
|
||||||
|
} else {
|
||||||
|
commentLength = endIndex - startIndex
|
||||||
|
+ commentEndExpression.matchedLength();
|
||||||
|
}
|
||||||
|
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
||||||
|
startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct HighlightingRule
|
||||||
|
{
|
||||||
|
QRegExp pattern;
|
||||||
|
QTextCharFormat format;
|
||||||
|
};
|
||||||
|
QVector<HighlightingRule> highlightingRules;
|
||||||
|
|
||||||
|
QRegExp commentStartExpression;
|
||||||
|
QRegExp commentEndExpression;
|
||||||
|
|
||||||
|
QTextCharFormat keywordFormat;
|
||||||
|
QTextCharFormat classFormat;
|
||||||
|
QTextCharFormat singleLineCommentFormat;
|
||||||
|
QTextCharFormat multiLineCommentFormat;
|
||||||
|
QTextCharFormat quotationFormat;
|
||||||
|
QTextCharFormat functionFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -592,8 +592,33 @@ bool CMainWindow::isPhraseEditor(QString filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* void CMainWindow::keyPressEvent(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
CEditorPhrase* editor = qobject_cast<CEditorPhrase*>(_ui.mdiArea->currentSubWindow());
|
||||||
|
|
||||||
|
QString chars = event->text();
|
||||||
|
int index = editor->text_edit->textCursor().position();
|
||||||
|
|
||||||
|
switch (event->key())
|
||||||
|
{
|
||||||
|
case Qt::Key_Backspace:
|
||||||
|
if (index > 0)
|
||||||
|
m_undoStack->push(new CUndoPhraseRemoveCommand(index--, 1, editor->text_edit));
|
||||||
|
break;
|
||||||
|
case Qt::Key_Delete:
|
||||||
|
if (index < editor->text_edit->toPlainText().length())
|
||||||
|
m_undoStack->push(new CUndoPhraseRemoveCommand(index, 1, editor->text_edit));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!chars.isEmpty())
|
||||||
|
m_undoStack->push(new CUndoPhraseInsertCommand(index, chars, editor->text_edit));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
bool CCoreListener::closeMainWindow() const
|
bool CCoreListener::closeMainWindow() const
|
||||||
{
|
{
|
||||||
|
bool okToClose = true;
|
||||||
Q_FOREACH(QMdiSubWindow *subWindow, m_MainWindow->_ui.mdiArea->subWindowList())
|
Q_FOREACH(QMdiSubWindow *subWindow, m_MainWindow->_ui.mdiArea->subWindowList())
|
||||||
{
|
{
|
||||||
CEditor *currentEditor = qobject_cast<CEditor*>(subWindow);
|
CEditor *currentEditor = qobject_cast<CEditor*>(subWindow);
|
||||||
|
@ -605,24 +630,18 @@ bool CCoreListener::closeMainWindow() const
|
||||||
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||||
msgBox.setDefaultButton(QMessageBox::Save);
|
msgBox.setDefaultButton(QMessageBox::Save);
|
||||||
int ret = msgBox.exec();
|
int ret = msgBox.exec();
|
||||||
switch (ret)
|
if(ret == QMessageBox::Save)
|
||||||
{
|
{
|
||||||
case QMessageBox::Save:
|
|
||||||
currentEditor->save();
|
currentEditor->save();
|
||||||
return true;
|
}
|
||||||
break;
|
else if(ret == QMessageBox::Cancel)
|
||||||
case QMessageBox::Discard:
|
{
|
||||||
return true;
|
okToClose = false;
|
||||||
break;
|
|
||||||
case QMessageBox::Cancel:
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return okToClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace Plugin */
|
} /* namespace Plugin */
|
||||||
|
|
|
@ -106,6 +106,7 @@ private:
|
||||||
bool isPhraseEditor(QString filename);
|
bool isPhraseEditor(QString filename);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CCoreListener : public Core::ICoreListener
|
class CCoreListener : public Core::ICoreListener
|
||||||
|
|
Loading…
Reference in a new issue