Compare commits

...

10 commits

Author SHA1 Message Date
Jan-Martin Raemer
1f12d93300 Make LenaPi usable on Android devices
- Add app icon
- prevend android device from shutting down cpu while playing music
- fix scaling bug
- fix energy saver for RasPi by reconnecting to music player
- minor refactorings and renaming
2022-07-16 12:19:57 +02:00
Jan-Martin Raemer
851b83a53a added todos 2022-06-03 22:09:54 +02:00
Jan-Martin Raemer
bcdf3d94f2 Scale all QML elements according to the current display size 2022-06-03 22:07:50 +02:00
Jan-Martin Raemer
9e7a55fc20 AppSettings for android
added debug output for Navigation as debugger does not work for Android
yet
2022-06-01 20:31:47 +02:00
Anika Raemer
75308b4423 fix previous button, single point of definition 2021-10-13 15:06:09 +02:00
Anika Raemer
a483a380d6 reset playlist to first track on stop 2021-10-13 14:13:48 +02:00
Anika Raemer
39a0356a51 fixed progress 2021-10-13 14:06:43 +02:00
Anika Raemer
2d985ca17d fixed next/previous buttons, simplyfied volume 2021-10-13 13:47:16 +02:00
Anika Raemer
e9a031e6d3 volume control 2021-10-13 13:01:19 +02:00
Anika Raemer
fe7bbed7c1 remove vlc and replace by basic QMediaPlayer 2021-10-12 22:15:06 +02:00
41 changed files with 1550 additions and 753 deletions

5
.gitignore vendored
View file

@ -1,5 +1,4 @@
*.autosave
build-LenaPi-Desktop-Debug
build-LenaPi-RasPi-Debug
build-LenaPi-RasPi-Release
build-LenaPi*
LenaPi/LenaPi.pro.user.4.8-pre1
musik

24
LenaPi/.qmake.stash Normal file
View file

@ -0,0 +1,24 @@
QMAKE_CXX.QT_COMPILER_STDCXX = 201402L
QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 10
QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 2
QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 1
QMAKE_CXX.COMPILER_MACROS = \
QT_COMPILER_STDCXX \
QMAKE_GCC_MAJOR_VERSION \
QMAKE_GCC_MINOR_VERSION \
QMAKE_GCC_PATCH_VERSION
QMAKE_CXX.INCDIRS = \
/usr/arm-linux-gnueabihf/include/c++/10 \
/usr/arm-linux-gnueabihf/include/c++/10/arm-linux-gnueabihf \
/usr/arm-linux-gnueabihf/include/c++/10/backward \
/usr/lib/gcc-cross/arm-linux-gnueabihf/10/include \
/usr/arm-linux-gnueabihf/include \
/usr/include/arm-linux-gnueabihf \
/usr/include
QMAKE_CXX.LIBDIRS = \
/usr/lib/gcc-cross/arm-linux-gnueabihf/10 \
/usr/arm-linux-gnueabihf/lib \
/lib/arm-linux-gnueabihf \
/lib \
/usr/lib/arm-linux-gnueabihf \
/usr/lib

View file

