From 2cd15276560bf62cfb97e92840768cf55e7a943a Mon Sep 17 00:00:00 2001 From: cemycc Date: Tue, 9 Aug 2011 01:55:46 +0300 Subject: [PATCH] Changed: #1307 Added undo/redo for editor and a little syntaxhighliter --HG-- branch : gsoc2011-translationovqt --- .../src/plugins/CMakeLists.txt | 5 +- .../src/plugins/core/core_constants.h | 3 +- .../translation_manager/editor_phrase.cpp | 38 +++- .../translation_manager/editor_phrase.h | 178 +++++++++++++++++- .../translation_manager_main_window.cpp | 53 ++++-- .../translation_manager_main_window.h | 1 + 6 files changed, 248 insertions(+), 30 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt index 99df2d874..6db50dac3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt @@ -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) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h index 389b9a9fa..cfe6b7e80 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/core_constants.h @@ -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"; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.cpp index b202b1cbb..2e5a576ab 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.cpp @@ -24,6 +24,10 @@ #include #include #include +#include +#include +#include + // Project includes #include "editor_phrase.h" @@ -38,19 +42,24 @@ void CEditorPhrase::open(QString filename) vector 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<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<toPlainText(); current_file = filename; setCurrentFile(current_file); } + + void CEditorPhrase::closeEvent(QCloseEvent *event) { if(isWindowModified()) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.h index 21152ad16..c792d0b21 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/editor_phrase.h @@ -28,6 +28,7 @@ #include #include #include +#include // 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 highlightingRules; + + QRegExp commentStartExpression; + QRegExp commentEndExpression; + + QTextCharFormat keywordFormat; + QTextCharFormat classFormat; + QTextCharFormat singleLineCommentFormat; + QTextCharFormat multiLineCommentFormat; + QTextCharFormat quotationFormat; + QTextCharFormat functionFormat; }; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.cpp index 47f6f95ea..efa7743cd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.cpp @@ -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(_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(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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.h index dfc67d1f2..02146a9dd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/translation_manager/translation_manager_main_window.h @@ -104,6 +104,7 @@ private: CEditorWorksheet* getEditorByWorksheetType(const QString &type); bool isWorksheetEditor(QString filename); bool isPhraseEditor(QString filename); + };