Changed: #1307 Added undo/redo for editor and a little syntaxhighliter
This commit is contained in:
parent
3a3637dbc6
commit
7ea1c96c01
6 changed files with 248 additions and 30 deletions
code/nel/tools/3d/object_viewer_qt/src/plugins
|
@ -7,11 +7,8 @@ ADD_SUBDIRECTORY(disp_sheet_id)
|
|||
ADD_SUBDIRECTORY(object_viewer)
|
||||
ADD_SUBDIRECTORY(zone_painter)
|
||||
ADD_SUBDIRECTORY(georges_editor)
|
||||
<<<<<<< local
|
||||
ADD_SUBDIRECTORY(translation_manager)
|
||||
=======
|
||||
|
||||
# Ryzom Specific Plugins
|
||||
IF(WITH_RYZOM AND WITH_RYZOM_TOOLS)
|
||||
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 RECURSIVE_SEARCH_PATHS = "RecursiveSearchPathes";
|
||||
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 ASSETS_PATH = "AssetsPath";
|
||||
const char * const LIGOCONFIG_FILE = "LigoConfigFile";
|
||||
const char * const REMAP_EXTENSIONS = "RemapExtensions";
|
||||
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#include <QtCore/qfileinfo.h>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QCloseEvent>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/qtextcodec.h>
|
||||
#include <QtGui/QTextCursor>
|
||||
|
||||
|
||||
// Project includes
|
||||
#include "editor_phrase.h"
|
||||
|
@ -38,19 +42,24 @@ void CEditorPhrase::open(QString filename)
|
|||
vector<STRING_MANAGER::TPhrase> phrases;
|
||||
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
|
||||
QFile file(filename);
|
||||
QTextStream in(&file);
|
||||
// set the file content to the text edit
|
||||
QString content = in.readAll();
|
||||
text_edit->setText(content);
|
||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
// set the file content to the text edit
|
||||
QByteArray data = file.readAll();
|
||||
text_edit->append(data);
|
||||
// window settings
|
||||
setCurrentFile(filename);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWidget(text_edit);
|
||||
editor_type = Constants::ED_PHRASE;
|
||||
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 {
|
||||
QErrorMessage error;
|
||||
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()
|
||||
{
|
||||
showMaximized();
|
||||
|
@ -66,6 +88,7 @@ void CEditorPhrase::activateWindow()
|
|||
void CEditorPhrase::save()
|
||||
{
|
||||
QFile file(current_file);
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
out<<text_edit->toPlainText();
|
||||
setCurrentFile(current_file);
|
||||
|
@ -74,12 +97,15 @@ void CEditorPhrase::save()
|
|||
void CEditorPhrase::saveAs(QString filename)
|
||||
{
|
||||
QFile file(filename);
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
out<<text_edit->toPlainText();
|
||||
current_file = filename;
|
||||
setCurrentFile(current_file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CEditorPhrase::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if(isWindowModified())
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <QtGui/QUndoCommand>
|
||||
#include <QtGui/QUndoStack>
|
||||
#include <QtGui/QTextEdit>
|
||||
#include <QtGui/QSyntaxHighlighter>
|
||||
|
||||
// Project includes
|
||||
#include "translation_manager_editor.h"
|
||||
|
@ -37,7 +38,7 @@ namespace Plugin {
|
|||
class CEditorPhrase : public CEditor
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
public:
|
||||
QTextEdit *text_edit;
|
||||
public:
|
||||
CEditorPhrase(QMdiArea* parent) : CEditor(parent) {}
|
||||
|
@ -47,6 +48,181 @@ public:
|
|||
void saveAs(QString filename);
|
||||
void activateWindow();
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ void CMainWindow::open()
|
|||
new_window->setUndoStack(m_undoStack);
|
||||
new_window->open(file_name);
|
||||
new_window->activateWindow();
|
||||
}
|
||||
}
|
||||
// phrase editor
|
||||
if(isPhraseEditor(file_name))
|
||||
{
|
||||
|
@ -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 okToClose = true;
|
||||
Q_FOREACH(QMdiSubWindow *subWindow, m_MainWindow->_ui.mdiArea->subWindowList())
|
||||
{
|
||||
CEditor *currentEditor = qobject_cast<CEditor*>(subWindow);
|
||||
|
@ -605,24 +630,18 @@ bool CCoreListener::closeMainWindow() const
|
|||
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(QMessageBox::Save);
|
||||
int ret = msgBox.exec();
|
||||
switch (ret)
|
||||
{
|
||||
case QMessageBox::Save:
|
||||
currentEditor->save();
|
||||
return true;
|
||||
break;
|
||||
case QMessageBox::Discard:
|
||||
return true;
|
||||
break;
|
||||
case QMessageBox::Cancel:
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(ret == QMessageBox::Save)
|
||||
{
|
||||
currentEditor->save();
|
||||
}
|
||||
else if(ret == QMessageBox::Cancel)
|
||||
{
|
||||
okToClose = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return okToClose;
|
||||
}
|
||||
|
||||
} /* namespace Plugin */
|
||||
|
|
|
@ -104,6 +104,7 @@ private:
|
|||
CEditorWorksheet* getEditorByWorksheetType(const QString &type);
|
||||
bool isWorksheetEditor(QString filename);
|
||||
bool isPhraseEditor(QString filename);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue