--- /dev/null
+jspeed (0.1-1) unstable; urgency=low
+
+ * Initial release.
+
+ -- Jesse Hakanen <jessehakanen@gmail.com> Tue, 13 Jul 2010 13:17:36 +0100
--- /dev/null
+Source: jspeed
+Section: user/utilities
+Priority: optional
+Maintainer: Jesse Hakanen <jessehakanen@gmail.com>
+Build-Depends: debhelper (>= 5), libqt4-dev, libzip-dev, liblocation-dev, libgconf2-dev
+Standards-Version: 3.7.2
+Homepage: http://jspeed.garage.maemo.org
+
+Package: jspeed
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: Highly customizable speedometer application.
+XSBC-Bugtracker: https://garage.maemo.org/tracker/?atid=6134&group_id=1756
+XB-Maemo-Display-Name: jSpeed
+XB-Maemo-Icon-26:
+ iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0
+ d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAFORJREFUeNqkWQmUFNW5/qp6
+ 756Znn0BhmVgWEUBIRE1EvdjlIgGQU9CJLi9RI2JmBgTjca8xMRgkqMh5hnU
+ GEVRMe9A1CSgIrIjCDjIvgwwzM4sPdMz00vVfd9/q7pnJCQnyZs591R11a1b
+ //r933/LUErhSG0bzvRnGAZM08NhwjANuQLTMPnbyN5XynDnocDn80wO+IxR
+ Xh+qvF4M4axcmaeAWCqF4+k0jiST9oFUyt5lK8SUsvks71MGPTjX5jXIOSfY
+ ts1h6Xtn+qsaXggv/t0//ULnlEIXRyLe63LCxmz+nMJRHOuKo6W1E+1t7ejt
+ 69PzwuEQCgoKUFiQj/xoSJ5s4hpbu3vsV3t60m/yvBP/4d+/rYBYxuczx0Sj
+ /u/4fZjV25coWrt2O1avXo2tmzfh2InjaI/F0EvLWTS5QelMnx9hmrqwsBAj
+ KofivAsvLLv8sstnnjt10szciL8xkVSvdXQmn0il7eP/tj3/1RASy/O8oDAa
+ eDAUMu9sbGoNLH15GV5+8Y+oOXYUts+H8Khq+CuHIJJKQ5WVwWtZMPsSSObm
+ QLW2oreLisU60bdrF7wMxcnVYzD/1tswd86X6KFod3fcWtQRSyyiTHFx878S
+ Qv+SAiJ9KOy7orQo+Pt4vHfoU4v/B4ufeRrN3d0oOOccRD57HkK9vfCJkMOG
+ wejoQGT7R4hPngST3ggdOoz2K69AsLkZZiKBRHk50qda0b5/H7o2bkTl4Erc
+ v/A+LLjlZvi83r1Nrb0LEn3pzZI9/28FaHcU5Ifuz4/6H9uy9SPjnoULsfPg
+ fhTNug7FBUXwNTfBCgTRF81D/jvvIllSwky04Wlvh/L7oegFgxmcKi3R3vB1
+ daF11heRu3sPEAmjr6ICHfRIy9o1+PyUaXhq8W8wflx14lR73zdjscQzXOw/
+ V0CeKy3JeTI3x3/3M8/8AQ/84ucIMI4LLr8cYSZpx5hqlCz/ExTDxxZEorBg
+ 3NsULD1sOEDBVTAAxXDxf/KJvgePBxp6eC73Ts28BnlUJpETQeM7qxCMdePJ
+ RU8wrK5De2ffw21tPY8aBv6hAp5HHnkE7R29f3fTZrJq4XMDdz/04KN46LdP
+ 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
--- /dev/null
+Copyright (c) 2010 Jesse Hakanen <jessehakanen@gmail.com>
+
+This program 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.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
--- /dev/null
+usr/bin
+usr/share/applications/hildon
--- /dev/null
+#!/usr/bin/make -f
+APPNAME := jspeed
+builddir:
+ mkdir -p builddir
+
+builddir/Makefile: builddir
+ cd builddir && qmake-qt4 PREFIX=/usr ../$(APPNAME).pro
+
+build: build-stamp
+
+build-stamp: builddir/Makefile
+ dh_testdir
+ # Add here commands to compile the package.
+ cd builddir && $(MAKE)
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+ # Add here commands to clean up after the build process.
+ rm -rf builddir
+ dh_clean
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+# Add here commands to install the package into debian/your_appname
+ cd builddir && $(MAKE) INSTALL_ROOT=$(CURDIR)/debian/$(APPNAME) install
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installdocs
+ dh_installexamples
+ dh_installman
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
--- /dev/null
+QT += maemo5 xml
+TARGET = jspeed
+TEMPLATE = app
+SOURCES += src/main.cpp \
+ src/mainwindow.cpp \
+ src/mainwindowstack.cpp \
+ src/location.cpp \
+ src/graphicsscreen.cpp \
+ src/abstractscreen.cpp \
+ src/widgetscreen.cpp \
+ src/imageitem.cpp \
+ src/reader.cpp \
+ src/zipreader.cpp \
+ src/filereader.cpp \
+ src/graphicselement.cpp \
+ src/textelement.cpp \
+ src/imageelement.cpp \
+ src/rectangle.cpp \
+ src/pointer.cpp \
+ src/odometer.cpp \
+ src/theme.cpp \
+ src/themescreen.cpp \
+ src/settings.cpp \
+ src/detailwidget.cpp \
+ src/detailscreen.cpp \
+ src/graphicsscene.cpp \
+ src/mainmenu.cpp \
+ src/buttonselector.cpp \
+ src/themeselector.cpp \
+ src/unitselector.cpp
+HEADERS += src/mainwindow.h \
+ src/mainwindowstack.h \
+ src/location.h \
+ src/graphicsscreen.h \
+ src/abstractscreen.h \
+ src/widgetscreen.h \
+ src/imageitem.h \
+ src/reader.h \
+ src/zipreader.h \
+ src/filereader.h \
+ src/graphicselement.h \
+ src/textelement.h \
+ src/imageelement.h \
+ src/rectangle.h \
+ src/pointer.h \
+ src/odometer.h \
+ src/theme.h \
+ src/themescreen.h \
+ src/settings.h \
+ src/detailwidget.h \
+ src/detailscreen.h \
+ src/graphicsscene.h \
+ src/mainmenu.h \
+ src/buttonselector.h \
+ src/themeselector.h \
+ src/unitselector.h
+RESOURCES = src/resources.qrc
+CONFIG += link_pkgconfig
+PKGCONFIG += liblocation libzip
+
+unix {
+ #VARIABLES
+ isEmpty(PREFIX) {
+ PREFIX = /usr
+ }
+
+ BINDIR = $$PREFIX/bin
+ DATADIR =$$PREFIX/share
+
+ DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\"
+
+ #MAKE INSTALL
+
+ INSTALLS += target desktop icon26 icon48 icon64
+
+ target.path =$$BINDIR
+
+ desktop.path = $$DATADIR/applications/hildon
+ desktop.files += src/data/$${TARGET}.desktop
+
+ icon26.path = $$DATADIR/icons/hicolor/26x26/apps
+ icon26.files += src/data/26x26/$${TARGET}.png
+
+ icon48.path = $$DATADIR/icons/hicolor/48x48/apps
+ icon48.files += src/data/48x48/$${TARGET}.png
+
+ icon64.path = $$DATADIR/icons/hicolor/64x64/apps
+ icon64.files += src/data/64x64/$${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 "abstractscreen.h"
+
+AbstractScreen::AbstractScreen(){}
--- /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 ABSTRACTSCREEN_H
+#define ABSTRACTSCREEN_H
+
+class AbstractScreen
+{
+public:
+ AbstractScreen();
+ virtual void reArrange() = 0;
+ virtual void flip() = 0;
+};
+
+#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 <QtGui/QStandardItem>
+#include <QtCore/QDebug>
+#include "buttonselector.h"
+
+ButtonSelector::ButtonSelector(QString const& text, QWidget* parent):
+QMaemo5ValueButton(text, parent), selector_(0), model_(0)
+{
+ setValueLayout(QMaemo5ValueButton::ValueBesideText);
+ selector_ = new QMaemo5ListPickSelector(this);
+ connect(selector_, SIGNAL(selected(QString const&)), this, SLOT(onSelected(QString const&)));
+ model_ = new QStandardItemModel(0, 1);
+ selector_->setModel(model_);
+ setPickSelector(selector_);
+}
+
+void ButtonSelector::addItem(QString const& text)
+{
+ addItem(text, QVariant(text));
+}
+
+void ButtonSelector::addItem(QString const& text, QVariant const& value)
+{
+ QStandardItem* item = new QStandardItem(text);
+ item->setData(value, Qt::UserRole);
+ item->setTextAlignment(Qt::AlignCenter);
+ item->setEditable(false);
+ model_->appendRow(item);
+
+ if(selector_->currentIndex() < 0)
+ {
+ selector_->setCurrentIndex(0);
+ }
+
+}
+
+void ButtonSelector::clear()
+{
+ model_->clear();
+}
+
+void ButtonSelector::setCurrentIndex(unsigned int index)
+{
+ selector_->setCurrentIndex(index);
+}
+
+int ButtonSelector::indexOfValue(QVariant const& value) const
+{
+ for(int i = 0; i < model_->rowCount(); i++)
+ {
+ QStandardItem* item = model_->item(i);
+
+ if(item && item->data(Qt::UserRole) == value)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+bool ButtonSelector::selectByValue(QVariant const& value)
+{
+ int index = indexOfValue(value);
+
+ if(index < 0)
+ {
+ return false;
+ }
+
+ setCurrentIndex(index);
+
+ return true;
+}
+
+int ButtonSelector::currentIndex() const
+{
+ return selector_->currentIndex();
+}
+
+QString ButtonSelector::text() const
+{
+ return selector_->currentValueText();
+}
+
+QVariant ButtonSelector::value() const
+{
+ int currentIndex = selector_->currentIndex();
+
+ if(currentIndex < 0)
+ {
+ return QVariant("");
+ }
+
+ QStandardItem* item = model_->item(currentIndex);
+
+ return item->data(Qt::UserRole);
+}
+
+bool ButtonSelector::changeItem(unsigned int index,
+ QString const& text)
+{
+ return changeItem(index, text, QVariant(text));
+}
+
+bool ButtonSelector::changeItem(unsigned int index,
+ QString const& text,
+ QVariant const& value)
+{
+ QStandardItem* item = model_->item(index);
+
+ if(!item)
+ {
+ return false;
+ }
+
+ item->setText(text);
+ item->setData(value, Qt::UserRole);
+
+ return true;
+}
+
+bool ButtonSelector::removeItem(unsigned int index)
+{
+ return model_->removeRow(index);
+}
+
+void ButtonSelector::onSelected(QString const& text)
+{
+ emit selected(currentIndex(), text, value());
+}
--- /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 BUTTONSELECTOR_H
+#define BUTTONSELECTOR_H
+
+#include <QtCore/QVariant>
+#include <QtCore/QString>
+#include <QtGui/QStandardItemModel>
+#include <QMaemo5ValueButton>
+#include <QMaemo5ListPickSelector>
+
+class ButtonSelector : public QMaemo5ValueButton
+{
+
+Q_OBJECT
+
+public:
+ ButtonSelector(QString const& text, QWidget* parent = 0);
+ void addItem(QString const& text);
+ void addItem(QString const& text, QVariant const& value);
+ void clear();
+ void setCurrentIndex(unsigned int index);
+ int indexOfValue(QVariant const& value) const;
+ bool selectByValue(QVariant const& value);
+ int currentIndex() const;
+ bool changeItem(unsigned int index, QString const& text);
+ bool changeItem(unsigned int index, QString const& text, QVariant const& value);
+ bool removeItem(unsigned int index);
+ bool setValue(unsigned int index);
+ QString text() const;
+ QVariant value() const;
+
+signals:
+ void selected(unsigned int index, QString const& text, QVariant const& value);
+
+private slots:
+ void onSelected(QString const& text);
+
+private:
+ QMaemo5ListPickSelector* selector_;
+ QStandardItemModel* model_;
+
+};
+
+#endif
--- /dev/null
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Name=jSpeed
+Exec=/usr/bin/jspeed
+Icon=jspeed
+X-Window-Icon=jspeed
+X-Window-Icon-Dimmed=jspeed
--- /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 <QtGui/QGraphicsTextItem>
+#include <QtGui/QGraphicsLineItem>
+#include <QtGui/QGraphicsView>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtCore/QString>
+#include <QtCore/QDebug>
+#include <math.h>
+#include "detailscreen.h"
+#include "odometer.h"
+#include "graphicsscene.h"
+
+namespace
+{
+ QString const FONT = "Tahoma";
+ QString const BACKGROUND = ":/resources/themes/default/background.png";
+ int const FONT_SIZE = 20;
+ int const PADDING_LEFT = 40;
+ int const START_HEIGHT = 80;
+ int const ITEM_WIDTH = 130;
+}
+
+DetailScreen::DetailScreen(QWidget* parent): GraphicsScreen(parent)
+{
+ QString unit = Odometer::getUnit();
+ QString speedUnit = Odometer::getSpeedUnit();
+
+ QGraphicsPixmapItem* background = new QGraphicsPixmapItem(QPixmap(BACKGROUND));
+ getScene()->addItem(background);
+
+ tripLabel_ = createItem(tr("Trip"));
+ trip_ = createItem(roundDouble(Odometer::instance().getTrip()));
+ tripUnit_ = createItem(unit);
+
+ totalLabel_ = createItem(tr("Total"));
+ total_ = createItem(roundDouble(Odometer::instance().getTotal()));
+ totalUnit_ = createItem(unit);
+
+ speedLabel_ = createItem(tr("Speed"));
+ speed_ = createItem(roundDouble(0.0));
+ speedUnit_ = createItem(speedUnit);
+
+ avgSpeedLabel_ = createItem(tr("Average speed"));
+ avgSpeed_ = createItem(roundDouble(Odometer::instance().getAverageSpeed()));
+ avgSpeedUnit_ = createItem(speedUnit);
+
+ maxSpeedLabel_ = createItem(tr("Max speed"));
+ maxSpeed_ = createItem(roundDouble(Odometer::instance().getMaxSpeed()));
+ maxSpeedUnit_ = createItem(speedUnit);
+
+ tripTimeLabel_ = createItem(tr("Trip time"));
+ tripTime_ = createItem(formatTime(Odometer::instance().getTripTime()));
+
+ totalTimeLabel_ = createItem(tr("Total time"));
+ totalTime_ = createItem(formatTime(Odometer::instance().getTotalTime()));
+
+ line1_ = createLine();
+ line2_ = createLine();
+
+ connect(&(Odometer::instance()), SIGNAL(timeUpdated()), this, SLOT(updateTime()));
+ connect(&(Odometer::instance()), SIGNAL(unitChanged()), this, SLOT(updateUnits()));
+
+ reArrange();
+}
+
+void DetailScreen::update()
+{
+ speed_->setPlainText(roundDouble(Odometer::instance().getLatestFix().speed));
+ trip_->setPlainText(roundDouble(Odometer::instance().getTrip()));
+ total_->setPlainText(roundDouble(Odometer::instance().getTotal()));
+ avgSpeed_->setPlainText(roundDouble(Odometer::instance().getAverageSpeed()));
+ maxSpeed_->setPlainText(roundDouble(Odometer::instance().getMaxSpeed()));
+}
+
+void DetailScreen::updateTime()
+{
+ tripTime_->setPlainText(formatTime(Odometer::instance().getTripTime()));
+ totalTime_->setPlainText(formatTime(Odometer::instance().getTotalTime()));
+}
+
+void DetailScreen::updateUnits()
+{
+ QString unit = Odometer::getUnit();
+ QString speedUnit = Odometer::getSpeedUnit();
+
+ tripUnit_->setPlainText(unit);
+ totalUnit_->setPlainText(unit);
+ speedUnit_->setPlainText(speedUnit);
+ avgSpeedUnit_->setPlainText(speedUnit);
+ maxSpeedUnit_->setPlainText(speedUnit);
+
+ update();
+}
+
+void DetailScreen::reArrange()
+{
+ GraphicsScreen::reArrange();
+
+ int lineHeight = getScene()->height() / 9;
+
+ int area1 = (getScene()->width() / 3) + ITEM_WIDTH / 2 + 20;
+ int area2 = area1 + ITEM_WIDTH;
+
+ tripLabel_->setPos(PADDING_LEFT, START_HEIGHT);
+ trip_->setPos(area1, START_HEIGHT);
+ tripUnit_->setPos(area2, START_HEIGHT);
+
+ totalLabel_->setPos(PADDING_LEFT, START_HEIGHT + lineHeight);
+ total_->setPos(area1, START_HEIGHT + lineHeight);
+ totalUnit_->setPos(area2, START_HEIGHT + lineHeight);
+
+ speedLabel_->setPos(PADDING_LEFT, START_HEIGHT + 2 * lineHeight);
+ speed_->setPos(area1, START_HEIGHT + 2 * lineHeight);
+ speedUnit_->setPos(area2, START_HEIGHT + 2 * lineHeight);
+
+ avgSpeedLabel_->setPos(PADDING_LEFT, START_HEIGHT + 3 * lineHeight);
+ avgSpeed_->setPos(area1, START_HEIGHT + 3 * lineHeight);
+ avgSpeedUnit_->setPos(area2, START_HEIGHT + 3 * lineHeight);
+
+ maxSpeedLabel_->setPos(PADDING_LEFT, START_HEIGHT + 4 * lineHeight);
+ maxSpeed_->setPos(area1, START_HEIGHT + 4 * lineHeight);
+ maxSpeedUnit_->setPos(area2, START_HEIGHT + 4 * lineHeight);
+
+ tripTimeLabel_->setPos(PADDING_LEFT, START_HEIGHT + 5 * lineHeight);
+ tripTime_->setPos(area1, START_HEIGHT + 5 * lineHeight);
+
+ totalTimeLabel_->setPos(PADDING_LEFT, START_HEIGHT + 6 * lineHeight);
+ totalTime_->setPos(area1, START_HEIGHT + 6 * lineHeight);
+
+ int y1 = START_HEIGHT + 2 * lineHeight - lineHeight / 2 + FONT_SIZE + 2;
+ int y2 = START_HEIGHT + 5 * lineHeight - lineHeight / 2 + FONT_SIZE + 2;
+ int x = getScene()->width() - PADDING_LEFT;
+ line1_->setLine(PADDING_LEFT + 2, y1, x, y1);
+ line2_->setLine(PADDING_LEFT + 2, y2, x, y2);
+}
+
+QGraphicsTextItem* DetailScreen::createItem(QString const& text)
+{
+ QGraphicsTextItem* item = new QGraphicsTextItem(text);
+ QFont font(FONT, FONT_SIZE);
+ font.setBold(true);
+ item->setFont(font);
+ item->setDefaultTextColor(QColor("#fff"));
+ getScene()->addItem(item);
+ return item;
+}
+
+QGraphicsLineItem* DetailScreen::createLine()
+{
+ QGraphicsLineItem* item = new QGraphicsLineItem;
+ QPen pen(QColor("#ddd"));
+ pen.setWidth(1);
+ item->setPen(pen);
+ getScene()->addItem(item);
+ return item;
+}
+
+QString DetailScreen::roundDouble(double number)
+{
+ QString result;
+ result.sprintf("%.2lf", number);
+ return result;
+}
+
+QString DetailScreen::formatTime(qulonglong time)
+{
+ qulonglong secs = time % 60;
+ qulonglong mins_tmp = time / 60;
+ qulonglong mins = mins_tmp % 60;
+ qulonglong hours = mins_tmp / 60;
+
+ static char format[] = "%02d";
+
+ return QString().sprintf(format, hours) + ":" +
+ QString().sprintf(format, mins) + ":" +
+ QString().sprintf(format, secs);
+}
--- /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 DETAILSCREEN_H
+#define DETAILSCREEN_H
+
+#include "location.h"
+#include "graphicsscreen.h"
+
+class QGraphicsTextItem;
+class QGraphicsLineItem;
+class QGraphicsView;
+class GraphicsScene;
+
+class DetailScreen : public GraphicsScreen
+{
+ Q_OBJECT
+
+public:
+ DetailScreen(QWidget* parent = 0);
+
+public slots:
+ virtual void update();
+ void reArrange();
+
+private slots:
+ void updateTime();
+ void updateUnits();
+
+private:
+ QString formatTime(qulonglong time);
+ QGraphicsTextItem* createItem(QString const& text);
+ QGraphicsLineItem* createLine();
+ QString roundDouble(double number);
+ QGraphicsTextItem* tripLabel_;
+ QGraphicsTextItem* trip_;
+ QGraphicsTextItem* tripUnit_;
+ QGraphicsTextItem* totalLabel_;
+ QGraphicsTextItem* total_;
+ QGraphicsTextItem* totalUnit_;
+ QGraphicsTextItem* speedLabel_;
+ QGraphicsTextItem* speed_;
+ QGraphicsTextItem* speedUnit_;
+ QGraphicsTextItem* avgSpeedLabel_;
+ QGraphicsTextItem* avgSpeed_;
+ QGraphicsTextItem* avgSpeedUnit_;
+ QGraphicsTextItem* maxSpeedLabel_;
+ QGraphicsTextItem* maxSpeed_;
+ QGraphicsTextItem* maxSpeedUnit_;
+ QGraphicsTextItem* tripTimeLabel_;
+ QGraphicsTextItem* tripTime_;
+ QGraphicsTextItem* totalTimeLabel_;
+ QGraphicsTextItem* totalTime_;
+ QGraphicsLineItem* line1_;
+ QGraphicsLineItem* line2_;
+};
+
+#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 "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();
+}
--- /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);
+
+public slots:
+ virtual void update();
+ void reArrange();
+ void flip();
+
+private:
+ DetailScreen* screen_;
+};
+
+#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/QString>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include "filereader.h"
+
+FileReader::FileReader(QString const& dirname): Reader(), dirname_(dirname)
+{
+}
+
+bool FileReader::open()
+{
+ return true;
+}
+
+bool FileReader::readFile(QString const& filename, QByteArray& data)
+{
+ QFile file(dirname_ + QDir::separator() + filename);
+
+ if(!file.exists())
+ {
+ error_ = "No such file: " + filename;
+ return false;
+ }
+
+ if(file.open(QIODevice::ReadOnly))
+ {
+ data = file.readAll();
+ }
+ else
+ {
+ error_ = "Unable to open file: " + filename;
+ return false;
+ }
+
+ file.close();
+ return true;
+}
+
+bool FileReader::fileExists(QString const& filename) const
+{
+ return QFile::exists(dirname_ + QDir::separator() + filename);
+}
+
+bool FileReader::close()
+{
+ return true;
+}
+
+QString const& FileReader::errorString() 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 FILEREADER_H
+#define FILEREADER_H
+
+class QString;
+class QByteArray;
+
+#include "reader.h"
+
+class FileReader : public Reader
+{
+public:
+ FileReader(QString const& dirname);
+ bool open();
+ bool readFile(QString const& filename, QByteArray& data);
+ bool fileExists(QString const& filename) const;
+ bool close();
+ QString const& errorString() const;
+
+private:
+ QString dirname_;
+ QString error_;
+};
+
+#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/QString>
+#include <QtCore/QByteArray>
+#include <QtCore/QDebug>
+#include <QtCore/QMap>
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QFont>
+#include <QtGui/QFontDatabase>
+#include "graphicselement.h"
+#include "reader.h"
+#include "textelement.h"
+#include "imageelement.h"
+#include "rectangle.h"
+#include "pointer.h"
+#include "settings.h"
+
+GraphicsElement::GraphicsElement(Reader* reader): reader_(reader), error_("")
+{
+}
+
+GraphicsElement* GraphicsElement::getElement(QString const& name, Reader* reader)
+{
+ if(name == "image")
+ {
+ return new ImageElement(reader);
+ }
+
+ if(name == "text")
+ {
+ return new TextElement(reader);
+ }
+
+ if(name == "rectangle")
+ {
+ return new Rectangle(reader);
+ }
+
+ if(name == "pointer")
+ {
+ bool animate = Settings::instance().value("animate_pointer", true).toBool();
+ return new Pointer(reader, animate);
+ }
+
+ qDebug() << "Element not found: " << name;
+ return 0;
+}
+
+QString const& GraphicsElement::getError() const
+{
+ return error_;
+}
+
+void GraphicsElement::setError(QString const& error)
+{
+ error_ = error;
+}
+
+bool GraphicsElement::readFile(QString const& filename, QByteArray& data)
+{
+
+ if(!reader_->readFile(filename, data))
+ {
+ setError(reader_->errorString());
+ return false;
+ }
+
+ return true;
+}
+
+bool GraphicsElement::getFont(QString const& name, QFont& font)
+{
+ QByteArray data;
+
+ QMap<QString, QString>::const_iterator it = loadedFonts_.find(name);
+
+ if(it != loadedFonts_.end())
+ {
+ font = QFont(it.value());
+ return true;
+ }
+
+ if(!reader_->fileExists(name))
+ {
+ font = QFont(name);
+ return true;
+ }
+
+ if(!readFile(name, data))
+ {
+ return false;
+ }
+
+ int id = QFontDatabase::addApplicationFontFromData(data);
+
+ if(id == -1)
+ {
+ setError("Unable to load font: " + name);
+ loadedFonts_[name] = "";
+ return false;
+ }
+
+ QStringList families = QFontDatabase::applicationFontFamilies(id);
+
+ if(families.size() == 0)
+ {
+ setError("No fonts found in " + name);
+ return false;
+ }
+
+ loadedFonts_[name] = families.at(0);
+ font = QFont(families.at(0));
+
+ return true;
+}
+
+int GraphicsElement::getAttribute(QString const& name,
+ QString const& value,
+ const GraphicsElement::AttributeDetails details[],
+ int count,
+ int& intValue)
+{
+ QString lower = name.toLower();
+
+ for(int i = 0; i < count; i++)
+ {
+ if(details[i].name == lower)
+ {
+ if(!details[i].isInt)
+ {
+ return i;
+ }
+ else
+ {
+ bool ok = true;
+ int tmp = value.toInt(&ok);
+
+ if(ok)
+ {
+ intValue = tmp;
+ return i;
+ }
+ else
+ {
+ setError("Value for " + name + " is not integer ("+value+")");
+ return -1;
+ }
+ }
+ }
+ }
+
+ setError("Unknown attribute: " + name);
+ return -1;
+}
--- /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 GRAPHICSELEMENT_H
+#define GRAPHICSELEMENT_H
+
+#include <QtCore/QMap>
+#include "location.h"
+
+class QString;
+class QByteArray;
+class GraphicsScene;
+class Reader;
+class QFont;
+
+class GraphicsElement
+{
+public:
+
+ struct AttributeDetails
+ {
+ QString name;
+ bool isInt;
+ };
+
+ GraphicsElement(Reader* reader);
+ static GraphicsElement* getElement(QString const& name, Reader* reader);
+ virtual bool setAttribute(QString const& name, QString const& value) = 0;
+ virtual void addToScene(GraphicsScene* scene) = 0;
+ virtual void update() = 0;
+ QString const& getError() const;
+
+protected:
+ int getAttribute(QString const& name, QString const& value, const AttributeDetails details[], int count, int& intValue);
+ void setError(QString const& error);
+ bool readFile(QString const& name, QByteArray& data);
+ bool getFont(QString const& name, QFont& font);
+
+private:
+ Reader* reader_;
+ QString error_;
+ QMap<QString, QString> loadedFonts_;
+};
+
+#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 <QtGui/QGraphicsSceneMouseEvent>
+#include "graphicsscene.h"
+
+GraphicsScene::GraphicsScene(QRectF const& rect): QGraphicsScene(rect)
+{
+}
+
+void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ QGraphicsScene::mousePressEvent(event);
+
+ QPointF pos = event->screenPos();
+
+ if(pos.x() > CLICK_MARGIN && pos.x() < (width() - CLICK_MARGIN) &&
+ pos.y() > CLICK_MARGIN && pos.y() < (height() - CLICK_MARGIN))
+ {
+ emit 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 GRAPHICSSCENE_H
+#define GRAPHICSSCENE_H
+
+#include <QtGui/QGraphicsScene>
+
+class QGraphicsSceneMouseEvent;
+
+class GraphicsScene : public QGraphicsScene
+{
+ Q_OBJECT
+
+public:
+ GraphicsScene(QRectF const& rect);
+ static int const CLICK_MARGIN = 45;
+
+signals:
+ void clicked();
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+
+
+};
+
+#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 <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QApplication>
+#include "graphicsscreen.h"
+#include "imageitem.h"
+#include "graphicsscene.h"
+#include "odometer.h"
+
+namespace
+{
+ int const PADDING = 8;
+}
+
+GraphicsScreen::GraphicsScreen(QWidget* parent): QGraphicsView(parent),
+AbstractScreen(), scene_(0)
+{
+ QRect rect = QApplication::desktop()->availableGeometry();
+
+ scene_ = new GraphicsScene(QRect(QPoint(0, 0), rect.size()));
+ setScene(scene_);
+
+ connect(scene_, SIGNAL(clicked()), this, SIGNAL(clicked()));
+
+ minimizeButton_ = new ImageItem(":/resources/minimize.png");
+ minimizeButton_->setZValue(9999);
+ scene_->addItem(minimizeButton_);
+ connect(minimizeButton_, SIGNAL(clicked()), this, SIGNAL(minimizePressed()));
+
+ imageWidth_ = minimizeButton_->pixmap().width();
+
+ closeButton_ = new ImageItem(":/resources/close.png");
+ closeButton_->setZValue(9999);
+ scene_->addItem(closeButton_);
+ connect(closeButton_, SIGNAL(clicked()), this, SIGNAL(closePressed()));
+
+ settingsButton_ = new ImageItem(":/resources/settings.png");
+ settingsButton_->setZValue(9999);
+ scene_->addItem(settingsButton_);
+ connect(settingsButton_, SIGNAL(clicked()), this, SIGNAL(settingsPressed()));
+
+ reArrange();
+
+ connect(&(Odometer::instance()), SIGNAL(dataUpdated()), this, SLOT(update()));
+ connect(&(Odometer::instance()), SIGNAL(unitChanged()), this, SLOT(update()));
+}
+
+GraphicsScreen::~GraphicsScreen()
+{
+}
+
+void GraphicsScreen::reArrange()
+{
+ QRect rect = QApplication::desktop()->screenGeometry();
+ scene_->setSceneRect(rect);
+ minimizeButton_->setPos(PADDING, PADDING);
+ closeButton_->setPos(rect.width() - imageWidth_ - PADDING, PADDING);
+ settingsButton_->setPos((rect.width() / 2) - (imageWidth_ / 2) - (PADDING / 2), PADDING);
+}
+
+void GraphicsScreen::flip()
+{
+ if(isTransformed())
+ {
+ resetMatrix();
+ return;
+ }
+
+ setTransform(QTransform(1, 0, 0, 0, -1, 0, 0, 0, 1));
+}
+
+GraphicsScene* GraphicsScreen::getScene() const
+{
+ return scene_;
+}
--- /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 GRAPHICSSCREEN_H
+#define GRAPHICSSCREEN_H
+
+#include <QtGui/QGraphicsView>
+#include "abstractscreen.h"
+#include "location.h"
+#include "imageitem.h"
+
+class QGraphicsScene;
+class GraphicsScene;
+
+class GraphicsScreen : public QGraphicsView, public AbstractScreen
+{
+ Q_OBJECT
+
+public:
+ enum Orientation {LANDSCAPE, PORTRAIT};
+ GraphicsScreen(QWidget* parent = 0);
+ virtual ~GraphicsScreen();
+
+signals:
+ void minimizePressed();
+ void settingsPressed();
+ void closePressed();
+ void clicked();
+
+public slots:
+ virtual void update() = 0;
+ virtual void reArrange();
+ void flip();
+
+protected:
+ GraphicsScene* getScene() const;
+
+private:
+ GraphicsScene* scene_;
+ ImageItem* minimizeButton_;
+ ImageItem* settingsButton_;
+ ImageItem* closeButton_;
+ int imageWidth_;
+};
+
+#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/QString>
+#include <QtCore/QDebug>
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QGraphicsPixmapItem>
+#include "imageelement.h"
+#include "reader.h"
+#include "graphicsscene.h"
+
+namespace
+{
+ const GraphicsElement::AttributeDetails ATTRIBUTES[ImageElement::ATTRIBUTE_COUNT] =
+ {
+ {"xpos", true},
+ {"ypos", true},
+ {"src", false}
+ };
+}
+
+ImageElement::ImageElement(Reader* reader): GraphicsElement(reader)
+{
+ element_ = new QGraphicsPixmapItem();
+}
+
+bool ImageElement::setAttribute(QString const& name,
+ QString const& value)
+{
+ int intVal = 0;
+ int attrId = -1;
+
+ if((attrId = getAttribute(name, value, ATTRIBUTES, ATTRIBUTE_COUNT, intVal)) != -1)
+ {
+ Attribute attr = static_cast<Attribute>(attrId);
+
+ switch(attr)
+ {
+ case XPOS:
+ element_->setX(intVal);
+ break;
+ case YPOS:
+ element_->setY(intVal);
+ break;
+ case SRC:
+ return loadImage(value);
+ break;
+
+ default:
+ qDebug() << "Unknown attribute: " << attr;
+ return false;
+ }
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void ImageElement::addToScene(GraphicsScene* scene)
+{
+ scene->addItem(element_);
+}
+
+void ImageElement::update()
+{
+}
+
+bool ImageElement::loadImage(QString const& name)
+{
+ QPixmap pixmap;
+ QByteArray data;
+
+ if(!readFile(name, data))
+ {
+ return false;
+ }
+
+ if(!pixmap.loadFromData(data))
+ {
+ setError("Invalid image file: " + name);
+ return false;
+ }
+
+ element_->setPixmap(pixmap);
+
+ return true;
+}
--- /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 IMAGELEMENT_H
+#define IMAGELEMENT_H
+
+#include "graphicselement.h"
+#include "location.h"
+
+class ZipReader;
+class GraphicsScene;
+class QString;
+class QGraphicsPixmapItem;
+
+class ImageElement : public GraphicsElement
+{
+public:
+ enum Attribute {XPOS, YPOS, SRC, ATTRIBUTE_COUNT};
+ ImageElement(Reader* reader);
+ virtual bool setAttribute(QString const& name, QString const& value);
+ virtual void addToScene(GraphicsScene* scene);
+ virtual void update();
+
+private:
+ bool loadImage(QString const& name);
+ QGraphicsPixmapItem* element_;
+};
+
+#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 "imageitem.h"
+
+ImageItem::ImageItem(QString const& filename, QGraphicsItem *parent):
+QGraphicsPixmapItem(QPixmap(filename), parent)
+{
+}
+
+void ImageItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event);
+ emit 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 IMAGEITEM_H
+#define IMAGEITEM_H
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtGui/QGraphicsPixmapItem>
+
+class ImageItem: public QObject, public QGraphicsPixmapItem
+{
+ Q_OBJECT
+
+public:
+ ImageItem(QString const& filename, QGraphicsItem *parent = 0);
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+
+signals:
+ void clicked();
+};
+
+
+#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/QDebug>
+#include "location.h"
+
+namespace
+{
+ static const double KM_MULTIPLIER = 1.0;
+ static const double MILE_MULTIPLIER = 0.621371192;
+}
+
+Location::Unit Location::unit_ = Location::KM;
+
+Location::Location(QObject* parent): QObject(parent), started_(false),
+control_(0), device_(0)
+{
+ g_type_init();
+}
+
+Location::~Location()
+{
+ end();
+}
+
+void Location::start()
+{
+ control_ = location_gpsd_control_get_default();
+ device_ = (LocationGPSDevice*) g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL);
+
+ g_object_set(G_OBJECT(control_),
+ "preferred-method", LOCATION_METHOD_USER_SELECTED,
+ "preferred-interval", LOCATION_INTERVAL_DEFAULT,
+ NULL);
+
+ g_signal_connect(control_, "error-verbose", G_CALLBACK(onError), this);
+ g_signal_connect(device_, "changed", G_CALLBACK(onChanged), this);
+
+ location_gpsd_control_start(control_);
+
+ started_ = true;
+}
+
+void Location::end()
+{
+ if(!started_)
+ {
+ return;
+ }
+
+ location_gpsd_control_stop(control_);
+
+ g_object_unref(device_);
+ device_ = 0;
+ g_object_unref(control_);
+ control_ = 0;
+
+ started_ = false;
+}
+
+void Location::setUnit(Location::Unit unit)
+{
+ unit_ = unit;
+}
+
+Location::Unit Location::getUnit()
+{
+ return unit_;
+}
+
+double Location::getUnitMultiplier()
+{
+ if(unit_ == MILE)
+ {
+ return MILE_MULTIPLIER;
+ }
+
+ return KM_MULTIPLIER;
+}
+
+void Location::onChanged(LocationGPSDevice *device, gpointer data)
+{
+ if(device && device->fix &&
+ !(device->fix->fields & LOCATION_GPS_DEVICE_NONE_SET))
+ {
+
+ Fix fix;
+ fix.unit = unit_;
+ fix.time = device->fix->time;
+ fix.ept = device->fix->ept;
+
+ if (device->fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET)
+ {
+ fix.latitude = device->fix->latitude;
+ fix.longitude = device->fix->longitude;
+ fix.eph = device->fix->eph;
+ }
+
+ if(device->fix->fields & LOCATION_GPS_DEVICE_ALTITUDE_SET)
+ {
+ fix.altitude = device->fix->altitude;
+ fix.epv = device->fix->epv;
+ }
+
+ if(device->fix->fields & LOCATION_GPS_DEVICE_SPEED_SET)
+ {
+ fix.kmSpeed = device->fix->speed;
+ fix.speed = device->fix->speed * getUnitMultiplier();
+ fix.eps = device->fix->eps;
+ }
+
+ if(device->fix->fields & LOCATION_GPS_DEVICE_TRACK_SET)
+ {
+ fix.track = device->fix->track;
+ fix.epd = device->fix->epd;
+ }
+
+ if(device->fix->fields & LOCATION_GPS_DEVICE_CLIMB_SET)
+ {
+ fix.climb = device->fix->climb;
+ fix.epc = device->fix->epc;
+ }
+
+ Location* meh = (Location*) data;
+ meh->emit locationChanged(fix);
+ }
+}
+
+void Location::onError(LocationGPSDControl *control, LocationGPSDControlError error, gpointer data)
+{
+ Q_UNUSED(control);
+
+ Error err = SYSTEM_ERROR;
+
+ switch(error)
+ {
+ case LOCATION_ERROR_USER_REJECTED_DIALOG:
+ err = USER_REJECTED_DIALOG;
+ break;
+ case LOCATION_ERROR_USER_REJECTED_SETTINGS:
+ err = USER_REJECTED_SETTINGS;
+ break;
+ case LOCATION_ERROR_BT_GPS_NOT_AVAILABLE:
+ err = GPS_NOT_AVAILABLE;
+ break;
+ case LOCATION_ERROR_METHOD_NOT_ALLOWED_IN_OFFLINE_MODE:
+ err = NOT_ALLOWED_IN_OFFLINE_MODE;
+ break;
+ case LOCATION_ERROR_SYSTEM:
+ err = SYSTEM_ERROR;
+ break;
+ }
+
+ Location* meh = (Location*) data;
+ meh->emit locationError(err);
+}
+
+Location::Fix::Fix()
+{
+ unit = KM;
+ kmSpeed = 0.0;
+ time = 0.0;
+ ept = 0.0;
+ latitude = 0.0;
+ longitude = 0.0;
+ eph = 0.0;
+ altitude = 0.0;
+ epv = 0.0;
+ track = 0.0;
+ epd = 0.0;
+ speed = 0.0;
+ eps = 0.0;
+ climb = 0.0;
+ epc = 0.0;
+}
--- /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 LOCATION_H
+#define LOCATION_H
+
+#include <QtCore/QObject>
+#include <location/location-gps-device.h>
+#include <location/location-gpsd-control.h>
+
+class Location : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum Unit {KM, MILE};
+
+ struct Fix
+ {
+ Unit unit;
+ double kmSpeed;
+ double time;
+ double ept;
+ double latitude;
+ double longitude;
+ double eph;
+ double altitude;
+ double epv;
+ double track;
+ double epd;
+ double speed;
+ double eps;
+ double climb;
+ double epc;
+ Fix();
+ };
+
+ enum Error {USER_REJECTED_DIALOG,
+ USER_REJECTED_SETTINGS,
+ GPS_NOT_AVAILABLE,
+ NOT_ALLOWED_IN_OFFLINE_MODE,
+ SYSTEM_ERROR};
+
+ Location(QObject* parent = 0);
+ ~Location();
+ void start();
+ void end();
+ static void setUnit(Unit unit);
+ static Unit getUnit();
+ static double getUnitMultiplier();
+
+signals:
+ void locationChanged(Location::Fix const& fix);
+ void locationError(Location::Error error);
+
+private:
+ static void onChanged(LocationGPSDevice *device, gpointer data);
+ static void onError(LocationGPSDControl *control, LocationGPSDControlError error, gpointer data);
+ bool started_;
+ LocationGPSDControl* control_;
+ LocationGPSDevice* device_;
+ static Unit unit_;
+};
+
+#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/QObject>
+#include <QtGui/QApplication>
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ MainWindow window;
+
+ QObject::connect(&window, SIGNAL(quit()), &app, SLOT(quit()));
+
+ window.show();
+
+ return app.exec();
+}
--- /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 <QtGui/QPushButton>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QMessageBox>
+#include <QtGui/QLabel>
+#include <QtGui/QPixmap>
+#include "mainmenu.h"
+#include "themeselector.h"
+#include "unitselector.h"
+
+MainMenu::MainMenu(QWidget* parent): QDialog(parent), itemCount_(0),
+currentRow_(0), themeSelector_(0), unitSelector_(0), aboutDialog_(0)
+{
+ layout_ = new QVBoxLayout;
+ setLayout(layout_);
+
+ setWindowTitle(tr("Menu"));
+ addAction(tr("Reset trip"), this, SIGNAL(resetTrip()));
+ addAction(tr("Reset all"), this, SLOT(confirmReset()));
+ addAction(tr("Select theme"), this, SLOT(selectTheme()));
+ addAction(tr("Set unit"), this, SLOT(selectUnit()));
+ addAction(tr("Flip screen"), this, SIGNAL(flip()));
+ addAction(tr("About"), this, SLOT(showAbout()));
+}
+
+void MainMenu::selectTheme()
+{
+ if(!themeSelector_)
+ {
+ themeSelector_ = new ThemeSelector(this);
+ connect(themeSelector_, SIGNAL(themeChanged()), this, SIGNAL(themeChanged()));
+ }
+
+ themeSelector_->show();
+}
+
+void MainMenu::selectUnit()
+{
+ if(!unitSelector_)
+ {
+ unitSelector_ = new UnitSelector(this);
+ connect(unitSelector_, SIGNAL(unitChanged()), this, SIGNAL(unitChanged()));
+ }
+
+ unitSelector_->show();
+}
+
+void MainMenu::showAbout()
+{
+ if(!aboutDialog_)
+ {
+ aboutDialog_ = new QDialog(this);
+ aboutDialog_->setWindowTitle(tr("About"));
+
+ QHBoxLayout* mainLayout = new QHBoxLayout;
+ QPixmap pixmap(":/resources/appicon.png");
+ QLabel* image = new QLabel;
+ image->setPixmap(pixmap);
+ mainLayout->addWidget(image, 0, Qt::AlignLeft);
+ mainLayout->addSpacing(15);
+ QLabel* text = new QLabel(QString::fromUtf8("<font size='4'><b>jSpeed</b></font><br>(c) 2010 Jesse Hakanen<br><a href='http://jspeed.garage.maemo.org' style='color:#ffffff'>http://jspeed.garage.maemo.org</a>"));
+ text->setOpenExternalLinks(true);
+ mainLayout->addWidget(text, 10, Qt::AlignLeft);
+
+ aboutDialog_->setLayout(mainLayout);
+ }
+
+ aboutDialog_->show();
+}
+
+void MainMenu::confirmReset()
+{
+ QMessageBox::StandardButton result = QMessageBox::question(this, tr("Reset all"),
+ tr("Are you sure? All recorded data will be lost."),
+ QMessageBox::Yes | QMessageBox::No);
+
+ if(result == QMessageBox::Yes)
+ {
+ emit resetAll();
+ }
+}
+
+void MainMenu::addAction(const QString& text,
+ const QObject* receiver,
+ const char* member)
+{
+ if(itemCount_ % 2 == 0 || !currentRow_)
+ {
+ currentRow_ = new QHBoxLayout;
+ layout_->addLayout(currentRow_);
+ }
+
+ QPushButton* button = new QPushButton(text);
+ connect(button, SIGNAL(clicked(bool)), receiver, member);
+ connect(button, SIGNAL(clicked(bool)), this, SLOT(hide()));
+ currentRow_->addWidget(button);
+ itemCount_++;
+}
--- /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 MAINMENU_H
+#define MAINMENU_H
+
+#include <QtGui/QDialog>
+
+class QVBoxLayout;
+class QHBoxLayout;
+class ThemeSelector;
+class UnitSelector;
+
+class MainMenu : public QDialog
+{
+ Q_OBJECT
+
+public:
+ MainMenu(QWidget* parent = 0);
+ void addAction(const QString& text, const QObject* receiver, const char* member);
+
+signals:
+ void resetTrip();
+ void resetAll();
+ void flip();
+ void themeChanged();
+ void unitChanged();
+
+private slots:
+ void selectTheme();
+ void selectUnit();
+ void showAbout();
+ void confirmReset();
+
+private:
+ QVBoxLayout* layout_;
+ int itemCount_;
+ QHBoxLayout* currentRow_;
+ ThemeSelector* themeSelector_;
+ UnitSelector* unitSelector_;
+ QDialog* aboutDialog_;
+};
+
+#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 <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusMessage>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtCore/QTimer>
+#include <QtCore/QDebug>
+#include <QMaemo5InformationBox>
+#include "mainwindow.h"
+#include "mainwindowstack.h"
+#include "theme.h"
+#include "detailwidget.h"
+#include "mainmenu.h"
+#include "odometer.h"
+
+MainWindow::MainWindow(): QMainWindow(0), menu_(0), theme_(0)
+{
+ setWindowTitle(tr("jSpeed"));
+ showFullScreen();
+ Odometer::instance().start();
+ addScreens();
+ startBacklight();
+}
+
+MainWindow::~MainWindow()
+{
+}
+
+void MainWindow::addScreens()
+{
+ stack_ = new MainWindowStack(this);
+
+ connect(stack_, SIGNAL(minimizePressed()), this, SLOT(minimize()));
+ connect(stack_, SIGNAL(settingsPressed()), this, SLOT(openMenu()));
+ connect(stack_, SIGNAL(closePressed()), this, SIGNAL(quit()));
+
+ theme_ = new Theme;
+
+ if(!loadTheme())
+ {
+ return;
+ }
+
+ stack_->addScreen(theme_);
+ stack_->addScreen(new DetailWidget(this));
+
+ connect(QApplication::desktop(), SIGNAL(resized(int)), stack_, SLOT(reArrange()));
+
+ setCentralWidget(stack_);
+}
+
+bool MainWindow::loadTheme()
+{
+ if(!theme_->load())
+ {
+ QMaemo5InformationBox::information(this, tr("Unable to load theme: %1").arg(theme_->error()));
+ close();
+ return false;
+ }
+
+ if(theme_->landscapeEnabled() && theme_->portraitEnabled())
+ {
+ setAttribute(Qt::WA_Maemo5AutoOrientation, true);
+ }
+ else if(theme_->portraitEnabled())
+ {
+ setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
+ }
+
+ return true;
+}
+
+void MainWindow::minimize()
+{
+ QDBusConnection connection = QDBusConnection::sessionBus();
+ QDBusMessage msg = QDBusMessage::createSignal("/",
+ "com.nokia.hildon_desktop",
+ "exit_app_view");
+ connection.send(msg);
+}
+
+void MainWindow::openMenu()
+{
+ if(!menu_)
+ {
+ menu_ = new MainMenu(this);
+ connect(menu_, SIGNAL(resetTrip()), &(Odometer::instance()), SLOT(resetTrip()));
+ connect(menu_, SIGNAL(resetAll()), &(Odometer::instance()), SLOT(resetAll()));
+ connect(menu_, SIGNAL(flip()), stack_, SLOT(flip()));
+ connect(menu_, SIGNAL(themeChanged()), this, SLOT(loadTheme()));
+ connect(menu_, SIGNAL(unitChanged()), &(Odometer::instance()), SLOT(updateUnit()));
+ }
+
+ menu_->show();
+}
+
+void MainWindow::startBacklight()
+{
+ QTimer* timer = new QTimer(this);
+ timer->setInterval(25000);
+ connect(timer, SIGNAL(timeout()), this, SLOT(keepBacklightOn()));
+ timer->start();
+}
+
+void MainWindow::keepBacklightOn()
+{
+ QDBusConnection connection = QDBusConnection::systemBus();
+ QDBusMessage msg = QDBusMessage::createMethodCall("com.nokia.mce",
+ "/com/nokia/mce/request",
+ "com.nokia.mce.request",
+ "req_display_blanking_pause");
+
+ connection.call(msg);
+}
--- /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 MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+class MainScreen;
+class MainWindowStack;
+class MainMenu;
+class Theme;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow();
+ ~MainWindow();
+
+signals:
+ void quit();
+
+private slots:
+ void minimize();
+ void openMenu();
+ void keepBacklightOn();
+ bool loadTheme();
+
+private:
+ void addScreens();
+ void startGps();
+ void startBacklight();
+ MainWindowStack* stack_;
+ MainMenu* menu_;
+ Theme* theme_;
+
+};
+
+#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 "widgetscreen.h"
+#include "mainwindowstack.h"
+
+MainWindowStack::MainWindowStack(QWidget* parent): WidgetScreen(parent),
+currentScreen_(-1)
+{
+}
+
+void MainWindowStack::addScreen(WidgetScreen* screen)
+{
+ screens_.push_back(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, SLOT(toggleScreen()));
+ addWidget(screen);
+
+ if(currentScreen_ == -1)
+ {
+ toggleScreen();
+ }
+}
+
+void MainWindowStack::reArrange()
+{
+ for(int i = 0; i < screens_.size(); i++)
+ {
+ screens_.at(i)->reArrange();
+ }
+}
+
+void MainWindowStack::flip()
+{
+ for(int i = 0; i < screens_.size(); i++)
+ {
+ screens_.at(i)->flip();
+ }
+}
+
+void MainWindowStack::toggleScreen()
+{
+ if(currentScreen_ < 0)
+ {
+ currentScreen_ = 0;
+ }
+ else
+ {
+ currentScreen_++;
+
+ if(currentScreen_ >= screens_.size())
+ {
+ currentScreen_ = 0;
+ }
+ }
+
+ setCurrentIndex(currentScreen_);
+}
--- /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 MAINWINDOWSTACK_H
+#define MAINWINDOWSTACK_H
+
+#include <QtGui/QStackedWidget>
+#include "abstractscreen.h"
+#include "widgetscreen.h"
+
+class MainWindowStack : public WidgetScreen
+{
+ Q_OBJECT
+
+public:
+ MainWindowStack(QWidget* parent = 0);
+ void addScreen(WidgetScreen* screen);
+
+signals:
+ void minimizePressed();
+ void settingsPressed();
+ void closePressed();
+
+public slots:
+ virtual void reArrange();
+ virtual void flip();
+
+private slots:
+ void toggleScreen();
+
+private:
+ QList<WidgetScreen*> screens_;
+ int currentScreen_;
+};
+
+#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/QTime>
+#include <QtCore/QDebug>
+#include <QtCore/QTimer>
+#include "odometer.h"
+#include "settings.h"
+
+namespace
+{
+ QString const TOTAL_FIELD = "odometer_total";
+ QString const TOTALTIME_FIELD = "odometer_totaltime";
+ QString const TRIP_FIELD = "odometer_trip";
+ QString const TRIPTIME_FIELD = "odometer_triptime";
+ QString const MAXSPEED_FIELD = "odometer_maxspeed";
+ QString const KM_UNIT = "km";
+ QString const MILE_UNIT = "mi";
+ QString const KM_SPEEDUNIT = "km/h";
+ QString const MILE_SPEEDUNIT = "mph";
+ double const SPEED_TRESHOLD = 0.8;
+ double const SPEED_IGNORE_LEVEL = 0.2;
+}
+
+Odometer::Odometer(): QObject(0), trip_(0), total_(0),
+maxSpeed_(0), totalTime_(0), tripTime_(0), fixTimer_(0),
+mainTimer_(0), emitUpdate_(true), location_(0), signalTimer_(0)
+{
+ total_ = Settings::instance().value(TOTAL_FIELD, 0).toDouble();
+ totalTime_ = Settings::instance().value(TOTALTIME_FIELD, 0).toULongLong();
+ maxSpeed_ = Settings::instance().value(MAXSPEED_FIELD, 0).toDouble();
+ trip_ = Settings::instance().value(TRIP_FIELD, 0).toDouble();
+ tripTime_ = Settings::instance().value(TRIPTIME_FIELD, 0).toULongLong();
+ signalTimer_ = new QTimer(this);
+ signalTimer_->setSingleShot(false);
+ signalTimer_->setInterval(1000);
+ connect(signalTimer_, SIGNAL(timeout()), this, SIGNAL(timeUpdated()));
+ updateUnit();
+}
+
+Odometer::~Odometer()
+{
+ store();
+ delete fixTimer_;
+ delete mainTimer_;
+ end();
+}
+
+Odometer& Odometer::instance()
+{
+ static Odometer instance;
+ return instance;
+}
+
+void Odometer::start()
+{
+ location_ = new Location;
+ connect(location_, SIGNAL(locationChanged(Location::Fix const&)),
+ this, SLOT(update(Location::Fix const&)));
+ location_->start();
+}
+
+void Odometer::end()
+{
+ delete location_;
+ location_ = 0;
+}
+
+void Odometer::update(Location::Fix const& fix)
+{
+ if(fix.kmSpeed > maxSpeed_)
+ {
+ maxSpeed_ = fix.kmSpeed;
+ }
+
+ if(!fixTimer_)
+ {
+ fixTimer_ = new QTime();
+ fixTimer_->start();
+ }
+
+ int elapsed = fixTimer_->elapsed();
+
+ fixTimer_->restart();
+
+ if(elapsed > 200 && fix.kmSpeed > SPEED_IGNORE_LEVEL && elapsed < 10000)
+ {
+ if(fix.kmSpeed > SPEED_TRESHOLD)
+ {
+ double km = fix.kmSpeed * (static_cast<double>(elapsed) / (1000 * 3600));
+ trip_ += km;
+ total_ += km;
+
+ if(!mainTimer_)
+ {
+ startTiming();
+ }
+ }
+ else
+ {
+ endTiming();
+ }
+
+ latestFix_ = fix;
+ emit dataUpdated();
+ }
+ else
+ {
+ if(latestFix_.kmSpeed > 0.49)
+ {
+ latestFix_ = fix;
+ latestFix_.speed = 0.0;
+ latestFix_.kmSpeed = 0.0;
+ emit dataUpdated();
+ }
+
+ endTiming();
+ }
+}
+
+double Odometer::getTrip() const
+{
+ return trip_ * Location::getUnitMultiplier();
+}
+
+double Odometer::getAverageSpeed() const
+{
+ int elapsed = getTripTime();
+
+ if(elapsed == 0)
+ {
+ return 0.0;
+ }
+
+ return (static_cast<double>(trip_) * Location::getUnitMultiplier()) / (static_cast<double>(elapsed) / 60.0);
+}
+
+double Odometer::getTotal() const
+{
+ return total_ * Location::getUnitMultiplier();
+}
+
+double Odometer::getMaxSpeed() const
+{
+ return maxSpeed_ * Location::getUnitMultiplier();
+}
+
+qulonglong Odometer::getTotalTime() const
+{
+ return totalTime_ + timeAddition();
+}
+
+qulonglong Odometer::getTripTime() const
+{
+ return tripTime_ + timeAddition();
+}
+
+void Odometer::resetTrip()
+{
+ resetTiming();
+ trip_ = 0;
+ tripTime_ = 0;
+ maxSpeed_ = 0;
+
+ if(emitUpdate_)
+ {
+ emit timeUpdated();
+ emit dataUpdated();
+ }
+}
+
+void Odometer::resetTotal()
+{
+ resetTiming();
+ total_ = 0;
+ totalTime_ = 0;
+
+ if(emitUpdate_)
+ {
+ emit timeUpdated();
+ emit dataUpdated();
+ }
+}
+
+void Odometer::resetAll()
+{
+ emitUpdate_ = false;
+ resetTrip();
+ resetTotal();
+ emitUpdate_ = true;
+ emit timeUpdated();
+ emit dataUpdated();
+}
+
+void Odometer::store()
+{
+ Settings::instance().setValue(TOTAL_FIELD, total_);
+ Settings::instance().setValue(TOTALTIME_FIELD, getTotalTime());
+ Settings::instance().setValue(TRIP_FIELD, trip_);
+ Settings::instance().setValue(TRIPTIME_FIELD, getTripTime());
+ Settings::instance().setValue(MAXSPEED_FIELD, maxSpeed_);
+ Settings::instance().sync();
+}
+
+Location::Fix const& Odometer::getLatestFix() const
+{
+ return latestFix_;
+}
+
+QString const& Odometer::getUnit()
+{
+ if(Location::getUnit() == Location::KM)
+ {
+ return KM_UNIT;
+ }
+ else
+ {
+ return MILE_UNIT;
+ }
+}
+
+QString const& Odometer::getSpeedUnit()
+{
+ if(Location::getUnit() == Location::KM)
+ {
+ return KM_SPEEDUNIT;
+ }
+ else
+ {
+ return MILE_SPEEDUNIT;
+ }
+}
+
+void Odometer::updateUnit()
+{
+ QString unit = Settings::instance().value("unit", "km").toString();
+
+ if(unit == "km")
+ {
+ Location::setUnit(Location::KM);
+ }
+ else if(unit == "mile")
+ {
+ Location::setUnit(Location::MILE);
+ }
+ else
+ {
+ return;
+ }
+
+ emit unitChanged();
+}
+
+void Odometer::startTiming()
+{
+ signalTimer_->start();
+
+ if(mainTimer_)
+ {
+ mainTimer_->restart();
+ return;
+ }
+
+ mainTimer_ = new QTime();
+ mainTimer_->start();
+ signalTimer_->start();
+}
+
+void Odometer::endTiming()
+{
+ signalTimer_->stop();
+
+ if(!mainTimer_)
+ {
+ return;
+ }
+
+ int elapsed = mainTimer_->elapsed() / 1000;
+ totalTime_ += elapsed;
+ tripTime_ += elapsed;
+ delete mainTimer_;
+ mainTimer_ = 0;
+}
+
+void Odometer::resetTiming()
+{
+ if(!mainTimer_)
+ {
+ return;
+ }
+
+ endTiming();
+ startTiming();
+}
+
+int Odometer::timeAddition() const
+{
+ if(mainTimer_)
+ {
+ return mainTimer_->elapsed() / 1000;
+ }
+
+ return 0;
+}
--- /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 ODOMETER_H
+#define ODOMETER_H
+
+#include <QtCore/QObject>
+#include "location.h"
+
+class QTime;
+class QTimer;
+
+class Odometer : public QObject
+{
+ Q_OBJECT
+
+public:
+ virtual ~Odometer();
+ static Odometer& instance();
+ void start();
+ void end();
+ double getTrip() const;
+ double getAverageSpeed() const;
+ double getTotal() const;
+ double getMaxSpeed() const;
+ qulonglong getTotalTime() const;
+ qulonglong getTripTime() const;
+ Location::Fix const& getLatestFix() const;
+ static QString const& getUnit();
+ static QString const& getSpeedUnit();
+
+public slots:
+ void update(Location::Fix const& fix);
+ void updateUnit();
+
+signals:
+ void dataUpdated();
+ void timeUpdated();
+ void unitChanged();
+
+public slots:
+ void resetTrip();
+ void resetTotal();
+ void resetAll();
+ void store();
+
+private:
+ Q_DISABLE_COPY(Odometer);
+ Odometer();
+ void startTiming();
+ void endTiming();
+ void resetTiming();
+ int timeAddition() const;
+ Location::Fix latestFix_;
+ double trip_;
+ double total_;
+ double maxSpeed_;
+ qulonglong totalTime_;
+ qulonglong tripTime_;
+ QTime* fixTimer_;
+ QTime* mainTimer_;
+ bool emitUpdate_;
+ Location* location_;
+ QTimer* signalTimer_;
+};
+
+#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/QDebug>
+#include <QtCore/QTimeLine>
+#include <QtGui/QGraphicsItemAnimation>
+#include <QtGui/QGraphicsPixmapItem>
+#include <math.h>
+#include "pointer.h"
+#include "reader.h"
+#include "graphicsscene.h"
+#include "odometer.h"
+
+namespace
+{
+ const GraphicsElement::AttributeDetails ATTRIBUTES[Pointer::ATTRIBUTE_COUNT] =
+ {
+ {"xpos", true},
+ {"ypos", true},
+ {"src", false},
+ {"zeroangle", true},
+ {"fullangle", true},
+ {"zerospeed", true},
+ {"fullspeed", true},
+ {"xrotationpoint", true},
+ {"yrotationpoint", true}
+ };
+
+ int const ANIMATION_TIME = 500;
+ int const ANIMATION_FRAMES = 50;
+ int const ANIMATION_UPDATEINTERVAL = 20;
+}
+
+Pointer::Pointer(Reader* reader, bool animate): QObject(0), GraphicsElement(reader),
+xRotationPoint_(0), yRotationPoint_(0), x_(0), y_(0), zeroAngle_(0),
+fullAngle_(180), zeroSpeed_(0), fullSpeed_(220), targetAngle_(0),
+startAngle_(0), angle_(-1), imageSet_(false), animate_(animate), timer_(0)
+{
+ element_ = new QGraphicsPixmapItem();
+
+ if(animate_)
+ {
+ timer_ = new QTimeLine(ANIMATION_TIME);
+ timer_->setFrameRange(0, ANIMATION_FRAMES);
+ timer_->setUpdateInterval(ANIMATION_UPDATEINTERVAL);
+ connect(timer_, SIGNAL(frameChanged(int)), this, SLOT(setFrame(int)));
+ }
+
+}
+
+Pointer::~Pointer()
+{
+ delete timer_;
+}
+
+bool Pointer::setAttribute(QString const& name, QString const& value)
+{
+ int intVal = 0;
+ int attrId = -1;
+
+ if((attrId = getAttribute(name, value, ATTRIBUTES, ATTRIBUTE_COUNT, intVal)) != -1)
+ {
+ Attribute attr = static_cast<Attribute>(attrId);
+
+ switch(attr)
+ {
+ case XPOS:
+ x_ = intVal;
+ break;
+ case YPOS:
+ y_ = intVal;
+ break;
+ case SRC:
+ return loadImage(value);
+ break;
+ case ZEROANGLE:
+ zeroAngle_ = intVal;
+ break;
+ case FULLANGLE:
+ fullAngle_ = intVal;
+ break;
+ case ZEROSPEED:
+ zeroSpeed_ = intVal;
+ break;
+ case FULLSPEED:
+ fullSpeed_ = intVal;
+ break;
+ case XROTATIONPOINT:
+ xRotationPoint_ = intVal;
+ break;
+ case YROTATIONPOINT:
+ yRotationPoint_ = intVal;
+ break;
+ default:
+ qDebug() << "Unknown attribute: " << attr;
+ return false;
+ }
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void Pointer::addToScene(GraphicsScene* scene)
+{
+ if(!imageSet_)
+ {
+ return;
+ }
+
+ element_->setTransformOriginPoint(xRotationPoint_, yRotationPoint_);
+ element_->setX(x_ - xRotationPoint_);
+ element_->setY(y_ - yRotationPoint_);
+
+ bool animateVal = animate_;
+ animate_ = false;
+ update();
+ animate_ = animateVal;
+
+ scene->addItem(element_);
+}
+
+void Pointer::update()
+{
+ double speed = Odometer::instance().getLatestFix().kmSpeed;
+
+ if(speed < zeroSpeed_)
+ {
+ speed = static_cast<double>(zeroSpeed_);
+ }
+ else if(speed > fullSpeed_)
+ {
+ speed = static_cast<double>(fullSpeed_);
+ }
+
+ double multiplier = static_cast<double>(speed - zeroSpeed_) / (fullSpeed_ - zeroSpeed_);
+ double angle = static_cast<double>(zeroAngle_) + ((fullAngle_ - zeroAngle_) * multiplier);
+
+ int rounded = static_cast<int>(round(angle));
+
+ if(rounded == angle_)
+ {
+ return;
+ }
+
+ angle_ = rounded;
+
+ if(!animate_)
+ {
+ element_->setRotation(rounded);
+ }
+ else
+ {
+ targetAngle_ = rounded;
+ startAngle_ = element_->rotation();
+
+ if(timer_->state() == QTimeLine::Running)
+ {
+ timer_->stop();
+ }
+
+ timer_->start();
+ }
+}
+
+void Pointer::setFrame(int frame)
+{
+ element_->setRotation(startAngle_ + ((static_cast<double>(frame) / ANIMATION_FRAMES) * (targetAngle_ - startAngle_)));
+}
+
+bool Pointer::loadImage(QString const& name)
+{
+ QPixmap pixmap;
+ QByteArray data;
+
+ if(!readFile(name, data))
+ {
+ return false;
+ }
+
+ if(!pixmap.loadFromData(data))
+ {
+ setError("Invalid image file: " + name);
+ return false;
+ }
+
+ element_->setPixmap(pixmap);
+ imageSet_ = true;
+
+ return true;
+}
--- /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 POINTER_H
+#define POINTER_H
+
+#include <QtCore/QObject>
+#include "graphicselement.h"
+#include "location.h"
+
+class Reader;
+class QGraphicsPixmapItem;
+class GraphicsScene;
+class QTimeLine;
+
+class Pointer : public QObject, public GraphicsElement
+{
+ Q_OBJECT
+
+public:
+ enum Attribute {XPOS, YPOS, SRC, ZEROANGLE, FULLANGLE, ZEROSPEED, FULLSPEED, XROTATIONPOINT, YROTATIONPOINT, ATTRIBUTE_COUNT};
+ Pointer(Reader* reader, bool animate);
+ ~Pointer();
+ virtual bool setAttribute(QString const& name, QString const& value);
+ virtual void addToScene(GraphicsScene* scene);
+ virtual void update();
+
+private slots:
+ void setFrame(int frame);
+
+private:
+ bool loadImage(QString const& name);
+ QGraphicsPixmapItem* element_;
+ int xRotationPoint_;
+ int yRotationPoint_;
+ int x_;
+ int y_;
+ int zeroAngle_;
+ int fullAngle_;
+ int zeroSpeed_;
+ int fullSpeed_;
+ int targetAngle_;
+ int startAngle_;
+ int angle_;
+ bool imageSet_;
+ bool animate_;
+ QTimeLine* timer_;
+};
+
+#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 "reader.h"
+
+Reader::Reader(){}
--- /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 READER_H
+#define READER_H
+
+class QString;
+class QByteArray;
+
+class Reader
+{
+public:
+ Reader();
+ virtual bool open() = 0;
+ virtual bool readFile(QString const& filename, QByteArray& data) = 0;
+ virtual bool fileExists(QString const& filename) const = 0;
+ virtual bool close() = 0;
+ virtual QString const& errorString() const = 0;
+};
+
+#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 <QtGui/QGraphicsRectItem>
+#include <QtCore/QString>
+#include <QtCore/QDebug>
+#include "rectangle.h"
+#include "reader.h"
+#include "graphicsscene.h"
+
+namespace
+{
+ const GraphicsElement::AttributeDetails ATTRIBUTES[Rectangle::ATTRIBUTE_COUNT] =
+ {
+ {"xpos", true},
+ {"ypos", true},
+ {"width", true},
+ {"height", true},
+ {"color", false}
+ };
+}
+
+Rectangle::Rectangle(Reader* reader): GraphicsElement(reader),
+x_(0), y_(0), width_(0), height_(0)
+{
+ element_ = new QGraphicsRectItem();
+}
+
+bool Rectangle::setAttribute(QString const& name, QString const& value)
+{
+ int intVal = 0;
+ int attrId = -1;
+
+ if((attrId = getAttribute(name, value, ATTRIBUTES, ATTRIBUTE_COUNT, intVal)) != -1)
+ {
+ Attribute attr = static_cast<Attribute>(attrId);
+
+ switch(attr)
+ {
+ case XPOS:
+ x_ = intVal;
+ break;
+ case YPOS:
+ y_ = intVal;
+ break;
+ case WIDTH:
+ width_ = intVal;
+ break;
+ case HEIGHT:
+ height_ = intVal;
+ break;
+ case COLOR:
+ element_->setBrush(QBrush(QColor(value)));
+ break;
+
+ default:
+ qDebug() << "Unknown attribute: " << attr;
+ return false;
+ }
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void Rectangle::addToScene(GraphicsScene* scene)
+{
+ int width = width_;
+
+ int maxSize = scene->width();
+
+ if(scene->height() > maxSize)
+ {
+ maxSize = scene->height();
+ }
+
+ if(width <= 0)
+ {
+ width = maxSize;
+ }
+
+ int height = height_;
+
+ if(height <= 0)
+ {
+ height = maxSize;
+ }
+
+ element_->setRect(x_, y_, width, height);
+ scene->addItem(element_);
+}
+
+void Rectangle::update()
+{
+}
--- /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 RECTANGLE_H
+#define RECTANGLE_H
+
+#include "graphicselement.h"
+#include "location.h"
+
+class GraphicsScene;
+class QString;
+class Reader;
+class QGraphicsRectItem;
+
+class Rectangle : public GraphicsElement
+{
+public:
+ enum Attribute {XPOS, YPOS, WIDTH, HEIGHT, COLOR, ATTRIBUTE_COUNT};
+ Rectangle(Reader* reader);
+ virtual bool setAttribute(QString const& name, QString const& value);
+ virtual void addToScene(GraphicsScene* scene);
+ virtual void update();
+
+private:
+ QGraphicsRectItem* element_;
+ int x_;
+ int y_;
+ int width_;
+ int height_;
+};
+
+#endif
--- /dev/null
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>resources/minimize.png</file>
+ <file>resources/close.png</file>
+ <file>resources/settings.png</file>
+ <file>resources/appicon.png</file>
+ <file>resources/themes/default/theme.xml</file>
+ <file>resources/themes/default/digital7.ttf</file>
+ <file>resources/themes/default/background.png</file>
+</qresource>
+</RCC>
--- /dev/null
+<theme>
+<orientation name="landscape">
+ <image>
+ <xpos>0</xpos>
+ <ypos>0</ypos>
+ <src>background.png</src>
+ </image>
+ <text>
+ <data>000</data>
+ <font>digital7.ttf</font>
+ <size>320</size>
+ <xpos>100</xpos>
+ <ypos>75</ypos>
+ <color>#17202b</color>
+ <align>right</align>
+ <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>
+ </text>
+</orientation>
+<orientation name="portrait">
+ <image>
+ <xpos>0</xpos>
+ <ypos>0</ypos>
+ <src>background.png</src>
+ </image>
+ <text>
+ <data>000</data>
+ <font>digital7.ttf</font>
+ <size>230</size>
+ <xpos>0</xpos>
+ <ypos>260</ypos>
+ <color>#17202b</color>
+ <align>right</align>
+ <width>450</width>
+ </text>
+ <text>
+ <data>{SPEED}</data>
+ <font>digital7.ttf</font>
+ <size>230</size>
+ <xpos>0</xpos>
+ <ypos>260</ypos>
+ <color>#fff</color>
+ <align>right</align>
+ <width>450</width>
+ <format>%.0f</format>
+ </text>
+</orientation>
+</theme>
--- /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/QDebug>
+#include "settings.h"
+
+QString Settings::dir_ = initDir();
+
+Settings::Settings(): QSettings("jspeed")
+{
+}
+
+Settings& Settings::instance()
+{
+ static Settings instance;
+ return instance;
+}
+
+QString const& Settings::getDir()
+{
+ return dir_;
+}
+
+QString Settings::initDir()
+{
+ return QDir::home().path() + QDir::separator() + ".jspeed" + QDir::separator();
+}
--- /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 SETTINGS_H
+#define SETTINGS_H
+
+#include <QtCore/QSettings>
+
+class Settings : public QSettings
+{
+public:
+ static Settings& instance();
+ static QString const& getDir();
+ static void close();
+
+private:
+ Settings();
+ static QString initDir();
+ static QString dir_;
+
+};
+
+#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/QString>
+#include <QtCore/QDebug>
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QGraphicsTextItem>
+#include "reader.h"
+#include "textelement.h"
+#include "odometer.h"
+#include "graphicsscene.h"
+#include "location.h"
+
+namespace
+{
+ const GraphicsElement::AttributeDetails ATTRIBUTES[TextElement::ATTRIBUTE_COUNT] =
+ {
+ {"xpos", true},
+ {"ypos", true},
+ {"data", false},
+ {"format", false},
+ {"width", true},
+ {"align", false},
+ {"color", false},
+ {"size", true},
+ {"font", false}
+ };
+}
+
+TextElement::TextElement(Reader* reader): GraphicsElement(reader),
+data_(""), format_(""), align_("left"), fontSize_(16), hasSpecialField_(false)
+{
+ element_ = new QGraphicsTextItem();
+}
+
+bool TextElement::setAttribute(QString const& name, QString const& value)
+{
+ int intVal = 0;
+ int attrId = -1;
+
+ if((attrId = getAttribute(name, value, ATTRIBUTES, ATTRIBUTE_COUNT, intVal)) != -1)
+ {
+ Attribute attr = static_cast<Attribute>(attrId);
+
+ bool fontChanged = false;
+
+ switch(attr)
+ {
+ case XPOS:
+ element_->setX(intVal);
+ break;
+ case YPOS:
+ element_->setY(intVal);
+ break;
+ case DATA:
+ data_ = value;
+ break;
+ case FORMAT:
+ format_ = value;
+ break;
+ case WIDTH:
+ element_->setTextWidth(intVal);
+ break;
+ case ALIGN:
+ align_ = value;
+ break;
+ case COLOR:
+ element_->setDefaultTextColor(QColor(value));
+ break;
+ case SIZE:
+ fontSize_ = intVal;
+ fontChanged = true;
+ break;
+ case FONT:
+ fontFile_ = value;
+ fontChanged = true;
+ break;
+ default:
+ qDebug() << "Unknown attribute: " << attr;
+ return false;
+ }
+
+ if(fontChanged)
+ {
+ if(!fontFile_.isEmpty())
+ {
+ QFont font;
+
+ if(getFont(fontFile_, font))
+ {
+ font.setPointSize(fontSize_);
+ element_->setFont(font);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ element_->setFont(QFont("Default", fontSize_));
+ }
+ }
+
+ return true;
+
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void TextElement::addToScene(GraphicsScene* scene)
+{
+ Location::Fix fix;
+
+ QString replaced = data_;
+
+ hasSpecialField_ = replaceSpecialField(replaced);
+
+ updateHtml(replaced);
+
+ scene->addItem(element_);
+}
+
+void TextElement::update()
+{
+ if(!hasSpecialField_)
+ {
+ return;
+ }
+
+ QString replaced = data_;
+ replaceSpecialField(replaced);
+
+ updateHtml(replaced);
+}
+
+void TextElement::updateHtml(QString const& data)
+{
+ element_->setHtml("<div align='"+align_+"'>"+data+"</div>");
+}
+
+bool TextElement::replaceSpecialField(QString& value)
+{
+ bool found = false;
+
+ if(value.indexOf("{TRIP}") != -1)
+ {
+ value = value.replace("{TRIP}", formatString(Odometer::instance().getTrip()));
+ found = true;
+ }
+
+ if(value.indexOf("{TOTAL}") != -1)
+ {
+ value = value.replace("{TOTAL}", formatString(Odometer::instance().getTotal()));
+ found = true;
+ }
+
+ if(value.indexOf("{SPEED}") != -1)
+ {
+ value = value.replace("{SPEED}", formatString(Odometer::instance().getLatestFix().speed));
+ found = true;
+ }
+
+ if(value.indexOf("{SPEED_UNIT}") != -1)
+ {
+ value = value.replace("{SPEED_UNIT}", Odometer::getSpeedUnit());
+ found = true;
+ }
+
+ if(value.indexOf("{UNIT}") != -1)
+ {
+ value = value.replace("{UNIT}", Odometer::getUnit());
+ found = true;
+ }
+
+ return found;
+
+}
+
+QString TextElement::formatString(double val)
+{
+ QString format = format_;
+
+ if(format.isEmpty())
+ {
+ format = "%.1lf";
+ }
+
+ QString result;
+ result.sprintf(format.toLatin1().data(), val);
+
+ return result;
+}
--- /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 TEXTELEMENT_H
+#define TEXTELEMENT_H
+
+#include "graphicselement.h"
+
+class Reader;
+class QString;
+class GraphicsScene;
+class QGraphicsTextItem;
+
+class TextElement : public GraphicsElement
+{
+public:
+ enum Attribute {XPOS, YPOS, DATA, FORMAT, WIDTH, ALIGN, COLOR, SIZE, FONT, ATTRIBUTE_COUNT};
+ TextElement(Reader* reader);
+ virtual bool setAttribute(QString const& name, QString const& value);
+ virtual void addToScene(GraphicsScene* scene);
+ virtual void update();
+
+private:
+ void updateHtml(QString const& data);
+ bool replaceSpecialField(QString& value);
+ QString formatString(double val);
+ QGraphicsTextItem* element_;
+ QString data_;
+ QString format_;
+ QString align_;
+ int fontSize_;
+ QString fontFile_;
+ bool hasSpecialField_;
+};
+
+#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 <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 "settings.h"
+
+namespace
+{
+ QString const RESOURCE_DIR = ":/resources/themes/";
+ QString const THEME_SUFFIX = ".jspeed";
+}
+
+Theme::Theme(QWidget* parent): WidgetScreen(parent),
+portraitId_(-1), landscapeId_(-1), reader_(0),
+portrait_(0), landscape_(0), 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())
+ {
+ qDebug() << "Ladattiin " << theme;
+ 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 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_);
+ }
+ }
+ 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 portraitId_ != -1;
+}
+
+bool Theme::landscapeEnabled() const
+{
+ return landscapeId_ != -1;
+}
+
+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_->reArrange();
+ }
+ }
+}
+
+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 Theme : public WidgetScreen
+{
+ Q_OBJECT
+
+public:
+ Theme(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_;
+ 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 <QtGui/QWidget>
+#include <QtCore/QString>
+#include <QtCore/QDebug>
+#include <QtXml/QDomNode>
+#include <QtXml/QDomNodeList>
+#include "themescreen.h"
+#include "graphicselement.h"
+#include "reader.h"
+
+ThemeScreen::ThemeScreen(QWidget* parent): GraphicsScreen(parent)
+{
+}
+
+bool ThemeScreen::load(QDomNode const& data, Reader* reader)
+{
+ QDomNodeList childNodes = data.childNodes();
+
+ if(childNodes.size() == 0)
+ {
+ error_ = "No elements specified for " + data.nodeName();
+ return false;
+ }
+
+ for(int i = 0; i < childNodes.size(); i++)
+ {
+ GraphicsElement* element = GraphicsElement::getElement(childNodes.at(i).nodeName(), reader);
+
+ if(element == 0)
+ {
+ qDebug() << "Warning: invalid element: " << childNodes.at(i).nodeName();
+ continue;
+ }
+
+ elements_.push_back(element);
+
+ QDomNodeList options = childNodes.at(i).childNodes();
+
+ for(int i = 0; i < options.size(); i++)
+ {
+ if(!element->setAttribute(options.at(i).nodeName(), options.at(i).toElement().text()))
+ {
+ qDebug() << "Warning: invalid option: " << options.at(i).nodeName();
+ }
+ }
+
+ element->addToScene(getScene());
+
+ }
+
+ return true;
+}
+
+void ThemeScreen::update()
+{
+ for(int i = 0; i < elements_.size(); i++)
+ {
+ elements_.at(i)->update();
+ }
+}
--- /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 THEMESCREEN_H
+#define THEMESCREEN_H
+
+#include "graphicsscreen.h"
+#include "location.h"
+
+class QString;
+class QWidget;
+class GraphicsElement;
+class QDomNode;
+class Reader;
+
+class ThemeScreen : public GraphicsScreen
+{
+public:
+ ThemeScreen(QWidget* parent = 0);
+ bool load(QDomNode const& data, Reader* reader);
+ virtual void update();
+
+private:
+ QList<GraphicsElement*> elements_;
+ QString error_;
+};
+
+#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/QDebug>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtGui/QFileDialog>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QMessageBox>
+#include "themeselector.h"
+#include "buttonselector.h"
+#include "theme.h"
+#include "settings.h"
+
+ThemeSelector::ThemeSelector(QWidget* parent): QDialog(parent)
+{
+ setWindowTitle(tr("Select theme"));
+
+ QHBoxLayout* layout = new QHBoxLayout;
+ QHBoxLayout* left = new QHBoxLayout;
+
+ QPushButton* saveButton = new QPushButton(tr("Save"));
+ connect(saveButton, SIGNAL(clicked(bool)), this, SLOT(saveTheme()));
+ QDialogButtonBox* buttons = new QDialogButtonBox;
+ buttons->setCenterButtons(false);
+ buttons->addButton(saveButton, QDialogButtonBox::AcceptRole);
+
+ selector_ = new ButtonSelector(tr("Theme"), this);
+ theme_ = Settings::instance().value("theme", "default").toString();
+
+ QPushButton* loadButton = new QPushButton(tr("Import"));
+ connect(loadButton, SIGNAL(clicked(bool)), this, SLOT(loadFromFile()));
+
+ left->addWidget(selector_, Qt::AlignLeft);
+ left->addWidget(loadButton);
+
+ layout->addLayout(left, Qt::AlignLeft);
+ layout->addWidget(buttons);
+
+ setLayout(layout);
+
+}
+
+void ThemeSelector::saveTheme()
+{
+ QString theme = selector_->value().toString();
+
+ if(theme == theme_)
+ {
+ hide();
+ return;
+ }
+
+ Settings::instance().setValue("theme", theme);
+ hide();
+ theme_ = theme;
+ emit themeChanged();
+}
+
+void ThemeSelector::loadFromFile()
+{
+ QString filename = QFileDialog::getOpenFileName(this, tr("Open file"),
+ QDir::home().path(),
+ tr("Theme files") + "(*" + Theme::getThemeSuffix() + ")");
+
+ if(filename.isEmpty())
+ {
+ return;
+ }
+
+ qDebug() << filename;
+
+ QString basename;
+ int i = filename.lastIndexOf(QDir::separator());
+
+ if(i == -1)
+ {
+ basename = filename;
+ }
+ else
+ {
+ basename = filename.mid(i + 1);
+ }
+
+ QString targetFile = Theme::getThemeDir() + basename;
+
+ qDebug() << targetFile;
+
+ bool ok = true;
+
+ if(QFile::exists(targetFile))
+ {
+ ok = confirmCopy(basename);
+
+ if(ok)
+ {
+ QFile::remove(targetFile);
+ }
+ }
+
+ if(ok)
+ {
+ QFile::copy(filename, targetFile);
+ QString name;
+ QString id;
+ getThemeDetails(basename, name, id);
+ theme_ = id;
+ loadThemes();
+ }
+}
+
+void ThemeSelector::loadThemes()
+{
+ selector_->clear();
+ selector_->addItem(tr("Default"), "default");
+ QDir themeDir(Theme::getThemeDir());
+
+ if(!themeDir.exists() || !themeDir.isReadable())
+ {
+ qDebug() << "Warning: theme dir (" + Theme::getThemeDir() + ") doesn't exist or is read protected";
+ return;
+ }
+
+ QStringList filters;
+ filters << "*" + Theme::getThemeSuffix();
+ themeDir.setNameFilters(filters);
+ themeDir.setFilter(QDir::Files);
+ QStringList files = themeDir.entryList();
+
+ for(int i = 0; i < files.size(); i++)
+ {
+ QString name;
+ QString id;
+ getThemeDetails(files.at(i), name, id);
+ selector_->addItem(name, id);
+
+ if(id == theme_)
+ {
+ selector_->setCurrentIndex(i + 1);
+ }
+ }
+
+}
+
+void ThemeSelector::getThemeDetails(QString filename,
+ QString& name,
+ QString& id)
+{
+ static QRegExp cleaner(QRegExp::escape(Theme::getThemeSuffix()) + "$");
+ filename = filename.replace(cleaner, "");
+
+ id = filename;
+ name = filename.at(0).toUpper() + filename.mid(1);
+}
+
+bool ThemeSelector::confirmCopy(QString const& filename)
+{
+ QMessageBox::StandardButton result = QMessageBox::question(this, tr("File exists"),
+ tr("Theme file %1 already exists in theme directory, overwrite?").arg(filename),
+ QMessageBox::Yes | QMessageBox::No);
+
+ return (result == QMessageBox::Yes);
+}
+
+void ThemeSelector::setVisible(bool visible)
+{
+ if(visible)
+ {
+ loadThemes();
+ }
+
+ QDialog::setVisible(visible);
+}
--- /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 THEMESELECTOR_H
+#define THEMESELECTOR_H
+
+#include <QtGui/QDialog>
+
+class ButtonSelector;
+class QString;
+
+class ThemeSelector : public QDialog
+{
+ Q_OBJECT
+
+public:
+ ThemeSelector(QWidget* parent = 0);
+
+signals:
+ void themeChanged();
+
+private slots:
+ void saveTheme();
+ void loadFromFile();
+
+protected:
+ virtual void setVisible(bool visible);
+
+private:
+ void loadThemes();
+ void getThemeDetails(QString filename, QString& name, QString& id);
+ bool confirmCopy(QString const& name);
+ ButtonSelector* selector_;
+ QString theme_;
+};
+
+
+#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/QString>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QPushButton>
+#include <QtGui/QDialogButtonBox>
+#include "unitselector.h"
+#include "buttonselector.h"
+#include "settings.h"
+
+UnitSelector::UnitSelector(QWidget* parent): QDialog(parent)
+{
+ setWindowTitle(tr("Set unit"));
+
+ unit_ = Settings::instance().value("unit", "km").toString();
+
+ QHBoxLayout* layout = new QHBoxLayout;
+
+ selector_ = new ButtonSelector(tr("Unit"));
+
+ selector_->addItem(tr("Kilometers"), "km");
+ selector_->addItem(tr("Miles"), "mile");
+
+ if(unit_ == "mile")
+ {
+ selector_->setCurrentIndex(1);
+ }
+
+ layout->addWidget(selector_, Qt::AlignLeft);
+
+ QPushButton* button = new QPushButton(tr("Save"));
+ connect(button, SIGNAL(clicked(bool)), this, SLOT(saveUnit()));
+ QDialogButtonBox* buttons = new QDialogButtonBox;
+ buttons->setCenterButtons(false);
+ buttons->addButton(button, QDialogButtonBox::AcceptRole);
+
+ layout->addWidget(buttons);
+
+ setLayout(layout);
+}
+
+void UnitSelector::saveUnit()
+{
+ QString value = selector_->value().toString();
+
+ if(value == unit_)
+ {
+ hide();
+ return;
+ }
+
+ Settings::instance().setValue("unit", value);
+ unit_ = value;
+ hide();
+ emit unitChanged();
+}
--- /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 UNITSELECTOR_H
+#define UNITSELECTOR_H
+
+#include <QtGui/QDialog>
+
+class ButtonSelector;
+class QString;
+
+class UnitSelector : public QDialog
+{
+ Q_OBJECT
+
+public:
+ UnitSelector(QWidget* parent = 0);
+
+signals:
+ void unitChanged();
+
+private slots:
+ void saveUnit();
+
+private:
+ ButtonSelector* selector_;
+ QString unit_;
+};
+
+#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 "widgetscreen.h"
+
+WidgetScreen::WidgetScreen(QWidget* parent): QStackedWidget(parent), AbstractScreen(){}
--- /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 WIDGETSCREEN_H
+#define WIDGETSCREEN_H
+
+#include <QtGui/QWidget>
+#include <QtGui/QStackedWidget>
+#include "abstractscreen.h"
+
+class WidgetScreen : public QStackedWidget, public AbstractScreen
+{
+ Q_OBJECT
+
+public:
+ WidgetScreen(QWidget* parent = 0);
+
+signals:
+ void minimizePressed();
+ void settingsPressed();
+ void closePressed();
+ void clicked();
+
+};
+
+#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/QString>
+#include <QtCore/QByteArray>
+#include <QtCore/QDebug>
+#include "zipreader.h"
+
+namespace
+{
+ int const BUFFER_SIZE = 16384;
+}
+
+ZipReader::ZipReader(QString const& filename): Reader(),
+filename_(filename), zip_(0), error_("")
+{
+}
+
+bool ZipReader::open()
+{
+ int error = 0;
+
+ zip_ = zip_open(filename_.toLatin1().data(), 0, &error);
+
+ if(error)
+ {
+ error_ = "Not a valid zip file";
+ zip_ = 0;
+ return false;
+ }
+
+ return true;
+}
+
+bool ZipReader::readFile(QString const& filename, QByteArray& data)
+{
+ zip_file* file = 0;
+
+ file = zip_fopen(zip_, filename.toLatin1().data(), 0);
+
+ if(!file)
+ {
+ error_ = QString(zip_strerror(zip_));
+ return false;
+ }
+
+ char buffer[BUFFER_SIZE];
+
+ int read = 0;
+
+ data.clear();
+
+ while((read = zip_fread(file, buffer, BUFFER_SIZE)) > 0)
+ {
+ data.append(buffer, read);
+ }
+
+ return true;
+}
+
+bool ZipReader::fileExists(QString const& filename) const
+{
+ return zip_name_locate(zip_, filename.toLatin1().data(), 0) != -1;
+}
+
+bool ZipReader::close()
+{
+ if(zip_close(zip_) == 0)
+ {
+ zip_ = 0;
+ return true;
+ }
+
+ return false;
+}
+
+QString const& ZipReader::errorString() 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 ZIPREADER_H
+#define ZIPREADER_H
+
+#include "reader.h"
+#include "zip.h"
+
+class QString;
+class QByteArray;
+
+class ZipReader : public Reader
+{
+public:
+ ZipReader(QString const& filename);
+ bool open();
+ bool readFile(QString const& filename, QByteArray& data);
+ bool fileExists(QString const& filename) const;
+ bool close();
+ QString const& errorString() const;
+
+private:
+ QString filename_;
+ zip* zip_;
+ QString error_;
+};
+
+#endif