tRename to harbour-passilic, implement folder listing - sailfish-safe - Sailfish frontend for safe(1)
(HTM) git clone git://git.z3bra.org/sailfish-safe.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 6e63350eb5773919bf0ef0cc0c985ef70f3735dc
(DIR) parent c0c27d5aa421cde6650c4146a3bc405773d88cfc
(HTM) Author: Daniel Vrátil <dvratil@kde.org>
Date: Sat, 2 Feb 2019 17:17:23 +0100
Rename to harbour-passilic, implement folder listing
Most of the backend C++ code is taken from Plasma Pass.
Diffstat:
A .gitmodules | 3 +++
A 3rdparty/kitemmodels | 1 +
R passilic.desktop -> harbour-passil… | 0
A harbour-passilic.pro | 43 ++++++++++++++++++++++++++++++
A harbour-passilic.pro.user.15149e1 | 803 +++++++++++++++++++++++++++++++
R icons/108x108/passilic.png -> icon… | 0
R icons/128x128/passilic.png -> icon… | 0
R icons/172x172/passilic.png -> icon… | 0
R icons/86x86/passilic.png -> icons/… | 0
D passilic.pro | 40 -------------------------------
A qml/harbour-passilic.qml | 48 +++++++++++++++++++++++++++++++
D qml/pages/FirstPage.qml | 43 ------------------------------
A qml/pages/PasswordListPage.qml | 76 +++++++++++++++++++++++++++++++
D qml/pages/SecondPage.qml | 30 ------------------------------
D qml/passilic.qml | 10 ----------
R rpm/passilic.changes.in -> rpm/har… | 0
R rpm/passilic.changes.run.in -> rpm… | 0
A rpm/harbour-passilic.spec | 71 +++++++++++++++++++++++++++++++
A rpm/harbour-passilic.yaml | 45 +++++++++++++++++++++++++++++++
D rpm/passilic.yaml | 45 -------------------------------
A src/abbreviations.cpp | 200 +++++++++++++++++++++++++++++++
A src/abbreviations.h | 45 +++++++++++++++++++++++++++++++
A src/main.cpp | 44 +++++++++++++++++++++++++++++++
D src/passilic.cpp | 20 --------------------
A src/passwordfiltermodel.cpp | 108 +++++++++++++++++++++++++++++++
A src/passwordfiltermodel.h | 58 ++++++++++++++++++++++++++++++
A src/passwordprovider.cpp | 184 +++++++++++++++++++++++++++++++
A src/passwordprovider.h | 75 +++++++++++++++++++++++++++++++
A src/passwordsmodel.cpp | 218 +++++++++++++++++++++++++++++++
A src/passwordsmodel.h | 73 +++++++++++++++++++++++++++++++
A src/passwordsortproxymodel.cpp | 42 +++++++++++++++++++++++++++++++
A src/passwordsortproxymodel.h | 35 +++++++++++++++++++++++++++++++
R translations/passilic.ts -> transl… | 0
33 files changed, 2172 insertions(+), 188 deletions(-)
---
(DIR) diff --git a/.gitmodules b/.gitmodules
t@@ -0,0 +1,3 @@
+[submodule "3rdparty/kitemmodels"]
+ path = 3rdparty/kitemmodels
+ url = git://anongit.kde.org/kitemmodels.git
(DIR) diff --git a/3rdparty/kitemmodels b/3rdparty/kitemmodels
t@@ -0,0 +1 @@
+Subproject commit 18244542c2bc895dfd1615468eb917aae06519ab
(DIR) diff --git a/passilic.desktop b/harbour-passilic.desktop
(DIR) diff --git a/harbour-passilic.pro b/harbour-passilic.pro
t@@ -0,0 +1,43 @@
+TARGET = harbour-passilic
+
+CONFIG += sailfishapp
+
+INCLUDEPATH += 3rdparty/kitemmodels/
+
+SOURCES += \
+ src/main.cpp \
+ src/abbreviations.cpp \
+ src/passwordfiltermodel.cpp \
+ src/passwordprovider.cpp \
+ src/passwordsmodel.cpp \
+ src/passwordsortproxymodel.cpp \
+ 3rdparty/kitemmodels/kdescendantsproxymodel.cpp
+
+
+HEADERS += \
+ src/abbreviations.h \
+ src/passwordfiltermodel.h \
+ src/passwordprovider.h \
+ src/passwordsmodel.h \
+ src/passwordsortproxymodel.h \
+ 3rdparty/kitemmodels/kdescendantsproxymodel.h
+
+DISTFILES += \
+ qml/harbour-passilic.qml \
+ qml/cover/CoverPage.qml \
+ qml/pages/PasswordListPage.qml \
+ rpm/harbour-passilic.changes.in \
+ rpm/harbour-passilic.changes.run.in \
+ rpm/harbour-passilic.spec \
+ rpm/harbour-passilic.yaml \
+ translations/*.ts \
+ harbour-passilic.desktop
+
+SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
+
+# to disable building translations every time, comment out the
+# following CONFIG line
+#CONFIG += sailfishapp_i18n
+
+#TRANSLATIONS += \
+# translations/harbour-passilic-de.ts
(DIR) diff --git a/harbour-passilic.pro.user.15149e1 b/harbour-passilic.pro.user.15149e1
t@@ -0,0 +1,803 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 4.7.2, 2019-02-02T14:56:19. -->
+<qtcreator>
+ <data>
+ <variable>EnvironmentId</variable>
+ <value type="QByteArray">{15149e1f-3676-4ba6-86eb-4a3b57615e78}</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.ActiveTarget</variable>
+ <value type="int">0</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.EditorSettings</variable>
+ <valuemap type="QVariantMap">
+ <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+ <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+ <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+ <value type="QString" key="language">Cpp</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+ </valuemap>
+ </valuemap>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+ <value type="QString" key="language">QmlJS</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+ </valuemap>
+ </valuemap>
+ <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+ <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+ <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+ <value type="int" key="EditorConfiguration.IndentSize">4</value>
+ <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+ <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+ <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+ <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+ <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+ <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+ <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+ <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+ <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
+ <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+ <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+ <value type="int" key="EditorConfiguration.TabSize">8</value>
+ <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+ <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+ <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+ <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+ <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+ <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.PluginSettings</variable>
+ <valuemap type="QVariantMap"/>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Target.0</variable>
+ <valuemap type="QVariantMap">
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">SailfishOS-3.0.1.11-i486 (in Sailfish OS Build Engine)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">SailfishOS-3.0.1.11-i486 (in Sailfish OS Build Engine)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{86fc4280-6f14-401f-92c1-d7747529b56d}</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">1</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/data/projects/build-harbour-passilic-SailfishOS_3_0_1_11_i486_in_Sailfish_OS_Build_Engine-Debug</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/data/projects/build-harbour-passilic-SailfishOS_3_0_1_11_i486_in_Sailfish_OS_Build_Engine-Release</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/data/projects/build-harbour-passilic-SailfishOS_3_0_1_11_i486_in_Sailfish_OS_Build_Engine-Profile</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmBuildStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM Validation</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmValidationStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build RPM Package For Manual Deployment</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build RPM Package For Manual Deployment</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerMb2RpmBuildConfiguration</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Prepare Target</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Rsync</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRsyncDeployStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy By Copying Binaries</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy By Copying Binaries</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRSyncDeployConfiguration</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.2">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Prepare Target</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmDeployStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy As RPM Package</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy As RPM Package</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmDeployConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">3</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+ <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+ <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+ <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+ <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+ <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="QString" key="MerRunConfiguration.QmlLiveBenchWorkspace">/data/projects/harbour-passilic</value>
+ <value type="bool" key="MerRunConfiguration.QmlLiveEnabled">false</value>
+ <value type="int" key="MerRunConfiguration.QmlLiveIpcPort">10234</value>
+ <value type="int" key="MerRunConfiguration.QmlLiveOptions">3</value>
+ <value type="QString" key="MerRunConfiguration.QmlLiveTargetWorkspace"></value>
+ <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">harbour-passilic (on Sailfish OS Emulator)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRunConfiguration:/data/projects/harbour-passilic/harbour-passilic.pro</value>
+ <value type="QString" key="Qt4ProjectManager.MaemoRunConfiguration.Arguments"></value>
+ <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
+ <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+ <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
+ <value type="QString" key="RemoteLinux.RunConfig.WorkingDirectory"></value>
+ <value type="QString" key="RemoteLinux.RunConfig.WorkingDirectory.default"></value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Target.1</variable>
+ <valuemap type="QVariantMap">
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">SailfishOS-3.0.1.11-armv7hl (in Sailfish OS Build Engine)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">SailfishOS-3.0.1.11-armv7hl (in Sailfish OS Build Engine)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{71f7a162-89f7-4d3f-95f3-fbadf9244567}</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/data/projects/build-harbour-passilic-SailfishOS_3_0_1_11_armv7hl_in_Sailfish_OS_Build_Engine-Debug</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/data/projects/build-harbour-passilic-SailfishOS_3_0_1_11_armv7hl_in_Sailfish_OS_Build_Engine-Release</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/data/projects/build-harbour-passilic-SailfishOS_3_0_1_11_armv7hl_in_Sailfish_OS_Build_Engine-Profile</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Start Build Engine</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Mer.MerSdkStartStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmBuildStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM Validation</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmValidationStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build RPM Package For Manual Deployment</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build RPM Package For Manual Deployment</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerMb2RpmBuildConfiguration</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Prepare Target</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Rsync</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRsyncDeployStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy By Copying Binaries</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy By Copying Binaries</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRSyncDeployConfiguration</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.2">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Prepare Target</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerPrepareTargetStep</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">RPM</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmDeployStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy As RPM Package</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy As RPM Package</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRpmDeployConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">3</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+ <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+ <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+ <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+ <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+ <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="QString" key="MerRunConfiguration.QmlLiveBenchWorkspace">/data/projects/harbour-passilic</value>
+ <value type="bool" key="MerRunConfiguration.QmlLiveEnabled">false</value>
+ <value type="int" key="MerRunConfiguration.QmlLiveIpcPort">10234</value>
+ <value type="int" key="MerRunConfiguration.QmlLiveOptions">3</value>
+ <value type="QString" key="MerRunConfiguration.QmlLiveTargetWorkspace"></value>
+ <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">harbour-passilic (on Sailfish OS Emulator)</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.MerRunConfiguration:/data/projects/harbour-passilic/harbour-passilic.pro</value>
+ <value type="QString" key="Qt4ProjectManager.MaemoRunConfiguration.Arguments"></value>
+ <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
+ <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+ <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
+ <value type="QString" key="RemoteLinux.RunConfig.WorkingDirectory"></value>
+ <value type="QString" key="RemoteLinux.RunConfig.WorkingDirectory.default"></value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.TargetCount</variable>
+ <value type="int">2</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+ <value type="int">18</value>
+ </data>
+ <data>
+ <variable>Version</variable>
+ <value type="int">18</value>
+ </data>
+</qtcreator>
(DIR) diff --git a/icons/108x108/passilic.png b/icons/108x108/harbour-passilic.png
Binary files differ.
(DIR) diff --git a/icons/128x128/passilic.png b/icons/128x128/harbour-passilic.png
Binary files differ.
(DIR) diff --git a/icons/172x172/passilic.png b/icons/172x172/harbour-passilic.png
Binary files differ.
(DIR) diff --git a/icons/86x86/passilic.png b/icons/86x86/harbour-passilic.png
Binary files differ.
(DIR) diff --git a/passilic.pro b/passilic.pro
t@@ -1,40 +0,0 @@
-# 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 = passilic
-
-CONFIG += sailfishapp
-
-SOURCES += src/passilic.cpp
-
-DISTFILES += qml/passilic.qml \
- qml/cover/CoverPage.qml \
- qml/pages/FirstPage.qml \
- qml/pages/SecondPage.qml \
- rpm/passilic.changes.in \
- rpm/passilic.changes.run.in \
- rpm/passilic.spec \
- rpm/passilic.yaml \
- translations/*.ts \
- passilic.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/passilic-de.ts
(DIR) diff --git a/qml/harbour-passilic.qml b/qml/harbour-passilic.qml
t@@ -0,0 +1,48 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import "pages"
+import harbour.passilic 1.0
+
+ApplicationWindow
+{
+ id: app
+
+ PasswordSortProxyModel {
+ id: passwordsModel
+
+ dynamicSortFilter: true
+ isSortLocaleAware: true
+ sortCaseSensitivity: Qt.CaseInsensitive
+
+ sourceModel: PasswordsModel {}
+ }
+
+ PasswordFilterModel {
+ id: filterModel
+
+ sourceModel: passwordsModel
+ }
+
+ Component {
+ id: passwordsPage
+
+ PasswordListPage {
+ model: passwordsModel
+ onFolderSelected: {
+ var newPage = passwordsPage.createObject(app, {
+ "rootIndex": index,
+ "currentPath": currentPath + "/" + name
+ });
+ app.pageStack.push(newPage)
+ }
+ }
+ }
+
+ cover: Qt.resolvedUrl("cover/CoverPage.qml")
+
+ allowedOrientations: defaultAllowedOrientations
+
+ Component.onCompleted: {
+ app.pageStack.push(passwordsPage.createObject(app));
+ }
+}
(DIR) diff --git a/qml/pages/FirstPage.qml b/qml/pages/FirstPage.qml
t@@ -1,43 +0,0 @@
-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.push(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
- }
- }
- }
-}
(DIR) diff --git a/qml/pages/PasswordListPage.qml b/qml/pages/PasswordListPage.qml
t@@ -0,0 +1,76 @@
+import QtQuick 2.2
+import QtQml.Models 2.2
+import Sailfish.Silica 1.0
+import harbour.passilic 1.0
+
+Page {
+ id: passwordListPage
+
+ property var rootIndex: null
+ property alias model: delegateModel.model
+ property string currentPath: ""
+
+
+ signal folderSelected(var index, var name)
+
+
+ SilicaListView {
+ id: listView
+
+ anchors.fill: parent
+
+ header: PageHeader {
+ id: pageHeader
+ width: parent.width
+ title: passwordListPage.currentPath === "" ? qsTr("Passilic") : passwordListPage.currentPath
+ }
+
+ model: DelegateModel {
+ id: delegateModel
+
+ rootIndex: passwordListPage.rootIndex
+
+ delegate: ListItem {
+ id: listItem
+ height: Theme.itemSizeSmall
+
+ Row {
+
+ spacing: Theme.paddingMedium
+
+ anchors {
+ left: parent.left
+ leftMargin: Theme.horizontalPageMargin
+ right: parent.right
+ rightMargin: Theme.horizontalPageMargin
+ verticalCenter: parent.verticalCenter
+ }
+
+ Image {
+ anchors.verticalCenter: parent.verticalCenter
+ source: "image://theme/"
+ + ((model.type === PasswordsModel.FolderEntry) ? "icon-m-folder" : "icon-m-device-lock")
+ + "?"
+ + (listItem.highlighted ? Theme.highlightColor : Theme.primaryColor)
+ width: Theme.iconSizeSmall
+ height: width
+ }
+
+ Label {
+ id: label
+ text: model.name
+ }
+
+ }
+
+ onClicked: {
+ if (model.type === PasswordsModel.FolderEntry) {
+ passwordListPage.folderSelected(delegateModel.modelIndex(index), model.name);
+ } else {
+ console.log("Password for " + model.name + " requested");
+ }
+ }
+ }
+ }
+ }
+}
(DIR) diff --git a/qml/pages/SecondPage.qml b/qml/pages/SecondPage.qml
t@@ -1,30 +0,0 @@
-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 {}
- }
-}
(DIR) diff --git a/qml/passilic.qml b/qml/passilic.qml
t@@ -1,10 +0,0 @@
-import QtQuick 2.0
-import Sailfish.Silica 1.0
-import "pages"
-
-ApplicationWindow
-{
- initialPage: Component { FirstPage { } }
- cover: Qt.resolvedUrl("cover/CoverPage.qml")
- allowedOrientations: defaultAllowedOrientations
-}
(DIR) diff --git a/rpm/passilic.changes.in b/rpm/harbour-passilic.changes.in
(DIR) diff --git a/rpm/passilic.changes.run.in b/rpm/harbour-passilic.changes.run.in
(DIR) diff --git a/rpm/harbour-passilic.spec b/rpm/harbour-passilic.spec
t@@ -0,0 +1,71 @@
+#
+# Do NOT Edit the Auto-generated Part!
+# Generated by: spectacle version 0.27
+#
+
+Name: harbour-passilic
+
+# >> 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: A frontend for the pass password manager
+Version: 0.1
+Release: 1
+Group: Qt/Qt
+License: LICENSE
+URL: http://example.org/
+Source0: %{name}-%{version}.tar.bz2
+Source100: harbour-passilic.yaml
+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
+A frontend for the pass password manager.
+
+
+%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,-)
+%{_bindir}
+%{_datadir}/%{name}
+%{_datadir}/applications/%{name}.desktop
+%{_datadir}/icons/hicolor/*/apps/%{name}.png
+# >> files
+# << files
(DIR) diff --git a/rpm/harbour-passilic.yaml b/rpm/harbour-passilic.yaml
t@@ -0,0 +1,45 @@
+Name: harbour-passilic
+Summary: A frontend for the pass password manager
+Version: 0.1
+Release: 1
+# The contents of the Group field should be one of the groups listed here:
+# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
+Group: Qt/Qt
+URL: http://example.org/
+License: LICENSE
+# This must be generated before uploading a package to a remote build service.
+# Usually this line does not need to be modified.
+Sources:
+- '%{name}-%{version}.tar.bz2'
+Description: |
+ A frontend for the pass password manager.
+Configure: none
+# The qtc5 builder inserts macros to allow QtCreator to have fine
+# control over qmake/make execution
+Builder: qtc5
+
+# This section specifies build dependencies that are resolved using pkgconfig.
+# This is the preferred way of specifying build dependencies for your package.
+PkgConfigBR:
+ - sailfishapp >= 1.0.2
+ - Qt5Core
+ - Qt5Qml
+ - Qt5Quick
+
+# Build dependencies without a pkgconfig setup can be listed here
+# PkgBR:
+# - package-needed-to-build
+
+# Runtime dependencies which are not automatically detected
+Requires:
+ - sailfishsilica-qt5 >= 0.10.9
+
+# All installed files
+Files:
+ - '%{_bindir}'
+ - '%{_datadir}/%{name}'
+ - '%{_datadir}/applications/%{name}.desktop'
+ - '%{_datadir}/icons/hicolor/*/apps/%{name}.png'
+
+# For more information about yaml and what's supported in Sailfish OS
+# build system, please see https://wiki.merproject.org/wiki/Spectacle
(DIR) diff --git a/rpm/passilic.yaml b/rpm/passilic.yaml
t@@ -1,45 +0,0 @@
-Name: passilic
-Summary: Passilic
-Version: 0.1
-Release: 1
-# The contents of the Group field should be one of the groups listed here:
-# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
-Group: Qt/Qt
-URL: http://example.org/
-License: LICENSE
-# This must be generated before uploading a package to a remote build service.
-# Usually this line does not need to be modified.
-Sources:
-- '%{name}-%{version}.tar.bz2'
-Description: |
- Short description of my Sailfish OS Application
-Configure: none
-# The qtc5 builder inserts macros to allow QtCreator to have fine
-# control over qmake/make execution
-Builder: qtc5
-
-# This section specifies build dependencies that are resolved using pkgconfig.
-# This is the preferred way of specifying build dependencies for your package.
-PkgConfigBR:
- - sailfishapp >= 1.0.2
- - Qt5Core
- - Qt5Qml
- - Qt5Quick
-
-# Build dependencies without a pkgconfig setup can be listed here
-# PkgBR:
-# - package-needed-to-build
-
-# Runtime dependencies which are not automatically detected
-Requires:
- - sailfishsilica-qt5 >= 0.10.9
-
-# All installed files
-Files:
- - '%{_bindir}'
- - '%{_datadir}/%{name}'
- - '%{_datadir}/applications/%{name}.desktop'
- - '%{_datadir}/icons/hicolor/*/apps/%{name}.png'
-
-# For more information about yaml and what's supported in Sailfish OS
-# build system, please see https://wiki.merproject.org/wiki/Spectacle
(DIR) diff --git a/src/abbreviations.cpp b/src/abbreviations.cpp
t@@ -0,0 +1,200 @@
+/*
+ * Borrowed from KDevelop (kdevplatform/language/interfaces/abbreviations.cpp)
+ *
+ * Copyright 2014 Sven Brauch <svenbrauch@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "abbreviations.h"
+
+#include <QStringList>
+#include <QVarLengthArray>
+
+namespace {
+
+// Taken and adapted for kdevelop from katecompletionmodel.cpp
+static bool matchesAbbreviationHelper(const QStringRef &word, const QStringRef &typed,
+ const QVarLengthArray< int, 32 > &offsets,
+ int &depth, int atWord = -1, int i = 0)
+{
+ int atLetter = 1;
+ for ( ; i < typed.size(); i++ ) {
+ const QChar c = typed.at(i).toLower();
+ bool haveNextWord = offsets.size() > atWord + 1;
+ bool canCompare = atWord != -1 && word.size() > offsets.at(atWord) + atLetter;
+ if (canCompare && c == word.at(offsets.at(atWord) + atLetter).toLower()) {
+ // the typed letter matches a letter after the current word beginning
+ if (!haveNextWord || c != word.at(offsets.at(atWord + 1)).toLower()) {
+ // good, simple case, no conflict
+ atLetter += 1;
+ continue;
+ }
+ // For maliciously crafted data, the code used here theoretically can have very high
+ // complexity. Thus ensure we don't run into this case, by limiting the amount of branches
+ // we walk through to 128.
+ depth++;
+ if (depth > 128) {
+ return false;
+ }
+ // the letter matches both the next word beginning and the next character in the word
+ if (haveNextWord && matchesAbbreviationHelper(word, typed, offsets, depth, atWord + 1, i + 1)) {
+ // resolving the conflict by taking the next word's first character worked, fine
+ return true;
+ }
+ // otherwise, continue by taking the next letter in the current word.
+ atLetter += 1;
+ continue;
+ } else if (haveNextWord && c == word.at(offsets.at(atWord + 1)).toLower()) {
+ // the typed letter matches the next word beginning
+ atWord++;
+ atLetter = 1;
+ continue;
+ }
+ // no match
+ return false;
+ }
+ // all characters of the typed word were matched
+ return true;
+}
+
+}
+
+bool PlasmaPass::matchesAbbreviation(const QStringRef &word, const QStringRef &typed)
+{
+ // A mismatch is very likely for random even for the first letter,
+ // thus this optimization makes sense.
+ if (word.at(0).toLower() != typed.at(0).toLower()) {
+ return false;
+ }
+
+ // First, check if all letters are contained in the word in the right order.
+ int atLetter = 0;
+ for (const auto c : typed) {
+ while (c.toLower() != word.at(atLetter).toLower()) {
+ atLetter += 1;
+ if (atLetter >= word.size()) {
+ return false;
+ }
+ }
+ }
+
+ bool haveUnderscore = true;
+ QVarLengthArray<int, 32> offsets;
+ // We want to make "KComplM" match "KateCompletionModel"; this means we need
+ // to allow parts of the typed text to be not part of the actual abbreviation,
+ // which consists only of the uppercased / underscored letters (so "KCM" in this case).
+ // However it might be ambigous whether a letter is part of such a word or part of
+ // the following abbreviation, so we need to find all possible word offsets first,
+ // then compare.
+ for (int i = 0; i < word.size(); ++i) {
+ const QChar c = word.at(i);
+ if (c == QLatin1Char('_') || c == QLatin1Char('-')) {
+ haveUnderscore = true;
+ } else if (haveUnderscore || c.isUpper()) {
+ offsets.append(i);
+ haveUnderscore = false;
+ }
+ }
+ int depth = 0;
+ return matchesAbbreviationHelper(word, typed, offsets, depth);
+}
+
+bool PlasmaPass::matchesPath(const QStringRef &path, const QStringRef &typed)
+{
+ int consumed = 0;
+ int pos = 0;
+ // try to find all the characters in typed in the right order in the path;
+ // jumps are allowed everywhere
+ while (consumed < typed.size() && pos < path.size()) {
+ if (typed.at(consumed).toLower() == path.at(pos).toLower()) {
+ consumed++;
+ }
+ pos++;
+ }
+ return consumed == typed.size();
+}
+
+int PlasmaPass::matchPathFilter(const QVector<QStringRef> &toFilter, const QVector<QStringRef> &text)
+{
+ enum PathFilterMatchQuality {
+ NoMatch = -1,
+ ExactMatch = 0,
+ StartMatch = 1,
+ OtherMatch = 2 // and anything higher than that
+ };
+ const auto segments = toFilter;
+
+ if (text.count() > segments.count()) {
+ // number of segments mismatches, thus item cannot match
+ return NoMatch;
+ }
+
+ bool allMatched = true;
+ int searchIndex = text.size() - 1;
+ int pathIndex = segments.size() - 1;
+ int lastMatchIndex = -1;
+ // stop early if more search fragments remain than available after path index
+ while (pathIndex >= 0 && searchIndex >= 0
+ && (pathIndex + text.size() - searchIndex - 1) < segments.size())
+ {
+ const auto &segment = segments.at(pathIndex);
+ const auto &typedSegment = text.at(searchIndex);
+ const int matchIndex = segment.indexOf(typedSegment, 0, Qt::CaseInsensitive);
+ const bool isLastPathSegment = pathIndex == segments.size() - 1;
+ const bool isLastSearchSegment = searchIndex == text.size() - 1;
+
+ // check for exact matches
+ allMatched &= matchIndex == 0 && segment.size() == typedSegment.size();
+
+ // check for fuzzy matches
+ bool isMatch = matchIndex != -1;
+ // do fuzzy path matching on the last segment
+ if (!isMatch && isLastPathSegment && isLastSearchSegment) {
+ isMatch = matchesPath(segment, typedSegment);
+ } else if (!isMatch) { // check other segments for abbreviations
+ isMatch = matchesAbbreviation(segment.mid(0), typedSegment);
+ }
+
+ if (!isMatch) {
+ // no match, try with next path segment
+ --pathIndex;
+ continue;
+ }
+ // else we matched
+ if (isLastPathSegment) {
+ lastMatchIndex = matchIndex;
+ }
+ --searchIndex;
+ --pathIndex;
+ }
+
+ if (searchIndex != -1) {
+ return NoMatch;
+ }
+
+ const int segmentMatchDistance = segments.size() - (pathIndex + 1);
+
+ if (allMatched) {
+ return ExactMatch;
+ } else if (lastMatchIndex == 0) {
+ // prefer matches whose last element starts with the filter
+ return StartMatch;
+ } else {
+ // prefer matches closer to the end of the path
+ return OtherMatch + segmentMatchDistance;
+ }
+}
(DIR) diff --git a/src/abbreviations.h b/src/abbreviations.h
t@@ -0,0 +1,45 @@
+/*
+ * Borrowed from KDevelop (kdevplatform/language/interfaces/abbreviations.h)
+ *
+ * Copyright 2014 Sven Brauch <svenbrauch@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PLASMAPASS_ABBREVIATIONS_H
+#define PLASMAPASS_ABBREVIATIONS_H
+
+#include <QVector>
+
+class QStringList;
+class QStringRef;
+class QString;
+
+namespace PlasmaPass {
+
+bool matchesAbbreviation(const QStringRef &word, const QStringRef &typed);
+
+bool matchesPath(const QStringRef &path, const QStringRef &typed);
+
+/**
+ * @brief Matches a path against a list of search fragments.
+ * @return -1 when no match is found, otherwise a positive integer, higher values mean lower quality
+ */
+int matchPathFilter(const QVector<QStringRef> &toFilter, const QVector<QStringRef> &text);
+
+}
+
+#endif
(DIR) diff --git a/src/main.cpp b/src/main.cpp
t@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 Daniel Vrátil <dvratil@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "passwordsmodel.h"
+#include "passwordfiltermodel.h"
+#include "passwordsortproxymodel.h"
+
+#ifdef QT_QML_DEBUG
+#include <QtQuick>
+#endif
+#include <QScopedPointer>
+
+#include <sailfishapp.h>
+
+int main(int argc, char *argv[])
+{
+ QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv));
+ QScopedPointer<QQuickView> view(SailfishApp::createView());
+
+ qmlRegisterType<PasswordsModel>("harbour.passilic", 1, 0, "PasswordsModel");
+ qmlRegisterType<PasswordFilterModel>("harbour.passilic", 1, 0, "PasswordFilterModel");
+ qmlRegisterType<PasswordSortProxyModel>("harbour.passilic", 1, 0, "PasswordSortProxyModel");
+
+ view->setSource(SailfishApp::pathToMainQml());
+ view->show();
+
+ return app->exec();
+}
(DIR) diff --git a/src/passilic.cpp b/src/passilic.cpp
t@@ -1,20 +0,0 @@
-#ifdef QT_QML_DEBUG
-#include <QtQuick>
-#endif
-
-#include <sailfishapp.h>
-
-int main(int argc, char *argv[])
-{
- // SailfishApp::main() will display "qml/passilic.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);
-}
(DIR) diff --git a/src/passwordfiltermodel.cpp b/src/passwordfiltermodel.cpp
t@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 Daniel Vrátil <dvratil@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "passwordfiltermodel.h"
+#include "passwordsmodel.h"
+#include "abbreviations.h"
+
+#include "kdescendantsproxymodel.h"
+
+#include <QDebug>
+
+using namespace PlasmaPass;
+
+PasswordFilterModel::PasswordFilterModel(QObject *parent)
+ : QSortFilterProxyModel(parent)
+ , mFlatModel(new KDescendantsProxyModel(this))
+{
+ mFlatModel->setDisplayAncestorData(false);
+ sort(0); // enable sorting
+}
+
+void PasswordFilterModel::setSourceModel(QAbstractItemModel *sourceModel)
+{
+ mFlatModel->setSourceModel(sourceModel);
+
+ if (!this->sourceModel()) {
+ QSortFilterProxyModel::setSourceModel(mFlatModel);
+ }
+}
+
+QString PasswordFilterModel::filter() const
+{
+ return mFilter;
+}
+
+void PasswordFilterModel::setFilter(const QString &filter)
+{
+ if (mFilter != filter) {
+ mFilter = filter;
+ mParts = filter.splitRef(QLatin1Char('/'), QString::SkipEmptyParts);
+ Q_EMIT filterChanged();
+ mSortingLookup.clear();
+ invalidate();
+ }
+}
+
+QVariant PasswordFilterModel::data(const QModelIndex &index, int role) const
+{
+ if (role == Qt::DisplayRole) {
+ return data(index, PasswordsModel::FullNameRole);
+ }
+
+ return QSortFilterProxyModel::data(index, role);
+}
+
+
+bool PasswordFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
+{
+ const auto src_index = sourceModel()->index(source_row, 0, source_parent);
+ const auto type = static_cast<PasswordsModel::EntryType>(sourceModel()->data(src_index, PasswordsModel::EntryTypeRole).toInt());
+ if (type == PasswordsModel::FolderEntry) {
+ return false;
+ }
+
+ if (mFilter.isEmpty()) {
+ return true;
+ }
+
+ const auto path = sourceModel()->data(src_index, PasswordsModel::FullNameRole).toString();
+
+ const auto weight = matchPathFilter(path.splitRef(QLatin1Char('/')), mParts);
+ if (weight > -1) {
+ mSortingLookup.insert(src_index, weight);
+ return true;
+ }
+
+ return false;
+}
+
+bool PasswordFilterModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
+{
+ const auto weightLeft = mSortingLookup.value(source_left, -1);
+ const auto weightRight = mSortingLookup.value(source_right, -1);
+
+ if (weightLeft == weightRight) {
+ const auto nameLeft = source_left.data(PasswordsModel::FullNameRole).toString();
+ const auto nameRight = source_right.data(PasswordsModel::FullNameRole).toString();
+ return QString::localeAwareCompare(nameLeft, nameRight) < 0;
+ }
+
+ return weightLeft < weightRight;
+}
(DIR) diff --git a/src/passwordfiltermodel.h b/src/passwordfiltermodel.h
t@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 Daniel Vrátil <dvratil@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PASSWORDFILTERMODEL_H_
+#define PASSWORDFILTERMODEL_H_
+
+#include <QSortFilterProxyModel>
+#include <QVector>
+
+class QStringRef;
+class KDescendantsProxyModel;
+
+class PasswordFilterModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
+public:
+ explicit PasswordFilterModel(QObject *parent = nullptr);
+
+ void setSourceModel(QAbstractItemModel *sourceModel) override;
+
+ QString filter() const;
+ void setFilter(const QString &filter);
+
+ QVariant data(const QModelIndex &index, int role) const override;
+
+Q_SIGNALS:
+ void filterChanged();
+
+protected:
+ bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
+ bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
+
+private:
+ KDescendantsProxyModel *mFlatModel = nullptr;
+ QString mFilter;
+ QVector<QStringRef> mParts;
+ mutable QHash<QModelIndex, int> mSortingLookup;
+};
+
+#endif
(DIR) diff --git a/src/passwordprovider.cpp b/src/passwordprovider.cpp
t@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2018 Daniel Vrátil <dvratil@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "passwordprovider.h"
+
+#include <QProcess>
+#include <QStandardPaths>
+#include <QClipboard>
+#include <QGuiApplication>
+
+namespace {
+
+static const auto PasswordTimeout = 45 * 1000;
+static const auto PasswordTimeoutUpdateInterval = 100;
+
+}
+
+PasswordProvider::PasswordProvider(const QString &path, QObject *parent)
+ : QObject(parent)
+{
+ mTimer.setInterval(PasswordTimeoutUpdateInterval);
+ connect(&mTimer, &QTimer::timeout,
+ this, [this]() {
+ mTimeout -= mTimer.interval();
+ Q_EMIT timeoutChanged();
+ if (mTimeout == 0) {
+ expirePassword();
+ }
+ });
+
+ bool isGpg2 = true;
+ auto gpgExe = QStandardPaths::findExecutable(QStringLiteral("gpg2"));
+ if (gpgExe.isEmpty()) {
+ gpgExe = QStandardPaths::findExecutable(QStringLiteral("gpg"));
+ isGpg2 = false;
+ }
+ if (gpgExe.isEmpty()) {
+ qWarning("Failed to find gpg or gpg2 executables");
+ setError(tr("Failed to decrypt password: GPG is not available"));
+ return;
+ }
+
+ QStringList args = { QStringLiteral("-d"),
+ QStringLiteral("--quiet"),
+ QStringLiteral("--yes"),
+ QStringLiteral("--compress-algo=none"),
+ QStringLiteral("--no-encrypt-to"),
+ path };
+ if (isGpg2) {
+ args = QStringList{ QStringLiteral("--batch"), QStringLiteral("--use-agent") } + args;
+ }
+
+ mGpg = new QProcess;
+ connect(mGpg, &QProcess::errorOccurred,
+ this, [this, gpgExe](QProcess::ProcessError state) {
+ if (state == QProcess::FailedToStart) {
+ qWarning("Failed to start %s: %s", qUtf8Printable(gpgExe), qUtf8Printable(mGpg->errorString()));
+ setError(tr("Failed to decrypt password: Failed to start GPG"));
+ }
+ });
+ connect(mGpg, &QProcess::readyReadStandardOutput,
+ this, [this]() {
+ // We only read the first line, second line usually is a username
+ setPassword(QString::fromUtf8(mGpg->readLine()).trimmed());
+ });
+ connect(mGpg, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
+ this, [this]() {
+ const auto err = mGpg->readAllStandardError();
+ if (mPassword.isEmpty()) {
+ if (err.isEmpty()) {
+ setError(tr("Failed to decrypt password"));
+ } else {
+ setError(tr("Failed to decrypt password: %1").arg(QString::fromUtf8(err)));
+ }
+ }
+
+ mGpg->deleteLater();
+ mGpg = nullptr;
+ });
+ mGpg->setProgram(gpgExe);
+ mGpg->setArguments(args);
+ mGpg->start(QIODevice::ReadOnly);
+}
+
+PasswordProvider::~PasswordProvider()
+{
+ if (mGpg) {
+ mGpg->terminate();
+ delete mGpg;
+ }
+}
+
+bool PasswordProvider::isValid() const
+{
+ return !mPassword.isNull();
+}
+
+QString PasswordProvider::password() const
+{
+ return mPassword;
+}
+
+void PasswordProvider::setPassword(const QString &password)
+{
+ qGuiApp->clipboard()->setText(password, QClipboard::Clipboard);
+
+ if (qGuiApp->clipboard()->supportsSelection()) {
+ qGuiApp->clipboard()->setText(password, QClipboard::Selection);
+ }
+
+ mPassword = password;
+ Q_EMIT validChanged();
+ Q_EMIT passwordChanged();
+
+ mTimeout = defaultTimeout();
+ Q_EMIT timeoutChanged();
+ mTimer.start();
+}
+
+void PasswordProvider::expirePassword()
+{
+ removePasswordFromClipboard(mPassword);
+
+ mPassword.clear();
+ mTimer.stop();
+ Q_EMIT validChanged();
+ Q_EMIT passwordChanged();
+
+ // Delete the provider, it's no longer needed
+ deleteLater();
+}
+
+int PasswordProvider::timeout() const
+{
+ return mTimeout;
+}
+
+int PasswordProvider::defaultTimeout() const
+{
+ return PasswordTimeout;
+}
+
+QString PasswordProvider::error() const
+{
+ return mError;
+}
+
+bool PasswordProvider::hasError() const
+{
+ return !mError.isNull();
+}
+
+void PasswordProvider::setError(const QString &error)
+{
+ mError = error;
+ Q_EMIT errorChanged();
+}
+
+
+void PasswordProvider::removePasswordFromClipboard(const QString &password)
+{
+ // Clear the WS clipboard itself
+ const auto clipboard = qGuiApp->clipboard();
+ if (clipboard->text() == password) {
+ clipboard->clear();
+ }
+}
+
(DIR) diff --git a/src/passwordprovider.h b/src/passwordprovider.h
t@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 Daniel Vrátil <dvratil@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PASSWORDPROVIDER_H_
+#define PASSWORDPROVIDER_H_
+
+#include <QObject>
+#include <QTimer>
+
+class QProcess;
+
+class PasswordsModel;
+
+class PasswordProvider : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString password READ password NOTIFY passwordChanged)
+ Q_PROPERTY(bool valid READ isValid NOTIFY validChanged)
+ Q_PROPERTY(int timeout READ timeout NOTIFY timeoutChanged)
+ Q_PROPERTY(int defaultTimeout READ defaultTimeout CONSTANT)
+ Q_PROPERTY(bool hasError READ hasError NOTIFY errorChanged)
+ Q_PROPERTY(QString error READ error NOTIFY errorChanged)
+public:
+ ~PasswordProvider() override;
+
+ QString password() const;
+ bool isValid() const;
+ int timeout() const;
+ int defaultTimeout() const;
+ bool hasError() const;
+ QString error() const;
+
+Q_SIGNALS:
+ void passwordChanged();
+ void validChanged();
+ void timeoutChanged();
+ void errorChanged();
+
+private:
+ void setError(const QString &error);
+ void setPassword(const QString &password);
+ void expirePassword();
+
+ void removePasswordFromClipboard(const QString &password);
+ void clearClipboard();
+
+ friend class PasswordsModel;
+ explicit PasswordProvider(const QString &path, QObject *parent = nullptr);
+
+ QProcess *mGpg = nullptr;
+ QString mPath;
+ QString mPassword;
+ QString mError;
+ QTimer mTimer;
+ int mTimeout = 0;
+};
+
+#endif
(DIR) diff --git a/src/passwordsmodel.cpp b/src/passwordsmodel.cpp
t@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2018 Daniel Vrátil <dvratil@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "passwordsmodel.h"
+#include "passwordprovider.h"
+
+#include <QDir>
+#include <QDebug>
+#include <QPointer>
+
+#define PASSWORD_STORE_DIR "PASSWORD_STORE_DIR"
+
+class PasswordsModel::Node
+{
+public:
+ Node() {}
+
+ Node(const QString &name, PasswordsModel::EntryType type, Node *parent)
+ : name(name), type(type), parent(parent)
+ {
+ if (parent) {
+ parent->children.append(this);
+ }
+ }
+
+ ~Node()
+ {
+ qDeleteAll(children);
+ }
+
+ QString path() const
+ {
+ if (!parent) {
+ return name;
+ } else {
+ QString fileName = name;
+ if (type == PasswordsModel::PasswordEntry) {
+ fileName += QStringLiteral(".gpg");
+ }
+ return parent->path() + QLatin1Char('/') + fileName;
+ }
+ }
+
+ QString fullName() const
+ {
+ if (!mFullName.isNull()) {
+ return mFullName;
+ }
+
+ if (!parent) {
+ return {};
+ }
+ const auto p = parent->fullName();
+ if (p.isEmpty()) {
+ mFullName = name;
+ } else {
+ mFullName = p + QLatin1Char('/') + name;
+ }
+ return mFullName;
+ }
+
+ QString name;
+ PasswordsModel::EntryType type;
+ QPointer<PasswordProvider> provider;
+ Node *parent = nullptr;
+ QVector<Node*> children;
+
+private:
+ mutable QString mFullName;
+};
+
+
+PasswordsModel::PasswordsModel(QObject *parent)
+ : QAbstractItemModel(parent)
+ , mWatcher(this)
+{
+ if (qEnvironmentVariableIsSet(PASSWORD_STORE_DIR)) {
+ mPassStore = QDir(QString::fromUtf8(qgetenv(PASSWORD_STORE_DIR)));
+ } else {
+ mPassStore = QDir(QStringLiteral("%1/.password-store").arg(QDir::homePath()));
+ }
+
+ // FIXME: Try to figure out what has actually changed and update the model
+ // accordingly instead of reseting it
+ connect(&mWatcher, &QFileSystemWatcher::directoryChanged, this, &PasswordsModel::populate);
+
+ populate();
+}
+
+PasswordsModel::~PasswordsModel()
+{
+ delete mRoot;
+}
+
+PasswordsModel::Node *PasswordsModel::node(const QModelIndex& index) const
+{
+ return static_cast<Node*>(index.internalPointer());
+}
+
+QHash<int, QByteArray> PasswordsModel::roleNames() const
+{
+ return { { NameRole, "name" },
+ { EntryTypeRole, "type" },
+ { FullNameRole, "fullName" },
+ { PathRole, "path" },
+ { HasPasswordRole, "hasPassword" },
+ { PasswordRole, "password" } };
+}
+
+int PasswordsModel::rowCount(const QModelIndex &parent) const
+{
+ const auto parentNode = parent.isValid() ? node(parent) : mRoot;
+ return parentNode ? parentNode->children.count() : 0;
+}
+
+int PasswordsModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent)
+ return 1;
+}
+
+QModelIndex PasswordsModel::index(int row, int column, const QModelIndex &parent) const
+{
+ const auto parentNode = parent.isValid() ? node(parent) : mRoot;
+ if (!parentNode || row < 0 || row >= parentNode->children.count() || column != 0) {
+ return {};
+ }
+
+ return createIndex(row, column, parentNode->children.at(row));
+}
+
+QModelIndex PasswordsModel::parent(const QModelIndex &child) const
+{
+ if (!child.isValid()) {
+ return {};
+ }
+
+ const auto childNode = node(child);
+ if (!childNode || !childNode->parent) {
+ return {};
+ }
+ const auto parentNode = childNode->parent;
+ if (parentNode == mRoot) {
+ return {};
+ }
+ return createIndex(parentNode->parent->children.indexOf(parentNode), 0, parentNode);
+}
+
+QVariant PasswordsModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid()) {
+ return {};
+ }
+ const auto node = this->node(index);
+ if (!node) {
+ return {};
+ }
+
+ switch (role) {
+ case Qt::DisplayRole:
+ return node->name;
+ case EntryTypeRole:
+ return node->type;
+ case PathRole:
+ return node->path();
+ case FullNameRole:
+ return node->fullName();
+ case PasswordRole:
+ if (!node->provider) {
+ node->provider = new PasswordProvider(node->path());
+ }
+ return QVariant::fromValue(node->provider.data());
+ case HasPasswordRole:
+ return !node->provider.isNull();
+ }
+
+ return {};
+}
+
+void PasswordsModel::populate()
+{
+ beginResetModel();
+ delete mRoot;
+ mRoot = new Node;
+ mRoot->name = mPassStore.absolutePath();
+ populateDir(mPassStore, mRoot);
+ endResetModel();
+}
+
+void PasswordsModel::populateDir(const QDir& dir, Node *parent)
+{
+ mWatcher.addPath(dir.absolutePath());
+ auto entries = dir.entryInfoList({ QStringLiteral("*.gpg") }, QDir::Files, QDir::NoSort);
+ Q_FOREACH (const auto &entry, entries) {
+ new Node(entry.completeBaseName(), PasswordEntry, parent);
+ }
+ entries = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::NoSort);
+ Q_FOREACH (const auto &entry, entries) {
+ auto node = new Node(entry.fileName(), FolderEntry, parent);
+ populateDir(entry.absoluteFilePath(), node);
+ }
+}
(DIR) diff --git a/src/passwordsmodel.h b/src/passwordsmodel.h
t@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 Daniel Vrátil <dvratil@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PASSWORDSMODEL_H_
+#define PASSWORDSMODEL_H_
+
+#include <QAbstractItemModel>
+#include <QFileSystemWatcher>
+#include <QDir>
+
+class PasswordsModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+ class Node;
+public:
+ enum EntryType {
+ FolderEntry,
+ PasswordEntry
+ };
+ Q_ENUM(EntryType)
+
+ enum Roles {
+ NameRole = Qt::DisplayRole,
+ EntryTypeRole = Qt::UserRole,
+ FullNameRole,
+ PathRole,
+ PasswordRole,
+ HasPasswordRole,
+ };
+
+ explicit PasswordsModel(QObject *parent = nullptr);
+ ~PasswordsModel() override;
+
+ QHash<int, QByteArray> roleNames() const override;
+
+ int rowCount(const QModelIndex & parent) const override;
+ int columnCount(const QModelIndex & parent) const override;
+
+ QModelIndex index(int row, int column, const QModelIndex & parent) const override;
+ QModelIndex parent(const QModelIndex & child) const override;
+
+ QVariant data(const QModelIndex &index, int role) const override;
+
+private:
+ void populate();
+ void populateDir(const QDir &dir, Node *parent);
+
+ Node *node(const QModelIndex &index) const;
+
+ QFileSystemWatcher mWatcher;
+ QDir mPassStore;
+
+ Node *mRoot = nullptr;
+};
+
+#endif
(DIR) diff --git a/src/passwordsortproxymodel.cpp b/src/passwordsortproxymodel.cpp
t@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 Daniel Vrátil <dvratil@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "passwordsortproxymodel.h"
+#include "passwordsmodel.h"
+
+#include <QDebug>
+
+PasswordSortProxyModel::PasswordSortProxyModel(QObject *parent)
+ : QSortFilterProxyModel(parent)
+{
+ sort(0); // enable sorting
+}
+
+bool PasswordSortProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
+{
+ const auto typeLeft = static_cast<PasswordsModel::EntryType>(source_left.data(PasswordsModel::EntryTypeRole).toInt());
+ const auto typeRight = static_cast<PasswordsModel::EntryType>(source_right.data(PasswordsModel::EntryTypeRole).toInt());
+
+ // Folders first
+ if (typeLeft != typeRight) {
+ return typeLeft == PasswordsModel::FolderEntry;
+ }
+
+ return QSortFilterProxyModel::lessThan(source_left, source_right);
+}
(DIR) diff --git a/src/passwordsortproxymodel.h b/src/passwordsortproxymodel.h
t@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 Daniel Vrátil <dvratil@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PASSWORDSORTPROXYMODEL_H_
+#define PASSWORDSORTPROXYMODEL_H_
+
+#include <QSortFilterProxyModel>
+
+class PasswordSortProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ explicit PasswordSortProxyModel(QObject *parent = nullptr);
+
+protected:
+ bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
+};
+
+#endif
(DIR) diff --git a/translations/passilic.ts b/translations/harbour-passilic.ts