Added zpos attribute to all elements. Changed architecture to allow detailscreen...
authoreshe <jessehakanen@gmail.com>
Tue, 20 Jul 2010 12:38:00 +0000 (13:38 +0100)
committereshe <jessehakanen@gmail.com>
Tue, 20 Jul 2010 12:38:00 +0000 (13:38 +0100)
25 files changed:
debian/dirs
jspeed.pro
src/data/graphical.jspeed [deleted file]
src/data/themes/graphical.jspeed [new file with mode: 0644]
src/detailwidget.cpp [deleted file]
src/detailwidget.h [deleted file]
src/imageelement.cpp
src/imageelement.h
src/mainwindow.cpp
src/mainwindow.h
src/odometer.cpp
src/pointer.cpp
src/pointer.h
src/rectangle.cpp
src/rectangle.h
src/resources/themes/default/theme.xml
src/textelement.cpp
src/textelement.h
src/theme.cpp [deleted file]
src/theme.h [deleted file]
src/themeloader.cpp [new file with mode: 0644]
src/themeloader.h [new file with mode: 0644]
src/themeselector.cpp
src/widgetscreen.cpp
src/widgetscreen.h

index 80507f1..be55d22 100644 (file)
@@ -1,2 +1,3 @@
 usr/bin
 usr/share/applications/hildon
+home/user/.jspeed/themes
index 2004508..cecdcef 100644 (file)
@@ -18,10 +18,9 @@ SOURCES += src/main.cpp \
            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 \
@@ -48,10 +47,9 @@ HEADERS += src/mainwindow.h \
            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 \
@@ -74,18 +72,22 @@ unix {
 
   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
 
diff --git a/src/data/graphical.jspeed b/src/data/graphical.jspeed
deleted file mode 100755 (executable)
index aac7e0d..0000000
Binary files a/src/data/graphical.jspeed and /dev/null differ
diff --git a/src/data/themes/graphical.jspeed b/src/data/themes/graphical.jspeed
new file mode 100644 (file)
index 0000000..d8fdd1c
Binary files /dev/null and b/src/data/themes/graphical.jspeed differ
diff --git a/src/detailwidget.cpp b/src/detailwidget.cpp
deleted file mode 100644 (file)
index cbacc65..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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_;
-}
diff --git a/src/detailwidget.h b/src/detailwidget.h
deleted file mode 100644 (file)
index d016fc9..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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
index 066c1b7..9abb612 100644 (file)
@@ -30,6 +30,7 @@ namespace
     {
      {"xpos", true},
      {"ypos", true},
+     {"zpos", true},
      {"src", false},
      {"width", true},
      {"height", true}
@@ -60,6 +61,9 @@ bool ImageElement::setAttribute(QString const& name,
         case YPOS:
             element_->setY(intVal);
             break;
+        case ZPOS:
+            element_->setZValue(intVal);
+            break;
         case SRC:
             return loadImage(value);
             break;
index f7b1d53..593def5 100644 (file)
@@ -31,7 +31,7 @@ class GraphicsScene;
 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);
index f383234..39b41b3 100644 (file)
 #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();
@@ -42,6 +41,7 @@ MainWindow::MainWindow(): QMainWindow(0), menu_(0), theme_(0)
 
 MainWindow::~MainWindow()
 {
+    delete themeLoader_;
 }
 
 void MainWindow::addScreens()
@@ -52,17 +52,18 @@ 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()));
 
@@ -71,18 +72,19 @@ void MainWindow::addScreens()
 
 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);
     }
index dba2779..e2724ec 100644 (file)
@@ -23,7 +23,8 @@
 
 class MainWindowStack;
 class MainMenu;
-class Theme;
+class ThemeLoader;
+class WidgetScreen;
 
 class MainWindow : public QMainWindow
 {
@@ -48,7 +49,8 @@ private:
     void startBacklight();
     MainWindowStack* stack_;
     MainMenu* menu_;
-    Theme* theme_;
+    ThemeLoader* themeLoader_;
+    WidgetScreen* mainScreen_;
 
 };
 
index 5dec354..d68fb1f 100644 (file)
@@ -95,11 +95,6 @@ void Odometer::end()
 
 void Odometer::update(Location::Fix const& fix)
 {
-    if(fix.kmSpeed > maxSpeed_)
-    {
-        maxSpeed_ = fix.kmSpeed;
-    }
-
     if(!fixTimer_)
     {
         fixTimer_ = new QTime();
@@ -125,6 +120,11 @@ void Odometer::update(Location::Fix const& fix)
            }
         }
 
+        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));
index b48412e..34e6b8d 100644 (file)
@@ -31,6 +31,7 @@ namespace
     {
      {"xpos", true},
      {"ypos", true},
+     {"zpos", true},
      {"src", false},
      {"zeroangle", true},
      {"fullangle", true},
@@ -84,6 +85,9 @@ bool Pointer::setAttribute(QString const& name, QString const& value)
         case YPOS:
             y_ = intVal;
             break;
+        case ZPOS:
+            element_->setZValue(intVal);
+            break;
         case SRC:
             return loadImage(value);
             break;
index d7870a7..4035538 100644 (file)
@@ -33,7 +33,7 @@ class Pointer : public QObject, public GraphicsElement
     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);