@ -4,16 +4,35 @@
#include <QFileInfo>
#include <QProcess>
#include <iostream>
EnergySaver::~EnergySaver()
{
#ifdef ANDROID
releaseAndroidLock();
#endif
}
void EnergySaver::init()
{
auto saver = instance();
saver->mIsAutoShutDownEnabled = false;
#ifdef ANDROID
saver->initAdroidLocks();
#endif
}
void EnergySaver::init(int interval, const QString &shutdownScript)
{
auto saver = instance();
saver->mIsAutoShutDownEnabled = true;
QFileInfo script(shutdownScript);
if(script.exists()){
auto saver = instance();
saver->setShutdownScript(shutdownScript);
saver->initTimer(interval*1000);
saver->restartTimer();
}
#ifdef ANDROID
saver->initAdroidLocks();
#endif
}
@ -21,15 +40,32 @@ void EnergySaver::init(int interval, const QString &shutdownScript)
EnergySaver *EnergySaver::instance()
{
static EnergySaver* inst;
if (inst == nullptr)
if (!inst)
{
inst = new EnergySaver();
}
return inst;
}
void EnergySaver::deactivate()
{
mIsActive = false;
mTimer.stop();
setAndroidLock();
}
void EnergySaver::activate()
{
mIsActive = true;
restartTimer();
releaseAndroidLock();
}
void EnergySaver::restartTimer()
{
// Energy saver is currently deactivated -> Do NOT start timer
if(!mIsActive) return;
if(mTimer.isActive()){
mTimer.stop();
}
@ -49,9 +85,59 @@ void EnergySaver::setShutdownScript(const QString &shutdownScript)
mShutdownScript = shutdownScript;
}
void EnergySaver::initAdroidLocks()
{
#ifdef ANDROID
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if ( activity.isValid() )
{
QAndroidJniObject serviceName = QAndroidJniObject::getStaticObjectField<jstring>("android/content/Context","POWER_SERVICE");
if ( serviceName.isValid() )
{
QAndroidJniObject powerMgr = activity.callObjectMethod("getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;",serviceName.object<jobject>());
if ( powerMgr.isValid() )
{
jint levelAndFlags = QAndroidJniObject::getStaticField<jint>("android/os/PowerManager","SCREEN_DIM_WAKE_LOCK");
QAndroidJniObject tag = QAndroidJniObject::fromString( "My Tag" );
m_wakeLock = powerMgr.callObjectMethod("newWakeLock", "(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;", levelAndFlags,tag.object<jstring>());
}
}
}
#endif
}
void EnergySaver::setAndroidLock()
{
#ifdef ANDROID
if ( m_wakeLock.isValid() )
{
m_wakeLock.callMethod<void>("acquire", "()V");
qDebug() << "Locked device, can't go to standby anymore";
}
else
{
assert( false );
}
#endif
}
void EnergySaver::releaseAndroidLock()
{
#ifdef ANDROID
if ( m_wakeLock.isValid() )
{
m_wakeLock.callMethod<void>("release", "()V");
qDebug() << "Unlocked device, can now go to standby";
}
#endif
}
void EnergySaver::onTimeout()
{
if(!mIsAutoShutDownEnabled) return;
std::cout << "Shutting down.";
#ifndef _DEBUG
QProcess p;

View file

@ -4,27 +4,39 @@
#include <QObject>
#include <QTimer>
#ifdef ANDROID
#include <qandroidjniobject.h>
#endif
/**
* @brief Class handling energy saving options.
*
* Shut down device if no mouse input is detected and music player
* has not been active or a certain time interval.
* On Android devices, it locks the cpu shutdown while active. On other devices, it
* will shut down device on timeout if the options are set accordingly and a shutdown script
* is provided.
*
* @todo For now this does only work for Lena's RasPi, where the
* shutdown script is positioned in a ceratin hardcoded path.
* Enable/disable energy saving option, timeout and path of
* shutdown script via config
* In the context of the LenaPi application, it will prevent cpu shutdown on android devices while playing
* music. On other devices, it will shutdown the device if no music has been playing and no mouse input was
* detected for a certain time intervall.
*/
class EnergySaver : public QObject
{
Q_OBJECT
protected:
explicit EnergySaver(QObject *parent = nullptr) : QObject(parent) {}
using QObject::QObject;
public:
~EnergySaver();
/**
* @brief Create instance if necessary. The instance will have auto shutdown disabeld.
*
* Used to prevent sleep on android devices.
*/
static void init();
/**
* @brief Create instance if necessary, configure it and start timer.
* @param enabledAutoShutdown Defines whether device will shutdown on inactivity using shutdownScript
* @param interval Timer interval in seconds
* @param shutdownScript Path to shutdown script file
* @see EnergySaver::instance
@ -43,7 +55,19 @@ public:
public slots:
/**
* @brief Restart shutdown timer, e.g. because of music player activiti
* @brief Deactivate energy saver, e.g., as music is currently playing
*
* Sets locks on adroid devics and stops shutdown-timer.
*/
void deactivate();
/**
* @brief Active energy saver
*
* Releases locks on android devices and restarts shutdown-timer if shutdown option is set.
*/
void activate();
/**
* @brief Restart shutdown timer, e.g. because of music player activity
*/
void restartTimer();
@ -54,8 +78,31 @@ private:
*/
void initTimer(int interval);
void setShutdownScript(const QString& shutdownScript);
/**
* @brief Initializes locking or Android devices
*/
void initAdroidLocks();
/**
* @brief Sets locks on Android devices to prevent sleep.
*
* Used to prevent cpu sleep as otherwise music will stop.
*/
void setAndroidLock();
/**
* @brief Releases locks on Android devices to allow the device's cpu to go into sleep mode.
*/
void releaseAndroidLock();
QTimer mTimer;
QString mShutdownScript;
bool mIsActive{false};
bool mIsAutoShutDownEnabled{false};
#ifdef ANDROID
/**
* @brief Prevent energy saving for Android devices
*/
QAndroidJniObject m_wakeLock;
#endif
private slots:
/**
@ -63,6 +110,7 @@ private slots:
*/
void onTimeout();
};
#endif // ENERGYSAVER_H

View file

@ -1,16 +1,20 @@
TEMPLATE = app
QT += qml quick
linux:android {
QT += androidextras
ANDROID_PERMISSIONS += android.permission.WAKE_LOCK
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-files
QMAKE_CXXFLAGS += -DANDROID=1
}
QT += qml quick multimedia
CONFIG += c++11
LIBS += -lVLCQtCore -lVLCQtQml
LIBS +=
SOURCES += main.cpp \
controllers/MusicPlayer.cpp \
controllers/StyleHandling.cpp \
models/NavigationListModel.cpp \
models/NavigationItemModel.cpp \
controllers/NavigationController.cpp \
models/UiStateModel.cpp \
controllers/MusicController.cpp \
models/MusicModel.cpp \
MouseEventSpy.cpp \
EnergySaver.cpp \
controllers/SettingsHandler.cpp
@ -41,14 +45,18 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
controllers/MusicPlayer.h \
controllers/StyleHandling.h \
models/MusicPlayer.h \
models/NavigationListModel.h \
models/NavigationItemModel.h \
controllers/NavigationController.h \
models/UiStateModel.h \
controllers/MusicController.h \
models/MusicModel.h \
MouseEventSpy.h \
EnergySaver.h \
controllers/SettingsHandler.h
INCLUDEPATH+=/usr/local/include
DISTFILES += \
android-files/AndroidManifest.xml

View file

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.8.2, 2021-09-26T21:51:47. -->
<!-- Written by QtCreator 7.0.1, 2022-07-15T15:40:08. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{76cb87c9-a04b-479b-87ff-1b3ddab073a7}</value>
<value type="QByteArray">{baaf8c13-9b67-4e08-b264-88275a728682}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
<value type="qlonglong">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
@ -28,7 +28,7 @@
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="qlonglong" 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>
@ -37,6 +37,7 @@
<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.PreferSingleLineComments">false</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>
@ -45,282 +46,703 @@
<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="bool" key="EditorConfiguration.UseIndenter">false</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="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.Questionable</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">4</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{f9938f31-357c-4785-aa6e-21a3feac2ebf}</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>
<value type="QString" key="DeviceType">GenericLinuxOsType</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">armhf/raspi 10.0.1.146</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">armhf/raspi 10.0.1.146</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{9f02fab2-7f72-4b24-bbd8-dbe33e863260}</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/araemer/source/LenaPi/build-LenaPi-Desktop-Debug</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-Debug</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-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">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>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</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.BuildTargets"/>
<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>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</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">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.BuildTargets"/>
<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>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</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.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">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"></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">/home/ar/source/LenaPi/build-LenaPi-Desktop-Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-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">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>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</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.BuildTargets"/>
<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>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</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">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.BuildTargets"/>
<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>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</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.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">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"></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">/home/ar/source/LenaPi/build-LenaPi-Desktop-Profile</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-Profile</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-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">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>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</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.BuildTargets"/>
<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>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</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">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.BuildTargets"/>
<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>
<value type="bool" key="Qt4ProjectManager.MakeStep.OverrideMakeflags">false</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</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.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">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"></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>
<value type="int" key="SeparateDebugInfo">0</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.CheckForFreeDiskSpaceStep</value>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
<value type="QString" key="RemoteLinux.CheckForFreeDiskSpaceStep.PathToCheck">/</value>
<value type="qlonglong" key="RemoteLinux.CheckForFreeDiskSpaceStep.RequiredSpace">5242880</value>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.KillAppStep</value>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.RsyncDeployStep</value>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
<value type="QString" key="RemoteLinux.RsyncDeployStep.Flags">-av</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</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 locally</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">DeployToGenericLinux</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<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.Perf.Settings.UseGlobalSettings">true</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>
<value type="QString">0</value>
<value type="QString">1</value>
<value type="QString">2</value>
<value type="QString">3</value>
<value type="QString">4</value>
<value type="QString">5</value>
<value type="QString">6</value>
<value type="QString">7</value>
<value type="QString">8</value>
<value type="QString">9</value>
<value type="QString">10</value>
<value type="QString">11</value>
<value type="QString">12</value>
<value type="QString">13</value>
<value type="QString">14</value>
</valuelist>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">LenaPi</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">LenaPi2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/ar/source/LenaPi/LenaPi/LenaPi.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">LenaPi.pro</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="QString">0</value>
<value type="QString">1</value>
<value type="QString">2</value>
<value type="QString">3</value>
<value type="QString">4</value>
<value type="QString">5</value>
<value type="QString">6</value>
<value type="QString">7</value>
<value type="QString">8</value>
<value type="QString">9</value>
<value type="QString">10</value>
<value type="QString">11</value>
<value type="QString">12</value>
<value type="QString">13</value>
<value type="QString">14</value>
</valuelist>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">1</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.CustomRunConfig</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.X11Forwarding">:0.0</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.1</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Android.Device.Type</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Android Qt 5.15.2 (android) Clang Multi-Abi</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Android Qt 5.15.2 (android) Clang Multi-Abi</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ec9ac26e-ce2e-4aaf-b544-ccaec5b0b918}</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-Android_Qt_5_15_2_android_Clang_Multi_Abi-Debug</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-Android_Qt_5_15_2_android_Clang_Multi_Abi-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.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis">
<value type="QString">armeabi-v7a</value>
</valuelist>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</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.DisplayName">Copy application data</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidPackageInstallationStep</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.3">
<value type="QString" key="BuildTargetSdk">android-31</value>
<value type="QString" key="KeystoreLocation"></value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build Android APK</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.AndroidBuildApkStep</value>
<value type="bool" key="VerboseOutput">false</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">4</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</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.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</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.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<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="int" key="RunSystemFunction">0</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-Android_Qt_5_15_2_android_Clang_Multi_Abi-Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-Android_Qt_5_15_2_android_Clang_Multi_Abi-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.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis">
<value type="QString">armeabi-v7a</value>
</valuelist>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</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.DisplayName">Copy application data</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidPackageInstallationStep</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.3">
<value type="QString" key="BuildTargetSdk">android-31</value>
<value type="QString" key="KeystoreLocation"></value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build Android APK</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.AndroidBuildApkStep</value>
<value type="bool" key="VerboseOutput">false</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">4</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</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.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</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.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<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="int" key="QtQuickCompiler">0</value>
<value type="int" key="RunSystemFunction">0</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-Android_Qt_5_15_2_android_Clang_Multi_Abi-Profile</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-Android_Qt_5_15_2_android_Clang_Multi_Abi-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.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</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.DisplayName">Copy application data</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidPackageInstallationStep</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.3">
<value type="QString" key="BuildTargetSdk">android-31</value>
<value type="QString" key="KeystoreLocation"></value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build Android APK</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.AndroidBuildApkStep</value>
<value type="bool" key="VerboseOutput">false</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">4</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</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.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</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.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<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="int" key="QtQuickCompiler">0</value>
<value type="int" key="RunSystemFunction">0</value>
<value type="int" key="SeparateDebugInfo">0</value>
</valuemap>
<value type="qlonglong" 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.DisplayName">&lt;b&gt;Deploy to Android device&lt;/b&gt;</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidDeployQtStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidDeployConfiguration2</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings">
<valuelist type="QVariantList" key="AndroidDeviceAbis">
<value type="QString">arm64-v8a</value>
<value type="QString">armeabi-v7a</value>
<value type="QString">armeabi</value>
</valuelist>
<value type="QString" key="AndroidDeviceSerialNumber">58009fc2</value>
<value type="int" key="AndroidVersion.ApiLevel">28</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Android.PostStartShellCmdListKey">
<value type="QString"></value>
</valuelist>
<valuelist type="QVariantList" key="Android.PreStartShellCmdListKey">
<value type="QString"></value>
</valuelist>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">0</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidRunConfiguration:/home/jmr/privat/src/LenaPi/LenaPi/LenaPi.pro</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/jmr/privat/src/LenaPi/LenaPi/LenaPi.pro</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.2</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{73308c85-3272-4fe8-8c9f-0eb72285644f}</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-desktop-Debug</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-desktop-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.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</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.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</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.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<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="int" key="RunSystemFunction">0</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-desktop-Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-desktop-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.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</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.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</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.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<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="int" key="RunSystemFunction">0</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-desktop-Profile</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-desktop-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.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</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.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</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.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<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="int" key="RunSystemFunction">0</value>
<value type="int" key="SeparateDebugInfo">0</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/jmr/privat/src/LenaPi/LenaPi/LenaPi.pro</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/jmr/privat/src/LenaPi/LenaPi/LenaPi.pro</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">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>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/araemer/source/LenaPi/build-LenaPi-Desktop-Debug</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
<value type="qlonglong">3</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">20</value>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">20</value>
<value type="int">22</value>
</data>
</qtcreator>

