aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING19
-rw-r--r--README2
-rw-r--r--harbour-unitmaster.desktop6
-rw-r--r--harbour-unitmaster.pngbin0 -> 4971 bytes
-rw-r--r--harbour-unitmaster.xcfbin0 -> 19620 bytes
-rw-r--r--qml/harbour-unitmaster.qml40
-rw-r--r--qml/pages/LengthModel.qml92
-rw-r--r--qml/pages/MassModel.qml50
-rw-r--r--qml/pages/QuantityModel.qml33
-rw-r--r--qml/pages/QuantityPage.qml124
-rw-r--r--qml/pages/SelectQuantityPage.qml45
-rw-r--r--qml/pages/TemperatureModel.qml43
-rw-r--r--qml/pages/helpers.js5
-rw-r--r--rpm/harbour-unitmaster.spec76
-rw-r--r--rpm/harbour-unitmaster.yaml32
-rw-r--r--src/unitmaster.cpp51
16 files changed, 618 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..5c0e6c0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Oskari Timperi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/README b/README
new file mode 100644
index 0000000..61b73b0
--- /dev/null
+++ b/README
@@ -0,0 +1,2 @@
+The application icon is derived from the Meanicons Icon Set
+(http://www.meanicons.com/).
diff --git a/harbour-unitmaster.desktop b/harbour-unitmaster.desktop
new file mode 100644
index 0000000..27dd6d4
--- /dev/null
+++ b/harbour-unitmaster.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Application
+X-Nemo-Application-Type=silica-qt5
+Name=Unit Master
+Icon=harbour-unitmaster
+Exec=harbour-unitmaster
diff --git a/harbour-unitmaster.png b/harbour-unitmaster.png
new file mode 100644
index 0000000..e54207a
--- /dev/null
+++ b/harbour-unitmaster.png
Binary files differ
diff --git a/harbour-unitmaster.xcf b/harbour-unitmaster.xcf
new file mode 100644
index 0000000..92ebedf
--- /dev/null
+++ b/harbour-unitmaster.xcf
Binary files differ
diff --git a/qml/harbour-unitmaster.qml b/qml/harbour-unitmaster.qml
new file mode 100644
index 0000000..7bef9ad
--- /dev/null
+++ b/qml/harbour-unitmaster.qml
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2013 Jolla Ltd.
+ Contact: Thomas Perl <thomas.perl@jollamobile.com>
+ All rights reserved.
+
+ You may use this file under the terms of BSD license as follows:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Jolla Ltd nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import "pages"
+
+ApplicationWindow
+{
+ initialPage: SelectQuantityPage { }
+}
+
+
diff --git a/qml/pages/LengthModel.qml b/qml/pages/LengthModel.qml
new file mode 100644
index 0000000..a374be3
--- /dev/null
+++ b/qml/pages/LengthModel.qml
@@ -0,0 +1,92 @@
+import QtQuick 2.0
+
+ListModel {
+ function from (title, value) {
+ var functions = {
+ "meter": function () { return value; },
+ "kilometer": function () { return value*1000.0; },
+ "decimeter": function () { return value/10.0; },
+ "centimeter": function () { return value/100.0; },
+ "millimeter": function () { return value/1000.0; },
+ "thou": function () { return value*(25.4e-6); },
+ "inch": function () { return value*0.0254; },
+ "foot": function () { return value*0.3048; },
+ "yard": function () { return value*0.9144; },
+ "mile": function () { return value*1609.344; },
+ "nautical mile": function () { return value*1852.0; }
+ }
+ return functions[title]();
+ }
+
+ function to (title, value) {
+ var functions = {
+ "meter": function () { return value; },
+ "kilometer": function () { return value/1000.0; },
+ "decimeter": function () { return value*10.0; },
+ "centimeter": function () { return value*100.0; },
+ "millimeter": function () { return value*1000.0; },
+ "thou": function () { return value/(25.4e-6); },
+ "inch": function () { return value/0.0254; },
+ "foot": function () { return value/0.3048; },
+ "yard": function () { return value/0.9144; },
+ "mile": function () { return value/1609.344; },
+ "nautical mile": function () { return value/1852.0; }
+ };
+ return functions[title]();
+ }
+
+ ListElement {
+ title: "meter"
+ abbr: "m"
+ }
+
+ ListElement {
+ title: "kilometer"
+ abbr: "km"
+ }
+
+ ListElement {
+ title: "decimeter"
+ abbr: "dm"
+ }
+
+ ListElement {
+ title: "centimeter"
+ abbr: "cm"
+ }
+
+ ListElement {
+ title: "millimeter"
+ abbr: "mm"
+ }
+
+ ListElement {
+ title: "thou"
+ abbr: "thou"
+ }
+
+ ListElement {
+ title: "inch"
+ abbr: "inch"
+ }
+
+ ListElement {
+ title: "foot"
+ abbr: "ft"
+ }
+
+ ListElement {
+ title: "yard"
+ abbr: "yd"
+ }
+
+ ListElement {
+ title: "mile"
+ abbr: ""
+ }
+
+ ListElement {
+ title: "nautical mile"
+ abbr: ""
+ }
+}
diff --git a/qml/pages/MassModel.qml b/qml/pages/MassModel.qml
new file mode 100644
index 0000000..cadcdf0
--- /dev/null
+++ b/qml/pages/MassModel.qml
@@ -0,0 +1,50 @@
+import QtQuick 2.0
+
+ListModel {
+ function from(title, value) {
+ var functions = {
+ "kilogram": function () { return value; },
+ "gram": function () { return value/1000.0; },
+ "tonne": function () { return value*1000.0; },
+ "pound": function () { return value*0.45359237; },
+ "ounce": function () { return value*0.028349523125; }
+ };
+ return functions[title]();
+ }
+
+ function to(title, value) {
+ var functions = {
+ "kilogram": function () { return value; },
+ "gram": function () { return value*1000.0; },
+ "tonne": function () { return value/1000.0; },
+ "pound": function () { return value/0.45359237; },
+ "ounce": function () { return value/0.028349523125; }
+ };
+ return functions[title]();
+ }
+
+ ListElement {
+ title: "kilogram"
+ abbr: "kg"
+ }
+
+ ListElement {
+ title: "gram"
+ abbr: "g"
+ }
+
+ ListElement {
+ title: "tonne"
+ abbr: "t"
+ }
+
+ ListElement {
+ title: "pound"
+ abbr: "lb"
+ }
+
+ ListElement {
+ title: "ounce"
+ abbr: "oz"
+ }
+}
diff --git a/qml/pages/QuantityModel.qml b/qml/pages/QuantityModel.qml
new file mode 100644
index 0000000..de0cf14
--- /dev/null
+++ b/qml/pages/QuantityModel.qml
@@ -0,0 +1,33 @@
+import QtQuick 2.0
+
+ListModel {
+ ListElement {
+ title: "mass"
+ model: "MassModel.qml"
+ }
+
+ ListElement {
+ title: "length"
+ model: "LengthModel.qml"
+ }
+
+ ListElement {
+ title: "temperature"
+ model: "TemperatureModel.qml"
+ }
+
+// ListElement {
+// title: "time"
+// model: "TimeModel.qml"
+// }
+
+// ListElement {
+// title: "current"
+// model: "CurrentModel.qml"
+// }
+
+// ListElement {
+// title: "area"
+// model: "AreaModel.qml"
+// }
+}
diff --git a/qml/pages/QuantityPage.qml b/qml/pages/QuantityPage.qml
new file mode 100644
index 0000000..fd7e5ad
--- /dev/null
+++ b/qml/pages/QuantityPage.qml
@@ -0,0 +1,124 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import "helpers.js" as Helpers
+
+Page {
+ id: page
+
+ property bool first: false
+ property string fromUnit: ""
+ property string modelFilename
+ property string quantityName
+
+ function formatText(value, unit) {
+ return value.toPrecision(5) + " " + pluralize(unit, value);
+ }
+
+ function updateResult() {
+ var f = parseFloat(fromField.text);
+
+ if (fromField.text.length === 0) {
+ f = 0.0;
+ }
+
+ if (fromCombo.value.length === 0 || toCombo.value.length === 0)
+ return;
+
+ var model = modelLoader.item;
+
+ var result = model.from(fromCombo.value, f);
+ result = model.to(toCombo.value, result);
+
+ resultLabel.text = formatText(result, toCombo.value);
+ }
+
+ function pluralize(s, n) {
+ if (n !== 1) {
+ if (s === "inch") {
+ return "inches";
+ } else if (s === "foot") {
+ return "feet";
+ } else if (s === "celcius") {
+ return s;
+ }
+ return s + "s";
+ }
+
+ return s;
+ }
+
+ Component.onCompleted: {
+ modelLoader.setSource(modelFilename);
+ }
+
+ Loader {
+ id: modelLoader
+ onLoaded: {
+ fromRepeater.model = modelLoader.item;
+ toRepeater.model = modelLoader.item;
+ }
+ }
+
+ Column {
+ id: column
+ spacing: Theme.paddingLarge
+ anchors.fill: parent
+
+ PageHeader {
+ title: Helpers.capitalize(page.quantityName)
+ }
+
+ ComboBox {
+ id: fromCombo
+ width: parent.width
+ label: "From"
+ menu: ContextMenu {
+ Repeater {
+ id: fromRepeater
+ delegate: MenuItem {
+ text: title
+ }
+ }
+ }
+ onValueChanged: updateResult()
+ }
+
+ TextField {
+ id: fromField
+ width: parent.width
+ placeholderText: "enter " + pluralize(fromCombo.value, 0)
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ EnterKey.onClicked: {
+ parent.focus = true;
+ updateResult();
+ }
+ }
+
+ ComboBox {
+ id: toCombo
+ width: parent.width
+ label: "To"
+ menu: ContextMenu {
+ Repeater {
+ id: toRepeater
+ delegate: MenuItem {
+ text: title
+ }
+ }
+ }
+ onValueChanged: updateResult()
+ }
+
+ SectionHeader {
+ text: "Result"
+ }
+
+ Label {
+ id: resultLabel
+ height: Theme.itemSizeSmall
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+}
+
+
diff --git a/qml/pages/SelectQuantityPage.qml b/qml/pages/SelectQuantityPage.qml
new file mode 100644
index 0000000..b39f08a
--- /dev/null
+++ b/qml/pages/SelectQuantityPage.qml
@@ -0,0 +1,45 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import "helpers.js" as H
+
+Page {
+ id: page
+
+ QuantityModel {
+ id: quantityModel
+ }
+
+ SilicaListView {
+ anchors.fill: parent
+ model: quantityModel
+ spacing: Theme.paddingLarge
+ delegate: BackgroundItem {
+ width: ListView.view.width
+ Label {
+ x: Theme.paddingLarge
+ text: H.capitalize(title)
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ onClicked: {
+ var props = {
+ "first": true,
+ "modelFilename": model,
+ "quantityName": title
+ };
+ pageStack.push(Qt.resolvedUrl("QuantityPage.qml"), props);
+ }
+ }
+ header: PageHeader {
+ title: "Quantity"
+ }
+ VerticalScrollDecorator {}
+
+// PullDownMenu {
+// MenuItem {
+// text: "About"
+// }
+// }
+ }
+}
+
+
diff --git a/qml/pages/TemperatureModel.qml b/qml/pages/TemperatureModel.qml
new file mode 100644
index 0000000..74fc7d2
--- /dev/null
+++ b/qml/pages/TemperatureModel.qml
@@ -0,0 +1,43 @@
+import QtQuick 2.0
+
+ListModel {
+ function from(title, value) {
+ var functions = {
+ "kelvin": function () { return value; },
+ "celcius": function () { return value + 273.15; },
+ "fahrenheit": function () { return (value + 459.67) * 5.0 / 9.0; },
+ "rankine": function () { return value * 5.0 / 9.0; }
+ };
+ return functions[title]();
+ }
+
+ function to(title, value) {
+ var functions = {
+ "kelvin": function () { return value; },
+ "celcius": function () { return value - 273.15; },
+ "fahrenheit": function () { return value * 9.0 / 5.0 - 459.67; },
+ "rankine": function () { return value * 9.0 / 5.0; }
+ };
+ return functions[title]();
+ }
+
+ ListElement {
+ title: "kelvin"
+ abbr: "K"
+ }
+
+ ListElement {
+ title: "celcius"
+ abbr: "°C"
+ }
+
+ ListElement {
+ title: "fahrenheit"
+ abbr: "F"
+ }
+
+ ListElement {
+ title: "rankine"
+ abbr: "°R"
+ }
+}
diff --git a/qml/pages/helpers.js b/qml/pages/helpers.js
new file mode 100644
index 0000000..dd7ad7c
--- /dev/null
+++ b/qml/pages/helpers.js
@@ -0,0 +1,5 @@
+.pragma library
+
+function capitalize(str) {
+ return str.substr(0, 1).toUpperCase() + str.substr(1);
+}
diff --git a/rpm/harbour-unitmaster.spec b/rpm/harbour-unitmaster.spec
new file mode 100644
index 0000000..73e58f0
--- /dev/null
+++ b/rpm/harbour-unitmaster.spec
@@ -0,0 +1,76 @@
+#
+# Do NOT Edit the Auto-generated Part!
+# Generated by: spectacle version 0.27
+#
+
+Name: harbour-unitmaster
+
+# >> macros
+# << macros
+
+%{!?qtc_qmake:%define qtc_qmake %qmake}
+%{!?qtc_qmake5:%define qtc_qmake5 %qmake5}
+%{!?qtc_make:%define qtc_make make}
+%{?qtc_builddir:%define _builddir %qtc_builddir}
+Summary: Unit Master
+Version: 0.1
+Release: 1
+Group: Qt/Qt
+License: COPYING
+Source0: %{name}-%{version}.tar.bz2
+Source100: harbour-unitmaster.yaml
+Requires: sailfishsilica-qt5
+BuildRequires: pkgconfig(Qt5Core)
+BuildRequires: pkgconfig(Qt5Qml)
+BuildRequires: pkgconfig(Qt5Quick)
+BuildRequires: pkgconfig(sailfishapp)
+BuildRequires: desktop-file-utils
+
+%description
+Unit conversion utility
+
+%prep
+%setup -q -n %{name}-%{version}
+
+# >> setup
+# << setup
+
+%build
+# >> build pre
+# << build pre
+
+%qtc_qmake5
+
+%qtc_make %{?_smp_mflags}
+
+# >> build post
+# << build post
+
+%install
+rm -rf %{buildroot}
+# >> install pre
+# << install pre
+%qmake5_install
+
+# >> install post
+# << install post
+
+desktop-file-install --delete-original \
+ --dir %{buildroot}%{_datadir}/applications \
+ %{buildroot}%{_datadir}/applications/*.desktop
+
+%files
+%defattr(-,root,root,-)
+%{_datadir}/applications
+%{_datadir}/%{name}
+%{_datadir}/icons/hicolor/86x86/apps/%{name}.png
+%{_datadir}/applications/%{name}.desktop
+%{_datadir}/%{name}/qml
+%{_bindir}
+%{_datadir}/icons/hicolor/86x86/apps
+/usr/bin
+/usr/share/harbour-unitmaster
+/usr/share/applications
+/usr/share/icons/hicolor/86x86/apps
+# >> files
+# << files
diff --git a/rpm/harbour-unitmaster.yaml b/rpm/harbour-unitmaster.yaml
new file mode 100644
index 0000000..8fd63e7
--- /dev/null
+++ b/rpm/harbour-unitmaster.yaml
@@ -0,0 +1,32 @@
+Name: harbour-unitmaster
+Summary: Unit Master
+Version: 0.1
+Release: 1
+Group: Qt/Qt
+License: COPYING
+Sources:
+- '%{name}-%{version}.tar.bz2'
+Description: |-
+ Unit conversion utility
+Configure: none
+Builder: qtc5
+PkgConfigBR:
+- Qt5Core
+- Qt5Qml
+- Qt5Quick
+- sailfishapp
+Requires:
+- sailfishsilica-qt5
+Files:
+- '%{_datadir}/applications'
+- '%{_datadir}/%{name}'
+- '%{_datadir}/icons/hicolor/86x86/apps/%{name}.png'
+- '%{_datadir}/applications/%{name}.desktop'
+- '%{_datadir}/%{name}/qml'
+- '%{_bindir}'
+- '%{_datadir}/icons/hicolor/86x86/apps'
+- /usr/bin
+- /usr/share/harbour-unitmaster
+- /usr/share/applications
+- /usr/share/icons/hicolor/86x86/apps
+PkgBR: []
diff --git a/src/unitmaster.cpp b/src/unitmaster.cpp
new file mode 100644
index 0000000..dfbb6d6
--- /dev/null
+++ b/src/unitmaster.cpp
@@ -0,0 +1,51 @@
+/*
+ Copyright (C) 2013 Jolla Ltd.
+ Contact: Thomas Perl <thomas.perl@jollamobile.com>
+ All rights reserved.
+
+ You may use this file under the terms of BSD license as follows:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Jolla Ltd nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef QT_QML_DEBUG
+#include <QtQuick>
+#endif
+
+#include <sailfishapp.h>
+
+
+int main(int argc, char *argv[])
+{
+ // SailfishApp::main() will display "qml/template.qml", if you need more
+ // control over initialization, you can use:
+ //
+ // - SailfishApp::application(int, char *[]) to get the QGuiApplication *
+ // - SailfishApp::createView() to get a new QQuickView * instance
+ // - SailfishApp::pathTo(QString) to get a QUrl to a resource file
+ //
+ // To display the view, call "show()" (will show fullscreen on device).
+
+ return SailfishApp::main(argc, argv);
+}
+