index 2e0705b..3a8dcc5 100644 (file)
@@ -29,6 +29,7 @@ namespace
     {
      {"xpos", true},
      {"ypos", true},
+     {"zpos", true},
      {"width", true},
      {"height", true},
      {"color", false}
@@ -58,6 +59,9 @@ bool Rectangle::setAttribute(QString const& name, QString const& value)
         case YPOS:
             y_ = intVal;
             break;
+        case ZPOS:
+            element_->setZValue(intVal);
+            break;
         case WIDTH:
             width_ = intVal;
             break;
index 1ccae40..e879ade 100644 (file)
@@ -31,7 +31,7 @@ class GraphicsScene;
 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);
index d9becb0..9bfd8f3 100644 (file)
@@ -1,12 +1,12 @@
 <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>
index bf79a68..7c11bc7 100644 (file)
@@ -32,6 +32,7 @@ namespace
     {
      {"xpos", true},
      {"ypos", true},
+     {"zpos", true},
      {"data", false},
      {"format", false},
      {"width", true},
@@ -42,16 +43,18 @@ namespace
      {"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();
@@ -76,6 +79,9 @@ bool TextElement::setAttribute(QString const& name, QString const& value)
         case YPOS:
             element_->setY(intVal);
             break;
+        case ZPOS:
+            element_->setZValue(intVal);
+            break;
         case DATA:
             data_ = value;
             break;
@@ -123,6 +129,12 @@ bool TextElement::setAttribute(QString const& name, QString const& value)
             letterSpacing_ = intVal;
             fontChanged = true;
             break;
+        case TIMEFORMAT:
+            timeFormat_ = value;
+            break;
+        case DATEFORMAT:
+            dateFormat_ = value;
+            break;
         default:
             qDebug() << "Unknown attribute: " << attr;
             return false;
@@ -250,7 +262,10 @@ void TextElement::replaceSpecialFields(QString& value)
             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;
index b531580..4d861f1 100644 (file)
@@ -30,8 +30,8 @@ class GraphicsScene;
 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);
@@ -48,6 +48,8 @@ private:
     QString data_;
     QString format_;
     QString align_;
+    QString timeFormat_;
+    QString dateFormat_;
     int fontSize_;
     bool bold_;
     bool italic_;
diff --git a/src/theme.cpp b/src/theme.cpp
deleted file mode 100644 (file)
index c44196a..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * 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()));
-}
-
diff --git a/src/theme.h b/src/theme.h
deleted file mode 100644 (file)
index 308043e..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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
diff --git a/src/themeloader.cpp b/src/themeloader.cpp
new file mode 100644 (file)
index 0000000..21ad981
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * 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_;
+}
+
diff --git a/src/themeloader.h b/src/themeloader.h
new file mode 100644 (file)
index 0000000..bdf2ce2
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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
index 7f22a09..e66d925 100644 (file)
@@ -28,7 +28,7 @@
 #include <QtGui/QMessageBox>
 #include "themeselector.h"
 #include "buttonselector.h"
-#include "theme.h"
+#include "themeloader.h"
 #include "settings.h"
 
 ThemeSelector::ThemeSelector(QWidget* parent): QDialog(parent)
@@ -80,7 +80,7 @@ void ThemeSelector::loadFromFile()
 {
     QString filename = QFileDialog::getOpenFileName(this, tr("Open file"),
                                                     QDir::home().path(),
-                                                    tr("Theme files") + "(*" + Theme::getThemeSuffix() + ")");
+                                                    tr("Theme files") + "(*" + ThemeLoader::getThemeSuffix() + ")");
 
     if(filename.isEmpty())
     {
@@ -101,7 +101,7 @@ void ThemeSelector::loadFromFile()
         basename = filename.mid(i + 1);
     }
 
-    QString targetFile = Theme::getThemeDir() + basename;
+    QString targetFile = ThemeLoader::getThemeDir() + basename;
 
     qDebug() << targetFile;
 
@@ -132,16 +132,16 @@ void ThemeSelector::loadThemes()
 {
     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();
@@ -165,7 +165,7 @@ void ThemeSelector::getThemeDetails(QString filename,
                                     QString& name,
                                     QString& id)
 {
-    static QRegExp cleaner(QRegExp::escape(Theme::getThemeSuffix()) + "$");
+    static QRegExp cleaner(QRegExp::escape(ThemeLoader::getThemeSuffix()) + "$");
     filename = filename.replace(cleaner, "");
 
     id = filename;
index fd00a06..4695f06 100644 (file)
  *
  */
 
+#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());
+        }
+    }
+}
index adef502..5862928 100644 (file)
 #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();
@@ -35,6 +55,11 @@ signals:
     void closePressed();
     void clicked();
 
+private:
+    QMap<Orientation, ThemeScreen*> screens_;
+    QSet<Orientation> loadedScreens_;
+    Orientation currentOrientation_;
+
 };
 
 #endif