From ca564287ee3f48945d45c7d92be7a83452f53745 Mon Sep 17 00:00:00 2001 From: Robert Bieber Date: Thu, 17 Jun 2010 05:37:01 +0000 Subject: Theme Editor: Moved source files into subdirectories git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26876 a1c6a512-1295-4272-9138-f99709370657 --- utils/themeeditor/codeeditor.cpp | 149 ----- utils/themeeditor/codeeditor.h | 106 ---- utils/themeeditor/configdocument.cpp | 267 -------- utils/themeeditor/configdocument.h | 86 --- utils/themeeditor/configdocument.ui | 79 --- utils/themeeditor/editorwindow.cpp | 468 -------------- utils/themeeditor/editorwindow.h | 93 --- utils/themeeditor/editorwindow.ui | 324 ---------- utils/themeeditor/gui/codeeditor.cpp | 149 +++++ utils/themeeditor/gui/codeeditor.h | 106 ++++ utils/themeeditor/gui/configdocument.cpp | 267 ++++++++ utils/themeeditor/gui/configdocument.h | 86 +++ utils/themeeditor/gui/configdocument.ui | 79 +++ utils/themeeditor/gui/editorwindow.cpp | 468 ++++++++++++++ utils/themeeditor/gui/editorwindow.h | 93 +++ utils/themeeditor/gui/editorwindow.ui | 324 ++++++++++ utils/themeeditor/gui/preferencesdialog.cpp | 206 +++++++ utils/themeeditor/gui/preferencesdialog.h | 72 +++ utils/themeeditor/gui/preferencesdialog.ui | 306 +++++++++ utils/themeeditor/gui/skindocument.cpp | 311 ++++++++++ utils/themeeditor/gui/skindocument.h | 96 +++ utils/themeeditor/gui/skinhighlighter.cpp | 172 ++++++ utils/themeeditor/gui/skinhighlighter.h | 59 ++ utils/themeeditor/gui/skinviewer.cpp | 67 ++ utils/themeeditor/gui/skinviewer.h | 51 ++ utils/themeeditor/gui/skinviewer.ui | 42 ++ utils/themeeditor/gui/tabcontent.h | 35 ++ utils/themeeditor/models/parsetreemodel.cpp | 266 ++++++++ utils/themeeditor/models/parsetreemodel.h | 68 ++ utils/themeeditor/models/parsetreenode.cpp | 474 ++++++++++++++ utils/themeeditor/models/parsetreenode.h | 69 +++ utils/themeeditor/models/projectmodel.cpp | 131 ++++ utils/themeeditor/models/projectmodel.h | 60 ++ utils/themeeditor/parser/skin_debug.c | 262 ++++++++ utils/themeeditor/parser/skin_debug.h | 48 ++ utils/themeeditor/parser/skin_parser.c | 923 ++++++++++++++++++++++++++++ utils/themeeditor/parser/skin_parser.h | 138 +++++ utils/themeeditor/parser/skin_scan.c | 218 +++++++ utils/themeeditor/parser/skin_scan.h | 44 ++ utils/themeeditor/parser/symbols.h | 49 ++ utils/themeeditor/parser/tag_table.c | 256 ++++++++ utils/themeeditor/parser/tag_table.h | 307 +++++++++ utils/themeeditor/parsetreemodel.cpp | 266 -------- utils/themeeditor/parsetreemodel.h | 68 -- utils/themeeditor/parsetreenode.cpp | 474 -------------- utils/themeeditor/parsetreenode.h | 69 --- utils/themeeditor/preferencesdialog.cpp | 206 ------- utils/themeeditor/preferencesdialog.h | 72 --- utils/themeeditor/preferencesdialog.ui | 306 --------- utils/themeeditor/projectmodel.cpp | 131 ---- utils/themeeditor/projectmodel.h | 60 -- utils/themeeditor/skin_debug.c | 262 -------- utils/themeeditor/skin_debug.h | 48 -- utils/themeeditor/skin_parser.c | 923 ---------------------------- utils/themeeditor/skin_parser.h | 138 ----- utils/themeeditor/skin_scan.c | 218 ------- utils/themeeditor/skin_scan.h | 44 -- utils/themeeditor/skindocument.cpp | 311 ---------- utils/themeeditor/skindocument.h | 96 --- utils/themeeditor/skinhighlighter.cpp | 172 ------ utils/themeeditor/skinhighlighter.h | 59 -- utils/themeeditor/skinviewer.cpp | 67 -- utils/themeeditor/skinviewer.h | 51 -- utils/themeeditor/skinviewer.ui | 42 -- utils/themeeditor/symbols.h | 49 -- utils/themeeditor/tabcontent.h | 35 -- utils/themeeditor/tag_table.c | 256 -------- utils/themeeditor/tag_table.h | 307 --------- utils/themeeditor/themeeditor.pro | 74 ++- 69 files changed, 6342 insertions(+), 6336 deletions(-) delete mode 100644 utils/themeeditor/codeeditor.cpp delete mode 100644 utils/themeeditor/codeeditor.h delete mode 100644 utils/themeeditor/configdocument.cpp delete mode 100644 utils/themeeditor/configdocument.h delete mode 100644 utils/themeeditor/configdocument.ui delete mode 100644 utils/themeeditor/editorwindow.cpp delete mode 100644 utils/themeeditor/editorwindow.h delete mode 100644 utils/themeeditor/editorwindow.ui create mode 100644 utils/themeeditor/gui/codeeditor.cpp create mode 100644 utils/themeeditor/gui/codeeditor.h create mode 100644 utils/themeeditor/gui/configdocument.cpp create mode 100644 utils/themeeditor/gui/configdocument.h create mode 100644 utils/themeeditor/gui/configdocument.ui create mode 100644 utils/themeeditor/gui/editorwindow.cpp create mode 100644 utils/themeeditor/gui/editorwindow.h create mode 100644 utils/themeeditor/gui/editorwindow.ui create mode 100644 utils/themeeditor/gui/preferencesdialog.cpp create mode 100644 utils/themeeditor/gui/preferencesdialog.h create mode 100644 utils/themeeditor/gui/preferencesdialog.ui create mode 100644 utils/themeeditor/gui/skindocument.cpp create mode 100644 utils/themeeditor/gui/skindocument.h create mode 100644 utils/themeeditor/gui/skinhighlighter.cpp create mode 100644 utils/themeeditor/gui/skinhighlighter.h create mode 100644 utils/themeeditor/gui/skinviewer.cpp create mode 100644 utils/themeeditor/gui/skinviewer.h create mode 100644 utils/themeeditor/gui/skinviewer.ui create mode 100644 utils/themeeditor/gui/tabcontent.h create mode 100644 utils/themeeditor/models/parsetreemodel.cpp create mode 100644 utils/themeeditor/models/parsetreemodel.h create mode 100644 utils/themeeditor/models/parsetreenode.cpp create mode 100644 utils/themeeditor/models/parsetreenode.h create mode 100644 utils/themeeditor/models/projectmodel.cpp create mode 100644 utils/themeeditor/models/projectmodel.h create mode 100644 utils/themeeditor/parser/skin_debug.c create mode 100644 utils/themeeditor/parser/skin_debug.h create mode 100644 utils/themeeditor/parser/skin_parser.c create mode 100644 utils/themeeditor/parser/skin_parser.h create mode 100644 utils/themeeditor/parser/skin_scan.c create mode 100644 utils/themeeditor/parser/skin_scan.h create mode 100644 utils/themeeditor/parser/symbols.h create mode 100644 utils/themeeditor/parser/tag_table.c create mode 100644 utils/themeeditor/parser/tag_table.h delete mode 100644 utils/themeeditor/parsetreemodel.cpp delete mode 100644 utils/themeeditor/parsetreemodel.h delete mode 100644 utils/themeeditor/parsetreenode.cpp delete mode 100644 utils/themeeditor/parsetreenode.h delete mode 100644 utils/themeeditor/preferencesdialog.cpp delete mode 100644 utils/themeeditor/preferencesdialog.h delete mode 100644 utils/themeeditor/preferencesdialog.ui delete mode 100644 utils/themeeditor/projectmodel.cpp delete mode 100644 utils/themeeditor/projectmodel.h delete mode 100644 utils/themeeditor/skin_debug.c delete mode 100644 utils/themeeditor/skin_debug.h delete mode 100644 utils/themeeditor/skin_parser.c delete mode 100644 utils/themeeditor/skin_parser.h delete mode 100644 utils/themeeditor/skin_scan.c delete mode 100644 utils/themeeditor/skin_scan.h delete mode 100644 utils/themeeditor/skindocument.cpp delete mode 100644 utils/themeeditor/skindocument.h delete mode 100644 utils/themeeditor/skinhighlighter.cpp delete mode 100644 utils/themeeditor/skinhighlighter.h delete mode 100644 utils/themeeditor/skinviewer.cpp delete mode 100644 utils/themeeditor/skinviewer.h delete mode 100644 utils/themeeditor/skinviewer.ui delete mode 100644 utils/themeeditor/symbols.h delete mode 100644 utils/themeeditor/tabcontent.h delete mode 100644 utils/themeeditor/tag_table.c delete mode 100644 utils/themeeditor/tag_table.h (limited to 'utils/themeeditor') diff --git a/utils/themeeditor/codeeditor.cpp b/utils/themeeditor/codeeditor.cpp deleted file mode 100644 index 49f4410..0000000 --- a/utils/themeeditor/codeeditor.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * This file has been copied from Nokia's Qt Examples, with minor modifications - * made available under the LGPL version 2.1, as the original file was licensed - * - **************************************************************************** - **************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include - -#include "codeeditor.h" - -//![constructor] - -CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) -{ - lineNumberArea = new LineNumberArea(this); - - connect(this, SIGNAL(blockCountChanged(int)), - this, SLOT(updateLineNumberAreaWidth(int))); - connect(this, SIGNAL(updateRequest(QRect,int)), - this, SLOT(updateLineNumberArea(QRect,int))); - - updateLineNumberAreaWidth(0); -} - -//![constructor] - -//![extraAreaWidth] - -int CodeEditor::lineNumberAreaWidth() -{ - int digits = 1; - int max = qMax(1, blockCount()); - while (max >= 10) { - max /= 10; - ++digits; - } - - int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits; - - return space; -} - -//![extraAreaWidth] - -//![slotUpdateExtraAreaWidth] - -void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) -{ - setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); -} - -//![slotUpdateExtraAreaWidth] - -//![slotUpdateRequest] - -void CodeEditor::updateLineNumberArea(const QRect &rect, int dy) -{ - if (dy) - lineNumberArea->scroll(0, dy); - else - lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); - - if (rect.contains(viewport()->rect())) - updateLineNumberAreaWidth(0); -} - -//![slotUpdateRequest] - -//![resizeEvent] - -void CodeEditor::resizeEvent(QResizeEvent *e) -{ - QPlainTextEdit::resizeEvent(e); - - QRect cr = contentsRect(); - lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), - lineNumberAreaWidth(), cr.height())); -} - -//![resizeEvent] - -//![extraAreaPaintEvent_0] - -void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) -{ - QPainter painter(lineNumberArea); - painter.fillRect(event->rect(), Qt::lightGray); - -//![extraAreaPaintEvent_0] - -//![extraAreaPaintEvent_1] - QTextBlock block = firstVisibleBlock(); - int blockNumber = block.blockNumber(); - int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); - int bottom = top + (int) blockBoundingRect(block).height(); -//![extraAreaPaintEvent_1] - -//![extraAreaPaintEvent_2] - while (block.isValid() && top <= event->rect().bottom()) { - if (block.isVisible() && bottom >= event->rect().top()) { - QString number = QString::number(blockNumber + 1); - /* Drawing an error circle if necessary */ - if(errors.contains(blockNumber + 1)) - { - painter.fillRect(QRect(0, top, lineNumberArea->width(), - fontMetrics().height()), errorColor); - } - painter.setPen(Qt::black); - painter.drawText(0, top, lineNumberArea->width(), - fontMetrics().height(), Qt::AlignRight, number); - } - - block = block.next(); - top = bottom; - bottom = top + (int) blockBoundingRect(block).height(); - ++blockNumber; - } -} -//![extraAreaPaintEvent_2] - diff --git a/utils/themeeditor/codeeditor.h b/utils/themeeditor/codeeditor.h deleted file mode 100644 index 1771e31..0000000 --- a/utils/themeeditor/codeeditor.h +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * This file has been copied from Nokia's Qt Examples, with minor modifications - * made available under the LGPL version 2.1, as the original file was licensed - * - **************************************************************************** - **************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CODEEDITOR_H -#define CODEEDITOR_H - -#include -#include - -QT_BEGIN_NAMESPACE -class QPaintEvent; -class QResizeEvent; -class QSize; -class QWidget; -QT_END_NAMESPACE - -class LineNumberArea; - -//![codeeditordefinition] - -class CodeEditor : public QPlainTextEdit -{ - Q_OBJECT - -public: - CodeEditor(QWidget *parent = 0); - - void lineNumberAreaPaintEvent(QPaintEvent *event); - int lineNumberAreaWidth(); - void addError(int line){ errors.append(line); } - void clearErrors(){ errors.clear(); } - void setErrorColor(QColor color){ errorColor = color; } - bool isError(int line){ return errors.contains(line); } - bool hasErrors(){ return !errors.isEmpty(); } - -protected: - void resizeEvent(QResizeEvent *event); - -private slots: - void updateLineNumberAreaWidth(int newBlockCount); - void updateLineNumberArea(const QRect &, int); - -private: - QWidget *lineNumberArea; - QList errors; - QColor errorColor; -}; - -//![codeeditordefinition] -//![extraarea] - -class LineNumberArea : public QWidget -{ -public: - LineNumberArea(CodeEditor *editor) : QWidget(editor) { - codeEditor = editor; - } - - QSize sizeHint() const { - return QSize(codeEditor->lineNumberAreaWidth(), 0); - } - -protected: - void paintEvent(QPaintEvent *event) { - codeEditor->lineNumberAreaPaintEvent(event); - } - -private: - CodeEditor *codeEditor; -}; - -//![extraarea] - -#endif diff --git a/utils/themeeditor/configdocument.cpp b/utils/themeeditor/configdocument.cpp deleted file mode 100644 index a897d3b..0000000 --- a/utils/themeeditor/configdocument.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "projectmodel.h" -#include "configdocument.h" -#include "ui_configdocument.h" - -#include -#include -#include -#include - -ConfigDocument::ConfigDocument(QMap& settings, QString file, - QWidget *parent) - : TabContent(parent), - ui(new Ui::ConfigDocument), - filePath(file) -{ - ui->setupUi(this); - - /* Populating the known keys list */ - QFile fin(":/resources/configkeys"); - fin.open(QFile::ReadOnly); - - QStringList* container = &primaryKeys; - while(!fin.atEnd()) - { - QString current = QString(fin.readLine()); - if(current == "-\n") - container = &secondaryKeys; - else if(current != "\n") - container->append(current.trimmed()); - } - - QMap::iterator i; - for(i = settings.begin(); i != settings.end(); i++) - if(i.key() != "themebase") - addRow(i.key(), i.value()); - - saved = toPlainText(); - - QObject::connect(ui->addKeyButton, SIGNAL(pressed()), - this, SLOT(addClicked())); -} - -ConfigDocument::~ConfigDocument() -{ - delete ui; -} - -void ConfigDocument::changeEvent(QEvent *e) -{ - QWidget::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - ui->retranslateUi(this); - break; - default: - break; - } -} - -QString ConfigDocument::title() const -{ - QStringList decompose = filePath.split("/"); - return decompose.last(); -} - -void ConfigDocument::save() -{ - QFile fout(filePath); - - if(!fout.exists()) - { - saveAs(); - return; - } - - fout.open(QFile::WriteOnly); - fout.write(toPlainText().toAscii()); - fout.close(); - - saved = toPlainText(); - emit titleChanged(title()); - -} - -void ConfigDocument::saveAs() -{ - /* Determining the directory to open */ - QString directory = filePath; - - QSettings settings; - settings.beginGroup("ProjectModel"); - if(directory == "") - directory = settings.value("defaultDirectory", "").toString(); - - filePath = QFileDialog::getSaveFileName(this, tr("Save Document"), - directory, - ProjectModel::fileFilter()); - directory = filePath; - if(filePath == "") - return; - - directory.chop(filePath.length() - filePath.lastIndexOf('/') - 1); - settings.setValue("defaultDirectory", directory); - settings.endGroup(); - - QFile fout(filePath); - fout.open(QFile::WriteOnly); - fout.write(toPlainText().toAscii()); - fout.close(); - - saved = toPlainText(); - emit titleChanged(title()); - emit configFileChanged(file()); - -} - -bool ConfigDocument::requestClose() -{ - if(toPlainText() != saved) - { - /* Spawning the "Are you sure?" dialog */ - QMessageBox confirm(this); - confirm.setWindowTitle(tr("Confirm Close")); - confirm.setText(title() + tr(" has been modified.")); - confirm.setInformativeText(tr("Do you want to save your changes?")); - confirm.setStandardButtons(QMessageBox::Save | QMessageBox::Discard - | QMessageBox::Cancel); - confirm.setDefaultButton(QMessageBox::Save); - int confirmation = confirm.exec(); - - switch(confirmation) - { - case QMessageBox::Save: - save(); - /* After calling save, make sure the user actually went through */ - if(toPlainText() != saved) - return false; - else - return true; - - case QMessageBox::Discard: - return true; - - case QMessageBox::Cancel: - return false; - } - } - return true; -} - -QString ConfigDocument::toPlainText() const -{ - QString buffer = ""; - - for(int i = 0; i < keys.count(); i++) - { - buffer += keys[i]->currentText(); - buffer += ":"; - buffer += values[i]->text(); - buffer += "\n"; - } - - return buffer; -} - -void ConfigDocument::addRow(QString key, QString value) -{ - QHBoxLayout* layout = new QHBoxLayout(); - QComboBox* keyEdit = new QComboBox(this); - QLineEdit* valueEdit = new QLineEdit(value, this); - QPushButton* delButton = new QPushButton(tr("-"), this); - QLabel* label = new QLabel(":"); - - /* Loading the combo box options */ - keyEdit->setInsertPolicy(QComboBox::InsertAlphabetically); - keyEdit->setEditable(true); - keyEdit->addItems(primaryKeys); - keyEdit->insertSeparator(keyEdit->count()); - keyEdit->addItems(secondaryKeys); - if(keyEdit->findText(key) != -1) - keyEdit->setCurrentIndex(keyEdit->findText(key)); - else - keyEdit->setEditText(key); - - layout->addWidget(keyEdit); - layout->addWidget(label); - layout->addWidget(valueEdit); - layout->addWidget(delButton); - - delButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - delButton->setMaximumWidth(35); - - QObject::connect(delButton, SIGNAL(clicked()), - this, SLOT(deleteClicked())); - QObject::connect(keyEdit, SIGNAL(currentIndexChanged(QString)), - this, SLOT(textChanged())); - QObject::connect(keyEdit, SIGNAL(textChanged(QString)), - this, SLOT(textChanged())); - QObject::connect(valueEdit, SIGNAL(textChanged(QString)), - this, SLOT(textChanged())); - - ui->configBoxes->addLayout(layout); - - containers.append(layout); - keys.append(keyEdit); - values.append(valueEdit); - deleteButtons.append(delButton); - labels.append(label); - -} - -void ConfigDocument::deleteClicked() -{ - QPushButton* button = dynamic_cast(sender()); - int row = deleteButtons.indexOf(button); - - deleteButtons[row]->deleteLater(); - keys[row]->deleteLater(); - values[row]->deleteLater(); - containers[row]->deleteLater(); - labels[row]->deleteLater(); - - deleteButtons.removeAt(row); - keys.removeAt(row); - values.removeAt(row); - containers.removeAt(row); - labels.removeAt(row); - - if(saved != toPlainText()) - emit titleChanged(title() + "*"); - else - emit titleChanged(title()); -} - -void ConfigDocument::addClicked() -{ - addRow(tr("Key"), tr("Value")); -} - -void ConfigDocument::textChanged() -{ - if(toPlainText() != saved) - emit titleChanged(title() + "*"); - else - emit titleChanged(title()); -} diff --git a/utils/themeeditor/configdocument.h b/utils/themeeditor/configdocument.h deleted file mode 100644 index 8493c7a..0000000 --- a/utils/themeeditor/configdocument.h +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 CONFIGDOCUMENT_H -#define CONFIGDOCUMENT_H - -#include -#include -#include -#include -#include -#include -#include - -#include "tabcontent.h" - -namespace Ui { - class ConfigDocument; -} - -class ConfigDocument : public TabContent { - Q_OBJECT -public: - ConfigDocument(QMap& settings, QString file, - QWidget *parent = 0); - virtual ~ConfigDocument(); - - TabType type() const{ return TabContent::Config; } - QString file() const{ return filePath; } - QString title() const; - - QString toPlainText() const; - - void save(); - void saveAs(); - - bool requestClose(); - -protected: - void changeEvent(QEvent *e); - -signals: - void configFileChanged(QString); - -private slots: - void deleteClicked(); - void addClicked(); - void textChanged(); - - -private: - Ui::ConfigDocument *ui; - QList containers; - QList keys; - QList values; - QList deleteButtons; - QList labels; - - QStringList primaryKeys; - QStringList secondaryKeys; - - QString filePath; - QString saved; - - void addRow(QString key, QString value); -}; - -#endif // CONFIGDOCUMENT_H diff --git a/utils/themeeditor/configdocument.ui b/utils/themeeditor/configdocument.ui deleted file mode 100644 index e2f9e7f..0000000 --- a/utils/themeeditor/configdocument.ui +++ /dev/null @@ -1,79 +0,0 @@ - - - ConfigDocument - - - - 0 - 0 - 422 - 299 - - - - Form - - - - - - true - - - - - 0 - 0 - 402 - 244 - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 35 - 16777215 - - - - + - - - - - - - - - - diff --git a/utils/themeeditor/editorwindow.cpp b/utils/themeeditor/editorwindow.cpp deleted file mode 100644 index 675520d..0000000 --- a/utils/themeeditor/editorwindow.cpp +++ /dev/null @@ -1,468 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "editorwindow.h" -#include "projectmodel.h" -#include "ui_editorwindow.h" - -#include -#include -#include -#include -#include - -EditorWindow::EditorWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::EditorWindow) -{ - ui->setupUi(this); - prefs = new PreferencesDialog(this); - project = 0; - loadSettings(); - setupUI(); - setupMenus(); -} - -void EditorWindow::loadTabFromSkinFile(QString fileName) -{ - /* Checking to see if the file is already open */ - for(int i = 0; i < ui->editorTabs->count(); i++) - { - TabContent* current = dynamic_cast - (ui->editorTabs->widget(i)); - if(current->file() == fileName) - { - ui->editorTabs->setCurrentIndex(i); - return; - } - } - - /* Adding a new document*/ - SkinDocument* doc = new SkinDocument(parseStatus, fileName); - addTab(doc); - ui->editorTabs->setCurrentWidget(doc); - -} - -void EditorWindow::loadConfigTab(ConfigDocument* doc) -{ - for(int i = 0; i < ui->editorTabs->count(); i++) - { - TabContent* current = dynamic_cast - (ui->editorTabs->widget(i)); - if(current->file() == doc->file()) - { - ui->editorTabs->setCurrentIndex(i); - doc->deleteLater(); - return; - } - } - - addTab(doc); - ui->editorTabs->setCurrentWidget(doc); - - QObject::connect(doc, SIGNAL(titleChanged(QString)), - this, SLOT(tabTitleChanged(QString))); -} - -void EditorWindow::loadSettings() -{ - - QSettings settings; - - /* Main Window location */ - settings.beginGroup("EditorWindow"); - QSize size = settings.value("size").toSize(); - QPoint pos = settings.value("position").toPoint(); - QByteArray state = settings.value("state").toByteArray(); - settings.endGroup(); - - if(!(size.isNull() || pos.isNull() || state.isNull())) - { - resize(size); - move(pos); - restoreState(state); - } - -} - -void EditorWindow::saveSettings() -{ - - QSettings settings; - - /* Saving window and panel positions */ - settings.beginGroup("EditorWindow"); - settings.setValue("position", pos()); - settings.setValue("size", size()); - settings.setValue("state", saveState()); - settings.endGroup(); -} - -void EditorWindow::setupUI() -{ - /* Connecting the tab bar signals */ - QObject::connect(ui->editorTabs, SIGNAL(currentChanged(int)), - this, SLOT(shiftTab(int))); - QObject::connect(ui->editorTabs, SIGNAL(tabCloseRequested(int)), - this, SLOT(closeTab(int))); - - /* Connecting the code gen button */ - QObject::connect(ui->fromTree, SIGNAL(pressed()), - this, SLOT(updateCurrent())); - - /* Connecting the preferences dialog */ - QObject::connect(ui->actionPreferences, SIGNAL(triggered()), - prefs, SLOT(exec())); - - /* Setting up the parse status label */ - parseStatus = new QLabel(this); - ui->statusbar->addPermanentWidget(parseStatus); - - /* Setting the selection for parse tree highlighting initially NULL */ - parseTreeSelection = 0; - - /* Adding the skin viewer */ - viewer = new SkinViewer(this); - ui->skinPreviewLayout->addWidget(viewer); - - //TODO: Remove this test code - QGraphicsScene* test = new QGraphicsScene(); - test->addRect(0,0,50,50); - - viewer->setScene(test); -} - -void EditorWindow::setupMenus() -{ - /* Connecting panel show actions */ - QObject::connect(ui->actionFile_Panel, SIGNAL(triggered()), - this, SLOT(showPanel())); - QObject::connect(ui->actionDisplay_Panel, SIGNAL(triggered()), - this, SLOT(showPanel())); - QObject::connect(ui->actionPreview_Panel, SIGNAL(triggered()), - this, SLOT(showPanel())); - - /* Connecting the document management actions */ - QObject::connect(ui->actionNew_Document, SIGNAL(triggered()), - this, SLOT(newTab())); - QObject::connect(ui->actionToolbarNew, SIGNAL(triggered()), - this, SLOT(newTab())); - - QObject::connect(ui->actionClose_Document, SIGNAL(triggered()), - this, SLOT(closeCurrent())); - - QObject::connect(ui->actionSave_Document, SIGNAL(triggered()), - this, SLOT(saveCurrent())); - QObject::connect(ui->actionSave_Document_As, SIGNAL(triggered()), - this, SLOT(saveCurrentAs())); - QObject::connect(ui->actionToolbarSave, SIGNAL(triggered()), - this, SLOT(saveCurrent())); - - QObject::connect(ui->actionOpen_Document, SIGNAL(triggered()), - this, SLOT(openFile())); - QObject::connect(ui->actionToolbarOpen, SIGNAL(triggered()), - this, SLOT(openFile())); - - QObject::connect(ui->actionOpen_Project, SIGNAL(triggered()), - this, SLOT(openProject())); -} - -void EditorWindow::addTab(TabContent *doc) -{ - ui->editorTabs->addTab(doc, doc->title()); - - /* Connecting to title change events */ - QObject::connect(doc, SIGNAL(titleChanged(QString)), - this, SLOT(tabTitleChanged(QString))); - QObject::connect(doc, SIGNAL(lineChanged(int)), - this, SLOT(lineChanged(int))); - - /* Connecting to settings change events */ - if(doc->type() == TabContent::Skin) - dynamic_cast(doc)->connectPrefs(prefs); -} - - -void EditorWindow::newTab() -{ - SkinDocument* doc = new SkinDocument(parseStatus); - addTab(doc); - ui->editorTabs->setCurrentWidget(doc); -} - -void EditorWindow::shiftTab(int index) -{ - TabContent* widget = dynamic_cast - (ui->editorTabs->currentWidget()); - if(index < 0) - { - ui->parseTree->setModel(0); - ui->actionSave_Document->setEnabled(false); - ui->actionSave_Document_As->setEnabled(false); - ui->actionClose_Document->setEnabled(false); - ui->actionToolbarSave->setEnabled(false); - ui->fromTree->setEnabled(false); - } - else if(widget->type() == TabContent::Config) - { - ui->actionSave_Document->setEnabled(true); - ui->actionSave_Document_As->setEnabled(true); - ui->actionClose_Document->setEnabled(true); - ui->actionToolbarSave->setEnabled(true); - } - else - { - /* Syncing the tree view and the status bar */ - SkinDocument* doc = dynamic_cast(widget); - ui->parseTree->setModel(doc->getModel()); - parseStatus->setText(doc->getStatus()); - - ui->actionSave_Document->setEnabled(true); - ui->actionSave_Document_As->setEnabled(true); - ui->actionClose_Document->setEnabled(true); - ui->actionToolbarSave->setEnabled(true); - ui->fromTree->setEnabled(true); - - sizeColumns(); - - } -} - -bool EditorWindow::closeTab(int index) -{ - TabContent* widget = dynamic_cast - (ui->editorTabs->widget(index)); - if(widget->requestClose()) - { - ui->editorTabs->removeTab(index); - widget->deleteLater(); - return true; - } - - return false; -} - -void EditorWindow::closeCurrent() -{ - closeTab(ui->editorTabs->currentIndex()); -} - -void EditorWindow::saveCurrent() -{ - if(ui->editorTabs->currentIndex() >= 0) - dynamic_cast(ui->editorTabs->currentWidget())->save(); -} - -void EditorWindow::saveCurrentAs() -{ - if(ui->editorTabs->currentIndex() >= 0) - dynamic_cast(ui->editorTabs->currentWidget())->saveAs(); -} - -void EditorWindow::openFile() -{ - QStringList fileNames; - QSettings settings; - - settings.beginGroup("SkinDocument"); - QString directory = settings.value("defaultDirectory", "").toString(); - fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files"), directory, - SkinDocument::fileFilter()); - - for(int i = 0; i < fileNames.count(); i++) - { - if(!QFile::exists(fileNames[i])) - continue; - - QString current = fileNames[i]; - - loadTabFromSkinFile(current); - - /* And setting the new default directory */ - current.chop(current.length() - current.lastIndexOf('/') - 1); - settings.setValue("defaultDirectory", current); - - } - - settings.endGroup(); -} - -void EditorWindow::openProject() -{ - QString fileName; - QSettings settings; - - settings.beginGroup("ProjectModel"); - QString directory = settings.value("defaultDirectory", "").toString(); - fileName = QFileDialog::getOpenFileName(this, tr("Open Project"), directory, - ProjectModel::fileFilter()); - - if(QFile::exists(fileName)) - { - - if(project) - delete project; - - project = new ProjectModel(fileName, this); - ui->projectTree->setModel(project); - - QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)), - project, SLOT(activated(QModelIndex))); - - fileName.chop(fileName.length() - fileName.lastIndexOf('/') - 1); - settings.setValue("defaultDirectory", fileName); - - } - - settings.endGroup(); - -} - -void EditorWindow::configFileChanged(QString configFile) -{ - - QSettings settings; - - settings.beginGroup("ProjectModel"); - - if(QFile::exists(configFile)) - { - - if(project) - delete project; - - project = new ProjectModel(configFile, this); - ui->projectTree->setModel(project); - - QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)), - project, SLOT(activated(QModelIndex))); - - configFile.chop(configFile.length() - configFile.lastIndexOf('/') - 1); - settings.setValue("defaultDirectory", configFile); - - } - - settings.endGroup(); - -} - -void EditorWindow::tabTitleChanged(QString title) -{ - TabContent* sender = dynamic_cast(QObject::sender()); - ui->editorTabs->setTabText(ui->editorTabs->indexOf(sender), title); -} - -void EditorWindow::showPanel() -{ - if(sender() == ui->actionFile_Panel) - ui->projectDock->setVisible(true); - if(sender() == ui->actionPreview_Panel) - ui->skinPreviewDock->setVisible(true); - if(sender() == ui->actionDisplay_Panel) - ui->parseTreeDock->setVisible(true); -} - -void EditorWindow::closeEvent(QCloseEvent* event) -{ - - saveSettings(); - - /* Closing all the tabs */ - for(int i = 0; i < ui->editorTabs->count(); i++) - { - if(!dynamic_cast - (ui->editorTabs->widget(i))->requestClose()) - { - event->ignore(); - return; - } - } - - event->accept(); -} - -void EditorWindow::updateCurrent() -{ - if(ui->editorTabs->currentIndex() < 0) - return; - - dynamic_cast - (ui->editorTabs->currentWidget())->genCode(); -} - -void EditorWindow::lineChanged(int line) -{ - ui->parseTree->collapseAll(); - if(parseTreeSelection) - parseTreeSelection->deleteLater(); - ParseTreeModel* model = dynamic_cast - (ui->parseTree->model()); - parseTreeSelection = new QItemSelectionModel(model); - expandLine(model, QModelIndex(), line); - sizeColumns(); - ui->parseTree->setSelectionModel(parseTreeSelection); - -} - -void EditorWindow::expandLine(ParseTreeModel* model, QModelIndex parent, - int line) -{ - for(int i = 0; i < model->rowCount(parent); i++) - { - QModelIndex dataType = model->index(i, ParseTreeModel::typeColumn, - parent); - QModelIndex dataVal = model->index(i, ParseTreeModel::valueColumn, - parent); - QModelIndex data = model->index(i, ParseTreeModel::lineColumn, parent); - QModelIndex recurse = model->index(i, 0, parent); - - expandLine(model, recurse, line); - - if(model->data(data, Qt::DisplayRole) == line) - { - ui->parseTree->expand(parent); - ui->parseTree->expand(data); - ui->parseTree->scrollTo(parent, QAbstractItemView::PositionAtTop); - - parseTreeSelection->select(data, QItemSelectionModel::Select); - parseTreeSelection->select(dataType, QItemSelectionModel::Select); - parseTreeSelection->select(dataVal, QItemSelectionModel::Select); - } - - } -} - -void EditorWindow::sizeColumns() -{ - /* Setting the column widths */ - ui->parseTree->resizeColumnToContents(ParseTreeModel::lineColumn); - ui->parseTree->resizeColumnToContents(ParseTreeModel::typeColumn); - ui->parseTree->resizeColumnToContents(ParseTreeModel::valueColumn); -} - -EditorWindow::~EditorWindow() -{ - delete ui; - delete prefs; - if(project) - delete project; -} diff --git a/utils/themeeditor/editorwindow.h b/utils/themeeditor/editorwindow.h deleted file mode 100644 index 6f73735..0000000 --- a/utils/themeeditor/editorwindow.h +++ /dev/null @@ -1,93 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 EDITORWINDOW_H -#define EDITORWINDOW_H - -#include -#include -#include - -#include "parsetreemodel.h" -#include "skinhighlighter.h" -#include "skindocument.h" -#include "configdocument.h" -#include "preferencesdialog.h" -#include "skinviewer.h" - -class ProjectModel; -class TabContent; - -namespace Ui -{ - class EditorWindow; -} - -class EditorWindow : public QMainWindow -{ - Q_OBJECT -public: - EditorWindow(QWidget *parent = 0); - ~EditorWindow(); - - /* A public function so external widgets can load files */ - void loadTabFromSkinFile(QString fileName); - void loadConfigTab(ConfigDocument* doc); - -protected: - virtual void closeEvent(QCloseEvent* event); - -public slots: - void configFileChanged(QString configFile); - -private slots: - void showPanel(); - void newTab(); - void shiftTab(int index); - bool closeTab(int index); - void closeCurrent(); - void saveCurrent(); - void saveCurrentAs(); - void openFile(); - void openProject(); - void tabTitleChanged(QString title); - void updateCurrent(); /* Generates code in the current tab */ - void lineChanged(int line); /* Used for auto-expand */ - -private: - /* Setup functions */ - void loadSettings(); - void saveSettings(); - void setupUI(); - void setupMenus(); - void addTab(TabContent* doc); - void expandLine(ParseTreeModel* model, QModelIndex parent, int line); - void sizeColumns(); - - Ui::EditorWindow *ui; - PreferencesDialog* prefs; - QLabel* parseStatus; - ProjectModel* project; - QItemSelectionModel* parseTreeSelection; - SkinViewer* viewer; -}; - -#endif // EDITORWINDOW_H diff --git a/utils/themeeditor/editorwindow.ui b/utils/themeeditor/editorwindow.ui deleted file mode 100644 index 10e2c52..0000000 --- a/utils/themeeditor/editorwindow.ui +++ /dev/null @@ -1,324 +0,0 @@ - - - EditorWindow - - - - 0 - 0 - 628 - 433 - - - - Rockbox Theme Editor - - - - :/resources/resources/windowicon.png:/resources/resources/windowicon.png - - - - - - - -1 - - - true - - - true - - - - - - - - - 0 - 0 - 628 - 25 - - - - - &File - - - - - - - - - - - - - - - - - &View - - - - - - - - - - - - Skin Preview - - - 2 - - - - - - - - - - - - toolBar - - - TopToolBarArea - - - false - - - - - - - - Project - - - 1 - - - - - - - - - - - - Parse Tree - - - 2 - - - - - - - true - - - QAbstractItemView::MultiSelection - - - - - - - false - - - Update Code - - - - - - - - - &Quit - - - Ctrl+Q - - - - - false - - - false - - - Parse &Tree Panel - - - - - &Preferences - - - Ctrl+P - - - - - false - - - false - - - P&roject Panel - - - - - false - - - false - - - &Preview Panel - - - - - &New Document - - - Ctrl+N - - - - - &Open Document - - - Ctrl+O - - - - - false - - - &Save Document - - - Ctrl+S - - - - - false - - - &Close Document - - - Ctrl+W - - - - - false - - - Save Document &As - - - Ctrl+Shift+S - - - - - - :/resources/resources/document-new.png:/resources/resources/document-new.png - - - ToolbarNew - - - New - - - - - - :/resources/resources/document-open.png:/resources/resources/document-open.png - - - ToolbarOpen - - - Open - - - - - false - - - - :/resources/resources/document-save.png:/resources/resources/document-save.png - - - ToolbarSave - - - Save - - - - - Open P&roject - - - Ctrl+Shift+O - - - - - projectTree - parseTree - fromTree - editorTabs - - - - - - - actionQuit - activated() - EditorWindow - close() - - - -1 - -1 - - - 299 - 199 - - - - - diff --git a/utils/themeeditor/gui/codeeditor.cpp b/utils/themeeditor/gui/codeeditor.cpp new file mode 100644 index 0000000..49f4410 --- /dev/null +++ b/utils/themeeditor/gui/codeeditor.cpp @@ -0,0 +1,149 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * This file has been copied from Nokia's Qt Examples, with minor modifications + * made available under the LGPL version 2.1, as the original file was licensed + * + **************************************************************************** + **************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include + +#include "codeeditor.h" + +//![constructor] + +CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) +{ + lineNumberArea = new LineNumberArea(this); + + connect(this, SIGNAL(blockCountChanged(int)), + this, SLOT(updateLineNumberAreaWidth(int))); + connect(this, SIGNAL(updateRequest(QRect,int)), + this, SLOT(updateLineNumberArea(QRect,int))); + + updateLineNumberAreaWidth(0); +} + +//![constructor] + +//![extraAreaWidth] + +int CodeEditor::lineNumberAreaWidth() +{ + int digits = 1; + int max = qMax(1, blockCount()); + while (max >= 10) { + max /= 10; + ++digits; + } + + int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits; + + return space; +} + +//![extraAreaWidth] + +//![slotUpdateExtraAreaWidth] + +void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) +{ + setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); +} + +//![slotUpdateExtraAreaWidth] + +//![slotUpdateRequest] + +void CodeEditor::updateLineNumberArea(const QRect &rect, int dy) +{ + if (dy) + lineNumberArea->scroll(0, dy); + else + lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + + if (rect.contains(viewport()->rect())) + updateLineNumberAreaWidth(0); +} + +//![slotUpdateRequest] + +//![resizeEvent] + +void CodeEditor::resizeEvent(QResizeEvent *e) +{ + QPlainTextEdit::resizeEvent(e); + + QRect cr = contentsRect(); + lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), + lineNumberAreaWidth(), cr.height())); +} + +//![resizeEvent] + +//![extraAreaPaintEvent_0] + +void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) +{ + QPainter painter(lineNumberArea); + painter.fillRect(event->rect(), Qt::lightGray); + +//![extraAreaPaintEvent_0] + +//![extraAreaPaintEvent_1] + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + (int) blockBoundingRect(block).height(); +//![extraAreaPaintEvent_1] + +//![extraAreaPaintEvent_2] + while (block.isValid() && top <= event->rect().bottom()) { + if (block.isVisible() && bottom >= event->rect().top()) { + QString number = QString::number(blockNumber + 1); + /* Drawing an error circle if necessary */ + if(errors.contains(blockNumber + 1)) + { + painter.fillRect(QRect(0, top, lineNumberArea->width(), + fontMetrics().height()), errorColor); + } + painter.setPen(Qt::black); + painter.drawText(0, top, lineNumberArea->width(), + fontMetrics().height(), Qt::AlignRight, number); + } + + block = block.next(); + top = bottom; + bottom = top + (int) blockBoundingRect(block).height(); + ++blockNumber; + } +} +//![extraAreaPaintEvent_2] + diff --git a/utils/themeeditor/gui/codeeditor.h b/utils/themeeditor/gui/codeeditor.h new file mode 100644 index 0000000..1771e31 --- /dev/null +++ b/utils/themeeditor/gui/codeeditor.h @@ -0,0 +1,106 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * This file has been copied from Nokia's Qt Examples, with minor modifications + * made available under the LGPL version 2.1, as the original file was licensed + * + **************************************************************************** + **************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CODEEDITOR_H +#define CODEEDITOR_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QPaintEvent; +class QResizeEvent; +class QSize; +class QWidget; +QT_END_NAMESPACE + +class LineNumberArea; + +//![codeeditordefinition] + +class CodeEditor : public QPlainTextEdit +{ + Q_OBJECT + +public: + CodeEditor(QWidget *parent = 0); + + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberAreaWidth(); + void addError(int line){ errors.append(line); } + void clearErrors(){ errors.clear(); } + void setErrorColor(QColor color){ errorColor = color; } + bool isError(int line){ return errors.contains(line); } + bool hasErrors(){ return !errors.isEmpty(); } + +protected: + void resizeEvent(QResizeEvent *event); + +private slots: + void updateLineNumberAreaWidth(int newBlockCount); + void updateLineNumberArea(const QRect &, int); + +private: + QWidget *lineNumberArea; + QList errors; + QColor errorColor; +}; + +//![codeeditordefinition] +//![extraarea] + +class LineNumberArea : public QWidget +{ +public: + LineNumberArea(CodeEditor *editor) : QWidget(editor) { + codeEditor = editor; + } + + QSize sizeHint() const { + return QSize(codeEditor->lineNumberAreaWidth(), 0); + } + +protected: + void paintEvent(QPaintEvent *event) { + codeEditor->lineNumberAreaPaintEvent(event); + } + +private: + CodeEditor *codeEditor; +}; + +//![extraarea] + +#endif diff --git a/utils/themeeditor/gui/configdocument.cpp b/utils/themeeditor/gui/configdocument.cpp new file mode 100644 index 0000000..a897d3b --- /dev/null +++ b/utils/themeeditor/gui/configdocument.cpp @@ -0,0 +1,267 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "projectmodel.h" +#include "configdocument.h" +#include "ui_configdocument.h" + +#include +#include +#include +#include + +ConfigDocument::ConfigDocument(QMap& settings, QString file, + QWidget *parent) + : TabContent(parent), + ui(new Ui::ConfigDocument), + filePath(file) +{ + ui->setupUi(this); + + /* Populating the known keys list */ + QFile fin(":/resources/configkeys"); + fin.open(QFile::ReadOnly); + + QStringList* container = &primaryKeys; + while(!fin.atEnd()) + { + QString current = QString(fin.readLine()); + if(current == "-\n") + container = &secondaryKeys; + else if(current != "\n") + container->append(current.trimmed()); + } + + QMap::iterator i; + for(i = settings.begin(); i != settings.end(); i++) + if(i.key() != "themebase") + addRow(i.key(), i.value()); + + saved = toPlainText(); + + QObject::connect(ui->addKeyButton, SIGNAL(pressed()), + this, SLOT(addClicked())); +} + +ConfigDocument::~ConfigDocument() +{ + delete ui; +} + +void ConfigDocument::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +QString ConfigDocument::title() const +{ + QStringList decompose = filePath.split("/"); + return decompose.last(); +} + +void ConfigDocument::save() +{ + QFile fout(filePath); + + if(!fout.exists()) + { + saveAs(); + return; + } + + fout.open(QFile::WriteOnly); + fout.write(toPlainText().toAscii()); + fout.close(); + + saved = toPlainText(); + emit titleChanged(title()); + +} + +void ConfigDocument::saveAs() +{ + /* Determining the directory to open */ + QString directory = filePath; + + QSettings settings; + settings.beginGroup("ProjectModel"); + if(directory == "") + directory = settings.value("defaultDirectory", "").toString(); + + filePath = QFileDialog::getSaveFileName(this, tr("Save Document"), + directory, + ProjectModel::fileFilter()); + directory = filePath; + if(filePath == "") + return; + + directory.chop(filePath.length() - filePath.lastIndexOf('/') - 1); + settings.setValue("defaultDirectory", directory); + settings.endGroup(); + + QFile fout(filePath); + fout.open(QFile::WriteOnly); + fout.write(toPlainText().toAscii()); + fout.close(); + + saved = toPlainText(); + emit titleChanged(title()); + emit configFileChanged(file()); + +} + +bool ConfigDocument::requestClose() +{ + if(toPlainText() != saved) + { + /* Spawning the "Are you sure?" dialog */ + QMessageBox confirm(this); + confirm.setWindowTitle(tr("Confirm Close")); + confirm.setText(title() + tr(" has been modified.")); + confirm.setInformativeText(tr("Do you want to save your changes?")); + confirm.setStandardButtons(QMessageBox::Save | QMessageBox::Discard + | QMessageBox::Cancel); + confirm.setDefaultButton(QMessageBox::Save); + int confirmation = confirm.exec(); + + switch(confirmation) + { + case QMessageBox::Save: + save(); + /* After calling save, make sure the user actually went through */ + if(toPlainText() != saved) + return false; + else + return true; + + case QMessageBox::Discard: + return true; + + case QMessageBox::Cancel: + return false; + } + } + return true; +} + +QString ConfigDocument::toPlainText() const +{ + QString buffer = ""; + + for(int i = 0; i < keys.count(); i++) + { + buffer += keys[i]->currentText(); + buffer += ":"; + buffer += values[i]->text(); + buffer += "\n"; + } + + return buffer; +} + +void ConfigDocument::addRow(QString key, QString value) +{ + QHBoxLayout* layout = new QHBoxLayout(); + QComboBox* keyEdit = new QComboBox(this); + QLineEdit* valueEdit = new QLineEdit(value, this); + QPushButton* delButton = new QPushButton(tr("-"), this); + QLabel* label = new QLabel(":"); + + /* Loading the combo box options */ + keyEdit->setInsertPolicy(QComboBox::InsertAlphabetically); + keyEdit->setEditable(true); + keyEdit->addItems(primaryKeys); + keyEdit->insertSeparator(keyEdit->count()); + keyEdit->addItems(secondaryKeys); + if(keyEdit->findText(key) != -1) + keyEdit->setCurrentIndex(keyEdit->findText(key)); + else + keyEdit->setEditText(key); + + layout->addWidget(keyEdit); + layout->addWidget(label); + layout->addWidget(valueEdit); + layout->addWidget(delButton); + + delButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + delButton->setMaximumWidth(35); + + QObject::connect(delButton, SIGNAL(clicked()), + this, SLOT(deleteClicked())); + QObject::connect(keyEdit, SIGNAL(currentIndexChanged(QString)), + this, SLOT(textChanged())); + QObject::connect(keyEdit, SIGNAL(textChanged(QString)), + this, SLOT(textChanged())); + QObject::connect(valueEdit, SIGNAL(textChanged(QString)), + this, SLOT(textChanged())); + + ui->configBoxes->addLayout(layout); + + containers.append(layout); + keys.append(keyEdit); + values.append(valueEdit); + deleteButtons.append(delButton); + labels.append(label); + +} + +void ConfigDocument::deleteClicked() +{ + QPushButton* button = dynamic_cast(sender()); + int row = deleteButtons.indexOf(button); + + deleteButtons[row]->deleteLater(); + keys[row]->deleteLater(); + values[row]->deleteLater(); + containers[row]->deleteLater(); + labels[row]->deleteLater(); + + deleteButtons.removeAt(row); + keys.removeAt(row); + values.removeAt(row); + containers.removeAt(row); + labels.removeAt(row); + + if(saved != toPlainText()) + emit titleChanged(title() + "*"); + else + emit titleChanged(title()); +} + +void ConfigDocument::addClicked() +{ + addRow(tr("Key"), tr("Value")); +} + +void ConfigDocument::textChanged() +{ + if(toPlainText() != saved) + emit titleChanged(title() + "*"); + else + emit titleChanged(title()); +} diff --git a/utils/themeeditor/gui/configdocument.h b/utils/themeeditor/gui/configdocument.h new file mode 100644 index 0000000..8493c7a --- /dev/null +++ b/utils/themeeditor/gui/configdocument.h @@ -0,0 +1,86 @@ +/*************************************************************************** + * __________ __ ___. + * 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 CONFIGDOCUMENT_H +#define CONFIGDOCUMENT_H + +#include +#include +#include +#include +#include +#include +#include + +#include "tabcontent.h" + +namespace Ui { + class ConfigDocument; +} + +class ConfigDocument : public TabContent { + Q_OBJECT +public: + ConfigDocument(QMap& settings, QString file, + QWidget *parent = 0); + virtual ~ConfigDocument(); + + TabType type() const{ return TabContent::Config; } + QString file() const{ return filePath; } + QString title() const; + + QString toPlainText() const; + + void save(); + void saveAs(); + + bool requestClose(); + +protected: + void changeEvent(QEvent *e); + +signals: + void configFileChanged(QString); + +private slots: + void deleteClicked(); + void addClicked(); + void textChanged(); + + +private: + Ui::ConfigDocument *ui; + QList containers; + QList keys; + QList values; + QList deleteButtons; + QList labels; + + QStringList primaryKeys; + QStringList secondaryKeys; + + QString filePath; + QString saved; + + void addRow(QString key, QString value); +}; + +#endif // CONFIGDOCUMENT_H diff --git a/utils/themeeditor/gui/configdocument.ui b/utils/themeeditor/gui/configdocument.ui new file mode 100644 index 0000000..e2f9e7f --- /dev/null +++ b/utils/themeeditor/gui/configdocument.ui @@ -0,0 +1,79 @@ + + + ConfigDocument + + + + 0 + 0 + 422 + 299 + + + + Form + + + + + + true + + + + + 0 + 0 + 402 + 244 + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 35 + 16777215 + + + + + + + + + + + + + + + diff --git a/utils/themeeditor/gui/editorwindow.cpp b/utils/themeeditor/gui/editorwindow.cpp new file mode 100644 index 0000000..675520d --- /dev/null +++ b/utils/themeeditor/gui/editorwindow.cpp @@ -0,0 +1,468 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "editorwindow.h" +#include "projectmodel.h" +#include "ui_editorwindow.h" + +#include +#include +#include +#include +#include + +EditorWindow::EditorWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::EditorWindow) +{ + ui->setupUi(this); + prefs = new PreferencesDialog(this); + project = 0; + loadSettings(); + setupUI(); + setupMenus(); +} + +void EditorWindow::loadTabFromSkinFile(QString fileName) +{ + /* Checking to see if the file is already open */ + for(int i = 0; i < ui->editorTabs->count(); i++) + { + TabContent* current = dynamic_cast + (ui->editorTabs->widget(i)); + if(current->file() == fileName) + { + ui->editorTabs->setCurrentIndex(i); + return; + } + } + + /* Adding a new document*/ + SkinDocument* doc = new SkinDocument(parseStatus, fileName); + addTab(doc); + ui->editorTabs->setCurrentWidget(doc); + +} + +void EditorWindow::loadConfigTab(ConfigDocument* doc) +{ + for(int i = 0; i < ui->editorTabs->count(); i++) + { + TabContent* current = dynamic_cast + (ui->editorTabs->widget(i)); + if(current->file() == doc->file()) + { + ui->editorTabs->setCurrentIndex(i); + doc->deleteLater(); + return; + } + } + + addTab(doc); + ui->editorTabs->setCurrentWidget(doc); + + QObject::connect(doc, SIGNAL(titleChanged(QString)), + this, SLOT(tabTitleChanged(QString))); +} + +void EditorWindow::loadSettings() +{ + + QSettings settings; + + /* Main Window location */ + settings.beginGroup("EditorWindow"); + QSize size = settings.value("size").toSize(); + QPoint pos = settings.value("position").toPoint(); + QByteArray state = settings.value("state").toByteArray(); + settings.endGroup(); + + if(!(size.isNull() || pos.isNull() || state.isNull())) + { + resize(size); + move(pos); + restoreState(state); + } + +} + +void EditorWindow::saveSettings() +{ + + QSettings settings; + + /* Saving window and panel positions */ + settings.beginGroup("EditorWindow"); + settings.setValue("position", pos()); + settings.setValue("size", size()); + settings.setValue("state", saveState()); + settings.endGroup(); +} + +void EditorWindow::setupUI() +{ + /* Connecting the tab bar signals */ + QObject::connect(ui->editorTabs, SIGNAL(currentChanged(int)), + this, SLOT(shiftTab(int))); + QObject::connect(ui->editorTabs, SIGNAL(tabCloseRequested(int)), + this, SLOT(closeTab(int))); + + /* Connecting the code gen button */ + QObject::connect(ui->fromTree, SIGNAL(pressed()), + this, SLOT(updateCurrent())); + + /* Connecting the preferences dialog */ + QObject::connect(ui->actionPreferences, SIGNAL(triggered()), + prefs, SLOT(exec())); + + /* Setting up the parse status label */ + parseStatus = new QLabel(this); + ui->statusbar->addPermanentWidget(parseStatus); + + /* Setting the selection for parse tree highlighting initially NULL */ + parseTreeSelection = 0; + + /* Adding the skin viewer */ + viewer = new SkinViewer(this); + ui->skinPreviewLayout->addWidget(viewer); + + //TODO: Remove this test code + QGraphicsScene* test = new QGraphicsScene(); + test->addRect(0,0,50,50); + + viewer->setScene(test); +} + +void EditorWindow::setupMenus() +{ + /* Connecting panel show actions */ + QObject::connect(ui->actionFile_Panel, SIGNAL(triggered()), + this, SLOT(showPanel())); + QObject::connect(ui->actionDisplay_Panel, SIGNAL(triggered()), + this, SLOT(showPanel())); + QObject::connect(ui->actionPreview_Panel, SIGNAL(triggered()), + this, SLOT(showPanel())); + + /* Connecting the document management actions */ + QObject::connect(ui->actionNew_Document, SIGNAL(triggered()), + this, SLOT(newTab())); + QObject::connect(ui->actionToolbarNew, SIGNAL(triggered()), + this, SLOT(newTab())); + + QObject::connect(ui->actionClose_Document, SIGNAL(triggered()), + this, SLOT(closeCurrent())); + + QObject::connect(ui->actionSave_Document, SIGNAL(triggered()), + this, SLOT(saveCurrent())); + QObject::connect(ui->actionSave_Document_As, SIGNAL(triggered()), + this, SLOT(saveCurrentAs())); + QObject::connect(ui->actionToolbarSave, SIGNAL(triggered()), + this, SLOT(saveCurrent())); + + QObject::connect(ui->actionOpen_Document, SIGNAL(triggered()), + this, SLOT(openFile())); + QObject::connect(ui->actionToolbarOpen, SIGNAL(triggered()), + this, SLOT(openFile())); + + QObject::connect(ui->actionOpen_Project, SIGNAL(triggered()), + this, SLOT(openProject())); +} + +void EditorWindow::addTab(TabContent *doc) +{ + ui->editorTabs->addTab(doc, doc->title()); + + /* Connecting to title change events */ + QObject::connect(doc, SIGNAL(titleChanged(QString)), + this, SLOT(tabTitleChanged(QString))); + QObject::connect(doc, SIGNAL(lineChanged(int)), + this, SLOT(lineChanged(int))); + + /* Connecting to settings change events */ + if(doc->type() == TabContent::Skin) + dynamic_cast(doc)->connectPrefs(prefs); +} + + +void EditorWindow::newTab() +{ + SkinDocument* doc = new SkinDocument(parseStatus); + addTab(doc); + ui->editorTabs->setCurrentWidget(doc); +} + +void EditorWindow::shiftTab(int index) +{ + TabContent* widget = dynamic_cast + (ui->editorTabs->currentWidget()); + if(index < 0) + { + ui->parseTree->setModel(0); + ui->actionSave_Document->setEnabled(false); + ui->actionSave_Document_As->setEnabled(false); + ui->actionClose_Document->setEnabled(false); + ui->actionToolbarSave->setEnabled(false); + ui->fromTree->setEnabled(false); + } + else if(widget->type() == TabContent::Config) + { + ui->actionSave_Document->setEnabled(true); + ui->actionSave_Document_As->setEnabled(true); + ui->actionClose_Document->setEnabled(true); + ui->actionToolbarSave->setEnabled(true); + } + else + { + /* Syncing the tree view and the status bar */ + SkinDocument* doc = dynamic_cast(widget); + ui->parseTree->setModel(doc->getModel()); + parseStatus->setText(doc->getStatus()); + + ui->actionSave_Document->setEnabled(true); + ui->actionSave_Document_As->setEnabled(true); + ui->actionClose_Document->setEnabled(true); + ui->actionToolbarSave->setEnabled(true); + ui->fromTree->setEnabled(true); + + sizeColumns(); + + } +} + +bool EditorWindow::closeTab(int index) +{ + TabContent* widget = dynamic_cast + (ui->editorTabs->widget(index)); + if(widget->requestClose()) + { + ui->editorTabs->removeTab(index); + widget->deleteLater(); + return true; + } + + return false; +} + +void EditorWindow::closeCurrent() +{ + closeTab(ui->editorTabs->currentIndex()); +} + +void EditorWindow::saveCurrent() +{ + if(ui->editorTabs->currentIndex() >= 0) + dynamic_cast(ui->editorTabs->currentWidget())->save(); +} + +void EditorWindow::saveCurrentAs() +{ + if(ui->editorTabs->currentIndex() >= 0) + dynamic_cast(ui->editorTabs->currentWidget())->saveAs(); +} + +void EditorWindow::openFile() +{ + QStringList fileNames; + QSettings settings; + + settings.beginGroup("SkinDocument"); + QString directory = settings.value("defaultDirectory", "").toString(); + fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files"), directory, + SkinDocument::fileFilter()); + + for(int i = 0; i < fileNames.count(); i++) + { + if(!QFile::exists(fileNames[i])) + continue; + + QString current = fileNames[i]; + + loadTabFromSkinFile(current); + + /* And setting the new default directory */ + current.chop(current.length() - current.lastIndexOf('/') - 1); + settings.setValue("defaultDirectory", current); + + } + + settings.endGroup(); +} + +void EditorWindow::openProject() +{ + QString fileName; + QSettings settings; + + settings.beginGroup("ProjectModel"); + QString directory = settings.value("defaultDirectory", "").toString(); + fileName = QFileDialog::getOpenFileName(this, tr("Open Project"), directory, + ProjectModel::fileFilter()); + + if(QFile::exists(fileName)) + { + + if(project) + delete project; + + project = new ProjectModel(fileName, this); + ui->projectTree->setModel(project); + + QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)), + project, SLOT(activated(QModelIndex))); + + fileName.chop(fileName.length() - fileName.lastIndexOf('/') - 1); + settings.setValue("defaultDirectory", fileName); + + } + + settings.endGroup(); + +} + +void EditorWindow::configFileChanged(QString configFile) +{ + + QSettings settings; + + settings.beginGroup("ProjectModel"); + + if(QFile::exists(configFile)) + { + + if(project) + delete project; + + project = new ProjectModel(configFile, this); + ui->projectTree->setModel(project); + + QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)), + project, SLOT(activated(QModelIndex))); + + configFile.chop(configFile.length() - configFile.lastIndexOf('/') - 1); + settings.setValue("defaultDirectory", configFile); + + } + + settings.endGroup(); + +} + +void EditorWindow::tabTitleChanged(QString title) +{ + TabContent* sender = dynamic_cast(QObject::sender()); + ui->editorTabs->setTabText(ui->editorTabs->indexOf(sender), title); +} + +void EditorWindow::showPanel() +{ + if(sender() == ui->actionFile_Panel) + ui->projectDock->setVisible(true); + if(sender() == ui->actionPreview_Panel) + ui->skinPreviewDock->setVisible(true); + if(sender() == ui->actionDisplay_Panel) + ui->parseTreeDock->setVisible(true); +} + +void EditorWindow::closeEvent(QCloseEvent* event) +{ + + saveSettings(); + + /* Closing all the tabs */ + for(int i = 0; i < ui->editorTabs->count(); i++) + { + if(!dynamic_cast + (ui->editorTabs->widget(i))->requestClose()) + { + event->ignore(); + return; + } + } + + event->accept(); +} + +void EditorWindow::updateCurrent() +{ + if(ui->editorTabs->currentIndex() < 0) + return; + + dynamic_cast + (ui->editorTabs->currentWidget())->genCode(); +} + +void EditorWindow::lineChanged(int line) +{ + ui->parseTree->collapseAll(); + if(parseTreeSelection) + parseTreeSelection->deleteLater(); + ParseTreeModel* model = dynamic_cast + (ui->parseTree->model()); + parseTreeSelection = new QItemSelectionModel(model); + expandLine(model, QModelIndex(), line); + sizeColumns(); + ui->parseTree->setSelectionModel(parseTreeSelection); + +} + +void EditorWindow::expandLine(ParseTreeModel* model, QModelIndex parent, + int line) +{ + for(int i = 0; i < model->rowCount(parent); i++) + { + QModelIndex dataType = model->index(i, ParseTreeModel::typeColumn, + parent); + QModelIndex dataVal = model->index(i, ParseTreeModel::valueColumn, + parent); + QModelIndex data = model->index(i, ParseTreeModel::lineColumn, parent); + QModelIndex recurse = model->index(i, 0, parent); + + expandLine(model, recurse, line); + + if(model->data(data, Qt::DisplayRole) == line) + { + ui->parseTree->expand(parent); + ui->parseTree->expand(data); + ui->parseTree->scrollTo(parent, QAbstractItemView::PositionAtTop); + + parseTreeSelection->select(data, QItemSelectionModel::Select); + parseTreeSelection->select(dataType, QItemSelectionModel::Select); + parseTreeSelection->select(dataVal, QItemSelectionModel::Select); + } + + } +} + +void EditorWindow::sizeColumns() +{ + /* Setting the column widths */ + ui->parseTree->resizeColumnToContents(ParseTreeModel::lineColumn); + ui->parseTree->resizeColumnToContents(ParseTreeModel::typeColumn); + ui->parseTree->resizeColumnToContents(ParseTreeModel::valueColumn); +} + +EditorWindow::~EditorWindow() +{ + delete ui; + delete prefs; + if(project) + delete project; +} diff --git a/utils/themeeditor/gui/editorwindow.h b/utils/themeeditor/gui/editorwindow.h new file mode 100644 index 0000000..6f73735 --- /dev/null +++ b/utils/themeeditor/gui/editorwindow.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * __________ __ ___. + * 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 EDITORWINDOW_H +#define EDITORWINDOW_H + +#include +#include +#include + +#include "parsetreemodel.h" +#include "skinhighlighter.h" +#include "skindocument.h" +#include "configdocument.h" +#include "preferencesdialog.h" +#include "skinviewer.h" + +class ProjectModel; +class TabContent; + +namespace Ui +{ + class EditorWindow; +} + +class EditorWindow : public QMainWindow +{ + Q_OBJECT +public: + EditorWindow(QWidget *parent = 0); + ~EditorWindow(); + + /* A public function so external widgets can load files */ + void loadTabFromSkinFile(QString fileName); + void loadConfigTab(ConfigDocument* doc); + +protected: + virtual void closeEvent(QCloseEvent* event); + +public slots: + void configFileChanged(QString configFile); + +private slots: + void showPanel(); + void newTab(); + void shiftTab(int index); + bool closeTab(int index); + void closeCurrent(); + void saveCurrent(); + void saveCurrentAs(); + void openFile(); + void openProject(); + void tabTitleChanged(QString title); + void updateCurrent(); /* Generates code in the current tab */ + void lineChanged(int line); /* Used for auto-expand */ + +private: + /* Setup functions */ + void loadSettings(); + void saveSettings(); + void setupUI(); + void setupMenus(); + void addTab(TabContent* doc); + void expandLine(ParseTreeModel* model, QModelIndex parent, int line); + void sizeColumns(); + + Ui::EditorWindow *ui; + PreferencesDialog* prefs; + QLabel* parseStatus; + ProjectModel* project; + QItemSelectionModel* parseTreeSelection; + SkinViewer* viewer; +}; + +#endif // EDITORWINDOW_H diff --git a/utils/themeeditor/gui/editorwindow.ui b/utils/themeeditor/gui/editorwindow.ui new file mode 100644 index 0000000..10e2c52 --- /dev/null +++ b/utils/themeeditor/gui/editorwindow.ui @@ -0,0 +1,324 @@ + + + EditorWindow + + + + 0 + 0 + 628 + 433 + + + + Rockbox Theme Editor + + + + :/resources/resources/windowicon.png:/resources/resources/windowicon.png + + + + + + + -1 + + + true + + + true + + + + + + + + + 0 + 0 + 628 + 25 + + + + + &File + + + + + + + + + + + + + + + + + &View + + + + + + + + + + + + Skin Preview + + + 2 + + + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + Project + + + 1 + + + + + + + + + + + + Parse Tree + + + 2 + + + + + + + true + + + QAbstractItemView::MultiSelection + + + + + + + false + + + Update Code + + + + + + + + + &Quit + + + Ctrl+Q + + + + + false + + + false + + + Parse &Tree Panel + + + + + &Preferences + + + Ctrl+P + + + + + false + + + false + + + P&roject Panel + + + + + false + + + false + + + &Preview Panel + + + + + &New Document + + + Ctrl+N + + + + + &Open Document + + + Ctrl+O + + + + + false + + + &Save Document + + + Ctrl+S + + + + + false + + + &Close Document + + + Ctrl+W + + + + + false + + + Save Document &As + + + Ctrl+Shift+S + + + + + + :/resources/resources/document-new.png:/resources/resources/document-new.png + + + ToolbarNew + + + New + + + + + + :/resources/resources/document-open.png:/resources/resources/document-open.png + + + ToolbarOpen + + + Open + + + + + false + + + + :/resources/resources/document-save.png:/resources/resources/document-save.png + + + ToolbarSave + + + Save + + + + + Open P&roject + + + Ctrl+Shift+O + + + + + projectTree + parseTree + fromTree + editorTabs + + + + + + + actionQuit + activated() + EditorWindow + close() + + + -1 + -1 + + + 299 + 199 + + + + + diff --git a/utils/themeeditor/gui/preferencesdialog.cpp b/utils/themeeditor/gui/preferencesdialog.cpp new file mode 100644 index 0000000..8cd9665 --- /dev/null +++ b/utils/themeeditor/gui/preferencesdialog.cpp @@ -0,0 +1,206 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "preferencesdialog.h" +#include "ui_preferencesdialog.h" + +#include +#include + +PreferencesDialog::PreferencesDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::PreferencesDialog) +{ + ui->setupUi(this); + setupUI(); + loadSettings(); +} + +PreferencesDialog::~PreferencesDialog() +{ + delete ui; +} + +void PreferencesDialog::loadSettings() +{ + loadColors(); + loadFont(); +} + +void PreferencesDialog::loadColors() +{ + + QSettings settings; + + /* The list of buttons from the SkinHighlighter group */ + + settings.beginGroup("SkinHighlighter"); + + commentColor = settings.value("commentColor", + QColor(0, 180, 0)).value(); + setButtonColor(ui->commentButton, commentColor); + + escapedColor = settings.value("escapedColor", + QColor(120,120,120)).value(); + setButtonColor(ui->escapedButton, escapedColor); + + conditionalColor = settings.value("conditionalColor", + QColor(0, 0, 180)).value(); + setButtonColor(ui->conditionalButton, conditionalColor); + + tagColor = settings.value("tagColor", + QColor(180, 0, 0)).value(); + setButtonColor(ui->tagButton, tagColor); + + settings.endGroup(); + + /* Buttons from the editor group */ + settings.beginGroup("SkinDocument"); + + fgColor = settings.value("fgColor", Qt::black).value(); + setButtonColor(ui->fgButton, fgColor); + + bgColor = settings.value("bgColor", Qt::white).value(); + setButtonColor(ui->bgButton, bgColor); + + errorColor = settings.value("errorColor", Qt::red).value(); + setButtonColor(ui->errorButton, errorColor); + + settings.endGroup(); +} + +void PreferencesDialog::loadFont() +{ + QSettings settings; + settings.beginGroup("SkinDocument"); + + QFont def("Monospace"); + def.setStyleHint(QFont::TypeWriter); + + QVariant family = settings.value("fontFamily", def); + int size = settings.value("fontSize", 12).toInt(); + + settings.endGroup(); + + ui->fontSelect->setCurrentFont(family.value()); + ui->fontSize->setValue(size); + +} + +void PreferencesDialog::saveSettings() +{ + saveColors(); + saveFont(); +} + +void PreferencesDialog::saveColors() +{ + QSettings settings; + + /* Saving the editor colors */ + settings.beginGroup("SkinDocument"); + + settings.setValue("fgColor", fgColor); + settings.setValue("bgColor", bgColor); + settings.setValue("errorColor", errorColor); + + settings.endGroup(); + + /* Saving the highlighting colors */ + settings.beginGroup("SkinHighlighter"); + + settings.setValue("tagColor", tagColor); + settings.setValue("commentColor", commentColor); + settings.setValue("conditionalColor", conditionalColor); + settings.setValue("escapedColor", escapedColor); + + settings.endGroup(); +} + +void PreferencesDialog::saveFont() +{ + QSettings settings; + settings.beginGroup("SkinDocument"); + + settings.setValue("fontFamily", ui->fontSelect->currentFont()); + settings.setValue("fontSize", ui->fontSize->value()); + + settings.endGroup(); +} + +void PreferencesDialog::setupUI() +{ + /* Connecting color buttons */ + QList buttons; + buttons.append(ui->bgButton); + buttons.append(ui->fgButton); + buttons.append(ui->commentButton); + buttons.append(ui->tagButton); + buttons.append(ui->conditionalButton); + buttons.append(ui->escapedButton); + buttons.append(ui->errorButton); + + for(int i = 0; i < buttons.count(); i++) + QObject::connect(buttons[i], SIGNAL(pressed()), + this, SLOT(colorClicked())); +} + +void PreferencesDialog::colorClicked() +{ + QColor* toEdit = 0, newColor; + + if(QObject::sender() == ui->bgButton) + toEdit = &bgColor; + else if(QObject::sender() == ui->fgButton) + toEdit = &fgColor; + else if(QObject::sender() == ui->commentButton) + toEdit = &commentColor; + else if(QObject::sender() == ui->tagButton) + toEdit = &tagColor; + else if(QObject::sender() == ui->conditionalButton) + toEdit = &conditionalColor; + else if(QObject::sender() == ui->escapedButton) + toEdit = &escapedColor; + else if(QObject::sender() == ui->errorButton) + toEdit = &errorColor; + + if(!toEdit) + return; + + newColor = QColorDialog::getColor(*toEdit, this); + if (newColor.isValid()) + { + *toEdit = newColor; + setButtonColor(dynamic_cast(QObject::sender()), *toEdit); + } +} + +void PreferencesDialog::accept() +{ + saveSettings(); + QDialog::accept(); +} + +void PreferencesDialog::reject() +{ + loadSettings(); + QDialog::reject(); +} diff --git a/utils/themeeditor/gui/preferencesdialog.h b/utils/themeeditor/gui/preferencesdialog.h new file mode 100644 index 0000000..e28a830 --- /dev/null +++ b/utils/themeeditor/gui/preferencesdialog.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * __________ __ ___. + * 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 PREFERENCESDIALOG_H +#define PREFERENCESDIALOG_H + +#include +#include + +namespace Ui { + class PreferencesDialog; +} + +class PreferencesDialog : public QDialog { + Q_OBJECT +public: + PreferencesDialog(QWidget *parent = 0); + ~PreferencesDialog(); + + static void setButtonColor(QPushButton* button, QColor color) + { + QString style = "* { background:" + color.name() + "}"; + button->setStyleSheet(style); + } + +public slots: + void accept(); + void reject(); + +private slots: + void colorClicked(); + +private: + Ui::PreferencesDialog *ui; + + void loadSettings(); + void loadColors(); + void loadFont(); + void saveSettings(); + void saveColors(); + void saveFont(); + + void setupUI(); + + QColor fgColor; + QColor bgColor; + QColor errorColor; + QColor commentColor; + QColor escapedColor; + QColor tagColor; + QColor conditionalColor; +}; + +#endif // PREFERENCESDIALOG_H diff --git a/utils/themeeditor/gui/preferencesdialog.ui b/utils/themeeditor/gui/preferencesdialog.ui new file mode 100644 index 0000000..1da7811 --- /dev/null +++ b/utils/themeeditor/gui/preferencesdialog.ui @@ -0,0 +1,306 @@ + + + PreferencesDialog + + + + 0 + 0 + 370 + 370 + + + + Preferences + + + + + + QTabWidget::North + + + 0 + + + + Editor + + + + + + + + Font + + + + + + + + + + + + + + Size + + + + + + + 12 + + + + + + + + + + + Foreground Colour + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + fgButton + + + + + + + false + + + Click To Change + + + + + + + + + + + Background Colour + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + bgButton + + + + + + + false + + + Click To Change + + + + + + + + + + + Error Colour + + + errorButton + + + + + + + Click To Change + + + + + + + + + + Highlighting + + + + + + + + Comment + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + commentButton + + + + + + + false + + + Click To Change + + + false + + + + + + + + + + + Escaped Character + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + escapedButton + + + + + + + false + + + Click To Change + + + + + + + + + + + Conditional + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + conditionalButton + + + + + + + false + + + Click To Change + + + + + + + + + + + Tag + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + tagButton + + + + + + + false + + + Click To Change + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + PreferencesDialog + accept() + + + 257 + 360 + + + 157 + 274 + + + + + buttonBox + rejected() + PreferencesDialog + reject() + + + 325 + 360 + + + 286 + 274 + + + + + diff --git a/utils/themeeditor/gui/skindocument.cpp b/utils/themeeditor/gui/skindocument.cpp new file mode 100644 index 0000000..82c7106 --- /dev/null +++ b/utils/themeeditor/gui/skindocument.cpp @@ -0,0 +1,311 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * This program is free software; 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 optiyouon) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "skindocument.h" + +#include +#include +#include +#include +#include + +#include + +SkinDocument::SkinDocument(QLabel* statusLabel, QWidget *parent) : + TabContent(parent), statusLabel(statusLabel) +{ + setupUI(); + + titleText = "Untitled"; + fileName = ""; + saved = ""; + parseStatus = tr("Empty document"); + blockUpdate = false; +} + +SkinDocument::SkinDocument(QLabel* statusLabel, QString file, QWidget *parent): + TabContent(parent), fileName(file), statusLabel(statusLabel) +{ + setupUI(); + blockUpdate = false; + + /* Loading the file */ + if(QFile::exists(fileName)) + { + QFile fin(fileName); + fin.open(QFile::ReadOnly); + editor->document()->setPlainText(QString(fin.readAll())); + saved = editor->document()->toPlainText(); + editor->setTextCursor(QTextCursor(editor->document()->begin())); + fin.close(); + } + + /* Setting the title */ + QStringList decomposed = fileName.split('/'); + titleText = decomposed.last(); +} + +SkinDocument::~SkinDocument() +{ + delete highlighter; + delete model; +} + +void SkinDocument::connectPrefs(PreferencesDialog* prefs) +{ + QObject::connect(prefs, SIGNAL(accepted()), + this, SLOT(settingsChanged())); + QObject::connect(prefs, SIGNAL(accepted()), + highlighter, SLOT(loadSettings())); +} + +bool SkinDocument::requestClose() +{ + /* Storing the response in blockUpdate will also block updates to the + status bar if the tab is being closed */ + if(editor->document()->toPlainText() != saved) + { + /* Spawning the "Are you sure?" dialog */ + QMessageBox confirm(this); + confirm.setWindowTitle(tr("Confirm Close")); + confirm.setText(titleText + tr(" has been modified.")); + confirm.setInformativeText(tr("Do you want to save your changes?")); + confirm.setStandardButtons(QMessageBox::Save | QMessageBox::Discard + | QMessageBox::Cancel); + confirm.setDefaultButton(QMessageBox::Save); + int confirmation = confirm.exec(); + + switch(confirmation) + { + case QMessageBox::Save: + save(); + /* After calling save, make sure the user actually went through */ + if(editor->document()->toPlainText() != saved) + blockUpdate = false; + else + blockUpdate = true; + break; + + case QMessageBox::Discard: + blockUpdate = true; + break; + + case QMessageBox::Cancel: + blockUpdate = false; + break; + } + } + else + blockUpdate = true; + + return blockUpdate; +} + +void SkinDocument::setupUI() +{ + /* Setting up the text edit */ + layout = new QHBoxLayout; + editor = new CodeEditor(this); + editor->setLineWrapMode(QPlainTextEdit::NoWrap); + layout->addWidget(editor); + + setLayout(layout); + + /* Attaching the syntax highlighter */ + highlighter = new SkinHighlighter(editor->document()); + + /* Setting up the model */ + model = new ParseTreeModel(""); + + /* Connecting the editor's signal */ + QObject::connect(editor, SIGNAL(textChanged()), + this, SLOT(codeChanged())); + QObject::connect(editor, SIGNAL(cursorPositionChanged()), + this, SLOT(cursorChanged())); + + settingsChanged(); +} + +void SkinDocument::settingsChanged() +{ + /* Setting the editor colors */ + QSettings settings; + settings.beginGroup("SkinDocument"); + + QColor fg = settings.value("fgColor", Qt::black).value(); + QColor bg = settings.value("bgColor", Qt::white).value(); + QPalette palette; + palette.setColor(QPalette::All, QPalette::Base, bg); + palette.setColor(QPalette::All, QPalette::Text, fg); + editor->setPalette(palette); + + QColor highlight = settings.value("errorColor", Qt::red).value(); + editor->setErrorColor(highlight); + + /* Setting the font */ + QFont def("Monospace"); + def.setStyleHint(QFont::TypeWriter); + QFont family = settings.value("fontFamily", def).value(); + family.setPointSize(settings.value("fontSize", 12).toInt()); + editor->setFont(family); + + editor->repaint(); + + settings.endGroup(); + +} + +void SkinDocument::cursorChanged() +{ + if(editor->isError(editor->textCursor().blockNumber() + 1)) + { + QTextCursor line = editor->textCursor(); + line.movePosition(QTextCursor::StartOfLine); + line.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + skin_parse(line.selectedText().toAscii()); + if(skin_error_line() > 0) + parseStatus = tr("Error on line ") + + QString::number(line.blockNumber() + 1) + tr(": ") + + skin_error_message(); + statusLabel->setText(parseStatus); + } + else if(editor->hasErrors()) + { + parseStatus = tr("Errors in document"); + statusLabel->setText(parseStatus); + } + else + { + emit lineChanged(editor->textCursor().blockNumber() + 1); + } + +} + +void SkinDocument::codeChanged() +{ + if(blockUpdate) + return; + + if(editor->document()->isEmpty()) + { + parseStatus = tr("Empty document"); + statusLabel->setText(parseStatus); + return; + } + + editor->clearErrors(); + parseStatus = model->changeTree(editor->document()-> + toPlainText().toAscii()); + if(skin_error_line() > 0) + parseStatus = tr("Errors in document"); + statusLabel->setText(parseStatus); + + /* Highlighting if an error was found */ + if(skin_error_line() > 0) + { + editor->addError(skin_error_line()); + + /* Now we're going to attempt parsing again at each line, until we find + one that won't error out*/ + QTextDocument doc(editor->document()->toPlainText()); + int base = 0; + while(skin_error_line() > 0 && !doc.isEmpty()) + { + QTextCursor rest(&doc); + + for(int i = 0; i < skin_error_line(); i++) + rest.movePosition(QTextCursor::NextBlock, + QTextCursor::KeepAnchor); + if(skin_error_line() == doc.blockCount()) + rest.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + + rest.removeSelectedText(); + base += skin_error_line(); + + skin_parse(doc.toPlainText().toAscii()); + + if(skin_error_line() > 0) + editor->addError(base + skin_error_line()); + + } + } + + if(editor->document()->toPlainText() != saved) + emit titleChanged(titleText + QChar('*')); + else + emit titleChanged(titleText); + + cursorChanged(); + +} + +void SkinDocument::save() +{ + QFile fout(fileName); + + if(!fout.exists()) + { + saveAs(); + return; + } + + fout.open(QFile::WriteOnly); + fout.write(editor->document()->toPlainText().toAscii()); + fout.close(); + + saved = editor->document()->toPlainText(); + QStringList decompose = fileName.split('/'); + titleText = decompose.last(); + emit titleChanged(titleText); + +} + +void SkinDocument::saveAs() +{ + /* Determining the directory to open */ + QString directory = fileName; + + QSettings settings; + settings.beginGroup("SkinDocument"); + if(directory == "") + directory = settings.value("defaultDirectory", "").toString(); + + fileName = QFileDialog::getSaveFileName(this, tr("Save Document"), + directory, fileFilter()); + directory = fileName; + if(fileName == "") + return; + + directory.chop(fileName.length() - fileName.lastIndexOf('/') - 1); + settings.setValue("defaultDirectory", directory); + settings.endGroup(); + + QFile fout(fileName); + fout.open(QFile::WriteOnly); + fout.write(editor->document()->toPlainText().toAscii()); + fout.close(); + + saved = editor->document()->toPlainText(); + QStringList decompose = fileName.split('/'); + titleText = decompose[decompose.count() - 1]; + emit titleChanged(titleText); + +} diff --git a/utils/themeeditor/gui/skindocument.h b/utils/themeeditor/gui/skindocument.h new file mode 100644 index 0000000..c6449ca --- /dev/null +++ b/utils/themeeditor/gui/skindocument.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * __________ __ ___. + * 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 SKINDOCUMENT_H +#define SKINDOCUMENT_H + +#include +#include +#include + +#include "skinhighlighter.h" +#include "parsetreemodel.h" +#include "preferencesdialog.h" +#include "codeeditor.h" +#include "tabcontent.h" + +class SkinDocument : public TabContent +{ +Q_OBJECT +public: + static QString fileFilter() + { + return tr("WPS Files (*.wps *.rwps);;" + "SBS Files (*.sbs *.rsbs);;" + "FMS Files (*.fms *.rfms);;" + "All Skin Files (*.wps *.rwps *.sbs " + "*.rsbs *.fms *.rfms);;" + "All Files (*.*)"); + } + + SkinDocument(QLabel* statusLabel, QWidget *parent = 0); + SkinDocument(QLabel* statusLabel, QString file, QWidget* parent = 0); + virtual ~SkinDocument(); + + void connectPrefs(PreferencesDialog* prefs); + + ParseTreeModel* getModel(){ return model; } + QString file() const{ return fileName; } + QString title() const{ return titleText; } + QString getStatus(){ return parseStatus; } + void genCode(){ editor->document()->setPlainText(model->genCode()); } + + void save(); + void saveAs(); + + bool requestClose(); + + TabType type() const{ return Skin; } + +signals: + +public slots: + void settingsChanged(); + void cursorChanged(); + +private slots: + void codeChanged(); + +private: + void setupUI(); + + QString titleText; + QString fileName; + QString saved; + QString parseStatus; + + QLayout* layout; + CodeEditor* editor; + + SkinHighlighter* highlighter; + ParseTreeModel* model; + + QLabel* statusLabel; + + bool blockUpdate; +}; + +#endif // SKINDOCUMENT_H diff --git a/utils/themeeditor/gui/skinhighlighter.cpp b/utils/themeeditor/gui/skinhighlighter.cpp new file mode 100644 index 0000000..25a479f --- /dev/null +++ b/utils/themeeditor/gui/skinhighlighter.cpp @@ -0,0 +1,172 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "skinhighlighter.h" + +#include + +SkinHighlighter::SkinHighlighter(QTextDocument* doc) + :QSyntaxHighlighter(doc) +{ + loadSettings(); +} + +SkinHighlighter::~SkinHighlighter() +{ + +} + +void SkinHighlighter::highlightBlock(const QString& text) +{ + for(int i = 0; i < text.length(); i++) + { + QChar c = text[i]; + + /* Checking for delimiters */ + if(c == ARGLISTOPENSYM + || c == ARGLISTCLOSESYM + || c == ARGLISTSEPERATESYM) + setFormat(i, 1, tag); + + if(c == ENUMLISTOPENSYM + || c == ENUMLISTCLOSESYM + || c == ENUMLISTSEPERATESYM) + setFormat(i, 1, conditional); + + /* Checking for comments */ + if(c == COMMENTSYM) + { + setFormat(i, text.length() - i, comment); + return; + } + + if(c == TAGSYM) + { + if(text.length() - i < 2) + return; + + if(find_escape_character(text[i + 1].toAscii())) + { + /* Checking for escaped characters */ + + setFormat(i, 2, escaped); + i++; + } + else if(text[i + 1] != CONDITIONSYM) + { + /* Checking for normal tags */ + + char lookup[3]; + struct tag_info* found = 0; + + /* First checking for a two-character tag name */ + lookup[2] = '\0'; + + if(text.length() - i >= 3) + { + lookup[0] = text[i + 1].toAscii(); + lookup[1] = text[i + 2].toAscii(); + + found = find_tag(lookup); + } + + if(found) + { + setFormat(i, 3, tag); + i += 2; + } + else + { + lookup[1] = '\0'; + lookup[0] = text[i + 1].toAscii(); + found = find_tag(lookup); + + if(found) + { + setFormat(i, 2, tag); + i++; + } + } + + } + else if(text[i + 1] == CONDITIONSYM) + { + /* Checking for conditional tags */ + + if(text.length() - i < 3) + return; + + char lookup[3]; + struct tag_info* found = 0; + + lookup[2] = '\0'; + + if(text.length() - i >= 4) + { + lookup[0] = text[i + 2].toAscii(); + lookup[1] = text[i + 3].toAscii(); + + found = find_tag(lookup); + } + + if(found) + { + setFormat(i, 4, conditional); + i += 3; + } + else + { + lookup[1] = '\0'; + lookup[0] = text[i + 2].toAscii(); + + found = find_tag(lookup); + + if(found) + { + setFormat(i, 3, conditional); + i += 2; + } + } + + } + } + } +} + +void SkinHighlighter::loadSettings() +{ + QSettings settings; + + settings.beginGroup("SkinHighlighter"); + + /* Loading the highlighting colors */ + tag = settings.value("tagColor", QColor(180,0,0)).value(); + conditional = settings.value("conditionalColor", + QColor(0, 0, 180)).value(); + escaped = settings.value("escapedColor", + QColor(120,120,120)).value(); + comment = settings.value("commentColor", + QColor(0, 180, 0)).value(); + + settings.endGroup(); + + rehighlight(); +} diff --git a/utils/themeeditor/gui/skinhighlighter.h b/utils/themeeditor/gui/skinhighlighter.h new file mode 100644 index 0000000..4d5c68b --- /dev/null +++ b/utils/themeeditor/gui/skinhighlighter.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * __________ __ ___. + * 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 SKINHIGHLIGHTER_H +#define SKINHIGHLIGHTER_H + +#include +#include + +#include "tag_table.h" +#include "symbols.h" + +class SkinHighlighter : public QSyntaxHighlighter +{ +Q_OBJECT +public: + /* + * font - The font used for all text + * normal - The normal text color + * escaped - The color for escaped characters + * tag - The color for tags and their delimiters + * conditional - The color for conditionals and their delimiters + * + */ + SkinHighlighter(QTextDocument* doc); + virtual ~SkinHighlighter(); + + void highlightBlock(const QString& text); + +public slots: + void loadSettings(); + +private: + QColor escaped; + QColor tag; + QColor conditional; + QColor comment; + +}; + +#endif // SKINHIGHLIGHTER_H diff --git a/utils/themeeditor/gui/skinviewer.cpp b/utils/themeeditor/gui/skinviewer.cpp new file mode 100644 index 0000000..152450e --- /dev/null +++ b/utils/themeeditor/gui/skinviewer.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "skinviewer.h" +#include "ui_skinviewer.h" + +SkinViewer::SkinViewer(QWidget *parent) : + QWidget(parent), + ui(new Ui::SkinViewer) +{ + ui->setupUi(this); + + QObject::connect(ui->zoomOutButton, SIGNAL(pressed()), + this, SLOT(zoomOut())); + QObject::connect(ui->zoomInButton, SIGNAL(pressed()), + this, SLOT(zoomIn())); +} + +SkinViewer::~SkinViewer() +{ + delete ui; +} + +void SkinViewer::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void SkinViewer::setScene(QGraphicsScene *scene) +{ + ui->viewer->setScene(scene); +} + +void SkinViewer::zoomIn() +{ + ui->viewer->scale(1.2, 1.2); +} + +void SkinViewer::zoomOut() +{ + ui->viewer->scale(1/1.2, 1/1.2); +} diff --git a/utils/themeeditor/gui/skinviewer.h b/utils/themeeditor/gui/skinviewer.h new file mode 100644 index 0000000..599a204 --- /dev/null +++ b/utils/themeeditor/gui/skinviewer.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * __________ __ ___. + * 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 SKINVIEWER_H +#define SKINVIEWER_H + +#include +#include + +namespace Ui { + class SkinViewer; +} + +class SkinViewer : public QWidget { + Q_OBJECT +public: + SkinViewer(QWidget *parent = 0); + ~SkinViewer(); + + void setScene(QGraphicsScene* scene); + +public slots: + void zoomIn(); + void zoomOut(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::SkinViewer *ui; +}; + +#endif // SKINVIEWER_H diff --git a/utils/themeeditor/gui/skinviewer.ui b/utils/themeeditor/gui/skinviewer.ui new file mode 100644 index 0000000..ed260d0 --- /dev/null +++ b/utils/themeeditor/gui/skinviewer.ui @@ -0,0 +1,42 @@ + + + SkinViewer + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + + + + + + Zoom In + + + + + + + Zoom Out + + + + + + + + + + diff --git a/utils/themeeditor/gui/tabcontent.h b/utils/themeeditor/gui/tabcontent.h new file mode 100644 index 0000000..1b153f7 --- /dev/null +++ b/utils/themeeditor/gui/tabcontent.h @@ -0,0 +1,35 @@ +#ifndef TABCONTENT_H +#define TABCONTENT_H + +#include + +class TabContent : public QWidget +{ +Q_OBJECT +public: + enum TabType + { + Skin, + Config + }; + + TabContent(QWidget *parent = 0): QWidget(parent){ } + + virtual TabType type() const = 0; + virtual QString title() const = 0; + virtual QString file() const = 0; + + virtual void save() = 0; + virtual void saveAs() = 0; + + virtual bool requestClose() = 0; + +signals: + void titleChanged(QString); + void lineChanged(int); + +public slots: + +}; + +#endif // TABCONTENT_H diff --git a/utils/themeeditor/models/parsetreemodel.cpp b/utils/themeeditor/models/parsetreemodel.cpp new file mode 100644 index 0000000..a709ea7 --- /dev/null +++ b/utils/themeeditor/models/parsetreemodel.cpp @@ -0,0 +1,266 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "parsetreemodel.h" +#include "symbols.h" + +#include + +#include + +ParseTreeModel::ParseTreeModel(const char* document, QObject* parent): + QAbstractItemModel(parent) +{ + this->tree = skin_parse(document); + + if(tree) + this->root = new ParseTreeNode(tree); + else + this->root = 0; +} + + +ParseTreeModel::~ParseTreeModel() +{ + if(root) + delete root; + if(tree) + skin_free_tree(tree); +} + +QString ParseTreeModel::genCode() +{ + if(root) + return root->genCode(); + else + return ""; +} + +QString ParseTreeModel::changeTree(const char *document) +{ + struct skin_element* test = skin_parse(document); + + if(!test) + { + QString error = tr("Error on line ") + + QString::number(skin_error_line()) + + tr(": ") + QString(skin_error_message()); + return error; + } + + ParseTreeNode* temp = new ParseTreeNode(test); + if(root && temp->genHash() == root->genHash()) + { + delete temp; + return tr("Document Parses Successfully"); + } + + if(root) + { + emit beginRemoveRows(QModelIndex(), 0, root->numChildren() - 1); + delete root; + emit endRemoveRows(); + } + + root = temp; + + emit beginInsertRows(QModelIndex(), 0, temp->numChildren() - 1); + emit endInsertRows(); + + return tr("Document Parses Successfully"); + +} + +QModelIndex ParseTreeModel::index(int row, int column, + const QModelIndex& parent) const +{ + if(!hasIndex(row, column, parent)) + return QModelIndex(); + + ParseTreeNode* foundParent; + + if(parent.isValid()) + foundParent = static_cast(parent.internalPointer()); + else + foundParent = root; + + if(row < foundParent->numChildren() && row >= 0) + return createIndex(row, column, foundParent->child(row)); + else + return QModelIndex(); +} + +QModelIndex ParseTreeModel::parent(const QModelIndex &child) const +{ + if(!child.isValid()) + return QModelIndex(); + + ParseTreeNode* foundParent = static_cast + (child.internalPointer())->getParent(); + + if(foundParent == root) + return QModelIndex(); + + return createIndex(foundParent->getRow(), 0, foundParent); +} + +int ParseTreeModel::rowCount(const QModelIndex &parent) const +{ + if(!root) + return 0; + + if(!parent.isValid()) + return root->numChildren(); + + if(parent.column() != typeColumn) + return 0; + + return static_cast(parent.internalPointer())->numChildren(); +} + +int ParseTreeModel::columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return numColumns; + else + return numColumns; +} + +QVariant ParseTreeModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + if(role != Qt::DisplayRole) + return QVariant(); + + return static_cast(index.internalPointer())-> + data(index.column()); +} + +QVariant ParseTreeModel::headerData(int col, Qt::Orientation orientation, + int role) const +{ + if(orientation != Qt::Horizontal) + return QVariant(); + + if(col >= numColumns) + return QVariant(); + + if(role != Qt::DisplayRole) + return QVariant(); + + switch(col) + { + case typeColumn: + return QObject::tr("Type"); + + case lineColumn: + return QObject::tr("Line"); + + case valueColumn: + return QObject::tr("Value"); + } + + return QVariant(); +} + +Qt::ItemFlags ParseTreeModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags retval = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + + ParseTreeNode* element = static_cast + (index.internalPointer()); + + if((element->isParam() + || element->getElement()->type == TEXT + || element->getElement()->type == COMMENT) + && index.column() == valueColumn) + { + retval |= Qt::ItemIsEditable; + } + + return retval; +} + +bool ParseTreeModel::setData(const QModelIndex &index, const QVariant &value, + int role) +{ + if(role != Qt::EditRole) + return false; + + if(index.column() != valueColumn) + return false; + + ParseTreeNode* node = static_cast + (index.internalPointer()); + + if(node->isParam()) + { + struct skin_tag_parameter* param = node->getParam(); + + /* Now that we've established that we do, in fact, have a parameter, + * set it to its new value if an acceptable one has been entered + */ + if(value.toString().trimmed() == QString(QChar(DEFAULTSYM))) + { + if(islower(param->type_code)) + param->type = skin_tag_parameter::DEFAULT; + else + return false; + } + else if(tolower(param->type_code) == 's' + || tolower(param->type_code) == 'f') + { + if(param->type == skin_tag_parameter::STRING) + free(param->data.text); + + param->type = skin_tag_parameter::STRING; + param->data.text = strdup(value.toString().trimmed().toAscii()); + } + else if(tolower(param->type_code) == 'i') + { + if(!value.canConvert(QVariant::Int)) + return false; + + param->type = skin_tag_parameter::NUMERIC; + param->data.numeric = value.toInt(); + } + else + { + return false; + } + } + else + { + struct skin_element* element = node->getElement(); + + if(element->type != COMMENT && element->type != TEXT) + return false; + + free(element->data); + element->data = strdup(value.toString().trimmed().toAscii()); + } + + emit dataChanged(index, index); + return true; +} diff --git a/utils/themeeditor/models/parsetreemodel.h b/utils/themeeditor/models/parsetreemodel.h new file mode 100644 index 0000000..55af549 --- /dev/null +++ b/utils/themeeditor/models/parsetreemodel.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "skin_parser.h" +#include "skin_debug.h" + +#ifndef PARSETREEMODEL_H +#define PARSETREEMODEL_H + +#include +#include + +#include "parsetreenode.h" + +class ParseTreeModel : public QAbstractItemModel +{ + + Q_OBJECT + +public: + /* Constants */ + static const int numColumns = 3; + static const int typeColumn = 0; + static const int lineColumn = 1; + static const int valueColumn = 2; + + /* Initializes a tree with a skin document in a string */ + ParseTreeModel(const char* document, QObject* parent = 0); + virtual ~ParseTreeModel(); + + QString genCode(); + /* Changes the parse tree to a new document */ + QString changeTree(const char* document); + QModelIndex index(int row, int column, const QModelIndex& parent) const; + QModelIndex parent(const QModelIndex &child) const; + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int col, Qt::Orientation orientation, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, int role); + +private: + ParseTreeNode* root; + struct skin_element* tree; +}; + + + +#endif // PARSETREEMODEL_H diff --git a/utils/themeeditor/models/parsetreenode.cpp b/utils/themeeditor/models/parsetreenode.cpp new file mode 100644 index 0000000..397031a --- /dev/null +++ b/utils/themeeditor/models/parsetreenode.cpp @@ -0,0 +1,474 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "symbols.h" +#include "tag_table.h" + +#include "parsetreenode.h" +#include "parsetreemodel.h" + +int ParseTreeNode::openConditionals = 0; + +/* Root element constructor */ +ParseTreeNode::ParseTreeNode(struct skin_element* data) + : parent(0), element(0), param(0), children() +{ + while(data) + { + children.append(new ParseTreeNode(data, this)); + data = data->next; + } +} + +/* Normal element constructor */ +ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeNode* parent) + : parent(parent), element(data), param(0), children() +{ + switch(element->type) + { + + case TAG: + for(int i = 0; i < element->params_count; i++) + { + if(element->params[i].type == skin_tag_parameter::CODE) + children.append(new ParseTreeNode(element->params[i].data.code, + this)); + else + children.append(new ParseTreeNode(&element->params[i], this)); + } + break; + + case CONDITIONAL: + for(int i = 0; i < element->params_count; i++) + children.append(new ParseTreeNode(&data->params[i], this)); + for(int i = 0; i < element->children_count; i++) + children.append(new ParseTreeNode(data->children[i], this)); + break; + + case SUBLINES: + for(int i = 0; i < element->children_count; i++) + { + children.append(new ParseTreeNode(data->children[i], this)); + } + break; + +case VIEWPORT: + for(int i = 0; i < element->params_count; i++) + children.append(new ParseTreeNode(&data->params[i], this)); + /* Deliberate fall-through here */ + + case LINE: + for(int i = 0; i < data->children_count; i++) + { + for(struct skin_element* current = data->children[i]; current; + current = current->next) + { + children.append(new ParseTreeNode(current, this)); + } + } + break; + + default: + break; + } +} + +/* Parameter constructor */ +ParseTreeNode::ParseTreeNode(skin_tag_parameter *data, ParseTreeNode *parent) + : parent(parent), element(0), param(data), children() +{ + +} + +QString ParseTreeNode::genCode() const +{ + QString buffer = ""; + + if(element) + { + switch(element->type) + { + case UNKNOWN: + break; + case VIEWPORT: + /* Generating the Viewport tag, if necessary */ + if(element->tag) + { + buffer.append(TAGSYM); + buffer.append(element->tag->name); + buffer.append(ARGLISTOPENSYM); + for(int i = 0; i < element->params_count; i++) + { + buffer.append(children[i]->genCode()); + if(i != element->params_count - 1) + buffer.append(ARGLISTSEPERATESYM); + } + buffer.append(ARGLISTCLOSESYM); + buffer.append('\n'); + } + + for(int i = element->params_count; i < children.count(); i++) + buffer.append(children[i]->genCode()); + break; + + case LINE: + for(int i = 0; i < children.count(); i++) + { + buffer.append(children[i]->genCode()); + } + if(openConditionals == 0 + && !(parent && parent->element->type == SUBLINES)) + { + buffer.append('\n'); + } + break; + + case SUBLINES: + for(int i = 0; i < children.count(); i++) + { + buffer.append(children[i]->genCode()); + if(i != children.count() - 1) + buffer.append(MULTILINESYM); + } + if(openConditionals == 0) + buffer.append('\n'); + break; + + case CONDITIONAL: + openConditionals++; + + /* Inserting the tag part */ + buffer.append(TAGSYM); + buffer.append(CONDITIONSYM); + buffer.append(element->tag->name); + if(element->params_count > 0) + { + buffer.append(ARGLISTOPENSYM); + for(int i = 0; i < element->params_count; i++) + { + buffer.append(children[i]->genCode()); + if( i != element->params_count - 1) + buffer.append(ARGLISTSEPERATESYM); + buffer.append(ARGLISTCLOSESYM); + } + } + + /* Inserting the sublines */ + buffer.append(ENUMLISTOPENSYM); + for(int i = element->params_count; i < children.count(); i++) + { + buffer.append(children[i]->genCode()); + if(i != children.count() - 1) + buffer.append(ENUMLISTSEPERATESYM); + } + buffer.append(ENUMLISTCLOSESYM); + openConditionals--; + break; + + case TAG: + buffer.append(TAGSYM); + buffer.append(element->tag->name); + + if(element->params_count > 0) + { + /* Rendering parameters if there are any */ + buffer.append(ARGLISTOPENSYM); + for(int i = 0; i < children.count(); i++) + { + buffer.append(children[i]->genCode()); + if(i != children.count() - 1) + buffer.append(ARGLISTSEPERATESYM); + } + buffer.append(ARGLISTCLOSESYM); + } + break; + + case TEXT: + for(char* cursor = (char*)element->data; *cursor; cursor++) + { + if(find_escape_character(*cursor)) + buffer.append(TAGSYM); + buffer.append(*cursor); + } + break; + + case COMMENT: + buffer.append(COMMENTSYM); + buffer.append((char*)element->data); + buffer.append('\n'); + break; + } + } + else if(param) + { + switch(param->type) + { + case skin_tag_parameter::STRING: + for(char* cursor = param->data.text; *cursor; cursor++) + { + if(find_escape_character(*cursor)) + buffer.append(TAGSYM); + buffer.append(*cursor); + } + break; + + case skin_tag_parameter::NUMERIC: + buffer.append(QString::number(param->data.numeric, 10)); + break; + + case skin_tag_parameter::DEFAULT: + buffer.append(DEFAULTSYM); + break; + + case skin_tag_parameter::CODE: + buffer.append(QObject::tr("This doesn't belong here")); + break; + + } + } + else + { + for(int i = 0; i < children.count(); i++) + buffer.append(children[i]->genCode()); + } + + return buffer; +} + +/* A more or less random hashing algorithm */ +int ParseTreeNode::genHash() const +{ + int hash = 0; + char *text; + + if(element) + { + hash += element->type; + switch(element->type) + { + case UNKNOWN: + break; + case VIEWPORT: + case LINE: + case SUBLINES: + case CONDITIONAL: + hash += element->children_count; + break; + + case TAG: + for(unsigned int i = 0; i < strlen(element->tag->name); i++) + hash += element->tag->name[i]; + break; + + case COMMENT: + case TEXT: + text = (char*)element->data; + for(unsigned int i = 0; i < strlen(text); i++) + { + if(i % 2) + hash += text[i] % element->type; + else + hash += text[i] % element->type * 2; + } + break; + } + + } + + if(param) + { + hash += param->type; + switch(param->type) + { + case skin_tag_parameter::DEFAULT: + case skin_tag_parameter::CODE: + break; + + case skin_tag_parameter::NUMERIC: + hash += param->data.numeric * (param->data.numeric / 4); + break; + + case skin_tag_parameter::STRING: + for(unsigned int i = 0; i < strlen(param->data.text); i++) + { + if(i % 2) + hash += param->data.text[i] * 2; + else + hash += param->data.text[i]; + } + break; + } + } + + for(int i = 0; i < children.count(); i++) + { + hash += children[i]->genHash(); + } + + return hash; +} + +ParseTreeNode* ParseTreeNode::child(int row) +{ + if(row < 0 || row >= children.count()) + return 0; + + return children[row]; +} + +int ParseTreeNode::numChildren() const +{ + return children.count(); +} + + +QVariant ParseTreeNode::data(int column) const +{ + switch(column) + { + case ParseTreeModel::typeColumn: + if(element) + { + switch(element->type) + { + case UNKNOWN: + return QObject::tr("Unknown"); + case VIEWPORT: + return QObject::tr("Viewport"); + + case LINE: + return QObject::tr("Logical Line"); + + case SUBLINES: + return QObject::tr("Alternator"); + + case COMMENT: + return QObject::tr("Comment"); + + case CONDITIONAL: + return QObject::tr("Conditional Tag"); + + case TAG: + return QObject::tr("Tag"); + + case TEXT: + return QObject::tr("Plaintext"); + } + } + else if(param) + { + switch(param->type) + { + case skin_tag_parameter::STRING: + return QObject::tr("String"); + + case skin_tag_parameter::NUMERIC: + return QObject::tr("Number"); + + case skin_tag_parameter::DEFAULT: + return QObject::tr("Default Argument"); + + case skin_tag_parameter::CODE: + return QObject::tr("This doesn't belong here"); + } + } + else + { + return QObject::tr("Root"); + } + + break; + + case ParseTreeModel::valueColumn: + if(element) + { + switch(element->type) + { + case UNKNOWN: + case VIEWPORT: + case LINE: + case SUBLINES: + return QString(); + + case CONDITIONAL: + return QString(element->tag->name); + + case TEXT: + case COMMENT: + return QString((char*)element->data); + + case TAG: + return QString(element->tag->name); + } + } + else if(param) + { + switch(param->type) + { + case skin_tag_parameter::DEFAULT: + return QObject::tr("-"); + + case skin_tag_parameter::STRING: + return QString(param->data.text); + + case skin_tag_parameter::NUMERIC: + return QString::number(param->data.numeric, 10); + + case skin_tag_parameter::CODE: + return QObject::tr("Seriously, something's wrong here"); + } + } + else + { + return QString(); + } + break; + + case ParseTreeModel::lineColumn: + if(element) + return QString::number(element->line, 10); + else + return QString(); + break; + } + + return QVariant(); +} + + +int ParseTreeNode::getRow() const +{ + if(!parent) + return -1; + + return parent->children.indexOf(const_cast(this)); +} + +ParseTreeNode* ParseTreeNode::getParent() const +{ + return parent; +} + +ParseTreeNode::~ParseTreeNode() +{ + for(int i = 0; i < children.count(); i++) + delete children[i]; +} diff --git a/utils/themeeditor/models/parsetreenode.h b/utils/themeeditor/models/parsetreenode.h new file mode 100644 index 0000000..7a0807b --- /dev/null +++ b/utils/themeeditor/models/parsetreenode.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * __________ __ ___. + * 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 PARSETREENODE_H +#define PARSETREENODE_H + +#include "skin_parser.h" + +#include +#include +#include + +class ParseTreeNode +{ +public: + ParseTreeNode(struct skin_element* data); + ParseTreeNode(struct skin_element* data, ParseTreeNode* parent); + ParseTreeNode(struct skin_tag_parameter* data, ParseTreeNode* parent); + virtual ~ParseTreeNode(); + + QString genCode() const; + int genHash() const; + + bool isParam() const{ if(param) return true; else return false; } + struct skin_tag_parameter* getParam(){ return param;} + struct skin_element* getElement(){return element;} + + ParseTreeNode* child(int row); + int numChildren() const; + QVariant data(int column) const; + int getRow() const; + ParseTreeNode* getParent() const; + ParseTreeNode* getChild(int row) const + { + if(row < children.count()) + return children[row]; + else + return 0; + } + +private: + ParseTreeNode* parent; + struct skin_element* element; + struct skin_tag_parameter* param; + QList children; + + static int openConditionals; + +}; + +#endif // PARSETREENODE_H diff --git a/utils/themeeditor/models/projectmodel.cpp b/utils/themeeditor/models/projectmodel.cpp new file mode 100644 index 0000000..632e0aa --- /dev/null +++ b/utils/themeeditor/models/projectmodel.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "projectmodel.h" +#include "editorwindow.h" + +#include +#include +#include +#include + +ProjectModel::ProjectModel(QString config, EditorWindow* mainWindow, + QObject *parent) + : QAbstractListModel(parent), + mainWindow(mainWindow) +{ + /* Reading the config file */ + QFile cfg(config); + cfg.open(QFile::ReadOnly | QFile::Text); + if(!cfg.isReadable()) + return; + + QTextStream fin(&cfg); + + /* Storing the base directory */ + QString confDir = config; + confDir.chop(confDir.length() - confDir.lastIndexOf('/') - 1); + QDir base(confDir); + base.cdUp(); + settings.insert("themebase", base.canonicalPath()); + + while(!fin.atEnd()) + { + QString current = fin.readLine(); + QList parts = current.split(':'); + + /* A valid setting has at least one : */ + if(parts.count() < 2) + continue; + + QString setting; + for(int i = 1; i < parts.count(); i++) + setting.append(parts[i].trimmed()); + + settings.insert(parts[0].trimmed(), setting); + } + + cfg.close(); + + /* Adding the files, starting with the .cfg */ + config.replace(base.canonicalPath() + "/", ""); + files.append(config); + + QList keys; + keys.append("wps"); + keys.append("rwps"); + keys.append("sbs"); + keys.append("rsbs"); + keys.append("fms"); + keys.append("rfms"); + + for(int i = 0; i < keys.count(); i++) + { + QString file = settings.value(keys[i], ""); + if(file != "" && file != "-") + { + file.replace("/.rockbox/", ""); + files.append(file); + } + } + + +} + +ProjectModel::~ProjectModel() +{ +} + +int ProjectModel::rowCount(const QModelIndex& parent) const +{ + return files.count(); +} + +QVariant ProjectModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + if(role != Qt::DisplayRole) + return QVariant(); + + return files[index.row()]; +} + +void ProjectModel::activated(const QModelIndex &index) +{ + if(index.row() == 0) + { + ConfigDocument* doc = new ConfigDocument(settings, + settings.value("themebase", + "") + "/" + + files[index.row()]); + QObject::connect(doc, SIGNAL(configFileChanged(QString)), + mainWindow, SLOT(configFileChanged(QString))); + mainWindow->loadConfigTab(doc); + } + else + { + mainWindow->loadTabFromSkinFile(settings.value("themebase", "") + + "/" + files[index.row()]); + } +} diff --git a/utils/themeeditor/models/projectmodel.h b/utils/themeeditor/models/projectmodel.h new file mode 100644 index 0000000..6623917 --- /dev/null +++ b/utils/themeeditor/models/projectmodel.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * __________ __ ___. + * 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 PROJECTMODEL_H +#define PROJECTMODEL_H + +#include +#include + +class EditorWindow; + +class ProjectModel : public QAbstractListModel +{ +Q_OBJECT +public: + static const int numColumns = 2; + + static QString fileFilter() + { + return QObject::tr("Project Files (*.cfg);;All Files (*.*)"); + } + + ProjectModel(QString config, EditorWindow* mainWindow, QObject *parent = 0); + virtual ~ProjectModel(); + + int rowCount(const QModelIndex& parent) const; + QVariant data(const QModelIndex &index, int role) const; + + QString getSetting(QString key){ return settings.value(key, ""); } + +signals: + +public slots: + void activated(const QModelIndex& index); + +private: + EditorWindow* mainWindow; + QMap settings; + QList files; +}; + +#endif // PROJECTMODEL_H diff --git a/utils/themeeditor/parser/skin_debug.c b/utils/themeeditor/parser/skin_debug.c new file mode 100644 index 0000000..549f7b9 --- /dev/null +++ b/utils/themeeditor/parser/skin_debug.c @@ -0,0 +1,262 @@ +/*************************************************************************** + * __________ __ ___. + * 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 + +#include "skin_parser.h" +#include "skin_debug.h" +#include "tag_table.h" + +/* Global variables for debug output */ +int debug_indent_level = 0; +extern int skin_line; + +/* Global error variables */ +int error_line; +char* error_message; + +/* Debugging functions */ +void skin_error(enum skin_errorcode error) +{ + + error_line = skin_line; + + switch(error) + { + case MEMORY_LIMIT_EXCEEDED: + error_message = "Memory limit exceeded"; + break; + case NEWLINE_EXPECTED: + error_message = "Newline expected"; + break; + case ILLEGAL_TAG: + error_message = "Illegal tag"; + break; + case ARGLIST_EXPECTED: + error_message = "Argument list expected"; + break; + case TOO_MANY_ARGS: + error_message = "Too many arguments given"; + break; + case DEFAULT_NOT_ALLOWED: + error_message = "Argument can not be set to default"; + break; + case UNEXPECTED_NEWLINE: + error_message = "Unexpected newline"; + break; + case INSUFFICIENT_ARGS: + error_message = "Not enough arguments"; + break; + case INT_EXPECTED: + error_message = "Expected integer"; + break; + case SEPERATOR_EXPECTED: + error_message = "Expected argument seperator"; + break; + case CLOSE_EXPECTED: + error_message = "Expected list close"; + break; + case MULTILINE_EXPECTED: + error_message = "Expected subline seperator"; + break; + }; + +} + +int skin_error_line() +{ + return error_line; +} + +char* skin_error_message() +{ + return error_message; +} + +void skin_clear_errors() +{ + error_line = 0; + error_message = NULL; +} + +void skin_debug_tree(struct skin_element* root) +{ + int i; + char *text; + + struct skin_element* current = root; + + while(current) + { + skin_debug_indent(); + + switch(current->type) + { + case UNKNOWN: + printf("[ Unknown element.. error\n]"); + break; + + case VIEWPORT: + printf("[ Viewport \n"); + + debug_indent_level++; + skin_debug_tree(current->children[0]); + debug_indent_level--; + + printf("]"); + break; + + case TEXT: + text = current->data; + printf("[ Plain text on line %d : %s ]\n", current->line, text); + break; + + case COMMENT: + text = current->data; + printf("[ Comment on line %d: ", current->line); + for(i = 0; i < (int)strlen(text); i++) + { + if(text[i] == '\n') + printf("\\n"); + else + printf("%c", text[i]); + } + printf(" ]\n"); + break; + + case TAG: + printf("[ %s tag on line %d with %d arguments\n", + current->tag->name, + current->line, current->params_count); + debug_indent_level++; + skin_debug_params(current->params_count, current->params); + debug_indent_level--; + skin_debug_indent(); + printf("]\n"); + + break; + + case SUBLINES: + printf("[ Alternator on line %d with %d sublines \n", current->line, + current->children_count); + debug_indent_level++; + for(i = 0; i < current->children_count; i++) + { + skin_debug_tree(current->children[i]); + } + debug_indent_level--; + + skin_debug_indent(); + printf("]\n"); + break; + + case CONDITIONAL: + printf("[ Conditional tag on line %d with %d enumerations \n", + current->line, current->children_count - 1); + debug_indent_level++; + + skin_debug_indent(); + printf("[ Condition tag \n"); + debug_indent_level++; + skin_debug_tree(current->children[0]); + debug_indent_level--; + skin_debug_indent(); + printf("]\n"); + + for(i = 1; i < current->children_count; i++) + { + skin_debug_indent(); + printf("[ Enumeration %d\n", i - 1); + debug_indent_level++; + skin_debug_tree(current->children[i]); + debug_indent_level--; + skin_debug_indent(); + printf("]\n"); + } + + debug_indent_level--; + skin_debug_indent(); + printf("]\n"); + + + break; + + case LINE: + printf("[ Logical line on line %d\n", current->line); + + debug_indent_level++; + skin_debug_tree(current->children[0]); + debug_indent_level--; + + skin_debug_indent(); + printf("]\n"); + break; + } + + current = current->next; + } + +} + +void skin_debug_params(int count, struct skin_tag_parameter params[]) +{ + int i; + for(i = 0; i < count; i++) + { + + skin_debug_indent(); + switch(params[i].type) + { + case DEFAULT: + printf("[-]"); + break; + + case STRING: + printf("[%s]", params[i].data.text); + break; + + case NUMERIC: + printf("[%d]", params[i].data.numeric); + break; + + case CODE: + printf("[ WPS Code: \n"); + debug_indent_level++; + skin_debug_tree(params[i].data.code); + debug_indent_level--; + skin_debug_indent(); + printf("]"); + break; + } + + printf("\n"); + + } +} + +void skin_debug_indent() +{ + int i; + for(i = 0; i < debug_indent_level; i++) + printf(" "); +} diff --git a/utils/themeeditor/parser/skin_debug.h b/utils/themeeditor/parser/skin_debug.h new file mode 100644 index 0000000..a550dc4 --- /dev/null +++ b/utils/themeeditor/parser/skin_debug.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * __________ __ ___. + * 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 SKIN_DEBUG_H +#define SKIN_DEBUG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "skin_parser.h" + +/* Debugging functions */ +void skin_error(enum skin_errorcode error); +int skin_error_line(); +char* skin_error_message(); +void skin_clear_errors(); +void skin_debug_tree(struct skin_element* root); + +/* Auxiliary debug functions */ +void skin_debug_params(int count, struct skin_tag_parameter params[]); +void skin_debug_indent(); + +#ifdef __cplusplus +} +#endif + +#endif // SKIN_DEBUG_H diff --git a/utils/themeeditor/parser/skin_parser.c b/utils/themeeditor/parser/skin_parser.c new file mode 100644 index 0000000..93a7191 --- /dev/null +++ b/utils/themeeditor/parser/skin_parser.c @@ -0,0 +1,923 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +#include + +#include "skin_parser.h" +#include "skin_debug.h" +#include "tag_table.h" +#include "symbols.h" +#include "skin_scan.h" + +#ifdef ROCKBOX +/* Declaration of parse tree buffer */ +#define SKIN_MAX_MEMORY (30*1024) +static char skin_parse_tree[SKIN_MAX_MEMORY]; +static char *skin_buffer; +#endif + +/* Global variables for the parser */ +int skin_line = 0; + +/* Auxiliary parsing functions (not visible at global scope) */ +static struct skin_element* skin_parse_viewport(char** document); +static struct skin_element* skin_parse_line(char** document); +static struct skin_element* skin_parse_line_optional(char** document, + int conditional); +static struct skin_element* skin_parse_sublines(char** document); +static struct skin_element* skin_parse_sublines_optional(char** document, + int conditional); + +static int skin_parse_tag(struct skin_element* element, char** document); +static int skin_parse_text(struct skin_element* element, char** document, + int conditional); +static int skin_parse_conditional(struct skin_element* element, + char** document); +static int skin_parse_comment(struct skin_element* element, char** document); +static struct skin_element* skin_parse_code_as_arg(char** document); + +struct skin_element* skin_parse(const char* document) +{ + + struct skin_element* root = NULL; + struct skin_element* last = NULL; + + struct skin_element** to_write = 0; + + char* cursor = (char*)document; /*Keeps track of location in the document*/ +#ifdef ROCKBOX + /* FIXME */ + skin_buffer = &skin_parse_tree[0]; +#endif + + skin_line = 1; + + skin_clear_errors(); + + while(*cursor != '\0') + { + + if(!root) + to_write = &root; + else + to_write = &(last->next); + + + *to_write = skin_parse_viewport(&cursor); + last = *to_write; + if(!last) + { + skin_free_tree(root); /* Clearing any memory already used */ + return NULL; + } + + /* Making sure last is at the end */ + while(last->next) + last = last->next; + + } + + return root; + +} + +static struct skin_element* skin_parse_viewport(char** document) +{ + + struct skin_element* root = NULL; + struct skin_element* last = NULL; + struct skin_element* retval = NULL; + + retval = skin_alloc_element(); + retval->type = VIEWPORT; + retval->children_count = 1; + retval->line = skin_line; + + struct skin_element** to_write = 0; + + char* cursor = *document; /* Keeps track of location in the document */ + char* bookmark; /* Used when we need to look ahead */ + + int sublines = 0; /* Flag for parsing sublines */ + + /* Parsing out the viewport tag if there is one */ + if(check_viewport(cursor)) + { + skin_parse_tag(retval, &cursor); + if(*cursor == '\n') + { + cursor++; + skin_line++; + } + } + + retval->children_count = 1; + retval->children = skin_alloc_children(1); + + + do + { + + /* First, we check to see if this line will contain sublines */ + bookmark = cursor; + sublines = 0; + while(*cursor != '\n' && *cursor != '\0' + && !(check_viewport(cursor) && cursor != *document)) + { + if(*cursor == MULTILINESYM) + { + sublines = 1; + break; + } + else if(*cursor == TAGSYM) + { + /* A ';' directly after a '%' doesn't count */ + cursor ++; + + if(*cursor == '\0') + break; + + cursor++; + } + else if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + } + else if(*cursor == ARGLISTOPENSYM) + { + skip_arglist(&cursor); + } + else if(*cursor == ENUMLISTOPENSYM) + { + skip_enumlist(&cursor); + } + else + { + /* Advancing the cursor as normal */ + cursor++; + } + } + cursor = bookmark; + + if(!root) + to_write = &root; + else + to_write = &(last->next); + + if(sublines) + { + *to_write = skin_parse_sublines(&cursor); + last = *to_write; + if(!last) + return NULL; + } + else + { + + *to_write = skin_parse_line(&cursor); + last = *to_write; + if(!last) + return NULL; + + } + + /* Making sure last is at the end */ + while(last->next) + last = last->next; + + if(*cursor == '\n') + { + cursor++; + skin_line++; + } + } + while(*cursor != '\0' && !(check_viewport(cursor) && cursor != *document)); + + *document = cursor; + + retval->children[0] = root; + return retval; + +} + +/* Auxiliary Parsing Functions */ + +static struct skin_element* skin_parse_line(char**document) +{ + + return skin_parse_line_optional(document, 0); + +} + + +/* + * If conditional is set to true, then this will break upon encountering + * SEPERATESYM. This should only be used when parsing a line inside a + * conditional, otherwise just use the wrapper function skin_parse_line() + */ +static struct skin_element* skin_parse_line_optional(char** document, + int conditional) +{ + char* cursor = *document; + + struct skin_element* root = NULL; + struct skin_element* current = NULL; + struct skin_element* retval = NULL; + + /* A wrapper for the line */ + retval = skin_alloc_element(); + retval->type = LINE; + retval->line = skin_line; + if(*cursor != '\0' && *cursor != '\n' + && !(conditional && (*cursor == ARGLISTSEPERATESYM + || *cursor == ARGLISTCLOSESYM + || *cursor == ENUMLISTSEPERATESYM + || *cursor == ENUMLISTCLOSESYM))) + { + retval->children_count = 1; + } + else + { + retval->children_count = 0; + } + + if(retval->children_count > 0) + retval->children = skin_alloc_children(1); + + while(*cursor != '\n' && *cursor != '\0' && *cursor != MULTILINESYM + && !((*cursor == ARGLISTSEPERATESYM + || *cursor == ARGLISTCLOSESYM + || *cursor == ENUMLISTSEPERATESYM + || *cursor == ENUMLISTCLOSESYM) + && conditional) + && !(check_viewport(cursor) && cursor != *document)) + { + /* Allocating memory if necessary */ + if(root) + { + current->next = skin_alloc_element(); + current = current->next; + } + else + { + current = skin_alloc_element(); + root = current; + } + + /* Parsing the current element */ + if(*cursor == TAGSYM && cursor[1] == CONDITIONSYM) + { + if(!skin_parse_conditional(current, &cursor)) + return NULL; + } + else if(*cursor == TAGSYM && !find_escape_character(cursor[1])) + { + if(!skin_parse_tag(current, &cursor)) + return NULL; + } + else if(*cursor == COMMENTSYM) + { + if(!skin_parse_comment(current, &cursor)) + return NULL; + } + else + { + if(!skin_parse_text(current, &cursor, conditional)) + return NULL; + } + } + + /* Moving up the calling function's pointer */ + *document = cursor; + + if(root) + retval->children[0] = root; + return retval; +} + +static struct skin_element* skin_parse_sublines(char** document) +{ + return skin_parse_sublines_optional(document, 0); +} + +static struct skin_element* skin_parse_sublines_optional(char** document, + int conditional) +{ + struct skin_element* retval; + char* cursor = *document; + int sublines = 1; + int i; + + retval = skin_alloc_element(); + retval->type = SUBLINES; + retval->next = NULL; + retval->line = skin_line; + + /* First we count the sublines */ + while(*cursor != '\0' && *cursor != '\n' + && !((*cursor == ARGLISTSEPERATESYM + || *cursor == ARGLISTCLOSESYM + || *cursor == ENUMLISTSEPERATESYM + || *cursor == ENUMLISTCLOSESYM) + && conditional) + && !(check_viewport(cursor) && cursor != *document)) + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + } + else if(*cursor == ENUMLISTOPENSYM) + { + skip_enumlist(&cursor); + } + else if(*cursor == ARGLISTOPENSYM) + { + skip_arglist(&cursor); + } + else if(*cursor == TAGSYM) + { + cursor++; + if(*cursor == '\0' || *cursor == '\n') + break; + cursor++; + } + else if(*cursor == MULTILINESYM) + { + sublines++; + cursor++; + } + else + { + cursor++; + } + } + + /* ...and then we parse them */ + retval->children_count = sublines; + retval->children = skin_alloc_children(sublines); + + cursor = *document; + for(i = 0; i < sublines; i++) + { + retval->children[i] = skin_parse_line_optional(&cursor, conditional); + skip_whitespace(&cursor); + + if(*cursor != MULTILINESYM && i != sublines - 1) + { + skin_error(MULTILINE_EXPECTED); + return NULL; + } + else if(i != sublines - 1) + { + cursor++; + } + } + + *document = cursor; + + return retval; +} + +static int skin_parse_tag(struct skin_element* element, char** document) +{ + + char* cursor = *document + 1; + char* bookmark; + + char tag_name[3]; + char* tag_args; + struct tag_info *tag; + + int num_args = 1; + int i; + int star = 0; /* Flag for the all-or-none option */ + int req_args; /* To mark when we enter optional arguments */ + + int optional = 0; + + /* Checking the tag name */ + tag_name[0] = cursor[0]; + tag_name[1] = cursor[1]; + tag_name[2] = '\0'; + + /* First we check the two characters after the '%', then a single char */ + tag = find_tag(tag_name); + + if(!tag) + { + tag_name[1] = '\0'; + tag = find_tag(tag_name); + cursor++; + } + else + { + cursor += 2; + } + + if(!tag) + { + skin_error(ILLEGAL_TAG); + return 0; + } + + /* Copying basic tag info */ + if(element->type != CONDITIONAL && element->type != VIEWPORT) + element->type = TAG; + element->tag = tag; + tag_args = tag->params; + element->line = skin_line; + + /* Checking for the * flag */ + if(tag_args[0] == '*') + { + star = 1; + tag_args++; + } + + /* If this tag has no arguments, we can bail out now */ + if(strlen(tag_args) == 0 + || (tag_args[0] == '|' && *cursor != ARGLISTOPENSYM) + || (star && *cursor != ARGLISTOPENSYM)) + { + *document = cursor; + return 1; + } + + /* Checking the number of arguments and allocating args */ + if(*cursor != ARGLISTOPENSYM && tag_args[0] != '|') + { + skin_error(ARGLIST_EXPECTED); + return 0; + } + else + { + cursor++; + } + + bookmark = cursor; + while(*cursor != '\n' && *cursor != '\0' && *cursor != ARGLISTCLOSESYM) + { + /* Skipping over escaped characters */ + if(*cursor == TAGSYM) + { + cursor++; + if(*cursor == '\0') + break; + cursor++; + } + else if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + } + else if(*cursor == ARGLISTOPENSYM) + { + skip_arglist(&cursor); + } + else if(*cursor == ARGLISTSEPERATESYM) + { + num_args++; + cursor++; + } + else + { + cursor++; + } + } + + cursor = bookmark; /* Restoring the cursor */ + element->params_count = num_args; + element->params = skin_alloc_params(num_args); + + /* Now we have to actually parse each argument */ + for(i = 0; i < num_args; i++) + { + /* Making sure we haven't run out of arguments */ + if(*tag_args == '\0') + { + skin_error(TOO_MANY_ARGS); + return 0; + } + + /* Checking for the optional bar */ + if(*tag_args == '|') + { + optional = 1; + req_args = i; + tag_args++; + } + + /* Scanning the arguments */ + skip_whitespace(&cursor); + + + /* Checking for comments */ + if(*cursor == COMMENTSYM) + skip_comment(&cursor); + + /* Storing the type code */ + element->params[i].type_code = *tag_args; + + /* Checking a nullable argument for null */ + if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) + { + if(islower(*tag_args)) + { + element->params[i].type = DEFAULT; + cursor++; + } + else + { + skin_error(DEFAULT_NOT_ALLOWED); + return 0; + } + } + else if(tolower(*tag_args) == 'i') + { + /* Scanning an int argument */ + if(!isdigit(*cursor) && *cursor != '-') + { + skin_error(INT_EXPECTED); + return 0; + } + + element->params[i].type = NUMERIC; + element->params[i].data.numeric = scan_int(&cursor); + } + else if(tolower(*tag_args) == 'n' || + tolower(*tag_args) == 's' || tolower(*tag_args) == 'f') + { + /* Scanning a string argument */ + element->params[i].type = STRING; + element->params[i].data.text = scan_string(&cursor); + + } + else if(tolower(*tag_args) == 'c') + { + /* Recursively parsing a code argument */ + element->params[i].type = CODE; + element->params[i].data.code = skin_parse_code_as_arg(&cursor); + if(!element->params[i].data.code) + return 0; + } + + skip_whitespace(&cursor); + + if(*cursor != ARGLISTSEPERATESYM && i < num_args - 1) + { + skin_error(SEPERATOR_EXPECTED); + return 0; + } + else if(*cursor != ARGLISTCLOSESYM && i == num_args - 1) + { + skin_error(CLOSE_EXPECTED); + return 0; + } + else + { + cursor++; + } + + if (*tag_args != 'N') + tag_args++; + + /* Checking for the optional bar */ + if(*tag_args == '|') + { + optional = 1; + req_args = i + 1; + tag_args++; + } + + } + + /* Checking for a premature end */ + if(*tag_args != '\0' && !optional) + { + skin_error(INSUFFICIENT_ARGS); + return 0; + } + + *document = cursor; + + return 1; +} + +/* + * If the conditional flag is set true, then parsing text will stop at an + * ARGLISTSEPERATESYM. Only set that flag when parsing within a conditional + */ +static int skin_parse_text(struct skin_element* element, char** document, + int conditional) +{ + char* cursor = *document; + int length = 0; + int dest; + char *text = NULL; + + /* First figure out how much text we're copying */ + while(*cursor != '\0' && *cursor != '\n' && *cursor != MULTILINESYM + && *cursor != COMMENTSYM + && !((*cursor == ARGLISTSEPERATESYM + || *cursor == ARGLISTCLOSESYM + || *cursor == ENUMLISTSEPERATESYM + || *cursor == ENUMLISTCLOSESYM) + && conditional)) + { + /* Dealing with possibility of escaped characters */ + if(*cursor == TAGSYM) + { + if(find_escape_character(cursor[1])) + cursor++; + else + break; + } + + length++; + cursor++; + } + + cursor = *document; + + /* Copying the text into the element struct */ + element->type = TEXT; + element->line = skin_line; + element->next = NULL; + element->data = text = skin_alloc_string(length); + + for(dest = 0; dest < length; dest++) + { + /* Advancing cursor if we've encountered an escaped character */ + if(*cursor == TAGSYM) + cursor++; + + text[dest] = *cursor; + cursor++; + } + text[length] = '\0'; + + *document = cursor; + + return 1; +} + +static int skin_parse_conditional(struct skin_element* element, char** document) +{ + + char* cursor = *document + 1; /* Starting past the "%" */ + char* bookmark; + int children = 1; + int i; + + element->type = CONDITIONAL; + element->line = skin_line; + + /* Parsing the tag first */ + if(!skin_parse_tag(element, &cursor)) + return 0; + + /* Counting the children */ + if(*(cursor++) != ENUMLISTOPENSYM) + { + skin_error(ARGLIST_EXPECTED); + return 0; + } + bookmark = cursor; + while(*cursor != ENUMLISTCLOSESYM && *cursor != '\n' && *cursor != '\0') + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + } + else if(*cursor == ENUMLISTOPENSYM) + { + skip_enumlist(&cursor); + } + else if(*cursor == TAGSYM) + { + cursor++; + if(*cursor == '\0' || *cursor == '\n') + break; + cursor++; + } + else if(*cursor == ENUMLISTSEPERATESYM) + { + children++; + cursor++; + } + else + { + cursor++; + } + } + cursor = bookmark; + + /* Parsing the children */ + element->children = skin_alloc_children(children); + element->children_count = children; + + for(i = 0; i < children; i++) + { + element->children[i] = skin_parse_code_as_arg(&cursor); + skip_whitespace(&cursor); + + if(i < children - 1 && *cursor != ENUMLISTSEPERATESYM) + { + skin_error(SEPERATOR_EXPECTED); + return 0; + } + else if(i == children - 1 && *cursor != ENUMLISTCLOSESYM) + { + skin_error(CLOSE_EXPECTED); + return 0; + } + else + { + cursor++; + } + } + + *document = cursor; + + return 1; +} + +static int skin_parse_comment(struct skin_element* element, char** document) +{ + char* cursor = *document; + char* text = NULL; + + int length; + /* + * Finding the index of the ending newline or null-terminator + * The length of the string of interest doesn't include the leading #, the + * length we need to reserve is the same as the index of the last character + */ + for(length = 0; cursor[length] != '\n' && cursor[length] != '\0'; length++); + + element->type = COMMENT; + element->line = skin_line; +#ifdef ROCKBOX + element->data = NULL; +#else + element->data = text = skin_alloc_string(length); + /* We copy from one char past cursor to leave out the # */ + memcpy((void*)text, (void*)(cursor + 1), + sizeof(char) * (length-1)); + text[length - 1] = '\0'; +#endif + if(cursor[length] == '\n') + skin_line++; + + *document += (length); /* Move cursor up past # and all text */ + if(**document == '\n') + (*document)++; + + return 1; +} + +static struct skin_element* skin_parse_code_as_arg(char** document) +{ + + int sublines = 0; + char* cursor = *document; + + /* Checking for sublines */ + while(*cursor != '\n' && *cursor != '\0' + && *cursor != ENUMLISTSEPERATESYM && *cursor != ARGLISTSEPERATESYM + && *cursor != ENUMLISTCLOSESYM && *cursor != ARGLISTCLOSESYM) + { + if(*cursor == MULTILINESYM) + { + sublines = 1; + break; + } + else if(*cursor == TAGSYM) + { + /* A ';' directly after a '%' doesn't count */ + cursor ++; + + if(*cursor == '\0') + break; + + cursor++; + } + else if(*cursor == ARGLISTOPENSYM) + { + skip_arglist(&cursor); + } + else if(*cursor == ENUMLISTOPENSYM) + { + skip_enumlist(&cursor); + } + else + { + /* Advancing the cursor as normal */ + cursor++; + } + } + + if(sublines) + return skin_parse_sublines_optional(document, 1); + else + return skin_parse_line_optional(document, 1); +} + + +/* Memory management */ +char* skin_alloc(size_t size) +{ +#ifdef ROCKBOX + char *retval = skin_buffer; + skin_buffer = (void *)(((unsigned long)skin_buffer + 3) & ~3); + return retval; +#else + return malloc(size); +#endif +} + +struct skin_element* skin_alloc_element() +{ + struct skin_element* retval = (struct skin_element*) + skin_alloc(sizeof(struct skin_element)); + retval->type = UNKNOWN; + retval->next = NULL; + retval->tag = NULL; + retval->params_count = 0; + retval->children_count = 0; + + return retval; + +} + +struct skin_tag_parameter* skin_alloc_params(int count) +{ + size_t size = sizeof(struct skin_tag_parameter) * count; + return (struct skin_tag_parameter*)skin_alloc(size); + +} + +char* skin_alloc_string(int length) +{ + return (char*)skin_alloc(sizeof(char) * (length + 1)); +} + +struct skin_element** skin_alloc_children(int count) +{ + return (struct skin_element**) + skin_alloc(sizeof(struct skin_element*) * count); +} + +void skin_free_tree(struct skin_element* root) +{ +#ifndef ROCKBOX + int i; + + /* First make the recursive call */ + if(!root) + return; + skin_free_tree(root->next); + + /* Free any text */ + if(root->type == TEXT || root->type == COMMENT) + free(root->data); + + /* Then recursively free any children, before freeing their pointers */ + for(i = 0; i < root->children_count; i++) + skin_free_tree(root->children[i]); + if(root->children_count > 0) + free(root->children); + + /* Free any parameters, making sure to deallocate strings */ + for(i = 0; i < root->params_count; i++) + if(root->params[i].type == STRING) + free(root->params[i].data.text); + if(root->params_count > 0) + free(root->params); + + /* Finally, delete root's memory */ + free(root); +#else + (void)root; +#endif +} diff --git a/utils/themeeditor/parser/skin_parser.h b/utils/themeeditor/parser/skin_parser.h new file mode 100644 index 0000000..1fc4a7a --- /dev/null +++ b/utils/themeeditor/parser/skin_parser.h @@ -0,0 +1,138 @@ +/*************************************************************************** + * __________ __ ___. + * 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 GENERIC_PARSER_H +#define GENERIC_PARSER_H + +#ifdef __cplusplus +extern "C" +{ +#endif +#include + +/******************************************************************** + ****** Data Structures ********************************************* + *******************************************************************/ + +/* Possible types of element in a WPS file */ +enum skin_element_type +{ + UNKNOWN = -1, + VIEWPORT, + LINE, + SUBLINES, + CONDITIONAL, + TAG, + TEXT, + COMMENT, +}; + +enum skin_errorcode +{ + MEMORY_LIMIT_EXCEEDED, + NEWLINE_EXPECTED, + ILLEGAL_TAG, + ARGLIST_EXPECTED, + TOO_MANY_ARGS, + DEFAULT_NOT_ALLOWED, + UNEXPECTED_NEWLINE, + INSUFFICIENT_ARGS, + INT_EXPECTED, + SEPERATOR_EXPECTED, + CLOSE_EXPECTED, + MULTILINE_EXPECTED +}; + +/* Holds a tag parameter, either numeric or text */ +struct skin_tag_parameter +{ + enum + { + NUMERIC, + STRING, + CODE, + DEFAULT + } type; + + union + { + int numeric; + char* text; + struct skin_element* code; + } data; + + char type_code; + +}; + +/* Defines an element of a SKIN file */ +struct skin_element +{ + /* Defines what type of element it is */ + enum skin_element_type type; + + /* The line on which it's defined in the source file */ + int line; + + /* Placeholder for element data + * TEXT and COMMENT uses it for the text string + * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage + */ + void* data; + + /* The tag or conditional name */ + struct tag_info *tag; + + /* Pointer to and size of an array of parameters */ + int params_count; + struct skin_tag_parameter* params; + + /* Pointer to and size of an array of children */ + int children_count; + struct skin_element** children; + + /* Link to the next element */ + struct skin_element* next; +}; + +/*********************************************************************** + ***** Functions ******************************************************* + **********************************************************************/ + +/* Parses a WPS document and returns a list of skin_element + structures. */ +struct skin_element* skin_parse(const char* document); + +/* Memory management functions */ +char *skin_alloc(size_t size); +struct skin_element* skin_alloc_element(); +struct skin_element** skin_alloc_children(int count); +struct skin_tag_parameter* skin_alloc_params(int count); +char* skin_alloc_string(int length); + +void skin_free_tree(struct skin_element* root); + + +#ifdef __cplusplus +} +#endif + +#endif /* GENERIC_PARSER_H */ diff --git a/utils/themeeditor/parser/skin_scan.c b/utils/themeeditor/parser/skin_scan.c new file mode 100644 index 0000000..79f7162 --- /dev/null +++ b/utils/themeeditor/parser/skin_scan.c @@ -0,0 +1,218 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +#include + +#include "skin_scan.h" +#include "skin_debug.h" +#include "symbols.h" +#include "skin_parser.h" + +/* Scanning Functions */ + +/* Simple function to advance a char* past a comment */ +void skip_comment(char** document) +{ + while(**document != '\n' && **document != '\0') + (*document)++; + if(**document == '\n') + (*document)++; +} + +void skip_whitespace(char** document) +{ + while(**document == ' ' || **document == '\t') + (*document)++; +} + +void skip_arglist(char** document) +{ + if(**document == ARGLISTOPENSYM) + (*document)++; + while(**document && **document != ARGLISTCLOSESYM) + { + if(**document == TAGSYM) + { + (*document)++; + if(**document == '\0') + break; + (*document)++; + } + else if(**document == ARGLISTOPENSYM) + skip_arglist(document); + else if(**document == ENUMLISTOPENSYM) + skip_enumlist(document); + else if(**document == COMMENTSYM) + skip_comment(document); + else + (*document)++; + } + if(**document == ARGLISTCLOSESYM) + (*document)++; +} + +void skip_enumlist(char** document) +{ + if(**document == ENUMLISTOPENSYM) + (*document)++; + while(**document && **document != ENUMLISTCLOSESYM) + { + if(**document == TAGSYM) + { + (*document)++; + if(**document == '\0') + break; + (*document)++; + } + else if(**document == ARGLISTOPENSYM) + skip_arglist(document); + else if(**document == ENUMLISTOPENSYM) + skip_enumlist(document); + else if(**document == COMMENTSYM) + skip_comment(document); + else + (*document)++; + } + + if(**document == ENUMLISTCLOSESYM) + (*document)++; +} + +char* scan_string(char** document) +{ + + char* cursor = *document; + int length = 0; + char* buffer = NULL; + int i; + + while(*cursor != ARGLISTSEPERATESYM && *cursor != ARGLISTCLOSESYM && + *cursor != '\0') + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + continue; + } + + if(*cursor == TAGSYM) + cursor++; + + if(*cursor == '\n') + { + skin_error(UNEXPECTED_NEWLINE); + return NULL; + } + + length++; + cursor++; + } + + /* Copying the string */ + cursor = *document; + buffer = skin_alloc_string(length); + buffer[length] = '\0'; + for(i = 0; i < length; i++) + { + if(*cursor == TAGSYM) + cursor++; + + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + i--; + continue; + } + + buffer[i] = *cursor; + cursor++; + } + + *document = cursor; + return buffer; +} + +int scan_int(char** document) +{ + + char* cursor = *document, *end; + int length = 0; + char buffer[16]; + int retval; + int i; + + while(isdigit(*cursor) || *cursor == COMMENTSYM || *cursor == '-') + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + continue; + } + + length++; + cursor++; + } + if (length > 15) + length = 15; + end = cursor; + /* Copying to the buffer while avoiding comments */ + cursor = *document; + buffer[length] = '\0'; + for(i = 0; i < length; i++) + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + i--; + continue; + } + + buffer[i] = *cursor; + cursor++; + + } + retval = atoi(buffer); + + *document = end; + return retval; +} + +int check_viewport(char* document) +{ + if(strlen(document) < 3) + return 0; + + if(document[0] != TAGSYM) + return 0; + + if(document[1] != 'V') + return 0; + + if(document[2] != ARGLISTOPENSYM + && document[2] != 'l' + && document[2] != 'i') + return 0; + + return 1; +} diff --git a/utils/themeeditor/parser/skin_scan.h b/utils/themeeditor/parser/skin_scan.h new file mode 100644 index 0000000..b1d04a6 --- /dev/null +++ b/utils/themeeditor/parser/skin_scan.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 SCANNING_H +#define SCANNING_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Scanning functions */ +void skip_comment(char** document); +void skip_whitespace(char** document); +void skip_arglist(char** document); +void skip_enumlist(char** document); +char* scan_string(char** document); +int scan_int(char** document); +int check_viewport(char* document); /* Checks for a viewport declaration */ + +#ifdef __cplusplus +} +#endif + +#endif // SCANNING_H diff --git a/utils/themeeditor/parser/symbols.h b/utils/themeeditor/parser/symbols.h new file mode 100644 index 0000000..b4f3128 --- /dev/null +++ b/utils/themeeditor/parser/symbols.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * __________ __ ___. + * 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 SYMBOLS_H +#define SYMBOLS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Symbol definitions for WPS parsing */ + +#define TAGSYM '%' +#define COMMENTSYM '#' +#define CONDITIONSYM '?' +#define MULTILINESYM ';' +#define ARGLISTOPENSYM '(' +#define ARGLISTCLOSESYM ')' +#define ARGLISTSEPERATESYM ',' +#define ENUMLISTSEPERATESYM '|' +#define ENUMLISTOPENSYM '<' +#define ENUMLISTCLOSESYM '>' +#define DEFAULTSYM '-' + +#ifdef __cplusplus +} +#endif + +#endif /* SYMBOLS_H */ diff --git a/utils/themeeditor/parser/tag_table.c b/utils/themeeditor/parser/tag_table.c new file mode 100644 index 0000000..6d82b47 --- /dev/null +++ b/utils/themeeditor/parser/tag_table.c @@ -0,0 +1,256 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "tag_table.h" + +#include +#define BAR_PARAMS "*|iiiiN" +/* The tag definition table */ +struct tag_info legal_tags[] = +{ + { SKIN_TOKEN_ALIGN_CENTER, "ac", "" }, + { SKIN_TOKEN_ALIGN_LEFT, "al", "" }, + { SKIN_TOKEN_ALIGN_LEFT_RTL, "aL", "" }, + { SKIN_TOKEN_ALIGN_RIGHT, "ar", "" }, + { SKIN_TOKEN_ALIGN_RIGHT_RTL, "aR", "" }, + { SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "" }, + + { SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS }, + { SKIN_TOKEN_BATTERY_VOLTS, "bv", "" }, + { SKIN_TOKEN_BATTERY_TIME, "bt", "" }, + { SKIN_TOKEN_BATTERY_SLEEPTIME, "bs", "" }, + { SKIN_TOKEN_BATTERY_CHARGING, "bc", "" }, + { SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, "bp", "" }, + { SKIN_TOKEN_USB_POWERED, "bu", "" }, + + + { SKIN_TOKEN_RTC_PRESENT, "cc", "" }, + { SKIN_TOKEN_RTC_DAY_OF_MONTH, "cd", "" }, + { SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, "ce", "" }, + { SKIN_TOKEN_RTC_12HOUR_CFG, "cf", "" }, + { SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, "cH", "" }, + { SKIN_TOKEN_RTC_HOUR_24, "ck", "" }, + { SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, "cI", "" }, + { SKIN_TOKEN_RTC_HOUR_12, "cl", "" }, + { SKIN_TOKEN_RTC_MONTH, "cm", "" }, + { SKIN_TOKEN_RTC_MINUTE, "cM", "" }, + { SKIN_TOKEN_RTC_SECOND, "cS", "" }, + { SKIN_TOKEN_RTC_YEAR_2_DIGITS, "cy", "" }, + { SKIN_TOKEN_RTC_YEAR_4_DIGITS, "cY", "" }, + { SKIN_TOKEN_RTC_AM_PM_UPPER, "cP", "" }, + { SKIN_TOKEN_RTC_AM_PM_LOWER, "cp", "" }, + { SKIN_TOKEN_RTC_WEEKDAY_NAME, "ca", "" }, + { SKIN_TOKEN_RTC_MONTH_NAME, "cb", "" }, + { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, "cu", "" }, + { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "cw", "" }, + + { SKIN_TOKEN_FILE_BITRATE, "fb", "" }, + { SKIN_TOKEN_FILE_CODEC, "fc", "" }, + { SKIN_TOKEN_FILE_FREQUENCY, "ff", "" }, + { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "fk", "" }, + { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "fm", "" }, + { SKIN_TOKEN_FILE_NAME, "fn", "" }, + { SKIN_TOKEN_FILE_PATH, "fp", "" }, + { SKIN_TOKEN_FILE_SIZE, "fs", "" }, + { SKIN_TOKEN_FILE_VBR, "fv", "" }, + { SKIN_TOKEN_FILE_DIRECTORY, "d" , "I" }, + + { SKIN_TOKEN_FILE_BITRATE, "Fb", "" }, + { SKIN_TOKEN_FILE_CODEC, "Fc", "" }, + { SKIN_TOKEN_FILE_FREQUENCY, "Ff", "" }, + { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "Fk", "" }, + { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "Fm", "" }, + { SKIN_TOKEN_FILE_NAME, "Fn", "" }, + { SKIN_TOKEN_FILE_PATH, "Fp", "" }, + { SKIN_TOKEN_FILE_SIZE, "Fs", "" }, + { SKIN_TOKEN_FILE_VBR, "Fv", "" }, + { SKIN_TOKEN_FILE_DIRECTORY, "D" , "I" }, + + + { SKIN_TOKEN_METADATA_ARTIST, "ia", "" }, + { SKIN_TOKEN_METADATA_COMPOSER, "ic", "" }, + { SKIN_TOKEN_METADATA_ALBUM, "id", "" }, + { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "iA", "" }, + { SKIN_TOKEN_METADATA_GROUPING, "iG", "" }, + { SKIN_TOKEN_METADATA_GENRE, "ig", "" }, + { SKIN_TOKEN_METADATA_DISC_NUMBER, "ik", "" }, + { SKIN_TOKEN_METADATA_TRACK_NUMBER, "in", "" }, + { SKIN_TOKEN_METADATA_TRACK_TITLE, "it", "" }, + { SKIN_TOKEN_METADATA_VERSION, "iv", "" }, + { SKIN_TOKEN_METADATA_YEAR, "iy", "" }, + { SKIN_TOKEN_METADATA_COMMENT, "iC", "" }, + + { SKIN_TOKEN_METADATA_ARTIST, "Ia", "" }, + { SKIN_TOKEN_METADATA_COMPOSER, "Ic", "" }, + { SKIN_TOKEN_METADATA_ALBUM, "Id", "" }, + { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "IA", "" }, + { SKIN_TOKEN_METADATA_GROUPING, "IG", "" }, + { SKIN_TOKEN_METADATA_GENRE, "Ig", "" }, + { SKIN_TOKEN_METADATA_DISC_NUMBER, "Ik", "" }, + { SKIN_TOKEN_METADATA_TRACK_NUMBER, "In", "" }, + { SKIN_TOKEN_METADATA_TRACK_TITLE, "It", "" }, + { SKIN_TOKEN_METADATA_VERSION, "Iv", "" }, + { SKIN_TOKEN_METADATA_YEAR, "Iy", "" }, + { SKIN_TOKEN_METADATA_COMMENT, "IC", "" }, + + { SKIN_TOKEN_SOUND_PITCH, "Sp", "" }, + { SKIN_TOKEN_SOUND_SPEED, "Ss", "" }, + + { SKIN_TOKEN_VLED_HDD, "lh", "" }, + + { SKIN_TOKEN_MAIN_HOLD, "mh", "" }, + { SKIN_TOKEN_REMOTE_HOLD, "mr", "" }, + { SKIN_TOKEN_REPEAT_MODE, "mm", "" }, + { SKIN_TOKEN_PLAYBACK_STATUS, "mp", "" }, + { SKIN_TOKEN_BUTTON_VOLUME, "mv", "|S" }, + + { SKIN_TOKEN_PEAKMETER, "pm", "" }, + { SKIN_TOKEN_PLAYER_PROGRESSBAR, "pf", "" }, + { SKIN_TOKEN_PROGRESSBAR, "pb" , BAR_PARAMS }, + { SKIN_TOKEN_VOLUME, "pv" , BAR_PARAMS }, + + { SKIN_TOKEN_TRACK_ELAPSED_PERCENT, "px", "" }, + { SKIN_TOKEN_TRACK_TIME_ELAPSED, "pc", "" }, + { SKIN_TOKEN_TRACK_TIME_REMAINING, "pr", "" }, + { SKIN_TOKEN_TRACK_LENGTH, "pt", "" }, + { SKIN_TOKEN_TRACK_STARTING, "pS" , "|S"}, + { SKIN_TOKEN_TRACK_ENDING, "pE" , "|S"}, + { SKIN_TOKEN_PLAYLIST_POSITION, "pp", "" }, + { SKIN_TOKEN_PLAYLIST_ENTRIES, "pe", "" }, + { SKIN_TOKEN_PLAYLIST_NAME, "pn", "" }, + { SKIN_TOKEN_PLAYLIST_SHUFFLE, "ps", "" }, + + { SKIN_TOKEN_DATABASE_PLAYCOUNT, "rp", "" }, + { SKIN_TOKEN_DATABASE_RATING, "rr", "" }, + { SKIN_TOKEN_DATABASE_AUTOSCORE, "ra", "" }, + + { SKIN_TOKEN_REPLAYGAIN, "rg", "" }, + { SKIN_TOKEN_CROSSFADE, "xf", "" }, + + { SKIN_TOKEN_HAVE_TUNER, "tp", "" }, + { SKIN_TOKEN_TUNER_TUNED, "tt", "" }, + { SKIN_TOKEN_TUNER_SCANMODE, "tm", "" }, + { SKIN_TOKEN_TUNER_STEREO, "ts", "" }, + { SKIN_TOKEN_TUNER_MINFREQ, "ta", "" }, + { SKIN_TOKEN_TUNER_MAXFREQ, "tb", "" }, + { SKIN_TOKEN_TUNER_CURFREQ, "tf", "" }, + { SKIN_TOKEN_PRESET_ID, "Ti", "" }, + { SKIN_TOKEN_PRESET_NAME, "Tn", "" }, + { SKIN_TOKEN_PRESET_FREQ, "Tf", "" }, + { SKIN_TOKEN_PRESET_COUNT, "Tc", "" }, + { SKIN_TOKEN_HAVE_RDS, "tx", "" }, + { SKIN_TOKEN_RDS_NAME, "ty", "" }, + { SKIN_TOKEN_RDS_TEXT, "tz", "" }, + + { SKIN_TOKEN_SUBLINE_SCROLL, "s", "" }, + { SKIN_TOKEN_SUBLINE_TIMEOUT, "t" , "S" }, + + { SKIN_TOKEN_ENABLE_THEME, "we", "" }, + { SKIN_TOKEN_DISABLE_THEME, "wd", "" }, + { SKIN_TOKEN_DRAW_INBUILTBAR, "wi", "" }, + + { SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SFII|I" }, + { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S" }, + { SKIN_TOKEN_IMAGE_PRELOAD, "x", "SFII" }, + + { SKIN_TOKEN_LOAD_FONT, "Fl" , "IF"}, + { SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss"}, + { SKIN_TOKEN_ALBUMART_DISPLAY, "Cd" , ""}, + { SKIN_TOKEN_ALBUMART_FOUND, "C" , ""}, + + { SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S"}, + { SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S"}, + + { SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "ICC"}, + { SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , ""}, + { SKIN_TOKEN_LIST_TITLE_ICON, "Li" , ""}, + + { SKIN_TOKEN_VIEWPORT_FGCOLOUR, "Vf" , "S"}, + { SKIN_TOKEN_VIEWPORT_BGCOLOUR, "Vb" , "S"}, + + { SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "SIIiii|ii"}, + { SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "sIIiii|ii"}, + { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "IIiii|ii"}, + + { SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f"}, + + { SKIN_TOKEN_SETTING, "St" , "S"}, + { SKIN_TOKEN_TRANSLATEDSTRING, "Sx" , "S"}, + { SKIN_TOKEN_LANG_IS_RTL, "Sr" , ""}, + + { SKIN_TOKEN_LASTTOUCH, "Tl" , "|S"}, + { SKIN_TOKEN_CURRENT_SCREEN, "cs", "" }, + { SKIN_TOKEN_TOUCHREGION, "T" , "IIiiS"}, + + { SKIN_TOKEN_HAVE_RECORDING, "Rp" , ""}, + { SKIN_TOKEN_IS_RECORDING, "Rr" , ""}, + { SKIN_TOKEN_REC_FREQ, "Rf" , ""}, + { SKIN_TOKEN_REC_ENCODER, "Re" , ""}, + { SKIN_TOKEN_REC_BITRATE, "Rb" , ""}, + { SKIN_TOKEN_REC_MONO, "Rm" , ""}, + { SKIN_TOKEN_REC_SECONDS, "Rs" , ""}, + { SKIN_TOKEN_REC_MINUTES, "Rn" , ""}, + { SKIN_TOKEN_REC_HOURS, "Rh" , ""}, + + { SKIN_TOKEN_UNKNOWN, "" , ""} + /* Keep this here to mark the end of the table */ +}; + +/* A table of legal escapable characters */ +char legal_escape_characters[] = "%(,);#<|>"; + +/* + * Just does a straight search through the tag table to find one by + * the given name + */ +struct tag_info* find_tag(char* name) +{ + + struct tag_info* current = legal_tags; + + /* + * Continue searching so long as we have a non-empty name string + * and the name of the current element doesn't match the name + * we're searching for + */ + + while(strcmp(current->name, name) && current->name[0] != '\0') + current++; + + if(current->name[0] == '\0') + return NULL; + else + return current; + +} + +/* Searches through the legal escape characters string */ +int find_escape_character(char lookup) +{ + char* current = legal_escape_characters; + while(*current != lookup && *current != '\0') + current++; + + if(*current == lookup && *current) + return 1; + else + return 0; +} diff --git a/utils/themeeditor/parser/tag_table.h b/utils/themeeditor/parser/tag_table.h new file mode 100644 index 0000000..ec9a102 --- /dev/null +++ b/utils/themeeditor/parser/tag_table.h @@ -0,0 +1,307 @@ +/*************************************************************************** + * __________ __ ___. + * 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 TAG_TABLE_H +#define TAG_TABLE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +enum skin_token_type { + + TOKEN_MARKER_CONTROL_TOKENS = -1, + SKIN_TOKEN_UNKNOWN, + + /* Markers */ + SKIN_TOKEN_CHARACTER, + SKIN_TOKEN_STRING, + SKIN_TOKEN_TRANSLATEDSTRING, + + /* Alignment */ + SKIN_TOKEN_ALIGN_LEFT, + SKIN_TOKEN_ALIGN_LEFT_RTL, + SKIN_TOKEN_ALIGN_CENTER, + SKIN_TOKEN_ALIGN_RIGHT, + SKIN_TOKEN_ALIGN_RIGHT_RTL, + SKIN_TOKEN_ALIGN_LANGDIRECTION, + + + /* Sublines */ + SKIN_TOKEN_SUBLINE_TIMEOUT, + SKIN_TOKEN_SUBLINE_SCROLL, + + /* Conditional */ + SKIN_TOKEN_CONDITIONAL, + SKIN_TOKEN_CONDITIONAL_START, + SKIN_TOKEN_CONDITIONAL_OPTION, + SKIN_TOKEN_CONDITIONAL_END, + + /* Viewport display */ + SKIN_TOKEN_VIEWPORT_LOAD, + SKIN_TOKEN_VIEWPORT_CONDITIONAL, + SKIN_TOKEN_VIEWPORT_ENABLE, + SKIN_TOKEN_VIEWPORT_CUSTOMLIST, + SKIN_TOKEN_UIVIEWPORT_ENABLE, + SKIN_TOKEN_UIVIEWPORT_LOAD, + SKIN_TOKEN_VIEWPORT_FGCOLOUR, + SKIN_TOKEN_VIEWPORT_BGCOLOUR, + + /* Battery */ + TOKEN_MARKER_BATTERY, + SKIN_TOKEN_BATTERY_PERCENT, + SKIN_TOKEN_BATTERY_PERCENTBAR, + SKIN_TOKEN_BATTERY_VOLTS, + SKIN_TOKEN_BATTERY_TIME, + SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, + SKIN_TOKEN_BATTERY_CHARGING, + SKIN_TOKEN_BATTERY_SLEEPTIME, + SKIN_TOKEN_USB_POWERED, + + /* Sound */ + TOKEN_MARKER_SOUND, + SKIN_TOKEN_SOUND_PITCH, + SKIN_TOKEN_SOUND_SPEED, + SKIN_TOKEN_REPLAYGAIN, + SKIN_TOKEN_CROSSFADE, + + /* Time */ + TOKEN_MARKER_RTC, + SKIN_TOKEN_RTC_PRESENT, + + /* The begin/end values allow us to know if a token is an RTC one. + New RTC tokens should be added between the markers. */ + + SKIN_TOKENs_RTC_BEGIN, /* just the start marker, not an actual token */ + + SKIN_TOKEN_RTC_DAY_OF_MONTH, + SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, + SKIN_TOKEN_RTC_12HOUR_CFG, + SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, + SKIN_TOKEN_RTC_HOUR_24, + SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, + SKIN_TOKEN_RTC_HOUR_12, + SKIN_TOKEN_RTC_MONTH, + SKIN_TOKEN_RTC_MINUTE, + SKIN_TOKEN_RTC_SECOND, + SKIN_TOKEN_RTC_YEAR_2_DIGITS, + SKIN_TOKEN_RTC_YEAR_4_DIGITS, + SKIN_TOKEN_RTC_AM_PM_UPPER, + SKIN_TOKEN_RTC_AM_PM_LOWER, + SKIN_TOKEN_RTC_WEEKDAY_NAME, + SKIN_TOKEN_RTC_MONTH_NAME, + SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, + SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, + + SKIN_TOKENS_RTC_END, /* just the end marker, not an actual token */ + + /* Database */ + TOKEN_MARKER_DATABASE, + SKIN_TOKEN_DATABASE_PLAYCOUNT, + SKIN_TOKEN_DATABASE_RATING, + SKIN_TOKEN_DATABASE_AUTOSCORE, + + /* File */ + TOKEN_MARKER_FILE, + SKIN_TOKEN_FILE_BITRATE, + SKIN_TOKEN_FILE_CODEC, + SKIN_TOKEN_FILE_FREQUENCY, + SKIN_TOKEN_FILE_FREQUENCY_KHZ, + SKIN_TOKEN_FILE_NAME, + SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, + SKIN_TOKEN_FILE_PATH, + SKIN_TOKEN_FILE_SIZE, + SKIN_TOKEN_FILE_VBR, + SKIN_TOKEN_FILE_DIRECTORY, + + /* Image */ + TOKEN_MARKER_IMAGES, + SKIN_TOKEN_IMAGE_BACKDROP, + SKIN_TOKEN_IMAGE_PROGRESS_BAR, + SKIN_TOKEN_IMAGE_PRELOAD, + SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, + SKIN_TOKEN_IMAGE_DISPLAY, + + /* Albumart */ + SKIN_TOKEN_ALBUMART_LOAD, + SKIN_TOKEN_ALBUMART_DISPLAY, + SKIN_TOKEN_ALBUMART_FOUND, + + /* Metadata */ + TOKEN_MARKER_METADATA, + SKIN_TOKEN_METADATA_ARTIST, + SKIN_TOKEN_METADATA_COMPOSER, + SKIN_TOKEN_METADATA_ALBUM_ARTIST, + SKIN_TOKEN_METADATA_GROUPING, + SKIN_TOKEN_METADATA_ALBUM, + SKIN_TOKEN_METADATA_GENRE, + SKIN_TOKEN_METADATA_DISC_NUMBER, + SKIN_TOKEN_METADATA_TRACK_NUMBER, + SKIN_TOKEN_METADATA_TRACK_TITLE, + SKIN_TOKEN_METADATA_VERSION, + SKIN_TOKEN_METADATA_YEAR, + SKIN_TOKEN_METADATA_COMMENT, + + TOKEN_MARKER_PLAYBACK_INFO, + /* Mode */ + SKIN_TOKEN_REPEAT_MODE, + SKIN_TOKEN_PLAYBACK_STATUS, + /* Progressbar */ + SKIN_TOKEN_PROGRESSBAR, + SKIN_TOKEN_PLAYER_PROGRESSBAR, + /* Peakmeter */ + SKIN_TOKEN_PEAKMETER, + + /* Current track */ + SKIN_TOKEN_TRACK_ELAPSED_PERCENT, + SKIN_TOKEN_TRACK_TIME_ELAPSED, + SKIN_TOKEN_TRACK_TIME_REMAINING, + SKIN_TOKEN_TRACK_LENGTH, + SKIN_TOKEN_TRACK_STARTING, + SKIN_TOKEN_TRACK_ENDING, + + /* Playlist */ + TOKEN_MARKER_PLAYLIST, + SKIN_TOKEN_PLAYLIST_ENTRIES, + SKIN_TOKEN_PLAYLIST_NAME, + SKIN_TOKEN_PLAYLIST_POSITION, + SKIN_TOKEN_PLAYLIST_SHUFFLE, + + + TOKEN_MARKER_MISC, + SKIN_TOKEN_ENABLE_THEME, + SKIN_TOKEN_DISABLE_THEME, + SKIN_TOKEN_DRAW_INBUILTBAR, + SKIN_TOKEN_LIST_TITLE_TEXT, + SKIN_TOKEN_LIST_TITLE_ICON, + + SKIN_TOKEN_LOAD_FONT, + + /* buttons */ + SKIN_TOKEN_BUTTON_VOLUME, + SKIN_TOKEN_LASTTOUCH, + SKIN_TOKEN_TOUCHREGION, + /* Virtual LED */ + SKIN_TOKEN_VLED_HDD, + /* Volume level */ + SKIN_TOKEN_VOLUME, + SKIN_TOKEN_VOLUMEBAR, + /* hold */ + SKIN_TOKEN_MAIN_HOLD, + SKIN_TOKEN_REMOTE_HOLD, + + /* Setting option */ + SKIN_TOKEN_SETTING, + SKIN_TOKEN_CURRENT_SCREEN, + SKIN_TOKEN_LANG_IS_RTL, + + /* Recording Tokens */ + TOKEN_MARKER_RECORDING, + SKIN_TOKEN_HAVE_RECORDING, + SKIN_TOKEN_IS_RECORDING, + SKIN_TOKEN_REC_FREQ, + SKIN_TOKEN_REC_ENCODER, + SKIN_TOKEN_REC_BITRATE, /* SWCODEC: MP3 bitrate, HWCODEC: MP3 "quality" */ + SKIN_TOKEN_REC_MONO, + SKIN_TOKEN_REC_SECONDS, + SKIN_TOKEN_REC_MINUTES, + SKIN_TOKEN_REC_HOURS, + + + /* Radio Tokens */ + TOKEN_MARKER_TUNER, + SKIN_TOKEN_HAVE_TUNER, + SKIN_TOKEN_TUNER_TUNED, + SKIN_TOKEN_TUNER_SCANMODE, + SKIN_TOKEN_TUNER_STEREO, + SKIN_TOKEN_TUNER_MINFREQ, /* changes based on "region" */ + SKIN_TOKEN_TUNER_MAXFREQ, /* changes based on "region" */ + SKIN_TOKEN_TUNER_CURFREQ, + SKIN_TOKEN_PRESET_ID, /* "id" of this preset.. really the array element number */ + SKIN_TOKEN_PRESET_NAME, + SKIN_TOKEN_PRESET_FREQ, + SKIN_TOKEN_PRESET_COUNT, + /* RDS tokens */ + SKIN_TOKEN_HAVE_RDS, + SKIN_TOKEN_RDS_NAME, + SKIN_TOKEN_RDS_TEXT, + + + TOKEN_MARKER_END, /* this needs to be the last value in this enum */ +}; + +/* + * Struct for tag parsing information + * name - The name of the tag, i.e. V for %V + * params - A string specifying all of the tags parameters, each + * character representing a single parameter. Valid + * characters for parameters are: + * I - Required integer + * i - Nullable integer + * S - Required string + * s - Nullable string + * F - Required file name + * f - Nullable file name + * C - Required skin code + * N - any amount of strings.. must be the last param in the list + * Any nullable parameter may be replaced in the WPS file + * with a '-'. To specify that parameters may be left off + * altogether, place a '|' in the parameter string. For + * instance, with the parameter string... + * Ii|Ss + * one integer must be specified, one integer can be + * specified or set to default with '-', and the user can + * stop providing parameters at any time after that. + * To specify multiple instances of the same type, put a + * number before the character. For instance, the string... + * 2s + * will specify two strings. An asterisk (*) at the beginning of the + * string will specify that you may choose to omit all arguments + * + */ +struct tag_info +{ + enum skin_token_type type; + char* name; + char* params; + +}; + +/* + * Finds a tag by name and returns its parameter list, or an empty + * string if the tag is not found in the table + */ +struct tag_info* find_tag(char* name); + +/* + * Determines whether a character is legal to escape or not. If + * lookup is not found in the legal escape characters string, returns + * false, otherwise returns true + */ +int find_escape_character(char lookup); + +#ifdef __cplusplus +} +#endif + +#endif /* TAG_TABLE_H */ diff --git a/utils/themeeditor/parsetreemodel.cpp b/utils/themeeditor/parsetreemodel.cpp deleted file mode 100644 index a709ea7..0000000 --- a/utils/themeeditor/parsetreemodel.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "parsetreemodel.h" -#include "symbols.h" - -#include - -#include - -ParseTreeModel::ParseTreeModel(const char* document, QObject* parent): - QAbstractItemModel(parent) -{ - this->tree = skin_parse(document); - - if(tree) - this->root = new ParseTreeNode(tree); - else - this->root = 0; -} - - -ParseTreeModel::~ParseTreeModel() -{ - if(root) - delete root; - if(tree) - skin_free_tree(tree); -} - -QString ParseTreeModel::genCode() -{ - if(root) - return root->genCode(); - else - return ""; -} - -QString ParseTreeModel::changeTree(const char *document) -{ - struct skin_element* test = skin_parse(document); - - if(!test) - { - QString error = tr("Error on line ") + - QString::number(skin_error_line()) - + tr(": ") + QString(skin_error_message()); - return error; - } - - ParseTreeNode* temp = new ParseTreeNode(test); - if(root && temp->genHash() == root->genHash()) - { - delete temp; - return tr("Document Parses Successfully"); - } - - if(root) - { - emit beginRemoveRows(QModelIndex(), 0, root->numChildren() - 1); - delete root; - emit endRemoveRows(); - } - - root = temp; - - emit beginInsertRows(QModelIndex(), 0, temp->numChildren() - 1); - emit endInsertRows(); - - return tr("Document Parses Successfully"); - -} - -QModelIndex ParseTreeModel::index(int row, int column, - const QModelIndex& parent) const -{ - if(!hasIndex(row, column, parent)) - return QModelIndex(); - - ParseTreeNode* foundParent; - - if(parent.isValid()) - foundParent = static_cast(parent.internalPointer()); - else - foundParent = root; - - if(row < foundParent->numChildren() && row >= 0) - return createIndex(row, column, foundParent->child(row)); - else - return QModelIndex(); -} - -QModelIndex ParseTreeModel::parent(const QModelIndex &child) const -{ - if(!child.isValid()) - return QModelIndex(); - - ParseTreeNode* foundParent = static_cast - (child.internalPointer())->getParent(); - - if(foundParent == root) - return QModelIndex(); - - return createIndex(foundParent->getRow(), 0, foundParent); -} - -int ParseTreeModel::rowCount(const QModelIndex &parent) const -{ - if(!root) - return 0; - - if(!parent.isValid()) - return root->numChildren(); - - if(parent.column() != typeColumn) - return 0; - - return static_cast(parent.internalPointer())->numChildren(); -} - -int ParseTreeModel::columnCount(const QModelIndex &parent) const -{ - if(parent.isValid()) - return numColumns; - else - return numColumns; -} - -QVariant ParseTreeModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid()) - return QVariant(); - - if(role != Qt::DisplayRole) - return QVariant(); - - return static_cast(index.internalPointer())-> - data(index.column()); -} - -QVariant ParseTreeModel::headerData(int col, Qt::Orientation orientation, - int role) const -{ - if(orientation != Qt::Horizontal) - return QVariant(); - - if(col >= numColumns) - return QVariant(); - - if(role != Qt::DisplayRole) - return QVariant(); - - switch(col) - { - case typeColumn: - return QObject::tr("Type"); - - case lineColumn: - return QObject::tr("Line"); - - case valueColumn: - return QObject::tr("Value"); - } - - return QVariant(); -} - -Qt::ItemFlags ParseTreeModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags retval = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - - ParseTreeNode* element = static_cast - (index.internalPointer()); - - if((element->isParam() - || element->getElement()->type == TEXT - || element->getElement()->type == COMMENT) - && index.column() == valueColumn) - { - retval |= Qt::ItemIsEditable; - } - - return retval; -} - -bool ParseTreeModel::setData(const QModelIndex &index, const QVariant &value, - int role) -{ - if(role != Qt::EditRole) - return false; - - if(index.column() != valueColumn) - return false; - - ParseTreeNode* node = static_cast - (index.internalPointer()); - - if(node->isParam()) - { - struct skin_tag_parameter* param = node->getParam(); - - /* Now that we've established that we do, in fact, have a parameter, - * set it to its new value if an acceptable one has been entered - */ - if(value.toString().trimmed() == QString(QChar(DEFAULTSYM))) - { - if(islower(param->type_code)) - param->type = skin_tag_parameter::DEFAULT; - else - return false; - } - else if(tolower(param->type_code) == 's' - || tolower(param->type_code) == 'f') - { - if(param->type == skin_tag_parameter::STRING) - free(param->data.text); - - param->type = skin_tag_parameter::STRING; - param->data.text = strdup(value.toString().trimmed().toAscii()); - } - else if(tolower(param->type_code) == 'i') - { - if(!value.canConvert(QVariant::Int)) - return false; - - param->type = skin_tag_parameter::NUMERIC; - param->data.numeric = value.toInt(); - } - else - { - return false; - } - } - else - { - struct skin_element* element = node->getElement(); - - if(element->type != COMMENT && element->type != TEXT) - return false; - - free(element->data); - element->data = strdup(value.toString().trimmed().toAscii()); - } - - emit dataChanged(index, index); - return true; -} diff --git a/utils/themeeditor/parsetreemodel.h b/utils/themeeditor/parsetreemodel.h deleted file mode 100644 index 55af549..0000000 --- a/utils/themeeditor/parsetreemodel.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "skin_parser.h" -#include "skin_debug.h" - -#ifndef PARSETREEMODEL_H -#define PARSETREEMODEL_H - -#include -#include - -#include "parsetreenode.h" - -class ParseTreeModel : public QAbstractItemModel -{ - - Q_OBJECT - -public: - /* Constants */ - static const int numColumns = 3; - static const int typeColumn = 0; - static const int lineColumn = 1; - static const int valueColumn = 2; - - /* Initializes a tree with a skin document in a string */ - ParseTreeModel(const char* document, QObject* parent = 0); - virtual ~ParseTreeModel(); - - QString genCode(); - /* Changes the parse tree to a new document */ - QString changeTree(const char* document); - QModelIndex index(int row, int column, const QModelIndex& parent) const; - QModelIndex parent(const QModelIndex &child) const; - int rowCount(const QModelIndex &parent) const; - int columnCount(const QModelIndex &parent) const; - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int col, Qt::Orientation orientation, int role) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - bool setData(const QModelIndex &index, const QVariant &value, int role); - -private: - ParseTreeNode* root; - struct skin_element* tree; -}; - - - -#endif // PARSETREEMODEL_H diff --git a/utils/themeeditor/parsetreenode.cpp b/utils/themeeditor/parsetreenode.cpp deleted file mode 100644 index 397031a..0000000 --- a/utils/themeeditor/parsetreenode.cpp +++ /dev/null @@ -1,474 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "symbols.h" -#include "tag_table.h" - -#include "parsetreenode.h" -#include "parsetreemodel.h" - -int ParseTreeNode::openConditionals = 0; - -/* Root element constructor */ -ParseTreeNode::ParseTreeNode(struct skin_element* data) - : parent(0), element(0), param(0), children() -{ - while(data) - { - children.append(new ParseTreeNode(data, this)); - data = data->next; - } -} - -/* Normal element constructor */ -ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeNode* parent) - : parent(parent), element(data), param(0), children() -{ - switch(element->type) - { - - case TAG: - for(int i = 0; i < element->params_count; i++) - { - if(element->params[i].type == skin_tag_parameter::CODE) - children.append(new ParseTreeNode(element->params[i].data.code, - this)); - else - children.append(new ParseTreeNode(&element->params[i], this)); - } - break; - - case CONDITIONAL: - for(int i = 0; i < element->params_count; i++) - children.append(new ParseTreeNode(&data->params[i], this)); - for(int i = 0; i < element->children_count; i++) - children.append(new ParseTreeNode(data->children[i], this)); - break; - - case SUBLINES: - for(int i = 0; i < element->children_count; i++) - { - children.append(new ParseTreeNode(data->children[i], this)); - } - break; - -case VIEWPORT: - for(int i = 0; i < element->params_count; i++) - children.append(new ParseTreeNode(&data->params[i], this)); - /* Deliberate fall-through here */ - - case LINE: - for(int i = 0; i < data->children_count; i++) - { - for(struct skin_element* current = data->children[i]; current; - current = current->next) - { - children.append(new ParseTreeNode(current, this)); - } - } - break; - - default: - break; - } -} - -/* Parameter constructor */ -ParseTreeNode::ParseTreeNode(skin_tag_parameter *data, ParseTreeNode *parent) - : parent(parent), element(0), param(data), children() -{ - -} - -QString ParseTreeNode::genCode() const -{ - QString buffer = ""; - - if(element) - { - switch(element->type) - { - case UNKNOWN: - break; - case VIEWPORT: - /* Generating the Viewport tag, if necessary */ - if(element->tag) - { - buffer.append(TAGSYM); - buffer.append(element->tag->name); - buffer.append(ARGLISTOPENSYM); - for(int i = 0; i < element->params_count; i++) - { - buffer.append(children[i]->genCode()); - if(i != element->params_count - 1) - buffer.append(ARGLISTSEPERATESYM); - } - buffer.append(ARGLISTCLOSESYM); - buffer.append('\n'); - } - - for(int i = element->params_count; i < children.count(); i++) - buffer.append(children[i]->genCode()); - break; - - case LINE: - for(int i = 0; i < children.count(); i++) - { - buffer.append(children[i]->genCode()); - } - if(openConditionals == 0 - && !(parent && parent->element->type == SUBLINES)) - { - buffer.append('\n'); - } - break; - - case SUBLINES: - for(int i = 0; i < children.count(); i++) - { - buffer.append(children[i]->genCode()); - if(i != children.count() - 1) - buffer.append(MULTILINESYM); - } - if(openConditionals == 0) - buffer.append('\n'); - break; - - case CONDITIONAL: - openConditionals++; - - /* Inserting the tag part */ - buffer.append(TAGSYM); - buffer.append(CONDITIONSYM); - buffer.append(element->tag->name); - if(element->params_count > 0) - { - buffer.append(ARGLISTOPENSYM); - for(int i = 0; i < element->params_count; i++) - { - buffer.append(children[i]->genCode()); - if( i != element->params_count - 1) - buffer.append(ARGLISTSEPERATESYM); - buffer.append(ARGLISTCLOSESYM); - } - } - - /* Inserting the sublines */ - buffer.append(ENUMLISTOPENSYM); - for(int i = element->params_count; i < children.count(); i++) - { - buffer.append(children[i]->genCode()); - if(i != children.count() - 1) - buffer.append(ENUMLISTSEPERATESYM); - } - buffer.append(ENUMLISTCLOSESYM); - openConditionals--; - break; - - case TAG: - buffer.append(TAGSYM); - buffer.append(element->tag->name); - - if(element->params_count > 0) - { - /* Rendering parameters if there are any */ - buffer.append(ARGLISTOPENSYM); - for(int i = 0; i < children.count(); i++) - { - buffer.append(children[i]->genCode()); - if(i != children.count() - 1) - buffer.append(ARGLISTSEPERATESYM); - } - buffer.append(ARGLISTCLOSESYM); - } - break; - - case TEXT: - for(char* cursor = (char*)element->data; *cursor; cursor++) - { - if(find_escape_character(*cursor)) - buffer.append(TAGSYM); - buffer.append(*cursor); - } - break; - - case COMMENT: - buffer.append(COMMENTSYM); - buffer.append((char*)element->data); - buffer.append('\n'); - break; - } - } - else if(param) - { - switch(param->type) - { - case skin_tag_parameter::STRING: - for(char* cursor = param->data.text; *cursor; cursor++) - { - if(find_escape_character(*cursor)) - buffer.append(TAGSYM); - buffer.append(*cursor); - } - break; - - case skin_tag_parameter::NUMERIC: - buffer.append(QString::number(param->data.numeric, 10)); - break; - - case skin_tag_parameter::DEFAULT: - buffer.append(DEFAULTSYM); - break; - - case skin_tag_parameter::CODE: - buffer.append(QObject::tr("This doesn't belong here")); - break; - - } - } - else - { - for(int i = 0; i < children.count(); i++) - buffer.append(children[i]->genCode()); - } - - return buffer; -} - -/* A more or less random hashing algorithm */ -int ParseTreeNode::genHash() const -{ - int hash = 0; - char *text; - - if(element) - { - hash += element->type; - switch(element->type) - { - case UNKNOWN: - break; - case VIEWPORT: - case LINE: - case SUBLINES: - case CONDITIONAL: - hash += element->children_count; - break; - - case TAG: - for(unsigned int i = 0; i < strlen(element->tag->name); i++) - hash += element->tag->name[i]; - break; - - case COMMENT: - case TEXT: - text = (char*)element->data; - for(unsigned int i = 0; i < strlen(text); i++) - { - if(i % 2) - hash += text[i] % element->type; - else - hash += text[i] % element->type * 2; - } - break; - } - - } - - if(param) - { - hash += param->type; - switch(param->type) - { - case skin_tag_parameter::DEFAULT: - case skin_tag_parameter::CODE: - break; - - case skin_tag_parameter::NUMERIC: - hash += param->data.numeric * (param->data.numeric / 4); - break; - - case skin_tag_parameter::STRING: - for(unsigned int i = 0; i < strlen(param->data.text); i++) - { - if(i % 2) - hash += param->data.text[i] * 2; - else - hash += param->data.text[i]; - } - break; - } - } - - for(int i = 0; i < children.count(); i++) - { - hash += children[i]->genHash(); - } - - return hash; -} - -ParseTreeNode* ParseTreeNode::child(int row) -{ - if(row < 0 || row >= children.count()) - return 0; - - return children[row]; -} - -int ParseTreeNode::numChildren() const -{ - return children.count(); -} - - -QVariant ParseTreeNode::data(int column) const -{ - switch(column) - { - case ParseTreeModel::typeColumn: - if(element) - { - switch(element->type) - { - case UNKNOWN: - return QObject::tr("Unknown"); - case VIEWPORT: - return QObject::tr("Viewport"); - - case LINE: - return QObject::tr("Logical Line"); - - case SUBLINES: - return QObject::tr("Alternator"); - - case COMMENT: - return QObject::tr("Comment"); - - case CONDITIONAL: - return QObject::tr("Conditional Tag"); - - case TAG: - return QObject::tr("Tag"); - - case TEXT: - return QObject::tr("Plaintext"); - } - } - else if(param) - { - switch(param->type) - { - case skin_tag_parameter::STRING: - return QObject::tr("String"); - - case skin_tag_parameter::NUMERIC: - return QObject::tr("Number"); - - case skin_tag_parameter::DEFAULT: - return QObject::tr("Default Argument"); - - case skin_tag_parameter::CODE: - return QObject::tr("This doesn't belong here"); - } - } - else - { - return QObject::tr("Root"); - } - - break; - - case ParseTreeModel::valueColumn: - if(element) - { - switch(element->type) - { - case UNKNOWN: - case VIEWPORT: - case LINE: - case SUBLINES: - return QString(); - - case CONDITIONAL: - return QString(element->tag->name); - - case TEXT: - case COMMENT: - return QString((char*)element->data); - - case TAG: - return QString(element->tag->name); - } - } - else if(param) - { - switch(param->type) - { - case skin_tag_parameter::DEFAULT: - return QObject::tr("-"); - - case skin_tag_parameter::STRING: - return QString(param->data.text); - - case skin_tag_parameter::NUMERIC: - return QString::number(param->data.numeric, 10); - - case skin_tag_parameter::CODE: - return QObject::tr("Seriously, something's wrong here"); - } - } - else - { - return QString(); - } - break; - - case ParseTreeModel::lineColumn: - if(element) - return QString::number(element->line, 10); - else - return QString(); - break; - } - - return QVariant(); -} - - -int ParseTreeNode::getRow() const -{ - if(!parent) - return -1; - - return parent->children.indexOf(const_cast(this)); -} - -ParseTreeNode* ParseTreeNode::getParent() const -{ - return parent; -} - -ParseTreeNode::~ParseTreeNode() -{ - for(int i = 0; i < children.count(); i++) - delete children[i]; -} diff --git a/utils/themeeditor/parsetreenode.h b/utils/themeeditor/parsetreenode.h deleted file mode 100644 index 7a0807b..0000000 --- a/utils/themeeditor/parsetreenode.h +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 PARSETREENODE_H -#define PARSETREENODE_H - -#include "skin_parser.h" - -#include -#include -#include - -class ParseTreeNode -{ -public: - ParseTreeNode(struct skin_element* data); - ParseTreeNode(struct skin_element* data, ParseTreeNode* parent); - ParseTreeNode(struct skin_tag_parameter* data, ParseTreeNode* parent); - virtual ~ParseTreeNode(); - - QString genCode() const; - int genHash() const; - - bool isParam() const{ if(param) return true; else return false; } - struct skin_tag_parameter* getParam(){ return param;} - struct skin_element* getElement(){return element;} - - ParseTreeNode* child(int row); - int numChildren() const; - QVariant data(int column) const; - int getRow() const; - ParseTreeNode* getParent() const; - ParseTreeNode* getChild(int row) const - { - if(row < children.count()) - return children[row]; - else - return 0; - } - -private: - ParseTreeNode* parent; - struct skin_element* element; - struct skin_tag_parameter* param; - QList children; - - static int openConditionals; - -}; - -#endif // PARSETREENODE_H diff --git a/utils/themeeditor/preferencesdialog.cpp b/utils/themeeditor/preferencesdialog.cpp deleted file mode 100644 index 8cd9665..0000000 --- a/utils/themeeditor/preferencesdialog.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "preferencesdialog.h" -#include "ui_preferencesdialog.h" - -#include -#include - -PreferencesDialog::PreferencesDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::PreferencesDialog) -{ - ui->setupUi(this); - setupUI(); - loadSettings(); -} - -PreferencesDialog::~PreferencesDialog() -{ - delete ui; -} - -void PreferencesDialog::loadSettings() -{ - loadColors(); - loadFont(); -} - -void PreferencesDialog::loadColors() -{ - - QSettings settings; - - /* The list of buttons from the SkinHighlighter group */ - - settings.beginGroup("SkinHighlighter"); - - commentColor = settings.value("commentColor", - QColor(0, 180, 0)).value(); - setButtonColor(ui->commentButton, commentColor); - - escapedColor = settings.value("escapedColor", - QColor(120,120,120)).value(); - setButtonColor(ui->escapedButton, escapedColor); - - conditionalColor = settings.value("conditionalColor", - QColor(0, 0, 180)).value(); - setButtonColor(ui->conditionalButton, conditionalColor); - - tagColor = settings.value("tagColor", - QColor(180, 0, 0)).value(); - setButtonColor(ui->tagButton, tagColor); - - settings.endGroup(); - - /* Buttons from the editor group */ - settings.beginGroup("SkinDocument"); - - fgColor = settings.value("fgColor", Qt::black).value(); - setButtonColor(ui->fgButton, fgColor); - - bgColor = settings.value("bgColor", Qt::white).value(); - setButtonColor(ui->bgButton, bgColor); - - errorColor = settings.value("errorColor", Qt::red).value(); - setButtonColor(ui->errorButton, errorColor); - - settings.endGroup(); -} - -void PreferencesDialog::loadFont() -{ - QSettings settings; - settings.beginGroup("SkinDocument"); - - QFont def("Monospace"); - def.setStyleHint(QFont::TypeWriter); - - QVariant family = settings.value("fontFamily", def); - int size = settings.value("fontSize", 12).toInt(); - - settings.endGroup(); - - ui->fontSelect->setCurrentFont(family.value()); - ui->fontSize->setValue(size); - -} - -void PreferencesDialog::saveSettings() -{ - saveColors(); - saveFont(); -} - -void PreferencesDialog::saveColors() -{ - QSettings settings; - - /* Saving the editor colors */ - settings.beginGroup("SkinDocument"); - - settings.setValue("fgColor", fgColor); - settings.setValue("bgColor", bgColor); - settings.setValue("errorColor", errorColor); - - settings.endGroup(); - - /* Saving the highlighting colors */ - settings.beginGroup("SkinHighlighter"); - - settings.setValue("tagColor", tagColor); - settings.setValue("commentColor", commentColor); - settings.setValue("conditionalColor", conditionalColor); - settings.setValue("escapedColor", escapedColor); - - settings.endGroup(); -} - -void PreferencesDialog::saveFont() -{ - QSettings settings; - settings.beginGroup("SkinDocument"); - - settings.setValue("fontFamily", ui->fontSelect->currentFont()); - settings.setValue("fontSize", ui->fontSize->value()); - - settings.endGroup(); -} - -void PreferencesDialog::setupUI() -{ - /* Connecting color buttons */ - QList buttons; - buttons.append(ui->bgButton); - buttons.append(ui->fgButton); - buttons.append(ui->commentButton); - buttons.append(ui->tagButton); - buttons.append(ui->conditionalButton); - buttons.append(ui->escapedButton); - buttons.append(ui->errorButton); - - for(int i = 0; i < buttons.count(); i++) - QObject::connect(buttons[i], SIGNAL(pressed()), - this, SLOT(colorClicked())); -} - -void PreferencesDialog::colorClicked() -{ - QColor* toEdit = 0, newColor; - - if(QObject::sender() == ui->bgButton) - toEdit = &bgColor; - else if(QObject::sender() == ui->fgButton) - toEdit = &fgColor; - else if(QObject::sender() == ui->commentButton) - toEdit = &commentColor; - else if(QObject::sender() == ui->tagButton) - toEdit = &tagColor; - else if(QObject::sender() == ui->conditionalButton) - toEdit = &conditionalColor; - else if(QObject::sender() == ui->escapedButton) - toEdit = &escapedColor; - else if(QObject::sender() == ui->errorButton) - toEdit = &errorColor; - - if(!toEdit) - return; - - newColor = QColorDialog::getColor(*toEdit, this); - if (newColor.isValid()) - { - *toEdit = newColor; - setButtonColor(dynamic_cast(QObject::sender()), *toEdit); - } -} - -void PreferencesDialog::accept() -{ - saveSettings(); - QDialog::accept(); -} - -void PreferencesDialog::reject() -{ - loadSettings(); - QDialog::reject(); -} diff --git a/utils/themeeditor/preferencesdialog.h b/utils/themeeditor/preferencesdialog.h deleted file mode 100644 index e28a830..0000000 --- a/utils/themeeditor/preferencesdialog.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 PREFERENCESDIALOG_H -#define PREFERENCESDIALOG_H - -#include -#include - -namespace Ui { - class PreferencesDialog; -} - -class PreferencesDialog : public QDialog { - Q_OBJECT -public: - PreferencesDialog(QWidget *parent = 0); - ~PreferencesDialog(); - - static void setButtonColor(QPushButton* button, QColor color) - { - QString style = "* { background:" + color.name() + "}"; - button->setStyleSheet(style); - } - -public slots: - void accept(); - void reject(); - -private slots: - void colorClicked(); - -private: - Ui::PreferencesDialog *ui; - - void loadSettings(); - void loadColors(); - void loadFont(); - void saveSettings(); - void saveColors(); - void saveFont(); - - void setupUI(); - - QColor fgColor; - QColor bgColor; - QColor errorColor; - QColor commentColor; - QColor escapedColor; - QColor tagColor; - QColor conditionalColor; -}; - -#endif // PREFERENCESDIALOG_H diff --git a/utils/themeeditor/preferencesdialog.ui b/utils/themeeditor/preferencesdialog.ui deleted file mode 100644 index 1da7811..0000000 --- a/utils/themeeditor/preferencesdialog.ui +++ /dev/null @@ -1,306 +0,0 @@ - - - PreferencesDialog - - - - 0 - 0 - 370 - 370 - - - - Preferences - - - - - - QTabWidget::North - - - 0 - - - - Editor - - - - - - - - Font - - - - - - - - - - - - - - Size - - - - - - - 12 - - - - - - - - - - - Foreground Colour - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - fgButton - - - - - - - false - - - Click To Change - - - - - - - - - - - Background Colour - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - bgButton - - - - - - - false - - - Click To Change - - - - - - - - - - - Error Colour - - - errorButton - - - - - - - Click To Change - - - - - - - - - - Highlighting - - - - - - - - Comment - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - commentButton - - - - - - - false - - - Click To Change - - - false - - - - - - - - - - - Escaped Character - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - escapedButton - - - - - - - false - - - Click To Change - - - - - - - - - - - Conditional - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - conditionalButton - - - - - - - false - - - Click To Change - - - - - - - - - - - Tag - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - tagButton - - - - - - - false - - - Click To Change - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - PreferencesDialog - accept() - - - 257 - 360 - - - 157 - 274 - - - - - buttonBox - rejected() - PreferencesDialog - reject() - - - 325 - 360 - - - 286 - 274 - - - - - diff --git a/utils/themeeditor/projectmodel.cpp b/utils/themeeditor/projectmodel.cpp deleted file mode 100644 index 632e0aa..0000000 --- a/utils/themeeditor/projectmodel.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "projectmodel.h" -#include "editorwindow.h" - -#include -#include -#include -#include - -ProjectModel::ProjectModel(QString config, EditorWindow* mainWindow, - QObject *parent) - : QAbstractListModel(parent), - mainWindow(mainWindow) -{ - /* Reading the config file */ - QFile cfg(config); - cfg.open(QFile::ReadOnly | QFile::Text); - if(!cfg.isReadable()) - return; - - QTextStream fin(&cfg); - - /* Storing the base directory */ - QString confDir = config; - confDir.chop(confDir.length() - confDir.lastIndexOf('/') - 1); - QDir base(confDir); - base.cdUp(); - settings.insert("themebase", base.canonicalPath()); - - while(!fin.atEnd()) - { - QString current = fin.readLine(); - QList parts = current.split(':'); - - /* A valid setting has at least one : */ - if(parts.count() < 2) - continue; - - QString setting; - for(int i = 1; i < parts.count(); i++) - setting.append(parts[i].trimmed()); - - settings.insert(parts[0].trimmed(), setting); - } - - cfg.close(); - - /* Adding the files, starting with the .cfg */ - config.replace(base.canonicalPath() + "/", ""); - files.append(config); - - QList keys; - keys.append("wps"); - keys.append("rwps"); - keys.append("sbs"); - keys.append("rsbs"); - keys.append("fms"); - keys.append("rfms"); - - for(int i = 0; i < keys.count(); i++) - { - QString file = settings.value(keys[i], ""); - if(file != "" && file != "-") - { - file.replace("/.rockbox/", ""); - files.append(file); - } - } - - -} - -ProjectModel::~ProjectModel() -{ -} - -int ProjectModel::rowCount(const QModelIndex& parent) const -{ - return files.count(); -} - -QVariant ProjectModel::data(const QModelIndex &index, int role) const -{ - if(!index.isValid()) - return QVariant(); - - if(role != Qt::DisplayRole) - return QVariant(); - - return files[index.row()]; -} - -void ProjectModel::activated(const QModelIndex &index) -{ - if(index.row() == 0) - { - ConfigDocument* doc = new ConfigDocument(settings, - settings.value("themebase", - "") + "/" + - files[index.row()]); - QObject::connect(doc, SIGNAL(configFileChanged(QString)), - mainWindow, SLOT(configFileChanged(QString))); - mainWindow->loadConfigTab(doc); - } - else - { - mainWindow->loadTabFromSkinFile(settings.value("themebase", "") - + "/" + files[index.row()]); - } -} diff --git a/utils/themeeditor/projectmodel.h b/utils/themeeditor/projectmodel.h deleted file mode 100644 index 6623917..0000000 --- a/utils/themeeditor/projectmodel.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 PROJECTMODEL_H -#define PROJECTMODEL_H - -#include -#include - -class EditorWindow; - -class ProjectModel : public QAbstractListModel -{ -Q_OBJECT -public: - static const int numColumns = 2; - - static QString fileFilter() - { - return QObject::tr("Project Files (*.cfg);;All Files (*.*)"); - } - - ProjectModel(QString config, EditorWindow* mainWindow, QObject *parent = 0); - virtual ~ProjectModel(); - - int rowCount(const QModelIndex& parent) const; - QVariant data(const QModelIndex &index, int role) const; - - QString getSetting(QString key){ return settings.value(key, ""); } - -signals: - -public slots: - void activated(const QModelIndex& index); - -private: - EditorWindow* mainWindow; - QMap settings; - QList files; -}; - -#endif // PROJECTMODEL_H diff --git a/utils/themeeditor/skin_debug.c b/utils/themeeditor/skin_debug.c deleted file mode 100644 index 549f7b9..0000000 --- a/utils/themeeditor/skin_debug.c +++ /dev/null @@ -1,262 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 - -#include "skin_parser.h" -#include "skin_debug.h" -#include "tag_table.h" - -/* Global variables for debug output */ -int debug_indent_level = 0; -extern int skin_line; - -/* Global error variables */ -int error_line; -char* error_message; - -/* Debugging functions */ -void skin_error(enum skin_errorcode error) -{ - - error_line = skin_line; - - switch(error) - { - case MEMORY_LIMIT_EXCEEDED: - error_message = "Memory limit exceeded"; - break; - case NEWLINE_EXPECTED: - error_message = "Newline expected"; - break; - case ILLEGAL_TAG: - error_message = "Illegal tag"; - break; - case ARGLIST_EXPECTED: - error_message = "Argument list expected"; - break; - case TOO_MANY_ARGS: - error_message = "Too many arguments given"; - break; - case DEFAULT_NOT_ALLOWED: - error_message = "Argument can not be set to default"; - break; - case UNEXPECTED_NEWLINE: - error_message = "Unexpected newline"; - break; - case INSUFFICIENT_ARGS: - error_message = "Not enough arguments"; - break; - case INT_EXPECTED: - error_message = "Expected integer"; - break; - case SEPERATOR_EXPECTED: - error_message = "Expected argument seperator"; - break; - case CLOSE_EXPECTED: - error_message = "Expected list close"; - break; - case MULTILINE_EXPECTED: - error_message = "Expected subline seperator"; - break; - }; - -} - -int skin_error_line() -{ - return error_line; -} - -char* skin_error_message() -{ - return error_message; -} - -void skin_clear_errors() -{ - error_line = 0; - error_message = NULL; -} - -void skin_debug_tree(struct skin_element* root) -{ - int i; - char *text; - - struct skin_element* current = root; - - while(current) - { - skin_debug_indent(); - - switch(current->type) - { - case UNKNOWN: - printf("[ Unknown element.. error\n]"); - break; - - case VIEWPORT: - printf("[ Viewport \n"); - - debug_indent_level++; - skin_debug_tree(current->children[0]); - debug_indent_level--; - - printf("]"); - break; - - case TEXT: - text = current->data; - printf("[ Plain text on line %d : %s ]\n", current->line, text); - break; - - case COMMENT: - text = current->data; - printf("[ Comment on line %d: ", current->line); - for(i = 0; i < (int)strlen(text); i++) - { - if(text[i] == '\n') - printf("\\n"); - else - printf("%c", text[i]); - } - printf(" ]\n"); - break; - - case TAG: - printf("[ %s tag on line %d with %d arguments\n", - current->tag->name, - current->line, current->params_count); - debug_indent_level++; - skin_debug_params(current->params_count, current->params); - debug_indent_level--; - skin_debug_indent(); - printf("]\n"); - - break; - - case SUBLINES: - printf("[ Alternator on line %d with %d sublines \n", current->line, - current->children_count); - debug_indent_level++; - for(i = 0; i < current->children_count; i++) - { - skin_debug_tree(current->children[i]); - } - debug_indent_level--; - - skin_debug_indent(); - printf("]\n"); - break; - - case CONDITIONAL: - printf("[ Conditional tag on line %d with %d enumerations \n", - current->line, current->children_count - 1); - debug_indent_level++; - - skin_debug_indent(); - printf("[ Condition tag \n"); - debug_indent_level++; - skin_debug_tree(current->children[0]); - debug_indent_level--; - skin_debug_indent(); - printf("]\n"); - - for(i = 1; i < current->children_count; i++) - { - skin_debug_indent(); - printf("[ Enumeration %d\n", i - 1); - debug_indent_level++; - skin_debug_tree(current->children[i]); - debug_indent_level--; - skin_debug_indent(); - printf("]\n"); - } - - debug_indent_level--; - skin_debug_indent(); - printf("]\n"); - - - break; - - case LINE: - printf("[ Logical line on line %d\n", current->line); - - debug_indent_level++; - skin_debug_tree(current->children[0]); - debug_indent_level--; - - skin_debug_indent(); - printf("]\n"); - break; - } - - current = current->next; - } - -} - -void skin_debug_params(int count, struct skin_tag_parameter params[]) -{ - int i; - for(i = 0; i < count; i++) - { - - skin_debug_indent(); - switch(params[i].type) - { - case DEFAULT: - printf("[-]"); - break; - - case STRING: - printf("[%s]", params[i].data.text); - break; - - case NUMERIC: - printf("[%d]", params[i].data.numeric); - break; - - case CODE: - printf("[ WPS Code: \n"); - debug_indent_level++; - skin_debug_tree(params[i].data.code); - debug_indent_level--; - skin_debug_indent(); - printf("]"); - break; - } - - printf("\n"); - - } -} - -void skin_debug_indent() -{ - int i; - for(i = 0; i < debug_indent_level; i++) - printf(" "); -} diff --git a/utils/themeeditor/skin_debug.h b/utils/themeeditor/skin_debug.h deleted file mode 100644 index a550dc4..0000000 --- a/utils/themeeditor/skin_debug.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 SKIN_DEBUG_H -#define SKIN_DEBUG_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "skin_parser.h" - -/* Debugging functions */ -void skin_error(enum skin_errorcode error); -int skin_error_line(); -char* skin_error_message(); -void skin_clear_errors(); -void skin_debug_tree(struct skin_element* root); - -/* Auxiliary debug functions */ -void skin_debug_params(int count, struct skin_tag_parameter params[]); -void skin_debug_indent(); - -#ifdef __cplusplus -} -#endif - -#endif // SKIN_DEBUG_H diff --git a/utils/themeeditor/skin_parser.c b/utils/themeeditor/skin_parser.c deleted file mode 100644 index 93a7191..0000000 --- a/utils/themeeditor/skin_parser.c +++ /dev/null @@ -1,923 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 -#include - -#include "skin_parser.h" -#include "skin_debug.h" -#include "tag_table.h" -#include "symbols.h" -#include "skin_scan.h" - -#ifdef ROCKBOX -/* Declaration of parse tree buffer */ -#define SKIN_MAX_MEMORY (30*1024) -static char skin_parse_tree[SKIN_MAX_MEMORY]; -static char *skin_buffer; -#endif - -/* Global variables for the parser */ -int skin_line = 0; - -/* Auxiliary parsing functions (not visible at global scope) */ -static struct skin_element* skin_parse_viewport(char** document); -static struct skin_element* skin_parse_line(char** document); -static struct skin_element* skin_parse_line_optional(char** document, - int conditional); -static struct skin_element* skin_parse_sublines(char** document); -static struct skin_element* skin_parse_sublines_optional(char** document, - int conditional); - -static int skin_parse_tag(struct skin_element* element, char** document); -static int skin_parse_text(struct skin_element* element, char** document, - int conditional); -static int skin_parse_conditional(struct skin_element* element, - char** document); -static int skin_parse_comment(struct skin_element* element, char** document); -static struct skin_element* skin_parse_code_as_arg(char** document); - -struct skin_element* skin_parse(const char* document) -{ - - struct skin_element* root = NULL; - struct skin_element* last = NULL; - - struct skin_element** to_write = 0; - - char* cursor = (char*)document; /*Keeps track of location in the document*/ -#ifdef ROCKBOX - /* FIXME */ - skin_buffer = &skin_parse_tree[0]; -#endif - - skin_line = 1; - - skin_clear_errors(); - - while(*cursor != '\0') - { - - if(!root) - to_write = &root; - else - to_write = &(last->next); - - - *to_write = skin_parse_viewport(&cursor); - last = *to_write; - if(!last) - { - skin_free_tree(root); /* Clearing any memory already used */ - return NULL; - } - - /* Making sure last is at the end */ - while(last->next) - last = last->next; - - } - - return root; - -} - -static struct skin_element* skin_parse_viewport(char** document) -{ - - struct skin_element* root = NULL; - struct skin_element* last = NULL; - struct skin_element* retval = NULL; - - retval = skin_alloc_element(); - retval->type = VIEWPORT; - retval->children_count = 1; - retval->line = skin_line; - - struct skin_element** to_write = 0; - - char* cursor = *document; /* Keeps track of location in the document */ - char* bookmark; /* Used when we need to look ahead */ - - int sublines = 0; /* Flag for parsing sublines */ - - /* Parsing out the viewport tag if there is one */ - if(check_viewport(cursor)) - { - skin_parse_tag(retval, &cursor); - if(*cursor == '\n') - { - cursor++; - skin_line++; - } - } - - retval->children_count = 1; - retval->children = skin_alloc_children(1); - - - do - { - - /* First, we check to see if this line will contain sublines */ - bookmark = cursor; - sublines = 0; - while(*cursor != '\n' && *cursor != '\0' - && !(check_viewport(cursor) && cursor != *document)) - { - if(*cursor == MULTILINESYM) - { - sublines = 1; - break; - } - else if(*cursor == TAGSYM) - { - /* A ';' directly after a '%' doesn't count */ - cursor ++; - - if(*cursor == '\0') - break; - - cursor++; - } - else if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } - else - { - /* Advancing the cursor as normal */ - cursor++; - } - } - cursor = bookmark; - - if(!root) - to_write = &root; - else - to_write = &(last->next); - - if(sublines) - { - *to_write = skin_parse_sublines(&cursor); - last = *to_write; - if(!last) - return NULL; - } - else - { - - *to_write = skin_parse_line(&cursor); - last = *to_write; - if(!last) - return NULL; - - } - - /* Making sure last is at the end */ - while(last->next) - last = last->next; - - if(*cursor == '\n') - { - cursor++; - skin_line++; - } - } - while(*cursor != '\0' && !(check_viewport(cursor) && cursor != *document)); - - *document = cursor; - - retval->children[0] = root; - return retval; - -} - -/* Auxiliary Parsing Functions */ - -static struct skin_element* skin_parse_line(char**document) -{ - - return skin_parse_line_optional(document, 0); - -} - - -/* - * If conditional is set to true, then this will break upon encountering - * SEPERATESYM. This should only be used when parsing a line inside a - * conditional, otherwise just use the wrapper function skin_parse_line() - */ -static struct skin_element* skin_parse_line_optional(char** document, - int conditional) -{ - char* cursor = *document; - - struct skin_element* root = NULL; - struct skin_element* current = NULL; - struct skin_element* retval = NULL; - - /* A wrapper for the line */ - retval = skin_alloc_element(); - retval->type = LINE; - retval->line = skin_line; - if(*cursor != '\0' && *cursor != '\n' - && !(conditional && (*cursor == ARGLISTSEPERATESYM - || *cursor == ARGLISTCLOSESYM - || *cursor == ENUMLISTSEPERATESYM - || *cursor == ENUMLISTCLOSESYM))) - { - retval->children_count = 1; - } - else - { - retval->children_count = 0; - } - - if(retval->children_count > 0) - retval->children = skin_alloc_children(1); - - while(*cursor != '\n' && *cursor != '\0' && *cursor != MULTILINESYM - && !((*cursor == ARGLISTSEPERATESYM - || *cursor == ARGLISTCLOSESYM - || *cursor == ENUMLISTSEPERATESYM - || *cursor == ENUMLISTCLOSESYM) - && conditional) - && !(check_viewport(cursor) && cursor != *document)) - { - /* Allocating memory if necessary */ - if(root) - { - current->next = skin_alloc_element(); - current = current->next; - } - else - { - current = skin_alloc_element(); - root = current; - } - - /* Parsing the current element */ - if(*cursor == TAGSYM && cursor[1] == CONDITIONSYM) - { - if(!skin_parse_conditional(current, &cursor)) - return NULL; - } - else if(*cursor == TAGSYM && !find_escape_character(cursor[1])) - { - if(!skin_parse_tag(current, &cursor)) - return NULL; - } - else if(*cursor == COMMENTSYM) - { - if(!skin_parse_comment(current, &cursor)) - return NULL; - } - else - { - if(!skin_parse_text(current, &cursor, conditional)) - return NULL; - } - } - - /* Moving up the calling function's pointer */ - *document = cursor; - - if(root) - retval->children[0] = root; - return retval; -} - -static struct skin_element* skin_parse_sublines(char** document) -{ - return skin_parse_sublines_optional(document, 0); -} - -static struct skin_element* skin_parse_sublines_optional(char** document, - int conditional) -{ - struct skin_element* retval; - char* cursor = *document; - int sublines = 1; - int i; - - retval = skin_alloc_element(); - retval->type = SUBLINES; - retval->next = NULL; - retval->line = skin_line; - - /* First we count the sublines */ - while(*cursor != '\0' && *cursor != '\n' - && !((*cursor == ARGLISTSEPERATESYM - || *cursor == ARGLISTCLOSESYM - || *cursor == ENUMLISTSEPERATESYM - || *cursor == ENUMLISTCLOSESYM) - && conditional) - && !(check_viewport(cursor) && cursor != *document)) - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == TAGSYM) - { - cursor++; - if(*cursor == '\0' || *cursor == '\n') - break; - cursor++; - } - else if(*cursor == MULTILINESYM) - { - sublines++; - cursor++; - } - else - { - cursor++; - } - } - - /* ...and then we parse them */ - retval->children_count = sublines; - retval->children = skin_alloc_children(sublines); - - cursor = *document; - for(i = 0; i < sublines; i++) - { - retval->children[i] = skin_parse_line_optional(&cursor, conditional); - skip_whitespace(&cursor); - - if(*cursor != MULTILINESYM && i != sublines - 1) - { - skin_error(MULTILINE_EXPECTED); - return NULL; - } - else if(i != sublines - 1) - { - cursor++; - } - } - - *document = cursor; - - return retval; -} - -static int skin_parse_tag(struct skin_element* element, char** document) -{ - - char* cursor = *document + 1; - char* bookmark; - - char tag_name[3]; - char* tag_args; - struct tag_info *tag; - - int num_args = 1; - int i; - int star = 0; /* Flag for the all-or-none option */ - int req_args; /* To mark when we enter optional arguments */ - - int optional = 0; - - /* Checking the tag name */ - tag_name[0] = cursor[0]; - tag_name[1] = cursor[1]; - tag_name[2] = '\0'; - - /* First we check the two characters after the '%', then a single char */ - tag = find_tag(tag_name); - - if(!tag) - { - tag_name[1] = '\0'; - tag = find_tag(tag_name); - cursor++; - } - else - { - cursor += 2; - } - - if(!tag) - { - skin_error(ILLEGAL_TAG); - return 0; - } - - /* Copying basic tag info */ - if(element->type != CONDITIONAL && element->type != VIEWPORT) - element->type = TAG; - element->tag = tag; - tag_args = tag->params; - element->line = skin_line; - - /* Checking for the * flag */ - if(tag_args[0] == '*') - { - star = 1; - tag_args++; - } - - /* If this tag has no arguments, we can bail out now */ - if(strlen(tag_args) == 0 - || (tag_args[0] == '|' && *cursor != ARGLISTOPENSYM) - || (star && *cursor != ARGLISTOPENSYM)) - { - *document = cursor; - return 1; - } - - /* Checking the number of arguments and allocating args */ - if(*cursor != ARGLISTOPENSYM && tag_args[0] != '|') - { - skin_error(ARGLIST_EXPECTED); - return 0; - } - else - { - cursor++; - } - - bookmark = cursor; - while(*cursor != '\n' && *cursor != '\0' && *cursor != ARGLISTCLOSESYM) - { - /* Skipping over escaped characters */ - if(*cursor == TAGSYM) - { - cursor++; - if(*cursor == '\0') - break; - cursor++; - } - else if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == ARGLISTSEPERATESYM) - { - num_args++; - cursor++; - } - else - { - cursor++; - } - } - - cursor = bookmark; /* Restoring the cursor */ - element->params_count = num_args; - element->params = skin_alloc_params(num_args); - - /* Now we have to actually parse each argument */ - for(i = 0; i < num_args; i++) - { - /* Making sure we haven't run out of arguments */ - if(*tag_args == '\0') - { - skin_error(TOO_MANY_ARGS); - return 0; - } - - /* Checking for the optional bar */ - if(*tag_args == '|') - { - optional = 1; - req_args = i; - tag_args++; - } - - /* Scanning the arguments */ - skip_whitespace(&cursor); - - - /* Checking for comments */ - if(*cursor == COMMENTSYM) - skip_comment(&cursor); - - /* Storing the type code */ - element->params[i].type_code = *tag_args; - - /* Checking a nullable argument for null */ - if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) - { - if(islower(*tag_args)) - { - element->params[i].type = DEFAULT; - cursor++; - } - else - { - skin_error(DEFAULT_NOT_ALLOWED); - return 0; - } - } - else if(tolower(*tag_args) == 'i') - { - /* Scanning an int argument */ - if(!isdigit(*cursor) && *cursor != '-') - { - skin_error(INT_EXPECTED); - return 0; - } - - element->params[i].type = NUMERIC; - element->params[i].data.numeric = scan_int(&cursor); - } - else if(tolower(*tag_args) == 'n' || - tolower(*tag_args) == 's' || tolower(*tag_args) == 'f') - { - /* Scanning a string argument */ - element->params[i].type = STRING; - element->params[i].data.text = scan_string(&cursor); - - } - else if(tolower(*tag_args) == 'c') - { - /* Recursively parsing a code argument */ - element->params[i].type = CODE; - element->params[i].data.code = skin_parse_code_as_arg(&cursor); - if(!element->params[i].data.code) - return 0; - } - - skip_whitespace(&cursor); - - if(*cursor != ARGLISTSEPERATESYM && i < num_args - 1) - { - skin_error(SEPERATOR_EXPECTED); - return 0; - } - else if(*cursor != ARGLISTCLOSESYM && i == num_args - 1) - { - skin_error(CLOSE_EXPECTED); - return 0; - } - else - { - cursor++; - } - - if (*tag_args != 'N') - tag_args++; - - /* Checking for the optional bar */ - if(*tag_args == '|') - { - optional = 1; - req_args = i + 1; - tag_args++; - } - - } - - /* Checking for a premature end */ - if(*tag_args != '\0' && !optional) - { - skin_error(INSUFFICIENT_ARGS); - return 0; - } - - *document = cursor; - - return 1; -} - -/* - * If the conditional flag is set true, then parsing text will stop at an - * ARGLISTSEPERATESYM. Only set that flag when parsing within a conditional - */ -static int skin_parse_text(struct skin_element* element, char** document, - int conditional) -{ - char* cursor = *document; - int length = 0; - int dest; - char *text = NULL; - - /* First figure out how much text we're copying */ - while(*cursor != '\0' && *cursor != '\n' && *cursor != MULTILINESYM - && *cursor != COMMENTSYM - && !((*cursor == ARGLISTSEPERATESYM - || *cursor == ARGLISTCLOSESYM - || *cursor == ENUMLISTSEPERATESYM - || *cursor == ENUMLISTCLOSESYM) - && conditional)) - { - /* Dealing with possibility of escaped characters */ - if(*cursor == TAGSYM) - { - if(find_escape_character(cursor[1])) - cursor++; - else - break; - } - - length++; - cursor++; - } - - cursor = *document; - - /* Copying the text into the element struct */ - element->type = TEXT; - element->line = skin_line; - element->next = NULL; - element->data = text = skin_alloc_string(length); - - for(dest = 0; dest < length; dest++) - { - /* Advancing cursor if we've encountered an escaped character */ - if(*cursor == TAGSYM) - cursor++; - - text[dest] = *cursor; - cursor++; - } - text[length] = '\0'; - - *document = cursor; - - return 1; -} - -static int skin_parse_conditional(struct skin_element* element, char** document) -{ - - char* cursor = *document + 1; /* Starting past the "%" */ - char* bookmark; - int children = 1; - int i; - - element->type = CONDITIONAL; - element->line = skin_line; - - /* Parsing the tag first */ - if(!skin_parse_tag(element, &cursor)) - return 0; - - /* Counting the children */ - if(*(cursor++) != ENUMLISTOPENSYM) - { - skin_error(ARGLIST_EXPECTED); - return 0; - } - bookmark = cursor; - while(*cursor != ENUMLISTCLOSESYM && *cursor != '\n' && *cursor != '\0') - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } - else if(*cursor == TAGSYM) - { - cursor++; - if(*cursor == '\0' || *cursor == '\n') - break; - cursor++; - } - else if(*cursor == ENUMLISTSEPERATESYM) - { - children++; - cursor++; - } - else - { - cursor++; - } - } - cursor = bookmark; - - /* Parsing the children */ - element->children = skin_alloc_children(children); - element->children_count = children; - - for(i = 0; i < children; i++) - { - element->children[i] = skin_parse_code_as_arg(&cursor); - skip_whitespace(&cursor); - - if(i < children - 1 && *cursor != ENUMLISTSEPERATESYM) - { - skin_error(SEPERATOR_EXPECTED); - return 0; - } - else if(i == children - 1 && *cursor != ENUMLISTCLOSESYM) - { - skin_error(CLOSE_EXPECTED); - return 0; - } - else - { - cursor++; - } - } - - *document = cursor; - - return 1; -} - -static int skin_parse_comment(struct skin_element* element, char** document) -{ - char* cursor = *document; - char* text = NULL; - - int length; - /* - * Finding the index of the ending newline or null-terminator - * The length of the string of interest doesn't include the leading #, the - * length we need to reserve is the same as the index of the last character - */ - for(length = 0; cursor[length] != '\n' && cursor[length] != '\0'; length++); - - element->type = COMMENT; - element->line = skin_line; -#ifdef ROCKBOX - element->data = NULL; -#else - element->data = text = skin_alloc_string(length); - /* We copy from one char past cursor to leave out the # */ - memcpy((void*)text, (void*)(cursor + 1), - sizeof(char) * (length-1)); - text[length - 1] = '\0'; -#endif - if(cursor[length] == '\n') - skin_line++; - - *document += (length); /* Move cursor up past # and all text */ - if(**document == '\n') - (*document)++; - - return 1; -} - -static struct skin_element* skin_parse_code_as_arg(char** document) -{ - - int sublines = 0; - char* cursor = *document; - - /* Checking for sublines */ - while(*cursor != '\n' && *cursor != '\0' - && *cursor != ENUMLISTSEPERATESYM && *cursor != ARGLISTSEPERATESYM - && *cursor != ENUMLISTCLOSESYM && *cursor != ARGLISTCLOSESYM) - { - if(*cursor == MULTILINESYM) - { - sublines = 1; - break; - } - else if(*cursor == TAGSYM) - { - /* A ';' directly after a '%' doesn't count */ - cursor ++; - - if(*cursor == '\0') - break; - - cursor++; - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } - else - { - /* Advancing the cursor as normal */ - cursor++; - } - } - - if(sublines) - return skin_parse_sublines_optional(document, 1); - else - return skin_parse_line_optional(document, 1); -} - - -/* Memory management */ -char* skin_alloc(size_t size) -{ -#ifdef ROCKBOX - char *retval = skin_buffer; - skin_buffer = (void *)(((unsigned long)skin_buffer + 3) & ~3); - return retval; -#else - return malloc(size); -#endif -} - -struct skin_element* skin_alloc_element() -{ - struct skin_element* retval = (struct skin_element*) - skin_alloc(sizeof(struct skin_element)); - retval->type = UNKNOWN; - retval->next = NULL; - retval->tag = NULL; - retval->params_count = 0; - retval->children_count = 0; - - return retval; - -} - -struct skin_tag_parameter* skin_alloc_params(int count) -{ - size_t size = sizeof(struct skin_tag_parameter) * count; - return (struct skin_tag_parameter*)skin_alloc(size); - -} - -char* skin_alloc_string(int length) -{ - return (char*)skin_alloc(sizeof(char) * (length + 1)); -} - -struct skin_element** skin_alloc_children(int count) -{ - return (struct skin_element**) - skin_alloc(sizeof(struct skin_element*) * count); -} - -void skin_free_tree(struct skin_element* root) -{ -#ifndef ROCKBOX - int i; - - /* First make the recursive call */ - if(!root) - return; - skin_free_tree(root->next); - - /* Free any text */ - if(root->type == TEXT || root->type == COMMENT) - free(root->data); - - /* Then recursively free any children, before freeing their pointers */ - for(i = 0; i < root->children_count; i++) - skin_free_tree(root->children[i]); - if(root->children_count > 0) - free(root->children); - - /* Free any parameters, making sure to deallocate strings */ - for(i = 0; i < root->params_count; i++) - if(root->params[i].type == STRING) - free(root->params[i].data.text); - if(root->params_count > 0) - free(root->params); - - /* Finally, delete root's memory */ - free(root); -#else - (void)root; -#endif -} diff --git a/utils/themeeditor/skin_parser.h b/utils/themeeditor/skin_parser.h deleted file mode 100644 index 1fc4a7a..0000000 --- a/utils/themeeditor/skin_parser.h +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 GENERIC_PARSER_H -#define GENERIC_PARSER_H - -#ifdef __cplusplus -extern "C" -{ -#endif -#include - -/******************************************************************** - ****** Data Structures ********************************************* - *******************************************************************/ - -/* Possible types of element in a WPS file */ -enum skin_element_type -{ - UNKNOWN = -1, - VIEWPORT, - LINE, - SUBLINES, - CONDITIONAL, - TAG, - TEXT, - COMMENT, -}; - -enum skin_errorcode -{ - MEMORY_LIMIT_EXCEEDED, - NEWLINE_EXPECTED, - ILLEGAL_TAG, - ARGLIST_EXPECTED, - TOO_MANY_ARGS, - DEFAULT_NOT_ALLOWED, - UNEXPECTED_NEWLINE, - INSUFFICIENT_ARGS, - INT_EXPECTED, - SEPERATOR_EXPECTED, - CLOSE_EXPECTED, - MULTILINE_EXPECTED -}; - -/* Holds a tag parameter, either numeric or text */ -struct skin_tag_parameter -{ - enum - { - NUMERIC, - STRING, - CODE, - DEFAULT - } type; - - union - { - int numeric; - char* text; - struct skin_element* code; - } data; - - char type_code; - -}; - -/* Defines an element of a SKIN file */ -struct skin_element -{ - /* Defines what type of element it is */ - enum skin_element_type type; - - /* The line on which it's defined in the source file */ - int line; - - /* Placeholder for element data - * TEXT and COMMENT uses it for the text string - * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage - */ - void* data; - - /* The tag or conditional name */ - struct tag_info *tag; - - /* Pointer to and size of an array of parameters */ - int params_count; - struct skin_tag_parameter* params; - - /* Pointer to and size of an array of children */ - int children_count; - struct skin_element** children; - - /* Link to the next element */ - struct skin_element* next; -}; - -/*********************************************************************** - ***** Functions ******************************************************* - **********************************************************************/ - -/* Parses a WPS document and returns a list of skin_element - structures. */ -struct skin_element* skin_parse(const char* document); - -/* Memory management functions */ -char *skin_alloc(size_t size); -struct skin_element* skin_alloc_element(); -struct skin_element** skin_alloc_children(int count); -struct skin_tag_parameter* skin_alloc_params(int count); -char* skin_alloc_string(int length); - -void skin_free_tree(struct skin_element* root); - - -#ifdef __cplusplus -} -#endif - -#endif /* GENERIC_PARSER_H */ diff --git a/utils/themeeditor/skin_scan.c b/utils/themeeditor/skin_scan.c deleted file mode 100644 index 79f7162..0000000 --- a/utils/themeeditor/skin_scan.c +++ /dev/null @@ -1,218 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 -#include - -#include "skin_scan.h" -#include "skin_debug.h" -#include "symbols.h" -#include "skin_parser.h" - -/* Scanning Functions */ - -/* Simple function to advance a char* past a comment */ -void skip_comment(char** document) -{ - while(**document != '\n' && **document != '\0') - (*document)++; - if(**document == '\n') - (*document)++; -} - -void skip_whitespace(char** document) -{ - while(**document == ' ' || **document == '\t') - (*document)++; -} - -void skip_arglist(char** document) -{ - if(**document == ARGLISTOPENSYM) - (*document)++; - while(**document && **document != ARGLISTCLOSESYM) - { - if(**document == TAGSYM) - { - (*document)++; - if(**document == '\0') - break; - (*document)++; - } - else if(**document == ARGLISTOPENSYM) - skip_arglist(document); - else if(**document == ENUMLISTOPENSYM) - skip_enumlist(document); - else if(**document == COMMENTSYM) - skip_comment(document); - else - (*document)++; - } - if(**document == ARGLISTCLOSESYM) - (*document)++; -} - -void skip_enumlist(char** document) -{ - if(**document == ENUMLISTOPENSYM) - (*document)++; - while(**document && **document != ENUMLISTCLOSESYM) - { - if(**document == TAGSYM) - { - (*document)++; - if(**document == '\0') - break; - (*document)++; - } - else if(**document == ARGLISTOPENSYM) - skip_arglist(document); - else if(**document == ENUMLISTOPENSYM) - skip_enumlist(document); - else if(**document == COMMENTSYM) - skip_comment(document); - else - (*document)++; - } - - if(**document == ENUMLISTCLOSESYM) - (*document)++; -} - -char* scan_string(char** document) -{ - - char* cursor = *document; - int length = 0; - char* buffer = NULL; - int i; - - while(*cursor != ARGLISTSEPERATESYM && *cursor != ARGLISTCLOSESYM && - *cursor != '\0') - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - continue; - } - - if(*cursor == TAGSYM) - cursor++; - - if(*cursor == '\n') - { - skin_error(UNEXPECTED_NEWLINE); - return NULL; - } - - length++; - cursor++; - } - - /* Copying the string */ - cursor = *document; - buffer = skin_alloc_string(length); - buffer[length] = '\0'; - for(i = 0; i < length; i++) - { - if(*cursor == TAGSYM) - cursor++; - - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - i--; - continue; - } - - buffer[i] = *cursor; - cursor++; - } - - *document = cursor; - return buffer; -} - -int scan_int(char** document) -{ - - char* cursor = *document, *end; - int length = 0; - char buffer[16]; - int retval; - int i; - - while(isdigit(*cursor) || *cursor == COMMENTSYM || *cursor == '-') - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - continue; - } - - length++; - cursor++; - } - if (length > 15) - length = 15; - end = cursor; - /* Copying to the buffer while avoiding comments */ - cursor = *document; - buffer[length] = '\0'; - for(i = 0; i < length; i++) - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - i--; - continue; - } - - buffer[i] = *cursor; - cursor++; - - } - retval = atoi(buffer); - - *document = end; - return retval; -} - -int check_viewport(char* document) -{ - if(strlen(document) < 3) - return 0; - - if(document[0] != TAGSYM) - return 0; - - if(document[1] != 'V') - return 0; - - if(document[2] != ARGLISTOPENSYM - && document[2] != 'l' - && document[2] != 'i') - return 0; - - return 1; -} diff --git a/utils/themeeditor/skin_scan.h b/utils/themeeditor/skin_scan.h deleted file mode 100644 index b1d04a6..0000000 --- a/utils/themeeditor/skin_scan.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 SCANNING_H -#define SCANNING_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - -/* Scanning functions */ -void skip_comment(char** document); -void skip_whitespace(char** document); -void skip_arglist(char** document); -void skip_enumlist(char** document); -char* scan_string(char** document); -int scan_int(char** document); -int check_viewport(char* document); /* Checks for a viewport declaration */ - -#ifdef __cplusplus -} -#endif - -#endif // SCANNING_H diff --git a/utils/themeeditor/skindocument.cpp b/utils/themeeditor/skindocument.cpp deleted file mode 100644 index 82c7106..0000000 --- a/utils/themeeditor/skindocument.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * This program is free software; 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 optiyouon) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "skindocument.h" - -#include -#include -#include -#include -#include - -#include - -SkinDocument::SkinDocument(QLabel* statusLabel, QWidget *parent) : - TabContent(parent), statusLabel(statusLabel) -{ - setupUI(); - - titleText = "Untitled"; - fileName = ""; - saved = ""; - parseStatus = tr("Empty document"); - blockUpdate = false; -} - -SkinDocument::SkinDocument(QLabel* statusLabel, QString file, QWidget *parent): - TabContent(parent), fileName(file), statusLabel(statusLabel) -{ - setupUI(); - blockUpdate = false; - - /* Loading the file */ - if(QFile::exists(fileName)) - { - QFile fin(fileName); - fin.open(QFile::ReadOnly); - editor->document()->setPlainText(QString(fin.readAll())); - saved = editor->document()->toPlainText(); - editor->setTextCursor(QTextCursor(editor->document()->begin())); - fin.close(); - } - - /* Setting the title */ - QStringList decomposed = fileName.split('/'); - titleText = decomposed.last(); -} - -SkinDocument::~SkinDocument() -{ - delete highlighter; - delete model; -} - -void SkinDocument::connectPrefs(PreferencesDialog* prefs) -{ - QObject::connect(prefs, SIGNAL(accepted()), - this, SLOT(settingsChanged())); - QObject::connect(prefs, SIGNAL(accepted()), - highlighter, SLOT(loadSettings())); -} - -bool SkinDocument::requestClose() -{ - /* Storing the response in blockUpdate will also block updates to the - status bar if the tab is being closed */ - if(editor->document()->toPlainText() != saved) - { - /* Spawning the "Are you sure?" dialog */ - QMessageBox confirm(this); - confirm.setWindowTitle(tr("Confirm Close")); - confirm.setText(titleText + tr(" has been modified.")); - confirm.setInformativeText(tr("Do you want to save your changes?")); - confirm.setStandardButtons(QMessageBox::Save | QMessageBox::Discard - | QMessageBox::Cancel); - confirm.setDefaultButton(QMessageBox::Save); - int confirmation = confirm.exec(); - - switch(confirmation) - { - case QMessageBox::Save: - save(); - /* After calling save, make sure the user actually went through */ - if(editor->document()->toPlainText() != saved) - blockUpdate = false; - else - blockUpdate = true; - break; - - case QMessageBox::Discard: - blockUpdate = true; - break; - - case QMessageBox::Cancel: - blockUpdate = false; - break; - } - } - else - blockUpdate = true; - - return blockUpdate; -} - -void SkinDocument::setupUI() -{ - /* Setting up the text edit */ - layout = new QHBoxLayout; - editor = new CodeEditor(this); - editor->setLineWrapMode(QPlainTextEdit::NoWrap); - layout->addWidget(editor); - - setLayout(layout); - - /* Attaching the syntax highlighter */ - highlighter = new SkinHighlighter(editor->document()); - - /* Setting up the model */ - model = new ParseTreeModel(""); - - /* Connecting the editor's signal */ - QObject::connect(editor, SIGNAL(textChanged()), - this, SLOT(codeChanged())); - QObject::connect(editor, SIGNAL(cursorPositionChanged()), - this, SLOT(cursorChanged())); - - settingsChanged(); -} - -void SkinDocument::settingsChanged() -{ - /* Setting the editor colors */ - QSettings settings; - settings.beginGroup("SkinDocument"); - - QColor fg = settings.value("fgColor", Qt::black).value(); - QColor bg = settings.value("bgColor", Qt::white).value(); - QPalette palette; - palette.setColor(QPalette::All, QPalette::Base, bg); - palette.setColor(QPalette::All, QPalette::Text, fg); - editor->setPalette(palette); - - QColor highlight = settings.value("errorColor", Qt::red).value(); - editor->setErrorColor(highlight); - - /* Setting the font */ - QFont def("Monospace"); - def.setStyleHint(QFont::TypeWriter); - QFont family = settings.value("fontFamily", def).value(); - family.setPointSize(settings.value("fontSize", 12).toInt()); - editor->setFont(family); - - editor->repaint(); - - settings.endGroup(); - -} - -void SkinDocument::cursorChanged() -{ - if(editor->isError(editor->textCursor().blockNumber() + 1)) - { - QTextCursor line = editor->textCursor(); - line.movePosition(QTextCursor::StartOfLine); - line.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); - skin_parse(line.selectedText().toAscii()); - if(skin_error_line() > 0) - parseStatus = tr("Error on line ") + - QString::number(line.blockNumber() + 1) + tr(": ") + - skin_error_message(); - statusLabel->setText(parseStatus); - } - else if(editor->hasErrors()) - { - parseStatus = tr("Errors in document"); - statusLabel->setText(parseStatus); - } - else - { - emit lineChanged(editor->textCursor().blockNumber() + 1); - } - -} - -void SkinDocument::codeChanged() -{ - if(blockUpdate) - return; - - if(editor->document()->isEmpty()) - { - parseStatus = tr("Empty document"); - statusLabel->setText(parseStatus); - return; - } - - editor->clearErrors(); - parseStatus = model->changeTree(editor->document()-> - toPlainText().toAscii()); - if(skin_error_line() > 0) - parseStatus = tr("Errors in document"); - statusLabel->setText(parseStatus); - - /* Highlighting if an error was found */ - if(skin_error_line() > 0) - { - editor->addError(skin_error_line()); - - /* Now we're going to attempt parsing again at each line, until we find - one that won't error out*/ - QTextDocument doc(editor->document()->toPlainText()); - int base = 0; - while(skin_error_line() > 0 && !doc.isEmpty()) - { - QTextCursor rest(&doc); - - for(int i = 0; i < skin_error_line(); i++) - rest.movePosition(QTextCursor::NextBlock, - QTextCursor::KeepAnchor); - if(skin_error_line() == doc.blockCount()) - rest.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); - - rest.removeSelectedText(); - base += skin_error_line(); - - skin_parse(doc.toPlainText().toAscii()); - - if(skin_error_line() > 0) - editor->addError(base + skin_error_line()); - - } - } - - if(editor->document()->toPlainText() != saved) - emit titleChanged(titleText + QChar('*')); - else - emit titleChanged(titleText); - - cursorChanged(); - -} - -void SkinDocument::save() -{ - QFile fout(fileName); - - if(!fout.exists()) - { - saveAs(); - return; - } - - fout.open(QFile::WriteOnly); - fout.write(editor->document()->toPlainText().toAscii()); - fout.close(); - - saved = editor->document()->toPlainText(); - QStringList decompose = fileName.split('/'); - titleText = decompose.last(); - emit titleChanged(titleText); - -} - -void SkinDocument::saveAs() -{ - /* Determining the directory to open */ - QString directory = fileName; - - QSettings settings; - settings.beginGroup("SkinDocument"); - if(directory == "") - directory = settings.value("defaultDirectory", "").toString(); - - fileName = QFileDialog::getSaveFileName(this, tr("Save Document"), - directory, fileFilter()); - directory = fileName; - if(fileName == "") - return; - - directory.chop(fileName.length() - fileName.lastIndexOf('/') - 1); - settings.setValue("defaultDirectory", directory); - settings.endGroup(); - - QFile fout(fileName); - fout.open(QFile::WriteOnly); - fout.write(editor->document()->toPlainText().toAscii()); - fout.close(); - - saved = editor->document()->toPlainText(); - QStringList decompose = fileName.split('/'); - titleText = decompose[decompose.count() - 1]; - emit titleChanged(titleText); - -} diff --git a/utils/themeeditor/skindocument.h b/utils/themeeditor/skindocument.h deleted file mode 100644 index c6449ca..0000000 --- a/utils/themeeditor/skindocument.h +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 SKINDOCUMENT_H -#define SKINDOCUMENT_H - -#include -#include -#include - -#include "skinhighlighter.h" -#include "parsetreemodel.h" -#include "preferencesdialog.h" -#include "codeeditor.h" -#include "tabcontent.h" - -class SkinDocument : public TabContent -{ -Q_OBJECT -public: - static QString fileFilter() - { - return tr("WPS Files (*.wps *.rwps);;" - "SBS Files (*.sbs *.rsbs);;" - "FMS Files (*.fms *.rfms);;" - "All Skin Files (*.wps *.rwps *.sbs " - "*.rsbs *.fms *.rfms);;" - "All Files (*.*)"); - } - - SkinDocument(QLabel* statusLabel, QWidget *parent = 0); - SkinDocument(QLabel* statusLabel, QString file, QWidget* parent = 0); - virtual ~SkinDocument(); - - void connectPrefs(PreferencesDialog* prefs); - - ParseTreeModel* getModel(){ return model; } - QString file() const{ return fileName; } - QString title() const{ return titleText; } - QString getStatus(){ return parseStatus; } - void genCode(){ editor->document()->setPlainText(model->genCode()); } - - void save(); - void saveAs(); - - bool requestClose(); - - TabType type() const{ return Skin; } - -signals: - -public slots: - void settingsChanged(); - void cursorChanged(); - -private slots: - void codeChanged(); - -private: - void setupUI(); - - QString titleText; - QString fileName; - QString saved; - QString parseStatus; - - QLayout* layout; - CodeEditor* editor; - - SkinHighlighter* highlighter; - ParseTreeModel* model; - - QLabel* statusLabel; - - bool blockUpdate; -}; - -#endif // SKINDOCUMENT_H diff --git a/utils/themeeditor/skinhighlighter.cpp b/utils/themeeditor/skinhighlighter.cpp deleted file mode 100644 index 25a479f..0000000 --- a/utils/themeeditor/skinhighlighter.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "skinhighlighter.h" - -#include - -SkinHighlighter::SkinHighlighter(QTextDocument* doc) - :QSyntaxHighlighter(doc) -{ - loadSettings(); -} - -SkinHighlighter::~SkinHighlighter() -{ - -} - -void SkinHighlighter::highlightBlock(const QString& text) -{ - for(int i = 0; i < text.length(); i++) - { - QChar c = text[i]; - - /* Checking for delimiters */ - if(c == ARGLISTOPENSYM - || c == ARGLISTCLOSESYM - || c == ARGLISTSEPERATESYM) - setFormat(i, 1, tag); - - if(c == ENUMLISTOPENSYM - || c == ENUMLISTCLOSESYM - || c == ENUMLISTSEPERATESYM) - setFormat(i, 1, conditional); - - /* Checking for comments */ - if(c == COMMENTSYM) - { - setFormat(i, text.length() - i, comment); - return; - } - - if(c == TAGSYM) - { - if(text.length() - i < 2) - return; - - if(find_escape_character(text[i + 1].toAscii())) - { - /* Checking for escaped characters */ - - setFormat(i, 2, escaped); - i++; - } - else if(text[i + 1] != CONDITIONSYM) - { - /* Checking for normal tags */ - - char lookup[3]; - struct tag_info* found = 0; - - /* First checking for a two-character tag name */ - lookup[2] = '\0'; - - if(text.length() - i >= 3) - { - lookup[0] = text[i + 1].toAscii(); - lookup[1] = text[i + 2].toAscii(); - - found = find_tag(lookup); - } - - if(found) - { - setFormat(i, 3, tag); - i += 2; - } - else - { - lookup[1] = '\0'; - lookup[0] = text[i + 1].toAscii(); - found = find_tag(lookup); - - if(found) - { - setFormat(i, 2, tag); - i++; - } - } - - } - else if(text[i + 1] == CONDITIONSYM) - { - /* Checking for conditional tags */ - - if(text.length() - i < 3) - return; - - char lookup[3]; - struct tag_info* found = 0; - - lookup[2] = '\0'; - - if(text.length() - i >= 4) - { - lookup[0] = text[i + 2].toAscii(); - lookup[1] = text[i + 3].toAscii(); - - found = find_tag(lookup); - } - - if(found) - { - setFormat(i, 4, conditional); - i += 3; - } - else - { - lookup[1] = '\0'; - lookup[0] = text[i + 2].toAscii(); - - found = find_tag(lookup); - - if(found) - { - setFormat(i, 3, conditional); - i += 2; - } - } - - } - } - } -} - -void SkinHighlighter::loadSettings() -{ - QSettings settings; - - settings.beginGroup("SkinHighlighter"); - - /* Loading the highlighting colors */ - tag = settings.value("tagColor", QColor(180,0,0)).value(); - conditional = settings.value("conditionalColor", - QColor(0, 0, 180)).value(); - escaped = settings.value("escapedColor", - QColor(120,120,120)).value(); - comment = settings.value("commentColor", - QColor(0, 180, 0)).value(); - - settings.endGroup(); - - rehighlight(); -} diff --git a/utils/themeeditor/skinhighlighter.h b/utils/themeeditor/skinhighlighter.h deleted file mode 100644 index 4d5c68b..0000000 --- a/utils/themeeditor/skinhighlighter.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 SKINHIGHLIGHTER_H -#define SKINHIGHLIGHTER_H - -#include -#include - -#include "tag_table.h" -#include "symbols.h" - -class SkinHighlighter : public QSyntaxHighlighter -{ -Q_OBJECT -public: - /* - * font - The font used for all text - * normal - The normal text color - * escaped - The color for escaped characters - * tag - The color for tags and their delimiters - * conditional - The color for conditionals and their delimiters - * - */ - SkinHighlighter(QTextDocument* doc); - virtual ~SkinHighlighter(); - - void highlightBlock(const QString& text); - -public slots: - void loadSettings(); - -private: - QColor escaped; - QColor tag; - QColor conditional; - QColor comment; - -}; - -#endif // SKINHIGHLIGHTER_H diff --git a/utils/themeeditor/skinviewer.cpp b/utils/themeeditor/skinviewer.cpp deleted file mode 100644 index 152450e..0000000 --- a/utils/themeeditor/skinviewer.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "skinviewer.h" -#include "ui_skinviewer.h" - -SkinViewer::SkinViewer(QWidget *parent) : - QWidget(parent), - ui(new Ui::SkinViewer) -{ - ui->setupUi(this); - - QObject::connect(ui->zoomOutButton, SIGNAL(pressed()), - this, SLOT(zoomOut())); - QObject::connect(ui->zoomInButton, SIGNAL(pressed()), - this, SLOT(zoomIn())); -} - -SkinViewer::~SkinViewer() -{ - delete ui; -} - -void SkinViewer::changeEvent(QEvent *e) -{ - QWidget::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - ui->retranslateUi(this); - break; - default: - break; - } -} - -void SkinViewer::setScene(QGraphicsScene *scene) -{ - ui->viewer->setScene(scene); -} - -void SkinViewer::zoomIn() -{ - ui->viewer->scale(1.2, 1.2); -} - -void SkinViewer::zoomOut() -{ - ui->viewer->scale(1/1.2, 1/1.2); -} diff --git a/utils/themeeditor/skinviewer.h b/utils/themeeditor/skinviewer.h deleted file mode 100644 index 599a204..0000000 --- a/utils/themeeditor/skinviewer.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 SKINVIEWER_H -#define SKINVIEWER_H - -#include -#include - -namespace Ui { - class SkinViewer; -} - -class SkinViewer : public QWidget { - Q_OBJECT -public: - SkinViewer(QWidget *parent = 0); - ~SkinViewer(); - - void setScene(QGraphicsScene* scene); - -public slots: - void zoomIn(); - void zoomOut(); - -protected: - void changeEvent(QEvent *e); - -private: - Ui::SkinViewer *ui; -}; - -#endif // SKINVIEWER_H diff --git a/utils/themeeditor/skinviewer.ui b/utils/themeeditor/skinviewer.ui deleted file mode 100644 index ed260d0..0000000 --- a/utils/themeeditor/skinviewer.ui +++ /dev/null @@ -1,42 +0,0 @@ - - - SkinViewer - - - - 0 - 0 - 400 - 300 - - - - Form - - - - - - - - - - - Zoom In - - - - - - - Zoom Out - - - - - - - - - - diff --git a/utils/themeeditor/symbols.h b/utils/themeeditor/symbols.h deleted file mode 100644 index b4f3128..0000000 --- a/utils/themeeditor/symbols.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 SYMBOLS_H -#define SYMBOLS_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - -/* Symbol definitions for WPS parsing */ - -#define TAGSYM '%' -#define COMMENTSYM '#' -#define CONDITIONSYM '?' -#define MULTILINESYM ';' -#define ARGLISTOPENSYM '(' -#define ARGLISTCLOSESYM ')' -#define ARGLISTSEPERATESYM ',' -#define ENUMLISTSEPERATESYM '|' -#define ENUMLISTOPENSYM '<' -#define ENUMLISTCLOSESYM '>' -#define DEFAULTSYM '-' - -#ifdef __cplusplus -} -#endif - -#endif /* SYMBOLS_H */ diff --git a/utils/themeeditor/tabcontent.h b/utils/themeeditor/tabcontent.h deleted file mode 100644 index 1b153f7..0000000 --- a/utils/themeeditor/tabcontent.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef TABCONTENT_H -#define TABCONTENT_H - -#include - -class TabContent : public QWidget -{ -Q_OBJECT -public: - enum TabType - { - Skin, - Config - }; - - TabContent(QWidget *parent = 0): QWidget(parent){ } - - virtual TabType type() const = 0; - virtual QString title() const = 0; - virtual QString file() const = 0; - - virtual void save() = 0; - virtual void saveAs() = 0; - - virtual bool requestClose() = 0; - -signals: - void titleChanged(QString); - void lineChanged(int); - -public slots: - -}; - -#endif // TABCONTENT_H diff --git a/utils/themeeditor/tag_table.c b/utils/themeeditor/tag_table.c deleted file mode 100644 index 6d82b47..0000000 --- a/utils/themeeditor/tag_table.c +++ /dev/null @@ -1,256 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 "tag_table.h" - -#include -#define BAR_PARAMS "*|iiiiN" -/* The tag definition table */ -struct tag_info legal_tags[] = -{ - { SKIN_TOKEN_ALIGN_CENTER, "ac", "" }, - { SKIN_TOKEN_ALIGN_LEFT, "al", "" }, - { SKIN_TOKEN_ALIGN_LEFT_RTL, "aL", "" }, - { SKIN_TOKEN_ALIGN_RIGHT, "ar", "" }, - { SKIN_TOKEN_ALIGN_RIGHT_RTL, "aR", "" }, - { SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "" }, - - { SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS }, - { SKIN_TOKEN_BATTERY_VOLTS, "bv", "" }, - { SKIN_TOKEN_BATTERY_TIME, "bt", "" }, - { SKIN_TOKEN_BATTERY_SLEEPTIME, "bs", "" }, - { SKIN_TOKEN_BATTERY_CHARGING, "bc", "" }, - { SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, "bp", "" }, - { SKIN_TOKEN_USB_POWERED, "bu", "" }, - - - { SKIN_TOKEN_RTC_PRESENT, "cc", "" }, - { SKIN_TOKEN_RTC_DAY_OF_MONTH, "cd", "" }, - { SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, "ce", "" }, - { SKIN_TOKEN_RTC_12HOUR_CFG, "cf", "" }, - { SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, "cH", "" }, - { SKIN_TOKEN_RTC_HOUR_24, "ck", "" }, - { SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, "cI", "" }, - { SKIN_TOKEN_RTC_HOUR_12, "cl", "" }, - { SKIN_TOKEN_RTC_MONTH, "cm", "" }, - { SKIN_TOKEN_RTC_MINUTE, "cM", "" }, - { SKIN_TOKEN_RTC_SECOND, "cS", "" }, - { SKIN_TOKEN_RTC_YEAR_2_DIGITS, "cy", "" }, - { SKIN_TOKEN_RTC_YEAR_4_DIGITS, "cY", "" }, - { SKIN_TOKEN_RTC_AM_PM_UPPER, "cP", "" }, - { SKIN_TOKEN_RTC_AM_PM_LOWER, "cp", "" }, - { SKIN_TOKEN_RTC_WEEKDAY_NAME, "ca", "" }, - { SKIN_TOKEN_RTC_MONTH_NAME, "cb", "" }, - { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, "cu", "" }, - { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "cw", "" }, - - { SKIN_TOKEN_FILE_BITRATE, "fb", "" }, - { SKIN_TOKEN_FILE_CODEC, "fc", "" }, - { SKIN_TOKEN_FILE_FREQUENCY, "ff", "" }, - { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "fk", "" }, - { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "fm", "" }, - { SKIN_TOKEN_FILE_NAME, "fn", "" }, - { SKIN_TOKEN_FILE_PATH, "fp", "" }, - { SKIN_TOKEN_FILE_SIZE, "fs", "" }, - { SKIN_TOKEN_FILE_VBR, "fv", "" }, - { SKIN_TOKEN_FILE_DIRECTORY, "d" , "I" }, - - { SKIN_TOKEN_FILE_BITRATE, "Fb", "" }, - { SKIN_TOKEN_FILE_CODEC, "Fc", "" }, - { SKIN_TOKEN_FILE_FREQUENCY, "Ff", "" }, - { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "Fk", "" }, - { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "Fm", "" }, - { SKIN_TOKEN_FILE_NAME, "Fn", "" }, - { SKIN_TOKEN_FILE_PATH, "Fp", "" }, - { SKIN_TOKEN_FILE_SIZE, "Fs", "" }, - { SKIN_TOKEN_FILE_VBR, "Fv", "" }, - { SKIN_TOKEN_FILE_DIRECTORY, "D" , "I" }, - - - { SKIN_TOKEN_METADATA_ARTIST, "ia", "" }, - { SKIN_TOKEN_METADATA_COMPOSER, "ic", "" }, - { SKIN_TOKEN_METADATA_ALBUM, "id", "" }, - { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "iA", "" }, - { SKIN_TOKEN_METADATA_GROUPING, "iG", "" }, - { SKIN_TOKEN_METADATA_GENRE, "ig", "" }, - { SKIN_TOKEN_METADATA_DISC_NUMBER, "ik", "" }, - { SKIN_TOKEN_METADATA_TRACK_NUMBER, "in", "" }, - { SKIN_TOKEN_METADATA_TRACK_TITLE, "it", "" }, - { SKIN_TOKEN_METADATA_VERSION, "iv", "" }, - { SKIN_TOKEN_METADATA_YEAR, "iy", "" }, - { SKIN_TOKEN_METADATA_COMMENT, "iC", "" }, - - { SKIN_TOKEN_METADATA_ARTIST, "Ia", "" }, - { SKIN_TOKEN_METADATA_COMPOSER, "Ic", "" }, - { SKIN_TOKEN_METADATA_ALBUM, "Id", "" }, - { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "IA", "" }, - { SKIN_TOKEN_METADATA_GROUPING, "IG", "" }, - { SKIN_TOKEN_METADATA_GENRE, "Ig", "" }, - { SKIN_TOKEN_METADATA_DISC_NUMBER, "Ik", "" }, - { SKIN_TOKEN_METADATA_TRACK_NUMBER, "In", "" }, - { SKIN_TOKEN_METADATA_TRACK_TITLE, "It", "" }, - { SKIN_TOKEN_METADATA_VERSION, "Iv", "" }, - { SKIN_TOKEN_METADATA_YEAR, "Iy", "" }, - { SKIN_TOKEN_METADATA_COMMENT, "IC", "" }, - - { SKIN_TOKEN_SOUND_PITCH, "Sp", "" }, - { SKIN_TOKEN_SOUND_SPEED, "Ss", "" }, - - { SKIN_TOKEN_VLED_HDD, "lh", "" }, - - { SKIN_TOKEN_MAIN_HOLD, "mh", "" }, - { SKIN_TOKEN_REMOTE_HOLD, "mr", "" }, - { SKIN_TOKEN_REPEAT_MODE, "mm", "" }, - { SKIN_TOKEN_PLAYBACK_STATUS, "mp", "" }, - { SKIN_TOKEN_BUTTON_VOLUME, "mv", "|S" }, - - { SKIN_TOKEN_PEAKMETER, "pm", "" }, - { SKIN_TOKEN_PLAYER_PROGRESSBAR, "pf", "" }, - { SKIN_TOKEN_PROGRESSBAR, "pb" , BAR_PARAMS }, - { SKIN_TOKEN_VOLUME, "pv" , BAR_PARAMS }, - - { SKIN_TOKEN_TRACK_ELAPSED_PERCENT, "px", "" }, - { SKIN_TOKEN_TRACK_TIME_ELAPSED, "pc", "" }, - { SKIN_TOKEN_TRACK_TIME_REMAINING, "pr", "" }, - { SKIN_TOKEN_TRACK_LENGTH, "pt", "" }, - { SKIN_TOKEN_TRACK_STARTING, "pS" , "|S"}, - { SKIN_TOKEN_TRACK_ENDING, "pE" , "|S"}, - { SKIN_TOKEN_PLAYLIST_POSITION, "pp", "" }, - { SKIN_TOKEN_PLAYLIST_ENTRIES, "pe", "" }, - { SKIN_TOKEN_PLAYLIST_NAME, "pn", "" }, - { SKIN_TOKEN_PLAYLIST_SHUFFLE, "ps", "" }, - - { SKIN_TOKEN_DATABASE_PLAYCOUNT, "rp", "" }, - { SKIN_TOKEN_DATABASE_RATING, "rr", "" }, - { SKIN_TOKEN_DATABASE_AUTOSCORE, "ra", "" }, - - { SKIN_TOKEN_REPLAYGAIN, "rg", "" }, - { SKIN_TOKEN_CROSSFADE, "xf", "" }, - - { SKIN_TOKEN_HAVE_TUNER, "tp", "" }, - { SKIN_TOKEN_TUNER_TUNED, "tt", "" }, - { SKIN_TOKEN_TUNER_SCANMODE, "tm", "" }, - { SKIN_TOKEN_TUNER_STEREO, "ts", "" }, - { SKIN_TOKEN_TUNER_MINFREQ, "ta", "" }, - { SKIN_TOKEN_TUNER_MAXFREQ, "tb", "" }, - { SKIN_TOKEN_TUNER_CURFREQ, "tf", "" }, - { SKIN_TOKEN_PRESET_ID, "Ti", "" }, - { SKIN_TOKEN_PRESET_NAME, "Tn", "" }, - { SKIN_TOKEN_PRESET_FREQ, "Tf", "" }, - { SKIN_TOKEN_PRESET_COUNT, "Tc", "" }, - { SKIN_TOKEN_HAVE_RDS, "tx", "" }, - { SKIN_TOKEN_RDS_NAME, "ty", "" }, - { SKIN_TOKEN_RDS_TEXT, "tz", "" }, - - { SKIN_TOKEN_SUBLINE_SCROLL, "s", "" }, - { SKIN_TOKEN_SUBLINE_TIMEOUT, "t" , "S" }, - - { SKIN_TOKEN_ENABLE_THEME, "we", "" }, - { SKIN_TOKEN_DISABLE_THEME, "wd", "" }, - { SKIN_TOKEN_DRAW_INBUILTBAR, "wi", "" }, - - { SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SFII|I" }, - { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S" }, - { SKIN_TOKEN_IMAGE_PRELOAD, "x", "SFII" }, - - { SKIN_TOKEN_LOAD_FONT, "Fl" , "IF"}, - { SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss"}, - { SKIN_TOKEN_ALBUMART_DISPLAY, "Cd" , ""}, - { SKIN_TOKEN_ALBUMART_FOUND, "C" , ""}, - - { SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S"}, - { SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S"}, - - { SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "ICC"}, - { SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , ""}, - { SKIN_TOKEN_LIST_TITLE_ICON, "Li" , ""}, - - { SKIN_TOKEN_VIEWPORT_FGCOLOUR, "Vf" , "S"}, - { SKIN_TOKEN_VIEWPORT_BGCOLOUR, "Vb" , "S"}, - - { SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "SIIiii|ii"}, - { SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "sIIiii|ii"}, - { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "IIiii|ii"}, - - { SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f"}, - - { SKIN_TOKEN_SETTING, "St" , "S"}, - { SKIN_TOKEN_TRANSLATEDSTRING, "Sx" , "S"}, - { SKIN_TOKEN_LANG_IS_RTL, "Sr" , ""}, - - { SKIN_TOKEN_LASTTOUCH, "Tl" , "|S"}, - { SKIN_TOKEN_CURRENT_SCREEN, "cs", "" }, - { SKIN_TOKEN_TOUCHREGION, "T" , "IIiiS"}, - - { SKIN_TOKEN_HAVE_RECORDING, "Rp" , ""}, - { SKIN_TOKEN_IS_RECORDING, "Rr" , ""}, - { SKIN_TOKEN_REC_FREQ, "Rf" , ""}, - { SKIN_TOKEN_REC_ENCODER, "Re" , ""}, - { SKIN_TOKEN_REC_BITRATE, "Rb" , ""}, - { SKIN_TOKEN_REC_MONO, "Rm" , ""}, - { SKIN_TOKEN_REC_SECONDS, "Rs" , ""}, - { SKIN_TOKEN_REC_MINUTES, "Rn" , ""}, - { SKIN_TOKEN_REC_HOURS, "Rh" , ""}, - - { SKIN_TOKEN_UNKNOWN, "" , ""} - /* Keep this here to mark the end of the table */ -}; - -/* A table of legal escapable characters */ -char legal_escape_characters[] = "%(,);#<|>"; - -/* - * Just does a straight search through the tag table to find one by - * the given name - */ -struct tag_info* find_tag(char* name) -{ - - struct tag_info* current = legal_tags; - - /* - * Continue searching so long as we have a non-empty name string - * and the name of the current element doesn't match the name - * we're searching for - */ - - while(strcmp(current->name, name) && current->name[0] != '\0') - current++; - - if(current->name[0] == '\0') - return NULL; - else - return current; - -} - -/* Searches through the legal escape characters string */ -int find_escape_character(char lookup) -{ - char* current = legal_escape_characters; - while(*current != lookup && *current != '\0') - current++; - - if(*current == lookup && *current) - return 1; - else - return 0; -} diff --git a/utils/themeeditor/tag_table.h b/utils/themeeditor/tag_table.h deleted file mode 100644 index ec9a102..0000000 --- a/utils/themeeditor/tag_table.h +++ /dev/null @@ -1,307 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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 TAG_TABLE_H -#define TAG_TABLE_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - -enum skin_token_type { - - TOKEN_MARKER_CONTROL_TOKENS = -1, - SKIN_TOKEN_UNKNOWN, - - /* Markers */ - SKIN_TOKEN_CHARACTER, - SKIN_TOKEN_STRING, - SKIN_TOKEN_TRANSLATEDSTRING, - - /* Alignment */ - SKIN_TOKEN_ALIGN_LEFT, - SKIN_TOKEN_ALIGN_LEFT_RTL, - SKIN_TOKEN_ALIGN_CENTER, - SKIN_TOKEN_ALIGN_RIGHT, - SKIN_TOKEN_ALIGN_RIGHT_RTL, - SKIN_TOKEN_ALIGN_LANGDIRECTION, - - - /* Sublines */ - SKIN_TOKEN_SUBLINE_TIMEOUT, - SKIN_TOKEN_SUBLINE_SCROLL, - - /* Conditional */ - SKIN_TOKEN_CONDITIONAL, - SKIN_TOKEN_CONDITIONAL_START, - SKIN_TOKEN_CONDITIONAL_OPTION, - SKIN_TOKEN_CONDITIONAL_END, - - /* Viewport display */ - SKIN_TOKEN_VIEWPORT_LOAD, - SKIN_TOKEN_VIEWPORT_CONDITIONAL, - SKIN_TOKEN_VIEWPORT_ENABLE, - SKIN_TOKEN_VIEWPORT_CUSTOMLIST, - SKIN_TOKEN_UIVIEWPORT_ENABLE, - SKIN_TOKEN_UIVIEWPORT_LOAD, - SKIN_TOKEN_VIEWPORT_FGCOLOUR, - SKIN_TOKEN_VIEWPORT_BGCOLOUR, - - /* Battery */ - TOKEN_MARKER_BATTERY, - SKIN_TOKEN_BATTERY_PERCENT, - SKIN_TOKEN_BATTERY_PERCENTBAR, - SKIN_TOKEN_BATTERY_VOLTS, - SKIN_TOKEN_BATTERY_TIME, - SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, - SKIN_TOKEN_BATTERY_CHARGING, - SKIN_TOKEN_BATTERY_SLEEPTIME, - SKIN_TOKEN_USB_POWERED, - - /* Sound */ - TOKEN_MARKER_SOUND, - SKIN_TOKEN_SOUND_PITCH, - SKIN_TOKEN_SOUND_SPEED, - SKIN_TOKEN_REPLAYGAIN, - SKIN_TOKEN_CROSSFADE, - - /* Time */ - TOKEN_MARKER_RTC, - SKIN_TOKEN_RTC_PRESENT, - - /* The begin/end values allow us to know if a token is an RTC one. - New RTC tokens should be added between the markers. */ - - SKIN_TOKENs_RTC_BEGIN, /* just the start marker, not an actual token */ - - SKIN_TOKEN_RTC_DAY_OF_MONTH, - SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, - SKIN_TOKEN_RTC_12HOUR_CFG, - SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, - SKIN_TOKEN_RTC_HOUR_24, - SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, - SKIN_TOKEN_RTC_HOUR_12, - SKIN_TOKEN_RTC_MONTH, - SKIN_TOKEN_RTC_MINUTE, - SKIN_TOKEN_RTC_SECOND, - SKIN_TOKEN_RTC_YEAR_2_DIGITS, - SKIN_TOKEN_RTC_YEAR_4_DIGITS, - SKIN_TOKEN_RTC_AM_PM_UPPER, - SKIN_TOKEN_RTC_AM_PM_LOWER, - SKIN_TOKEN_RTC_WEEKDAY_NAME, - SKIN_TOKEN_RTC_MONTH_NAME, - SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, - SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, - - SKIN_TOKENS_RTC_END, /* just the end marker, not an actual token */ - - /* Database */ - TOKEN_MARKER_DATABASE, - SKIN_TOKEN_DATABASE_PLAYCOUNT, - SKIN_TOKEN_DATABASE_RATING, - SKIN_TOKEN_DATABASE_AUTOSCORE, - - /* File */ - TOKEN_MARKER_FILE, - SKIN_TOKEN_FILE_BITRATE, - SKIN_TOKEN_FILE_CODEC, - SKIN_TOKEN_FILE_FREQUENCY, - SKIN_TOKEN_FILE_FREQUENCY_KHZ, - SKIN_TOKEN_FILE_NAME, - SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, - SKIN_TOKEN_FILE_PATH, - SKIN_TOKEN_FILE_SIZE, - SKIN_TOKEN_FILE_VBR, - SKIN_TOKEN_FILE_DIRECTORY, - - /* Image */ - TOKEN_MARKER_IMAGES, - SKIN_TOKEN_IMAGE_BACKDROP, - SKIN_TOKEN_IMAGE_PROGRESS_BAR, - SKIN_TOKEN_IMAGE_PRELOAD, - SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, - SKIN_TOKEN_IMAGE_DISPLAY, - - /* Albumart */ - SKIN_TOKEN_ALBUMART_LOAD, - SKIN_TOKEN_ALBUMART_DISPLAY, - SKIN_TOKEN_ALBUMART_FOUND, - - /* Metadata */ - TOKEN_MARKER_METADATA, - SKIN_TOKEN_METADATA_ARTIST, - SKIN_TOKEN_METADATA_COMPOSER, - SKIN_TOKEN_METADATA_ALBUM_ARTIST, - SKIN_TOKEN_METADATA_GROUPING, - SKIN_TOKEN_METADATA_ALBUM, - SKIN_TOKEN_METADATA_GENRE, - SKIN_TOKEN_METADATA_DISC_NUMBER, - SKIN_TOKEN_METADATA_TRACK_NUMBER, - SKIN_TOKEN_METADATA_TRACK_TITLE, - SKIN_TOKEN_METADATA_VERSION, - SKIN_TOKEN_METADATA_YEAR, - SKIN_TOKEN_METADATA_COMMENT, - - TOKEN_MARKER_PLAYBACK_INFO, - /* Mode */ - SKIN_TOKEN_REPEAT_MODE, - SKIN_TOKEN_PLAYBACK_STATUS, - /* Progressbar */ - SKIN_TOKEN_PROGRESSBAR, - SKIN_TOKEN_PLAYER_PROGRESSBAR, - /* Peakmeter */ - SKIN_TOKEN_PEAKMETER, - - /* Current track */ - SKIN_TOKEN_TRACK_ELAPSED_PERCENT, - SKIN_TOKEN_TRACK_TIME_ELAPSED, - SKIN_TOKEN_TRACK_TIME_REMAINING, - SKIN_TOKEN_TRACK_LENGTH, - SKIN_TOKEN_TRACK_STARTING, - SKIN_TOKEN_TRACK_ENDING, - - /* Playlist */ - TOKEN_MARKER_PLAYLIST, - SKIN_TOKEN_PLAYLIST_ENTRIES, - SKIN_TOKEN_PLAYLIST_NAME, - SKIN_TOKEN_PLAYLIST_POSITION, - SKIN_TOKEN_PLAYLIST_SHUFFLE, - - - TOKEN_MARKER_MISC, - SKIN_TOKEN_ENABLE_THEME, - SKIN_TOKEN_DISABLE_THEME, - SKIN_TOKEN_DRAW_INBUILTBAR, - SKIN_TOKEN_LIST_TITLE_TEXT, - SKIN_TOKEN_LIST_TITLE_ICON, - - SKIN_TOKEN_LOAD_FONT, - - /* buttons */ - SKIN_TOKEN_BUTTON_VOLUME, - SKIN_TOKEN_LASTTOUCH, - SKIN_TOKEN_TOUCHREGION, - /* Virtual LED */ - SKIN_TOKEN_VLED_HDD, - /* Volume level */ - SKIN_TOKEN_VOLUME, - SKIN_TOKEN_VOLUMEBAR, - /* hold */ - SKIN_TOKEN_MAIN_HOLD, - SKIN_TOKEN_REMOTE_HOLD, - - /* Setting option */ - SKIN_TOKEN_SETTING, - SKIN_TOKEN_CURRENT_SCREEN, - SKIN_TOKEN_LANG_IS_RTL, - - /* Recording Tokens */ - TOKEN_MARKER_RECORDING, - SKIN_TOKEN_HAVE_RECORDING, - SKIN_TOKEN_IS_RECORDING, - SKIN_TOKEN_REC_FREQ, - SKIN_TOKEN_REC_ENCODER, - SKIN_TOKEN_REC_BITRATE, /* SWCODEC: MP3 bitrate, HWCODEC: MP3 "quality" */ - SKIN_TOKEN_REC_MONO, - SKIN_TOKEN_REC_SECONDS, - SKIN_TOKEN_REC_MINUTES, - SKIN_TOKEN_REC_HOURS, - - - /* Radio Tokens */ - TOKEN_MARKER_TUNER, - SKIN_TOKEN_HAVE_TUNER, - SKIN_TOKEN_TUNER_TUNED, - SKIN_TOKEN_TUNER_SCANMODE, - SKIN_TOKEN_TUNER_STEREO, - SKIN_TOKEN_TUNER_MINFREQ, /* changes based on "region" */ - SKIN_TOKEN_TUNER_MAXFREQ, /* changes based on "region" */ - SKIN_TOKEN_TUNER_CURFREQ, - SKIN_TOKEN_PRESET_ID, /* "id" of this preset.. really the array element number */ - SKIN_TOKEN_PRESET_NAME, - SKIN_TOKEN_PRESET_FREQ, - SKIN_TOKEN_PRESET_COUNT, - /* RDS tokens */ - SKIN_TOKEN_HAVE_RDS, - SKIN_TOKEN_RDS_NAME, - SKIN_TOKEN_RDS_TEXT, - - - TOKEN_MARKER_END, /* this needs to be the last value in this enum */ -}; - -/* - * Struct for tag parsing information - * name - The name of the tag, i.e. V for %V - * params - A string specifying all of the tags parameters, each - * character representing a single parameter. Valid - * characters for parameters are: - * I - Required integer - * i - Nullable integer - * S - Required string - * s - Nullable string - * F - Required file name - * f - Nullable file name - * C - Required skin code - * N - any amount of strings.. must be the last param in the list - * Any nullable parameter may be replaced in the WPS file - * with a '-'. To specify that parameters may be left off - * altogether, place a '|' in the parameter string. For - * instance, with the parameter string... - * Ii|Ss - * one integer must be specified, one integer can be - * specified or set to default with '-', and the user can - * stop providing parameters at any time after that. - * To specify multiple instances of the same type, put a - * number before the character. For instance, the string... - * 2s - * will specify two strings. An asterisk (*) at the beginning of the - * string will specify that you may choose to omit all arguments - * - */ -struct tag_info -{ - enum skin_token_type type; - char* name; - char* params; - -}; - -/* - * Finds a tag by name and returns its parameter list, or an empty - * string if the tag is not found in the table - */ -struct tag_info* find_tag(char* name); - -/* - * Determines whether a character is legal to escape or not. If - * lookup is not found in the legal escape characters string, returns - * false, otherwise returns true - */ -int find_escape_character(char lookup); - -#ifdef __cplusplus -} -#endif - -#endif /* TAG_TABLE_H */ diff --git a/utils/themeeditor/themeeditor.pro b/utils/themeeditor/themeeditor.pro index ef3f499..213bcd8 100644 --- a/utils/themeeditor/themeeditor.pro +++ b/utils/themeeditor/themeeditor.pro @@ -4,37 +4,43 @@ OBJECTS_DIR = $$MYBUILDDIR/o UI_DIR = $$MYBUILDDIR/ui MOC_DIR = $$MYBUILDDIR/moc RCC_DIR = $$MYBUILDDIR/rcc -HEADERS += tag_table.h \ - symbols.h \ - skin_parser.h \ - skin_scan.h \ - skin_debug.h \ - parsetreemodel.h \ - parsetreenode.h \ - editorwindow.h \ - skinhighlighter.h \ - skindocument.h \ - preferencesdialog.h \ - codeeditor.h \ - projectmodel.h \ - tabcontent.h \ - configdocument.h \ - skinviewer.h -SOURCES += tag_table.c \ - skin_parser.c \ - skin_scan.c \ - skin_debug.c \ + +#Include directories +INCLUDEPATH += gui +INCLUDEPATH += parser +INCLUDEPATH += models + +HEADERS += parser/tag_table.h \ + parser/symbols.h \ + parser/skin_parser.h \ + parser/skin_scan.h \ + parser/skin_debug.h \ + models/parsetreemodel.h \ + models/parsetreenode.h \ + gui/editorwindow.h \ + gui/skinhighlighter.h \ + gui/skindocument.h \ + gui/preferencesdialog.h \ + gui/codeeditor.h \ + models/projectmodel.h \ + gui/tabcontent.h \ + gui/configdocument.h \ + gui/skinviewer.h +SOURCES += parser/tag_table.c \ + parser/skin_parser.c \ + parser/skin_scan.c \ + parser/skin_debug.c \ main.cpp \ - parsetreemodel.cpp \ - parsetreenode.cpp \ - editorwindow.cpp \ - skinhighlighter.cpp \ - skindocument.cpp \ - preferencesdialog.cpp \ - codeeditor.cpp \ - projectmodel.cpp \ - configdocument.cpp \ - skinviewer.cpp + models/parsetreemodel.cpp \ + models/parsetreenode.cpp \ + gui/editorwindow.cpp \ + gui/skinhighlighter.cpp \ + gui/skindocument.cpp \ + gui/preferencesdialog.cpp \ + gui/codeeditor.cpp \ + models/projectmodel.cpp \ + gui/configdocument.cpp \ + gui/skinviewer.cpp OTHER_FILES += README \ resources/windowicon.png \ resources/appicon.xcf \ @@ -42,8 +48,8 @@ OTHER_FILES += README \ resources/document-save.png \ resources/document-open.png \ resources/document-new.png -FORMS += editorwindow.ui \ - preferencesdialog.ui \ - configdocument.ui \ - skinviewer.ui +FORMS += gui/editorwindow.ui \ + gui/preferencesdialog.ui \ + gui/configdocument.ui \ + gui/skinviewer.ui RESOURCES += resources.qrc -- cgit v1.1