From 5d22e3cbdd251819a4d2d07b9a12994d5aef778d Mon Sep 17 00:00:00 2001 From: Frank Gevaerts Date: Fri, 29 Aug 2008 21:08:38 +0000 Subject: Add wpseditor, the Google Summer of Code 2008 project of Rostislav Chekan. Closes FS#9327 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18362 a1c6a512-1295-4272-9138-f99709370657 --- utils/wpseditor/README | 21 ++ utils/wpseditor/TODO | 7 + utils/wpseditor/gui/gui.pro | 40 +++ .../gui/src/QPropertyEditor/ColorCombo.cpp | 73 +++++ .../wpseditor/gui/src/QPropertyEditor/ColorCombo.h | 49 +++ .../wpseditor/gui/src/QPropertyEditor/Property.cpp | 136 ++++++++ utils/wpseditor/gui/src/QPropertyEditor/Property.h | 157 +++++++++ .../gui/src/QPropertyEditor/QPropertyEditor.pro | 26 ++ .../src/QPropertyEditor/QPropertyEditorWidget.cpp | 56 ++++ .../src/QPropertyEditor/QPropertyEditorWidget.h | 113 +++++++ .../gui/src/QPropertyEditor/QPropertyModel.cpp | 236 ++++++++++++++ .../gui/src/QPropertyEditor/QPropertyModel.h | 105 ++++++ .../gui/src/QPropertyEditor/QVariantDelegate.cpp | 105 ++++++ .../gui/src/QPropertyEditor/QVariantDelegate.h | 78 +++++ utils/wpseditor/gui/src/main.cpp | 16 + utils/wpseditor/gui/src/qtrackstate.cpp | 41 +++ utils/wpseditor/gui/src/qtrackstate.h | 57 ++++ utils/wpseditor/gui/src/qwpsdrawer.cpp | 200 ++++++++++++ utils/wpseditor/gui/src/qwpsdrawer.h | 82 +++++ utils/wpseditor/gui/src/qwpsdrawer_static.cpp | 77 +++++ utils/wpseditor/gui/src/qwpseditorwindow.cpp | 120 +++++++ utils/wpseditor/gui/src/qwpseditorwindow.h | 45 +++ utils/wpseditor/gui/src/qwpsstate.cpp | 29 ++ utils/wpseditor/gui/src/qwpsstate.h | 54 +++ utils/wpseditor/gui/src/slider.cpp | 20 ++ utils/wpseditor/gui/src/slider.h | 21 ++ utils/wpseditor/gui/src/utils.cpp | 28 ++ utils/wpseditor/gui/src/utils.h | 12 + utils/wpseditor/gui/ui/mainwindow.ui | 290 ++++++++++++++++ utils/wpseditor/gui/ui/slider.ui | 43 +++ utils/wpseditor/libwps/Makefile | 100 ++++++ utils/wpseditor/libwps/buildall.sh | 7 + utils/wpseditor/libwps/cleanall.sh | 7 + utils/wpseditor/libwps/src/api.c | 268 +++++++++++++++ utils/wpseditor/libwps/src/api.h | 85 +++++ utils/wpseditor/libwps/src/defs.h | 41 +++ utils/wpseditor/libwps/src/dummies.c | 363 +++++++++++++++++++++ utils/wpseditor/libwps/src/dummies.h | 44 +++ utils/wpseditor/libwps/src/include/lang.h | 10 + utils/wpseditor/libwps/src/include/rockboxlogo.h | 1 + utils/wpseditor/libwps/src/include/sysfont.h | 1 + utils/wpseditor/libwps/src/include/system-target.h | 1 + utils/wpseditor/libwps/src/lcd.c | 150 +++++++++ utils/wpseditor/libwps/src/proxy.c | 132 ++++++++ utils/wpseditor/libwps/src/proxy.h | 25 ++ utils/wpseditor/libwps/src/wpsstate.h | 34 ++ utils/wpseditor/libwps/targets.txt | 33 ++ utils/wpseditor/wpseditor.pro | 2 + 48 files changed, 3641 insertions(+) create mode 100644 utils/wpseditor/README create mode 100644 utils/wpseditor/TODO create mode 100644 utils/wpseditor/gui/gui.pro create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/ColorCombo.cpp create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/ColorCombo.h create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/Property.cpp create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/Property.h create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditor.pro create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditorWidget.cpp create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditorWidget.h create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.cpp create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.h create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/QVariantDelegate.cpp create mode 100644 utils/wpseditor/gui/src/QPropertyEditor/QVariantDelegate.h create mode 100644 utils/wpseditor/gui/src/main.cpp create mode 100644 utils/wpseditor/gui/src/qtrackstate.cpp create mode 100644 utils/wpseditor/gui/src/qtrackstate.h create mode 100644 utils/wpseditor/gui/src/qwpsdrawer.cpp create mode 100644 utils/wpseditor/gui/src/qwpsdrawer.h create mode 100644 utils/wpseditor/gui/src/qwpsdrawer_static.cpp create mode 100644 utils/wpseditor/gui/src/qwpseditorwindow.cpp create mode 100644 utils/wpseditor/gui/src/qwpseditorwindow.h create mode 100644 utils/wpseditor/gui/src/qwpsstate.cpp create mode 100644 utils/wpseditor/gui/src/qwpsstate.h create mode 100644 utils/wpseditor/gui/src/slider.cpp create mode 100644 utils/wpseditor/gui/src/slider.h create mode 100644 utils/wpseditor/gui/src/utils.cpp create mode 100644 utils/wpseditor/gui/src/utils.h create mode 100644 utils/wpseditor/gui/ui/mainwindow.ui create mode 100644 utils/wpseditor/gui/ui/slider.ui create mode 100644 utils/wpseditor/libwps/Makefile create mode 100644 utils/wpseditor/libwps/buildall.sh create mode 100644 utils/wpseditor/libwps/cleanall.sh create mode 100644 utils/wpseditor/libwps/src/api.c create mode 100644 utils/wpseditor/libwps/src/api.h create mode 100644 utils/wpseditor/libwps/src/defs.h create mode 100644 utils/wpseditor/libwps/src/dummies.c create mode 100644 utils/wpseditor/libwps/src/dummies.h create mode 100644 utils/wpseditor/libwps/src/include/lang.h create mode 100644 utils/wpseditor/libwps/src/include/rockboxlogo.h create mode 100644 utils/wpseditor/libwps/src/include/sysfont.h create mode 100644 utils/wpseditor/libwps/src/include/system-target.h create mode 100644 utils/wpseditor/libwps/src/lcd.c create mode 100644 utils/wpseditor/libwps/src/proxy.c create mode 100644 utils/wpseditor/libwps/src/proxy.h create mode 100644 utils/wpseditor/libwps/src/wpsstate.h create mode 100644 utils/wpseditor/libwps/targets.txt create mode 100644 utils/wpseditor/wpseditor.pro (limited to 'utils/wpseditor') diff --git a/utils/wpseditor/README b/utils/wpseditor/README new file mode 100644 index 0000000000..3a8b87c511 --- /dev/null +++ b/utils/wpseditor/README @@ -0,0 +1,21 @@ + __________ __ ___. + Open \______ \ ____ ____ | | _\_ |__ _______ ___ + Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + \/ \/ \/ \/ \/ + +Installation + +Windows: + + * be sure that you have properly installed mingw, QT > 4.3.* + * if you want to debug wpseditor, you'll have to build Qt debug libraries + * cd to rockbox/utils/wpseditor/ from Qt command promt and run qmake and then make + * >gui\bin\wpseditor.exe + +Linux: + + * Make sure you have libqt4-dev installed and you have a working Rockbox environment + * cd to utils/wpseditor/ and do 'qmake-qt4 && make' + * cd to gui/bin/ and start WPS editor with './wpseditord' diff --git a/utils/wpseditor/TODO b/utils/wpseditor/TODO new file mode 100644 index 0000000000..28f559111f --- /dev/null +++ b/utils/wpseditor/TODO @@ -0,0 +1,7 @@ +* Enable ability in gui to load different targets on the fly +* Enable animation(timers,sliding lines, etc) +* Test on Mac OS +* Redesign GUI for more usability +* Replace checkwps functionality +* Include 'screenshot utility' functionality +* Make editing via gui diff --git a/utils/wpseditor/gui/gui.pro b/utils/wpseditor/gui/gui.pro new file mode 100644 index 0000000000..db7cfa1343 --- /dev/null +++ b/utils/wpseditor/gui/gui.pro @@ -0,0 +1,40 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . build src ui +INCLUDEPATH += . src/QPropertyEditor ../libwps/src +DESTDIR = bin +OBJECTS_DIR = build +MOC_DIR = build +UI_DIR = build +QMAKE_LIBDIR += lib +QT = gui core +CONFIG += qt warn_on console debug_and_release +libwps.commands += $(MAKE) -C ../libwps shared +QMAKE_EXTRA_TARGETS += libwps +PRE_TARGETDEPS += libwps +HEADERS += ../libwps/src/api.h \ + ../libwps/src/defs.h \ + src/slider.h \ + src/qtrackstate.h \ + src/qwpsstate.h \ + src/qwpseditorwindow.h \ + src/utils.h \ + src/qwpsdrawer.h +FORMS += ui/mainwindow.ui ui/slider.ui +SOURCES += src/main.cpp \ + src/slider.cpp \ + src/qtrackstate.cpp \ + src/qwpsstate.cpp \ + src/qwpseditorwindow.cpp \ + src/utils.cpp \ + src/qwpsdrawer.cpp \ + src/qwpsdrawer_static.cpp +LIBS += -Lbin +CONFIG(debug, debug|release) { + LIBS += -lQPropertyEditord + TARGET = wpseditord +} +CONFIG(release, debug|release) { + LIBS += -lQPropertyEditor + TARGET = wpseditor +} diff --git a/utils/wpseditor/gui/src/QPropertyEditor/ColorCombo.cpp b/utils/wpseditor/gui/src/QPropertyEditor/ColorCombo.cpp new file mode 100644 index 0000000000..f5eeb030dc --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/ColorCombo.cpp @@ -0,0 +1,73 @@ +// ************************************************************************************************* +// +// QPropertyEditor v 0.1 +// +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// +// This class is based on the Color Editor Factory Example by Trolltech +// +// ************************************************************************************************* + +#include "ColorCombo.h" + +#include + +ColorCombo::ColorCombo(QWidget* parent /*= 0*/) : QComboBox(parent) { + QStringList colorNames = QColor::colorNames(); + for (int i = 0; i < colorNames.size(); ++i) { + QColor color(colorNames[i]); + insertItem(i, colorNames[i]); + setItemData(i, color, Qt::DecorationRole); + } + addItem(tr("Custom"), QVariant((int)QVariant::UserType)); + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(currentChanged(int))); +} + + +ColorCombo::~ColorCombo() {} + + +QColor ColorCombo::color() const { + return qVariantValue(itemData(currentIndex(), Qt::DecorationRole)); +} + +void ColorCombo::setColor(QColor color) { + m_init = color; + setCurrentIndex(findData(color, int(Qt::DecorationRole))); + if (currentIndex() == -1) { + addItem(color.name()); + setItemData(count()-1, color, Qt::DecorationRole); + setCurrentIndex(count()-1); + } +} + +void ColorCombo::currentChanged(int index) { + if (itemData(index).isValid() && itemData(index) == QVariant((int)QVariant::UserType)) { + QColor color = QColorDialog::getColor(m_init, this); + if (color.isValid()) { + if (findData(color, int(Qt::DecorationRole)) == -1) { + addItem(color.name()); + setItemData(count()-1, color, Qt::DecorationRole); + } + setCurrentIndex(findData(color, int(Qt::DecorationRole))); + } else + setCurrentIndex(findData(m_init)); + } +} diff --git a/utils/wpseditor/gui/src/QPropertyEditor/ColorCombo.h b/utils/wpseditor/gui/src/QPropertyEditor/ColorCombo.h new file mode 100644 index 0000000000..530b05bbc5 --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/ColorCombo.h @@ -0,0 +1,49 @@ +// ************************************************************************************************* +// +// QPropertyEditor v 0.1 +// +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// +// This class is based on the Color Editor Factory Example by Trolltech +// +// ************************************************************************************************* + +#ifndef COLORCOMBO_H_ +#define COLORCOMBO_H_ + +#include + +class ColorCombo : public QComboBox { + Q_OBJECT +public: + ColorCombo(QWidget* parent = 0); + virtual ~ColorCombo(); + + QColor color() const; + void setColor(QColor c); + +private slots: + void currentChanged(int index); + +private: + QColor m_init; + +}; +#endif diff --git a/utils/wpseditor/gui/src/QPropertyEditor/Property.cpp b/utils/wpseditor/gui/src/QPropertyEditor/Property.cpp new file mode 100644 index 0000000000..0746d15140 --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/Property.cpp @@ -0,0 +1,136 @@ +// **************************************************************************************** +// +// QPropertyEditor Library +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// This file is part of the Horde3D Scene Editor. +// +// The QPropertyEditor Library 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 version 3 of the License +// +// The Horde3D Scene Editor is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// **************************************************************************************** + +#include "Property.h" +#include "ColorCombo.h" + +#include +#include + +#include + +Property::Property(const QString& name /*= QString()*/, QObject* propertyObject /*= 0*/, QObject* parent /*= 0*/) : QObject(parent), + m_propertyObject(propertyObject) { + setObjectName(name); +} + +QVariant Property::value(int /*role = Qt::UserRole*/) const { + if (m_propertyObject) + return m_propertyObject->property(qPrintable(objectName())); + else + return QVariant(); +} + +void Property::setValue(const QVariant &value) { + if (m_propertyObject) + m_propertyObject->setProperty(qPrintable(objectName()), value); +} + +bool Property::isReadOnly() { + if (m_propertyObject && m_propertyObject->metaObject()->property(m_propertyObject->metaObject()->indexOfProperty(qPrintable(objectName()))).isWritable()) + return false; + else + return true; +} + +QWidget* Property::createEditor(QWidget *parent, const QStyleOptionViewItem &option) { + (void)option; + QWidget* editor = 0; + switch (value().type()) { + case QVariant::Color: + editor = new ColorCombo(parent); + break; + case QVariant::Int: + editor = new QSpinBox(parent); + editor->setProperty("minimum", -INT_MAX); + editor->setProperty("maximum", INT_MAX); + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(setValue(int))); + break; + case QMetaType::Float: + case QVariant::Double: + editor = new QDoubleSpinBox(parent); + editor->setProperty("minimum", -INT_MAX); + editor->setProperty("maximum", INT_MAX); + connect(editor, SIGNAL(valueChanged(double)), this, SLOT(setValue(double))); + break; + default: + return editor; + } + return editor; +} + +bool Property::setEditorData(QWidget *editor, const QVariant &data) { + switch (value().type()) { + case QVariant::Color: + static_cast(editor)->setColor(data.value()); + return true; + ; + case QVariant::Int: + editor->blockSignals(true); + static_cast(editor)->setValue(data.toInt()); + editor->blockSignals(false); + return true; + case QMetaType::Float: + case QVariant::Double: + editor->blockSignals(true); + static_cast(editor)->setValue(data.toDouble()); + editor->blockSignals(false); + return true; + default: + return false; + } + return false; +} + +QVariant Property::editorData(QWidget *editor) { + switch (value().type()) { + case QVariant::Color: + return QVariant::fromValue(static_cast(editor)->color()); + case QVariant::Int: + return QVariant(static_cast(editor)->value()); + case QMetaType::Float: + case QVariant::Double: + return QVariant(static_cast(editor)->value()); + break; + default: + return QVariant(); + } +} + +Property* Property::findPropertyObject(QObject* propertyObject) { + if (m_propertyObject == propertyObject) + return this; + for (int i=0; i(children()[i])->findPropertyObject(propertyObject); + if (child) + return child; + } + return 0; +} + +void Property::setValue(double value) { + setValue(QVariant(value)); +} + +void Property::setValue(int value) { + setValue(QVariant(value)); +} diff --git a/utils/wpseditor/gui/src/QPropertyEditor/Property.h b/utils/wpseditor/gui/src/QPropertyEditor/Property.h new file mode 100644 index 0000000000..52d6842987 --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/Property.h @@ -0,0 +1,157 @@ +// ************************************************************************************************* +// +// QPropertyEditor v 0.1 +// +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// ************************************************************************************************* + +#ifndef PROPERTY_H_ +#define PROPERTY_H_ + +#include +#include +#include + +/** + * The Property class is the base class for all properties in the QPropertyEditor + * You can implement custom properties inherited from this class to further enhence the + * functionality of the QPropertyEditor + */ +class Property : public QObject { + Q_OBJECT + +public: + + /** + * Constructor + * + * @param name the name of the property within the propertyObject (will be used in the QPropertyEditorWidget view too) + * @param propertyObject the object that contains the property + * @param parent optional parent object + */ + Property(const QString& name = QString(), QObject* propertyObject = 0, QObject* parent = 0); + + /** + * The value stored by this property + * @return QVariant the data converted to a QVariant + */ + virtual QVariant value(int role = Qt::UserRole) const; + /** + * Sets the value stored by this property + * @param value the data converted to a QVariant + */ + virtual void setValue(const QVariant& value); + + /** + * Returns the QObject which contains the property managed by this instance + * @return QObject* pointer to the QObject that contains user defined properties + */ + QObject* propertyObject() { + return m_propertyObject; + } + + /** + * Flag if property is used for indicating a group or really manages a property + * @return bool true if this property is only used to display a category in the QPropertyEditorWidget + */ + bool isRoot() { + return m_propertyObject == 0; + } + + /** + * Flag if the property can be set + * @return bool true if this property has no set method + */ + bool isReadOnly(); + + /** + * Returns the row of this instance within the QPropertyModel + * @return int row within the QPropertyModel + */ + int row() { + return parent()->children().indexOf(this); + } + + /** + * returns optional settings for the editor widget that is used to manipulate the properties value + * @return QString a string that contains property settings for the editor widget (e.g. "minimum=1.0;maximum=10.0;") + */ + QString editorHints() { + return m_hints; + } + + /** + * Sets properties for the editor widget that is used to manipulate the data value managed by this instance + * @param hints a string containing property settings for the editor widget that manipulates this property + */ + virtual void setEditorHints(const QString& hints) { + m_hints = hints; + } + + /** + * Creates an editor for the data managed by this instance + * @param parent widget the newly created editor widget will be child of + * @param option currently not used + * @return QWidget* pointer to the editor widget + */ + virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option); + + /** + * Returns the data of the editor widget used to manipulate this instance + * @return QVariant the data converted to a QVariant + */ + virtual QVariant editorData(QWidget *editor); + + /** + * Changes the editor widget's data to a specific value + * @param editor the editor widget + * @param data the data to set in the editor widget + * @return bool true if editor widget was set to the given data successfully, false if the data can not be set in the editor (e.g. wrong datatype) + */ + virtual bool setEditorData(QWidget *editor, const QVariant& data); + + /** + * Tries to find the first property that manages the given propertyObject + * @param propertyObject + * @return Property + */ + Property* findPropertyObject(QObject* propertyObject); + +private slots: + /** + * This slot is used to immediately set the properties when the editor widget's value of a double or float + * property has changed + * @param value the new value + */ + void setValue(double value); + /** + * This slot is used to immediately set the properties when the editor widget's value of an integer + * property has changed + * @param value the new value + */ + void setValue(int value); + +private: + QObject* m_propertyObject; + QString m_hints; + +}; + +#endif diff --git a/utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditor.pro b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditor.pro new file mode 100644 index 0000000000..85fd29ee2c --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditor.pro @@ -0,0 +1,26 @@ +TEMPLATE = lib +CONFIG += staticlib debug_and_release +SOURCES = ColorCombo.cpp \ + Property.cpp \ + QPropertyEditorWidget.cpp \ + QPropertyModel.cpp \ + QVariantDelegate.cpp +HEADERS = ColorCombo.h \ + Property.h \ + QPropertyEditorWidget.h \ + QPropertyModel.h \ + QVariantDelegate.h +INCLUDEPATH += . +DESTDIR = ../../lib +UI_DIR = . +CONFIG(debug, debug|release) { + TARGET = QPropertyEditord + OBJECTS_DIR = ../../build/QPropertyEditor/debug + MOC_DIR = ../../build/QPropertyEditor/debug +} +CONFIG(release, debug|release) { + TARGET = QPropertyEditor + OBJECTS_DIR = ../../build/QPropertyEditor/release + MOC_DIR = ../../build/QPropertyEditor/release + DEFINES += QT_NO_DEBUG +} diff --git a/utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditorWidget.cpp b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditorWidget.cpp new file mode 100644 index 0000000000..fc4b90c227 --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditorWidget.cpp @@ -0,0 +1,56 @@ +// ************************************************************************************************* +// +// QPropertyEditor v 0.1 +// +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// ************************************************************************************************* + +#include "QPropertyEditorWidget.h" +#include "QPropertyModel.h" +#include "QVariantDelegate.h" +#include "Property.h" + +QPropertyEditorWidget::QPropertyEditorWidget(QWidget* parent /*= 0*/) : QTreeView(parent) { + m_model = new QPropertyModel(this); + setModel(m_model); + setItemDelegate(new QVariantDelegate(this)); +} + + +QPropertyEditorWidget::~QPropertyEditorWidget() {} + +void QPropertyEditorWidget::addObject(QObject* propertyObject) { + m_model->addItem(propertyObject); + expandToDepth(0); +} + +void QPropertyEditorWidget::setObject(QObject* propertyObject) { + m_model->clear(); + if (propertyObject) + addObject(propertyObject); +} + +void QPropertyEditorWidget::updateObject(QObject* propertyObject) { + m_model->updateItem(propertyObject); +} + +void QPropertyEditorWidget::setCustomPropertyCB(UserTypeCB callback) { + m_model->setCustomPropertyCB(callback); +} diff --git a/utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditorWidget.h b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditorWidget.h new file mode 100644 index 0000000000..2dab87722a --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyEditorWidget.h @@ -0,0 +1,113 @@ +// ************************************************************************************************* +// +// QPropertyEditor v 0.1 +// +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// ************************************************************************************************* + +#ifndef QPROPERTYEDITORWIDGET_H_ +#define QPROPERTYEDITORWIDGET_H_ + +#include + +class QPropertyModel; +class Property; + +/** + * \mainpage QPropertyEditor + * + * \section intro_sec Introduction + * + * The main purpose for the QPropertyEditor is the visualization and manipulation of properties defined via the Q_PROPERTY macro in + * QObject based classes. + */ + +/** + * \brief The QPropertyEditorWidget offers an easy to use mechanism to visualize properties of a class inherited from QObject. + * + * Qt provides a nice way to define class properties by using the Q_PROPERTY macro. The purpose of the QPropertyEditor + * is to visualize these properties in an easy way. + * + * To use the property editor, all you have to do is to create a class that defines it's properties by using Q_PROPERTY + * and to add this class by using the addObject() method of this QPropertyEditorWidget class. + * The QPropertyEditorWidget is inherited from QTreeView and will display the properties in a tree with two columns: Name and Value + * + * For basic data types the build in editor widgets of Qt will be used. The QPropertyEditor itself only defines an additional + * editor for QColor (based on the Color Editor Factory Example from Trolltech). But it can easily be extended by yourself + * either within the library or for special datatypes also outside of the library in your application. + */ +class QPropertyEditorWidget : public QTreeView { + Q_OBJECT +public: + + /** + * A typedef for a callback used to create user defined properties for custom datatypes + */ + typedef Property* (*UserTypeCB)(const QString& name, QObject* propertyObject, Property* parent); + + /** + * \brief Constructor + * + * Creates a new editor widget based on QTreeView + * @param parent optional parent widget + */ + QPropertyEditorWidget(QWidget* parent = 0); + + /// Destructor + virtual ~QPropertyEditorWidget(); + + /** + * Adds the user properties of the given class to the QPropertyModel associated with this view + * + * @param propertyObject the class inherited from QObject that contains user properties that should be + * managed by the QPropertyModel associated with this view + */ + void addObject(QObject* propertyObject); + + /** + * Similar to the addObject() method this method adds the properties of the given class to the QPropertyModel + * associated with this view. But in contrast to addObject() it will clear the model before, removing all + * previously added objects. + * + * @param propertyObject the class inherited from QObject that contains user properties that should be + * managed by the QPropertyModel associated with this view + */ + void setObject(QObject* propertyObject); + + /** + * Updates the view for the given object. This can be usefull if a property was changed programmatically instead + * of using the view. In this case the view normally will display the new property values only after the user clicked + * on it. To overcome this problem you can call updateObject with the object whose property was changed. + */ + void updateObject(QObject* propertyObject); + + /** + * If you define custom datatypes outside of this library the QPropertyModel will check if you + * also defined a callback that is responsible to create custom property classes inherited from Property to handle + * these datatypes. With this method you can set such a callback that will create custom properties for custom datatypes. + */ + void setCustomPropertyCB(UserTypeCB callback); + +private: + /// The Model for this view + QPropertyModel* m_model; + +}; +#endif diff --git a/utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.cpp b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.cpp new file mode 100644 index 0000000000..b147cd089d --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.cpp @@ -0,0 +1,236 @@ +// ************************************************************************************************* +// +// QPropertyEditor v 0.1 +// +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// ************************************************************************************************* + +#include "QPropertyModel.h" + +#include "Property.h" + +#include +#include +#include + +struct PropertyPair { + PropertyPair(const QMetaObject* obj, QMetaProperty property) : Property(property), Object(obj) {} + + QMetaProperty Property; + const QMetaObject* Object; + + bool operator==(const PropertyPair& other) const { + return QString(other.Property.name()) == QString(Property.name()); + } +}; + + +QPropertyModel::QPropertyModel(QObject* parent /*= 0*/) : QAbstractItemModel(parent), m_userCallback(0) { + m_rootItem = new Property("Root",0, this); +} + + +QPropertyModel::~QPropertyModel() {} + +QModelIndex QPropertyModel::index ( int row, int column, const QModelIndex & parent /*= QModelIndex()*/ ) const { + Property *parentItem = m_rootItem; + if (parent.isValid()) + parentItem = static_cast(parent.internalPointer()); + if (row >= parentItem->children().size()) + return QModelIndex(); + return createIndex(row, column, parentItem->children().at(row)); + +} + +QModelIndex QPropertyModel::parent ( const QModelIndex & index ) const { + if (!index.isValid()) + return QModelIndex(); + + Property *childItem = static_cast(index.internalPointer()); + Property *parentItem = qobject_cast(childItem->parent()); + + if (!parentItem || parentItem == m_rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} + +int QPropertyModel::rowCount ( const QModelIndex & parent /*= QModelIndex()*/ ) const { + Property *parentItem = m_rootItem; + if (parent.isValid()) + parentItem = static_cast(parent.internalPointer()); + return parentItem->children().size(); +} + +int QPropertyModel::columnCount ( const QModelIndex & parent /*= QModelIndex()*/ ) const { + (void)parent; + return 2; +} + +QVariant QPropertyModel::data ( const QModelIndex & index, int role /*= Qt::DisplayRole*/ ) const { + if (!index.isValid()) + return QVariant(); + + Property *item = static_cast(index.internalPointer()); + switch (role) { + case Qt::ToolTipRole: + case Qt::DecorationRole: + case Qt::DisplayRole: + case Qt::EditRole: + if (index.column() == 0) + return item->objectName(); + if (index.column() == 1) + return item->value(role); + case Qt::BackgroundRole: + if (item->isRoot()) return QApplication::palette("QTreeView").brush(QPalette::Normal, QPalette::Button).color(); + break; + }; + return QVariant(); +} + +// edit methods +bool QPropertyModel::setData ( const QModelIndex & index, const QVariant & value, int role /*= Qt::EditRole*/ ) { + if (index.isValid() && role == Qt::EditRole) { + Property *item = static_cast(index.internalPointer()); + item->setValue(value); + emit dataChanged(index, index); + return true; + } + return false; +} + +Qt::ItemFlags QPropertyModel::flags ( const QModelIndex & index ) const { + if (!index.isValid()) + return Qt::ItemIsEnabled; + Property *item = static_cast(index.internalPointer()); + // only allow change of value attribute + if (item->isRoot()) + return Qt::ItemIsEnabled; + else if (item->isReadOnly()) + return Qt::ItemIsDragEnabled | Qt::ItemIsSelectable; + else + return Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; +} + + +QVariant QPropertyModel::headerData ( int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole*/ ) const { + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + switch (section) { + case 0: + return tr("Name"); + case 1: + return tr("Value"); + } + } + return QVariant(); +} + +QModelIndex QPropertyModel::buddy ( const QModelIndex & index ) const { + if (index.isValid() && index.column() == 0) + return createIndex(index.row(), 1, index.internalPointer()); + return index; +} + +void QPropertyModel::addItem(QObject *propertyObject) { + // first create property <-> class hierarchy + QList propertyMap; + QList classList; + const QMetaObject* metaObject = propertyObject->metaObject(); + do { + int count = metaObject->propertyCount(); + for (int i=0; iproperty(i); + if (property.isUser()) // Hide Qt specific properties + { + PropertyPair pair(metaObject, property); + int index = propertyMap.indexOf(pair); + if (index != -1) + propertyMap[index] = pair; + else + propertyMap.push_back(pair); + } + } + classList.push_front(metaObject); + } while ((metaObject = metaObject->superClass())!=0); + + QList finalClassList; + // remove empty classes from hierarchy list + foreach(const QMetaObject* obj, classList) { + bool keep = false; + foreach(PropertyPair pair, propertyMap) { + if (pair.Object == obj) { + keep = true; + break; + } + } + if (keep) + finalClassList.push_back(obj); + } + + // finally insert properties for classes containing them + int i=rowCount(); + beginInsertRows(QModelIndex(), i, i + finalClassList.count()); + foreach(const QMetaObject* metaObject, finalClassList) { + // Set default name of the hierarchy property to the class name + QString name = metaObject->className(); + // Check if there is a special name for the class + int index = metaObject->indexOfClassInfo(qPrintable(name)); + if (index != -1) + name = metaObject->classInfo(index).value(); + // Create Property Item for class node + Property* propertyItem = new Property(name, 0, m_rootItem); + foreach(PropertyPair pair, propertyMap) { + // Check if the property is associated with the current class from the finalClassList + if (pair.Object == metaObject) { + QMetaProperty property(pair.Property); + Property* p = 0; + if (property.type() == QVariant::UserType && m_userCallback) + p = m_userCallback(property.name(), propertyObject, propertyItem); + else + p = new Property(property.name(), propertyObject, propertyItem); + int index = metaObject->indexOfClassInfo(property.name()); + if (index != -1) + p->setEditorHints(metaObject->classInfo(index).value()); + } + } + } + endInsertRows(); +} + +void QPropertyModel::updateItem ( QObject* propertyObject, const QModelIndex& parent /*= QModelIndex() */ ) { + Property *parentItem = m_rootItem; + if (parent.isValid()) + parentItem = static_cast(parent.internalPointer()); + if (parentItem->propertyObject() != propertyObject) + parentItem = parentItem->findPropertyObject(propertyObject); + if (parentItem) // Indicate view that the data for the indices have changed + dataChanged(createIndex(parentItem->row(), 0, static_cast(parentItem)), createIndex(parentItem->row(), 1, static_cast(parentItem))); +} + +void QPropertyModel::clear() { + beginRemoveRows(QModelIndex(), 0, rowCount()); + delete m_rootItem; + m_rootItem = new Property("Root",0, this); + endRemoveRows(); +} + +void QPropertyModel::setCustomPropertyCB(QPropertyEditorWidget::UserTypeCB callback) { + m_userCallback = callback; +} diff --git a/utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.h b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.h new file mode 100644 index 0000000000..8a52bbe87c --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/QPropertyModel.h @@ -0,0 +1,105 @@ +// ************************************************************************************************* +// +// QPropertyEditor v 0.1 +// +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// ************************************************************************************************* +#ifndef QPROPERTYMODEL_H_ +#define QPROPERTYMODEL_H_ + +#include +#include + +#include "QPropertyEditorWidget.h" + +class Property; + +/** + * The QPropertyModel handles the user defined properties of QObjects + */ +class QPropertyModel : public QAbstractItemModel { + Q_OBJECT +public: + /** + * Constructor + * @param parent optional parent object + */ + QPropertyModel(QObject* parent = 0); + /// Destructor + virtual ~QPropertyModel(); + + /// QAbstractItemModel implementation + QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const; + + /// QAbstractItemModel implementation + QModelIndex parent ( const QModelIndex & index ) const; + /// QAbstractItemModel implementation + int rowCount ( const QModelIndex & parent = QModelIndex() ) const; + /// QAbstractItemModel implementation + int columnCount ( const QModelIndex & parent = QModelIndex() ) const; + /// QAbstractItemModel implementation + QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const; + + /// QAbstractItemModel implementation + bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ); + /// QAbstractItemModel implementation + Qt::ItemFlags flags ( const QModelIndex & index ) const; + + /// QAbstractItemModel implementation + QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; + + /// QAbstractItemModel implementation + QModelIndex buddy ( const QModelIndex & index ) const; + + /** + * Adds the user properties of the given class to the QPropertyModel instance + * + * @param propertyObject the class inherited from QObject that contains user properties that should be + * managed by this instance + */ + void addItem(QObject* propertyObject); + + /** + * Creates a dataChanged signal for the given object + * @param propertyObject the instance of a QObject based class that should be updated + * @param parent optional model index the propertyObject is child of + */ + void updateItem ( QObject* propertyObject, const QModelIndex& parent = QModelIndex() ) ; + + /** + * Removes all objects from the model + */ + void clear(); + + /** + * Sets custom callback that will be used to create Property instances for custom datatypes + */ + void setCustomPropertyCB(QPropertyEditorWidget::UserTypeCB callback); + +private: + + /// The Root Property for all objects + Property* m_rootItem; + + /// Custom callback + QPropertyEditorWidget::UserTypeCB m_userCallback; + +}; +#endif diff --git a/utils/wpseditor/gui/src/QPropertyEditor/QVariantDelegate.cpp b/utils/wpseditor/gui/src/QPropertyEditor/QVariantDelegate.cpp new file mode 100644 index 0000000000..ebda9b2c31 --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/QVariantDelegate.cpp @@ -0,0 +1,105 @@ +// ************************************************************************************************* +// +// QPropertyEditor v 0.1 +// +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// ************************************************************************************************* + +#include "QVariantDelegate.h" + +#include "Property.h" + +#include + + +QVariantDelegate::QVariantDelegate(QObject* parent) : QItemDelegate(parent) {} + + +QVariantDelegate::~QVariantDelegate() {} + +QWidget *QVariantDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option , const QModelIndex & index ) const { + QWidget* editor = 0; + Property* p = static_cast(index.internalPointer()); + switch (p->value().type()) { + case QVariant::Color: + case QVariant::Int: + case QMetaType::Float: + case QVariant::Double: + case QVariant::UserType: + editor = p->createEditor(parent, option); + if (editor) break; // if no editor could be created take default case + default: + editor = QItemDelegate::createEditor(parent, option, index); + } + parseEditorHints(editor, p->editorHints()); + return editor; +} + +void QVariantDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { + QVariant data = index.model()->data(index, Qt::EditRole); + switch (data.type()) { + case QVariant::Color: + case QMetaType::Double: + case QMetaType::Float: + case QVariant::UserType: + if (static_cast(index.internalPointer())->setEditorData(editor, data)) // if editor couldn't be recognized use default + break; + default: + QItemDelegate::setEditorData(editor, index); + break; + } +} + +void QVariantDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { + QVariant data = index.model()->data(index, Qt::EditRole); + switch (data.type()) { + case QVariant::Color: + case QMetaType::Double: + case QMetaType::Float: + case QVariant::UserType: { + QVariant data = static_cast(index.internalPointer())->editorData(editor); + if (data.isValid()) { + model->setData(index, data , Qt::EditRole); + break; + } + } + default: + QItemDelegate::setModelData(editor, model, index); + break; + } +} + +void QVariantDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex& index ) const { + return QItemDelegate::updateEditorGeometry(editor, option, index); +} + +void QVariantDelegate::parseEditorHints(QWidget* editor, const QString& editorHints) const { + if (editor && !editorHints.isEmpty()) { + // Parse for property values + QRegExp rx("(.*)(=\\s*)(.*)(;{1})"); + rx.setMinimal(true); + int pos = 0; + while ((pos = rx.indexIn(editorHints, pos)) != -1) { + qDebug("Setting %s to %s", qPrintable(rx.cap(1)), qPrintable(rx.cap(3))); + editor->setProperty(qPrintable(rx.cap(1).trimmed()), rx.cap(3).trimmed()); + pos += rx.matchedLength(); + } + } +} diff --git a/utils/wpseditor/gui/src/QPropertyEditor/QVariantDelegate.h b/utils/wpseditor/gui/src/QPropertyEditor/QVariantDelegate.h new file mode 100644 index 0000000000..e06265af82 --- /dev/null +++ b/utils/wpseditor/gui/src/QPropertyEditor/QVariantDelegate.h @@ -0,0 +1,78 @@ +// ************************************************************************************************* +// +// QPropertyEditor v 0.1 +// +// -------------------------------------- +// Copyright (C) 2007 Volker Wiendl +// +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// ************************************************************************************************* + +#ifndef COLORSELECTIONBUTTON_H_ +#define COLORSELECTIONBUTTON_H_ + +#include + + +/** + * This class is used to create the editor widgets for datatypes encapsulated in QVariant variables + */ +class QVariantDelegate : public QItemDelegate { + Q_OBJECT + +public: + /** + * Constructor + * @param parent optional parent object + */ + QVariantDelegate(QObject* parent = 0); + /// Destructor + virtual ~QVariantDelegate(); + + /** + * Creates an editor widget as child of a given widget for a specific QModelIndex + * + * @param parent the parent widget for the editor + * @param option some style options that the editor should use + * @param index the index of the item the editor will be created for + * @return QWidget the editor widget + */ + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + /** + * Tries to set the editor data based on the value stored at a specific QModelIndex + * @param editor the editor widget + * @param index the model index of the value that should be used in the editor + */ + virtual void setEditorData(QWidget *editor, const QModelIndex &index) const; + + /** + * Sets the data of a specific QModelIndex to tha value of the editor widget + * @param editor the editor widget that contains the new value + * @param model the model that contains the index + * @param index the index within the model whose data value should be set to the data value of the editor + */ + virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + + /// QItemDelegate implementation + virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +protected: + void parseEditorHints(QWidget* editor, const QString& editorHints) const; + +}; +#endif diff --git a/utils/wpseditor/gui/src/main.cpp b/utils/wpseditor/gui/src/main.cpp new file mode 100644 index 0000000000..0ba22c9fce --- /dev/null +++ b/utils/wpseditor/gui/src/main.cpp @@ -0,0 +1,16 @@ +#include +#include "qwpseditorwindow.h" +#include "utils.h" +#include + +QPointer win; + +int main(int argc, char ** argv) { + QApplication app( argc, argv ); + + win = new QWpsEditorWindow; + win->show(); + app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) ); + + return app.exec(); +} diff --git a/utils/wpseditor/gui/src/qtrackstate.cpp b/utils/wpseditor/gui/src/qtrackstate.cpp new file mode 100644 index 0000000000..dad2f9a4aa --- /dev/null +++ b/utils/wpseditor/gui/src/qtrackstate.cpp @@ -0,0 +1,41 @@ +#include "qtrackstate.h" +#include + +// +QTrackState::QTrackState( ) + : QObject() { + memset(&state,0,sizeof(state)); + state.title = (char*)"title"; + state.artist = (char*)"artist"; + state.album = (char*)"album"; + state.length = 100; + state.elapsed = 50; +} + +void QTrackState::setTitle(const QString& name) { + state.title = new char[name.length()]; + strcpy(state.title,name.toAscii()); + emit stateChanged(state); +} + +void QTrackState::setArtist(const QString& name) { + state.artist = new char[name.length()]; + strcpy(state.artist,name.toAscii()); + emit stateChanged(state); +} + +void QTrackState::setAlbum(const QString& name) { + state.album = new char[name.length()]; + strcpy(state.album,name.toAscii()); + emit stateChanged(state); +} + +void QTrackState::setLength(int le) { + state.length = le; + emit stateChanged(state); +} + +void QTrackState::setElapsed(int le) { + state.elapsed = le; + emit stateChanged(state); +} diff --git a/utils/wpseditor/gui/src/qtrackstate.h b/utils/wpseditor/gui/src/qtrackstate.h new file mode 100644 index 0000000000..b57f7a8376 --- /dev/null +++ b/utils/wpseditor/gui/src/qtrackstate.h @@ -0,0 +1,57 @@ +#ifndef __QTRACKSTATE_H__ +#define __QTRACKSTATE_H__ + +#include "wpsstate.h" +#include + +class QWpsState; + +class QTrackState : public QObject { + Q_OBJECT + Q_CLASSINFO ( "QTrackState", "Mp3 State" ); + Q_PROPERTY ( QString Title READ title WRITE setTitle DESIGNABLE true USER true ) + Q_PROPERTY ( QString Artist READ artist WRITE setArtist DESIGNABLE true USER true ) + Q_PROPERTY ( QString Album READ album WRITE setAlbum DESIGNABLE true USER true ) + Q_PROPERTY ( int Length READ length WRITE setLength DESIGNABLE true USER true ) + Q_CLASSINFO("Length", "readOnly=true;value=100"); + Q_PROPERTY ( int Elapsed READ elapsed WRITE setElapsed DESIGNABLE true USER true ) + Q_CLASSINFO("Elapsed", "minimum=0;maximum=100;value=50"); + + + trackstate state; + +public: + QTrackState(); + +public slots: + QString title() const { + return state.title; + } + void setTitle ( const QString& name ); + + QString artist() const { + return state.artist; + } + void setArtist ( const QString& name ); + + QString album() const { + return state.album; + } + void setAlbum ( const QString& name ); + + int length() const { + return state.length; + } + void setLength ( int l ); + + int elapsed() const { + return state.elapsed; + } + void setElapsed ( int l ); + +signals: + void stateChanged ( trackstate state ); + +}; + +#endif // __QTRACKSTATE_H__ diff --git a/utils/wpseditor/gui/src/qwpsdrawer.cpp b/utils/wpseditor/gui/src/qwpsdrawer.cpp new file mode 100644 index 0000000000..ab8a4b32d6 --- /dev/null +++ b/utils/wpseditor/gui/src/qwpsdrawer.cpp @@ -0,0 +1,200 @@ +#include "qwpsdrawer.h" +#include "slider.h" +#include "utils.h" +#include +#include +#include +// + + +QPointer drawer; +QPixmap *QWpsDrawer::pix = NULL; +QString QWpsDrawer::mTmpWpsString; +QImage QWpsDrawer::backdrop; +proxy_api QWpsDrawer::api; + +QWpsDrawer::QWpsDrawer( QWpsState *ws,QTrackState *ms, QWidget *parent ) + : QWidget(parent),wpsState(ws),trackState(ms),showGrid(false),mTargetLibName("libwps") { + + tryResolve(); + memset(&api,0,sizeof(struct proxy_api)); + + api.verbose = 2; + api.putsxy = &QWpsDrawer::putsxy; + api.transparent_bitmap_part = &QWpsDrawer::transparent_bitmap_part; + api.bitmap_part = &QWpsDrawer::bitmap_part; + api.drawpixel = &QWpsDrawer::drawpixel; + api.fillrect = &QWpsDrawer::fillrect; + api.hline = &QWpsDrawer::hline; + api.vline = &QWpsDrawer::vline; + api.clear_viewport = &QWpsDrawer::clear_viewport; + api.load_wps_backdrop = &QWpsDrawer::load_wps_backdrop; + api.read_bmp_file = &QWpsDrawer::read_bmp_file; + api.debugf = &qlogger; + newTempWps(); +} + +bool QWpsDrawer::tryResolve() { + QLibrary lib(qApp->applicationDirPath()+"/"+mTargetLibName); + wps_init = (pfwps_init)lib.resolve("wps_init"); + wps_display = (pfwps_display)lib.resolve("wps_display"); + wps_refresh = (pfwps_refresh)lib.resolve("wps_refresh"); + mResolved = wps_init && wps_display && wps_refresh; + if (!mResolved) + DEBUGF1(tr("ERR: Failed to resolve funcs!")); + return mResolved; +} +QWpsDrawer::~QWpsDrawer() { + qDebug()<<"QWpsDrawer::~QWpsDrawer()"; + cleanTemp(); +} + +void QWpsDrawer::mouseReleaseEvent ( QMouseEvent * event ) { + Q_UNUSED(event); + /*int x = event->x() - (this->width()-pix->width())/2, + y = event->y() - (this->height()-pix->height())/2; + DEBUGF1("x=%d,y=%d",x,y);*/ +} +void QWpsDrawer::newTempWps() { + QTemporaryFile tmpWps; + tmpWps.setAutoRemove(false); + tmpWps.setFileTemplate(QDir::tempPath()+"/XXXXXXXXXX.wps"); + if (tmpWps.open()) { + QString tmpDir = tmpWps.fileName().left(tmpWps.fileName().length()-4); + if (QDir::temp().mkpath(tmpDir)) { + mTmpWpsString = tmpDir; + DEBUGF1(mTmpWpsString); + } + } +} + +void QWpsDrawer::WpsInit(QString buffer, bool isFile) { + + if (!mResolved) + if (!tryResolve()) + return; + if (isFile) { + cleanTemp(); + DEBUGF1( tr("Loading %1").arg(buffer)); + QFile file(buffer); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) + mWpsString = file.readAll(); + newTempWps(); + } else + mWpsString = buffer; + { + QFile tfile(mTmpWpsString+".wps"); + if (tfile.open(QIODevice::WriteOnly | QIODevice::Text)) + tfile.write(mWpsString.toAscii(),mWpsString.length()); + } + + if (isFile) + wps_init(buffer.toAscii(), &api, isFile); + else + wps_init(QString(mTmpWpsString+".wps").toAscii(), &api, true); + pix = new QPixmap(api.getwidth(),api.getheight()); + + drawBackdrop(); + + setMinimumWidth(api.getwidth()); + setMinimumHeight(api.getheight()); + + update(); +} + +void QWpsDrawer::paintEvent(QPaintEvent * event) { + if (!mResolved) + return; + if (pix==NULL) + return; + QPainter p(this); + QRect rect = event->rect(); + + drawBackdrop(); + wps_refresh(); + + if (showGrid) { + QPainter g(pix); + viewport_api avp; + api.get_current_vp(&avp); + + g.setPen(Qt::green); + + for (int i=0;i*avp.fontheight/1.5width())/2,(rect.height()-pix->height())/2,*pix); + +} + +void QWpsDrawer::clear_viewport(int x,int y,int w,int h, int color) { + DEBUGF2("clear_viewport(int x=%d,int y=%d,int w=%d,int h=%d, int color)",x,y,w,h); + QPainter p(pix); + //p.setOpacity(0.1); + //QImage img = backdrop.copy(x,y,w,h); + //p.drawImage(x,y,img); +} + +void QWpsDrawer::slotSetVolume() { + Slider *slider = new Slider(this, tr("Volume"),-74,10); + slider->show(); + connect(slider, SIGNAL(valueChanged(int)), wpsState, SLOT(setVolume(int))); + connect(this, SIGNAL(destroyed()),slider, SLOT(close())); +} + +void QWpsDrawer::slotSetProgress() { + Slider *slider = new Slider(this,tr("Progress"),0,100); + slider->show(); + connect(slider, SIGNAL(valueChanged(int)), trackState, SLOT(setElapsed(int))); + connect(this, SIGNAL(destroyed()),slider, SLOT(close())); +} + +void QWpsDrawer::slotWpsStateChanged(wpsstate ws_) { + if (api.set_wpsstate) + api.set_wpsstate(ws_); + update(); +} + +void QWpsDrawer::slotTrackStateChanged(trackstate ms_) { + if (api.set_wpsstate) + api.set_trackstate(ms_); + update(); +} + +void QWpsDrawer::slotShowGrid(bool show) { + showGrid = show; + update(); +} + +void QWpsDrawer::drawBackdrop() { + QPainter b(pix); + QImage pink = backdrop.createMaskFromColor(qRgb(255,0,255),Qt::MaskOutColor); + backdrop.setAlphaChannel(pink); + b.drawImage(0,0,backdrop); +} + +void QWpsDrawer::slotSetAudioStatus(int status) { + api.set_audio_status(status); + update(); +} + +void QWpsDrawer::cleanTemp(bool fileToo) { + if (fileToo) + QFile::remove(mTmpWpsString+".wps"); + QDirIterator it(mTmpWpsString, QDirIterator::Subdirectories); + while (it.hasNext()) { + QFile::remove(it.next()); + } + QDir(mTmpWpsString).rmdir(mTmpWpsString); +} + +void QWpsDrawer::closeEvent(QCloseEvent *event) { + qDebug()<<"QWpsDrawer::closeEvent()"; + cleanTemp(); + event->accept(); +} diff --git a/utils/wpseditor/gui/src/qwpsdrawer.h b/utils/wpseditor/gui/src/qwpsdrawer.h new file mode 100644 index 0000000000..d4dfa6c7a2 --- /dev/null +++ b/utils/wpseditor/gui/src/qwpsdrawer.h @@ -0,0 +1,82 @@ +#ifndef WPSDRAWER_H +#define WPSDRAWER_H +// +#include +#include +#include +#include +#include "api.h" +#include "qtrackstate.h" +#include "qwpsstate.h" +// + +typedef int (*pfwps_init)(const char* buff,struct proxy_api *api, bool isfile); +typedef int (*pfwps_display)(); +typedef int (*pfwps_refresh)(); + +class QWpsDrawer : public QWidget { + Q_OBJECT + + pfwps_init wps_init; + pfwps_display wps_display; + pfwps_refresh wps_refresh; + + static QPixmap *pix; + static QImage backdrop; + + QWpsState *wpsState; + QTrackState *trackState; + + bool showGrid; + bool mResolved; + QString mWpsString; + QString mTargetLibName; + static QString mTmpWpsString; + + +protected: + virtual void paintEvent(QPaintEvent * event); + virtual void closeEvent(QCloseEvent *event); + virtual void mouseReleaseEvent ( QMouseEvent * event ) ; + void drawBackdrop(); + void newTempWps(); + void cleanTemp(bool fileToo=true); + bool tryResolve(); +public: + QWpsDrawer(QWpsState *ws,QTrackState *ms, QWidget *parent=0); + ~QWpsDrawer(); + void WpsInit(QString buffer, bool isFile = true); + + QString wpsString() const { + return mWpsString; + }; + QString tempWps() const { + return mTmpWpsString; + }; + + + static proxy_api api; + /***********Drawing api******************/ + static void putsxy(int x, int y, const unsigned char *str); + static void transparent_bitmap_part(const void *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); + static void bitmap_part(const void *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); + static void drawpixel(int x, int y); + static void fillrect(int x, int y, int width, int height); + static void hline(int x1, int x2, int y); + static void vline(int x, int y1, int y2); + static void clear_viewport(int x,int y,int w,int h, int color); + static bool load_wps_backdrop(char* filename); + static int read_bmp_file(const char* filename,int *width, int *height); + /****************************************/ +public slots: + void slotSetVolume(); + void slotSetProgress(); + + void slotShowGrid(bool); + void slotWpsStateChanged(wpsstate); + void slotTrackStateChanged(trackstate); + void slotSetAudioStatus(int); +}; +#endif diff --git a/utils/wpseditor/gui/src/qwpsdrawer_static.cpp b/utils/wpseditor/gui/src/qwpsdrawer_static.cpp new file mode 100644 index 0000000000..bf94d28a5a --- /dev/null +++ b/utils/wpseditor/gui/src/qwpsdrawer_static.cpp @@ -0,0 +1,77 @@ +#include "qwpsdrawer.h" +#include +#include +#include +#include "utils.h" + +void QWpsDrawer::putsxy(int x, int y, const unsigned char *str) { + QPainter p(pix); + viewport_api avp; + api.get_current_vp(&avp); + p.setPen(Qt::gray); + + + QFont font("times",avp.fontheight,QFont::Bold); + p.setFont(font); + p.drawText(x+avp.x,y + avp.fontheight + avp.y,(char*)str); +} +void QWpsDrawer::transparent_bitmap_part(const void *src, int src_x, int src_y, + int stride, int x, int y, int width, int height) { + QImage img; + img.load((char*)src); + DEBUGF2("transparent_bitmap_part(const void *src=%s, int src_x=%d, int src_y=%d,int stride=%d, int x=%d, int y=%d, int width=%d, int height=%d",(char*)src,src_x, src_y,stride, x, y, width, height); + QPainter p(pix); + QPoint target(x,y); + QRectF source(src_x, src_y, width, height); + + QImage pink = img.createMaskFromColor(qRgb(255,0,255),Qt::MaskOutColor); + img.setAlphaChannel(pink); + + p.drawImage(target, img, source); +} +void QWpsDrawer::bitmap_part(const void *src, int src_x, int src_y, + int stride, int x, int y, int width, int height) { + transparent_bitmap_part(src,src_x,src_y,stride,x,y,width,height); +} +void QWpsDrawer::drawpixel(int x, int y) { + QPainter p(pix); + p.setPen(Qt::blue); + p.drawPoint(x,y); +} +void QWpsDrawer::fillrect(int x, int y, int width, int height) { + QPainter p(pix); + DEBUGF2("fillrect(int x=%d, int y=%d, int width=%d, int height=%d)\n",x, y, width, height); + p.setPen(Qt::green); +} +void QWpsDrawer::hline(int x1, int x2, int y) { + QPainter p(pix); + p.setPen(Qt::black); + p.drawLine(x1,y,x2,y); +} +void QWpsDrawer::vline(int x, int y1, int y2) { + QPainter p(pix); + p.setPen(Qt::black); + p.drawLine(x,y1,x,y2); +} +bool QWpsDrawer::load_wps_backdrop(char* filename) { + DEBUGF2("load backdrop: %s", filename); + QFile file(filename); + QFileInfo info(file); + file.copy(mTmpWpsString+"/"+info.fileName()); + backdrop.load(filename); + return true; +} + +int QWpsDrawer::read_bmp_file(const char* filename,int *width, int *height) { + QImage img; + + QFile file(filename); + QFileInfo info(file); + file.copy(mTmpWpsString+"/"+info.fileName()); + + img.load(filename); + //qDebug()<<"QWpsDrawer::read_bmp_file"< +#include +#include + +enum api_playmode playmodes[PLAYMODES_NUM] = { + API_STATUS_PLAY, + API_STATUS_STOP, + API_STATUS_PAUSE, + API_STATUS_FASTFORWARD, + API_STATUS_FASTBACKWARD + }; + +const char *playmodeNames[] = { + "Play", + "Stop", + "Pause", + "FastForward", + "FastBackward" + }; + +QWpsEditorWindow::QWpsEditorWindow( QWidget * parent, Qt::WFlags f) + : QMainWindow(parent, f) { + logEdit = 0; + setupUi(this); + drawer = new QWpsDrawer(&wpsState,&trackState, this); + QWpsDrawer::api.verbose = 1; + //drawer->WpsInit("iCatcher.wps"); + setCentralWidget(drawer); + connectActions(); + m_propertyEditor->addObject(&trackState); + m_propertyEditor->addObject(&wpsState); +} + +void QWpsEditorWindow::connectActions() { + qDebug()<<"connect actions"; + connect(actOpenWps, SIGNAL(triggered()), this, SLOT(slotOpenWps())); + connect(actSetVolume, SIGNAL(triggered()), drawer, SLOT(slotSetVolume())); + connect(actSetProgress, SIGNAL(triggered()), drawer, SLOT(slotSetProgress())); + connect(actShowGrid, SIGNAL(triggered(bool)), drawer, SLOT(slotShowGrid(bool))); + + connect(actUpdatePlainWps, SIGNAL(triggered()), SLOT(slotUpdatePlainWps())); + connect(plainWpsEdit->document(), SIGNAL(modificationChanged(bool)), SLOT(slotPlainDocModChanged(bool))); + + connect(&wpsState, SIGNAL(stateChanged(wpsstate)), drawer, SLOT(slotWpsStateChanged(wpsstate))); + connect(&trackState, SIGNAL(stateChanged(trackstate)), drawer, SLOT(slotTrackStateChanged(trackstate))); + connect(&wpsState, SIGNAL(stateChanged(wpsstate)), this, SLOT(slotWpsStateChanged(wpsstate))); + connect(&trackState, SIGNAL(stateChanged(trackstate)), this, SLOT(slotTrackStateChanged(trackstate))); + + connect(actClearLog, SIGNAL(triggered()), logEdit, SLOT(clear())); + connect(actVerboseLevel, SIGNAL(triggered()), SLOT(slotVerboseLevel())); + + actGroupAudios = new QActionGroup(this); + signalMapper = new QSignalMapper(this); + for (int i=0;isetCheckable(true); + actGroupAudios->addAction(act); + connect(act,SIGNAL(triggered()),signalMapper,SLOT(map())); + signalMapper->setMapping(act, i); + menuPlay->addAction(act); + actAudios[playmodes[i]] = act; + } + connect(signalMapper, SIGNAL(mapped(int)), SIGNAL(signalAudioStatusChanged(int))); + connect(this, SIGNAL(signalAudioStatusChanged(int)), drawer, SLOT(slotSetAudioStatus(int))); + actGroupAudios->setEnabled(false); +} + +void QWpsEditorWindow::slotWpsStateChanged(wpsstate) { + m_propertyEditor->updateObject(&wpsState); + m_propertyEditor->update(); +} + +void QWpsEditorWindow::slotTrackStateChanged(trackstate) { + m_propertyEditor->updateObject(&trackState); + m_propertyEditor->update(); +} + +void QWpsEditorWindow::slotOpenWps() { + QString wpsfile = QFileDialog::getOpenFileName(this, + tr("Open WPS"), "", tr("WPS Files (*.wps);; All Files (*.*)")); + if (wpsfile == "") { + DEBUGF1(tr("File wasn't chosen")); + return; + } + m_propertyEditor->setEnabled(true); + drawer->WpsInit(wpsfile); + plainWpsEdit->clear(); + plainWpsEdit->append(drawer->wpsString()); + trackState.setAlbum(trackState.album()); + actGroupAudios->setEnabled(true); +} + +void QWpsEditorWindow::logMsg(QString s) { + logEdit->append(s); +} + +void QWpsEditorWindow::slotVerboseLevel() { + bool ok; + int i = QInputDialog::getInteger(this, tr("Set Verbose Level"),tr("Level:"), QWpsDrawer::api.verbose, 0, 3, 1, &ok); + if (ok) + QWpsDrawer::api.verbose = i; +} + +void QWpsEditorWindow::slotUpdatePlainWps() { + DEBUGF1(tr("Updating WPS")); + plainWpsEdit->document()->setModified(false); + drawer->WpsInit(plainWpsEdit->toPlainText(),false); + +} + +void QWpsEditorWindow::slotPlainDocModChanged(bool changed) { + if (changed) + dockPlainWps->setWindowTitle(tr("PlainWps*")); + else + dockPlainWps->setWindowTitle(tr("PlainWps")); +} + diff --git a/utils/wpseditor/gui/src/qwpseditorwindow.h b/utils/wpseditor/gui/src/qwpseditorwindow.h new file mode 100644 index 0000000000..019eb63808 --- /dev/null +++ b/utils/wpseditor/gui/src/qwpseditorwindow.h @@ -0,0 +1,45 @@ +#ifndef MAINWINDOWIMPL_H +#define MAINWINDOWIMPL_H +// +#include +#include +#include +#include "ui_mainwindow.h" +#include "wpsstate.h" +#include "qwpsdrawer.h" +#include "qwpsstate.h" +#include "qtrackstate.h" +// +class QWpsEditorWindow : public QMainWindow, public Ui::MainWindow { + Q_OBJECT + QWpsState wpsState; + QTrackState trackState; + QPointer drawer; + + QHash actAudios; + QActionGroup *actGroupAudios; + QSignalMapper *signalMapper; + +protected: + void connectActions(); +public: + QWpsEditorWindow( QWidget * parent = 0, Qt::WFlags f = 0 ); + void logMsg(QString s); +private slots: + void slotOpenWps(); + void slotVerboseLevel(); + void slotWpsStateChanged(wpsstate); + void slotTrackStateChanged(trackstate); + + void slotUpdatePlainWps(); + void slotPlainDocModChanged(bool m); + +signals: + void signalAudioStatusChanged(int); + +}; +#endif + + + + diff --git a/utils/wpseditor/gui/src/qwpsstate.cpp b/utils/wpseditor/gui/src/qwpsstate.cpp new file mode 100644 index 0000000000..4244bf6293 --- /dev/null +++ b/utils/wpseditor/gui/src/qwpsstate.cpp @@ -0,0 +1,29 @@ +#include "qwpsstate.h" + +QWpsState::QWpsState(): QObject() { + state.fontheight = 8; + state.fontwidth = 5; + state.volume = -30; + state.battery_level = 50; + +} + +void QWpsState::setFontHeight(int val) { + state.fontheight = val; + emit stateChanged(state); +} + +void QWpsState::setFontWidth(int val) { + state.fontwidth = val; + emit stateChanged(state); +} + +void QWpsState::setVolume(int val) { + state.volume = val; + emit stateChanged(state); +} + +void QWpsState::setBattery(int val) { + state.battery_level = val; + emit stateChanged(state); +} diff --git a/utils/wpseditor/gui/src/qwpsstate.h b/utils/wpseditor/gui/src/qwpsstate.h new file mode 100644 index 0000000000..eb43531de6 --- /dev/null +++ b/utils/wpseditor/gui/src/qwpsstate.h @@ -0,0 +1,54 @@ +#ifndef __WPSSTATE_H__ +#define __WPSSTATE_H__ + +#include +#include "wpsstate.h" + +class QWpsState : public QObject { + Q_OBJECT + + + Q_CLASSINFO("QWpsState", "WPS State"); + Q_PROPERTY(int FontHeight READ fontHeight WRITE setFontHeight DESIGNABLE true USER true) + Q_CLASSINFO("FontHeight", "minimum=6;maximum=20;value=10"); + Q_PROPERTY(int FontWidth READ fontWidth WRITE setFontWidth DESIGNABLE true USER true) + Q_CLASSINFO("FontWidth", "minimum=4;maximum=20;value=8"); + Q_PROPERTY(int Volume READ volume WRITE setVolume DESIGNABLE true USER true) + Q_CLASSINFO("Volume", "minimum=-74;maximum=24;value=-15"); + Q_PROPERTY(int Battery READ battery WRITE setBattery DESIGNABLE true USER true) + Q_CLASSINFO("Battery", "minimum=0;maximum=100;value=50"); + + wpsstate state; + +public: + QWpsState(); + + int fontHeight() const { + return state.fontheight; + } + void setFontHeight(int val); + + int fontWidth() const { + return state.fontwidth; + } + void setFontWidth(int val); + + int battery() const { + return state.battery_level; + } + void setBattery(int val); + + int volume() const { + return state.volume; + } +public slots: + void setVolume(int val); + + + + + +signals: + void stateChanged ( wpsstate state ); +}; +#endif // __WPSSTATE_H__ diff --git a/utils/wpseditor/gui/src/slider.cpp b/utils/wpseditor/gui/src/slider.cpp new file mode 100644 index 0000000000..7e3c9a942c --- /dev/null +++ b/utils/wpseditor/gui/src/slider.cpp @@ -0,0 +1,20 @@ +#include "slider.h" +#include +// +Slider::Slider(QWidget *parent, QString caption, int min, int max ):QDialog(parent) { + setupUi ( this ); + connect(horslider, SIGNAL(valueChanged(int)), this, SIGNAL(valueChanged(int))); + connect(this, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int))); + setWindowTitle(caption); + horslider->setMinimum(min); + horslider->setMaximum(max); +} +// +int Slider::value() { + return horslider->value(); +} +void Slider::slotValueChanged(int step) { + setWindowTitle(tr("Value =%1 ").arg(step)); +} + + diff --git a/utils/wpseditor/gui/src/slider.h b/utils/wpseditor/gui/src/slider.h new file mode 100644 index 0000000000..2620731644 --- /dev/null +++ b/utils/wpseditor/gui/src/slider.h @@ -0,0 +1,21 @@ +#ifndef SLIDERIMPL_H +#define SLIDERIMPL_H +// +#include +#include +#include "ui_slider.h" +// +class Slider : public QDialog , Ui::slider { + Q_OBJECT +public slots: + void slotValueChanged(int step); +signals: + void valueChanged(int); +public: + Slider(QWidget *parent, QString caption, int min, int max ); + int value(); + + + +}; +#endif diff --git a/utils/wpseditor/gui/src/utils.cpp b/utils/wpseditor/gui/src/utils.cpp new file mode 100644 index 0000000000..f18442555b --- /dev/null +++ b/utils/wpseditor/gui/src/utils.cpp @@ -0,0 +1,28 @@ +#include "utils.h" +#include +#include +#include "qwpseditorwindow.h" + +extern QPointer win; + +int qlogger(const char* fmt,...) { + va_list ap; + va_start(ap, fmt); + QString s; + s.vsprintf(fmt,ap); + va_end(ap); + s.replace("\n",""); + //qDebug()<=0) + s = ""+s+""; + if (win!=0) + win->logMsg(s); + va_end(ap); + return s.length(); +} + +int qlogger(const QString& s) { + return qlogger(s.toAscii().data()); +} diff --git a/utils/wpseditor/gui/src/utils.h b/utils/wpseditor/gui/src/utils.h new file mode 100644 index 0000000000..ae88d78249 --- /dev/null +++ b/utils/wpseditor/gui/src/utils.h @@ -0,0 +1,12 @@ +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#include + +#define DEBUGF1 qlogger +#define DEBUGF2(...) + +extern int qlogger(const char* fmt,...); +extern int qlogger(const QString& s); + +#endif // __UTILS_H__ diff --git a/utils/wpseditor/gui/ui/mainwindow.ui b/utils/wpseditor/gui/ui/mainwindow.ui new file mode 100644 index 0000000000..cd3f52bd66 --- /dev/null +++ b/utils/wpseditor/gui/ui/mainwindow.ui @@ -0,0 +1,290 @@ + + MainWindow + + + + 0 + 0 + 882 + 669 + + + + WPS Editor + + + + + 260 + 21 + 344 + 345 + + + + + + + 0 + 0 + 882 + 21 + + + + + File + + + + + + + + + + + + Play + + + + + + + + + 0 + 650 + 882 + 19 + + + + + + + 0 + 370 + 882 + 280 + + + + + 0 + 30 + + + + PlainWps + + + 8 + + + + + 0 + 22 + 882 + 258 + + + + + + + false + + + false + + + + + + + Update WPS + + + + + + + Qt::Vertical + + + + 20 + 211 + + + + + + + + + + + 0 + 21 + 256 + 345 + + + + Property Editor + + + 1 + + + + false + + + + 0 + 22 + 256 + 323 + + + + + + + + 608 + 21 + 274 + 345 + + + + + 0 + 30 + + + + Log + + + 2 + + + + + 0 + 22 + 274 + 323 + + + + + + + false + + + true + + + + + + + + + Quit + + + + + Open WPS + + + + + Set Volume + + + + + Set Progress + + + + + true + + + false + + + Show Grid + + + + + Clear Log + + + + + Verbose Level + + + + + Update WPS + + + + + + QPropertyEditorWidget + QTreeView +
QPropertyEditorWidget.h
+
+
+ + + + btnUpdatePlainWps + clicked() + actUpdatePlainWps + trigger() + + + 835 + 411 + + + -1 + -1 + + + + + actQuit + triggered() + MainWindow + close() + + + -1 + -1 + + + 440 + 334 + + + + +
diff --git a/utils/wpseditor/gui/ui/slider.ui b/utils/wpseditor/gui/ui/slider.ui new file mode 100644 index 0000000000..24fff0bf23 --- /dev/null +++ b/utils/wpseditor/gui/ui/slider.ui @@ -0,0 +1,43 @@ + + slider + + + + 0 + 0 + 295 + 37 + + + + Value + + + + + 0 + 10 + 291 + 21 + + + + -78 + + + 24 + + + 1 + + + -78 + + + Qt::Horizontal + + + + + + diff --git a/utils/wpseditor/libwps/Makefile b/utils/wpseditor/libwps/Makefile new file mode 100644 index 0000000000..3779a9ed30 --- /dev/null +++ b/utils/wpseditor/libwps/Makefile @@ -0,0 +1,100 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# +ROOT=../../.. + +OS = w32 +CC = gcc +MKDIR = mkdir -p + +ifeq ($(findstring MINGW,$(shell uname)),MINGW) +OS = w32 +CC = mingw32-gcc +COPY = copy +RM = rm +endif + +ifeq ($(findstring Linux,$(shell uname)),Linux) +OS = linux +CC = gcc +COPY = cp +RM = rm -f +endif + + + +COMMON= \ + src/dummies.c \ + src/api.c \ + src/lcd.c \ + $(ROOT)/apps/gui/wps_parser.c \ + $(ROOT)/apps/gui/wps_debug.c \ + $(ROOT)/firmware/font.c \ + $(ROOT)/apps/misc.c \ + $(ROOT)/apps/gui/gwps-common.c \ + $(ROOT)/apps/status.c \ + $(ROOT)/apps/recorder/peakmeter.c \ + $(ROOT)/apps/recorder/icons.c \ + $(ROOT)/apps/gui/scrollbar.c \ + $(ROOT)/firmware/common/timefuncs.c \ + $(ROOT)/firmware/common/unicode.c \ + $(ROOT)/firmware/common/ctype.c \ + $(ROOT)/firmware/id3.c \ + $(ROOT)/firmware/font_cache.c \ + $(ROOT)/firmware/lru.c \ + $(ROOT)/firmware/mp3data.c \ + $(ROOT)/firmware/replaygain.c + +# $(ROOT)/apps/recorder/bmp.c +# $(ROOT)/apps/abrepeat.c \ +# $(ROOT)/apps/action.c \ +# $(ROOT)/apps/cuesheet.c \ +# $(ROOT)/apps/gui/statusbar.c \ +# $(ROOT)/apps/gui/gwps.c \ + +INCLUDE=-I src/include \ + -I $(ROOT)/apps/gui \ + -I $(ROOT)/firmware/export \ + -I $(ROOT)/firmware/include \ + -I $(ROOT)/apps/recorder \ + -I $(ROOT)/apps \ + -I src + +CFLAGS = -g -Wall -D__PCTOOL__ -DWPSEDITOR -DDEBUG -DROCKBOX_DIR_LEN=1 -DBUTTON_REMOTE + +all: + @echo To build, run the buildall.sh script + +build: build-$(OS) + +build-w32: src/proxy.c $(COMMON) + @echo CC [$(TARGET)] + @$(CC) $(INCLUDE) $(CFLAGS) -D$(TARGET) -DTARGET_MODEL=\"$(MODEL)\" -DBUILD_DLL $(COMMON) -shared src/proxy.c -o libwps_$(MODEL).dll + +build-linux: src/proxy.c $(COMMON) + @echo CC [$(TARGET)] + @$(CC) $(INCLUDE) $(CFLAGS) -D$(TARGET) -DTARGET_MODEL=\"$(MODEL)\" -shared -Wl,-soname,libwps_$(MODEL).so,-olibwps_$(MODEL).so -fPIC $(COMMON) src/proxy.c + +clean: clean-$(OS) + +clean-w32: + $(RM) "libwps_$(MODEL).dll" + +clean-linux: + $(RM) "libwps_$(MODEL).so.1" + +shared: shared-$(OS) + +shared-w32: src/proxy.c $(COMMON) + @echo CC [IRIVER_H10_5GB] + @$(CC) $(INCLUDE) $(CFLAGS) -DIRIVER_H10_5GB -DTARGET_MODEL=\"h10_5gb\" -DBUILD_DLL $(COMMON) -shared src/proxy.c -o ../gui/bin/libwps.dll + +shared-linux: src/proxy.c $(COMMON) + @echo CC [IRIVER_H10_5GB] + @$(CC) $(INCLUDE) $(CFLAGS) -DIRIVER_H10_5GB -DTARGET_MODEL=\"h10_5gb\" -shared -Wl,-soname,libwps.so,-olibwps.so -fPIC $(COMMON) src/proxy.c + @$(COPY) libwps.so ../gui/bin/libwps.so diff --git a/utils/wpseditor/libwps/buildall.sh b/utils/wpseditor/libwps/buildall.sh new file mode 100644 index 0000000000..60677d22b6 --- /dev/null +++ b/utils/wpseditor/libwps/buildall.sh @@ -0,0 +1,7 @@ +#!/bin/sh +cat targets.txt | ( + while read target model + do + make MODEL=$model TARGET=$target build + done +) diff --git a/utils/wpseditor/libwps/cleanall.sh b/utils/wpseditor/libwps/cleanall.sh new file mode 100644 index 0000000000..15b733a6a7 --- /dev/null +++ b/utils/wpseditor/libwps/cleanall.sh @@ -0,0 +1,7 @@ +#!/bin/sh +cat targets.txt | ( + while read target model + do + make MODEL=$model TARGET=$target clean + done +) diff --git a/utils/wpseditor/libwps/src/api.c b/utils/wpseditor/libwps/src/api.c new file mode 100644 index 0000000000..485efa8e00 --- /dev/null +++ b/utils/wpseditor/libwps/src/api.c @@ -0,0 +1,268 @@ +#include +#include +#include "sound.h" +#include "api.h" +#include "proxy.h" +#include "dummies.h" +#include "scroll_engine.h" +#include "wpsstate.h" +#include + +struct proxy_api *xapi; + +void get_current_vp(struct viewport_api *avp); +/************************************************************* + +*************************************************************/ +#ifdef HAVE_LCD_BITMAP +void screen_clear_area(struct screen * display, int xstart, int ystart, + int width, int height) { + display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + display->fillrect(xstart, ystart, width, height); + display->set_drawmode(DRMODE_SOLID); +} +#endif + +bool load_wps_backdrop(char* filename) { + return xapi->load_wps_backdrop(filename); +} + +bool load_remote_wps_backdrop(char* filename) { + return xapi->load_remote_wps_backdrop(filename); +} + +int read_bmp_file(const char* filename,struct bitmap *bm, int maxsize,int format) { + if (!xapi->read_bmp_file) + { + DEBUGF1("can't read bmp file! NULL api!\n"); + return -1; + } + bm->format = 3;//FORMAT_ANY? + bm->data = (unsigned char*)malloc(255); + memset(bm->data,0,255); + strcpy((char*)bm->data,filename); + //bm->data[strlen(filename)] = '\0'; + xapi->read_bmp_file(filename,&bm->width, &bm->height); + return 1; +} + +bool load_wps_backdrop2(char* filename) { + DEBUGF1("load_wps_backdrop(char* filename='%s')",filename); + return true; +} + +bool load_remote_wps_backdrop2(char* filename) { + DEBUGF1("load_remote_wps_backdrop2(char* filename='%s')",filename); + return true; +} + +void stop_scroll() { + DEBUGF3("stop_scroll\n"); + return; +} + +void puts_scroll(int x, int y, const unsigned char *string) { + DEBUGF2("puts_scroll(int x=%d, int y=%d, const unsigned char *string='%s'\n",x,y,string); +} + +void putsxy(int x, int y, const unsigned char *str) { + DEBUGF2("putsxy(int =%d, int y=%d, const unsigned char *str='%s')\n",x,y,str); +} + +void lcd_update() { + DEBUGF3("update\n"); +} + +void clear_viewport(int x, int y, int w, int h, int color) { + DEBUGF3("clear_viewport(int x=%d, int y=%d, int w=%d, int h=%d, int color=%d)\n", x, y, w, h, color); +}; + +int getstringsize(const unsigned char *str, int *w, int *h) { + //DEBUGF1("getstringsize(const unsigned char *str=\"%s\", int *w=%d, int *h=%d \n",str,*w,*h); + *w=strlen((char*)str)*sysfont.maxwidth; + *h=sysfont.height; + return 1; +} + +void set_wpsstate(struct wpsstate state){ + sysfont.height = state.fontheight; + sysfont.maxwidth = state.fontwidth; + global_settings.volume = state.volume; + battery_percent = state.battery_level; + _audio_status = state.audio_status; +} + +void set_trackstate(struct trackstate state){ + gui_wps[0].state->id3->title = state.title; + gui_wps[0].state->id3->artist = state.artist; + gui_wps[0].state->id3->album = state.album; + gui_wps[0].state->id3->elapsed = state.elapsed; + gui_wps[0].state->id3->length = state.length; +} + +void set_next_trackstate(struct trackstate state) +{ + gui_wps[0].state->nid3->title = state.title; + gui_wps[0].state->nid3->artist = state.artist; + gui_wps[0].state->nid3->album = state.album; + gui_wps[0].state->nid3->elapsed = state.elapsed; + gui_wps[0].state->nid3->length = state.length; +} + +enum api_playmode playmodes[PLAYMODES_NUM] = { + API_STATUS_PLAY, + API_STATUS_STOP, + API_STATUS_PAUSE, + API_STATUS_FASTFORWARD, + API_STATUS_FASTBACKWARD +}; + +const char *playmodeNames[] = { + "Play", "Stop", "Pause", "FastForward", "FastBackward" +}; + + +void set_audio_status(int status){ + DEBUGF1("%s",playmodeNames[status]); + switch(status){ + case API_STATUS_PLAY: + _audio_status = AUDIO_STATUS_PLAY; + status_set_ffmode(STATUS_PLAY); + break; + case API_STATUS_STOP: + _audio_status = 0; + status_set_ffmode(STATUS_STOP); + break; + case API_STATUS_PAUSE: + _audio_status = AUDIO_STATUS_PAUSE; + status_set_ffmode(STATUS_PLAY); + break; + case API_STATUS_FASTFORWARD: + status_set_ffmode(STATUS_FASTFORWARD); + break; + case API_STATUS_FASTBACKWARD: + status_set_ffmode(STATUS_FASTBACKWARD); + break; + default: + DEBUGF1("ERR: Unknown status"); + } +} + +void test_api(struct proxy_api *api) { + if (!api->stop_scroll) + api->stop_scroll=stop_scroll; + if (!api->set_viewport) + api->set_viewport=lcd_set_viewport; + if (!api->clear_viewport) + api->clear_viewport=clear_viewport; + if (!api->getstringsize) + api->getstringsize=getstringsize; + if (!api->getwidth) + api->getwidth=lcd_getwidth; + if (!api->getheight) + api->getheight=lcd_getheight; + if (!api->set_drawmode) + api->set_drawmode=lcd_set_drawmode; + if (!api->puts_scroll) + api->puts_scroll=puts_scroll; + if (!api->update) + api->update=lcd_update; + if (!api->clear_display) + api->clear_display=lcd_clear_display; + if (!api->getfont) + api->getfont=lcd_getfont; + if (!api->putsxy) + api->putsxy=putsxy; + +#if LCD_DEPTH > 1 + if (!api->get_foreground) + api->get_foreground=lcd_get_foreground; + if (!api->get_background) + api->get_background=lcd_get_background; +#endif + if (!api->load_remote_wps_backdrop) + api->load_remote_wps_backdrop = load_remote_wps_backdrop2; + if (!api->load_wps_backdrop) + api->load_wps_backdrop = load_wps_backdrop2; + //dbgf = printf; +} + +/************************************************************** + +**************************************************************/ + +int set_api(struct proxy_api* api) { + if (api->debugf) + dbgf = api->debugf; + screens[0].screen_type=SCREEN_MAIN; + screens[0].lcdwidth=LCD_WIDTH; + screens[0].lcdheight=LCD_HEIGHT; + screens[0].depth=LCD_DEPTH; +#ifdef HAVE_LCD_COLOR + screens[0].is_color=true; +#else + screens[0].is_color=false; +#endif + if (api->getwidth) + screens[0].getwidth = api->getwidth; + if (api->stop_scroll) + screens[0].stop_scroll=api->stop_scroll; + screens[0].scroll_stop = lcd_scroll_stop; + if (api->set_viewport) + screens[0].set_viewport=api->set_viewport; + if (api->clear_viewport) + screens[0].clear_viewport=lcd_clear_viewport; + if (api->getstringsize) + screens[0].getstringsize=api->getstringsize; + if (api->getwidth) + screens[0].getwidth=api->getwidth; + if (api->getheight) + screens[0].getheight=api->getheight; + if (api->set_drawmode) + screens[0].set_drawmode=api->set_drawmode; + if (api->fillrect) + screens[0].fillrect=api->fillrect; + if (api->puts_scroll) + screens[0].puts_scroll=api->puts_scroll; + if (api->transparent_bitmap_part) + screens[0].transparent_bitmap_part=api->transparent_bitmap_part; + if (api->update) + screens[0].update=api->update; + if (api->clear_display) + screens[0].clear_display=api->clear_display; + if (api->getfont) + screens[0].getfont=api->getfont; + if (api->hline) + screens[0].hline=api->hline; + if (api->vline) + screens[0].vline=api->vline; + if (api->drawpixel) + screens[0].drawpixel=api->drawpixel; + if (api->putsxy) + screens[0].putsxy=api->putsxy; +#if LCD_DEPTH > 1 + if (api->get_foreground) + screens[0].get_foreground=api->get_foreground; + if (api->get_background) + screens[0].get_background=api->get_background; +#endif + + screens[0].bitmap_part = api->bitmap_part; + /************************** + * OUT * + **************************/ + api->get_model_name = get_model_name; + api->get_current_vp = get_current_vp; + api->set_wpsstate = set_wpsstate; + api->set_trackstate = set_trackstate; + api->set_next_trackstate= set_next_trackstate; + api->set_audio_status= set_audio_status; + xapi = api; + return 0; +} + + + + + + diff --git a/utils/wpseditor/libwps/src/api.h b/utils/wpseditor/libwps/src/api.h new file mode 100644 index 0000000000..86bb1a6597 --- /dev/null +++ b/utils/wpseditor/libwps/src/api.h @@ -0,0 +1,85 @@ +#ifndef API_H_INCLUDED +#define API_H_INCLUDED +#include +#include +#include "defs.h" +#include "wpsstate.h" +#ifdef __PCTOOL__ +#include "dummies.h" +#endif + +struct viewport_api { + int x; + int y; + int width; + int height; + int font; + int drawmode; + unsigned fg_pattern; + unsigned bg_pattern; + unsigned lss_pattern; + unsigned lse_pattern; + unsigned lst_pattern; + + //TODO: ?? + int fontheight; + int fontwidth; +}; + +struct proxy_api +{ + bool (*load_remote_wps_backdrop)(char* file_name); + bool (*load_wps_backdrop)(char* file_name); + + unsigned (*get_foreground)(void); + unsigned (*get_background)(void); + int (*getwidth)(void); + int (*getheight)(void); + + void (*puts_scroll)(int x, int y, const unsigned char *string); + void (*putsxy)(int x, int y, const unsigned char *str); + int (*getfont)(); + int (*getstringsize)(const unsigned char *str, int *w, int *h); + void (*stop_scroll)(); + + void (*transparent_bitmap_part)(const void *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); + void (*bitmap_part)(const void *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); + void (*hline)(int x1, int x2, int y); + void (*vline)(int x, int y1, int y2); + void (*drawpixel)(int x, int y); + void (*set_drawmode)(int mode); + void (*fillrect)(int x, int y, int width, int height); + + + void (*update)(); + void (*set_viewport)(struct viewport* vp); + void (*clear_display)(void); + void (*clear_viewport)(int x,int y,int w,int h, int color); + + void* (*plugin_get_buffer)(size_t *buffer_size); + int (*read_bmp_file)(const char* filename,int *width, int *height); + void (*set_wpsstate)(struct wpsstate state); + void (*set_trackstate)(struct trackstate state); + void (*set_next_trackstate)(struct trackstate state); + void (*set_audio_status)(int status); + + pfdebugf debugf; + int verbose; + + +/************************** +* OUT * +**************************/ + const char* (*get_model_name)(); + void (*get_current_vp)(struct viewport_api *avp); + + +}; + +extern struct proxy_api *xapi; + +EXPORT int set_api(struct proxy_api* api); + +#endif // API_H_INCLUDED diff --git a/utils/wpseditor/libwps/src/defs.h b/utils/wpseditor/libwps/src/defs.h new file mode 100644 index 0000000000..810c8da238 --- /dev/null +++ b/utils/wpseditor/libwps/src/defs.h @@ -0,0 +1,41 @@ +#ifndef DEFS_H_INCLUDED +#define DEFS_H_INCLUDED + +typedef int (*pfdebugf)(const char* fmt,...); +extern pfdebugf dbgf; + +#ifdef BUILD_DLL +# define EXPORT __declspec(dllexport) +#else +# define EXPORT +#endif + +#ifndef MIN +# define MIN(a, b) (((a)<(b))?(a):(b)) +#endif + +#ifndef MAX +# define MAX(a, b) (((a)>(b))?(a):(b)) +#endif + +#define SWAP_16(x) ((typeof(x))(unsigned short)(((unsigned short)(x) >> 8) | \ + ((unsigned short)(x) << 8))) + +#define SWAP_32(x) ((typeof(x))(unsigned long)( ((unsigned long)(x) >> 24) | \ + (((unsigned long)(x) & 0xff0000ul) >> 8) | \ + (((unsigned long)(x) & 0xff00ul) << 8) | \ + ((unsigned long)(x) << 24))) + +#define PLAYMODES_NUM 5 +enum api_playmode { + API_STATUS_PLAY, + API_STATUS_STOP, + API_STATUS_PAUSE, + API_STATUS_FASTFORWARD, + API_STATUS_FASTBACKWARD +}; + +extern enum api_playmode playmodes[PLAYMODES_NUM]; +extern const char *playmodeNames[]; + +#endif // DEFS_H_INCLUDED diff --git a/utils/wpseditor/libwps/src/dummies.c b/utils/wpseditor/libwps/src/dummies.c new file mode 100644 index 0000000000..8592610701 --- /dev/null +++ b/utils/wpseditor/libwps/src/dummies.c @@ -0,0 +1,363 @@ +#include +#include +#include "dummies.h" +#include "proxy.h" + +struct user_settings global_settings; + +struct wps_state wps_state; +struct gui_wps gui_wps[NB_SCREENS]; +struct wps_data wps_datas[NB_SCREENS]; +struct cuesheet *curr_cue; +struct cuesheet *temp_cue; +struct system_status global_status; +struct gui_syncstatusbar statusbars; +struct playlist_info current_playlist; +struct font sysfont; +int battery_percent = 100; +struct mp3entry current_song, next_song; +int _audio_status; + +charger_input_state_type charger_input_state; +#if CONFIG_CHARGING >= CHARGING_MONITOR +charge_state_type charge_state; +#endif + +#if defined(CPU_PP) && defined(BOOTLOADER) +/* We don't enable interrupts in the iPod bootloader, so we need to fake +the current_tick variable */ +#define current_tick (signed)(USEC_TIMER/10000) +#else +volatile long current_tick; +#endif + + +void dummies_init(){ + sysfont.height = 9; + sysfont.maxwidth = 6; + global_settings.statusbar=true; +} + +int playlist_amount_ex(const struct playlist_info* playlist); +void sound_set_volume(int value) +{ + DEBUGF3("sound_set_volume(int value=%d)",value); + global_settings.volume = value; +} +int sound_get_pitch(void) +{ + return 0; +} +int sound_min(int setting) +{ + DEBUGF3("sound_min(int setting=%d)",setting); + return -78; //audiohw_settings[setting].minval; +} + +void sleep(int hz) +{ +} + +void audio_init(void){} +void audio_wait_for_init(void){} +void audio_play(long offset){} +void audio_stop(void){} +void audio_pause(void){} +void audio_resume(void){} +void audio_next(void){} +void audio_prev(void){} +int audio_status(void) +{ + return _audio_status; +} + +#if CONFIG_CODEC == SWCODEC +int audio_track_count(void){return 0;} /* SWCODEC only */ +long audio_filebufused(void){return 0;} /* SWCODEC only */ +void audio_pre_ff_rewind(void){} /* SWCODEC only */ +#endif /* CONFIG_CODEC == SWCODEC */ +void audio_ff_rewind(long newtime){} +void audio_flush_and_reload_tracks(void){} +#ifdef HAVE_ALBUMART +int audio_current_aa_hid(void){return -1;} +#endif +struct mp3entry* audio_current_track(void){return 0;} +struct mp3entry* audio_next_track(void){return 0;} +bool audio_has_changed_track(void) +{ + return false; +} + +int get_sleep_timer(void){return 0;} + + +int battery_level(void){return battery_percent;} /* percent */ +int battery_time(void){return 0;} /* minutes */ +unsigned int battery_adc_voltage(void){return 0;} /* voltage from ADC in millivolts */ +unsigned int battery_voltage(void){return 0;} /* filtered batt. voltage in millivolts */ +int get_radio_status(void){return 0;} + + +/* returns full path of playlist (minus extension) */ +char *playlist_name(const struct playlist_info* playlist, char *buf, +int buf_size) +{ + char *sep; + + if (!playlist) + return "no"; + + snprintf(buf, buf_size, "%s", playlist->filename+playlist->dirlen); + + if (!buf[0]) + return NULL; + + /* Remove extension */ + sep = strrchr(buf, '.'); + if(sep) + *sep = 0; + + return buf; +} +int playlist_get_display_index(void) +{ + return 1; +} + +void gui_syncsplash(int ticks, const unsigned char *fmt, ...) +{ + +} + +void splash(int ticks, const unsigned char *fmt, ...) +{ + +} + +void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw){ + DEBUGF3("gui_statusbar_draw"); +} + +void yield(void){} + + +/* returns true if cuesheet support is initialised */ +bool cuesheet_is_enabled(void){return false;} + +/* allocates the cuesheet buffer */ +void cuesheet_init(void){} + +/* looks if there is a cuesheet file that has a name matching "trackpath" */ +bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path){return false;} + +/* parse cuesheet "file" and store the information in "cue" */ +bool parse_cuesheet(char *file, struct cuesheet *cue){return false;} + +/* reads a cuesheet to find the audio track associated to it */ +bool get_trackname_from_cuesheet(char *filename, char *buf){return false;} + +/* display a cuesheet struct */ +void browse_cuesheet(struct cuesheet *cue){} + +/* display a cuesheet file after parsing and loading it to the plugin buffer */ +bool display_cuesheet_content(char* filename){return false;} + +/* finds the index of the current track played within a cuesheet */ +int cue_find_current_track(struct cuesheet *cue, unsigned long curpos){return 0;} + +/* update the id3 info to that of the currently playing track in the cuesheet */ +void cue_spoof_id3(struct cuesheet *cue, struct mp3entry *id3){} + +/* skip to next track in the cuesheet towards "direction" (which is 1 or -1) */ +bool curr_cuesheet_skip(int direction, unsigned long curr_pos){return false;} + +#ifdef HAVE_LCD_BITMAP +/* draw track markers on the progressbar */ +void cue_draw_markers(struct screen *screen, unsigned long tracklen, +int x1, int x2, int y, int h){} +#endif + + +void draw_album_art(struct gui_wps *gwps, int handle_id, bool clear) +{ + if (!gwps || !gwps->data || !gwps->display || handle_id < 0) + return; + + struct wps_data *data = gwps->data; + +#ifdef HAVE_REMOTE_LCD + /* No album art on RWPS */ + if (data->remote_wps) + return; +#endif + + struct bitmap *bmp; + /* if (bufgetdata(handle_id, 0, (void *)&bmp) <= 0) + return;*/ + + short x = data->albumart_x; + short y = data->albumart_y; + short width = bmp->width; + short height = bmp->height; + + if (data->albumart_max_width > 0) + { + /* Crop if the bitmap is too wide */ + width = MIN(bmp->width, data->albumart_max_width); + + /* Align */ + if (data->albumart_xalign & WPS_ALBUMART_ALIGN_RIGHT) + x += data->albumart_max_width - width; + else if (data->albumart_xalign & WPS_ALBUMART_ALIGN_CENTER) + x += (data->albumart_max_width - width) / 2; + } + + if (data->albumart_max_height > 0) + { + /* Crop if the bitmap is too high */ + height = MIN(bmp->height, data->albumart_max_height); + + /* Align */ + if (data->albumart_yalign & WPS_ALBUMART_ALIGN_BOTTOM) + y += data->albumart_max_height - height; + else if (data->albumart_yalign & WPS_ALBUMART_ALIGN_CENTER) + y += (data->albumart_max_height - height) / 2; + } + + if (!clear) + { + /* Draw the bitmap */ + gwps->display->set_drawmode(DRMODE_FG); + gwps->display->bitmap_part((fb_data*)bmp->data, 0, 0, bmp->width, + x, y, width, height); + gwps->display->set_drawmode(DRMODE_SOLID); + } + else + { + /* Clear the bitmap */ + gwps->display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + gwps->display->fillrect(x, y, width, height); + gwps->display->set_drawmode(DRMODE_SOLID); + } +} + +/* Update the "data" pointer to make the handle's data available to the caller. +Return the length of the available linear data or < 0 for failure (handle +not found). +The caller is blocked until the requested amount of data is available. +size is the amount of linear data requested. it can be 0 to get as +much as possible. +The guard buffer may be used to provide the requested size. This means it's +unsafe to request more than the size of the guard buffer. +*/ +size_t bufgetdata(int handle_id, size_t size, void **data) +{ + + + return size; +} + + +void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars, +bool force_redraw) +{ +#ifdef HAVE_LCD_BITMAP + if(!global_settings.statusbar) + return; +#endif /* HAVE_LCD_BITMAP */ + int i; + FOR_NB_SCREENS(i) { + gui_statusbar_draw( &(bars->statusbars[i]), force_redraw ); + } +} +void unload_wps_backdrop(void) +{ + +} + +#if CONFIG_CODEC == SWCODEC +int get_replaygain_mode(bool have_track_gain, bool have_album_gain) +{ + int type; + + bool track = ((global_settings.replaygain_type == REPLAYGAIN_TRACK) + || ((global_settings.replaygain_type == REPLAYGAIN_SHUFFLE) + && global_settings.playlist_shuffle)); + + type = (!track && have_album_gain) ? REPLAYGAIN_ALBUM + : have_track_gain ? REPLAYGAIN_TRACK : -1; + + return type; +} +#endif + +/* Common functions for all targets */ +void rtc_init(void){} +int rtc_read_datetime(unsigned char* buf){return 0;} +int rtc_write_datetime(unsigned char* buf){return 0;} + +void backlight_on(void){} +void backlight_off(void){} + + +void debugf(const char *fmt, ...) +{} +void panicf( const char *fmt, ...) +{ +} + +off_t filesize(int fd){return 0;} + +int playlist_amount(void) +{ + return playlist_amount_ex(NULL); +} +int playlist_amount_ex(const struct playlist_info* playlist) +{ + if (!playlist) + playlist = ¤t_playlist; + + return playlist->amount; +} + +int get_action(int context, int timeout) +{ + return 0; +} + +void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, + int height){} + +void pcm_calculate_rec_peaks(int *left, int *right) +{ +} +void pcm_calculate_peaks(int *left, int *right) +{ +} +bool led_read(int delayticks) /* read by status bar update */ +{ + return false; +} + +#ifndef HAS_BUTTON_HOLD +bool is_keys_locked(void) +{ + return false; +} +#endif + +long default_event_handler_ex(long event, void (*callback)(void *), void *parameter) +{ + return 0; +} + +long default_event_handler(long event) +{ + return default_event_handler_ex(event, NULL, NULL); +} + +void ab_draw_markers(struct screen * screen, int capacity, + int x0, int x1, int y, int h) + { + } +void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude){} diff --git a/utils/wpseditor/libwps/src/dummies.h b/utils/wpseditor/libwps/src/dummies.h new file mode 100644 index 0000000000..2bfce1d53b --- /dev/null +++ b/utils/wpseditor/libwps/src/dummies.h @@ -0,0 +1,44 @@ +#ifndef DUMMIES_H_INCLUDED +#define DUMMIES_H_INCLUDED + +#include + +#include "settings.h" +#include "gwps.h" +#include "lang.h" +#include "powermgmt.h" +#include "font.h" +#include "playlist.h" + +#include "defs.h" + +extern struct font sysfont; +extern struct user_settings global_settings; +extern struct wps_state wps_state; +extern struct gui_wps gui_wps[NB_SCREENS]; +extern struct wps_data wps_datas[NB_SCREENS]; +extern struct cuesheet *curr_cue; +extern struct cuesheet *temp_cue; +extern struct system_status global_status; +extern struct gui_syncstatusbar statusbars; +extern struct playlist_info current_playlist; +extern int battery_percent; +extern struct mp3entry current_song, next_song; +extern int _audio_status; + +charger_input_state_type charger_input_state; +#if CONFIG_CHARGING >= CHARGING_MONITOR +extern charge_state_type charge_state; +#endif + +#if defined(CPU_PP) && defined(BOOTLOADER) +/* We don't enable interrupts in the iPod bootloader, so we need to fake +the current_tick variable */ +#define current_tick (signed)(USEC_TIMER/10000) +#else +extern volatile long current_tick; +#endif + +void dummies_init(); + +#endif /*DUMMIES_H_INCLUDED*/ diff --git a/utils/wpseditor/libwps/src/include/lang.h b/utils/wpseditor/libwps/src/include/lang.h new file mode 100644 index 0000000000..3274bdec6c --- /dev/null +++ b/utils/wpseditor/libwps/src/include/lang.h @@ -0,0 +1,10 @@ +#define LANG_END_PLAYLIST (signed char)1 +#define LANG_KEYLOCK_ON (signed char)2 +#define LANG_KEYLOCK_OFF (signed char)3 +#define LANG_WEEKDAY_SUNDAY (signed char)4 +#define LANG_MONTH_JANUARY (signed char)5 +#define VOICE_PAUSE (signed char)6 +#define LANG_BATTERY_TIME (signed char)7 +#define UNIT_PERCENT (signed char)8 + +#define str(...) "empty" diff --git a/utils/wpseditor/libwps/src/include/rockboxlogo.h b/utils/wpseditor/libwps/src/include/rockboxlogo.h new file mode 100644 index 0000000000..8d1c8b69c3 --- /dev/null +++ b/utils/wpseditor/libwps/src/include/rockboxlogo.h @@ -0,0 +1 @@ + diff --git a/utils/wpseditor/libwps/src/include/sysfont.h b/utils/wpseditor/libwps/src/include/sysfont.h new file mode 100644 index 0000000000..4ba770347c --- /dev/null +++ b/utils/wpseditor/libwps/src/include/sysfont.h @@ -0,0 +1 @@ +#define SYSFONT_HEIGHT 9 diff --git a/utils/wpseditor/libwps/src/include/system-target.h b/utils/wpseditor/libwps/src/include/system-target.h new file mode 100644 index 0000000000..8d1c8b69c3 --- /dev/null +++ b/utils/wpseditor/libwps/src/include/system-target.h @@ -0,0 +1 @@ + diff --git a/utils/wpseditor/libwps/src/lcd.c b/utils/wpseditor/libwps/src/lcd.c new file mode 100644 index 0000000000..1f12332750 --- /dev/null +++ b/utils/wpseditor/libwps/src/lcd.c @@ -0,0 +1,150 @@ +#include "font.h" +#include "screen_access.h" +//#include +#include "api.h" +#include "defs.h" +#include "proxy.h" +#include "dummies.h" + +static struct viewport default_vp = +{ + .x = 0, + .y = 0, + .width = LCD_WIDTH, + .height = LCD_HEIGHT, + .font = FONT_SYSFIXED, + .drawmode = DRMODE_SOLID, + .fg_pattern = LCD_DEFAULT_FG, + .bg_pattern = LCD_DEFAULT_BG, + .lss_pattern = LCD_DEFAULT_BG, + .lse_pattern = LCD_DEFAULT_BG, + .lst_pattern = LCD_DEFAULT_BG, +}; + +struct viewport* current_vp = &default_vp; + +void get_current_vp(struct viewport_api *avp){ + avp->x = current_vp->x; + avp->y = current_vp->y; + avp->width = current_vp->width; + avp->height = current_vp->height; + + //TODO: font_get(current_vp->font)->height; + avp->fontheight = sysfont.height; +} + +void lcd_set_viewport(struct viewport* vp) +{ + if (vp == NULL){ + current_vp = &default_vp; + DEBUGF3("lcd_set_viewport(struct viewport* vp= DEFAULT)\n"); + } + else{ + current_vp = vp; + DEBUGF3("lcd_set_viewport(struct viewport* vp=%x,vpx=%d,vpy=%d,vpw=%d,vph=%d)\n",vp,vp->x,vp->y,vp->width,vp->height); + } +} + +void lcd_update_viewport(void) +{ + //lcd_update_rect(current_vp->x, current_vp->y,current_vp->width, current_vp->height); +} + +void lcd_update_viewport_rect(int x, int y, int width, int height) +{ + //lcd_update_rect(current_vp->x + x, current_vp->y + y, width, height); +} +/*** parameter handling ***/ + +void lcd_set_drawmode(int mode) +{ + current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); +} + +int lcd_get_drawmode(void) +{ + return current_vp->drawmode; +} + +void lcd_set_foreground(unsigned color) +{ + current_vp->fg_pattern = color; +} + +unsigned lcd_get_foreground(void) +{ + return current_vp->fg_pattern; +} + +void lcd_set_background(unsigned color) +{ + current_vp->bg_pattern = color; +} + +unsigned lcd_get_background(void) +{ + return current_vp->bg_pattern; +} + +void lcd_set_selector_start(unsigned color) +{ + current_vp->lss_pattern = color; +} + +void lcd_set_selector_end(unsigned color) +{ + current_vp->lse_pattern = color; +} + +void lcd_set_selector_text(unsigned color) +{ + current_vp->lst_pattern = color; +} + +void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color) +{ + //lcd_set_drawmode(mode); + current_vp->fg_pattern = fg_color; + current_vp->bg_pattern = bg_color; +} + +int lcd_getwidth(void) +{ + return current_vp->width; +} + +int lcd_getheight(void) +{ + return current_vp->height; +} + +void lcd_setfont(int newfont) +{ + current_vp->font = newfont; +} + +int lcd_getfont(void) +{ + return current_vp->font; +} + +/* Clear the whole display */ +void lcd_clear_display(void) +{ + struct viewport* old_vp = current_vp; + + current_vp = &default_vp; + + lcd_clear_viewport(); + + current_vp = old_vp; +} + +void lcd_clear_viewport(){ + DEBUGF2("lcd_clear_viewport()\n"); + xapi->clear_viewport(current_vp->x,current_vp->y,current_vp->width,current_vp->height,current_vp->bg_pattern); + +} +void lcd_scroll_stop(struct viewport* vp){ + DEBUGF3("lcd_scroll_stop(struct viewport* vp=%x)\n",vp); +} diff --git a/utils/wpseditor/libwps/src/proxy.c b/utils/wpseditor/libwps/src/proxy.c new file mode 100644 index 0000000000..3a3b8ce4d9 --- /dev/null +++ b/utils/wpseditor/libwps/src/proxy.c @@ -0,0 +1,132 @@ +#include +#include +#include "dummies.h" +#include "proxy.h" +#include "api.h" +#include "gwps.h" +#include "gwps-common.h" +#include + +struct screen screens[NB_SCREENS]; +struct wps_data wpsdata; +struct gui_wps gwps; +struct mp3entry id3; +struct mp3entry nid3; + +extern void test_api(struct proxy_api *api); + +bool debug_wps = true; +int wps_verbose_level = 0; +int errno_; +pfdebugf dbgf = 0; + +static char pluginbuf[PLUGIN_BUFFER_SIZE]; + +const char* get_model_name(){ +#ifdef TARGET_MODEL + return TARGET_MODEL; +#else + return "unknown"; +#endif +} + +int read_line(int fd, char* buffer, int buffer_size) +{ + int count = 0; + int num_read = 0; + + errno_ = 0; + + while (count < buffer_size) + { + unsigned char c; + + if (1 != read(fd, &c, 1)) + break; + + num_read++; + + if ( c == '\n' ) + break; + + if ( c == '\r' ) + continue; + + buffer[count++] = c; + } + + buffer[MIN(count, buffer_size - 1)] = 0; + + return errno_ ? -1 : num_read; +} + +void* plugin_get_buffer(size_t *buffer_size) +{ + *buffer_size = PLUGIN_BUFFER_SIZE; + return pluginbuf; +} + +int checkwps(const char *filename, int verbose){ + int res; + int fd; + + struct wps_data wps; + wps_verbose_level = verbose; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + DEBUGF1("Failed to open %s\n",filename); + return 2; + } + close(fd); + + res = wps_data_load(&wps, &screens[0], filename, true); + + if (!res) { + DEBUGF1("WPS parsing failure\n"); + return 3; + } + + DEBUGF1("WPS parsed OK\n"); + return 0; +} + +int wps_init(const char* filename,struct proxy_api *api, bool isfile){ + int res; + if (!api) + return 4; + dummies_init(); + test_api(api); + set_api(api); + wps_data_init(&wpsdata); + wps_verbose_level = api->verbose; + res = wps_data_load(&wpsdata, &screens[0], filename, isfile); + if (!res) + { + DEBUGF1("ERR: WPS parsing failure\n"); + return 3; + } + DEBUGF1("WPS parsed OK\n"); + DEBUGF1("\n-------------------------------------------------\n"); + wps_state.paused = true; + gwps.data = &wpsdata; + gwps.display = &screens[0]; + gwps.state = &wps_state; + gwps.state->id3 = &id3; + gwps.state->nid3 = &nid3; + gui_wps[0] = gwps; + return res; +} + +int wps_display(){ + DEBUGF3("wps_display(): begin\n"); + int res = gui_wps_display(); + DEBUGF3("\nWPS %sdisplayed\n", (res ? "" : "not ")); + return res; +} +int wps_refresh(){ + DEBUGF3("----------------------------------\n"); + int res = gui_wps_refresh(&gwps, 0, WPS_REFRESH_ALL); + DEBUGF3("\nWPS %srefreshed\n", (res ? "" : "not ")); + return res; +} diff --git a/utils/wpseditor/libwps/src/proxy.h b/utils/wpseditor/libwps/src/proxy.h new file mode 100644 index 0000000000..3836ecc6d0 --- /dev/null +++ b/utils/wpseditor/libwps/src/proxy.h @@ -0,0 +1,25 @@ +#ifndef PROXY_H +#define PROXY_h + +#include "screen_access.h" +#include "api.h" +#include "defs.h" + +#define DEBUGF dbgf +#define DEBUGF1 dbgf +#define DEBUGF2(...) +#define DEBUGF3(...) + +EXPORT int checkwps(const char *filename, int verbose); +EXPORT int wps_init(const char* filename,struct proxy_api *api,bool isfile); +EXPORT int wps_display(); +EXPORT int wps_refresh(); + +const char* get_model_name(); + +extern struct screen screens[NB_SCREENS]; +extern bool debug_wps; +extern int wps_verbose_level; + + +#endif diff --git a/utils/wpseditor/libwps/src/wpsstate.h b/utils/wpseditor/libwps/src/wpsstate.h new file mode 100644 index 0000000000..148936a481 --- /dev/null +++ b/utils/wpseditor/libwps/src/wpsstate.h @@ -0,0 +1,34 @@ +#ifndef STATES_H +#define STATES_H +// +struct trackstate +{ + char* title; + char* artist; + char* album; + char* genre_string; + char* disc_string; + char* track_string; + char* year_string; + char* composer; + char* comment; + char* albumartist; + char* grouping; + int discnum; + int tracknum; + int version; + int layer; + int year; + + int length; + int elapsed; +}; + +struct wpsstate{ + int volume; + int fontheight; + int fontwidth; + int battery_level; + int audio_status; +}; +#endif diff --git a/utils/wpseditor/libwps/targets.txt b/utils/wpseditor/libwps/targets.txt new file mode 100644 index 0000000000..d2c54378d9 --- /dev/null +++ b/utils/wpseditor/libwps/targets.txt @@ -0,0 +1,33 @@ +ARCHOS_RECORDER recorder +ARCHOS_FMRECORDER fmrecorder +ARCHOS_RECORDERV2 recorderv2 +ARCHOS_ONDIOSP ondiosp +ARCHOS_ONDIOFM ondiofm +IRIVER_H120 h120 +IRIVER_H300 h300 +IRIVER_H100 h100 +IRIVER_IFP7XX ifp7xx +IRIVER_H10 h10 +IRIVER_H10_5GB h10_5gb +IPOD_COLOR ipodcolor +IPOD_NANO ipodnano +IPOD_VIDEO ipodvideo +IPOD_3G ipod3g +IPOD_4G ipod4g +IPOD_MINI ipodmini +IPOD_MINI2G ipodmini2g +IPOD_1G2G ipod1g2g +IAUDIO_X5 x5 +IAUDIO_M5 m5 +COWON_D2 cowond2 +IAUDIO_M3 m3 +GIGABEAT_F gigabeatf +GIGABEAT_S gigabeats +MROBE_500 mrobe500 +MROBE_100 mrobe100 +LOGIK_DAX logikdax +CREATIVE_ZVM creativezvm +SANSA_E200 e200 +SANSA_E200 e200r +SANSA_C200 c200 +ELIO_TPJ1022 tpj1022 diff --git a/utils/wpseditor/wpseditor.pro b/utils/wpseditor/wpseditor.pro new file mode 100644 index 0000000000..0e9ecbbf51 --- /dev/null +++ b/utils/wpseditor/wpseditor.pro @@ -0,0 +1,2 @@ +SUBDIRS =gui/src/QPropertyEditor gui +TEMPLATE = subdirs -- cgit