1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Robert Bieber 2010-07-30 01:26:10 +00:00
parent 5848f5f724
commit f8dd370ff8
9 changed files with 282 additions and 10 deletions

View file

@ -34,12 +34,14 @@
****************************************************************************/ ****************************************************************************/
#include <QtGui> #include <QtGui>
#include <QApplication>
#include "codeeditor.h" #include "codeeditor.h"
//![constructor] //![constructor]
CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) CodeEditor::CodeEditor(QWidget *parent)
: QPlainTextEdit(parent), completer(this)
{ {
lineNumberArea = new LineNumberArea(this); lineNumberArea = new LineNumberArea(this);
@ -49,6 +51,11 @@ CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent)
this, SLOT(updateLineNumberArea(QRect,int))); this, SLOT(updateLineNumberArea(QRect,int)));
updateLineNumberAreaWidth(0); updateLineNumberAreaWidth(0);
QObject::connect(this, SIGNAL(cursorPositionChanged()),
this, SLOT(cursorMoved()));
completer.hide();
settings.beginGroup("CodeEditor");
} }
//![constructor] //![constructor]
@ -95,6 +102,19 @@ void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
//![slotUpdateRequest] //![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] //![resizeEvent]
void CodeEditor::resizeEvent(QResizeEvent *e) void CodeEditor::resizeEvent(QResizeEvent *e)
@ -108,6 +128,89 @@ void CodeEditor::resizeEvent(QResizeEvent *e)
//![resizeEvent] //![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] //![extraAreaPaintEvent_0]
void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)

View file

@ -38,6 +38,9 @@
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QObject> #include <QObject>
#include <QSettings>
#include "syntaxcompleter.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QPaintEvent; class QPaintEvent;
@ -68,15 +71,22 @@ public:
protected: protected:
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);
void keyPressEvent(QKeyEvent *event);
private slots: private slots:
void updateLineNumberAreaWidth(int newBlockCount); void updateLineNumberAreaWidth(int newBlockCount);
void updateLineNumberArea(const QRect &, int); void updateLineNumberArea(const QRect &, int);
void cursorMoved();
private: private:
QWidget *lineNumberArea; QWidget *lineNumberArea;
QList<int> errors; QList<int> errors;
QColor errorColor; QColor errorColor;
SyntaxCompleter completer;
QSettings settings;
int tagBegin;
int tagEnd;
}; };
//![codeeditordefinition] //![codeeditordefinition]

View file

@ -47,6 +47,12 @@ void PreferencesDialog::loadSettings()
loadColors(); loadColors();
loadFont(); loadFont();
loadRender(); loadRender();
QSettings settings;
settings.beginGroup("CodeEditor");
ui->completionBox->setChecked(settings.value("completeSyntax",
false).toBool());
settings.endGroup();
} }
void PreferencesDialog::loadColors() void PreferencesDialog::loadColors()
@ -144,6 +150,12 @@ void PreferencesDialog::saveSettings()
saveColors(); saveColors();
saveFont(); saveFont();
saveRender(); saveRender();
QSettings settings;
settings.beginGroup("CodeEditor");
settings.setValue("completeSyntax", ui->completionBox->isChecked());
settings.endGroup();
} }
void PreferencesDialog::saveColors() void PreferencesDialog::saveColors()

View file

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>370</width> <width>370</width>
<height>295</height> <height>304</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -63,6 +63,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1">
<widget class="QCheckBox" name="completionBox">
<property name="text">
<string>Enable Syntax Completion</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View file

@ -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 <QFile>
#include <QTreeWidgetItem>
#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<QString, QStringList>::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()));
}
}

View file

@ -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 <QTreeWidget>
class SyntaxCompleter : public QTreeWidget
{
Q_OBJECT
public:
SyntaxCompleter(QWidget *parent = 0);
void filter(QString text);
signals:
public slots:
private:
QMap<QString, QStringList> tags;
QStringList keys;
};
#endif // SYNTAXCOMPLETER_H

View file

@ -15,6 +15,7 @@
<file>resources/rwnd.png</file> <file>resources/rwnd.png</file>
<file>resources/cursor.png</file> <file>resources/cursor.png</file>
<file>resources/lines.png</file> <file>resources/lines.png</file>
<file alias="tagdb">resources/tagdb</file>
</qresource> </qresource>
<qresource prefix="/render"> <qresource prefix="/render">
<file alias="scenebg.png">resources/render/scenebg.png</file> <file alias="scenebg.png">resources/render/scenebg.png</file>

View file

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

View file

@ -1,11 +1,10 @@
#Setting the binary name # Setting the binary name
TARGET = rbthemeeditor TARGET = rbthemeeditor
VERSION = 0.5 VERSION = 0.5
CONFIG(debug) {
CONFIG(debug){
REVISION = $$system(svnversion) REVISION = $$system(svnversion)
VERSION=$$join(VERSION,,,r) VERSION = $$join(VERSION,,,r)
VERSION=$$join(VERSION,,,$$REVISION) VERSION = $$join(VERSION,,,$$REVISION)
} }
# Adding network support # Adding network support
@ -106,7 +105,8 @@ HEADERS += models/parsetreemodel.h \
qtfindreplacedialog/findform.h \ qtfindreplacedialog/findform.h \
qtfindreplacedialog/finddialog.h \ qtfindreplacedialog/finddialog.h \
gui/projectexporter.h \ gui/projectexporter.h \
gui/targetdownloader.h gui/targetdownloader.h \
gui/syntaxcompleter.h
SOURCES += main.cpp \ SOURCES += main.cpp \
models/parsetreemodel.cpp \ models/parsetreemodel.cpp \
models/parsetreenode.cpp \ models/parsetreenode.cpp \
@ -146,7 +146,8 @@ SOURCES += main.cpp \
qtfindreplacedialog/findform.cpp \ qtfindreplacedialog/findform.cpp \
qtfindreplacedialog/finddialog.cpp \ qtfindreplacedialog/finddialog.cpp \
gui/projectexporter.cpp \ gui/projectexporter.cpp \
gui/targetdownloader.cpp gui/targetdownloader.cpp \
gui/syntaxcompleter.cpp
OTHER_FILES += README \ OTHER_FILES += README \
resources/windowicon.png \ resources/windowicon.png \
resources/appicon.xcf \ resources/appicon.xcf \
@ -171,7 +172,8 @@ OTHER_FILES += README \
resources/targetdb \ resources/targetdb \
quazip/README.ROCKBOX \ quazip/README.ROCKBOX \
quazip/LICENSE.GPL \ quazip/LICENSE.GPL \
qtfindreplacedialog/dialogs.pro qtfindreplacedialog/dialogs.pro \
resources/tagdb
FORMS += gui/editorwindow.ui \ FORMS += gui/editorwindow.ui \
gui/preferencesdialog.ui \ gui/preferencesdialog.ui \
gui/configdocument.ui \ gui/configdocument.ui \