sailfish-safe

Sailfish frontend for safe(1)
git clone git://git.z3bra.org/sailfish-safe.git
Log | Files | Refs | README | LICENSE

commit 6e63350eb5773919bf0ef0cc0c985ef70f3735dc
parent c0c27d5aa421cde6650c4146a3bc405773d88cfc
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+++
A3rdparty/kitemmodels | 1+
Rpassilic.desktop -> harbour-passilic.desktop | 0
Aharbour-passilic.pro | 43+++++++++++++++++++++++++++++++++++++++++++
Aharbour-passilic.pro.user.15149e1 | 803+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ricons/108x108/passilic.png -> icons/108x108/harbour-passilic.png | 0
Ricons/128x128/passilic.png -> icons/128x128/harbour-passilic.png | 0
Ricons/172x172/passilic.png -> icons/172x172/harbour-passilic.png | 0
Ricons/86x86/passilic.png -> icons/86x86/harbour-passilic.png | 0
Dpassilic.pro | 40----------------------------------------
Aqml/harbour-passilic.qml | 48++++++++++++++++++++++++++++++++++++++++++++++++
Dqml/pages/FirstPage.qml | 43-------------------------------------------
Aqml/pages/PasswordListPage.qml | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dqml/pages/SecondPage.qml | 30------------------------------
Dqml/passilic.qml | 10----------
Rrpm/passilic.changes.in -> rpm/harbour-passilic.changes.in | 0
Rrpm/passilic.changes.run.in -> rpm/harbour-passilic.changes.run.in | 0
Arpm/harbour-passilic.spec | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arpm/harbour-passilic.yaml | 45+++++++++++++++++++++++++++++++++++++++++++++
Drpm/passilic.yaml | 45---------------------------------------------
Asrc/abbreviations.cpp | 200+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/abbreviations.h | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/main.cpp | 44++++++++++++++++++++++++++++++++++++++++++++
Dsrc/passilic.cpp | 20--------------------
Asrc/passwordfiltermodel.cpp | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/passwordfiltermodel.h | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/passwordprovider.cpp | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/passwordprovider.h | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/passwordsmodel.cpp | 218+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/passwordsmodel.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/passwordsortproxymodel.cpp | 42++++++++++++++++++++++++++++++++++++++++++
Asrc/passwordsortproxymodel.h | 35+++++++++++++++++++++++++++++++++++
Rtranslations/passilic.ts -> translations/harbour-passilic.ts | 0
33 files changed, 2172 insertions(+), 188 deletions(-)

diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "3rdparty/kitemmodels"] + path = 3rdparty/kitemmodels + url = git://anongit.kde.org/kitemmodels.git diff --git a/3rdparty/kitemmodels b/3rdparty/kitemmodels @@ -0,0 +1 @@ +Subproject commit 18244542c2bc895dfd1615468eb917aae06519ab diff --git a/passilic.desktop b/harbour-passilic.desktop diff --git a/harbour-passilic.pro b/harbour-passilic.pro @@ -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 diff --git a/harbour-passilic.pro.user.15149e1 b/harbour-passilic.pro.user.15149e1 @@ -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> diff --git a/icons/108x108/passilic.png b/icons/108x108/harbour-passilic.png Binary files differ. diff --git a/icons/128x128/passilic.png b/icons/128x128/harbour-passilic.png Binary files differ. diff --git a/icons/172x172/passilic.png b/icons/172x172/harbour-passilic.png Binary files differ. diff --git a/icons/86x86/passilic.png b/icons/86x86/harbour-passilic.png Binary files differ. diff --git a/passilic.pro b/passilic.pro @@ -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 diff --git a/qml/harbour-passilic.qml b/qml/harbour-passilic.qml @@ -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)); + } +} diff --git a/qml/pages/FirstPage.qml b/qml/pages/FirstPage.qml @@ -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 - } - } - } -} diff --git a/qml/pages/PasswordListPage.qml b/qml/pages/PasswordListPage.qml @@ -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"); + } + } + } + } + } +} diff --git a/qml/pages/SecondPage.qml b/qml/pages/SecondPage.qml @@ -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 {} - } -} diff --git a/qml/passilic.qml b/qml/passilic.qml @@ -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 -} diff --git a/rpm/passilic.changes.in b/rpm/harbour-passilic.changes.in diff --git a/rpm/passilic.changes.run.in b/rpm/harbour-passilic.changes.run.in diff --git a/rpm/harbour-passilic.spec b/rpm/harbour-passilic.spec @@ -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 diff --git a/rpm/harbour-passilic.yaml b/rpm/harbour-passilic.yaml @@ -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 diff --git a/rpm/passilic.yaml b/rpm/passilic.yaml @@ -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 diff --git a/src/abbreviations.cpp b/src/abbreviations.cpp @@ -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; + } +} diff --git a/src/abbreviations.h b/src/abbreviations.h @@ -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 diff --git a/src/main.cpp b/src/main.cpp @@ -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(); +} diff --git a/src/passilic.cpp b/src/passilic.cpp @@ -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); -} diff --git a/src/passwordfiltermodel.cpp b/src/passwordfiltermodel.cpp @@ -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; +} diff --git a/src/passwordfiltermodel.h b/src/passwordfiltermodel.h @@ -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 diff --git a/src/passwordprovider.cpp b/src/passwordprovider.cpp @@ -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(); + } +} + diff --git a/src/passwordprovider.h b/src/passwordprovider.h @@ -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 diff --git a/src/passwordsmodel.cpp b/src/passwordsmodel.cpp @@ -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); + } +} diff --git a/src/passwordsmodel.h b/src/passwordsmodel.h @@ -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 diff --git a/src/passwordsortproxymodel.cpp b/src/passwordsortproxymodel.cpp @@ -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); +} diff --git a/src/passwordsortproxymodel.h b/src/passwordsortproxymodel.h @@ -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 diff --git a/translations/passilic.ts b/translations/harbour-passilic.ts