Initial comit

This commit is contained in:
Niels 2025-05-31 09:58:34 +02:00
commit e44717c1f3
40 changed files with 2221 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Use target-compatible line endings as the safe default for cross compilation.
* text=auto eol=lf

11
harbour-anchor.desktop Normal file
View File

@ -0,0 +1,11 @@
[Desktop Entry]
Type=Application
X-Nemo-Application-Type=silica-qt5
Name=harbour-anchor
Icon=harbour-anchor
Exec=harbour-anchor
[X-Sailjail]
Permissions=Location
OrganizationName=org.nesnomis
ApplicationName=Anchor

39
harbour-anchor.pro Normal file
View File

@ -0,0 +1,39 @@
# NOTICE:
#
# Application name defined in TARGET has a corresponding QML filename.
# If name defined in TARGET is changed, the following needs to be done
# to match new name:
# - corresponding QML filename must be changed
# - desktop icon filename must be changed
# - desktop filename must be changed
# - icon definition filename in desktop file must be changed
# - translation filenames have to be changed
# The name of your application
TARGET = harbour-anchor
CONFIG += sailfishapp
SOURCES += src/harbour-anchor.cpp
DISTFILES += qml/harbour-anchor.qml \
qml/cover/CoverPage.qml \
qml/pages/FirstPage.qml \
qml/pages/SecondPage.qml \
rpm/harbour-anchor.changes.in \
rpm/harbour-anchor.changes.run.in \
rpm/harbour-anchor.spec \
translations/*.ts \
harbour-anchor.desktop
SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
# to disable building translations every time, comment out the
# following CONFIG line
CONFIG += sailfishapp_i18n
# German translation is enabled as an example. If you aren't
# planning to localize your app, remember to comment out the
# following TRANSLATIONS line. And also do not forget to
# modify the localized app name in the the .desktop file.
TRANSLATIONS += translations/harbour-anchor-de.ts

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -0,0 +1,42 @@
import QtQuick 2.0
import QtSensors 5.0
Item {
property int azimuth: 0
property real calibration: 0.0
property bool running: false
property bool enabled: true//settings.getSettings("compassSetting",false)
Timer {
id: waittimer
running: false
repeat: false
interval: 750
onTriggered: {
if (!aCompass.running) {
aCompass.enabled = false
aMagnetometer.enabled = true
}
}
}
Component.onCompleted: waittimer.running = true//if (!running) {enabled = false;aMagnetometer.enabled = true}
onEnabledChanged: {
console.log("*** COMPASS: "+enabled)
if (!enabled) running = false
}
Compass {
active: enabled && Qt.application.active
dataRate: 5
onReadingChanged: {
running = true
if (enabled) {
azimuth = reading.azimuth
calibration = reading.calibrationLevel
}
}
}
}

View File

@ -0,0 +1,71 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Item {
id: compassCapsule
width: parent.height
height: width
property real direction: normalize360(- __ringRotation) // In degrees, 0-359
property int azimuth: 0 // In degrees, set (bind) from outside, the compass needle follows this
property int anchor: 0
property bool changingDirection: false // Is the direction (ring rotation) changing right now?
property alias anchorArrow: anchorArrow.opacity
property real __previousAngle: 0
property real __ringRotation: 0
function normalize360(angle) {
var semiNormalized = angle % 360
return semiNormalized >= 0 ? semiNormalized : semiNormalized + 360
}
Image {
id: basePicture
source: showCompasNumbers ? "../images/compass_ring_base_black.png" : "../images/compass_ring_base_white.png"
opacity: showCompasNumbers ? 0.7 : 0.5
//visible: !aGps.enabled
width: parent.width
height: parent.height
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
}
Image {
id: numberRing
source: "../images/compass_ring_360_day.png"
// opacity:
visible: showCompasNumbers
width: parent.width
height: parent.height
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
}
Image {
source: "../images/compass_needle_day_N_red.png"
anchors.centerIn: parent
width: parent.width*0.80
height: parent.height*0.80
fillMode: Image.PreserveAspectFit
visible: true
opacity: 0.7
rotation: - compassCapsule.azimuth
Behavior on rotation { RotationAnimation { duration: 250; direction: RotationAnimation.Shortest } }
Behavior on opacity {
FadeAnimator {}
}
}
Image {
id: anchorArrow
source: "../images/compass_needle_day_N_green.png"
anchors.centerIn: parent
width: parent.width*0.80
height: parent.height*0.80
fillMode: Image.PreserveAspectFit
opacity: 0.8
rotation: - compassCapsule.azimuth + compassCapsule.anchor //compassCapsule.azimuth > compassCapsule.anchor ? compassCapsule.anchor - compassCapsule.azimuth : compassCapsule.azimuth - compassCapsule.anchor
Behavior on rotation { RotationAnimation { duration: 200; direction: RotationAnimation.Shortest } }
Behavior on opacity {
FadeAnimator {duration: 200}
}
}
}

33
qml/components/Dot.qml Normal file
View File

@ -0,0 +1,33 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
GlassItem {
property int active: 0 // 0 = empty; 1 = active; 2 = inactive
property bool ghost: false
property bool glowing: false
id: dot
width: Theme.paddingLarge * 2
height: width
radius: dots == 1 ? 0.6 : 0 // 0 ? 0.2 : 0
falloffRadius: dots == 1 ? 0.65 : 3 // 0 ? 0.25 : 2
color: Theme.highlightColor
opacity: 0.1
Timer {
property bool up
id: glowingTimer
running: glowing
repeat: true
interval: 30
onTriggered: {
if (opacity == 1){
up = false
} else if (opacity < 0.5) {
up = true
}
if (up)
opacity += 0.05
else
opacity -= 0.05
}
}
}

99
qml/components/Gps.qml Normal file
View File

@ -0,0 +1,99 @@
import QtQuick 2.0
import QtPositioning 5.2
//import QtLocation 5.0
Item {
property real currentLatitude: 0.0
property real currentLongitude: 0.0
property real currentAltitude: 0.0
property int distance: 0
property int direction: 0
property string positionBearing: ""
property bool active: inact == 0 ? true : false
property int inact: 2
property bool enabled: false
onEnabledChanged: {
if (!enabled) inact = 2; else waittimer.running = true
}
Timer {
id: waittimer
running: inact == 0 ? false : true
repeat: true
interval: 3000
onTriggered: {
inact = inact + 1
}
}
PositionSource {
id: src
active: enabled ? true : false
preferredPositioningMethods: PositionSource.AllPositioningMethods
onPositionChanged: {
var coord = src.position.coordinate;
currentLongitude = coord.longitude
currentLatitude = coord.latitude
currentAltitude = coord.altitude
if (anchorLatitude == 500 && anchorLongitude == 500) {
anchorLatitude = currentLatitude
anchorLongitude = currentLongitude
}
distance = getdistance(currentLatitude,currentLongitude,anchorLatitude,anchorLongitude)
direction = positionbearing(currentLatitude,currentLongitude,anchorLatitude,anchorLongitude)
//console.log(anchorLatitude + " - " + anchorLongitude)
if (inact > 2) {
waittimer.running = false
inact = 0
}
}
}
function radians(n) {
return n * (Math.PI / 180);
}
function degrees(n) {
return n * (180 / Math.PI);
}
function getdistance(lat1,lon1,lat2,lon2){
var R = 6371; // km
var dLat = radians(lat2-lat1) //(lat2-lat1) * Math.PI / 180;
var dLon = radians(lon2-lon1) //(lon2-lon1) * Math.PI / 180;
lat1 = radians(lat1) //lat1 * Math.PI / 180;
lat2 = radians(lat2) //lat2 * Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = (R * c) * 1000;
return d
}
function positionbearing(lat1,lon1,lat2,lon2){
var startLat = radians(lat1);
var startLong = radians(lon1);
var endLat = radians(lat2);
var endLong = radians(lon2);
var dLong = endLong - startLong;
var dPhi = Math.log(Math.tan(endLat/2.0+Math.PI/4.0)/Math.tan(startLat/2.0+Math.PI/4.0));
if (Math.abs(dLong) > Math.PI){
if (dLong > 0.0)
dLong = -(2.0 * Math.PI - dLong);
else
dLong = (2.0 * Math.PI + dLong);
}
var brng = degrees(Math.atan2(dLong,dPhi))
return brng
}
}

View File

@ -0,0 +1,92 @@
import QtQuick 2.0
import QtSensors 5.0
Item {
property bool running: false
property bool enabled: false//settings.getSettings("magnetometerSetting",true)
property int azimuth: 0
property real calibration: 0.0
property variant data: [0,0,0,0,0]
onEnabledChanged: {
console.log("*** MAGNETOMETER: "+enabled)
if (!enabled) running = false
}
Accelerometer
{
id: accel
dataRate: 6
active: enabled && Qt.application.active
}
Magnetometer {
id: mag
dataRate: 6
returnGeoValues: true // not sure
active: enabled && Qt.application.active
onReadingChanged: {
running = true
var accelVec = [accel.reading.x, accel.reading.y, accel.reading.z]
var magEast = crossProduct([mag.reading.x, mag.reading.y, mag.reading.z], accelVec)
var magNorth = crossProduct(accelVec, magEast)
magEast = normVec(magEast)
magNorth = normVec(magNorth)
var deviceHeading = [0., 1., -1.] //This is for portrait orientation on android
var dotWithEast = dotProduct(deviceHeading, magEast)
var dotWithNorth = dotProduct(deviceHeading, magNorth)
var bearingRad = Math.atan2(dotWithEast, dotWithNorth)
var t = ((bearingRad * 180 / Math.PI) - 360) %360
var bearingDeg = 360 - Math.abs(t)
calibration = mag.reading.calibrationLevel
azimuth = normalize360(bearingDeg)
}
function normalize360(angle) {
var semiNormalized = angle % 360
return semiNormalized >= 0 ? semiNormalized : semiNormalized + 360
}
function normalizeAngle(angle)
{
var newAngle = angle;
if (newAngle <= -180) newAngle = newAngle + 360;
if (newAngle > 180) newAngle = newAngle - 360;
return newAngle;
}
function crossProduct(a, b) {
if (a.length != 3 || b.length != 3) {
return;
}
return [a[1]*b[2] - a[2]*b[1],
a[2]*b[0] - a[0]*b[2],
a[0]*b[1] - a[1]*b[0]];
}
function normVec(a) {
var compSq = 0.
for(var i=0;i<a.length;i++)
compSq += Math.pow(a[i], 2)
var mag = Math.pow(compSq, 0.5)
if(mag == 0.) return
var out = []
for(var i=0;i<a.length;i++)
out.push(a[i]/mag)
return out
}
function dotProduct(a, b)
{
if (a.length != b.length) return;
var comp = 0.
for(var i=0;i<a.length;i++)
comp += a[i] * b[i]
return comp
}
}
}

View File

@ -0,0 +1,41 @@
import QtQuick 2.0
import Nemo.DBus 2.0
Item {
property bool enabled: keepScreenOn && Qt.application.active ? true : false
function request(){
var method = "req_display" + (enabled ? "" : "_cancel") + "_blanking_pause";
console.log('screen blank:', enabled, method);
dbif.call(method, [])
}
onEnabledChanged: {
request();
}
DBusInterface {
id: dbif
service: "com.nokia.mce"
path: "/com/nokia/mce/request"
iface: "com.nokia.mce.request"
bus: DBusInterface.SystemBus
}
Timer { //request seems to time out after a while:
running: parent.enabled
interval: 15000 //minimum setting for blank display is 15s
repeat: true
onTriggered: {
if(parent.enabled) {
parent.request()
}
}
}
Component.onDestruction: {
if(enabled){
enabled=false
}
}
}

View File

@ -0,0 +1,51 @@
import QtQuick 2.0
import QtQuick.LocalStorage 2.0
import "../js/settings.js" as Settings
Item {
function delAnchor(name) {
Settings.delAnchor(name)
}
function getAnchors() {
Settings.getAnchors(dbAnchors)
}
function setAnchor(name, description, icon, latitude, longitude) {
Settings.setAnchor(name, description, icon, latitude, longitude)
}
function setSettings(slati,slongi,icon,name,description) {
Settings.setValue("anchorLatitude",slati)
Settings.setValue("anchorLongitude",slongi)
Settings.setValue("anchorIcon",icon)
Settings.setValue("anchorName",name)
Settings.setValue("anchorDescription",description)
}
function getQanchor() {
anchorIcon = Settings.getValue("anchorIcon")
anchorName = Settings.getValue("anchorName")
anchorDescription = Settings.getValue("anchorDescription")
anchorLatitude = Settings.getValue("anchorLatitude")
anchorLongitude = Settings.getValue("anchorLongitude")
}
function getSettings(setting,def) {
return Settings.getValue(setting,def)
}
function setSetting(setting,value) {
Settings.setValue(setting,value)
}
function setSettingSetting(compass,magnet,radius,numbers,screenon) {
// Settings.setValue("compassSetting",compass)
// Settings.setValue("magnetometerSetting",magnet)
Settings.setValue("keepScreenOn",screenon)
Settings.setValue("anchorRadius",radius)
Settings.setValue("numbers",numbers)
}
}

42
qml/cover/CoverPage.qml Normal file
View File

@ -0,0 +1,42 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
CoverBackground {
onStatusChanged: {
// status !== 2 ? inact = true : inact = false
// console.log(inact)
}
CoverPlaceholder {
Label {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: Theme.paddingLarge
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeExtraLarge//!aGps.running ? Theme.fontSizeMedium : Theme.fontSizeHuge
text: "Anchor"//aGps.active ? aGps.distance > 10 ? aGps.distance + " m" : "HERE" : "ANCHOR"//compass.running ? compass.distance>10 ? compass.distance + " m" : "HERE" : "CONNECTING"//compass.running ? compass.distance + " m" : "CONNECTING"
}
Image {
//id:iBtn
// anchors.verticalCenter: parent.verticalCenter
width: parent.width * 0.85
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
// anchors.top: column.bottom
// anchors.bottom: parent.bottom
//height: parent.height * 0.8
//width: parent.width * 0.8
opacity: 0.7
fillMode: Image.PreserveAspectFit
source: "../images/harbour-anchor.png"//anchorIcon !== "0" ? anchorIcon : "image://theme/icon-m-whereami" //anchorIcon !== "0" ? anchorIcon + "?" + Theme.highlightColor : "image://theme/icon-m-whereami?" + Theme.highlightColor
}
Label {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.paddingLarge
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeExtraLarge//!aGps.running ? Theme.fontSizeMedium : Theme.fontSizeHuge
text: "v."+Qt.application.version//aGps.active ? aGps.distance > 10 ? aGps.distance + " m" : "HERE" : "ANCHOR"//compass.running ? compass.distance>10 ? compass.distance + " m" : "HERE" : "CONNECTING"//compass.running ? compass.distance + " m" : "CONNECTING"
}
}
}

38
qml/harbour-anchor.qml Normal file
View File

@ -0,0 +1,38 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
import "pages"
import "components"
ApplicationWindow
{
property string anchorIcon: settings.getSettings("anchorIcon")
property string anchorName
property string anchorDescription
property real anchorLatitude: settings.getSettings("anchorLatitude",500)
property real anchorLongitude: settings.getSettings("anchorLongitude",500)
property int anchorRadius: settings.getSettings("anchorRadius",10)
property int showCompasNumbers: settings.getSettings("numbers",0)
property int calibrateDist: 0
property variant dbModel: dbAnchors
property int azimuth: aCompass.enabled ? 360 - aCompass.azimuth : 360 - aMagnetometer.azimuth
property bool inact: false
property bool keepScreenOn: settings.getSettings("keepScreenOn",0) == 1 ? true : false
//onKeepScreenOnChanged: console.log(" ---- **** KEEPSCREENALIVE: "+keepScreenOn)
ListModel{id: dbAnchors}
Settings {id: settings}
Gps {id: aGps}
Compass {id: aCompass}
Magnetometer {id: aMagnetometer}
ScreenBlank {id: screenBlank}
Component.onCompleted: {
settings.getAnchors(dbAnchors)
}
initialPage: Component { AnchorPage { } }
cover: Qt.resolvedUrl("cover/CoverPage.qml")
allowedOrientations: defaultAllowedOrientations
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
qml/images/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

30
qml/js/calc.js Normal file
View File

@ -0,0 +1,30 @@
var array = [0,0,0,0,0]
var lastSin
var lastCos
var smoothingFactor = 0.9
function smoothout(azi) {
//if (last < azi - 100 || last > azi + 100) array = [azi,azi,azi,azi,azi];
//var tem = data
//Math.atan2(Math.sin(azi),cos(azi)) = azi
lastSin = smoothingFactor * lastSin + (1-smoothingFactor) * Math.sin(azi)
lastCos = smoothingFactor * lastCos + (1-smoothingFactor) * Math.cos(azi)
var azim = Math.atan2(lastSin, lastCos)
console.log(Math.sin(azi)+ " - "+Math.cos(azi))
array.shift()
array.push(azim)
var total = 0,i;
for (i = 0; i < array.length; i += 1) {
total += array[i]
//if (array[i] > 0) total += array[i]; else total -= array[i];
}
//data = tem
// console.log("******** "+ total / array.length+" ---- "+array)
// last = azi
return total / array.length;
}

134
qml/js/settings.js Normal file
View File

@ -0,0 +1,134 @@
var db = undefined;
function settings_db_open() {
if (db == undefined)
db = LocalStorage.openDatabaseSync("harbour-anchor", "1.0", "StorageDatabase", 100000);
return db;
}
/// GAME SETTINGS
function getValue(setting,def) {
var db = settings_db_open();
var res=def;
try {
db.transaction(function(tx) {
var rs = tx.executeSql('SELECT value FROM settings WHERE setting=?;', [setting]);
if (rs.rows.length > 0) {
res = rs.rows.item(0).value;
} else {
res = def;
}
})
} catch (err) {
console.log("*** getValue ERROR ")
res = def
};
console.log("*** getValue: "+res+" setting: "+setting)
return res
}
// insert anchor in db
function setAnchor(name, description, icon, latitude, longitude) {
var db = settings_db_open();
var res = "";
db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS anchors(name TEXT UNIQUE, description TEXT, icon TEXT, latitude REAL, longitude REAL)');
var rs = tx.executeSql('INSERT OR REPLACE INTO anchors VALUES (?,?,?,?,?);', [name, description, icon, latitude, longitude]);
if (rs.rowsAffected > 0) {
res = "OK";
} else {
res = "Error";
}
}
);
return res;
}
function setValue(setting, value) {
var db = settings_db_open();
var res = "";
db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS settings(setting TEXT UNIQUE, value TEXT)');
var rs = tx.executeSql('INSERT OR REPLACE INTO settings VALUES (?,?);', [setting,value]);
if (rs.rowsAffected > 0) {
res = "OK";
} else {
res = "Error";
}
}
);
console.log("*** setValue: "+res+" setting: "+setting+" = "+value)
return res;
}
/// GET ANCHORS
function getAnchors(model) {
model.clear()
var db = settings_db_open();
var res="OK";
try {
db.transaction(function(tx) {
var rs = tx.executeSql('SELECT * FROM anchors;');
for (var i = 0; i < rs.rows.length; i++)
{
model.append({"name" : rs.rows.item(i).name,"description" : rs.rows.item(i).description,"icon" : rs.rows.item(i).icon,"latitude" : rs.rows.item(i).latitude,"longitude" : rs.rows.item(i).longitude})
}
})
} catch (err) {
res = "ERROR"
};
return res
}
function delAnchor(name) {
var db = settings_db_open();
var res = "";
db.transaction(function(tx) {
//tx.executeSql('CREATE TABLE IF NOT EXISTS settings(savegame TEXT UNIQUE, value TEXT)'); //tx.executeSql('DELETE FROM channels WHERE source=?', [source])
var rs = tx.executeSql('DELETE FROM anchors where name=?', [name]);
if (rs.rowsAffected > 0) {
res = "OK";
} else {
res = "Error";
}
}
);
return res;
}
/// LOAD/SAVE GAME
function getSave(setting,def) {
var db = settings_db_open();
var res=def;
try {
db.transaction(function(tx) {
var rs = tx.executeSql('SELECT value FROM savegame WHERE setting=?;', [setting]);
if (rs.rows.length > 0) {
res = rs.rows.item(0).value;
} else {
res = def;
}
})
} catch (err) {
res = def
};
return res
}
function setSave(setting, value) {
var db = settings_db_open();
var res = "";
db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS settings(savegame TEXT UNIQUE, value TEXT)');
var rs = tx.executeSql('INSERT OR REPLACE INTO savegame VALUES (?,?);', [setting,value]);
if (rs.rowsAffected > 0) {
res = "OK";
} else {
res = "Error";
}
}
);
return res;
}

77
qml/pages/AboutPage.qml Normal file
View File

@ -0,0 +1,77 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
id: page
//allowedOrientations: Orientation.Landscape | Orientation.Portrait
SilicaFlickable {
anchors.fill: parent
contentHeight: column.height
Column {
id: column
PageHeader {
title: qsTr("About Anchor v.")+Qt.application.version
}
width: parent.width
spacing: Theme.paddingLarge
Label {
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("Author")
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeLarge
}
Label {
anchors.horizontalCenter: parent.horizontalCenter
text: "Niels Simonsen (nesnomis)"
font.pixelSize: Theme.fontSizeMedium
}
Label {
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("Info")
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeLarge
}
Text {
x: Theme.paddingLarge
width: parent.width - 2*Theme.paddingLarge
wrapMode: Text.Wrap
text: qsTr("Anchor is a small app using compass/magnetometer and GPS to mark your current position (make an anchor) so you can find your direction back. This could be where you parked your car, or other useful places?!")
font.pixelSize: Theme.fontSizeMedium
color: Theme.primaryColor
horizontalAlignment: Text.AlignHCenter
}
Label {
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("Copyrights (2018)")
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeLarge
}
Label {
text: qsTr("Anchor is public domain. If nothing else is stated, it is licened under GPL.")
x: Theme.paddingLarge
width: parent.width - 2*Theme.paddingLarge
wrapMode: Text.Wrap
font.pixelSize: Theme.fontSizeMedium
color: Theme.primaryColor
horizontalAlignment: Text.AlignHCenter
}
Image {
anchors.horizontalCenter: parent.horizontalCenter
opacity: 0.7
fillMode: Image.PreserveAspectFit
source: "../images/harbour-anchor.png"//anchorIcon !== "0" ? anchorIcon : "image://theme/icon-m-whereami" //anchorIcon !== "0" ? anchorIcon + "?" + Theme.highlightColor : "image://theme/icon-m-whereami?" + Theme.highlightColor
}
}
}
}

211
qml/pages/AddAnchorPage.qml Normal file
View File

@ -0,0 +1,211 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
//import "../components"
Dialog {
id: page
canAccept: sName.text !== "" && lName.text !=="" && la.text !== "" && lo.text !=="" ? true : false
property bool edit: false
property bool newAnchor: false
allowedOrientations: Orientation.Portrait
SilicaFlickable {
anchors.fill: parent
contentX: 0
contentHeight: col1.height
//contentWidth: text.width; contentHeight: text.height
Column {
id: col1
anchors.left: parent.left
anchors.right: parent.right
spacing: Theme.paddingMedium
DialogHeader {}
Label {
id: aLabel
anchors.right: parent.right
anchors.rightMargin: Theme.paddingLarge
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeLarge
text: edit ? qsTr("Edit anchor") : qsTr("Create anchor")
}
Separator {
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: Theme.paddingMedium
color: Theme.highlightColor
}
Row {
width:parent.width
TextField {
id: sName
width: parent.width - iBtn.width
EnterKey.iconSource: "image://theme/icon-m-enter-next"
EnterKey.onClicked: {focus = false;lName.focus = true}
placeholderText: edit && !newAnchor ? "" : qsTr("Anchor name")
text: edit ? anchorName : ""
label: qsTr("Anchor name")
}
Image {
id:iBtn
source: edit ? anchorIcon : "image://theme/icon-m-car"
}
}
TextField {
id: lName
width: parent.width
EnterKey.iconSource: "image://theme/icon-m-enter-next"
EnterKey.onClicked: {edit || newAnchor? la.focus = true : focus = false}
placeholderText: edit && !newAnchor ? "" : qsTr("Anchor description")
text: edit ? anchorDescription : ""
label: qsTr("Anchor description")
}
Label {
id: iLabel
anchors.right: parent.right
anchors.rightMargin: Theme.paddingLarge
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeLarge
text: qsTr("Choose icon")
}
Separator {
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: Theme.paddingMedium
color: Theme.highlightColor
}
Grid {
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
columns: 4
spacing: 2
IconButton {
width: parent.width / 4
height: width / 1.5
icon.source: "image://theme/icon-m-car"
onClicked: iBtn.source = icon.source
}
IconButton {
width: parent.width / 4
height: width / 1.5
icon.source: "image://theme/icon-m-airplane-mode"
onClicked: iBtn.source = icon.source
}
IconButton {
width: parent.width / 4
height: width / 1.5
icon.source: "image://theme/icon-m-whereami"
onClicked: iBtn.source = icon.source
}
IconButton {
width: parent.width / 4
height: width / 1.5
icon.source: "image://theme/icon-m-person"
onClicked: iBtn.source = icon.source
}
IconButton {
width: parent.width / 4
height: width / 1.5
icon.source: "image://theme/icon-m-train"
onClicked: iBtn.source = icon.source
}
IconButton {
width: parent.width / 4
height: width / 1.5
icon.source: "image://theme/icon-m-region"
onClicked: iBtn.source = icon.source
}
IconButton {
width: parent.width / 4
height: width / 1.5
icon.source: "image://theme/icon-m-favorite"
onClicked: iBtn.source = icon.source
}
IconButton {
id: lim
width: parent.width / 4
height: width / 1.5
icon.source: "image://theme/icon-m-home"
onClicked: iBtn.source = icon.source
}
}
Label {
id: cLabel
anchors.right: parent.right
anchors.rightMargin: Theme.paddingLarge
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeLarge
text: qsTr("Latitude & Longitude")
}
Separator {
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: Theme.paddingMedium
color: Theme.highlightColor
}
Item {
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: Theme.itemSizeMedium
TextField {
id: lo
enabled: edit || newAnchor
anchors.left: parent.horizontalCenter
anchors.leftMargin: Theme.paddingLarge
width: parent.width * 0.5 - Theme.paddingLarge
EnterKey.iconSource: "image://theme/icon-m-enter-next"
EnterKey.onClicked: {focus = false}
inputMethodHints: Qt.ImhFormattedNumbersOnly //| Qt.ImhNoPredictiveText
placeholderText: newAnchor ? "Longitude" : ""
text: edit ? anchorLongitude : newAnchor ? "" : aGps.currentLongitude
onTextChanged: text = text.replace(",",".")
}
TextField {
id: la
enabled: edit || newAnchor
anchors.right: parent.horizontalCenter
anchors.rightMargin: Theme.paddingLarge
anchors.top: lo.top
width: parent.width * 0.5 - Theme.paddingLarge
EnterKey.iconSource: "image://theme/icon-m-enter-next"
EnterKey.onClicked: {focus = false;lo.focus = true}
inputMethodHints: Qt.ImhFormattedNumbersOnly //| Qt.ImhNoPredictiveText
placeholderText: newAnchor ? "Latitude" : ""
horizontalAlignment: Qt.AlignRight
text: edit ? anchorLatitude : newAnchor ? "" : aGps.currentLatitude
onTextChanged: text = text.replace(",",".")
}
}
}
}
onAccepted: {
console.log("*** ACCEPTED")
if (sName.text !== "" && la.text !== "" && lo.text !=="") {
if (edit && !newAnchor) settings.delAnchor(anchorName)
anchorIcon = iBtn.source
anchorName = sName.text
anchorDescription = lName.text
anchorLatitude = la.text
anchorLongitude = lo.text
settings.setSettings(anchorLatitude,anchorLongitude,anchorIcon,anchorName,anchorDescription)
settings.getAnchors(dbAnchors)
settings.setAnchor(anchorName, anchorDescription, anchorIcon, anchorLatitude, anchorLongitude)
settings.getAnchors(dbAnchors)
}
}
}

307
qml/pages/AnchorPage.qml Normal file
View File

@ -0,0 +1,307 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
import "../components"
import QtSensors 5.0
Page {
id: page
property int dots: 1
property real calibration: aCompass.calibration ? aCompass.calibration : aMagnetometer.calibration
allowedOrientations: Orientation.Portrait
SilicaFlickable {
anchors.fill: parent
contentHeight: Screen.height
PullDownMenu {
// pageStack.push(Qt.resolvedUrl("AddAnchorPage.qml"),{edit: true,newAnchor: false});
MenuItem {
enabled: false//aGps.active
visible: false
text: qsTr("Refresh to current position")
onClicked: {
anchorLatitude = aGps.currentLatitude
anchorLongitude = aGps.currentLongitude
settings.setSettings(anchorLatitude,anchorLongitude,anchorIcon,anchorName,anchorDescription)
settings.setAnchor(anchorName, anchorDescription, anchorIcon, anchorLatitude, anchorLongitude)
}
}
MenuItem {
enabled: aGps.active
visible: aGps.active && anchorLatitude !=="" ? true : false
text: qsTr("Edit current position")
onClicked: pageStack.push(Qt.resolvedUrl("AddAnchorPage.qml"),{edit: true,newAnchor: false});
}
MenuItem {
enabled: aGps.active
visible: aGps.active
text: qsTr("Add current position")
onClicked: pageStack.push(Qt.resolvedUrl("AddAnchorPage.qml"),{edit: false,newAnchor: false});//posTimer.running = true//pageStack.push(Qt.resolvedUrl("SecondPage.qml"))
}
MenuItem {
enabled: true
text: qsTr("Add custom position")
onClicked: pageStack.push(Qt.resolvedUrl("AddAnchorPage.qml"),{edit: false,newAnchor: true});//posTimer.running = true//pageStack.push(Qt.resolvedUrl("SecondPage.qml"))
}
MenuItem {
enabled: true
text: qsTr("Select anchor")
onClicked: {pageStack.push(Qt.resolvedUrl("ChooseAnchorsPage.qml"))}
}
}
PushUpMenu {
MenuItem {
enabled: true
text: aGps.enabled ? qsTr("Disable GPS in app") : qsTr("Enable GPS in app")
onClicked: aGps.enabled ? aGps.enabled = false : aGps.enabled = true
}
MenuItem {
enabled: true
text: qsTr("Settings")
onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml"))
}
MenuItem {
enabled: true
text: qsTr("About Anchor")
onClicked: pageStack.push(Qt.resolvedUrl("AboutPage.qml"))
}
}
Item {
id: header2
visible: !header.visible
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: Theme.paddingLarge
anchors.top: parent.top
anchors.bottom: compassCapsule.top
anchors.bottomMargin: Theme.paddingLarge
Row {
spacing: Theme.paddingLarge
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Image {
//id:iBtn
height: apHeader2.height+apInfo2.height
width: height
fillMode: Image.PreserveAspectFit
source: "../images/harbour-anchor.png"//anchorIcon !== "0" ? anchorIcon : "image://theme/icon-m-whereami" //anchorIcon !== "0" ? anchorIcon + "?" + Theme.highlightColor : "image://theme/icon-m-whereami?" + Theme.highlightColor
}
Column {
Label {
id: apHeader2
style: Text.Outline; styleColor: Theme.secondaryHighlightColor;
font.pixelSize: Theme.fontSizeHuge
text: qsTr("Anchor") //anchorName !== "0" ? anchorName : qsTr("No anchor") //"Anchor: Quick"
}
Label {
id: apInfo2
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeMedium
text: qsTr("A compass & anchor app") //anchorDescription !== "0" ? anchorDescription : "" // "[Default anchor]"
}
}
}
}
Item {
id: header
visible: aGps.enabled
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: Theme.paddingLarge
anchors.top: parent.top
anchors.bottom: compassCapsule.top
anchors.bottomMargin: Theme.paddingLarge
Row {
spacing: Theme.paddingMedium
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Image {
id:iBtn
height: apHeader.height+apInfo.height
width: height
fillMode: Image.PreserveAspectFit
source: anchorIcon ? anchorIcon : "image://theme/icon-m-whereami" //anchorIcon !== "0" ? anchorIcon + "?" + Theme.highlightColor : "image://theme/icon-m-whereami?" + Theme.highlightColor
}
Column {
Label {
id: apHeader
style: Text.Outline; styleColor: Theme.secondaryHighlightColor;
font.pixelSize: Theme.fontSizeExtraLarge
text: anchorName ? anchorName : qsTr("No anchor") //"Anchor: Quick"
}
Label {
id: apInfo
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeMedium
text: anchorDescription ? anchorDescription : qsTr("Add an anchor") // "[Default anchor]"
}
}
}
}
CompassCapsule {
id: compassCapsule
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
width: parent.width * 0.8
height: width
anchorArrow: aGps.active && aGps.distance > anchorRadius ? 0.8 : 0.0
azimuth: aCompass.enabled ? aCompass.azimuth : aMagnetometer.azimuth
anchor: aGps.direction
}
Dot {
id: dotN
visible: !showCompasNumbers
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: compassCapsule.top
width: compassCapsule.width / 12
color: Theme.highlightColor
opacity: aGps.active && aGps.distance > anchorRadius ? 0.7 : 0.1
}
Item {
id: footer
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: Theme.paddingLarge
anchors.top: compassCapsule.bottom
anchors.bottom: info.top
anchors.bottomMargin: Theme.paddingLarge
Column {
spacing: Theme.paddingMedium
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Label {
id: gpsconnect
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.primaryColor
font.pixelSize: Theme.fontSizeHuge//aGps.active ? Theme.fontSizeHuge : Theme.fontSizeExtraLarge
text: aGps.active ? aGps.distance > anchorRadius ? qsTr("Distance: ")+aGps.distance + " m" : qsTr("HERE") : aGps.enabled ? qsTr("WAITING FOR GPS") : azimuth
Timer {
property bool up
id: glowingTimer
running: !aGps.active && aGps.enabled
repeat: true
interval: 100
onRunningChanged: if (!running) gpsconnect.opacity = 1
onTriggered: {
if (gpsconnect.opacity == 1){
up = false
} else if (gpsconnect.opacity < 0.5) {
up = true
}
if (up)
gpsconnect.opacity += 0.1
else
gpsconnect.opacity -= 0.1
}
}
}
Label {
id: gpsheight
visible: aGps.enabled
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.secondaryColor
font.pixelSize: aGps.active ? Theme.fontSizeExtraLarge : Theme.fontSizeMedium
text: aGps.active ? qsTr("Altitude: ")+aGps.currentAltitude + " m" : qsTr("Make sure your phone GPS is enabled!")
}
}
}
Rectangle {
id: calibRect
color: "transparent"
border.color: Theme.highlightColor
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.paddingMedium
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: Theme.paddingMedium
anchors.rightMargin: Theme.paddingMedium
height: calibrationBar.height
visible: calibration < 1 ? true : false//aCompass.enabled ? aCompass.calibration < 1 && aCompass.calibration > 0 ? true : aMagnetometer.calibration < 1 && aMagnetometer.calibration > 0 ? true : false : false
ProgressBar {
id: calibrationBar
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
minimumValue: 0.0
maximumValue: 1.0
width: parent.width
value: aCompass.enabled ? aCompass.calibration : aMagnetometer.calibration
label: qsTr("Rotate phone to calibrate compass")
}
}
Label {
id: info
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottomMargin: Theme.paddingLarge
anchors.bottom: parent.bottom
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeSmall
text: "Anchor v."+Qt.application.version+" "+qsTr("is an app by")+" nesnomis"
visible: !calibRect.visible
}
Rectangle {
id: rect
visible: false
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
width: page.width * 0.75
height: width
color: Theme.highlightDimmerColor
border.color: Theme.highlightColor
border.width: 1
radius: width
Column {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Text {
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeHuge
text: aGps.positionBearing + " ("+aGps.direction+")"
}
Text {
visible: aCompass.running
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeHuge
text: aCompass.enabled ? aCompass.azimuth : aMagnetometer.azimuth//compass.compassBearing + " ("+compass.compasNumber+")"
}
}
}
}
Component.onCompleted: {
settings.getQanchor()
var types = QmlSensors.sensorTypes();
console.log(types.join(", "));
}
}

View File

@ -0,0 +1,127 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
SilicaListView {
id: listView
anchors.fill: parent
clip: true
header: PageHeader {
id: pHeader
title: qsTr("Anchors")
}
model: dbModel
delegate: ListItem {
id: delegate
height: menuOpen ? contextMenu.height + img.height + (Theme.paddingMedium * 2): img.height + (Theme.paddingMedium * 2)
contentHeight: img.height
width: parent.width - Theme.paddingMedium * 2
anchors.horizontalCenter: parent.horizontalCenter
menu: contextMenu
showMenuOnPressAndHold: true
ListView.onRemove: animateRemoval(delegate)
function remove() {
remorseAction(qsTr("Deleting"), function() { settings.delAnchor(name);listView.model.remove(index) })
}
ContextMenu {
id: contextMenu
MenuItem {
id:mlisten
text: qsTr("Select anchor")
//enabled: false
onClicked: {
aGps.enabled = true
anchorIcon = icon
anchorName = name
anchorDescription = description
anchorLatitude = latitude
anchorLongitude = longitude
settings.setSettings(latitude,longitude,icon,name,description)
pageStack.navigateBack() }
}
MenuItem {
id:medit
text: qsTr("Edit anchor")
enabled: true
onClicked: {
// aGps.enabled = true
// anchorIcon = icon
// anchorName = name
// anchorDescription = description
//anchorLatitude = latitude
//anchorLongitude = longitude
anchorIcon = icon
anchorName = name
anchorDescription = description
anchorLatitude = latitude
anchorLongitude = longitude
settings.setSettings(latitude,longitude,icon,name,description)
pageStack.push(Qt.resolvedUrl("AddAnchorPage.qml"),{edit: true,newAnchor: false});
//settings.setSettings(anchorLatitude,anchorLatitude,anchorIcon,anchorName,anchorDescription)
//pageStack.navigateBack()
}
// onClicked: window.pageStack.push(Qt.resolvedUrl("AddOwnRadio.qml"),
// {infotext: qsTr("Edit radio station"),titlfield: title,streamurlfield: source,homepagefield: site,sectionfield: section,oldsource: source})
}
MenuItem {
id:mdelete
text: qsTr("Delete anchor")
onClicked: remove()//listView.currentItem.remove(rpindex,rpsource) //listView.remorseAction();
}
}
Row {
spacing: Theme.paddingLarge
width: parent.width
Image {
id: img
height: aName.height + aDesc.height
width: height
fillMode: Image.PreserveAspectFit
source: icon
}
Column {
Text {
id: aName
text: name
color: highlighted ? Theme.highlightColor : Theme.primaryColor
wrapMode: Text.ElideRight
font.pixelSize: Theme.fontSizeLarge
}
Text {
id: aDesc
text: description
color: highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
wrapMode: Text.ElideRight
font.pixelSize: Theme.fontSizeMedium
}
}
}
onClicked: {
aGps.enabled = true
anchorIcon = icon
anchorName = name
anchorDescription = description
anchorLatitude = latitude
anchorLongitude = longitude
settings.setSettings(latitude,longitude,icon,name,description)
pageStack.navigateBack()
}
}
}
}

43
qml/pages/FirstPage.qml Normal file
View File

@ -0,0 +1,43 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
id: page
// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All
// To enable PullDownMenu, place our content in a SilicaFlickable
SilicaFlickable {
anchors.fill: parent
// PullDownMenu and PushUpMenu must be declared in SilicaFlickable, SilicaListView or SilicaGridView
PullDownMenu {
MenuItem {
text: qsTr("Show Page 2")
onClicked: pageStack.animatorPush(Qt.resolvedUrl("SecondPage.qml"))
}
}
// Tell SilicaFlickable the height of its content.
contentHeight: column.height
// Place our content in a Column. The PageHeader is always placed at the top
// of the page, followed by our content.
Column {
id: column
width: page.width
spacing: Theme.paddingLarge
PageHeader {
title: qsTr("UI Template")
}
Label {
x: Theme.horizontalPageMargin
text: qsTr("Hello Sailors")
color: Theme.secondaryHighlightColor
font.pixelSize: Theme.fontSizeExtraLarge
}
}
}
}

30
qml/pages/SecondPage.qml Normal file
View File

@ -0,0 +1,30 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
id: page
// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All
SilicaListView {
id: listView
model: 20
anchors.fill: parent
header: PageHeader {
title: qsTr("Nested Page")
}
delegate: BackgroundItem {
id: delegate
Label {
x: Theme.horizontalPageMargin
text: qsTr("Item") + " " + index
anchors.verticalCenter: parent.verticalCenter
color: delegate.highlighted ? Theme.highlightColor : Theme.primaryColor
}
onClicked: console.log("Clicked " + index)
}
VerticalScrollDecorator {}
}
}

124
qml/pages/SettingsPage.qml Normal file
View File

@ -0,0 +1,124 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Dialog {
id: settingsDialog
property bool aComp
property bool aMag
property int aR: anchorRadius
Column {
//id: col1
anchors.left: parent.left
anchors.right: parent.right
spacing: Theme.paddingMedium
DialogHeader {}
Label {
id: sLabel
anchors.right: parent.right
anchors.rightMargin: Theme.paddingLarge
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeLarge
text: qsTr("Compass")
}
Separator {
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: Theme.paddingMedium
color: Theme.highlightColor
}
TextSwitch {
id: activateACompass
width: parent.width
checked: aCompass.enabled
enabled: false //aCompass.running
text: qsTr("Compass")
description: qsTr("Enables the compass")
onCheckedChanged: {
activateAMagnet.checked = !checked
aComp = checked
aMag = !checked
}
}
TextSwitch {
id: activateAMagnet
width: parent.width
checked: aMagnetometer.enabled
enabled: false //aMagnetometer.running
text: qsTr("Magnetometer")
description: qsTr("Activates the magnetometer")
onCheckedChanged: {
activateACompass.checked = !checked
aComp = !checked
aMag = checked
}
}
TextSwitch {
id: activateNumbers
width: parent.width
checked: showCompasNumbers
enabled: true //aMagnetometer.running
text: qsTr("Degrees")
description: qsTr("Show degrees in compass")
onCheckedChanged: {
}
}
Label {
id: rLabel
anchors.right: parent.right
anchors.rightMargin: Theme.paddingLarge
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeLarge
text: qsTr("Here radius")+" "+rSlider.value + " "+qsTr("meters")
}
Slider {
id: rSlider
width: parent.width
minimumValue: 1
maximumValue: 30
stepSize: 1.0
value: aR
onValueChanged: aR = value
}
Label {
// id: sLabel
anchors.right: parent.right
anchors.rightMargin: Theme.paddingLarge
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeLarge
text: qsTr("Anchor settings")
}
Separator {
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: Theme.paddingMedium
color: Theme.highlightColor
}
TextSwitch {
id: keepSon
width: parent.width
checked: keepScreenOn
enabled: true //aMagnetometer.running
text: qsTr("Prevent screensaver")
description: qsTr("Prevent screensaver when Anchor is active")
}
}
onAccepted: {
activateNumbers.checked ? showCompasNumbers = 1 : showCompasNumbers = 0
var scron
keepSon.checked ? scron = 1 : scron = 0
keepScreenOn = keepSon.checked
settings.setSettingSetting(aComp,aMag,aR,showCompasNumbers,scron)
anchorRadius = aR
}
}

View File

@ -0,0 +1,18 @@
# Rename this file as harbour-anchor.changes to include changelog
# entries in your RPM file.
#
# Add new changelog entries following the format below.
# Add newest entries to the top of the list.
# Separate entries from eachother with a blank line.
#
# Alternatively, if your changelog is automatically generated (e.g. with
# the git-change-log command provided with Sailfish OS SDK), create a
# harbour-anchor.changes.run script to let mb2 run the required commands for you.
# * date Author's Name <author's email> version-release
# - Summary of changes
* Sun Apr 13 2014 Jack Tar <jack.tar@example.com> 0.0.1-1
- Scrubbed the deck
- Hoisted the sails

View File

@ -0,0 +1,24 @@
#!/bin/bash
#
# Rename this file as harbour-anchor.changes.run to let sfdk automatically
# generate changelog from well formatted Git commit messages and tag
# annotations. Note that 'sfdk changelog' must be invoked as 'sfdk-changelog' here.
sfdk-changelog
# Here are some basic examples how to change from the default behavior. Run
# 'sfdk --help-maintaining' to learn more.
# Use a subset of tags
#sfdk-changelog --tags refs/tags/my-prefix/*
# Group entries by minor revision, suppress headlines for patch-level revisions
#sfdk-changelog --dense '/[0-9]+.[0-9+$'
# Trim very old changes
#sfdk-changelog --since 2014-04-01
#echo '[ Some changelog entries trimmed for brevity ]'
# Use the subjects (first lines) of tag annotations when no entry would be
# included for a revision otherwise
#sfdk-changelog --auto-add-annotations

41
rpm/harbour-anchor.spec Normal file
View File

@ -0,0 +1,41 @@
Name: harbour-anchor
Summary: Anchor
Version: 0.1
Release: 1
License: LICENSE
URL: http://example.org/
Source0: %{name}-%{version}.tar.bz2
Requires: sailfishsilica-qt5 >= 0.10.9
BuildRequires: pkgconfig(sailfishapp) >= 1.0.2
BuildRequires: pkgconfig(Qt5Core)
BuildRequires: pkgconfig(Qt5Qml)
BuildRequires: pkgconfig(Qt5Quick)
BuildRequires: desktop-file-utils
%description
App using compass and GPS to mark your position and create an anchor so you can find back to that location at a later time.
%prep
%setup -q -n %{name}-%{version}
%build
%qmake5
%make_build
%install
%qmake5_install
desktop-file-install --delete-original --dir %{buildroot}%{_datadir}/applications %{buildroot}%{_datadir}/applications/*.desktop
%files
%defattr(-,root,root,-)
%{_bindir}/%{name}
%{_datadir}/%{name}
%{_datadir}/applications/%{name}.desktop
%{_datadir}/icons/hicolor/*/apps/%{name}.png

