Changed: #1307 Added undo/redo for editor and a little syntaxhighliter

--HG--
branch : gsoc2011-translationovqt
This commit is contained in:
cemycc 2011-08-09 01:55:46 +03:00
parent b226300450
commit 2cd1527656
6 changed files with 248 additions and 30 deletions

View file

@ -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)

View file

@ -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";

View file

@ -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())

View file

@ -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;
}; };
} }

View file

@ -221,7 +221,7 @@ void CMainWindow::open()
new_window->setUndoStack(m_undoStack); new_window->setUndoStack(m_undoStack);
new_window->open(file_name); new_window->open(file_name);
new_window->activateWindow(); new_window->activateWindow();
} }
// phrase editor // phrase editor
if(isPhraseEditor(file_name)) 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 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; else if(ret == QMessageBox::Cancel)
break; {
case QMessageBox::Discard: okToClose = false;
return true; break;
break; }
case QMessageBox::Cancel:
return false;
break;
default:
break;
}
} }
} }
return okToClose;
} }
} /* namespace Plugin */ } /* namespace Plugin */

View file

@ -104,6 +104,7 @@ private:
CEditorWorksheet* getEditorByWorksheetType(const QString &type); CEditorWorksheet* getEditorByWorksheetType(const QString &type);
bool isWorksheetEditor(QString filename); bool isWorksheetEditor(QString filename);
bool isPhraseEditor(QString filename); bool isPhraseEditor(QString filename);
}; };