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
This commit is contained in:
Frank Gevaerts 2008-08-29 21:08:38 +00:00
parent cc31b1fbda
commit 5d22e3cbdd
57 changed files with 3711 additions and 33 deletions

View File

@ -25,7 +25,11 @@
#include <string.h>
#include "gwps.h"
#ifdef __PCTOOL__
#ifdef WPSEDITOR
#include "proxy.h"
#else
#define DEBUGF printf
#endif
#else
#include "debug.h"
#endif
@ -589,18 +593,18 @@ void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line
{
char buf[64];
DEBUGF("Failed parsing on line %d : ", line);
DEBUGF("ERR: Failed parsing on line %d : ", line);
switch (fail)
{
case PARSE_OK:
break;
case PARSE_FAIL_UNCLOSED_COND:
DEBUGF("Unclosed conditional");
DEBUGF("ERR: Unclosed conditional");
break;
case PARSE_FAIL_INVALID_CHAR:
DEBUGF("unexpected conditional char after token %d: \"%s\"",
DEBUGF("ERR: Unexpected conditional char after token %d: \"%s\"",
data->num_tokens-1,
get_token_desc(&data->tokens[data->num_tokens-1], data,
buf, sizeof(buf))
@ -608,7 +612,7 @@ void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line
break;
case PARSE_FAIL_COND_SYNTAX_ERROR:
DEBUGF("Conditional syntax error after token %d: \"%s\"",
DEBUGF("ERR: Conditional syntax error after token %d: \"%s\"",
data->num_tokens-1,
get_token_desc(&data->tokens[data->num_tokens-1], data,
buf, sizeof(buf))
@ -616,7 +620,7 @@ void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line
break;
case PARSE_FAIL_COND_INVALID_PARAM:
DEBUGF("Invalid parameter list for token %d: \"%s\"",
DEBUGF("ERR: Invalid parameter list for token %d: \"%s\"",
data->num_tokens,
get_token_desc(&data->tokens[data->num_tokens], data,
buf, sizeof(buf))
@ -624,7 +628,7 @@ void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line
break;
case PARSE_FAIL_LIMITS_EXCEEDED:
DEBUGF("Limits exceeded");
DEBUGF("ERR: Limits exceeded");
break;
}
DEBUGF("\n");

View File

@ -28,14 +28,25 @@
#include "plugin.h"
#ifdef __PCTOOL__
#ifdef WPSEDITOR
#include "proxy.h"
#include "settings.h"
#include "sysfont.h"
#include "gwps.h"
#include "font.h"
#include "bmp.h"
#include "backdrop.h"
#include "ctype.h"
#else
#include "checkwps.h"
#define SYSFONT_HEIGHT 8
#define DEBUGF printf
#endif /*WPSEDITOR*/
#define FONT_SYSFIXED 0
#define FONT_UI 1
#define SYSFONT_HEIGHT 8
#include "checkwps.h"
#else
#include "debug.h"
#endif
#endif /*__PCTOOL__*/
#ifndef __PCTOOL__
#include <ctype.h>

View File

@ -27,7 +27,10 @@
#ifdef __PCTOOL__
#include <stdint.h>
#include <stdarg.h>
#include <unistd.h>
#include <stdio.h>
#ifdef WPSEDITOR
#include "string.h"
#endif
#else
#include "sprintf.h"
#include "lang.h"
@ -196,26 +199,6 @@ char *create_numbered_filename(char *buffer, const char *path,
return buffer;
}
/* Format time into buf.
*
* buf - buffer to format to.
* buf_size - size of buffer.
* t - time to format, in milliseconds.
*/
void format_time(char* buf, int buf_size, long t)
{
if ( t < 3600000 )
{
snprintf(buf, buf_size, "%d:%02d",
(int) (t / 60000), (int) (t % 60000 / 1000));
}
else
{
snprintf(buf, buf_size, "%d:%02d:%02d",
(int) (t / 3600000), (int) (t % 3600000 / 60000),
(int) (t % 60000 / 1000));
}
}
#if CONFIG_RTC
/* Create a filename with a date+time part.
@ -1179,6 +1162,28 @@ char *strip_extension(char* buffer, int buffer_size, const char *filename)
}
#endif /* !defined(__PCTOOL__) */
/* Format time into buf.
*
* buf - buffer to format to.
* buf_size - size of buffer.
* t - time to format, in milliseconds.
*/
void format_time(char* buf, int buf_size, long t)
{
if ( t < 3600000 )
{
snprintf(buf, buf_size, "%d:%02d",
(int) (t / 60000), (int) (t % 60000 / 1000));
}
else
{
snprintf(buf, buf_size, "%d:%02d:%02d",
(int) (t / 3600000), (int) (t % 3600000 / 60000),
(int) (t % 60000 / 1000));
}
}
/** Open a UTF-8 file and set file descriptor to first byte after BOM.
* If no BOM is present this behaves like open().
* If the file is opened for writing and O_TRUNC is set, write a BOM to

View File

@ -51,6 +51,9 @@ struct opt_items {
/* name of directory where configuration, fonts and other data
* files are stored */
#ifdef __PCTOOL__
#undef ROCKBOX_DIR
#undef ROCKBOX_DIR_LEN
#undef WPS_DIR
#define ROCKBOX_DIR "."
#define ROCKBOX_DIR_LEN 1
#else

View File

@ -413,6 +413,7 @@ Daniel Weck
Clément Pit-Claudel
Jelle Geerts
Tadeusz Pyś
Rostislav Chekan
The libmad team
The wavpack team

View File

@ -522,9 +522,11 @@ void glyph_cache_save(void)
{
if (fnt_file >= 0) {
#ifdef WPSEDITOR
glyph_file = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC);
#else
glyph_file = creat(GLYPH_CACHE_FILE);
#endif
if (glyph_file < 0) return;
lru_traverse(&font_cache_ui._lru, glyph_file_write);

View File

@ -22,6 +22,8 @@
#ifndef __INTTYPES_H__
#define __INTTYPES_H__
#ifndef WPSEDITOR
#include <limits.h>
/* 8 bit */
@ -103,5 +105,8 @@
#define uint64_t unsigned long long
#endif
#else
#include <stdint.h>
#endif /* !WPSEDITOR*/
#endif /* __INTTYPES_H__ */

View File

@ -7,6 +7,11 @@
#ifndef _TIME_H_
#define _TIME_H_
#ifdef WPSEDITOR
#include <sys/types.h>
#include <time.h>
#endif
struct tm
{
int tm_sec;
@ -34,3 +39,4 @@ struct tm *localtime(const time_t *timep);
#endif /* _TIME_H_ */

View File

@ -550,6 +550,7 @@ int get_mp3file_info(int fd, struct mp3info *info)
return bytecount;
}
#ifndef __PCTOOL__
static void long2bytes(unsigned char *buf, long val)
{
buf[0] = (val >> 24) & 0xff;
@ -558,7 +559,6 @@ static void long2bytes(unsigned char *buf, long val)
buf[3] = val & 0xff;
}
#ifndef __PCTOOL__
int count_mp3_frames(int fd, int startpos, int filesize,
void (*progressfunc)(int))
{

21
utils/wpseditor/README Normal file
View File

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

7
utils/wpseditor/TODO Normal file
View File

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

View File

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

View File

@ -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 <Qt/qcolordialog.h>
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<QColor>(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));
}
}

View File

@ -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 <Qt/qcombobox.h>
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

View File

@ -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 <http://www.gnu.org/licenses/>.
//
// ****************************************************************************************
#include "Property.h"
#include "ColorCombo.h"
#include <Qt/qmetaobject.h>
#include <Qt/qspinbox.h>
#include <limits.h>
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<ColorCombo*>(editor)->setColor(data.value<QColor>());
return true;
;
case QVariant::Int:
editor->blockSignals(true);
static_cast<QSpinBox*>(editor)->setValue(data.toInt());
editor->blockSignals(false);
return true;
case QMetaType::Float:
case QVariant::Double:
editor->blockSignals(true);
static_cast<QDoubleSpinBox*>(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<ColorCombo*>(editor)->color());
case QVariant::Int:
return QVariant(static_cast<QSpinBox*>(editor)->value());
case QMetaType::Float:
case QVariant::Double:
return QVariant(static_cast<QDoubleSpinBox*>(editor)->value());
break;
default:
return QVariant();
}
}
Property* Property::findPropertyObject(QObject* propertyObject) {
if (m_propertyObject == propertyObject)
return this;
for (int i=0; i<children().size(); ++i) {
Property* child = static_cast<Property*>(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));
}

View File

@ -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 <Qt/qwidget.h>
#include <Qt/qstyleoption.h>
#include <Qt/qvariant.h>
/**
* 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

View File

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

View File

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

View File

@ -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 <Qt/qtreeview.h>
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

View File

@ -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 <Qt/qapplication.h>
#include <Qt/qmetaobject.h>
#include <Qt/qitemeditorfactory.h>
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<Property*>(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<Property*>(index.internalPointer());
Property *parentItem = qobject_cast<Property*>(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<Property*>(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<Property*>(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<Property*>(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<Property*>(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<PropertyPair> propertyMap;
QList<const QMetaObject*> classList;
const QMetaObject* metaObject = propertyObject->metaObject();
do {
int count = metaObject->propertyCount();
for (int i=0; i<count; ++i) {
QMetaProperty property = metaObject->property(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<const QMetaObject*> 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<Property*>(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<Property*>(parentItem)), createIndex(parentItem->row(), 1, static_cast<Property*>(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;
}

View File

@ -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 <Qt/qabstractitemmodel.h>
#include <Qt/qmap.h>
#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

View File

@ -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 <Qt/qabstractitemview.h>
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<Property*>(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<Property*>(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<Property*>(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();
}
}
}

View File

@ -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 <Qt/qitemdelegate.h>
/**
* 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

View File

@ -0,0 +1,16 @@
#include <QApplication>
#include "qwpseditorwindow.h"
#include "utils.h"
#include <QPointer>
QPointer<QWpsEditorWindow> 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();
}

View File

@ -0,0 +1,41 @@
#include "qtrackstate.h"
#include <stdlib.h>
//
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);
}

View File

@ -0,0 +1,57 @@
#ifndef __QTRACKSTATE_H__
#define __QTRACKSTATE_H__
#include "wpsstate.h"
#include <QObject>
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__

View File

@ -0,0 +1,200 @@
#include "qwpsdrawer.h"
#include "slider.h"
#include "utils.h"
#include <QtGui>
#include <QLibrary>
#include <stdarg.h>
//
QPointer<QWpsDrawer> 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.5<avp.width ;i++) {
g.drawLine(int(i*avp.fontheight/1.5), 0, int(i*avp.fontheight/1.5), avp.height);
}
for (int j=0;j*avp.fontheight<avp.height; j++) {
g.drawLine(0,j*avp.fontheight,avp.width,j*avp.fontheight);
}
}
p.drawPixmap((rect.width()-pix->width())/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();
}

View File

@ -0,0 +1,82 @@
#ifndef WPSDRAWER_H
#define WPSDRAWER_H
//
#include <QWidget>
#include <QPixmap>
#include <QPointer>
#include <QTemporaryFile>
#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

View File

@ -0,0 +1,77 @@
#include "qwpsdrawer.h"
#include <QPainter>
#include <QFile>
#include <QFileInfo>
#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"<<img.width()<<img.height();
*width = img.width();
*height = img.height();
return 1;
}

View File

@ -0,0 +1,120 @@
#include "qwpseditorwindow.h"
#include "qwpsdrawer.h"
#include "utils.h"
#include <QFileDialog>
#include <QDebug>
#include <QInputDialog>
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;i<PLAYMODES_NUM;i++) {
QAction *act = new QAction(playmodeNames[i],this);
act->setCheckable(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"));
}

View File

@ -0,0 +1,45 @@
#ifndef MAINWINDOWIMPL_H
#define MAINWINDOWIMPL_H
//
#include <QMainWindow>
#include <QActionGroup>
#include <QSignalMapper>
#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<QWpsDrawer> drawer;
QHash<int, QAction*> 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

View File

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

View File

@ -0,0 +1,54 @@
#ifndef __WPSSTATE_H__
#define __WPSSTATE_H__
#include <QObject>
#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__

View File

@ -0,0 +1,20 @@
#include "slider.h"
#include <QDebug>
//
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));
}

View File

@ -0,0 +1,21 @@
#ifndef SLIDERIMPL_H
#define SLIDERIMPL_H
//
#include <QWidget>
#include <QDialog>
#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

View File

@ -0,0 +1,28 @@
#include "utils.h"
#include <QPointer>
#include <QtGlobal>
#include "qwpseditorwindow.h"
extern QPointer<QWpsEditorWindow> 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()<<s;
if (win==0)
qDebug()<<s;
if (s.indexOf("ERR")>=0)
s = "<font color=red>"+s+"</font>";
if (win!=0)
win->logMsg(s);
va_end(ap);
return s.length();
}
int qlogger(const QString& s) {
return qlogger(s.toAscii().data());
}

View File

@ -0,0 +1,12 @@
#ifndef __UTILS_H__
#define __UTILS_H__
#include <QDebug>
#define DEBUGF1 qlogger
#define DEBUGF2(...)
extern int qlogger(const char* fmt,...);
extern int qlogger(const QString& s);
#endif // __UTILS_H__

View File

@ -0,0 +1,290 @@
<ui version="4.0" >
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>882</width>
<height>669</height>
</rect>
</property>
<property name="windowTitle" >
<string>WPS Editor</string>
</property>
<widget class="QWidget" name="centralwidget" >
<property name="geometry" >
<rect>
<x>260</x>
<y>21</y>
<width>344</width>
<height>345</height>
</rect>
</property>
</widget>
<widget class="QMenuBar" name="menubar" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>882</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile" >
<property name="title" >
<string>File</string>
</property>
<addaction name="actOpenWps" />
<addaction name="actSetVolume" />
<addaction name="actSetProgress" />
<addaction name="actShowGrid" />
<addaction name="actClearLog" />
<addaction name="actVerboseLevel" />
<addaction name="actQuit" />
</widget>
<widget class="QMenu" name="menuPlay" >
<property name="title" >
<string>Play</string>
</property>
</widget>
<addaction name="menuFile" />
<addaction name="menuPlay" />
</widget>
<widget class="QStatusBar" name="statusbar" >
<property name="geometry" >
<rect>
<x>0</x>
<y>650</y>
<width>882</width>
<height>19</height>
</rect>
</property>
</widget>
<widget class="QDockWidget" name="dockPlainWps" >
<property name="geometry" >
<rect>
<x>0</x>
<y>370</y>
<width>882</width>
<height>280</height>
</rect>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="windowTitle" >
<string>PlainWps</string>
</property>
<attribute name="dockWidgetArea" >
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_3" >
<property name="geometry" >
<rect>
<x>0</x>
<y>22</y>
<width>882</width>
<height>258</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2" >
<item rowspan="2" row="0" column="0" >
<widget class="QTextEdit" name="plainWpsEdit" >
<property name="autoFillBackground" >
<bool>false</bool>
</property>
<property name="readOnly" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QPushButton" name="btnUpdatePlainWps" >
<property name="text" >
<string>Update WPS</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<spacer name="verticalSpacer" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>211</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="m_dockWidget" >
<property name="geometry" >
<rect>
<x>0</x>
<y>21</y>
<width>256</width>
<height>345</height>
</rect>
</property>
<property name="windowTitle" >
<string>Property Editor</string>
</property>
<attribute name="dockWidgetArea" >
<number>1</number>
</attribute>
<widget class="QPropertyEditorWidget" name="m_propertyEditor" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="geometry" >
<rect>
<x>0</x>
<y>22</y>
<width>256</width>
<height>323</height>
</rect>
</property>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget" >
<property name="geometry" >
<rect>
<x>608</x>
<y>21</y>
<width>274</width>
<height>345</height>
</rect>
</property>
<property name="minimumSize" >
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="windowTitle" >
<string>Log</string>
</property>
<attribute name="dockWidgetArea" >
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents" >
<property name="geometry" >
<rect>
<x>0</x>
<y>22</y>
<width>274</width>
<height>323</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" >
<widget class="QTextEdit" name="logEdit" >
<property name="autoFillBackground" >
<bool>false</bool>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<action name="actQuit" >
<property name="text" >
<string>Quit</string>
</property>
</action>
<action name="actOpenWps" >
<property name="text" >
<string>Open WPS</string>
</property>
</action>
<action name="actSetVolume" >
<property name="text" >
<string>Set Volume</string>
</property>
</action>
<action name="actSetProgress" >
<property name="text" >
<string>Set Progress</string>
</property>
</action>
<action name="actShowGrid" >
<property name="checkable" >
<bool>true</bool>
</property>
<property name="checked" >
<bool>false</bool>
</property>
<property name="text" >
<string>Show Grid</string>
</property>
</action>
<action name="actClearLog" >
<property name="text" >
<string>Clear Log</string>
</property>
</action>
<action name="actVerboseLevel" >
<property name="text" >
<string>Verbose Level</string>
</property>
</action>
<action name="actUpdatePlainWps" >
<property name="text" >
<string>Update WPS</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>QPropertyEditorWidget</class>
<extends>QTreeView</extends>
<header>QPropertyEditorWidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>btnUpdatePlainWps</sender>
<signal>clicked()</signal>
<receiver>actUpdatePlainWps</receiver>
<slot>trigger()</slot>
<hints>
<hint type="sourcelabel" >
<x>835</x>
<y>411</y>
</hint>
<hint type="destinationlabel" >
<x>-1</x>
<y>-1</y>
</hint>
</hints>
</connection>
<connection>
<sender>actQuit</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel" >
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel" >
<x>440</x>
<y>334</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,43 @@
<ui version="4.0" >
<class>slider</class>
<widget class="QWidget" name="slider" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>295</width>
<height>37</height>
</rect>
</property>
<property name="windowTitle" >
<string>Value</string>
</property>
<widget class="QSlider" name="horslider" >
<property name="geometry" >
<rect>
<x>0</x>
<y>10</y>
<width>291</width>
<height>21</height>
</rect>
</property>
<property name="minimum" >
<number>-78</number>
</property>
<property name="maximum" >
<number>24</number>
</property>
<property name="singleStep" >
<number>1</number>
</property>
<property name="value" >
<number>-78</number>
</property>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

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

View File

@ -0,0 +1,7 @@
#!/bin/sh
cat targets.txt | (
while read target model
do
make MODEL=$model TARGET=$target build
done
)

View File

@ -0,0 +1,7 @@
#!/bin/sh
cat targets.txt | (
while read target model
do
make MODEL=$model TARGET=$target clean
done
)

View File

@ -0,0 +1,268 @@
#include <stdio.h>
#include <stdlib.h>
#include "sound.h"
#include "api.h"
#include "proxy.h"
#include "dummies.h"
#include "scroll_engine.h"
#include "wpsstate.h"
#include <string.h>
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;
}

View File

@ -0,0 +1,85 @@
#ifndef API_H_INCLUDED
#define API_H_INCLUDED
#include <stdbool.h>
#include <stddef.h>
#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

View File

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

View File

@ -0,0 +1,363 @@
#include <string.h>
#include <stdio.h>
#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 = &current_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){}

View File

@ -0,0 +1,44 @@
#ifndef DUMMIES_H_INCLUDED
#define DUMMIES_H_INCLUDED
#include <stdio.h>
#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*/

View File

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

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
#define SYSFONT_HEIGHT 9

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,150 @@
#include "font.h"
#include "screen_access.h"
//#include <windef.h>
#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);
}

View File

@ -0,0 +1,132 @@
#include <stdio.h>
#include <stdlib.h>
#include "dummies.h"
#include "proxy.h"
#include "api.h"
#include "gwps.h"
#include "gwps-common.h"
#include <string.h>
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("-----------------<wps_refresh(): begin>-----------------\n");
int res = gui_wps_refresh(&gwps, 0, WPS_REFRESH_ALL);
DEBUGF3("\nWPS %srefreshed\n", (res ? "" : "not "));
return res;
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,2 @@
SUBDIRS =gui/src/QPropertyEditor gui
TEMPLATE = subdirs