View file

@ -1,51 +1,52 @@
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import QtQuick.Controls.Styles 1.4
Item {
ColumnLayout {
id: container
property var model
// manually set height
Component.onCompleted: height = childrenRect.height
spacing: StyleSpacings.tinySpacing
Label{
anchors.left: progress.left
anchors.bottom: progress.top
font.pointSize: 9
color: "grey"
text: model.pMediaTitle
}
RowLayout{
Label{
font.pointSize: 9
color: "grey"
text: model.pMediaTitle
}
Item{
// spacer
Layout.fillWidth: true
}
Label{
anchors.right: progress.right
anchors.bottom: progress.top
font.pointSize: 9
color: "grey"
text: model.pTime + " / " + model.pMediaLength
Label{
font.pointSize: 9
color: "grey"
text: model.pTime + " / " + model.pMediaLength
}
}
ProgressBar{
id: progress
anchors.top: parent.top
anchors.left: parent.left
Layout.fillWidth: true
value: model.pProgress
style:ProgressBarStyle {
background: Rectangle {
radius: 5
radius: StyleSizes.progressBackgroundRadius
color: "white"
border.color: "grey"
border.width: 1
border.width: StyleSizes.progressBackgroundBorderWidth
implicitWidth: container.width
implicitHeight: 10
implicitHeight: StyleSizes.progressBackgroundDefaultHeight
}
progress: Rectangle {
color: "blue"
border.color: "blue"
radius: 5
implicitHeight: 8
radius: StyleSizes.progressBackgroundRadius
implicitHeight: StyleSizes.progressBarDefaultHeight
}
}
}

View file

@ -12,7 +12,7 @@ void MouseEventSpy::init()
MouseEventSpy* MouseEventSpy::instance()
{
static MouseEventSpy* inst;
if (inst == nullptr)
if (!inst)
{
inst = new MouseEventSpy();
QGuiApplication* app = qGuiApp;

View file

@ -5,7 +5,7 @@ import QtGraphicalEffects 1.0
Item{
id: container
property int margins: 20
property int margins: StyleMargins.defaultMargin
RoundImageButton{
id: backNavigation
@ -43,9 +43,9 @@ Item{
Image{
id: cover
anchors.centerIn: parent
height: parent.height-10
height: parent.height-StyleMargins.smallMargin
width: height
source: musicModel.pCurrentItem.pImageSource
source: musicModel.pCoverImageSource
fillMode: Image.PreserveAspectCrop
layer.enabled: true
layer.effect: OpacityMask{
@ -64,12 +64,9 @@ Item{
margins: container.margins
topMargin: closeAppButton.visible ? 2*container.margins : container.margins
}
from: 34 // we cannot hear anything if lower than 35%
to: 100
stepSize: 1
value: musicModel.pAudioVolume
value: musicModel.volume
onValueChanged: {
musicModel.pAudioVolume = value;
musicModel.volume = value;
}
}
PlayerControlPannel {

View file

@ -6,24 +6,24 @@ ScrollView{
style: ScrollViewStyle{
transientScrollBars: true
handle: Item {
implicitWidth: 16
implicitHeight: 8
implicitWidth: StyleSizes.scrollHandleWidth
implicitHeight: StyleSizes.scrollHandleHeight
Rectangle {
color: "blue"
border.color: "black"
radius: height/2
anchors.fill: parent
anchors.topMargin: 1
anchors.leftMargin: 1
anchors.rightMargin: 1
anchors.bottomMargin: 1
anchors.topMargin: StyleMargins.scrollHandleMargin
anchors.leftMargin: StyleMargins.scrollHandleMargin
anchors.rightMargin: StyleMargins.scrollHandleMargin
anchors.bottomMargin: StyleMargins.scrollHandleMargin
}
}
scrollBarBackground: Rectangle{
color: "transparent"
border.color: "grey"
border.width: 1
height: 8
border.width: StyleSizes.scrollHandleBorderWidth
height: StyleSizes.scrollHandleHeight
radius: height/2
}
decrementControl: Item{}

View file

@ -1,11 +1,12 @@
import QtQuick 2.0
import QtQuick.Controls 2.4
/**
* @brief Navigation view containing list view displaying artists or genres and albums
*/
Item {
id: container
property int margins: 20
property int margins: StyleMargins.defaultMargin
RoundImageButton{
id: back
@ -35,21 +36,27 @@ Item {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
height: 210
height: StyleSizes.navigationListHeight
color: "#99ffffff"
Label{
text: debug.pDebugOutput
anchors.centerIn: parent
visible: text !== ""
}
ListView{
id: circleList
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: 20
anchors.margins: StyleMargins.defaultMargin
height: parent.height - 40
height: parent.height - 2*StyleMargins.defaultMargin
model: navigationList.pModelItems
spacing: 20
spacing: StyleSpacings.defaultSpacing
orientation: ListView.Horizontal
delegate: NavigationListDelegate{
id: delegate

View file

@ -14,11 +14,11 @@ ItemDelegate{
property alias imageSource: contentImage.source
padding: 5
padding: StylePaddings.defaultPadding
background: Rectangle{
id: background
implicitWidth: 150
implicitWidth: StyleSizes.navigationDelegateDefaultSize
implicitHeight: implicitWidth
radius: container.isCircleDelegate ? height/2 : 0
color: "blue"
@ -26,7 +26,7 @@ ItemDelegate{
id: contentImage
source: "qrc:/default_image"
anchors.fill: parent
anchors.margins: 5
anchors.margins: StyleMargins.tinyMargin
fillMode: Image.PreserveAspectCrop
layer.enabled: true

View file

@ -1,62 +1,58 @@
import QtQuick 2.0
import QtQuick.Layouts 1.3
Item {
RowLayout{
id: container
property var model
property var spacing: 20
Row{
id: buttons
anchors.centerIn: parent
spacing: container.spacing
property var spacing: StyleSpacings.defaultSpacing
RoundImageButton{
id: previous
anchors.verticalCenter: parent.verticalCenter
RoundImageButton{
id: previous
Layout.alignment: Qt.AlignVCenter
diameter: 60
imageSource: "qrc:/icon_previous"
diameter: StyleSizes.smallPlayerButtonSize //60
imageSource: "qrc:/icon_previous"
enabled: model.pHasPrevious
enabled: model.pHasPrevious
onClicked:{
model.playPrevious();
}
onClicked:{
model.playPrevious();
}
RoundImageButton{
id: playPause
anchors.verticalCenter: parent.verticalCenter
diameter: 80
imageSource: model.pIsPlaying ? "qrc:/icon_pause" : "qrc:/icon_play"
}
RoundImageButton{
id: playPause
Layout.alignment: Qt.AlignVCenter
diameter: StyleSizes.largePlayerButtonSize
imageSource: model.pIsPlaying ? "qrc:/icon_pause" : "qrc:/icon_play"
onClicked:{
model.playPause();
}
onClicked:{
model.playPause();
}
RoundImageButton{
id: stop
anchors.verticalCenter: parent.verticalCenter
}
RoundImageButton{
id: stop
Layout.alignment: Qt.AlignVCenter
diameter: 60
imageSource: "qrc:/icon_stop"
diameter: StyleSizes.smallPlayerButtonSize
imageSource: "qrc:/icon_stop"
enabled: model.pIsPlaying
enabled: model.pIsPlaying
onClicked:{
model.stopMusic();
}
onClicked:{
model.stopMusic();
}
RoundImageButton{
id: next
anchors.verticalCenter: parent.verticalCenter
}
RoundImageButton{
id: next
Layout.alignment: Qt.AlignVCenter
diameter: 60
imageSource: "qrc:/icon_next"
diameter: StyleSizes.smallPlayerButtonSize
imageSource: "qrc:/icon_next"
enabled: model.pHasNext
enabled: model.pHasNext
onClicked:{
model.playNext();
}
onClicked:{
model.playNext();
}
} //Row
}
}

View file

@ -1,4 +1,5 @@
import QtQuick 2.0
import QtQuick.Layouts 1.3
Rectangle {
id: container
@ -6,28 +7,29 @@ Rectangle {
property int margins
color: "#99ffffff"
height: 140
height: content.height + 2* margins //StyleSizes.playerControlPanelHeight
MediaProgress{
id: progress
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: container.margins
model: container.model
// might require height for labels to be shown on RasPi (Qt 5.10)
//2019-04-04: defined in MediaProgress.qml -> test on rasPi
}
PlayerButtons{
id: buttons
ColumnLayout{
id: content
spacing: StyleSpacings.smallSpacing
anchors.margins: container.margins
anchors.left: parent.left
anchors.right: parent.right
anchors.top: progress.bottom
anchors.bottom: parent.bottom
model: container.model
spacing: 20
MediaProgress{
id: progress
model: container.model
}
PlayerButtons{
id: buttons
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.fillHeight: true
model: container.model
spacing: StyleSpacings.defaultSpacing
}
}
}

View file

@ -8,7 +8,7 @@ Button {
id: container
property alias imageSource: image.source
// default button diameter -> default width, readonly
readonly property int defaultDiameter: 65
readonly property int defaultDiameter: StyleSizes.roundButtonDefaultSize
// button diameter -> width
property int diameter: defaultDiameter
// diameter of content image -> width
@ -16,7 +16,7 @@ Button {
background: Rectangle{
border.width: 2
border.width: StyleSizes.roundButtonBorderWidth
border.color: "grey"
color: "white"

View file

@ -7,7 +7,7 @@ ColumnLayout {
property alias to: slider.to
property alias stepSize: slider.stepSize
property alias value: slider.value
spacing: 5
spacing: StyleSpacings.tinySpacing
RoundImageButton{
id: increaseButton
imageSource: "qrc:///icon_increase_volume"
@ -18,9 +18,9 @@ ColumnLayout {
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
orientation: Qt.Vertical
from: 34 // we cannot hear anything if lower than 35%
from: 0
to: 100
stepSize: 1
stepSize: 2
value: 50
}
RoundImageButton{

View file

@ -0,0 +1,86 @@
<?xml version="1.0"?>
<manifest package="org.qtproject.example.LenaPi" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Remove the comment if you do not require these default permissions. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
Remove the comment if you do not require these default features. -->
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.microphone" android:required="false"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="LenaPi" android:extractNativeLibs="true" android:icon="@drawable/icon">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="LenaPi" android:screenOrientation="landscape" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- Application arguments -->
<!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
<!-- Application arguments -->
<meta-data android:name="android.app.lib_name" android:value="LenaPi"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="1"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="1"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
<meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroidBearer.jar:jar/QtAndroid.jar:jar/QtMultimedia.jar"/>
<meta-data android:name="android.app.static_init_classes" android:value="org.qtproject.qt5.android.multimedia.QtMultimediaUtils"/>
<!-- Used to specify custom system library path to run with local system libs -->
<!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> -->
<!-- Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<meta-data android:value="@string/unsupported_android_version" android:name="android.app.unsupported_android_version"/>
<!-- Messages maps -->
<!-- Splash screen -->
<!-- Orientation-specific (portrait/landscape) data is checked first. If not available for current orientation,
then android.app.splash_screen_drawable. For best results, use together with splash_screen_sticky and
use hideSplashScreen() with a fade-out animation from Qt Android Extras to hide the splash screen when you
are done populating your window with content. -->
<!-- meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/logo_portrait" / -->
<!-- meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/logo_landscape" / -->
<!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
<!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
<!-- Splash screen -->
<!-- Background running -->
<!-- Warning: changing this value to true may cause unexpected crashes if the
application still try to draw after
"applicationStateChanged(Qt::ApplicationSuspended)"
signal is sent! -->
<meta-data android:name="android.app.background_running" android:value="false"/>
<!-- Background running -->
<!-- auto screen scale factor -->
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
<!-- auto screen scale factor -->
<!-- extract android style -->
<!-- available android:values :
* default - In most cases this will be the same as "full", but it can also be something else if needed, e.g., for compatibility reasons
* full - useful QWidget & Quick Controls 1 apps
* minimal - useful for Quick Controls 2 apps, it is much faster than "full"
* none - useful for apps that don't use any of the above Qt modules
-->
<meta-data android:name="android.app.extract_android_style" android:value="default"/>
<!-- extract android style -->
</activity>
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
</application>
<!-- %%INSERT_PERMISSIONS -->
<!-- %%INSERT_FEATURES -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.PERSISTENT_ACTIVITY"/>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View file

@ -1,72 +0,0 @@
#include "MusicController.h"
#include <QDebug>
#include <models/MusicModel.h>
#include <VLCQtCore/MediaPlayer.h>
#include "EnergySaver.h"
MusicController::MusicController(QObject *parent) : QObject(parent)
{
mVlc = new VlcInstance(VlcCommon::args(), this);
mModel = new MusicModel(mVlc, this);
mPlayer = new VlcMediaListPlayer(mVlc);
mVlcAudio = new VlcAudio(mPlayer->mediaPlayer());
connect(mModel, &MusicModel::navigateTo, this, &MusicController::onNavigationRequest);
//connect(mModel, &MusicModel::play, mPlayer, &VlcMediaListPlayer::play);
connect(mModel, &MusicModel::play, [this](){
mVlcAudio->setVolume(mModel->getAudioVolume());
mPlayer->play();
});
connect(mModel, &MusicModel::stop, mPlayer, &VlcMediaListPlayer::stop);
connect(mModel, &MusicModel::previous, mPlayer, &VlcMediaListPlayer::previous);
connect(mModel, &MusicModel::next, mPlayer, &VlcMediaListPlayer::next);
connect(mModel, &MusicModel::pause, mPlayer->mediaPlayer(), &VlcMediaPlayer::pause);
connect(mModel, &MusicModel::audioVolumeChanged, mVlcAudio, &VlcAudio::setVolume);
connect(mPlayer, SIGNAL(nextItemSet(VlcMedia*)), mModel, SLOT(onNextMediaSet(VlcMedia*)));
connect(mPlayer->mediaPlayer(), &VlcMediaPlayer::lengthChanged, mModel, &MusicModel::onLengthChanged);
connect(mPlayer->mediaPlayer(), &VlcMediaPlayer::timeChanged, mModel, &MusicModel::onTimeChanged);
// hand over player signals to energy saver in order to determine player activity.
connect(mPlayer->mediaPlayer(), &VlcMediaPlayer::timeChanged, EnergySaver::instance(), &EnergySaver::restartTimer);
}
MusicController::~MusicController()
{
mPlayer->deleteLater();
mVlcAudio->deleteLater();
}
void MusicController::initPlayer(NavigationItemModel *item)
{
if(item != mModel->getCurrentItem()){
mPlayer->stop();
mModel->init(item);
}
if(!mIsMediaListSet){
mPlayer->setMediaList(mModel->getMedia());
mIsMediaListSet = true;
}
}
void MusicController::setContext(QQmlContext *context)
{
mContext = context;
setContextProperties();
}
void MusicController::setContextProperties()
{
if(!mContext) return;
mContext->setContextProperty("musicModel", mModel);
}
void MusicController::onNavigationRequest(NavigationItemModel *item)
{
if(mModel->isPlaying()) {
mModel->playPause();
}
emit navigateTo(item);
}

View file

@ -1,52 +0,0 @@
#ifndef MUSICCONTROLLER_H
#define MUSICCONTROLLER_H
#include <QObject>
#include <QQmlContext>
#include <models/NavigationItemModel.h>
#include <VLCQtCore/Common.h>
#include <VLCQtCore/Instance.h>
#include <VLCQtCore/MediaListPlayer.h>
#include <VLCQtCore/Audio.h>
class MusicModel;
class MusicController : public QObject
{
Q_OBJECT
signals:
void navigateTo(NavigationItemModel* item);
public:
MusicController(QObject *parent = Q_NULLPTR);
~MusicController();
void initPlayer(NavigationItemModel* item);
void setContext(QQmlContext* context);
private:
void setContextProperties();
QQmlContext* mContext = Q_NULLPTR;
MusicModel* mModel = Q_NULLPTR;
VlcInstance* mVlc = Q_NULLPTR;
VlcMediaListPlayer* mPlayer = Q_NULLPTR;
VlcAudio* mVlcAudio = Q_NULLPTR;
bool mIsMediaListSet = false;
private slots:
/**
* @brief Stop player if necessary and forward signal navigatTo
* @param item target of navigation request
* @see navigateTo(NavigationItemModel* item);
*/
void onNavigationRequest(NavigationItemModel* item);
};
#endif // MUSICCONTROLLER_H

View file

@ -0,0 +1,165 @@
#include "MusicPlayer.h"
#include <QDir>
#include <QMediaPlaylist>
#include <controllers/SettingsHandler.h>
MusicPlayer::MusicPlayer(QObject *parent) : QMediaPlayer(parent)
{
// init audio
/// @todo remove magic number
setVolume(50);
// relay signal to qml
connect(this, &QMediaPlayer::stateChanged, this, &MusicPlayer::isPlayingChanged);
connect(this, &QMediaPlayer::currentMediaChanged, this, [this](const QMediaContent&){
// notify qml to refresh enable state of next and previous button
emit hasNextChanged();
emit hasPreviousChanged();
});
connect(this, &QMediaPlayer::positionChanged, this, [this](qint64){
emit progressChanged();
});
connect(this, &QMediaPlayer::durationChanged, this, [this](qint64){
emit progressChanged();
emit mediaLengthChanged();
});
}
void MusicPlayer::init(NavigationItemModel *item)
{
if(mCurrentItem == item){
return;
}
mCurrentItem = item;
emit coverImageSourceChanged();
clearPlaylist();
readMedia(mCurrentItem->getPath());
}
void MusicPlayer::navigateBack()
{
emit navigateTo(mCurrentItem);
}
void MusicPlayer::playPause()
{
if(isPlaying())
pause();
else
play();
}
void MusicPlayer::stopMusic()
{
if(isPlaying()){
stop();
resetPlaylistToFirstTrack();
}
}
void MusicPlayer::playNext()
{
if(!hasNext()) return; // checks if playlist exists
playlist()->next();
}
void MusicPlayer::playPrevious()
{
if(!hasPrevious()) return; // checks if playlist exists
playlist()->previous();
}
void MusicPlayer::resetPlaylistToFirstTrack()
{
if(!playlist() && !playlist()->isEmpty()) return;
playlist()->setCurrentIndex(0);
}
bool MusicPlayer::isPlaying() const
{
return state() == State::PlayingState;
}
bool MusicPlayer::hasNext() const
{
if(!playlist()) return false;
const auto nextIndex = playlist()->nextIndex();
/* player yields -1 as next index while playing last track
*/
return nextIndex >=0 && nextIndex < playlist()->mediaCount();
}
bool MusicPlayer::hasPrevious() const
{
if(!playlist()) return false;
const auto previousIndex = playlist()->previousIndex();
/* player inits with currentIndex -1 and hence previousIndex = last index
* until started. Yet, previousButton should initially be disabled.
*/
return previousIndex >= 0 && previousIndex < playlist()->currentIndex();
}
double MusicPlayer::getProgress() const
{
if(duration() <= 0 || position() < 0){
return 0.0;
}
return (double)position()/duration();
}
QString MusicPlayer::getMediaTitle() const
{
return metaData("Title").toString();
}
QString MusicPlayer::getMediaDuration() const
{
return millisecondsToString(duration());
}
QString MusicPlayer::getPosition() const
{
return millisecondsToString(position());
}
void MusicPlayer::clearPlaylist()
{
if(playlist()){
playlist()->clear();
}
}
void MusicPlayer::readMedia(const QString& path)
{
auto dir = QDir(path);
if(!dir.exists()) return;
// create playlist if necessary
auto playList = playlist();
if(!playList){
playList = new QMediaPlaylist(this);
setPlaylist(playList);
}
// add audio files to playlist
dir.setNameFilters(SettingsHandler::getAudioFileNameFilters());
auto files = dir.entryInfoList(QDir::Files);
for(auto file:files){
auto fileName = file.absoluteFilePath();
auto fileUrl = QUrl::fromLocalFile(fileName);
playList->addMedia(QMediaContent(fileUrl));
}
}
QString MusicPlayer::millisecondsToString(int timeInMilliseconds) const
{
int seconds = timeInMilliseconds/1000; // ms to secons
int minutes = seconds/60; //seconds to minutes
seconds %= 60; // seconds remaining after subtracting minutes
// format according to [M]M:ss
// at leading zero to seconds if necessary
QString secStr = (seconds < 10) ? "0"+QString::number(seconds) : QString::number(seconds);
return QString::number(minutes) + ":" + secStr;
}

View file

@ -0,0 +1,143 @@
#ifndef MUSICPLAYER_H
#define MUSICPLAYER_H
#include <QObject>
#include <QMediaPlayer>
#include <models/NavigationItemModel.h>
/**
* @brief MusicPlayer providing interface to QML and Navigation.
*
* Adds media from directory referenced by the current navigation item to
* playlist and provides interface to QML MusicPlayer.
*/
class MusicPlayer : public QMediaPlayer
{
Q_OBJECT
Q_PROPERTY(QUrl pCoverImageSource READ getCoverImageSource NOTIFY coverImageSourceChanged)
Q_PROPERTY(bool pHasNext READ hasNext NOTIFY hasNextChanged)
Q_PROPERTY(bool pHasPrevious READ hasPrevious NOTIFY hasPreviousChanged)
Q_PROPERTY(bool pIsPlaying READ isPlaying NOTIFY isPlayingChanged)
Q_PROPERTY(double pProgress READ getProgress NOTIFY progressChanged)
Q_PROPERTY(QString pMediaLength READ getMediaDuration NOTIFY mediaLengthChanged)
Q_PROPERTY(QString pTime READ getPosition NOTIFY progressChanged)
Q_PROPERTY(QString pMediaTitle READ getMediaTitle NOTIFY metaDataChanged)
signals:
void navigateTo(NavigationItemModel *item);
void coverImageSourceChanged();
void hasPreviousChanged();
void hasNextChanged();
void isPlayingChanged();
void progressChanged();
void mediaLengthChanged();
public:
MusicPlayer(QObject *parent = Q_NULLPTR);
~MusicPlayer() =default;
/**
* @brief Init playlist with media from directory referenced by item.
* @param item Navigation item representing a leaf
* @see void readMedia(const QString& path)
*/
void init(NavigationItemModel* item);
/**
* @brief Get path to media cover image.
* @return Path to media cover image.
*/
inline const QString& getCoverImageSource() const {return mCurrentItem->getImageSource();}
/**
* @brief Indicates whether the media player is currently playing a track.
* @return true if media player is playing a track.
*/
bool isPlaying() const;
/**
* @brief Indicates whether there is a next item in the playlist.
* @return True if there is a next item in the playlist
* Does not wrap.
*/
bool hasNext() const;
/**
* @brief Indicates whether there is a previous item in the playlist.
* @return True if there is a previous item in the playlist
* Does not wrap.
*/
bool hasPrevious() const;
/**
* @brief Get media progress as value in between 0 and 1
* @return Media progress
* 0 corresponds to the beginning and 1 to the end of the current track.
*/
double getProgress() const;
/**
* @brief Get current media title extracted from media meta data (id3 tags)
* @return Current media title
*/
QString getMediaTitle() const;
/**
* @brief Get duration of the current track
* @return Duration of the current track formatted as string
* @see QMediaPlayer::duration()
* @see millisecondsToString(int timeInMilliseconds) const
*/
QString getMediaDuration() const;
/**
* @brief Get current position within the track
* @return Postion within the track formatted as string
* @see QMediaPlayer::position()
* @see millisecondsToString(int timeInMilliseconds) const
*/
QString getPosition() const;
public slots:
/**
* @brief Navigate back to navgation list
*/
void navigateBack();
/**
* @brief Play or pause music depending on whether it is currently playing
*/
void playPause();
/**
* @brief Stop music and reset track to first track in playlist
*/
void stopMusic();
/**
* @brief Play next track in current playlist if available
*/
void playNext();
/**
* @brief Replay previoustrack in current playlist if available
*/
void playPrevious();
private:
/**
* @brief Resets playlist to first track if playlist exists and is non-empty
*/
void resetPlaylistToFirstTrack();
/**
* @brief Clear the current playlist
*/
void clearPlaylist();
/**
* @brief Add all media from path to playlist
* @param path Path to media
*/
void readMedia(const QString& path);
/**
* @brief Format time in milliseconds acoording to [M]m:ss
* @param time Time in ms
* @return formateted string
*/
QString millisecondsToString(int timeInMilliseconds) const;
NavigationItemModel* mCurrentItem = nullptr;
};
#endif // MUSICPLAYER_H

View file

@ -1,30 +1,41 @@
#include "NavigationController.h"
#include <controllers/SettingsHandler.h>
#include <QDir>
#include <QDebug>
#include <EnergySaver.h>
#include <models/NavigationItemModel.h>
#include <models/NavigationListModel.h>
#include <models/UiStateModel.h>
#include <controllers/MusicController.h>
#include <controllers/MusicPlayer.h>
NavigationController::NavigationController(QObject *parent) : QObject(parent),
mRootItem(new NavigationItemModel(this)),
mNavList(new NavigationListModel(this)),
mUiState(new UiStateModel(this)),
mMusicController(new MusicController(this))
mMediaPlayer(new MusicPlayer(this))
{
connect(mMusicController, &MusicController::navigateTo, [this](NavigationItemModel* item) {
connect(mMediaPlayer, &MusicPlayer::navigateTo, [this](NavigationItemModel* item) {
mUiState->showNavigation();
mNavList->navigateTo(item);
});
/* Connect player state to energy saver to prevent device shutdown while playing music.
*/
connect(mMediaPlayer, &MusicPlayer::isPlayingChanged, this, &NavigationController::startOrStopEnergySaverDependingOnPlayerState);
}
void NavigationController::setDebugOutput(const QString& text)
{
mDebugOutput = text;
emit debugOutputChanged();
}
void NavigationController::init(const QString &rootPath)
{
auto rootDir = QDir(rootPath);
if(!rootDir.exists()) return;
mRootPath = rootPath;
mRootPath = rootPath;
add(mRootPath, mRootItem);
@ -40,7 +51,6 @@ void NavigationController::setContext(QQmlContext *context)
{
mContext = context;
setContextProperties();
mMusicController->setContext(mContext);
}
void NavigationController::setContextProperties()
@ -48,6 +58,8 @@ void NavigationController::setContextProperties()
if(!mContext) return;
mContext->setContextProperty("navigationList", mNavList);
mContext->setContextProperty("uiStateModel", mUiState);
mContext->setContextProperty("musicModel", mMediaPlayer);
mContext->setContextProperty("debug", this);
}
void NavigationController::add(const QString &path, NavigationItemModel *parentItem)
@ -75,18 +87,18 @@ bool NavigationController::checkContent(const QString &path)
{
bool valid = false;
auto dir =QDir(path);
// directory must either contain subdirectories or media files
auto subDirsNames = dir.entryList(QDir::AllDirs);
if(subDirsNames.length() > 0) {
valid = true;
} else {
dir.setNameFilters(SettingsHandler::getAudioFileNameFilters());
auto fileNames = dir.entryList(QDir::Files);
int numAudio = 0;
for(auto file:fileNames){
if(file.endsWith(".flac") || file.endsWith(".mp3")){
numAudio++;
}
}
if(numAudio > 0) valid = true;
valid = numAudio > 0;
}
return valid;
}
@ -99,7 +111,20 @@ void NavigationController::onNavigationRequest()
if(item->hasChildren())
mNavList->setModelItems(item->getChildren());
else {
mMusicController->initPlayer(item);
mMediaPlayer->init(item);
mUiState->showMusicPlayer();
}
}
void NavigationController::startOrStopEnergySaverDependingOnPlayerState()
{
auto* energySaver = EnergySaver::instance();
assert(energySaver);
if(energySaver){
if(mMediaPlayer->isPlaying()){
energySaver->deactivate();
} else {
energySaver->activate();
}
}
}

View file

@ -7,7 +7,7 @@
class NavigationItemModel;
class NavigationListModel;
class UiStateModel;
class MusicController;
class MusicPlayer;
/**
* @brief Main controller controlling ui state, navigation and music player.
@ -15,6 +15,12 @@ class MusicController;
class NavigationController : public QObject
{
Q_OBJECT
Q_PROPERTY(QString pDebugOutput READ getDebugOutput NOTIFY debugOutputChanged)
signals:
void debugOutputChanged();
public:
explicit NavigationController(QObject *parent = nullptr);
@ -37,6 +43,8 @@ public:
*/
void setContext(QQmlContext* context);
QString getDebugOutput() const { return mDebugOutput; }
private:
/**
* @brief Register models in context
@ -55,14 +63,22 @@ private:
*/
bool checkContent(const QString& path);
/**
* @brief Set Debug Output. Necessary as Android Debugger does not work yet
* @param text Output to show in ui
*/
void setDebugOutput(const QString& text);
NavigationItemModel* mRootItem;
NavigationListModel* mNavList;
UiStateModel* mUiState;
MusicController* mMusicController;
MusicPlayer* mMediaPlayer;
QString mRootPath = ".";
QString mDebugOutput;
QQmlContext* mContext = nullptr;
private slots:
@ -70,6 +86,7 @@ private slots:
* @brief Either show subdirectories or music player depending on current directory type
*/
void onNavigationRequest();
void startOrStopEnergySaverDependingOnPlayerState();
};
#endif // NAVIGATIONCONTROLLER_H

View file

@ -1,4 +1,5 @@
#include "SettingsHandler.h"
#include <QStandardPaths>
constexpr const char* const rootPath = "rootPath";
constexpr const char* const profile = "profile";
@ -59,11 +60,20 @@ QString SettingsHandler::getShutdownScript() const
void SettingsHandler::initDefaults()
{
mDefaults.insert(rootPath, "/home/ar/source/lenaMusic/");
mDefaults.insert(profile, "RasPiTouch");
mDefaults.insert(enableEnergySaver, true);
mDefaults.insert(rootPath, QStandardPaths::MusicLocation);
mDefaults.insert(enableEnergySaver, false);
mDefaults.insert(timeout, 60);
mDefaults.insert(shutdownScript, "/usr/local/sbin/do_shutdown.sh");
mDefaults.insert(profile, "RasPiTouch");
// @todo add profile Android? Or simply scale ui for RasPi
// mDefaults.insert(profile, "Android");
// Defaults for LenaPi
// mDefaults.insert(rootPath, "/home/ar/source/lenaMusic/");
// mDefaults.insert(profile, "RasPiTouch");
// mDefaults.insert(enableEnergySaver, true);
// mDefaults.insert(timeout, 60);
// mDefaults.insert(shutdownScript, "/usr/local/sbin/do_shutdown.sh");
}

View file

@ -17,6 +17,12 @@ public:
static SettingsHandler* createSettingsHandlerAndFillWithDefaultsIfMissing(QSettings* settings);
/**
* @brief Provides a name filter for QDir that can be used to filter all audio files with valid formats.
* @return name filter for QDir
*/
static QStringList getAudioFileNameFilters() {return {"*.mp3", "*.flac"};}
inline void setSettings(QSettings* settings) { mSettings = settings;}
inline QSettings* getSettings() const { return mSettings; }
void fillWithDefaultIfMissing();

View file

@ -0,0 +1,90 @@
#include "StyleHandling.h"
#include <QGuiApplication>
#include <QScreen>
#include <QDebug>
StyleHandling::StyleHandling(QObject *parent)
: QObject{parent}, mStyleSizes(new QQmlPropertyMap(this)),
mMargins(new QQmlPropertyMap(this)), mSpacings(new QQmlPropertyMap(this)), mPaddings(new QQmlPropertyMap(this))
{
// nothing
}
void StyleHandling::calculateAndSetRatio()
{
qreal refHeight = 480;
qreal refWidth = 800;
// Scales to fullscreen. No rescaling when changing window size
QRect rect = QGuiApplication::primaryScreen()->geometry();
qreal height = qMin(rect.width(),rect.height());
qreal width = qMax(rect.width(), rect.height());
mRatio = qMin(height/refHeight, width/refWidth);
qDebug() << "mRation=" << mRatio<< "sizes="<<width<<", "<< height<<"\n";
}
void StyleHandling::initStyleSizes()
{
scaleAndInsert(mStyleSizes, "roundButtonDefaultSize", 65);
scaleAndInsert(mStyleSizes, "roundButtonBorderWidth", 2);
scaleAndInsert(mStyleSizes, "smallPlayerButtonSize", 60);
scaleAndInsert(mStyleSizes, "largePlayerButtonSize", 80);
scaleAndInsert(mStyleSizes, "scrollHandleWidth", 16);
scaleAndInsert(mStyleSizes, "scrollHandleHeight", 8);
scaleAndInsert(mStyleSizes, "scrollHandleBorderWidth", 1);
int progressBackgroundDefaultHeight = 10;
scaleAndInsert(mStyleSizes, "progressBackgroundDefaultHeight", progressBackgroundDefaultHeight);
scaleAndInsert(mStyleSizes, "progressBackgroundRadius", progressBackgroundDefaultHeight/2);
scaleAndInsert(mStyleSizes, "progressBarDefaultHeight", 8);
scaleAndInsert(mStyleSizes, "progressBackgroundBorderWidth", 1);
scaleAndInsert(mStyleSizes, "navigationListHeight", 210);
scaleAndInsert(mStyleSizes, "navigationDelegateDefaultSize", 150);
}
void StyleHandling::initSpacings()
{
scaleAndInsert(mSpacings, "defaultSpacing", 20);
scaleAndInsert(mSpacings, "smallSpacing", 10);
scaleAndInsert(mSpacings, "tinySpacing", 5);
}
void StyleHandling::initMargins()
{
scaleAndInsert(mMargins, "defaultMargin", 20);
scaleAndInsert(mMargins, "smallMargin", 10);
scaleAndInsert(mMargins, "tinyMargin", 5);
scaleAndInsert(mMargins, "scrollHandleMargins", 1);
}
void StyleHandling::initPaddings()
{
scaleAndInsert(mPaddings, "defaultPadding", 5);
}
void StyleHandling::scaleAndInsert(QQmlPropertyMap *map, const QString &key, int value)
{
map->insert(key, applyRatio(value));
}
int StyleHandling::applyRatio(int size) const
{
return size*mRatio;
}
void StyleHandling::init(QQmlContext *context)
{
calculateAndSetRatio();
initStyleSizes();
initMargins();
initSpacings();
initPaddings();
context->setContextProperty("StyleSizes", mStyleSizes);
context->setContextProperty("StyleSpacings", mSpacings);
context->setContextProperty("StyleMargins", mMargins);
context->setContextProperty("StylePaddings", mPaddings);
}

View file

@ -0,0 +1,81 @@
#ifndef STYLEHANDLING_H
#define STYLEHANDLING_H
#include <QObject>
#include <QQmlContext>
#include <QQmlPropertyMap>
/**
* @brief Contains all style sizes, margins and paddings used throughout the application
*
* Based on a reference screen size, maps for scaled margins, paddings and spacings are created and
* registered in the QML context. The values stored in the maps can then be used from QML.
* Map names: StyleSizes, StylePaddings, StyleSpacings, StyleMargins
*
* Always use values from these maps in QML! Never use magic numbers! They will NOT scale when
* the application is run on a different screen.
*
* See https://doc.qt.io/qt-5/scalability.html
*
* @todo scale fonts as well?
* @todo use dpi for scaling as app is very small on Android?
*/
class StyleHandling : public QObject
{
Q_OBJECT
public:
explicit StyleHandling(QObject *parent = nullptr);
/**
* @brief Calculates ratio, initializes all maps and registers them in QML context
* @param context Context to register Maps in
*/
void init(QQmlContext* context);
private:
/**
* @brief Calculates ratio from reference screen size and size of the current primary screen and inits member mRatio
*/
void calculateAndSetRatio();
/**
* @brief Initializes map containing all sizes (e.g., button or delegate sizes)
*/
void initStyleSizes();
/**
* @brief Initializes map containing all spacings
*/
void initSpacings();
/**
* @brief Initializes map containing all margins
*/
void initMargins();
/**
* @brief Initializes map containing all paddings
*/
void initPaddings();
/**
* @brief Scales the value with calculated ratio and inserts it into the given map under the given key
* @param map Map to insert key-value pair into
* @param key Key used in the map. This is the name used to retrieve the value in QML
* @param value Unscaled value
* @see mRatio
*
* In QML the value with the key "defaulSpacing" in the Map "StyleSpacings" is accessed by StyleSpacings.defaultSpacing
*/
void scaleAndInsert(QQmlPropertyMap* map, const QString& key, int value);
/**
* @brief Applys ratio to given size
* @param size Size to be scaled
* @return scaled size
* @see mRatio
*/
int applyRatio(int size) const;
qreal mRatio = 1.0;
QQmlPropertyMap* mStyleSizes = nullptr;
QQmlPropertyMap* mMargins = nullptr;
QQmlPropertyMap* mSpacings = nullptr;
QQmlPropertyMap* mPaddings = nullptr;
};
#endif // STYLEHANDLING_H

View file

@ -4,20 +4,20 @@
#include <QCommandLineParser>
#include <QFileInfo>
#include <QDebug>
#include "controllers/NavigationController.h"
#include <controllers/StyleHandling.h>
#include <controllers/NavigationController.h>
#include <controllers/SettingsHandler.h>
#include "MouseEventSpy.h"
#include "EnergySaver.h"
#include "controllers/SettingsHandler.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
/* Add command line parser to specify a custom config file
* https://doc.qt.io/qt-5/qcommandlineparser.html
*/
/****************************************************************************
* Configure and parse commandline arguments
****************************************************************************/
QCommandLineParser parser;
parser.setApplicationDescription("Lena's music app");
// Define a custom config file using -c or --config
@ -27,6 +27,12 @@ int main(int argc, char *argv[])
// process commandline arguments
parser.process(app);
/****************************************************************************
* Find and read settings
* If a config file is handed over via commandline arguments, it is preferred.
* Otherwise, the config in the standard location is used. If none exists yet,
* a default config is created.
****************************************************************************/
QSettings* settings = nullptr;
if(!parser.value(configOption).isEmpty()){
// config was handed over via commandline argument. Use this config if file exists.
@ -37,20 +43,35 @@ int main(int argc, char *argv[])
}
}
if(!settings){
// default config
// create config from default location
settings = new QSettings(QSettings::Scope::UserScope, "MaleyanaSoft", "LenaPi");
}
/* Read Settings */
// Read Settings
const auto settingsHandler = SettingsHandler::createSettingsHandlerAndFillWithDefaultsIfMissing(settings);
// init main app
/****************************************************************************
* init style
* Sets default sizes for ui elements. The element size is scaled according
* to the device's display size.
****************************************************************************/
StyleHandling styleHandler;
styleHandler.init(engine.rootContext());
/****************************************************************************
* init main app
****************************************************************************/
NavigationController navController;
navController.setContext(engine.rootContext());
navController.init(settingsHandler->getRootPath());
navController.setUiProfile(settingsHandler->getProfile());
/****************************************************************************
* init energy saver
* Prevents sleep on android devices and shuts down other device if inactive
* (no music or mouse events) for a certain time intervall
****************************************************************************/
if(settingsHandler->isEnergySaverEnabled()){
/* install MouseEventSpy and energy saver used for auto shut down of device
* if not used for a predefined time.
@ -59,9 +80,13 @@ int main(int argc, char *argv[])
EnergySaver::init(settingsHandler->getEnergySaverTimeout(), settingsHandler->getShutdownScript());
QObject::connect(MouseEventSpy::instance(), &MouseEventSpy::mouseEventDetected,
EnergySaver::instance(), &EnergySaver::restartTimer);
} else {
EnergySaver::init();
}
// load GUI
/****************************************************************************
* load view
****************************************************************************/
engine.load(QUrl("qrc:/main.qml"));
return app.exec();

View file

@ -4,8 +4,8 @@ import QtQuick.Controls 2.4
Window {
visible: true
width: 800
height: 480
// width: 800
//height: 480
title: "LenaPi 1.2"
Component.onCompleted: showMaximized();

View file

@ -1,218 +0,0 @@
#include "MusicModel.h"
#include <QDir>
#include <QDebug>
#include <VLCQtCore/Media.h>
MusicModel::MusicModel(VlcInstance* instance, QObject *parent) : QObject(parent),
mVlc(instance), mMedia(new VlcMediaList(instance))
{
/* nothing */
}
MusicModel::~MusicModel()
{
// do not delete! will cause segmentation fault
//if(mMedia)
// mMedia->deleteLater();
}
void MusicModel::init(NavigationItemModel *item)
{
if(mCurrentItem == item){
return;
}
mCurrentItem = item;
emit currentItemChanged();
reset();
clearMediaList();
readMedia(mCurrentItem->getPath());
setMediaTitle(mMedia->at(0));
}
void MusicModel::navigateBack()
{
emit navigateTo(mCurrentItem);
}
void MusicModel::playPause()
{
mIsPlaying = !mIsPlaying;
emit isPlayingChanged();
if(mIsPlaying)
emit play();
else
emit pause();
}
void MusicModel::stopMusic()
{
if(mIsPlaying){
mIsPlaying = false;
emit isPlayingChanged();
reset();
emit stop();
}
}
void MusicModel::playNext()
{
emit next();
if(!mIsPlaying){
mIsPlaying = true;
emit isPlayingChanged();
}
}
void MusicModel::playPrevious()
{
emit previous();
if(!mIsPlaying){
mIsPlaying = true;
emit isPlayingChanged();
}
}
NavigationItemModel *MusicModel::getCurrentItem()
{
return mCurrentItem;
}
VlcMediaList *MusicModel::getMedia()
{
return mMedia;
}
bool MusicModel::isPlaying() const
{
return mIsPlaying;
}
bool MusicModel::hasNext() const
{
return mHasNext;
}
bool MusicModel::hasPrevious() const
{
return mHasPrevious;
}
void MusicModel::setAudioVolume(int newVolume)
{
if(newVolume != mAudioVolume){
if(newVolume > 100){
mAudioVolume = 100;
} else if(newVolume < 0){
mAudioVolume = 0;
} else {
mAudioVolume = newVolume;
}
emit audioVolumeChanged(mAudioVolume);
}
}
double MusicModel::getProgress() const
{
return mCurrentMediaItemProgress;
}
QString MusicModel::getMediaTitle() const
{
return mMediaTitle;
}
QString MusicModel::getMediaLength()
{
return timeToString(mCurrentMediaItemLength);
}
QString MusicModel::getTime()
{
return timeToString(mCurrentTime);
}
void MusicModel::onNextMediaSet(VlcMedia *media)
{
setMediaTitle(media);
mHasNext = true;
mHasPrevious = true;
if(mMedia->at(0) == media){
mHasPrevious = false;
}
if(mMedia->at(mMedia->count()-1) == media){
mHasNext = false;
}
emit hasPreviousChanged();
emit hasNextChanged();
}
void MusicModel::onTimeChanged(int time)
{
mCurrentMediaItemProgress = (double) time / mCurrentMediaItemLength;
mCurrentTime = time;
emit progressChanged();
}
void MusicModel::onLengthChanged(int length)
{
mCurrentMediaItemLength= length;
emit mediaLengthChanged();
}
void MusicModel::reset()
{
mHasNext = false;
mHasPrevious = false;
emit hasNextChanged();
emit hasPreviousChanged();
mCurrentMediaItemProgress = 0.0;
mCurrentTime = 0.0;
emit progressChanged();
mCurrentMediaItemLength = 0.0;
emit mediaLengthChanged();
}
void MusicModel::clearMediaList()
{
while(mMedia->count() > 0){
mMedia->removeMedia(0);
}
}
void MusicModel::readMedia(const QString& path)
{
auto dir = QDir(path);
if(!dir.exists()) return;
auto fileNames = dir.entryList(QDir::Files);
for(auto file:fileNames){
if(file.endsWith(".flac") || file.endsWith(".mp3")){
mMedia->addMedia(new VlcMedia(dir.filePath(file), true, mVlc));
}
}
}
QString MusicModel::timeToString(int time)
{
int sec = time/1000;
int min = sec/60;
sec = sec-min*60;
QString secStr = (sec < 10) ? "0"+QString::number(sec) : QString::number(sec);
return QString::number(min) + ":" + secStr;
}
void MusicModel::setMediaTitle(VlcMedia *media)
{
auto list = media->currentLocation().split("/");
auto title = list.at(list.count() -1 );
mMediaTitle = title.left(title.lastIndexOf("."));
emit mediaTitleChanged();
}

View file

@ -1,100 +0,0 @@
#ifndef MUSICMODEL_H
#define MUSICMODEL_H
#include <QObject>
#include <models/NavigationItemModel.h>
#include <VLCQtCore/MediaList.h>
class MusicModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QObject* pCurrentItem READ getCurrentItem NOTIFY currentItemChanged)
Q_PROPERTY(bool pHasNext READ hasNext NOTIFY hasNextChanged)
Q_PROPERTY(bool pHasPrevious READ hasPrevious NOTIFY hasPreviousChanged)
Q_PROPERTY(bool pIsPlaying READ isPlaying NOTIFY isPlayingChanged)
Q_PROPERTY(double pProgress READ getProgress NOTIFY progressChanged)
Q_PROPERTY(QString pMediaLength READ getMediaLength NOTIFY mediaLengthChanged)
Q_PROPERTY(QString pTime READ getTime NOTIFY progressChanged)
Q_PROPERTY(QString pMediaTitle READ getMediaTitle NOTIFY mediaTitleChanged)
Q_PROPERTY(int pAudioVolume READ getAudioVolume WRITE setAudioVolume NOTIFY audioVolumeChanged)
signals:
void navigateTo(NavigationItemModel *item);
void currentItemChanged();
void play();
void pause();
void stop();
void previous();
void next();
void hasPreviousChanged();
void hasNextChanged();
void isPlayingChanged();
void progressChanged();
void mediaLengthChanged();
void mediaTitleChanged();
void audioVolumeChanged(int newVolume);
public:
MusicModel(VlcInstance* instance, QObject *parent = Q_NULLPTR);
~MusicModel();
void init(NavigationItemModel* item);
Q_INVOKABLE void navigateBack();
Q_INVOKABLE void playPause();
Q_INVOKABLE void stopMusic();
Q_INVOKABLE void playNext();
Q_INVOKABLE void playPrevious();
NavigationItemModel *getCurrentItem();
VlcMediaList *getMedia();
bool isPlaying() const;
bool hasNext() const;
bool hasPrevious() const;
inline int getAudioVolume() const { return mAudioVolume; }
/**
* @brief Set audio volume. Information is transferred to VlcAudio
* @param newVolume value between 0 and 100 (audio level in percent)
* Ensures that volume is inbetween 0 and 100. If this range is exceeded,
* the volume is set to the lowest and highest allowed value, respectively.
*/
void setAudioVolume(int newVolume);
double getProgress() const;
QString getMediaTitle() const;
QString getMediaLength();
QString getTime();
public slots:
void onNextMediaSet(VlcMedia* media);
void onTimeChanged(int time);
void onLengthChanged(int length);
private:
void reset();
void clearMediaList();
void readMedia(const QString& path);
void setMediaTitle(VlcMedia* media);
QString timeToString(int time);
bool mIsPlaying = false;
bool mHasNext = false;
bool mHasPrevious = false;
int mCurrentMediaItemLength = 0;
int mCurrentTime = 0;
double mCurrentMediaItemProgress = 0;
int mAudioVolume{50};
QString mMediaTitle = QString("");
NavigationItemModel* mCurrentItem = Q_NULLPTR;
VlcMediaList* mMedia = Q_NULLPTR;
VlcInstance* mVlc = Q_NULLPTR;
};
#endif // MUSICMODEL_H

View file

@ -10,12 +10,12 @@ NavigationItemModel::NavigationItemModel(QObject *parent) : QObject(parent),
qRegisterMetaType<NavigationItemModel*>("NavigationItemModel*");
}
QString NavigationItemModel::getImageSource() const
const QString& NavigationItemModel::getImageSource() const
{
return mImageSource;
}
QString NavigationItemModel::getPath() const
const QString& NavigationItemModel::getPath() const
{
return mPath;
}

View file

@ -36,13 +36,13 @@ public:
* represented by this item. If no such image is found, a default image is displayed
* on the delegate.
*/
QString getImageSource() const;
const QString &getImageSource() const;
/**
* @brief Get path to folder represented by this navigation item.
* @return Path to folder
*/
QString getPath() const;
const QString& getPath() const;
/**
* @brief Set folder path and set image source displayed on delegate.
* @param path Path to directory that is represented by this navigation item.

View file

@ -4,6 +4,7 @@
#include <QObject>
#include <QUrl>
#include <QHash>
#include <qstandardpaths.h>
/**
* @brief Handles state of UI by providing the qml source.

BIN
LenaPi/resources/icon.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB