usr/bin
usr/share/applications/hildon
+home/user/.jspeed/themes
src/rectangle.cpp \
src/pointer.cpp \
src/odometer.cpp \
- src/theme.cpp \
+ src/themeloader.cpp \
src/themescreen.cpp \
src/settings.cpp \
- src/detailwidget.cpp \
src/detailscreen.cpp \
src/graphicsscene.cpp \
src/mainmenu.cpp \
src/rectangle.h \
src/pointer.h \
src/odometer.h \
- src/theme.h \
+ src/themeloader.h \
src/themescreen.h \
src/settings.h \
- src/detailwidget.h \
src/detailscreen.h \
src/graphicsscene.h \
src/mainmenu.h \
BINDIR = $$PREFIX/bin
DATADIR =$$PREFIX/share
+ THEMEDIR = /home/user/.jspeed/themes
DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\"
#MAKE INSTALL
- INSTALLS += target desktop icon26 icon48 icon64
+ INSTALLS += target desktop themes icon26 icon48 icon64
target.path =$$BINDIR
desktop.path = $$DATADIR/applications/hildon
desktop.files += src/data/$${TARGET}.desktop
+ themes.path = $$THEMEDIR
+ themes.files += src/data/themes/graphical.jspeed
+
icon26.path = $$DATADIR/icons/hicolor/26x26/apps
icon26.files += src/data/26x26/$${TARGET}.png
+++ /dev/null
-/*
- * This file is part of jSpeed.
- *
- * jSpeed is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * jSpeed 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 jSpeed. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "detailwidget.h"
-#include "detailscreen.h"
-
-DetailWidget::DetailWidget(QWidget* parent): WidgetScreen(parent)
-{
- screen_ = new DetailScreen;
- connect(screen_, SIGNAL(minimizePressed()), this, SIGNAL(minimizePressed()));
- connect(screen_, SIGNAL(settingsPressed()), this, SIGNAL(settingsPressed()));
- connect(screen_, SIGNAL(closePressed()), this, SIGNAL(closePressed()));
- connect(screen_, SIGNAL(clicked()), this, SIGNAL(clicked()));
- addWidget(screen_);
-}
-
-void DetailWidget::update()
-{
- screen_->update();
-}
-
-void DetailWidget::reArrange()
-{
- screen_->reArrange();
-}
-
-void DetailWidget::flip()
-{
- screen_->flip();
-}
-
-DetailScreen* DetailWidget::getScreen() const
-{
- return screen_;
-}
+++ /dev/null
-/*
- * This file is part of jSpeed.
- *
- * jSpeed is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * jSpeed 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 jSpeed. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef DETAILWIDGET_H
-#define DETAILWIDGET_H
-
-#include "widgetscreen.h"
-
-class DetailScreen;
-
-class DetailWidget : public WidgetScreen
-{
- Q_OBJECT
-
-public:
- DetailWidget(QWidget* parent = 0);
- DetailScreen* getScreen() const;
-
-public slots:
- virtual void update();
- void reArrange();
- void flip();
-
-private:
- DetailScreen* screen_;
-};
-
-#endif
{
{"xpos", true},
{"ypos", true},
+ {"zpos", true},
{"src", false},
{"width", true},
{"height", true}
case YPOS:
element_->setY(intVal);
break;
+ case ZPOS:
+ element_->setZValue(intVal);
+ break;
case SRC:
return loadImage(value);
break;
class ImageElement : public GraphicsElement
{
public:
- enum Attribute {XPOS, YPOS, SRC, WIDTH, HEIGHT, ATTRIBUTE_COUNT};
+ enum Attribute {XPOS, YPOS, ZPOS, SRC, WIDTH, HEIGHT, ATTRIBUTE_COUNT};
ImageElement(Reader* reader);
virtual bool setAttribute(QString const& name, QString const& value);
virtual void addToScene(GraphicsScene* scene);
#include <QMaemo5InformationBox>
#include "mainwindow.h"
#include "mainwindowstack.h"
-#include "theme.h"
-#include "detailwidget.h"
-#include "detailscreen.h"
+#include "themeloader.h"
#include "mainmenu.h"
#include "odometer.h"
+#include "widgetscreen.h"
-MainWindow::MainWindow(): QMainWindow(0), menu_(0), theme_(0)
+MainWindow::MainWindow(): QMainWindow(0), menu_(0), themeLoader_(0), mainScreen_(0)
{
setWindowTitle(tr("jSpeed"));
showFullScreen();
MainWindow::~MainWindow()
{
+ delete themeLoader_;
}
void MainWindow::addScreens()
connect(stack_, SIGNAL(settingsPressed()), this, SLOT(openMenu()));
connect(stack_, SIGNAL(closePressed()), this, SIGNAL(quit()));
- DetailWidget* details = new DetailWidget(this);
+ mainScreen_ = new WidgetScreen(this);
+ WidgetScreen* detailScreen = new WidgetScreen(this);
- theme_ = new Theme(details->getScreen());
+ themeLoader_ = new ThemeLoader(mainScreen_, detailScreen);
if(!loadTheme())
{
return;
}
- stack_->addScreen(theme_);
- stack_->addScreen(details);
+ stack_->addScreen(mainScreen_);
+ stack_->addScreen(detailScreen);
connect(QApplication::desktop(), SIGNAL(resized(int)), stack_, SLOT(reArrange()));
bool MainWindow::loadTheme()
{
- if(!theme_->load())
+ if(!themeLoader_->load())
{
- QMaemo5InformationBox::information(this, tr("Unable to load theme: %1").arg(theme_->error()));
+ QMaemo5InformationBox::information(this, tr("Unable to load theme: %1").arg(themeLoader_->error()));
close();
return false;
}
- if(theme_->landscapeEnabled() && theme_->portraitEnabled())
+ if(mainScreen_->orientationEnabled(WidgetScreen::LANDSCAPE) &&
+ mainScreen_->orientationEnabled(WidgetScreen::PORTRAIT))
{
setAttribute(Qt::WA_Maemo5AutoOrientation, true);
}
- else if(theme_->portraitEnabled())
+ else if(mainScreen_->orientationEnabled(WidgetScreen::PORTRAIT))
{
setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
}
class MainWindowStack;
class MainMenu;
-class Theme;
+class ThemeLoader;
+class WidgetScreen;
class MainWindow : public QMainWindow
{
void startBacklight();
MainWindowStack* stack_;
MainMenu* menu_;
- Theme* theme_;
+ ThemeLoader* themeLoader_;
+ WidgetScreen* mainScreen_;
};
void Odometer::update(Location::Fix const& fix)
{
- if(fix.kmSpeed > maxSpeed_)
- {
- maxSpeed_ = fix.kmSpeed;
- }
-
if(!fixTimer_)
{
fixTimer_ = new QTime();
}
}
+ if(fix.kmSpeed > treshold && fix.kmSpeed > maxSpeed_)
+ {
+ maxSpeed_ = fix.kmSpeed;
+ }
+
if(fix.kmSpeed > treshold && elapsed > 200 && elapsed < FIX_TIMEOUT)
{
double km = fix.kmSpeed * (static_cast<double>(elapsed) / (1000 * 3600));
{
{"xpos", true},
{"ypos", true},
+ {"zpos", true},
{"src", false},
{"zeroangle", true},
{"fullangle", true},
case YPOS:
y_ = intVal;
break;
+ case ZPOS:
+ element_->setZValue(intVal);
+ break;
case SRC:
return loadImage(value);
break;
Q_OBJECT
public:
- enum Attribute {XPOS, YPOS, SRC, ZEROANGLE, FULLANGLE, ZEROSPEED, FULLSPEED, XROTATIONPOINT, YROTATIONPOINT, ATTRIBUTE_COUNT};
+ enum Attribute {XPOS, YPOS, ZPOS, SRC, ZEROANGLE, FULLANGLE, ZEROSPEED, FULLSPEED, XROTATIONPOINT, YROTATIONPOINT, ATTRIBUTE_COUNT};
Pointer(Reader* reader, bool animate);
~Pointer();
virtual bool setAttribute(QString const& name, QString const& value);
{
{"xpos", true},
{"ypos", true},
+ {"zpos", true},
{"width", true},
{"height", true},
{"color", false}
case YPOS:
y_ = intVal;
break;
+ case ZPOS:
+ element_->setZValue(intVal);
+ break;
case WIDTH:
width_ = intVal;
break;
class Rectangle : public GraphicsElement
{
public:
- enum Attribute {XPOS, YPOS, WIDTH, HEIGHT, COLOR, ATTRIBUTE_COUNT};
+ enum Attribute {XPOS, YPOS, ZPOS, WIDTH, HEIGHT, COLOR, ATTRIBUTE_COUNT};
Rectangle(Reader* reader);
virtual bool setAttribute(QString const& name, QString const& value);
virtual void addToScene(GraphicsScene* scene);
<theme>
-<detailscreen color="#fff">
+<detailscreen orientation="both" color="#fff">
<image>
<xpos>0</xpos>
<ypos>0</ypos>
<src>background.png</src>
</image>
</detailscreen>
-<orientation name="landscape">
+<mainscreen orientation="landscape">
<image>
<xpos>0</xpos>
<ypos>0</ypos>
<width>600</width>
</text>
<text>
- <data>{SPEED}</data>
- <font>digital7.ttf</font>
- <size>320</size>
- <xpos>100</xpos>
- <ypos>75</ypos>
- <color>#fff</color>
- <align>right</align>
- <width>600</width>
- <format>%.0f</format>
- <effect name="dropshadow">
- <xoffset>0</xoffset>
- <yoffset>0</yoffset>
- <radius>35</radius>
- <color>#a5efff</color>
- </effect>
- </text>
- <text>
<data>{SPEEDUNIT}</data>
<xpos>520</xpos>
<ypos>402</ypos>
<color>#a5efff</color>
</effect>
</text>
-</orientation>
-<orientation name="portrait">
+ <text>
+ <data>{SPEED}</data>
+ <font>digital7.ttf</font>
+ <size>320</size>
+ <xpos>100</xpos>
+ <ypos>75</ypos>
+ <color>#fff</color>
+ <align>right</align>
+ <width>600</width>
+ <format>%.0f</format>
+ <effect name="dropshadow">
+ <xoffset>0</xoffset>
+ <yoffset>0</yoffset>
+ <radius>35</radius>
+ <color>#a5efff</color>
+ </effect>
+ </text>
+</mainscreen>
+<mainscreen orientation="portrait">
<image>
- <xpos>0</xpos>
- <ypos>0</ypos>
- <src>background.png</src>
- </image>
+ <xpos>0</xpos>
+ <ypos>0</ypos>
+ <src>background.png</src>
+ </image>
<text>
<data>000</data>
<font>digital7.ttf</font>
<width>470</width>
</text>
<text>
- <data>{SPEED}</data>
- <font>digital7.ttf</font>
- <size>250</size>
- <xpos>0</xpos>
- <ypos>260</ypos>
- <color>#fff</color>
- <align>right</align>
- <width>470</width>
- <format>%.0f</format>
- <effect name="dropshadow">
- <xoffset>0</xoffset>
- <yoffset>0</yoffset>
- <radius>35</radius>
- <color>#a5efff</color>
- </effect>
- </text>
- <text>
<data>{SPEEDUNIT}</data>
<xpos>330</xpos>
<ypos>522</ypos>
<radius>35</radius>
<color>#a5efff</color>
</effect>
+ </text>
+ <text>
+ <data>{SPEED}</data>
+ <font>digital7.ttf</font>
+ <size>250</size>
+ <xpos>0</xpos>
+ <ypos>260</ypos>
+ <color>#fff</color>
+ <align>right</align>
+ <width>470</width>
+ <format>%.0f</format>
+ <effect name="dropshadow">
+ <xoffset>0</xoffset>
+ <yoffset>0</yoffset>
+ <radius>35</radius>
+ <color>#a5efff</color>
+ </effect>
</text>
-</orientation>
+</mainscreen>
</theme>
{
{"xpos", true},
{"ypos", true},
+ {"zpos", true},
{"data", false},
{"format", false},
{"width", true},
{"bold", false},
{"italic", false},
{"uppercase", false},
- {"letterspacing", true}
+ {"letterspacing", true},
+ {"timeformat", false},
+ {"dateformat", false}
};
const QString FIELDS[TextElement::FIELD_COUNT] = {"TRIP", "TOTAL", "SPEED",
"MAXSPEED", "AVGSPEED",
- "UNIT", "SPEEDUNIT", "TIME"};
+ "UNIT", "SPEEDUNIT", "TIME", "DATE"};
}
TextElement::TextElement(Reader* reader): GraphicsElement(reader),
-data_(""), format_(""), align_("left"), fontSize_(16), bold_(false), italic_(false),
+data_(""), format_(""), align_("left"), timeFormat_("hh:mm"), dateFormat_("dd.MM.yyyy"), fontSize_(16), bold_(false), italic_(false),
uppercase_(false), letterSpacing_(0)
{
element_ = new QGraphicsTextItem();
case YPOS:
element_->setY(intVal);
break;
+ case ZPOS:
+ element_->setZValue(intVal);
+ break;
case DATA:
data_ = value;
break;
letterSpacing_ = intVal;
fontChanged = true;
break;
+ case TIMEFORMAT:
+ timeFormat_ = value;
+ break;
+ case DATEFORMAT:
+ dateFormat_ = value;
+ break;
default:
qDebug() << "Unknown attribute: " << attr;
return false;
replaceValue(value, f, o->getSpeedUnit());
break;
case TIME:
- replaceValue(value, f, QTime::currentTime().toString("hh:mm"));
+ replaceValue(value, f, QTime::currentTime().toString(timeFormat_));
+ break;
+ case DATE:
+ replaceValue(value, f, QDate::currentDate().toString(dateFormat_));
break;
default:
qDebug() << "Unknown field: " << f;
class TextElement : public GraphicsElement
{
public:
- enum Attribute {XPOS, YPOS, DATA, FORMAT, WIDTH, ALIGN, COLOR, SIZE, FONT, BOLD, ITALIC, UPPERCASE, LETTERSPACING, ATTRIBUTE_COUNT};
- enum Field {TRIP, TOTAL, SPEED, MAXSPEED, AVGSPEED, UNIT, SPEEDUNIT, TIME, FIELD_COUNT};
+ enum Attribute {XPOS, YPOS, ZPOS, DATA, FORMAT, WIDTH, ALIGN, COLOR, SIZE, FONT, BOLD, ITALIC, UPPERCASE, LETTERSPACING, TIMEFORMAT, DATEFORMAT, ATTRIBUTE_COUNT};
+ enum Field {TRIP, TOTAL, SPEED, MAXSPEED, AVGSPEED, UNIT, SPEEDUNIT, TIME, DATE, FIELD_COUNT};
TextElement(Reader* reader);
virtual bool setAttribute(QString const& name, QString const& value);
virtual void addToScene(GraphicsScene* scene);
QString data_;
QString format_;
QString align_;
+ QString timeFormat_;
+ QString dateFormat_;
int fontSize_;
bool bold_;
bool italic_;
+++ /dev/null
-/*
- * This file is part of jSpeed.
- *
- * jSpeed is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * jSpeed 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 jSpeed. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <QtCore/QDir>
-#include <QtCore/QString>
-#include <QtCore/QDebug>
-#include <QtCore/QTimer>
-#include <QtGui/QApplication>
-#include <QtGui/QDesktopWidget>
-#include <QtGui/QStackedWidget>
-#include <QtXml/QDomNode>
-#include <QtXml/QDomDocument>
-#include <QtXml/QDomAttr>
-#include <QMaemo5InformationBox>
-#include "theme.h"
-#include "reader.h"
-#include "zipreader.h"
-#include "filereader.h"
-#include "themescreen.h"
-#include "detailscreen.h"
-#include "settings.h"
-
-namespace
-{
- QString const RESOURCE_DIR = ":/resources/themes/";
- QString const THEME_SUFFIX = ".jspeed";
-}
-
-Theme::Theme(DetailScreen* detailScreen, QWidget* parent): WidgetScreen(parent),
-portraitId_(-1), landscapeId_(-1), reader_(0),
-portrait_(0), landscape_(0), detailScreen_(detailScreen), portraitMode_(false)
-{
-}
-
-Theme::~Theme()
-{
-}
-
-bool Theme::load()
-{
- if(landscape_)
- {
- removeWidget(landscape_);
- delete landscape_;
- landscape_ = 0;
- landscapeId_ = -1;
- }
-
- if(portrait_)
- {
- removeWidget(portrait_);
- delete portrait_;
- portrait_ = 0;
- portraitId_ = -1;
- }
-
- QString theme = Settings::instance().value("theme", "default").toString();
-
- QString themeDir = getThemeDir();
-
- if(QFile::exists(themeDir + theme + THEME_SUFFIX))
- {
- reader_ = new ZipReader(themeDir + theme + THEME_SUFFIX);
-
- if(read())
- {
- return true;
- }
- else
- {
- QMaemo5InformationBox::information(this,
- tr("Unable to load theme: %1.").arg(error_),
- QMaemo5InformationBox::NoTimeout);
- }
- }
-
- theme = "default";
- Settings::instance().setValue("theme", theme);
-
- if(QFile::exists(RESOURCE_DIR + theme))
- {
- if(reader_)
- {
- delete reader_;
- }
-
- reader_ = new FileReader(RESOURCE_DIR + theme);
- return read();
- }
-
- error_ = "No themes found";
-
- return false;
-}
-
-bool Theme::read()
-{
- Q_ASSERT(reader_ != 0);
-
- if(!reader_->open())
- {
- error_ = reader_->errorString();
- return false;
- }
-
- QByteArray xmlData;
-
- if(!reader_->readFile("theme.xml", xmlData))
- {
- error_ = "Unable to find <b>theme.xml</b> from theme file";
- return false;
- }
-
- QDomDocument doc;
- int line = 0;
- int column = 0;
- QString msg;
-
- if(!doc.setContent(xmlData, false, &msg, &line, &column))
- {
- error_ = "Invalid xml file, " + msg + " (line "+line+", column "+column+")";
- return false;
- }
-
- QDomNodeList detailConfigs = doc.elementsByTagName("detailscreen");
-
- if(detailConfigs.size() > 1)
- {
- error_ = "Multiple <detailscreen> tags specified";
- return false;
- }
-
- if(detailConfigs.size() == 1)
- {
- detailScreen_->removeElements();
-
- QDomNode color = detailConfigs.at(0).attributes().namedItem("color");
-
- if(!color.isNull())
- {
- detailScreen_->setColor(color.toAttr().value());
- }
-
- detailScreen_->load(detailConfigs.at(0), reader_);
- }
-
- QDomNodeList orientations = doc.elementsByTagName("orientation");
-
- if(orientations.isEmpty())
- {
- error_ = "No <orientation> tags found";
- return false;
- }
-
- bool ok = true;
-
- for(int i = 0; i < orientations.size(); i++)
- {
- QDomNode data = orientations.at(i);
- QString type = data.attributes().namedItem("name").toAttr().value();
-
- if(type == "landscape")
- {
- if(landscape_)
- {
- error_ = "More than one <orientation name=\"landscape\"> specified";
- ok = false;
- }
-
- landscape_ = new ThemeScreen();
- ok = ok && landscape_->load(data, reader_);
-
- }
- else if(type == "portrait")
- {
- if(portrait_)
- {
- error_ = "More than one <orientation name=\"portrait\"> specified";
- ok = false;
- }
-
- portrait_ = new ThemeScreen();
- ok = ok && portrait_->load(data, reader_);
- }
- else
- {
- error_ = "Invalid orientation: " + type;
- ok = false;
- }
- }
-
- reader_->close();
- delete reader_;
- reader_ = 0;
-
- if(!portrait_ && !landscape_)
- {
- error_ = "No valid orientation tags found";
- ok = false;
- }
-
- if(ok)
- {
- if(landscape_)
- {
- landscapeId_ = addWidget(landscape_);
- connectSignals(landscape_);
- }
-
- if(portrait_)
- {
- portraitId_ = addWidget(portrait_);
- connectSignals(portrait_);
- }
-
- if(landscape_ && portrait_)
- {
- QRect rect = QApplication::desktop()->screenGeometry();
-
- if(rect.height() > rect.width())
- {
- setCurrentIndex(portraitId_);
- portraitMode_ = true;
- }
- else
- {
- setCurrentIndex(landscapeId_);
- portraitMode_ = false;
- }
- }
- }
- else
- {
- delete portrait_;
- portrait_ = 0;
- delete landscape_;
- landscape_ = 0;
- }
-
- return ok;
-}
-
-QString Theme::getThemeDir()
-{
- return Settings::getDir() + "themes" + QDir::separator();
-}
-
-QString const& Theme::getThemeSuffix()
-{
- return THEME_SUFFIX;
-}
-
-QString const& Theme::error() const
-{
- return error_;
-}
-
-bool Theme::portraitEnabled() const
-{
- return portrait_ != 0;
-}
-
-bool Theme::landscapeEnabled() const
-{
- return landscape_ != 0;
-}
-
-void Theme::reArrange()
-{
- QRect rect = QApplication::desktop()->screenGeometry();
-
- bool portrait = rect.height() > rect.width();
-
- if(portrait != portraitMode_)
- {
- if((portrait && portraitId_ == -1) ||
- (!portrait && landscapeId_ == -1))
- {
- return;
- }
-
- portraitMode_ = portrait;
-
- if(portrait)
- {
- setCurrentIndex(portraitId_);
- portrait_->reArrange();
- }
- else
- {
- setCurrentIndex(landscapeId_);
- landscape_->forceRepaint();
- //QTimer::singleShot(5000, landscape_, SLOT(forceRepaint()));
- }
- }
-}
-
-void Theme::flip()
-{
- if(portrait_)
- {
- portrait_->flip();
- }
-
- if(landscape_)
- {
- landscape_->flip();
- }
-}
-
-void Theme::connectSignals(ThemeScreen* screen)
-{
- connect(screen, SIGNAL(minimizePressed()), this, SIGNAL(minimizePressed()));
- connect(screen, SIGNAL(settingsPressed()), this, SIGNAL(settingsPressed()));
- connect(screen, SIGNAL(closePressed()), this, SIGNAL(closePressed()));
- connect(screen, SIGNAL(clicked()), this, SIGNAL(clicked()));
-}
-
+++ /dev/null
-/*
- * This file is part of jSpeed.
- *
- * jSpeed is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * jSpeed 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 jSpeed. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef THEME_H
-#define THEME_H
-
-#include "widgetscreen.h"
-
-class QString;
-class Reader;
-class ThemeScreen;
-class DetailScreen;
-
-class Theme : public WidgetScreen
-{
- Q_OBJECT
-
-public:
- Theme(DetailScreen* detailScreen, QWidget* parent = 0);
- ~Theme();
- bool load();
- bool portraitEnabled() const;
- bool landscapeEnabled() const;
- QString const& error() const;
- static QString getThemeDir();
- static QString const& getThemeSuffix();
-
-public slots:
- virtual void reArrange();
- virtual void flip();
-
-private:
- bool read();
- void connectSignals(ThemeScreen* screen);
- int portraitId_;
- int landscapeId_;
- Reader* reader_;
- QString error_;
- ThemeScreen* portrait_;
- ThemeScreen* landscape_;
- DetailScreen* detailScreen_;
- bool portraitMode_;
-
-};
-
-#endif
--- /dev/null
+/*
+ * This file is part of jSpeed.
+ *
+ * jSpeed is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * jSpeed 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 jSpeed. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <QtCore/QDir>
+#include <QtCore/QString>
+#include <QtCore/QDebug>
+#include <QtCore/QTimer>
+#include <QtGui/QStackedWidget>
+#include <QtXml/QDomNode>
+#include <QtXml/QDomDocument>
+#include <QtXml/QDomAttr>
+#include <QMaemo5InformationBox>
+#include "themeloader.h"
+#include "reader.h"
+#include "zipreader.h"
+#include "filereader.h"
+#include "themescreen.h"
+#include "detailscreen.h"
+#include "settings.h"
+#include "widgetscreen.h"
+
+namespace
+{
+ QString const RESOURCE_DIR = ":/resources/themes/";
+ QString const THEME_SUFFIX = ".jspeed";
+}
+
+ThemeLoader::ThemeLoader(WidgetScreen* mainScreen, WidgetScreen* detailScreen, QObject* parent): QObject(parent),
+reader_(0), mainScreen_(mainScreen), detailScreen_(detailScreen)
+{
+}
+
+ThemeLoader::~ThemeLoader()
+{
+}
+
+bool ThemeLoader::load()
+{
+ QString theme = Settings::instance().value("theme", "default").toString();
+
+ QString themeDir = getThemeDir();
+
+ if(QFile::exists(themeDir + theme + THEME_SUFFIX))
+ {
+ reader_ = new ZipReader(themeDir + theme + THEME_SUFFIX);
+
+ if(read())
+ {
+ return true;
+ }
+ else
+ {
+ QMaemo5InformationBox::information(mainScreen_,
+ tr("Unable to load theme: %1.").arg(error_),
+ QMaemo5InformationBox::NoTimeout);
+ }
+ }
+
+ theme = "default";
+ Settings::instance().setValue("theme", theme);
+
+ if(QFile::exists(RESOURCE_DIR + theme))
+ {
+ if(reader_)
+ {
+ delete reader_;
+ }
+
+ reader_ = new FileReader(RESOURCE_DIR + theme);
+ return read();
+ }
+
+ error_ = "No themes found";
+
+ return false;
+}
+
+bool ThemeLoader::read()
+{
+ Q_ASSERT(reader_ != 0);
+
+ if(!reader_->open())
+ {
+ error_ = reader_->errorString();
+ return false;
+ }
+
+ QByteArray xmlData;
+
+ if(!reader_->readFile("theme.xml", xmlData))
+ {
+ error_ = "Unable to find <b>theme.xml</b> from theme file";
+ return false;
+ }
+
+ QDomDocument doc;
+ int line = 0;
+ int column = 0;
+ QString msg;
+
+ if(!doc.setContent(xmlData, false, &msg, &line, &column))
+ {
+ error_ = "Invalid xml file, " + msg + " (line " + QString::number(line)+", column " + QString::number(column) + ")";
+ return false;
+ }
+
+ detailScreen_->clear();
+ detailScreen_->addScreen(new DetailScreen, WidgetScreen::LANDSCAPE);
+ detailScreen_->addScreen(new DetailScreen, WidgetScreen::PORTRAIT);
+ loadScreen("detailscreen", doc, detailScreen_);
+
+ mainScreen_->clear();
+ mainScreen_->addScreen(new ThemeScreen, WidgetScreen::LANDSCAPE);
+ mainScreen_->addScreen(new ThemeScreen, WidgetScreen::PORTRAIT);
+ bool ret = loadScreen("mainscreen", doc, mainScreen_);
+ mainScreen_->removeUnloaded();
+
+ reader_->close();
+
+ return ret;
+}
+
+bool ThemeLoader::loadScreen(QString const& tag, QDomDocument const& doc, WidgetScreen* screen)
+{
+ QDomNodeList orientations = doc.elementsByTagName(tag);
+
+ if(orientations.isEmpty())
+ {
+ error_ = "No <"+tag+"> tags found";
+ return false;
+ }
+
+ bool ok = true;
+
+ for(int i = 0; i < orientations.size(); i++)
+ {
+ QDomNode data = orientations.at(i);
+ QString type = data.attributes().namedItem("orientation").toAttr().value();
+ QDomNode color = data.attributes().namedItem("color");
+
+ if(type == "landscape")
+ {
+ if(screen->orientationLoaded(WidgetScreen::LANDSCAPE))
+ {
+ error_ = "More than one <"+tag+" orientation=\"landscape\"> specified";
+ ok = false;
+ }
+
+ ok = ok && screen->load(WidgetScreen::LANDSCAPE, data, reader_);
+
+ }
+ else if(type == "portrait")
+ {
+ if(screen->orientationLoaded(WidgetScreen::PORTRAIT))
+ {
+ error_ = "More than one <"+tag+" orientation=\"portrait\"> specified";
+ ok = false;
+ }
+
+ ok = ok && screen->load(WidgetScreen::PORTRAIT, data, reader_);
+ }
+ else if(type == "both")
+ {
+ if(screen->orientationLoaded(WidgetScreen::PORTRAIT) ||
+ screen->orientationLoaded(WidgetScreen::LANDSCAPE))
+ {
+ error_ = "Multiple orientations specified for same screen";
+ ok = false;
+ }
+
+ ok = ok && screen->load(WidgetScreen::PORTRAIT, data, reader_);
+ ok = ok && screen->load(WidgetScreen::LANDSCAPE, data, reader_);
+ }
+ else
+ {
+ error_ = "Invalid orientation: " + type;
+ ok = false;
+ }
+
+ if(ok && !color.isNull())
+ {
+ screen->setColor(color.toAttr().value());
+ }
+ }
+
+ return ok;
+}
+
+QString ThemeLoader::getThemeDir()
+{
+ return Settings::getDir() + "themes" + QDir::separator();
+}
+
+QString const& ThemeLoader::getThemeSuffix()
+{
+ return THEME_SUFFIX;
+}
+
+QString const& ThemeLoader::error() const
+{
+ return error_;
+}
+
--- /dev/null
+/*
+ * This file is part of jSpeed.
+ *
+ * jSpeed is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * jSpeed 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 jSpeed. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef THEMELOADER_H
+#define THEMELOADER_H
+
+#include <QtCore/QObject>
+
+class QString;
+class QDomDocument;
+class Reader;
+class WidgetScreen;
+
+class ThemeLoader : public QObject
+{
+public:
+ ThemeLoader(WidgetScreen* mainScreen, WidgetScreen* detailScreen, QObject* parent = 0);
+ ~ThemeLoader();
+ bool load();
+ QString const& error() const;
+ static QString getThemeDir();
+ static QString const& getThemeSuffix();
+
+private:
+ bool read();
+ bool loadScreen(QString const& tag, QDomDocument const& doc, WidgetScreen* screen);
+ Reader* reader_;
+ QString error_;
+ WidgetScreen* mainScreen_;
+ WidgetScreen* detailScreen_;
+
+};
+
+#endif
#include <QtGui/QMessageBox>
#include "themeselector.h"
#include "buttonselector.h"
-#include "theme.h"
+#include "themeloader.h"
#include "settings.h"
ThemeSelector::ThemeSelector(QWidget* parent): QDialog(parent)
{
QString filename = QFileDialog::getOpenFileName(this, tr("Open file"),
QDir::home().path(),
- tr("Theme files") + "(*" + Theme::getThemeSuffix() + ")");
+ tr("Theme files") + "(*" + ThemeLoader::getThemeSuffix() + ")");
if(filename.isEmpty())
{
basename = filename.mid(i + 1);
}
- QString targetFile = Theme::getThemeDir() + basename;
+ QString targetFile = ThemeLoader::getThemeDir() + basename;
qDebug() << targetFile;
{
selector_->clear();
selector_->addItem(tr("Default"), "default");
- QDir themeDir(Theme::getThemeDir());
+ QDir themeDir(ThemeLoader::getThemeDir());
if(!themeDir.exists() || !themeDir.isReadable())
{
- qDebug() << "Warning: theme dir (" + Theme::getThemeDir() + ") doesn't exist or is read protected";
+ qDebug() << "Warning: theme dir (" + ThemeLoader::getThemeDir() + ") doesn't exist or is read protected";
return;
}
QStringList filters;
- filters << "*" + Theme::getThemeSuffix();
+ filters << "*" + ThemeLoader::getThemeSuffix();
themeDir.setNameFilters(filters);
themeDir.setFilter(QDir::Files);
QStringList files = themeDir.entryList();
QString& name,
QString& id)
{
- static QRegExp cleaner(QRegExp::escape(Theme::getThemeSuffix()) + "$");
+ static QRegExp cleaner(QRegExp::escape(ThemeLoader::getThemeSuffix()) + "$");
filename = filename.replace(cleaner, "");
id = filename;
*
*/
+#include <QtCore/QString>
+#include <QtCore/QDebug>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtXml/QDomNode>
#include "widgetscreen.h"
+#include "themescreen.h"
-WidgetScreen::WidgetScreen(QWidget* parent): QStackedWidget(parent), AbstractScreen(){}
+WidgetScreen::WidgetScreen(QWidget* parent): QStackedWidget(parent), AbstractScreen(),
+currentOrientation_(LANDSCAPE)
+{
+}
+
+WidgetScreen::~WidgetScreen()
+{
+ clear();
+}
+
+bool WidgetScreen::load(Orientation orientation, QDomNode const& data, Reader* reader)
+{
+ if(screens_.find(orientation) == screens_.end())
+ {
+ qDebug() << "Orientation " << orientation << " not set";
+ return false;
+ }
+
+ bool ret = screens_[orientation]->load(data, reader);
+
+ if(ret && screens_.size() == 1)
+ {
+ currentOrientation_ = orientation;
+ }
+
+ if(ret)
+ {
+ loadedScreens_.insert(orientation);
+ }
+
+ return ret;
+}
+
+void WidgetScreen::addScreen(ThemeScreen* screen, Orientation orientation)
+{
+ if(screens_.find(orientation) != screens_.end())
+ {
+ removeWidget(screens_[orientation]);
+ delete screens_[orientation];
+ screens_.remove(orientation);
+ }
+
+ screens_[orientation] = screen;
+ addWidget(screen);
+ connect(screen, SIGNAL(minimizePressed()), this, SIGNAL(minimizePressed()));
+ connect(screen, SIGNAL(settingsPressed()), this, SIGNAL(settingsPressed()));
+ connect(screen, SIGNAL(closePressed()), this, SIGNAL(closePressed()));
+ connect(screen, SIGNAL(clicked()), this, SIGNAL(clicked()));
+}
+
+bool WidgetScreen::orientationEnabled(Orientation orientation) const
+{
+ return screens_.find(orientation) != screens_.end();
+}
+
+bool WidgetScreen::orientationLoaded(Orientation orientation) const
+{
+ return loadedScreens_.find(orientation) != loadedScreens_.end();
+}
+
+void WidgetScreen::reArrange()
+{
+ QRect rect = QApplication::desktop()->screenGeometry();
+
+ Orientation o = LANDSCAPE;
+
+ if(rect.height() > rect.width())
+ {
+ o = PORTRAIT;
+ }
+
+ if(o != currentOrientation_)
+ {
+ if(screens_.find(o) != screens_.end())
+ {
+ setCurrentWidget(screens_[o]);
+ screens_[o]->reArrange();
+ screens_[o]->forceRepaint();
+ currentOrientation_ = o;
+ }
+ }
+}
+
+void WidgetScreen::flip()
+{
+ for(QMap<Orientation, ThemeScreen*>::iterator it = screens_.begin();
+ it != screens_.end(); it++)
+ {
+ it.value()->flip();
+ }
+}
+
+void WidgetScreen::setColor(QString const& color)
+{
+ Q_UNUSED(color);
+}
+
+void WidgetScreen::clear()
+{
+ for(QMap<Orientation, ThemeScreen*>::iterator it = screens_.begin();
+ it != screens_.end(); it++)
+ {
+ removeWidget(it.value());
+ delete it.value();
+ }
+
+ screens_.clear();
+ loadedScreens_.clear();
+}
+
+void WidgetScreen::removeUnloaded()
+{
+ for(QMap<Orientation, ThemeScreen*>::iterator it = screens_.begin();
+ it != screens_.end(); it++)
+ {
+ if(loadedScreens_.find(it.key()) == loadedScreens_.end())
+ {
+ removeWidget(it.value());
+ delete it.value();
+ screens_.remove(it.key());
+ }
+ }
+}
#ifndef WIDGETSCREEN_H
#define WIDGETSCREEN_H
+#include <QtCore/QMap>
+#include <QtCore/QSet>
#include <QtGui/QStackedWidget>
#include "abstractscreen.h"
+class QDomNode;
+class QString;
+class Reader;
+class ThemeScreen;
+
class WidgetScreen : public QStackedWidget, public AbstractScreen
{
Q_OBJECT
public:
+ enum Orientation {LANDSCAPE, PORTRAIT};
WidgetScreen(QWidget* parent = 0);
+ ~WidgetScreen();
+ void addScreen(ThemeScreen* screen, Orientation orientation);
+ bool load(Orientation orientation, QDomNode const& data, Reader* reader);
+ bool orientationEnabled(Orientation orientation) const;
+ bool orientationLoaded(Orientation orientation) const;
+ virtual void setColor(QString const& color);
+
+public slots:
+ virtual void reArrange();
+ virtual void flip();
+ virtual void clear();
+ void removeUnloaded();
signals:
void minimizePressed();
void closePressed();
void clicked();
+private:
+ QMap<Orientation, ThemeScreen*> screens_;
+ QSet<Orientation> loadedScreens_;
+ Orientation currentOrientation_;
+
};
#endif