diff --git a/android-sources/AndroidManifest.old.xml b/android-sources/AndroidManifest.old.xml new file mode 100644 index 0000000..bcc4ebd --- /dev/null +++ b/android-sources/AndroidManifest.old.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sources/AndroidManifest.xml b/android-sources/AndroidManifest.xml index 999e16e..6c2852d 100644 --- a/android-sources/AndroidManifest.xml +++ b/android-sources/AndroidManifest.xml @@ -1,44 +1,54 @@ - - - + + + + + + + + + + - - - + - - - + - + - - - + + + + - + + + - - - - + - - - - + + - - - - - - - - - - - - - + diff --git a/android-sources/build.gradle b/android-sources/build.gradle new file mode 100644 index 0000000..3cfc5f3 --- /dev/null +++ b/android-sources/build.gradle @@ -0,0 +1,68 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.6.0' + } +} + +repositories { + google() + jcenter() +} + +apply plugin: 'com.android.application' + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) +} + +android { + /******************************************************* + * The following variables: + * - androidBuildToolsVersion, + * - androidCompileSdkVersion + * - qt5AndroidDir - holds the path to qt android files + * needed to build any Qt application + * on Android. + * + * are defined in gradle.properties file. This file is + * updated by QtCreator and androiddeployqt tools. + * Changing them manually might break the compilation! + *******************************************************/ + + compileSdkVersion androidCompileSdkVersion.toInteger() + + buildToolsVersion '28.0.3' + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] + aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] + res.srcDirs = [qt5AndroidDir + '/res', 'res'] + resources.srcDirs = ['resources'] + renderscript.srcDirs = ['src'] + assets.srcDirs = ['assets'] + jniLibs.srcDirs = ['libs'] + } + } + + lintOptions { + abortOnError false + } + + // Do not compress Qt binary resources file + aaptOptions { + noCompress 'rcc' + } + defaultConfig { + resConfig "en" + minSdkVersion = qtMinSdkVersion + targetSdkVersion = 29 + //qtTargetSdkVersion + } +} diff --git a/android-sources/gradle/wrapper/gradle-wrapper.jar b/android-sources/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f Binary files /dev/null and b/android-sources/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android-sources/gradle/wrapper/gradle-wrapper.properties b/android-sources/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..5028f28 --- /dev/null +++ b/android-sources/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/android-sources/gradlew b/android-sources/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/android-sources/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/android-sources/gradlew.bat b/android-sources/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/android-sources/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/android-sources/res/drawable-hdpi/icon.png b/android-sources/res/drawable-hdpi/icon.png index 159d958..a228a59 100644 Binary files a/android-sources/res/drawable-hdpi/icon.png and b/android-sources/res/drawable-hdpi/icon.png differ diff --git a/android-sources/res/drawable-ldpi/icon.png b/android-sources/res/drawable-ldpi/icon.png index 159d958..a228a59 100644 Binary files a/android-sources/res/drawable-ldpi/icon.png and b/android-sources/res/drawable-ldpi/icon.png differ diff --git a/android-sources/res/drawable-mdpi/icon.png b/android-sources/res/drawable-mdpi/icon.png index 159d958..a228a59 100644 Binary files a/android-sources/res/drawable-mdpi/icon.png and b/android-sources/res/drawable-mdpi/icon.png differ diff --git a/android-sources/res/values/libs.xml b/android-sources/res/values/libs.xml new file mode 100644 index 0000000..6b1a4a2 --- /dev/null +++ b/android-sources/res/values/libs.xml @@ -0,0 +1,22 @@ + + + + https://download.qt.io/ministro/android/qt5/qt-5.14 + + + + + + + + + + + + + + + + + diff --git a/blueROCK.pro b/blueROCK.pro index 305e2c3..e14f685 100644 --- a/blueROCK.pro +++ b/blueROCK.pro @@ -5,6 +5,7 @@ VERSION = 0.04 android { QT += androidextras + android: include(/home/dorian/Android/Sdk/android_openssl/openssl.pri) ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources } @@ -82,5 +83,18 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin DISTFILES += \ CHANGELOG.md \ android-sources/AndroidManifest.xml \ + android-sources/build.gradle \ + android-sources/gradle/wrapper/gradle-wrapper.jar \ + android-sources/gradle/wrapper/gradle-wrapper.properties \ + android-sources/gradlew \ + android-sources/gradlew.bat \ + android-sources/res/values/libs.xml \ resources/shared/icons/bluerock/index.theme \ $$files(resources/shared/icons/*.png, true) + +ANDROID_ABIS = armeabi-v7a + +contains(ANDROID_TARGET_ARCH,armeabi-v7a) { + ANDROID_ABIS = \ + armeabi-v7a +} diff --git a/headers/appsettings.h b/headers/appsettings.h index 7c31ddc..7b8a8a8 100644 --- a/headers/appsettings.h +++ b/headers/appsettings.h @@ -10,7 +10,6 @@ class AppSettings : public QObject { Q_OBJECT - Q_PROPERTY(NOTIFY themeChanged) public: explicit AppSettings(QObject *parent = nullptr); diff --git a/headers/brcompetition.h b/headers/brcompetition.h index 5f5316c..dd45b26 100644 --- a/headers/brcompetition.h +++ b/headers/brcompetition.h @@ -22,6 +22,7 @@ class BRCompetition : public BRWidget Q_PROPERTY(BRLeague* league READ getLeague NOTIFY metadataChanged) Q_PROPERTY(QUrl eventWebsiteUrl READ getEventWebsiteUrl NOTIFY metadataChanged) Q_PROPERTY(QList infosheetUrls READ getInfosheetUrls NOTIFY metadataChanged) + Q_PROPERTY(bool pinned READ getPinned WRITE setPinned NOTIFY pinnedChanged) Q_PROPERTY(QList categories READ getCategoriesQML NOTIFY categoriesChanged) Q_PROPERTY(BRCategory* currentCategory READ getCurrentCategory WRITE setCurrentCategory NOTIFY currentCategoryChanged) Q_PROPERTY(QList results READ getResultsQML NOTIFY resultsChanged) @@ -47,6 +48,7 @@ public: QUrl eventWebsiteUrl; QList infosheetUrls; + bool pinned; BRCategory* currentCategory; QList categories; } BRCompetitionData; @@ -61,6 +63,8 @@ public: Q_INVOKABLE BRLeague* getLeague(); Q_INVOKABLE QUrl getEventWebsiteUrl(); Q_INVOKABLE QList getInfosheetUrls(); + Q_INVOKABLE bool getPinned(); + Q_INVOKABLE void setPinned(bool pinned); Q_INVOKABLE QList getCategoriesQML(); Q_INVOKABLE QList getCategories(); Q_INVOKABLE BRCategory* getCurrentCategory() const; @@ -84,6 +88,7 @@ private: QList infosheetUrls; // data + bool pinned; QList categories; BRCategory* currentCategory; @@ -91,6 +96,7 @@ private: signals: void metadataChanged(); + void pinnedChanged(); void categoriesChanged(); void currentCategoryChanged(); void resultsChanged(); diff --git a/headers/brleague.h b/headers/brleague.h index 86e3537..adf7c07 100644 --- a/headers/brleague.h +++ b/headers/brleague.h @@ -14,6 +14,7 @@ class BRLeague : public BRWidget Q_OBJECT Q_PROPERTY(QString name READ getName NOTIFY metadataChanged) Q_PROPERTY(QColor color READ getColor NOTIFY metadataChanged) + Q_PROPERTY(bool enabled READ getEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(QList competitions READ getCompetitionsQML NOTIFY competitionsChanged) Q_PROPERTY(QList cups READ getCupsQML NOTIFY cupsChanged) public: @@ -24,6 +25,7 @@ public: QString name; QColor color; + bool enabled; QList competitions; QList cups; @@ -33,6 +35,8 @@ public: Q_INVOKABLE QString getName(); Q_INVOKABLE QColor getColor(); + Q_INVOKABLE bool getEnabled(); + Q_INVOKABLE void setEnabled(bool enabled); Q_INVOKABLE QList getCompetitions(); Q_INVOKABLE QList getCompetitionsQML(); Q_INVOKABLE QList getCupsQML(); @@ -43,12 +47,14 @@ private: QString name; QColor color; + bool enabled; QList competitions; QList cups; signals: void metadataChanged(); + void enabledChanged(); void competitionsChanged(); void cupsChanged(); }; diff --git a/headers/brwidget.h b/headers/brwidget.h index 924e2bb..792a415 100644 --- a/headers/brwidget.h +++ b/headers/brwidget.h @@ -8,6 +8,7 @@ class BRProvider; class BRWidget : public QObject { Q_OBJECT + Q_PROPERTY(BRWidgetState state READ getState NOTIFY stateChanged) public: enum BRFederation { @@ -17,6 +18,14 @@ public: }; Q_ENUM(BRFederation) + enum BRWidgetState { + Unconfigured = -1, + Configured, + Loading, + Loaded + }; + Q_ENUM(BRWidgetState) + enum BRWidgetStatusCode { Success = 200, InternalError = 900, @@ -28,13 +37,17 @@ public: Q_INVOKABLE virtual BRWidget::BRWidgetStatusCode load() = 0; + Q_INVOKABLE BRWidgetState getState() const; Q_INVOKABLE BRFederation getFederation() const; Q_INVOKABLE int getId() const; protected: explicit BRWidget(BRProvider* provider, BRFederation federation, int id); + void setState(BRWidgetState state); BRProvider* getProvider(); + BRWidgetState state; + template QList listToQmlList(QList list) { QList tmpList; @@ -51,6 +64,7 @@ private: const int id; signals: + void stateChanged(); }; diff --git a/resources/qml/Components/DataListView.qml b/resources/qml/Components/DataListView.qml index 38f7c7a..0282063 100644 --- a/resources/qml/Components/DataListView.qml +++ b/resources/qml/Components/DataListView.qml @@ -53,11 +53,23 @@ ListView { width: 8 - visible: control.model > 0 + visible: control.model.length > 0 active: true } + header: Item { + id: topSpacerItm + width: parent.width + height: 10 + } + + footer: Item { + id: bottomSpacerItm + width: parent.width + height: 10 + } + Behavior on opacity { NumberAnimation { duration: 200 diff --git a/resources/qml/Components/PullRefresher.qml b/resources/qml/Components/PullRefresher.qml index e252bee..1e72f89 100644 --- a/resources/qml/Components/PullRefresher.qml +++ b/resources/qml/Components/PullRefresher.qml @@ -162,7 +162,7 @@ Item { Connections { target: control.target - onDragEnded: { + function onDragEnded() { if(userPosition >= control.dragOutPosition * control.dragRefreshPositionMultiplier){ control.state = "refreshing" preRefreshTimer.start() diff --git a/resources/qml/Components/SelectorPopup.qml b/resources/qml/Components/SelectorPopup.qml new file mode 100644 index 0000000..89bf15b --- /dev/null +++ b/resources/qml/Components/SelectorPopup.qml @@ -0,0 +1,137 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.3 + +Dialog { + id: control + + property var dataObj + property string subTitle: "" + property int implicitY: parent.height - implicitHeight + + signal selectionFinished(int index, var data) + + parent: Overlay.overlay + + x: 0 + y: parent.height - implicitHeight + + opacity: 1 + + width: parent.width + implicitWidth: width + contentHeight: Math.min(parent.height * 0.7, implicitContentHeight) + implicitHeight: contentHeight + topPadding + bottomPadding + header.height + padding: 30 + + modal: true + focus: true + + title: "" + + header: Column { + id: selectorPuHeaderCol + + width: control.width + height: headerSubLa.text !== "" && headerLa.text !== "" ? 73 : 40 + + Label { + id: headerLa + + visible: control.title + + width: selectorPuHeaderCol.width + + elide: "ElideRight" + padding: control.padding + bottomPadding: 0 + font.bold: true + font.pixelSize: 16 + + text: control.title + + onLinkActivated: { + Qt.openUrlExternally(link) + } + } + + Label { + id: headerSubLa + + visible: control.subTitle + + width: selectorPuHeaderCol.width + + elide: "ElideRight" + padding: control.padding + topPadding: 5 + bottomPadding: 0 + font.bold: true + font.pixelSize: 16 + + text: control.subTitle + + onLinkActivated: { + Qt.openUrlExternally(link) + } + + } + } + + background: Item { + Rectangle { + id: backgroundRect + anchors { + fill: parent + bottomMargin: -radius + } + + radius: control.leftPadding + + color: control.Material.dialogColor + } + } + + function appear(dataObj, title, subTitle) { + + if(dataObj.length > 0){ + control.dataObj = dataObj + } + else { + control.dataObj = undefined + } + + control.title = title + control.subTitle = subTitle === undefined ? "":subTitle + control.open() + } + + enter: Transition { + NumberAnimation { + property: "opacity"; + from: 0 + to: 1.0 + easing.type: Easing.Linear + } + + NumberAnimation { + property: "y" + from: control.parent.height - control.implicitHeight * 0.7 + to: control.parent.height - control.implicitHeight + } + } + + exit: Transition { + NumberAnimation { + property: "opacity"; + from: 1 + to: 0 + } + + NumberAnimation { + property: "y" + from: control.parent.height - control.implicitHeight + to: control.parent.height - control.implicitHeight * 0.7 + } + } +} diff --git a/resources/qml/Pages/BRWidgetPage.qml b/resources/qml/Pages/BRWidgetPage.qml index 5f0883c..ca226ba 100644 --- a/resources/qml/Pages/BRWidgetPage.qml +++ b/resources/qml/Pages/BRWidgetPage.qml @@ -31,7 +31,7 @@ Page { property BRWidget data property Component headerComponent - property alias selector: selectorPu + property alias selector: selectorPopup property string subTitle property bool titleIsPageTitle: true @@ -93,107 +93,21 @@ Page { } - Dialog { - id: selectorPu + SelectorPopup { + id: selectorPopup - property var dataObj - property string subTitle: "" - - x: 0 //root.width / 2 - width / 2 - y: root.height - selectorPu.height * 0.7//root.height - height //root.height / 2 - height / 2 - - opacity: 0 - - width: root.width - height: selectorLv.implicitHeight - - modal: true - focus: true - - title: "" - - header: Column { - id: selectorPuHeaderCol - - width: parent.width - - Label { - id: headerLa - - visible: selectorPu.title - - width: parent.width - - elide: "ElideRight" - padding: 24 - bottomPadding: 0 - font.bold: true - font.pixelSize: 16 - background: Rectangle { - radius: 2 - color: selectorPu.Material.dialogColor - clip: true - } - - text: selectorPu.title - - onLinkActivated: { - Qt.openUrlExternally(link) - } - - } - Label { - id: headerSubLa - - visible: selectorPu.subTitle - - width: parent.width - - elide: "ElideRight" - padding: 24 - topPadding: 5 - bottomPadding: 0 - font.bold: true - font.pixelSize: 16 - background: Rectangle { - radius: 2 - color: selectorPu.Material.dialogColor - clip: true - } - - text: selectorPu.subTitle - - onLinkActivated: { - Qt.openUrlExternally(link) - } - - } - } - - function appear(dataObj, title, subTitle) { - if(dataObj.length > 0){ - selectorPu.dataObj = dataObj - } - else { - selectorPu.dataObj = undefined - } - selectorPu.title = title - selectorPu.subTitle = subTitle === undefined ? "":subTitle - selectorPu.open() - - } - - ListView { + contentItem: ListView { id: selectorLv property int delegateHeight: 50 + spacing: 10 - anchors.fill: parent + clip: true - implicitWidth: parent.width - implicitHeight: root.height * 0.7 < ( (delegateHeight + spacing) * model ) ? root.height * 0.7 : (delegateHeight + spacing) * model + 100 + implicitWidth: selectorPopup.width + implicitHeight: model === undefined ? 0:(delegateHeight + spacing) * model.length - model: selectorPu.dataObj !== undefined ? selectorPu.dataObj.length:0 + model: selectorPopup.dataObj !== undefined ? selectorPopup.dataObj:undefined ScrollIndicator.vertical: ScrollIndicator { parent: selectorLv.parent @@ -215,40 +129,13 @@ Page { flat: true - text: selectorPu.dataObj[index].text + text: selectorPopup.dataObj[index].text onClicked: { - selectorPu.close() - control.selectionFinished(index, selectorPu.dataObj[index].data) + selectorPopup.close() + control.selectionFinished(index, selectorPopup.dataObj[index].data) } } } - - enter: Transition { - NumberAnimation { - property: "opacity"; - //from: 0.0; - to: 1.0 - } - NumberAnimation { - property: "y" - //from: root.height - selectorPu.height * 0.7 - to: root.height - selectorPu.height - } - } - - exit: Transition { - NumberAnimation { - property: "opacity"; - //from: 1.0; - to: 0.0 - } - NumberAnimation { - property: "y" - //from: root.height - selectorPu.height - to: root.height - selectorPu.height * 0.7 - } - } } - } diff --git a/resources/qml/Pages/CalendarPage.qml b/resources/qml/Pages/CalendarPage.qml index c4833b6..2ce17a9 100644 --- a/resources/qml/Pages/CalendarPage.qml +++ b/resources/qml/Pages/CalendarPage.qml @@ -150,9 +150,7 @@ BRWidgetPage { var selectOptions = [] for(var i = 0; i < leagues.length; i++) { - //console.log("found cat: " + obj[prop]['label']) - - selectOptions.push( {text: leagues[i].name, data:{task:"leagues", league: selectOptions}} ) + selectOptions.push( {text: leagues[i].name, data:{task:"leagues", league: leagues[i]}} ) } //compCats.push( {"text": qsTr("Pinned"), "data": {"sort_rank":0, "cat_id":[-1]}} ) @@ -164,38 +162,10 @@ BRWidgetPage { id: calendarLv anchors.fill: parent - //boundsBehavior: Flickable.StopAtBounds - model: control.data.currentSeason.competitions - //listData: widgetData['competitions'] + onRefresh: control.data.load() - onRefresh: { - control.data.load() - } - - Component.onCompleted: { - //initFilters() - //initFavorites() - - /*if(model){ - control.status = 200 - control.ready = true - } - else { - control.ready = false - control.status = 901 - return - }*/ - } - /* - onWidgetDataChanged: { - // if the IFSC Calendar is open -> add the worldranking - if(params.nation === "ICC"){ - control.widgetData['cups'].unshift({"SerId":"","rkey":"","name":"Worldranking","modified":"2018-10-24 16:11:12","modifier":"","year":"","num_comps":"","cats":["ICC-COA","ICC-HD","ICC-MED","ICC_F","ICC_FB","ICC_FS","ICC_M","ICC_MB","ICC_MS"]}) - } - } -*/ function autoScroll() { // function to scroll to the next competition that is not already over var compList = calendarLv.model @@ -211,154 +181,20 @@ BRWidgetPage { } } - function getCompCatData(compCatId) { - var obj = app.compCats - - for(var prop in obj) { - // go through the whole array and search for data keys - if (obj.hasOwnProperty(prop) && obj[prop]["cat_id"].indexOf(compCatId) >= 0) { - //console.log("found cat: " + obj[prop]['label']) - return obj[prop] - } - } - } - - function filterCats(display, cats) { - //console.log("filtering cats: " + cats + " displaying: " + display) - for(var i = 0; i < cats.length; i ++){ - if(control.displayedCompCats.indexOf(cats[i]) >= 0 && !display){ - control.displayedCompCats.splice(control.displayedCompCats.indexOf(cats[i]), 1) - } - else if(control.displayedCompCats.indexOf(cats[i]) == -1 && display){ - control.displayedCompCats.push(cats[i]) - - } - } - // trigger 'changed' signal - control.displayedCompCats = control.displayedCompCats - appSettings.write("displayedCompCats"+params.nation, JSON.stringify(displayedCompCats)) - //console.log("new JSON string is: " + JSON.stringify(displayedCompCats)) - //console.log("displayed cats is now: " + control.displayedCompCats) - } - - function initFilters() { - if(appSettings.read("displayedCompCats"+params.nation) !== "false"){ - //console.log(appSettings.read("displayedCompCats"+params.nation)) - control.displayedCompCats = JSON.parse(appSettings.read("displayedCompCats"+params.nation)) - } - if(control.displayedCompCats.length === 0){ - var obj = app.compCats - var compCats = new Array - - for(var prop in obj) { - // go through the whole array and search for data keys - if (obj.hasOwnProperty(prop) && obj[prop]["nation"] === params.nation) { - //console.log("found cat: " + obj[prop]['label']) - filterCats(true, obj[prop]['cat_id']) - } - } - } - // trigger 'changed' signal - control.displayedCompCats = control.displayedCompCats - //console.log(control.displayedCompCats) - } - - function editFavorites(favorite, compId) { - if(control.compFavorites.indexOf(compId) >= 0 && !favorite) { - control.compFavorites.splice( control.compFavorites.indexOf(compId), 1) - } - else if(control.compFavorites.indexOf(compId) < 0 && favorite) { - control.compFavorites.push(compId) - } - - appSettings.write("compFavorites", JSON.stringify(control.compFavorites)) - // trigger 'changed' signal - control.compFavorites = control.compFavorites - } - - function initFavorites() { - if(appSettings.read("compFavorites") !== "false"){ - //console.log(appSettings.read("displayedCompCats"+params.nation)) - control.compFavorites = JSON.parse(appSettings.read("compFavorites")) - } - else { - control.compFavorites = [] - appSettings.write("compFavorites", JSON.stringify(control.compFavorites)) - } - - // trigger 'changed' signal - control.compFavorites = control.compFavorites - console.log(control.compFavorites) - } - - header: Item { - id: topSpacerItm - width: parent.width - height: 10 - } - - footer: Item { - id: bottomSpacerItm - width: parent.width - height: 10 - } - delegate: ItemDelegate { id: competitionDel - property bool over property var thisData: modelData - property string name: thisData.name - property string date: thisData.dateSpan //"test" // TODO thisData["date_span"] - property var cats: thisData["cats"] - property int catId: thisData["cat_id"] === undefined ? 0:thisData["cat_id"] + width: calendarLv.width + height: compDelCol.height + 10 - property bool thisIsFavored: true //control.compFavorites.indexOf(parseInt(thisData['WetId'])) >= 0 - property bool includedByFavorites: true //control.displayedCompCats.indexOf(-1) >= 0 && thisIsFavored - property bool includedByFilter: true//control.displayedCompCats.indexOf(parseInt(thisData['cat_id'])) >= 0 - property bool thisIsVisible: includedByFavorites || includedByFilter - - function updateVisibility() { - competitionDel.includedByFilter = control.displayedCompCats.indexOf(parseInt(competitionDel.thisData['cat_id'])) >= 0 - competitionDel.thisIsFavored = control.compFavorites.indexOf(parseInt(thisData['WetId'])) >= 0 - competitionDel.includedByFavorites = control.displayedCompCats.indexOf(-1) >= 0 && thisIsFavored - } - - width: parent.width - height: thisIsVisible ? compDelCol.height + 10 : 0 - - enabled: true//((thisData["cats"] !== undefined && thisData["cats"].length > 0) || competitionDel.thisData["homepage"] !== undefined || getCompInfoUrls(index).length > 0) && height > 0 - //visible: includedByFilter + enabled: thisData.categories.length > 0 || thisData.eventWebsiteUrl.toString() !== "" || thisData.infosheetUrls.length > 0 opacity: 0 scale: 0.9 - /*Connections { - target: control - onDisplayedCompCatsChanged: { - competitionDel.updateVisibility() - } - - onCompFavoritesChanged: { - competitionDel.updateVisibility() - } - }*/ - - onThisDataChanged: { - if(thisIsVisible){ - fadeInPa.start() - } - } - - onThisIsVisibleChanged: { - if(thisIsVisible){ - fadeInPa.start() - } - else { - fadeOutPa.start() - } - } + onThisDataChanged: fadeInPa.start() Behavior on height { NumberAnimation { @@ -366,9 +202,7 @@ BRWidgetPage { } } - onClicked: { - control.openCompetition(competitionDel.thisData) - } + onClicked: control.openCompetition(competitionDel.thisData) ParallelAnimation { id: fadeInPa @@ -412,16 +246,16 @@ BRWidgetPage { wrapMode: Text.WordWrap - text: name + text: competitionDel.thisData.name Layout.fillWidth: true } ToolButton { id: bookmarkTb - icon.name: competitionDel.thisIsFavored ? "pinFilled":"pin" + icon.name: competitionDel.thisData.pinned ? "pinFilled":"pin" onClicked: { - control.editFavorites(!competitionDel.thisIsFavored, parseInt(thisData['WetId'])) + competitionDel.thisData.pinned = !competitionDel.thisData.pinned } Layout.alignment: Layout.Right @@ -450,7 +284,7 @@ BRWidgetPage { color: "grey" - text: date + text: competitionDel.thisData.dateSpan } } @@ -482,105 +316,21 @@ BRWidgetPage { } } - Dialog { + SelectorPopup { id: filterSelectPu - property var dataObj - property string subTitle: "" - - signal selectionFinished(int index, var data) - - x: 0 - control.anchors.leftMargin //root.width / 2 - width / 2 - y: control.height - filterSelectPu.height * 0.7//root.height - height //root.height / 2 - height / 2 - - opacity: 0 - - width: control.width + control.anchors.leftMargin + control.anchors.rightMargin - height: selectorLv.implicitHeight - - modal: true - focus: true - - title: "" - - function appear(dataObj, title, subTitle) { - if(dataObj.length > 0){ - filterSelectPu.dataObj = dataObj - filterSelectPu.title = title - filterSelectPu.subTitle = subTitle === undefined ? "":subTitle - filterSelectPu.open() - } - } - - header: Column { - id: filterSelectPuHeaderCol - - width: parent.width - - Label { - id: headerLa - - visible: filterSelectPu.title - - width: parent.width - - elide: "ElideRight" - padding: 24 - bottomPadding: 0 - font.bold: true - font.pixelSize: 16 - background: Rectangle { - radius: 2 - //color: filterSelectPu.Material.dialogColor - clip: true - } - - text: filterSelectPu.title - - onLinkActivated: { - Qt.openUrlExternally(link) - } - - } - Label { - id: headerSubLa - - visible: filterSelectPu.subTitle - - width: parent.width - - elide: "ElideRight" - padding: 24 - topPadding: 5 - bottomPadding: 0 - font.bold: true - font.pixelSize: 16 - background: Rectangle { - radius: 2 - //color: filterSelectPu.Material.dialogColor - clip: true - } - - text: filterSelectPu.subTitle - - onLinkActivated: { - Qt.openUrlExternally(link) - } - - } - } - - ListView { + contentItem: ListView { id: selectorLv property int delegateHeight: 50 + spacing: 10 - anchors.fill: parent + clip: true implicitWidth: parent.width - implicitHeight: control.height * 0.7 < ( (delegateHeight + spacing) * model ) ? root.height * 0.7 : (delegateHeight + spacing) * model + 100 + implicitHeight: model === undefined ? 0:(delegateHeight + spacing) * model.length - model: filterSelectPu.dataObj !== undefined ? filterSelectPu.dataObj.length:0 + model: filterSelectPu.dataObj ScrollIndicator.vertical: ScrollIndicator { parent: selectorLv.parent @@ -597,73 +347,25 @@ BRWidgetPage { delegate: CheckDelegate { id: catBt + property var thisData: modelData + width: parent.width height: text !== "" ? selectorLv.delegateHeight:0 - //flat: true - - text: filterSelectPu.dataObj[index].text - - Component.onCompleted: { - checked = getCheckedState() - } - - Connections { - target: control - onDisplayedCompCatsChanged: { - //console.log("filters changed") - //competitionDel.visible = control.displayedCompCats.indexOf(parseInt(competitionDel.thisData['cat_id'])) >= 0 - checked = getCheckedState() - } - } - - function getCheckedState() { - for(var i = 0; i < filterSelectPu.dataObj[index].data.cat_id.length; i ++){ - - //console.log("checking cat " + filterSelectPu.dataObj[index].data.label ) - if(control.displayedCompCats.indexOf(filterSelectPu.dataObj[index].data.cat_id[i] ) >= 0){ - return true - } - } - return false - } + checked: thisData.data.league.enabled + text: thisData.text onClicked: { - control.filterCats(checked, filterSelectPu.dataObj[index].data.cat_id) - if(control.displayedCompCats.length === 0){ - control.filterCats(true, filterSelectPu.dataObj[index].data.cat_id) - checked = true + if(thisData.data.league.state !== BRWidget.Loaded) { + loadingDl.open() + thisData.data.league.load() + loadingDl.close() } + + thisData.data.league.enabled = checked } } } - - enter: Transition { - NumberAnimation { - property: "opacity"; - //from: 0.0; - to: 1.0 - } - NumberAnimation { - property: "y" - //from: root.height - filterSelectPu.height * 0.7 - to: control.height - filterSelectPu.height - } - } - - exit: Transition { - NumberAnimation { - property: "opacity"; - //from: 1.0; - to: 0.0 - } - NumberAnimation { - property: "y" - //from: root.height - filterSelectPu.height - to: control.height - filterSelectPu.height * 0.7 - } - } } - } diff --git a/resources/qml/Pages/ResultPage.qml b/resources/qml/Pages/ResultPage.qml index ad96438..bdf09fb 100644 --- a/resources/qml/Pages/ResultPage.qml +++ b/resources/qml/Pages/ResultPage.qml @@ -43,9 +43,9 @@ BRWidgetPage { ToolButton { id: flowToolBt - visible: speedFlowChart.enabled + visible: false //speedFlowChart.enabled - enabled: false // TODO control.data.currentCategory.currentRound.getId() === -1 && Object.keys(control.widgetData['route_names']).length > 2 + enabled: true // TODO control.data.currentCategory.currentRound.getId() === -1 && Object.keys(control.widgetData['route_names']).length > 2 onClicked: { if(speedFlowChartBackgroundRect.state === "hidden"){ @@ -63,8 +63,6 @@ BRWidgetPage { ToolButton { id: moreToolBt - Layout.alignment: Layout.Right - onClicked: { control.changeCategory() } @@ -130,7 +128,13 @@ BRWidgetPage { DataListView { id: resultLv - anchors.fill: parent + anchors { + top: parent.top + topMargin: 0 + left: parent.left + right: parent.right + bottom: routeSelectTb.top + } model: control.data.currentCategory.currentRound.results @@ -158,6 +162,8 @@ BRWidgetPage { } } + header: Item {} + delegate: ItemDelegate { id: partDel @@ -681,10 +687,6 @@ BRWidgetPage { width: Math.max(150, routeSelectTb.width / routeSelectButtonRep.model.length) //text.length * font.pixelSize - onWidthChanged: { - console.log("WIDTH IS: " + Math.max(150, routeSelectTb.width / routeSelectButtonRep.model.length)) - } - onClicked: { control.changeRound(modelData) return; @@ -737,15 +739,15 @@ BRWidgetPage { Connections { target: speedFlowChartProduct - onPurchaseRestored: { + function onPurchaseRestored() { speedFlowChartLockedOverlay.state = appSettings.read("speedBackendPurchase") === "1" ? "unlocked":"locked" } - onPurchaseSucceeded: { + function onPurchaseSucceeded() { speedFlowChartLockedOverlay.state = appSettings.read("speedBackendPurchase") === "1" ? "unlocked":"locked" } - onPurchaseFailed: { + function onPurchaseFailed() { purchaseBt.text = qsTr("Purchase failed") purchaseBt.enabled = false buttonTextResetTimer.start() diff --git a/resources/qml/main.qml b/resources/qml/main.qml index a02cf12..0c543ef 100644 --- a/resources/qml/main.qml +++ b/resources/qml/main.qml @@ -141,7 +141,8 @@ Window { RowLayout { - anchors.fill: parent + width: toolBar.width + height: toolBar.height spacing: width * 0.02 @@ -162,9 +163,10 @@ Window { Column { Layout.fillWidth: true + Layout.alignment: Layout.Center height: childrenRect.height - width: parent.width - extraComponentLoader.width - toolButton.width - 3 * parent.spacing + //width: parent.width - extraComponentLoader.width - toolButton.width - 3 * parent.spacing Label { id: toolBarTitleLa @@ -248,28 +250,29 @@ Window { height: parent.height - Layout.alignment: Layout.Right + Layout.alignment: Layout.Center + + active: true onStatusChanged: { - //console.log("loader status changed: " + status) + console.log("LOADER status changed: " + status) - if(status == 0){ - extraComponentLoader.Layout.preferredWidth = 0 - } - else { + if(status === Loader.Ready){ + console.log("set loader width to: " + extraComponentLoader.Layout.preferredWidth + " for a item width of: " + extraComponentLoader.item.implicitWidth) extraComponentLoader.item.width = extraComponentLoader.item.implicitWidth extraComponentLoader.Layout.preferredWidth = extraComponentLoader.item.width widthChangedCon.target = extraComponentLoader.item } - - //console.log("set loader width to: " + extraComponentLoader.Layout.preferredWidth + " for a item width of: " + extraComponentLoader.item.implicitWidth) + else { + extraComponentLoader.Layout.preferredWidth = 0 + } } //sourceComponent: mainStack.currentItem.headerComponent Connections { target: mainStack - onCurrentItemChanged: { + function onCurrentItemChanged() { secondCon.target = mainStack.currentItem disappearNa.start() } @@ -277,14 +280,14 @@ Window { Connections { id: secondCon - onHeaderComponentChanged: { + function onHeaderComponentChanged() { disappearNa.start() } } Connections { id: widthChangedCon - onImplicitWidthChanged:{ + function onImplicitWidthChanged() { extraComponentLoader.item.width = extraComponentLoader.item.implicitWidth extraComponentLoader.Layout.preferredWidth = extraComponentLoader.item.implicitWidth } @@ -343,6 +346,9 @@ Window { onRunningChanged: { if(!running){ + console.log("SETTING HEADER COMP") + extraComponentLoader.Layout.preferredWidth = 0 + extraComponentLoader.sourceComponent = null extraComponentLoader.sourceComponent = mainStack.currentItem.headerComponent appearNa.start() } diff --git a/resources/qml/qml.qrc b/resources/qml/qml.qrc index fdb6266..1d768ea 100644 --- a/resources/qml/qml.qrc +++ b/resources/qml/qml.qrc @@ -22,5 +22,6 @@ Pages/CalendarPage.qml Pages/BRWidgetPage.qml Pages/ResultPage.qml + Components/SelectorPopup.qml diff --git a/sources/brcompetition.cpp b/sources/brcompetition.cpp index 9e106db..0a219cd 100644 --- a/sources/brcompetition.cpp +++ b/sources/brcompetition.cpp @@ -4,6 +4,8 @@ BRCompetition::BRCompetition(BRProvider* provider, BRWidget::BRFederation federation, int id, BRCompetitionData initialData) : BRWidget(provider, federation, id) { this->currentCategory = nullptr; + this->eventWebsiteUrl = ""; + this->pinned = false; this->setData(initialData); } @@ -50,6 +52,18 @@ QList BRCompetition::getInfosheetUrls() { return this->infosheetUrls; } +bool BRCompetition::getPinned() { + return this->pinned; +} + +void BRCompetition::setPinned(bool pinned) { + if(this->pinned == pinned) + return; + + this->pinned= pinned; + emit this->pinnedChanged(); +} + QList BRCompetition::getCategoriesQML() { return this->listToQmlList(this->categories); } @@ -97,6 +111,7 @@ BRWidget::BRWidgetStatusCode BRCompetition::load() { this->eventWebsiteUrl, this->infosheetUrls, + this->pinned, this->currentCategory, this->categories }; diff --git a/sources/brleague.cpp b/sources/brleague.cpp index 7a46e0c..cefff79 100644 --- a/sources/brleague.cpp +++ b/sources/brleague.cpp @@ -4,7 +4,8 @@ BRLeague::BRLeague(BRProvider* provider, BRWidget::BRFederation federation, int id, BRLeagueData initialData) : BRWidget(provider, federation, id) { this->competitions = {}; - this->competitions = {}; + connect(this, &BRLeague::stateChanged, this, &BRLeague::enabledChanged); + this->setState(Configured); this->setData(initialData); } @@ -16,6 +17,19 @@ QColor BRLeague::getColor() { return this->color; } + +bool BRLeague::getEnabled() { + return this->enabled && this->state == Loaded; +} + +void BRLeague::setEnabled(bool enabled) { + if(this->enabled == enabled) + return; + + this->enabled = enabled; + emit this->enabledChanged(); +} + QList BRLeague::getCompetitions() { return this->competitions; } @@ -38,8 +52,10 @@ void BRLeague::setData(BRLeagueData data) { this->competitions.clear(); this->competitions = data.competitions; - for(BRCompetition* competition : this->competitions) + for(BRCompetition* competition : this->competitions) { competition->setLeague(this); + connect(competition, &BRCompetition::pinnedChanged, this, &BRLeague::competitionsChanged); + } emit this->competitionsChanged(); } @@ -49,6 +65,16 @@ void BRLeague::setData(BRLeagueData data) { this->cups = data.cups; emit this->cupsChanged(); } + + if(this->competitions.length() > 0 || this->cups.length() > 0) + this->setState(Loaded); + else + this->setState(Configured); + + if(data.enabled != this->enabled) { + this->enabled = data.enabled; + emit this->enabledChanged(); + } } @@ -56,12 +82,13 @@ BRWidget::BRWidgetStatusCode BRLeague::load() { if(this->getProvider() == nullptr) return BRWidget::NoProviderError; - // reload all comp data using our providers + this->setState(Loading); BRLeagueData newData { this, this->name, this->color, + this->enabled, this->competitions, this->cups }; diff --git a/sources/brproviderdr.cpp b/sources/brproviderdr.cpp index 5ffd407..31f3c5c 100644 --- a/sources/brproviderdr.cpp +++ b/sources/brproviderdr.cpp @@ -143,13 +143,16 @@ void BRProviderDr::parseSeasonData(BRSeason::BRSeasonData* seasonData, int id, Q seasonData->nativeMultiLeagueSupport = true; seasonData->name = QString::number(id); + qDebug() << "Parsing season: " << seasonData->name; + BRWidget::BRFederation federation = BRWidget::BRFederation(rawData["federation"].toInt(0)); - // insert the leagues - for(QVariantMap leagueVar : this->leagues[federation]) { - BRLeague* league = this->getLeague(federation, leagueVar["id"].toInt(), this->parseLeagueData(leagueVar, rawData)); - seasonData->leagues.append(league); - } + // insert the leagues if the season is the current one + if(seasonData->name == rawData["year"].toString()) + for(QVariantMap leagueVar : this->leagues[federation]) { + BRLeague* league = this->getLeague(federation, leagueVar["id"].toInt(), this->parseLeagueData(leagueVar, rawData)); + seasonData->leagues.append(league); + } } BRWidget::BRWidgetStatusCode BRProviderDr::getWidgetData(BRLeague::BRLeagueData* leagueData) { @@ -165,8 +168,9 @@ BRLeague::BRLeagueData BRProviderDr::parseLeagueData(QVariantMap leaguePropertie data.name = leagueProperties["name"].toString(); data.color = QColor(leagueProperties["color"].toString()); + data.enabled = true; - qDebug() << "Adding league: " << data.name; + qDebug() << "- Parsing league: " << data.name; // parse competitions QVariantList competitionsVar = rawData["competitions"].toList(); @@ -180,7 +184,6 @@ BRLeague::BRLeagueData BRProviderDr::parseLeagueData(QVariantMap leaguePropertie if(leagueProperties["leagueIDs"].toList().contains(competitionMap["cat_id"].toInt())) { BRCompetition* competition = this->getCompetition(federation, competitionVar.toMap()["WetId"].toInt(), this->parseCompetitionData(competitionMap, federation)); data.competitions.append(competition); - qDebug() << "- Adding competition: " << competition->getName(); } } @@ -208,26 +211,26 @@ BRWidget::BRWidgetStatusCode BRProviderDr::getWidgetData(BRCompetition::BRCompet // reload all data BRCategory* currentCategory = competitionData->competition->getCurrentCategory(); - // load category data - QString competitionId = QString::number(currentCategory->getCompetition()->getId()); - QString categoryId = QString::number(currentCategory->getId()); - QString requestUrl = "https://www.digitalrock.de/egroupware/ranking/json.php?comp=" + competitionId + "&cat=" + categoryId; + // load category data + QString competitionId = QString::number(currentCategory->getCompetition()->getId()); + QString categoryId = QString::number(currentCategory->getId()); + QString requestUrl = "https://www.digitalrock.de/egroupware/ranking/json.php?comp=" + competitionId + "&cat=" + categoryId; - if(currentCategory->getCurrentRound() != nullptr) - requestUrl += "&route=" + QString::number(currentCategory->getCurrentRound()->getId()); + if(currentCategory->getCurrentRound() != nullptr && currentCategory->getCurrentRound()->getId() >= 0) + requestUrl += "&route=" + QString::number(currentCategory->getCurrentRound()->getId()); - QVariantMap ret = this->serverRequest(QUrl(requestUrl)); + QVariantMap ret = this->serverRequest(QUrl(requestUrl)); - if(ret["status"] != 200){ - // request was a failure - return BRWidget::BRWidgetStatusCode(ret["status"].toInt()); - } + if(ret["status"] != 200){ + // request was a failure + return BRWidget::BRWidgetStatusCode(ret["status"].toInt()); + } - QVariantMap data = QJsonDocument::fromJson(ret["text"].toString().toUtf8()).toVariant().toMap(); + QVariantMap data = QJsonDocument::fromJson(ret["text"].toString().toUtf8()).toVariant().toMap(); - this->parseCompetitionData(competitionData, data, competitionData->competition->getFederation()); + this->parseCompetitionData(competitionData, data, competitionData->competition->getFederation()); - return BRWidget::Success; + return BRWidget::Success; } BRCompetition::BRCompetitionData BRProviderDr::parseCompetitionData(QVariantMap rawData, BRWidget::BRFederation federation) { @@ -241,6 +244,8 @@ BRCompetition::BRCompetitionData BRProviderDr::parseCompetitionData(QVariantMap data.name = rawData["name"].toString(); + qDebug() << "-- Parsing competition: " << data.name; + if(disciplineTranslations.contains(rawData["discipline"].toString())) data.discipline = disciplineTranslations[rawData["discipline"].toString()]; @@ -249,7 +254,7 @@ BRCompetition::BRCompetitionData BRProviderDr::parseCompetitionData(QVariantMap if(rawData.contains("date_end")) data.endDate = QDate::fromString(rawData["date_end"].toString(), "yyyy-MM-dd"); - if(rawData.contains("hompage")) + if(rawData.contains("homepage")) data.eventWebsiteUrl = rawData["homepage"].toString(); // load infosheet URLs @@ -306,7 +311,14 @@ void BRProviderDr::parseCompetitionData(BRCompetition::BRCompetitionData* compet qDebug() << "Loading category: " << categoryData.name; - QVariantMap roundList = rawData["route_names"].toMap(); + QVariantMap roundList; + // check if route_names are given: + if(rawData.contains("route_names")) + roundList = rawData["route_names"].toMap(); + else + // if they are not -> insert Qualification + roundList.insert("-1", "Qualifikation"); + // load rounds for(QString roundId : roundList.keys()) { if(roundId.toInt() > categoryMap["route_order"].toInt()) @@ -335,6 +347,7 @@ void BRProviderDr::parseCompetitionData(BRCompetition::BRCompetitionData* compet if(categoryData.currentRound != nullptr) { BRRound::BRRoundData roundData = categoryData.currentRound->getData(); + roundData.results = {}; // load results QVariantList resultList = rawData["participants"].toList(); for(QVariant resultVar : resultList) { @@ -355,11 +368,10 @@ void BRProviderDr::parseCompetitionData(BRCompetition::BRCompetitionData* compet // load result QString resultNumber = categoryData.currentRound->getId() < 0 ? "":QString::number(categoryData.currentRound->getId()); - qDebug() << "Adding result: rank: " << resultMap["result_rank"]; BRResult::BRResultData resultData; resultData.rank = resultMap["result_rank"].toInt(); resultData.athlete = athlete; - BRResult* result = this->getResult(categoryData.category->getFederation(), -1, resultData); + BRResult* result = this->getResult(federation, -1, resultData); roundData.results.append(result); } diff --git a/sources/brprovidervl.cpp b/sources/brprovidervl.cpp index 5a30ebc..42a8741 100644 --- a/sources/brprovidervl.cpp +++ b/sources/brprovidervl.cpp @@ -103,6 +103,7 @@ void BRProviderVl::parseLeagueData(BRLeague::BRLeagueData* data, QVariantMap raw data->name = rawData["league"].toString(); data->color = QColor("#ffffff"); // TODO + data->enabled = true; qDebug() << "Adding league: " << data->name; diff --git a/sources/brseason.cpp b/sources/brseason.cpp index b6bebfc..edf115b 100644 --- a/sources/brseason.cpp +++ b/sources/brseason.cpp @@ -7,6 +7,7 @@ BRSeason::BRSeason(BRProvider* provider, BRWidget::BRFederation federation, int { connect(this, &BRSeason::leaguesChanged, this, &BRSeason::competitionsChanged); connect(this, &BRSeason::leaguesChanged, this, &BRSeason::cupsChanged); + this->leagues = {}; this->setData(initialData); } @@ -30,7 +31,12 @@ QList BRSeason::getCompetitionsQML() { QList allCompetitions; for(BRLeague* league : this->leagues) { - allCompetitions.append(league->getCompetitions()); + if(league->getEnabled()) + allCompetitions.append(league->getCompetitions()); + else + for(BRCompetition* competition : league->getCompetitions()) + if(competition->getPinned()) + allCompetitions.append(competition); } std::sort(allCompetitions.begin(), allCompetitions.end(), BRCompetition::lessThan); @@ -61,6 +67,7 @@ void BRSeason::setData(BRSeasonData data) { for(BRLeague* league : this->leagues) { connect(league, &BRLeague::competitionsChanged, this, &BRSeason::competitionsChanged); + connect(league, &BRLeague::enabledChanged, this, &BRSeason::competitionsChanged); connect(league, &BRLeague::cupsChanged, this, &BRSeason::cupsChanged); } } diff --git a/sources/brwidget.cpp b/sources/brwidget.cpp index 758545f..761003a 100644 --- a/sources/brwidget.cpp +++ b/sources/brwidget.cpp @@ -4,6 +4,20 @@ BRWidget::BRWidget(BRProvider* provider, BRFederation federation, int id) : QObject(provider), provider(provider), federation(federation), id(id) { + this->state = Unconfigured; +} + + +BRWidget::BRWidgetState BRWidget::getState() const { + return this->state; +} + +void BRWidget::setState(BRWidgetState state) { + if(this->state == state) + return; + + this->state = state; + emit this->stateChanged(); } BRWidget::BRFederation BRWidget::getFederation() const { diff --git a/sources/main.cpp b/sources/main.cpp index cfe1455..0faf879 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -54,6 +54,7 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType("de.itsblue.blueRock", 2, 0, "BRResult", "BRResult is not creatable"); qmlRegisterUncreatableType("de.itsblue.blueRock", 2, 0, "BRWidget", "BRWidget is not creatable"); qRegisterMetaType("BRWidget::BRFederation"); + qRegisterMetaType("BRWidget::BRWidgetState"); qRegisterMetaType("BRWidget::BRWidgetStatusCode"); //qmlRegisterType("de.itsblue.blueRock", 2, 0, "BRController");