From 64f0d552c4c5235f19988138edeb3048ac7ec151 Mon Sep 17 00:00:00 2001 From: eshe Date: Tue, 13 Jul 2010 20:44:15 +0100 Subject: [PATCH] Initial commit. --- debian/changelog | 5 + debian/compat | 1 + debian/control | 136 ++++++++++++ debian/copyright | 14 ++ debian/dirs | 2 + debian/rules | 54 +++++ jspeed.pro | 89 ++++++++ src/abstractscreen.cpp | 21 ++ src/abstractscreen.h | 30 +++ src/buttonselector.cpp | 148 +++++++++++++ src/buttonselector.h | 61 +++++ src/data/26x26/jspeed.png | Bin 0 -> 2074 bytes src/data/48x48/jspeed.png | Bin 0 -> 5442 bytes src/data/64x64/jspeed.png | Bin 0 -> 8601 bytes src/data/jspeed.desktop | 9 + src/detailscreen.cpp | 195 ++++++++++++++++ src/detailscreen.h | 73 ++++++ src/detailwidget.cpp | 45 ++++ src/detailwidget.h | 42 ++++ src/filereader.cpp | 70 ++++++ src/filereader.h | 42 ++++ src/graphicselement.cpp | 170 ++++++++++++++ src/graphicselement.h | 60 +++++ src/graphicsscene.cpp | 37 ++++ src/graphicsscene.h | 43 ++++ src/graphicsscreen.cpp | 93 ++++++++ src/graphicsscreen.h | 61 +++++ src/imageelement.cpp | 105 +++++++++ src/imageelement.h | 44 ++++ src/imageitem.cpp | 31 +++ src/imageitem.h | 41 ++++ src/location.cpp | 190 ++++++++++++++++ src/location.h | 81 +++++++ src/main.cpp | 34 +++ src/mainmenu.cpp | 116 ++++++++++ src/mainmenu.h | 59 +++++ src/mainwindow.cpp | 131 +++++++++++ src/mainwindow.h | 56 +++++ src/mainwindowstack.cpp | 75 +++++++ src/mainwindowstack.h | 51 +++++ src/odometer.cpp | 319 +++++++++++++++++++++++++++ src/odometer.h | 82 +++++++ src/pointer.cpp | 209 ++++++++++++++++++ src/pointer.h | 65 ++++++ src/reader.cpp | 21 ++ src/reader.h | 36 +++ src/rectangle.cpp | 113 ++++++++++ src/rectangle.h | 47 ++++ src/resources.qrc | 11 + src/resources/appicon.png | Bin 0 -> 26930 bytes src/resources/close.png | Bin 0 -> 3588 bytes src/resources/minimize.png | Bin 0 -> 3694 bytes src/resources/settings.png | Bin 0 -> 4822 bytes src/resources/themes/default/background.png | Bin 0 -> 132701 bytes src/resources/themes/default/digital7.ttf | Bin 0 -> 33992 bytes src/resources/themes/default/theme.xml | 58 +++++ src/settings.cpp | 43 ++++ src/settings.h | 38 ++++ src/textelement.cpp | 211 ++++++++++++++++++ src/textelement.h | 51 +++++ src/theme.cpp | 293 ++++++++++++++++++++++++ src/theme.h | 59 +++++ src/themescreen.cpp | 77 +++++++ src/themescreen.h | 43 ++++ src/themeselector.cpp | 192 ++++++++++++++++ src/themeselector.h | 53 +++++ src/unitselector.cpp | 72 ++++++ src/unitselector.h | 45 ++++ src/widgetscreen.cpp | 21 ++ src/widgetscreen.h | 41 ++++ src/zipreader.cpp | 95 ++++++++ src/zipreader.h | 44 ++++ 72 files changed, 4854 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/dirs create mode 100644 debian/rules create mode 100644 jspeed.pro create mode 100644 src/abstractscreen.cpp create mode 100644 src/abstractscreen.h create mode 100644 src/buttonselector.cpp create mode 100644 src/buttonselector.h create mode 100644 src/data/26x26/jspeed.png create mode 100644 src/data/48x48/jspeed.png create mode 100644 src/data/64x64/jspeed.png create mode 100644 src/data/jspeed.desktop create mode 100644 src/detailscreen.cpp create mode 100644 src/detailscreen.h create mode 100644 src/detailwidget.cpp create mode 100644 src/detailwidget.h create mode 100644 src/filereader.cpp create mode 100644 src/filereader.h create mode 100644 src/graphicselement.cpp create mode 100644 src/graphicselement.h create mode 100644 src/graphicsscene.cpp create mode 100644 src/graphicsscene.h create mode 100644 src/graphicsscreen.cpp create mode 100644 src/graphicsscreen.h create mode 100644 src/imageelement.cpp create mode 100644 src/imageelement.h create mode 100644 src/imageitem.cpp create mode 100644 src/imageitem.h create mode 100644 src/location.cpp create mode 100644 src/location.h create mode 100644 src/main.cpp create mode 100644 src/mainmenu.cpp create mode 100644 src/mainmenu.h create mode 100644 src/mainwindow.cpp create mode 100644 src/mainwindow.h create mode 100644 src/mainwindowstack.cpp create mode 100644 src/mainwindowstack.h create mode 100644 src/odometer.cpp create mode 100644 src/odometer.h create mode 100644 src/pointer.cpp create mode 100644 src/pointer.h create mode 100644 src/reader.cpp create mode 100644 src/reader.h create mode 100644 src/rectangle.cpp create mode 100644 src/rectangle.h create mode 100644 src/resources.qrc create mode 100644 src/resources/appicon.png create mode 100644 src/resources/close.png create mode 100644 src/resources/minimize.png create mode 100644 src/resources/settings.png create mode 100755 src/resources/themes/default/background.png create mode 100755 src/resources/themes/default/digital7.ttf create mode 100755 src/resources/themes/default/theme.xml create mode 100644 src/settings.cpp create mode 100644 src/settings.h create mode 100644 src/textelement.cpp create mode 100644 src/textelement.h create mode 100644 src/theme.cpp create mode 100644 src/theme.h create mode 100644 src/themescreen.cpp create mode 100644 src/themescreen.h create mode 100644 src/themeselector.cpp create mode 100644 src/themeselector.h create mode 100644 src/unitselector.cpp create mode 100644 src/unitselector.h create mode 100644 src/widgetscreen.cpp create mode 100644 src/widgetscreen.h create mode 100644 src/zipreader.cpp create mode 100644 src/zipreader.h delete mode 100644 welcome diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..999b76d --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +jspeed (0.1-1) unstable; urgency=low + + * Initial release. + + -- Jesse Hakanen Tue, 13 Jul 2010 13:17:36 +0100 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..f522be9 --- /dev/null +++ b/debian/control @@ -0,0 +1,136 @@ +Source: jspeed +Section: user/utilities +Priority: optional +Maintainer: Jesse Hakanen +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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 diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..8e8e2e4 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,14 @@ +Copyright (c) 2010 Jesse Hakanen + +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 . diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..80507f1 --- /dev/null +++ b/debian/dirs @@ -0,0 +1,2 @@ +usr/bin +usr/share/applications/hildon diff --git a/debian/rules b/debian/rules new file mode 100644 index 0000000..64396e2 --- /dev/null +++ b/debian/rules @@ -0,0 +1,54 @@ +#!/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 diff --git a/jspeed.pro b/jspeed.pro new file mode 100644 index 0000000..b770792 --- /dev/null +++ b/jspeed.pro @@ -0,0 +1,89 @@ +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 +} diff --git a/src/abstractscreen.cpp b/src/abstractscreen.cpp new file mode 100644 index 0000000..4c9097e --- /dev/null +++ b/src/abstractscreen.cpp @@ -0,0 +1,21 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include "abstractscreen.h" + +AbstractScreen::AbstractScreen(){} diff --git a/src/abstractscreen.h b/src/abstractscreen.h new file mode 100644 index 0000000..fe22f04 --- /dev/null +++ b/src/abstractscreen.h @@ -0,0 +1,30 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef ABSTRACTSCREEN_H +#define ABSTRACTSCREEN_H + +class AbstractScreen +{ +public: + AbstractScreen(); + virtual void reArrange() = 0; + virtual void flip() = 0; +}; + +#endif diff --git a/src/buttonselector.cpp b/src/buttonselector.cpp new file mode 100644 index 0000000..c1adde3 --- /dev/null +++ b/src/buttonselector.cpp @@ -0,0 +1,148 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include "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()); +} diff --git a/src/buttonselector.h b/src/buttonselector.h new file mode 100644 index 0000000..e36c159 --- /dev/null +++ b/src/buttonselector.h @@ -0,0 +1,61 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef BUTTONSELECTOR_H +#define BUTTONSELECTOR_H + +#include +#include +#include +#include +#include + +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 diff --git a/src/data/26x26/jspeed.png b/src/data/26x26/jspeed.png new file mode 100644 index 0000000000000000000000000000000000000000..ab74e4b1b51913b4245a1461d89ae1af5554aa84 GIT binary patch literal 2074 zcmV+#2<7*QP)kFXIKz;@RGNx92{FD6LZUNk{kj&b!}ozVm(8N_WpVKL2Q%M(9u! z6{@Pj=XD0XUZuszh!v9)llLX!vAO)w^7-=H1Hr&G-GMW)ggBK*WTq@(!m=!whFs16 zu&aELBSqEV^LdK>KJA&y7cXyaJ$|(0?9~qRj*TIfO!5>^;P#-ds0d%4I~R|xSv%A; zuj%E&% zA%%^X8raZF89ot2wuMqjnSso zJOYyj{3lL8zkM5mH55E3VbXc5xfw>D2YCnof-J=_URMv%*@2_`UXBNfYafV4;~k2k zK)GVez&N`F~4nn69cPs`Msn(c@N~cr_a}*GySV*c(6GkQjlTI_F zEkmKC96E;T>+t}oerx}m@AeFgeT@g8CQ~Vy&APY$_Scndi8%5)t|B>S4yHD2V5DBV zZo*cg3QdA~wn1eIu0c8}rGvz(79@VW3E9#x3VLth@8jcWZ9TL$;Pu6^~OD z8}}c74^Ap5n@B)>{1MzQyZ~!r0w(JzGq5!+DIiq2(y8E9OJo#NnhJe*7|PHfL@dg4 z+nkBlP9{m!ng z3i_C@78dv#du|T_bldp3;na+vH9Ll!&dNd7iGokWxZiA_%6m)%|Xr`Lyw!wJEl zEExzhH5V;{)v}rjQUTiN8y-_R}__4!=oepbkujTv9@m9t7#!C7=&256lQG=%-7$5!UIyu zQfZglJ8|%>qqx-BjX3+QyRQ$uy*)XBm<&FHEEzHUei+l!$P^dDpGu;-vTCrW@75*# z#;4uqX4KW5UfM8Y{Rh`NpdUE`#p#40Wo+qoRGO}%2bm0RbWv~ zmPo@Qr5cUMdun84m>sU&9mleXnXN4rg9>F`vQnvXG?kXvzdiZYwYYeteg9}=^o}Y& zJa_(+BTX}#&a5mdMuOAWkO#tH7(d*A4C|626=@ohy(NuhS!7wa6h)Gz(y|RRV1Dm$ zh)34KA{&{CO021>MP+rvu`3~a9_Tsa>LYM^O~eG-OzwAGu-);r{nLQIJV7JFQI&8^}{wT-h4kE z`}()Ggo{G2Jn_5VAkp3qhn#gTH=0+jg3db0rVUasY4(Zit01Ss2xnc}M;}6y>MSWi zfOpk_Z98$Jr{@Q!KREg46a$ok`RtK~f|T~o=XY&A)Ou1h&YdTd6^hd>iYseGQB{p7 zt!)tH^^KyWx=s}H@ACQ?B2-Z&RJX_e_DjoGh{H!u8(W{*v8jkt+{qsLqDSgjl`m`7 zto#1q)>FgJZhu~cO2f7hHkp*4;B_iEnt8#fA~#`0X?dmC@vB|p?RVbmZ*FdR?B4DD z-^TB4ay%eJloAEOP|>o@n}7P`!o^D)`}%s73l~2@SJw?p@CuNM3xz_M*?1ooEL@C= z@+zyX?c?@0_V3#tjZU58`6w|eyMRdB%-s7gizpl52o+~VMn|(3&Yw%3J^SHMJQlsi?|X?)iJL?Z!D)^7=N-w_Nyu*W6G5Ul z2bpC-E@NjdDEY{iNy)1z7x@?w$*q&b6p_q*hkpw&08AJiopwl>mH+?%07*qoM6N<$ Eg7Q8Dj8)FhxHvLgsM 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 literal 0 HcmV?d00001 diff --git a/src/data/64x64/jspeed.png b/src/data/64x64/jspeed.png new file mode 100644 index 0000000000000000000000000000000000000000..b431a0724f3b23dc2eea7cd42dd4b8b57051743c GIT binary patch literal 8601 zcmV;KA!go*P)8_R-j5{(;^jd9&&|V?6dRud&)iK|JwV#-}fIBAp}lVwBm35sj3P^;i1TV zD3JT|9E^R~wlL0`=lB*Smu?$E+d(u6RRzQ8ryvbMqeB-c)pb#;YoeO=PidNHF@K}` z1$dtPXW#PB<*|_e>AG&7*X91-`Wrqh3r_qm|C#fH!-0I4OTED3Rxa>*lygZ5MRYpz zuiq^d#!qOa`Iq!Y#jaRP-x`aHZS>qW{2l(3|1A&T6LjeJcpUTnKF4wrd?uX?@h@#1 zVN_OCqrAKVRaI4JYHUPHYbyj>N#SQZkeic(oV;8V4J)EC6hns;A}!#xl-k@I)jx?u zv=?G={Zl%Qv7Y{4cz}FA>BQ%C+>jo0K18}1%;%e$JMh`I9oX{m7JRz-160@7BGMgB zxriAXecVQ#Q<0Vy#Nfgqm^Xg`E}DB0W==mZCm8ho$mdmmlt|!MM^}7hG^)L8zwQ6r z1B7B&-RE&G%m}%D<#Z~OD0Z=H&wi|V{dH{KvKeK^i$OMlbIdqo_r?&PI|tdvj-hMT z1xP1ZQ@bRY~p@$}r z6HEtgya9y=kDz_tMabT|9ZeTsh~R-kP}^GJq7Z1M^Ii%ISA9L4(HPnWq==R`}%dWsZci)3^&z{87(!077uXJ`rR}pA7C}v3fT@}Dy z=kvNQ&&~F&rc4h*2taR-LaQAZGKk;sNWSVC`ThR!}|mY|7d4d#C_*I_hZS8*CE^!#)RvZ z!?}Dpa(C@P3t81gvFvJYfv>a-`R{Lp?(uMrfIHb#XDgWM;mlJrnr7etQ zH{6KrCB+zj-gG!ZA^JUmtiAiBg*@c)iNS->GiMG&dOE_hXG0@z=sD+X_=)_e9NVl2 z9u6m*i8y+P7a>5Pr&0>^pD2N=p~1L@lqAUF-4|X6e{CJYls+*qA3bNC1y4<_;R)>> zNZYd)T@%khu&o`TAw#j_qYqJ0T8RahEkJt6GcVE`KM{?^k9?bvv$FyQ5#snhUCamk z?yCk4Nc%%aX9UYhyF0gkig6cTikcO-V9-l1!*i;d(AHAW~v?n|Jf%m7AzQX=FtAkXt~cK5*5)+WKwLC<65 z2;v4#N~=5vRyhBbNDrZX@Zpn;My3U;3qMwNw+!(fRlq~9;y zN)M$=EYN&jW70|z4U=V$uvK>^Oq%X#T%ctTS0~bxpl9lY4{_Q$2tPRVc*rm%DRl}j zJr+YJg`4~2Ny>-KPzhu|+PnpmCyqf)ZTrvL+Pfd=4~pZ*78nXReDqWw*H26H{%}N5 z-ulW@4VZWFJhUZZ&>#6V{N(DPkG4oU%=S_#ue0zR)BJFGUNPewhNXEcRD(jN;60@R z(T~vE%Uu?X{0h1$tRMi?=sj#8O948aOHgW!GYzKsv@Tx;H5x@Pk+bm=CgGDUTd1h= zXva>}O^?OmyX~Pc@r=Pn2qbjPK9t;?;3_`3{w+ob+&&CLzu^1Cg6YZm$vE z=#)k^vUY-wJte&}e`IphUjT3#@1%5cL2 zGE=|I zhC#+gfvkEx<^D)^j})Vwl-wHohNAeemy|e$-Z6{IX?jPDGD^qNC5X8)mkKiY2&lMlit9^KPmvM=5&@0inC8iBhDF?%A^tA3B7Pp9-!nGEUwA z!U&z~WW**ecXMWkF7f}tcWE|+A?UE+4Jk4zv2^eJ5Cl7R#mm@&LsdwZ^DyX7z{w`vm2~Md5 z&uVQA((b(v8i()FrKot}1$;n!VcE4;xza;{MfDA>#SVv>Qb2;-f+iQr$x5FWjp=xI z(?)oikWflVkbvr`QxGn^>c`gOj9txKE&M++boYbdfwNbwxUgTxq1Ny$e^0lq%q zVZM`%B&{yY%xbxpDtU^dCxQggXV?7s*t7F<)KMXqnUOZhw3uB18s$p=bl%^+ zZ!f}Kop5a5j`-k0L@2fBlww%pnywi+Sl1#MXJ?HfC0A1+L^pO91yua)7?ZA{NNKlpKA|Bvc^9FPVBh3;}lLE8$b+hx5nv5nV zAbWF^2Q-lq4iNp)-f0VOM93qGi2dD3;}E@fdmsQGTRE8;jraCnACSkEq8TtLYk3}h z6iy;;v8%6!o{^4SJ9o-^0%;_xf}ErR2oDN^LI0TEsKD`Z;smFvpzPU0tV@+4Zp1Og zzSj%5J%k4?)1o4!1YNfsn@X^s*ZW>)SBT{$oMzQX4}MX40FzrL5au zXo*J&Bjm_HoFQaE#q*%pR|pH-+sLR?TO2uY%us;eH<3WFC<%f@UJ86ZZ(dVVJL($h zp-@Sy<>txa!$DP?j4&#Nby9!`_+^+mURh0UnJ`*e-zYT=5M(7O{U^&%CwYSCLxuU7 zUG)Fu6!&M)xf)XPZc?_N@JDBW6Dj;jq7N%GI~%>{pAWUN5{Wa$%SNim&xb;pjEl4Q z)G5%14u#X9p!o1XguCPL`@MxOr;8{p_DK(LIh})DPDiMe5VNtV5$@wBWGhPKRaogM_Dw(2|Y$~v7{pm_g%sC#xpP`(A1r<9&_Gc%;HKu?09X5t0o zf}R}Kc{}hCyCcCo;VwK-dK{jNOmvfi|3X4|i1_FxYtyXv*g{TX50M~+C^_2O;3zJJ zsH~EPQ%Dx{bi@79OGf#8!AwMm%d}F7?RKeYKCgE`G6aaI$km)KUb&%MtCp0|%@O+5 zVb#Y_*1RscfYGj^+FaK1jy`T_0Z}qla?C1y5t=ztFEPv*F*Z(lEKr0lUsXq_Pw|hU z;n+b8t}-hdK~`9jQCiQ``+5@{xHf$#6-!i>ilHzx3RRs-V(Fzv{7LMy@r5<@~QJM#C~WDbxL#=jbN8`)2$L z(ruiusE5kX@t8&Fbx^@T^im3LBxZT#v(JzKej+sjtLZvtT3S+At1!}&?=n__jMvjO zq)<+il)sH@!r>$pPh51NtXsfdVsZ!miTH=xPKDz}@895~+@oWm71K%zQVXHxA}CV* z4aJ;@NY((xqNifAK_h2tgvLyNf4TBLEd0TIbDhEbyM$u*<{KfNeI6e@`6Lcf1(#-| zXS2RA7eV`^QNz=$&ar?=fY^#Ghi1->6s~l30+EQ>ZQ}ZZYd3=k$XUeV30{kry);N( zPPI5=0EYqtijBi7iVcA5ux2U2wrZOcfJQf^p?mMT9gD75&{ue?o~Jym+;=zj6Ntrl zZklCblU-V6vi-Y&tX7qyi#65!n#PV^`rE zPYBP!DooyQA-QhFwXJUN%Ljx(mV|BtJq?|mU6@AcXwl^hzJ2Y%+%8+W5}CvSqP(({ zFj`+4Z4(w4YQ{5##R4rbmA@s7t!`tcoI>3$B!X!KelBECb=w=&BW>+%tw{xRb%m>m z1jR><9EA+d^;K2S7hDGYM~jVIYtOxZWgWp1TuU|{^(2ZfqZ+>dA0u)%AvMu{G`GZ2 zRTDcvWn2&rafZ|2NpmcOV{rb4ky)_FBg)#&ygs}m7%H4&Y z8oG%A*5uf70U}T1#*FGCJg408<)*k zTU*;J$Bqu>4j(og$2NWlW!f~T73BsdaEpuA>@K|&3U_)(Q60W@Dz8%CQq zk4oPh`F#PeI|?E_j9p^K=TPeEpc0?Jjvbi1;#P^1t!=F(RPdE070}bu(^gmCaA54{ z!DpRC+WVlQ6gpLc&OLjR3zZl*9*LW8fl8I3sw@~FLGBbhFQc2mZu+T=00QT<2*;CJy?`UXj_#$lgfOsN?>e|{Jw0p~W z=YJoLM}G?!<^A|QcT0D7Q&k9dC#nmOorOeZ23$?esaCp~^O*!lo?^_mY$Ohy!#%+ zph3{S{uX<^_F{my?+1DJq6~N!f04TkiL#(y90+5c2y-c=5$P*%@YQ>*R6z zzCH3=1J~1kg7&@h5g#@b(|V&AJ!%xnE9x8D+S(3UD??5z#kID#A1|+{_;T8mQRmK@ zH3u)h`U=FNMMNc4`N;}XUyTbSCKUXI7ai*=_wWt3G!{OTBx~gcqM;BY3>Y-G@7#ug z0|t_Cp5$_QvPG^lMzo=gxjG4NxxX%u>H+lcLGV5skl8DvKF2+u=dh)@>O+P=A@s-g zZCLOxzhS0~((=;JdLq4TE?!zoHAFa7#c`y#_-#I3a^)f*EhyLHRLTZ|JVG!vwK}z` zVm3jvRI#F&oguTmp3K{v!+C{=LxYYh3F%K&SIVlhGu+9Dj2fx{Pga(pl@#lgM8(Me z3Hdye3)u6!mHw;-jhTItS%RuVSrAcSq@@MmAz7}x{7STu&&Y_5n@XG+uid=(}Kn~1ppVL;-+UqYWe3EKK~ zxcmo~W8%cIC_YwPQdd{|p&}G1bE+q3_WQ!!;o7}l?tPiPAY`z=q>ZGA^g*ZVxj3WZd7n7o<0 z*oP0n`I~=*M%ATpU_fXAuHB|Y}N6**ye`P%n;zrK{bbV<}_&6T?2jXo4A^4i!-NABoHnx zFRwVcn(@ZIGGtVPi9`~O$u&>z-nVm2(Xjcq^7nXKZnz$J^;M`IH)8j%f|FZKC(9*1 zNPaM9E|f`=APBtp%MkU27fACFULi=fzlEa7G-=dSN@^)g*w+WF)nX)j3dsUXuKd#b z7B7+OfediOn4ogE_`p}dN1J8uPms|xLVER;)zB!s0$Dlu$2;#Pa3$-1x#yW!EZXIE zxxe{=gtV49*fn?V-tq7kUzJr|GH(v$GzXE)R>H1deNnCEM9cklEcKN=FFOjj)hmid+0DU;@div zx2``Dl??=B7l~Jg!DL7Xv)&irm014cydEdZaPF1uZwfgNg;bpHAw{{I6kbHJIRz@R zKM|Mv77^n6d08Iv8v&<`e_8d>?+P)&*uD3_`Q%g3Mvq3kJB(pO)wk{32d_61FTeKE z?}&u0lD&?8f6qSgnBf76wTNkc#lddJDQU}RTkiOD+rGn-CQZPab#EcCb}f481^QK2 z!TH8o2|_xRvpS_TJwjWm;dQfqj}r45I%F_Lj~pq(VGK==A{e$ihK| zQuq=42@d_vDU$DDB^DJG$@?U5@){uVhB$vG*wsO!%Xl9ZKq}GS`0YPMeDfyc69rzo z;XS0M=VIgL4?ZK|A7qAUtz-$?NPZ^w>2R^tdWw%9{cu3u&>zm8 zd3I>@m;HONnp{1PC7>KX*-4e*BDdDpOb7xB?T#PavV<_~8``<(J=V z^+lIof!y2ySV-IR&OQ%Rh+*kfi>1d5A3g$i-+l*b>+12tg^Nf*L#Q@5LJE!87X_sN zydaXe^A4y)coOT@BAY;X!@9RIb@EhvuxZOzA8h{1e23H7?Q|MnpKzv%lY%X5x$^S) zMizK){hFj(u$vAn9D-j`j z%Ha2>;oT2Dz&X>-F$yCVShdy{M6xZ%YnU;A067#6udR6#XH7c`+jo4~{Lv?yt|M96 zW8^vYHC3put3@5v8NBXkeSh%Evrifr@NM7Fxe4eB3J0Tb$S_QpbmqLsx3JO&LLChlGNfH-jIxQLSHm6W%LUp?~p zm-zz+EjH)H%X@=p;H@|u`2dk$GF-QH6tr8uZ2c2W$xrKhlv3LVSNiv2no zX>{+r`3uCG>o$n$nl>qTRZUnt{mg646DCc4j;>is<5FH*qA`QUS^Nbo|5E@O1vIkF zf1K$xJwolT0DBftYzlCjH~CDrPqU4nIYQ>(eK(=};8}Aoo^a)&rGsY9nC%@pG?xgG zj+0b7?BD+dLDU zAwvo&J196&T8@uD-V}cCoplwvcW(QN*d+J$WAd{CV|3c~srW_M+%kdaHLqoAs$0qA zbP7;SO@cmMMWbWg@cDW2MowpGBPra^?y=ARIb~%qQ1UPuc|6fRFs!#B_+oaC(BA=;m(ej zX}zc^NViRB`)Ic*z!E-eQ$X~)C_ph4V4=RxriehlFbMVYj-YuQuz`<-#!g#Cp|E#3 z$l9DuWZg(ahziYaDkEf{%03e2q+_N9drYCa`dK+_+jiNmi zYYUHn4I}*KvEQaN>prJV5vpz2|Ji^=^7L;JK5FxTh-pQzXTWnHI8@0-4&~i00000NkvXXu0mjf@B_YF literal 0 HcmV?d00001 diff --git a/src/data/jspeed.desktop b/src/data/jspeed.desktop new file mode 100644 index 0000000..e22e0e2 --- /dev/null +++ b/src/data/jspeed.desktop @@ -0,0 +1,9 @@ +[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 diff --git a/src/detailscreen.cpp b/src/detailscreen.cpp new file mode 100644 index 0000000..1c3cd10 --- /dev/null +++ b/src/detailscreen.cpp @@ -0,0 +1,195 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "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); +} diff --git a/src/detailscreen.h b/src/detailscreen.h new file mode 100644 index 0000000..4c30e75 --- /dev/null +++ b/src/detailscreen.h @@ -0,0 +1,73 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef 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 diff --git a/src/detailwidget.cpp b/src/detailwidget.cpp new file mode 100644 index 0000000..4a6f523 --- /dev/null +++ b/src/detailwidget.cpp @@ -0,0 +1,45 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include "detailwidget.h" +#include "detailscreen.h" + +DetailWidget::DetailWidget(QWidget* parent): WidgetScreen(parent) +{ + screen_ = new DetailScreen; + connect(screen_, SIGNAL(minimizePressed()), this, SIGNAL(minimizePressed())); + connect(screen_, SIGNAL(settingsPressed()), this, SIGNAL(settingsPressed())); + connect(screen_, SIGNAL(closePressed()), this, SIGNAL(closePressed())); + connect(screen_, SIGNAL(clicked()), this, SIGNAL(clicked())); + addWidget(screen_); +} + +void DetailWidget::update() +{ + screen_->update(); +} + +void DetailWidget::reArrange() +{ + screen_->reArrange(); +} + +void DetailWidget::flip() +{ + screen_->flip(); +} diff --git a/src/detailwidget.h b/src/detailwidget.h new file mode 100644 index 0000000..037c60d --- /dev/null +++ b/src/detailwidget.h @@ -0,0 +1,42 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef DETAILWIDGET_H +#define DETAILWIDGET_H + +#include "widgetscreen.h" + +class DetailScreen; + +class DetailWidget : public WidgetScreen +{ + Q_OBJECT + +public: + DetailWidget(QWidget* parent = 0); + +public slots: + virtual void update(); + void reArrange(); + void flip(); + +private: + DetailScreen* screen_; +}; + +#endif diff --git a/src/filereader.cpp b/src/filereader.cpp new file mode 100644 index 0000000..0cd9054 --- /dev/null +++ b/src/filereader.cpp @@ -0,0 +1,70 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include "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_; +} diff --git a/src/filereader.h b/src/filereader.h new file mode 100644 index 0000000..dc118d4 --- /dev/null +++ b/src/filereader.h @@ -0,0 +1,42 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef 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 diff --git a/src/graphicselement.cpp b/src/graphicselement.cpp new file mode 100644 index 0000000..b290d87 --- /dev/null +++ b/src/graphicselement.cpp @@ -0,0 +1,170 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "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::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; +} diff --git a/src/graphicselement.h b/src/graphicselement.h new file mode 100644 index 0000000..fbd7858 --- /dev/null +++ b/src/graphicselement.h @@ -0,0 +1,60 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef GRAPHICSELEMENT_H +#define GRAPHICSELEMENT_H + +#include +#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 loadedFonts_; +}; + +#endif diff --git a/src/graphicsscene.cpp b/src/graphicsscene.cpp new file mode 100644 index 0000000..d512944 --- /dev/null +++ b/src/graphicsscene.cpp @@ -0,0 +1,37 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include "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(); + } +} diff --git a/src/graphicsscene.h b/src/graphicsscene.h new file mode 100644 index 0000000..d5ac6d7 --- /dev/null +++ b/src/graphicsscene.h @@ -0,0 +1,43 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef GRAPHICSSCENE_H +#define GRAPHICSSCENE_H + +#include + +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 diff --git a/src/graphicsscreen.cpp b/src/graphicsscreen.cpp new file mode 100644 index 0000000..19dfb36 --- /dev/null +++ b/src/graphicsscreen.cpp @@ -0,0 +1,93 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include "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_; +} diff --git a/src/graphicsscreen.h b/src/graphicsscreen.h new file mode 100644 index 0000000..75947a7 --- /dev/null +++ b/src/graphicsscreen.h @@ -0,0 +1,61 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef GRAPHICSSCREEN_H +#define GRAPHICSSCREEN_H + +#include +#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 diff --git a/src/imageelement.cpp b/src/imageelement.cpp new file mode 100644 index 0000000..2002666 --- /dev/null +++ b/src/imageelement.cpp @@ -0,0 +1,105 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include "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(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; +} diff --git a/src/imageelement.h b/src/imageelement.h new file mode 100644 index 0000000..c21cba6 --- /dev/null +++ b/src/imageelement.h @@ -0,0 +1,44 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef 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 diff --git a/src/imageitem.cpp b/src/imageitem.cpp new file mode 100644 index 0000000..046334c --- /dev/null +++ b/src/imageitem.cpp @@ -0,0 +1,31 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include "imageitem.h" + +ImageItem::ImageItem(QString const& filename, QGraphicsItem *parent): +QGraphicsPixmapItem(QPixmap(filename), parent) +{ +} + +void ImageItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + emit clicked(); +} + diff --git a/src/imageitem.h b/src/imageitem.h new file mode 100644 index 0000000..286d561 --- /dev/null +++ b/src/imageitem.h @@ -0,0 +1,41 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef IMAGEITEM_H +#define IMAGEITEM_H + +#include +#include +#include + +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 diff --git a/src/location.cpp b/src/location.cpp new file mode 100644 index 0000000..f22c7c8 --- /dev/null +++ b/src/location.cpp @@ -0,0 +1,190 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include "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; +} diff --git a/src/location.h b/src/location.h new file mode 100644 index 0000000..656be1c --- /dev/null +++ b/src/location.h @@ -0,0 +1,81 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef LOCATION_H +#define LOCATION_H + +#include +#include +#include + +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 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..cee1700 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,34 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include "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(); +} diff --git a/src/mainmenu.cpp b/src/mainmenu.cpp new file mode 100644 index 0000000..e9bb4f8 --- /dev/null +++ b/src/mainmenu.cpp @@ -0,0 +1,116 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include "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("jSpeed
(c) 2010 Jesse Hakanen
http://jspeed.garage.maemo.org")); + 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_++; +} diff --git a/src/mainmenu.h b/src/mainmenu.h new file mode 100644 index 0000000..44e8b0c --- /dev/null +++ b/src/mainmenu.h @@ -0,0 +1,59 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef MAINMENU_H +#define MAINMENU_H + +#include + +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 diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 0000000..e0280d3 --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,131 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "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); +} diff --git a/src/mainwindow.h b/src/mainwindow.h new file mode 100644 index 0000000..373fe2d --- /dev/null +++ b/src/mainwindow.h @@ -0,0 +1,56 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +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 diff --git a/src/mainwindowstack.cpp b/src/mainwindowstack.cpp new file mode 100644 index 0000000..ca9b501 --- /dev/null +++ b/src/mainwindowstack.cpp @@ -0,0 +1,75 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include "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_); +} diff --git a/src/mainwindowstack.h b/src/mainwindowstack.h new file mode 100644 index 0000000..9325044 --- /dev/null +++ b/src/mainwindowstack.h @@ -0,0 +1,51 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef MAINWINDOWSTACK_H +#define MAINWINDOWSTACK_H + +#include +#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 screens_; + int currentScreen_; +}; + +#endif diff --git a/src/odometer.cpp b/src/odometer.cpp new file mode 100644 index 0000000..bb28ec8 --- /dev/null +++ b/src/odometer.cpp @@ -0,0 +1,319 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include "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(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(trip_) * Location::getUnitMultiplier()) / (static_cast(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; +} diff --git a/src/odometer.h b/src/odometer.h new file mode 100644 index 0000000..93b91d8 --- /dev/null +++ b/src/odometer.h @@ -0,0 +1,82 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef ODOMETER_H +#define ODOMETER_H + +#include +#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 diff --git a/src/pointer.cpp b/src/pointer.cpp new file mode 100644 index 0000000..2431844 --- /dev/null +++ b/src/pointer.cpp @@ -0,0 +1,209 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include "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(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(zeroSpeed_); + } + else if(speed > fullSpeed_) + { + speed = static_cast(fullSpeed_); + } + + double multiplier = static_cast(speed - zeroSpeed_) / (fullSpeed_ - zeroSpeed_); + double angle = static_cast(zeroAngle_) + ((fullAngle_ - zeroAngle_) * multiplier); + + int rounded = static_cast(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(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; +} diff --git a/src/pointer.h b/src/pointer.h new file mode 100644 index 0000000..4ae1818 --- /dev/null +++ b/src/pointer.h @@ -0,0 +1,65 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef POINTER_H +#define POINTER_H + +#include +#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 diff --git a/src/reader.cpp b/src/reader.cpp new file mode 100644 index 0000000..0831361 --- /dev/null +++ b/src/reader.cpp @@ -0,0 +1,21 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include "reader.h" + +Reader::Reader(){} diff --git a/src/reader.h b/src/reader.h new file mode 100644 index 0000000..7b9b04b --- /dev/null +++ b/src/reader.h @@ -0,0 +1,36 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef 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 diff --git a/src/rectangle.cpp b/src/rectangle.cpp new file mode 100644 index 0000000..5448748 --- /dev/null +++ b/src/rectangle.cpp @@ -0,0 +1,113 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include "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(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() +{ +} diff --git a/src/rectangle.h b/src/rectangle.h new file mode 100644 index 0000000..72912a0 --- /dev/null +++ b/src/rectangle.h @@ -0,0 +1,47 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef 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 diff --git a/src/resources.qrc b/src/resources.qrc new file mode 100644 index 0000000..7b6a999 --- /dev/null +++ b/src/resources.qrc @@ -0,0 +1,11 @@ + + + resources/minimize.png + resources/close.png + resources/settings.png + resources/appicon.png + resources/themes/default/theme.xml + resources/themes/default/digital7.ttf + resources/themes/default/background.png + + diff --git a/src/resources/appicon.png b/src/resources/appicon.png new file mode 100644 index 0000000000000000000000000000000000000000..5c3d9f12d9e47dbf5feb4053846a3677e5979208 GIT binary patch literal 26930 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 JPDHLkV1fV^kt6^B literal 0 HcmV?d00001 diff --git a/src/resources/close.png b/src/resources/close.png new file mode 100644 index 0000000000000000000000000000000000000000..c7942ad36295fa03cd743c6369cc9eb486d90a24 GIT binary patch literal 3588 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 KMNUMnLSTX+BeD?y literal 0 HcmV?d00001 diff --git a/src/resources/minimize.png b/src/resources/minimize.png new file mode 100644 index 0000000000000000000000000000000000000000..d4c6bcdb4b258bfc2ad937ef87b4e909df161b46 GIT binary patch literal 3694 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 M07*qoM6N<$f?VGA#Q*>R literal 0 HcmV?d00001 diff --git a/src/resources/settings.png b/src/resources/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..39ae7ca30f8900c142b135e2229ef262c3693e29 GIT binary patch literal 4822 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 z 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 literal 0 HcmV?d00001 diff --git a/src/resources/themes/default/digital7.ttf b/src/resources/themes/default/digital7.ttf new file mode 100755 index 0000000000000000000000000000000000000000..e94f8e3b870df4f0e22585db2e8d6c7a2e402ed7 GIT binary patch literal 33992 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 Hej@)5)c5h& literal 0 HcmV?d00001 diff --git a/src/resources/themes/default/theme.xml b/src/resources/themes/default/theme.xml new file mode 100755 index 0000000..a05dafe --- /dev/null +++ b/src/resources/themes/default/theme.xml @@ -0,0 +1,58 @@ + + + + 0 + 0 + background.png + + + 000 + digital7.ttf + 320 + 100 + 75 + #17202b + right + 600 + + + {SPEED} + digital7.ttf + 320 + 100 + 75 + #fff + right + 600 + %.0f + + + + + 0 + 0 + background.png + + + 000 + digital7.ttf + 230 + 0 + 260 + #17202b + right + 450 + + + {SPEED} + digital7.ttf + 230 + 0 + 260 + #fff + right + 450 + %.0f + + + diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 0000000..12f7234 --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,43 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include "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(); +} diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 0000000..d1e0056 --- /dev/null +++ b/src/settings.h @@ -0,0 +1,38 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef SETTINGS_H +#define SETTINGS_H + +#include + +class Settings : public QSettings +{ +public: + static Settings& instance(); + static QString const& getDir(); + static void close(); + +private: + Settings(); + static QString initDir(); + static QString dir_; + +}; + +#endif diff --git a/src/textelement.cpp b/src/textelement.cpp new file mode 100644 index 0000000..92bf7fa --- /dev/null +++ b/src/textelement.cpp @@ -0,0 +1,211 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include "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(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("
"+data+"
"); +} + +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; +} diff --git a/src/textelement.h b/src/textelement.h new file mode 100644 index 0000000..02e34f8 --- /dev/null +++ b/src/textelement.h @@ -0,0 +1,51 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef 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 diff --git a/src/theme.cpp b/src/theme.cpp new file mode 100644 index 0000000..09baddf --- /dev/null +++ b/src/theme.cpp @@ -0,0 +1,293 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "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 theme.xml from theme file"; + return false; + } + + QDomDocument doc; + int line = 0; + int column = 0; + QString msg; + + if(!doc.setContent(xmlData, false, &msg, &line, &column)) + { + error_ = "Invalid xml file, " + msg + " (line "+line+", column "+column+")"; + return false; + } + + QDomNodeList orientations = doc.elementsByTagName("orientation"); + + if(orientations.isEmpty()) + { + error_ = "No tags found"; + return false; + } + + bool ok = true; + + for(int i = 0; i < orientations.size(); i++) + { + QDomNode data = orientations.at(i); + QString type = data.attributes().namedItem("name").toAttr().value(); + + if(type == "landscape") + { + if(landscape_) + { + error_ = "More than one specified"; + ok = false; + } + + landscape_ = new ThemeScreen(); + ok = ok && landscape_->load(data, reader_); + + } + else if(type == "portrait") + { + if(portrait_) + { + error_ = "More than one specified"; + ok = false; + } + + portrait_ = new ThemeScreen(); + ok = ok && portrait_->load(data, reader_); + } + else + { + error_ = "Invalid orientation: " + type; + ok = false; + } + } + + reader_->close(); + delete reader_; + reader_ = 0; + + if(!portrait_ && !landscape_) + { + error_ = "No valid orientation tags found"; + ok = false; + } + + if(ok) + { + if(landscape_) + { + landscapeId_ = addWidget(landscape_); + connectSignals(landscape_); + } + + if(portrait_) + { + portraitId_ = addWidget(portrait_); + connectSignals(portrait_); + } + } + 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())); +} + diff --git a/src/theme.h b/src/theme.h new file mode 100644 index 0000000..79682d5 --- /dev/null +++ b/src/theme.h @@ -0,0 +1,59 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef THEME_H +#define THEME_H + +#include "widgetscreen.h" + +class QString; +class Reader; +class ThemeScreen; + +class 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 diff --git a/src/themescreen.cpp b/src/themescreen.cpp new file mode 100644 index 0000000..d4dcaa0 --- /dev/null +++ b/src/themescreen.cpp @@ -0,0 +1,77 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include "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(); + } +} diff --git a/src/themescreen.h b/src/themescreen.h new file mode 100644 index 0000000..3e1da8b --- /dev/null +++ b/src/themescreen.h @@ -0,0 +1,43 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef 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 elements_; + QString error_; +}; + +#endif diff --git a/src/themeselector.cpp b/src/themeselector.cpp new file mode 100644 index 0000000..7f22a09 --- /dev/null +++ b/src/themeselector.cpp @@ -0,0 +1,192 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "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); +} diff --git a/src/themeselector.h b/src/themeselector.h new file mode 100644 index 0000000..4543657 --- /dev/null +++ b/src/themeselector.h @@ -0,0 +1,53 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef THEMESELECTOR_H +#define THEMESELECTOR_H + +#include + +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 diff --git a/src/unitselector.cpp b/src/unitselector.cpp new file mode 100644 index 0000000..90cadfa --- /dev/null +++ b/src/unitselector.cpp @@ -0,0 +1,72 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include +#include "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(); +} diff --git a/src/unitselector.h b/src/unitselector.h new file mode 100644 index 0000000..793682b --- /dev/null +++ b/src/unitselector.h @@ -0,0 +1,45 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef UNITSELECTOR_H +#define UNITSELECTOR_H + +#include + +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 diff --git a/src/widgetscreen.cpp b/src/widgetscreen.cpp new file mode 100644 index 0000000..fd00a06 --- /dev/null +++ b/src/widgetscreen.cpp @@ -0,0 +1,21 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include "widgetscreen.h" + +WidgetScreen::WidgetScreen(QWidget* parent): QStackedWidget(parent), AbstractScreen(){} diff --git a/src/widgetscreen.h b/src/widgetscreen.h new file mode 100644 index 0000000..83c83f5 --- /dev/null +++ b/src/widgetscreen.h @@ -0,0 +1,41 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef WIDGETSCREEN_H +#define WIDGETSCREEN_H + +#include +#include +#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 diff --git a/src/zipreader.cpp b/src/zipreader.cpp new file mode 100644 index 0000000..7cafef4 --- /dev/null +++ b/src/zipreader.cpp @@ -0,0 +1,95 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#include +#include +#include +#include "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_; +} diff --git a/src/zipreader.h b/src/zipreader.h new file mode 100644 index 0000000..c510b7f --- /dev/null +++ b/src/zipreader.h @@ -0,0 +1,44 @@ +/* + * This file is part of jSpeed. + * + * jSpeed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * jSpeed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with jSpeed. If not, see . + * + */ + +#ifndef 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 diff --git a/welcome b/welcome deleted file mode 100644 index e69de29..0000000 -- 1.7.9.5