From f8dd370ff8ece4d32589767dc4a9b43398c1cf7e Mon Sep 17 00:00:00 2001 From: Robert Bieber Date: Fri, 30 Jul 2010 01:26:10 +0000 Subject: Theme Editor: Began implementing syntax highlighting. What I've accomplished so far isn't particularly useful for anything other than testing, so at the moment it will only function if activated in the preferences dialog git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27624 a1c6a512-1295-4272-9138-f99709370657 --- utils/themeeditor/gui/codeeditor.cpp | 105 +++++++++++++++++++++++++++- utils/themeeditor/gui/codeeditor.h | 10 +++ utils/themeeditor/gui/preferencesdialog.cpp | 12 ++++ utils/themeeditor/gui/preferencesdialog.ui | 9 ++- utils/themeeditor/gui/syntaxcompleter.cpp | 83 ++++++++++++++++++++++ utils/themeeditor/gui/syntaxcompleter.h | 44 ++++++++++++ utils/themeeditor/resources.qrc | 1 + utils/themeeditor/resources/tagdb | 10 +++ utils/themeeditor/themeeditor.pro | 18 ++--- 9 files changed, 282 insertions(+), 10 deletions(-) create mode 100644 utils/themeeditor/gui/syntaxcompleter.cpp create mode 100644 utils/themeeditor/gui/syntaxcompleter.h create mode 100644 utils/themeeditor/resources/tagdb (limited to 'utils') diff --git a/utils/themeeditor/gui/codeeditor.cpp b/utils/themeeditor/gui/codeeditor.cpp index 49f441057c..44f331d280 100644 --- a/utils/themeeditor/gui/codeeditor.cpp +++ b/utils/themeeditor/gui/codeeditor.cpp @@ -34,12 +34,14 @@ ****************************************************************************/ #include +#include #include "codeeditor.h" //![constructor] -CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) +CodeEditor::CodeEditor(QWidget *parent) + : QPlainTextEdit(parent), completer(this) { lineNumberArea = new LineNumberArea(this); @@ -49,6 +51,11 @@ CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) this, SLOT(updateLineNumberArea(QRect,int))); updateLineNumberAreaWidth(0); + + QObject::connect(this, SIGNAL(cursorPositionChanged()), + this, SLOT(cursorMoved())); + completer.hide(); + settings.beginGroup("CodeEditor"); } //![constructor] @@ -95,6 +102,19 @@ void CodeEditor::updateLineNumberArea(const QRect &rect, int dy) //![slotUpdateRequest] +void CodeEditor::cursorMoved() +{ + /* Closing the completer if the cursor has moved out of its bounds */ + if(completer.isVisible()) + { + if(textCursor().position() < tagBegin + || textCursor().position() > tagEnd) + { + completer.hide(); + } + } +} + //![resizeEvent] void CodeEditor::resizeEvent(QResizeEvent *e) @@ -108,6 +128,89 @@ void CodeEditor::resizeEvent(QResizeEvent *e) //![resizeEvent] +void CodeEditor::keyPressEvent(QKeyEvent *event) +{ + + if(!settings.value("completeSyntax", false).toBool()) + { + QPlainTextEdit::keyPressEvent(event); + return; + } + + if(completer.isVisible()) + { + /* Handling the completer */ + if(event->key() == Qt::Key_Up) + { + /* Up/down arrow presses get sent right along to the completer + * to navigate through the list + */ + if(completer.currentIndex().row() > 0) + QApplication::sendEvent(&completer, event); + } + else if(event->key() == Qt::Key_Down) + { + if(completer.currentIndex().row() + < completer.topLevelItemCount() - 1) + QApplication::sendEvent(&completer, event); + } + else if(event->key() == Qt::Key_Backspace) + { + tagEnd--; + QPlainTextEdit::keyPressEvent(event); + } + else if(event->key() == Qt::Key_Escape) + { + /* Escape hides the completer */ + completer.hide(); + QPlainTextEdit::keyPressEvent(event); + } + else if(event->key() == Qt::Key_Enter) + { + /* The enter key inserts the currently selected tag */ + } + else if(event->key() == Qt::Key_Question) + { + /* The question mark doesn't filter the list */ + tagEnd++; + QPlainTextEdit::keyPressEvent(event); + } + else if(event->key() == Qt::Key_Left + || event->key() == Qt::Key_Right) + { + /* Left and right keys shouldn't affect tagEnd */ + QPlainTextEdit::keyPressEvent(event); + } + else + { + /* Otherwise, we have to filter the list */ + tagEnd++; + QPlainTextEdit::keyPressEvent(event); + + QString filterText = ""; + } + } + else + { + /* Deciding whether to show the completer */ + QPlainTextEdit::keyPressEvent(event); + if(event->key() == Qt::Key_Percent) + { + tagBegin = textCursor().position(); + tagEnd = textCursor().position(); + completer.filter(""); + completer.move(cursorRect().left(), cursorRect().bottom()); + if(completer.frameGeometry().right() > width()) + completer.move(width() - completer.width(), completer.y()); + if(completer.frameGeometry().bottom() > height()) + completer.move(completer.x(), + cursorRect().top() - completer.height()); + completer.show(); + } + } + +} + //![extraAreaPaintEvent_0] void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) diff --git a/utils/themeeditor/gui/codeeditor.h b/utils/themeeditor/gui/codeeditor.h index 528dfb2c12..a25c5664f0 100644 --- a/utils/themeeditor/gui/codeeditor.h +++ b/utils/themeeditor/gui/codeeditor.h @@ -38,6 +38,9 @@ #include #include +#include + +#include "syntaxcompleter.h" QT_BEGIN_NAMESPACE class QPaintEvent; @@ -68,15 +71,22 @@ public: protected: void resizeEvent(QResizeEvent *event); + void keyPressEvent(QKeyEvent *event); private slots: void updateLineNumberAreaWidth(int newBlockCount); void updateLineNumberArea(const QRect &, int); + void cursorMoved(); private: QWidget *lineNumberArea; QList errors; QColor errorColor; + SyntaxCompleter completer; + QSettings settings; + + int tagBegin; + int tagEnd; }; //![codeeditordefinition] diff --git a/utils/themeeditor/gui/preferencesdialog.cpp b/utils/themeeditor/gui/preferencesdialog.cpp index 34ee8c9b22..d3aec1234d 100644 --- a/utils/themeeditor/gui/preferencesdialog.cpp +++ b/utils/themeeditor/gui/preferencesdialog.cpp @@ -47,6 +47,12 @@ void PreferencesDialog::loadSettings() loadColors(); loadFont(); loadRender(); + + QSettings settings; + settings.beginGroup("CodeEditor"); + ui->completionBox->setChecked(settings.value("completeSyntax", + false).toBool()); + settings.endGroup(); } void PreferencesDialog::loadColors() @@ -144,6 +150,12 @@ void PreferencesDialog::saveSettings() saveColors(); saveFont(); saveRender(); + + QSettings settings; + settings.beginGroup("CodeEditor"); + settings.setValue("completeSyntax", ui->completionBox->isChecked()); + settings.endGroup(); + } void PreferencesDialog::saveColors() diff --git a/utils/themeeditor/gui/preferencesdialog.ui b/utils/themeeditor/gui/preferencesdialog.ui index 384f7fced3..c57a38ce20 100644 --- a/utils/themeeditor/gui/preferencesdialog.ui +++ b/utils/themeeditor/gui/preferencesdialog.ui @@ -7,7 +7,7 @@ 0 0 370 - 295 + 304 @@ -63,6 +63,13 @@ + + + + Enable Syntax Completion + + + diff --git a/utils/themeeditor/gui/syntaxcompleter.cpp b/utils/themeeditor/gui/syntaxcompleter.cpp new file mode 100644 index 0000000000..0b4f05f487 --- /dev/null +++ b/utils/themeeditor/gui/syntaxcompleter.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include + +#include "syntaxcompleter.h" + +SyntaxCompleter::SyntaxCompleter(QWidget *parent) : + QTreeWidget(parent) +{ + setHeaderHidden(true); + + setWordWrap(true); + setColumnCount(2); + + QFile fin(":/resources/tagdb"); + fin.open(QFile::ReadOnly | QFile::Text); + + while(!fin.atEnd()) + { + QString line(fin.readLine()); + if(line.trimmed().length() == 0 || line.trimmed()[0] == '#') + continue; + + QStringList split = line.split(":"); + QStringList tag; + tag.append(split[0].trimmed()); + tag.append(split[1].trimmed()); + tags.insert(split[0].trimmed().toLower(), tag); + } + + filter(""); + + resizeColumnToContents(0); + setColumnWidth(0, columnWidth(0) + 10); // Auto-resize is too small + +} + +void SyntaxCompleter::filter(QString text) +{ + clear(); + + for(QMap::iterator i = tags.begin() + ; i != tags.end(); i++) + { + if(text.length() == 1) + { + if(text[0].toLower() != i.key()[0]) + continue; + } + else if(text.length() == 2) + { + if(text[0].toLower() != i.key()[0] || i.key().length() < 2 + || text[1].toLower() != i.key()[1]) + continue; + } + else if(text.length() > 2) + { + hide(); + } + + addTopLevelItem(new QTreeWidgetItem(i.value())); + } +} diff --git a/utils/themeeditor/gui/syntaxcompleter.h b/utils/themeeditor/gui/syntaxcompleter.h new file mode 100644 index 0000000000..f0e0794d63 --- /dev/null +++ b/utils/themeeditor/gui/syntaxcompleter.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef SYNTAXCOMPLETER_H +#define SYNTAXCOMPLETER_H + +#include + +class SyntaxCompleter : public QTreeWidget +{ +Q_OBJECT +public: + SyntaxCompleter(QWidget *parent = 0); + void filter(QString text); + +signals: + +public slots: + +private: + QMap tags; + QStringList keys; + +}; + +#endif // SYNTAXCOMPLETER_H diff --git a/utils/themeeditor/resources.qrc b/utils/themeeditor/resources.qrc index 9674595834..c00953a3c0 100644 --- a/utils/themeeditor/resources.qrc +++ b/utils/themeeditor/resources.qrc @@ -15,6 +15,7 @@ resources/rwnd.png resources/cursor.png resources/lines.png + resources/tagdb resources/render/scenebg.png diff --git a/utils/themeeditor/resources/tagdb b/utils/themeeditor/resources/tagdb new file mode 100644 index 0000000000..d6b230144e --- /dev/null +++ b/utils/themeeditor/resources/tagdb @@ -0,0 +1,10 @@ +z : Ending tag +aa : Should come at the beginning of everything +za : Should come after z +y : Should come before z +T : Test tag 1 +Ta : Test tag 2 +Tb : Test tag 3 +U : Another test +Ua : Yet another test +Uc : A sixth test diff --git a/utils/themeeditor/themeeditor.pro b/utils/themeeditor/themeeditor.pro index a58b878692..bf2be3abd8 100644 --- a/utils/themeeditor/themeeditor.pro +++ b/utils/themeeditor/themeeditor.pro @@ -1,11 +1,10 @@ -#Setting the binary name +# Setting the binary name TARGET = rbthemeeditor VERSION = 0.5 - -CONFIG(debug){ +CONFIG(debug) { REVISION = $$system(svnversion) - VERSION=$$join(VERSION,,,r) - VERSION=$$join(VERSION,,,$$REVISION) + VERSION = $$join(VERSION,,,r) + VERSION = $$join(VERSION,,,$$REVISION) } # Adding network support @@ -106,7 +105,8 @@ HEADERS += models/parsetreemodel.h \ qtfindreplacedialog/findform.h \ qtfindreplacedialog/finddialog.h \ gui/projectexporter.h \ - gui/targetdownloader.h + gui/targetdownloader.h \ + gui/syntaxcompleter.h SOURCES += main.cpp \ models/parsetreemodel.cpp \ models/parsetreenode.cpp \ @@ -146,7 +146,8 @@ SOURCES += main.cpp \ qtfindreplacedialog/findform.cpp \ qtfindreplacedialog/finddialog.cpp \ gui/projectexporter.cpp \ - gui/targetdownloader.cpp + gui/targetdownloader.cpp \ + gui/syntaxcompleter.cpp OTHER_FILES += README \ resources/windowicon.png \ resources/appicon.xcf \ @@ -171,7 +172,8 @@ OTHER_FILES += README \ resources/targetdb \ quazip/README.ROCKBOX \ quazip/LICENSE.GPL \ - qtfindreplacedialog/dialogs.pro + qtfindreplacedialog/dialogs.pro \ + resources/tagdb FORMS += gui/editorwindow.ui \ gui/preferencesdialog.ui \ gui/configdocument.ui \ -- cgit v1.2.3