From: eshe Date: Tue, 20 Jul 2010 12:38:00 +0000 (+0100) Subject: Added zpos attribute to all elements. Changed architecture to allow detailscreen... X-Git-Url: http://git.maemo.org/git/?p=jspeed;a=commitdiff_plain;h=e37daa8a1873c9a9be25cf52c30044d53eeea6bc Added zpos attribute to all elements. Changed architecture to allow detailscreen to also be themed in both landscape and portrait mode. --- diff --git a/debian/dirs b/debian/dirs index 80507f1..be55d22 100644 --- a/debian/dirs +++ b/debian/dirs @@ -1,2 +1,3 @@ usr/bin usr/share/applications/hildon +home/user/.jspeed/themes diff --git a/jspeed.pro b/jspeed.pro index 2004508..cecdcef 100644 --- a/jspeed.pro +++ b/jspeed.pro @@ -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 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 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 index cbacc65..0000000 --- a/src/detailwidget.cpp +++ /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 . - * - */ - -#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 index d016fc9..0000000 --- a/src/detailwidget.h +++ /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 . - * - */ - -#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 diff --git a/src/imageelement.cpp b/src/imageelement.cpp index 066c1b7..9abb612 100644 --- a/src/imageelement.cpp +++ b/src/imageelement.cpp @@ -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; diff --git a/src/imageelement.h b/src/imageelement.h index f7b1d53..593def5 100644 --- a/src/imageelement.h +++ b/src/imageelement.h @@ -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); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f383234..39b41b3 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -25,13 +25,12 @@ #include #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); } diff --git a/src/mainwindow.h b/src/mainwindow.h index dba2779..e2724ec 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -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_; }; diff --git a/src/odometer.cpp b/src/odometer.cpp index 5dec354..d68fb1f 100644 --- a/src/odometer.cpp +++ b/src/odometer.cpp @@ -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(elapsed) / (1000 * 3600)); diff --git a/src/pointer.cpp b/src/pointer.cpp index b48412e..34e6b8d 100644 --- a/src/pointer.cpp +++ b/src/pointer.cpp @@ -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; diff --git a/src/pointer.h b/src/pointer.h index d7870a7..4035538 100644 --- a/src/pointer.h +++ b/src/pointer.h @@ -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); diff --git a/src/rectangle.cpp b/src/rectangle.cpp index 2e0705b..3a8dcc5 100644 --- a/src/rectangle.cpp +++ b/src/rectangle.cpp @@ -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; diff --git a/src/rectangle.h b/src/rectangle.h index 1ccae40..e879ade 100644 --- a/src/rectangle.h +++ b/src/rectangle.h @@ -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); diff --git a/src/resources/themes/default/theme.xml b/src/resources/themes/default/theme.xml index d9becb0..9bfd8f3 100644 --- a/src/resources/themes/default/theme.xml +++ b/src/resources/themes/default/theme.xml @@ -1,12 +1,12 @@ - + 0 0 background.png - + 0 0 @@ -23,23 +23,6 @@ 600 - {SPEED} - digital7.ttf - 320 - 100 - 75 - #fff - right - 600 - %.0f - - 0 - 0 - 35 - #a5efff - - - {SPEEDUNIT} 520 402 @@ -55,13 +38,30 @@ #a5efff - - + + {SPEED} + digital7.ttf + 320 + 100 + 75 + #fff + right + 600 + %.0f + + 0 + 0 + 35 + #a5efff + + + + - 0 - 0 - background.png - + 0 + 0 + background.png + 000 digital7.ttf @@ -73,23 +73,6 @@ 470 - {SPEED} - digital7.ttf - 250 - 0 - 260 - #fff - right - 470 - %.0f - - 0 - 0 - 35 - #a5efff - - - {SPEEDUNIT} 330 522 @@ -104,6 +87,23 @@ 35 #a5efff + + + {SPEED} + digital7.ttf + 250 + 0 + 260 + #fff + right + 470 + %.0f + + 0 + 0 + 35 + #a5efff + - + diff --git a/src/textelement.cpp b/src/textelement.cpp index bf79a68..7c11bc7 100644 --- a/src/textelement.cpp +++ b/src/textelement.cpp @@ -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; diff --git a/src/textelement.h b/src/textelement.h index b531580..4d861f1 100644 --- a/src/textelement.h +++ b/src/textelement.h @@ -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 index c44196a..0000000 --- a/src/theme.cpp +++ /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 . - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 theme.xml 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 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 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 specified"; - ok = false; - } - - landscape_ = new ThemeScreen(); - ok = ok && landscape_->load(data, reader_); - - } - else if(type == "portrait") - { - if(portrait_) - { - error_ = "More than one 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 index 308043e..0000000 --- a/src/theme.h +++ /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 . - * - */ - -#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 index 0000000..21ad981 --- /dev/null +++ b/src/themeloader.cpp @@ -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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 theme.xml 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 index 0000000..bdf2ce2 --- /dev/null +++ b/src/themeloader.h @@ -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 . + * + */ + +#ifndef THEMELOADER_H +#define THEMELOADER_H + +#include + +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 diff --git a/src/themeselector.cpp b/src/themeselector.cpp index 7f22a09..e66d925 100644 --- a/src/themeselector.cpp +++ b/src/themeselector.cpp @@ -28,7 +28,7 @@ #include #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; diff --git a/src/widgetscreen.cpp b/src/widgetscreen.cpp index fd00a06..4695f06 100644 --- a/src/widgetscreen.cpp +++ b/src/widgetscreen.cpp @@ -16,6 +16,134 @@ * */ +#include +#include +#include +#include +#include #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::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::iterator it = screens_.begin(); + it != screens_.end(); it++) + { + removeWidget(it.value()); + delete it.value(); + } + + screens_.clear(); + loadedScreens_.clear(); +} + +void WidgetScreen::removeUnloaded() +{ + for(QMap::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()); + } + } +} diff --git a/src/widgetscreen.h b/src/widgetscreen.h index adef502..5862928 100644 --- a/src/widgetscreen.h +++ b/src/widgetscreen.h @@ -19,15 +19,35 @@ #ifndef WIDGETSCREEN_H #define WIDGETSCREEN_H +#include +#include #include #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 screens_; + QSet loadedScreens_; + Orientation currentOrientation_; + }; #endif