20
src/harbour-anchor.cpp Normal file
View File

@ -0,0 +1,20 @@
#ifdef QT_QML_DEBUG
#include <QtQuick>
#endif
#include <sailfishapp.h>
int main(int argc, char *argv[])
{
// SailfishApp::main() will display "qml/harbour-anchor.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
// - SailfishApp::pathToMainQml() to get a QUrl to the main QML file
//
// To display the view, call "show()" (will show fullscreen on device).
return SailfishApp::main(argc, argv);
}

View File

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>AboutPage</name>
<message>
<source>About Anchor v.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Author</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Info</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor is a small app using compass/magnetometer and GPS to mark your current position (make an anchor) so you can find your direction back. This could be where you parked your car, or other useful places?!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copyrights (2018)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor is public domain. If nothing else is stated, it is licened under GPL.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AddAnchorPage</name>
<message>
<source>Edit anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Create anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Choose icon</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Latitude &amp; Longitude</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AnchorPage</name>
<message>
<source>Refresh to current position</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit current position</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add current position</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add custom position</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Disable GPS in app</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enable GPS in app</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>About Anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>A compass &amp; anchor app</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add an anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Distance: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HERE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WAITING FOR GPS</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Altitude: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Make sure your phone GPS is enabled!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rotate phone to calibrate compass</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>is an app by</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChooseAnchorsPage</name>
<message>
<source>Anchors</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Deleting</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete anchor</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FirstPage</name>
<message>
<source>Show Page 2</source>
<translation>Zur Seite 2</translation>
</message>
<message>
<source>UI Template</source>
<translation>UI-Vorlage</translation>
</message>
<message>
<source>Hello Sailors</source>
<translation>Hallo Matrosen</translation>
</message>
</context>
<context>
<name>SecondPage</name>
<message>
<source>Nested Page</source>
<translation>Unterseite</translation>
</message>
<message>
<source>Item</source>
<translation>Element</translation>
</message>
</context>
<context>
<name>SettingsPage</name>
<message>
<source>Compass</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enables the compass</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Magnetometer</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Activates the magnetometer</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Degrees</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show degrees in compass</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Here radius</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Prevent screensaver</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Prevent screensaver when Anchor is active</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>AboutPage</name>
<message>
<source>About Anchor v.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Author</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Info</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor is a small app using compass/magnetometer and GPS to mark your current position (make an anchor) so you can find your direction back. This could be where you parked your car, or other useful places?!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copyrights (2018)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor is public domain. If nothing else is stated, it is licened under GPL.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AddAnchorPage</name>
<message>
<source>Edit anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Create anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Choose icon</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Latitude &amp; Longitude</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AnchorPage</name>
<message>
<source>Refresh to current position</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit current position</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add current position</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add custom position</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Disable GPS in app</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enable GPS in app</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>About Anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>A compass &amp; anchor app</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add an anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Distance: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>HERE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WAITING FOR GPS</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Altitude: </source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Make sure your phone GPS is enabled!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Rotate phone to calibrate compass</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>is an app by</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChooseAnchorsPage</name>
<message>
<source>Anchors</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Deleting</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit anchor</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete anchor</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>FirstPage</name>
<message>
<source>Show Page 2</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>UI Template</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Hello Sailors</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SecondPage</name>
<message>
<source>Nested Page</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Item</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsPage</name>
<message>
<source>Compass</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enables the compass</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Magnetometer</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Activates the magnetometer</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Degrees</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show degrees in compass</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Here radius</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>meters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Anchor settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Prevent screensaver</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Prevent screensaver when Anchor is active</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>