diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f3292aa --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +sudo: required + +arch: + packages: + - plasma-framework + # build deps + - cmake + - extra-cmake-modules + - python + # test + - xorg-server-xvfb + # additional targets + - clang + - cppcheck + script: + - export DISPLAY=:99.0 + - git clone https://github.com/arcan1s/awesome-widgets/ + - cd awesome-widgets; git submodule update --init --recursive + - mkdir awesome-widgets/build + - cd awesome-widgets/build; cmake -DKDE_INSTALL_USE_QT_SYS_PATHS=ON -DCMAKE_BUILD_TYPE=Optimization -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_FUTURE=ON -DBUILD_TESTING=ON ../sources + - cd awesome-widgets/build; make + - cd awesome-widgets/build; make cppcheck + - cd awesome-widgets/build; make clangformat && ( [ `git status -s | wc -l` -eq 0 ] || exit 1 ) + - cd awesome-widgets/build; xvfb-run make test + - sleep 3 + +script: + - "curl -s https://raw.githubusercontent.com/mikkeloscar/arch-travis/master/arch-travis.sh | bash" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3ace2e4..982ae08 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,6 +54,7 @@ for more details. To avoid manual labor there is automatic cmake target named ``` * C-like `NULL`, use `nullptr` instead. + * C-like constant definition, use `const vartype foo = bar` definition instead. * It is highly recommended to avoid implicit casts. Exception `nullptr` casts to boolean, e.g.: diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt index 18aefd8..343d534 100644 --- a/sources/CMakeLists.txt +++ b/sources/CMakeLists.txt @@ -50,14 +50,14 @@ if (CMAKE_COMPILER_IS_GNUCXX) # avoid newer gcc warnings add_definitions(-D_DEFAULT_SOURCE) elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -stdlib=libc++") + set(CMAKE_CXX_FLAGS "-Wall -std=c++11") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG") # linker flags - set(CMAKE_EXE_LINKER_FLAGS "-lc++abi") - set(CMAKE_MODULE_LINKER_FLAGS "-lc++abi") - set(CMAKE_SHARED_LINKER_FLAGS "-lc++abi") +# set(CMAKE_EXE_LINKER_FLAGS "-lc++abi") +# set(CMAKE_MODULE_LINKER_FLAGS "-lc++abi") +# set(CMAKE_SHARED_LINKER_FLAGS "-lc++abi") else () message(FATAL_ERROR "Unknown compiler") endif () @@ -65,6 +65,9 @@ if (CMAKE_BUILD_TYPE MATCHES Debug) set(CMAKE_VERBOSE_MAKEFILE ON) endif () +# required by successfully coverity and cppcheck build +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + set(PROJECT_TRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty) set(PROJECT_LIBRARY awesomewidgets) set(PROJECT_MONITORSOURCES extsysmonsources) @@ -79,6 +82,7 @@ add_subdirectory(awesomewidgets) add_subdirectory(extsysmonsources) add_subdirectory(extsysmon) if (BUILD_PLASMOIDS) + add_subdirectory(qml) add_subdirectory(awesome-widget) add_subdirectory(desktop-panel) add_subdirectory(translations) @@ -89,3 +93,4 @@ if (BUILD_TESTING) endif () include(packages-recipe.cmake) + diff --git a/sources/awdebug.cpp b/sources/awdebug.cpp index 09e4ea5..bbe0166 100644 --- a/sources/awdebug.cpp +++ b/sources/awdebug.cpp @@ -16,11 +16,14 @@ ***************************************************************************/ +#include + #include "awdebug.h" Q_LOGGING_CATEGORY(LOG_AW, "org.kde.plasma.awesomewidget", QtMsgType::QtWarningMsg) +Q_LOGGING_CATEGORY(LOG_DBUS, "org.kde.plasma.awdbus", QtMsgType::QtWarningMsg) Q_LOGGING_CATEGORY(LOG_DP, "org.kde.plasma.desktoppanel", QtMsgType::QtWarningMsg) Q_LOGGING_CATEGORY(LOG_ESM, "org.kde.plasma.extsysmon", QtMsgType::QtWarningMsg) @@ -30,7 +33,80 @@ Q_LOGGING_CATEGORY(LOG_LIB, "org.kde.plasma.awesomewidgets", QtMsgType::QtWarningMsg) -const QStringList getBuildData() +QString AWDebug::getAboutText(const QString type) +{ + QString text; + if (type == QString("header")) { + text = QString(NAME); + } else if (type == QString("version")) { + text = i18n("Version %1 (build date %2)", QString(VERSION), + QString(BUILD_DATE)); + if (!QString(COMMIT_SHA).isEmpty()) + text += QString(" (%1)").arg(QString(COMMIT_SHA)); + } else if (type == QString("description")) { + text = i18n("A set of minimalistic plasmoid widgets"); + } else if (type == QString("links")) { + text = i18n("Links:") + QString(""); + } else if (type == QString("copy")) { + text = QString("© %1 %3
") + .arg(QString(DATE)) + .arg(QString(EMAIL)) + .arg(QString(AUTHOR)) + + i18n("This software is licensed under %1", QString(LICENSE)) + + QString("
"); + } else if (type == QString("translators")) { + QStringList translatorList = QString(TRANSLATORS).split(QChar(',')); + for (auto &translator : translatorList) + translator = QString("
  • %1
  • ").arg(translator); + text = i18n("Translators:") + QString(""); + } else if (type == QString("3rdparty")) { + QStringList trdPartyList + = QString(TRDPARTY_LICENSE) + .split(QChar(';'), QString::SkipEmptyParts); + for (int i = 0; i < trdPartyList.count(); i++) + trdPartyList[i] + = QString("
  • %1 (%2 license)
  • ") + .arg(trdPartyList.at(i).split(QChar(','))[0]) + .arg(trdPartyList.at(i).split(QChar(','))[1]) + .arg(trdPartyList.at(i).split(QChar(','))[2]); + text = i18n("This software uses:") + QString(""); + } else if (type == QString("thanks")) { + QStringList thanks = QString(SPECIAL_THANKS) + .split(QChar(';'), QString::SkipEmptyParts); + for (int i = 0; i < thanks.count(); i++) + thanks[i] = QString("
  • %1
  • ") + .arg(thanks.at(i).split(QChar(','))[0]) + .arg(thanks.at(i).split(QChar(','))[1]); + text = i18n("Special thanks to:") + QString(""); + } + + return text; +} + + +QStringList AWDebug::getBuildData() { QStringList metadata; metadata.append(QString("=== Awesome Widgets configuration details ===")); @@ -41,12 +117,14 @@ const QStringList getBuildData() metadata.append(QString(" BUILD_DATE: %1").arg(BUILD_DATE)); // configuration metadata.append(QString("API details:")); - metadata.append(QString(" AWGIAPI: %1").arg(AWGIAPI)); - metadata.append(QString(" AWEQAPI: %1").arg(AWEQAPI)); - metadata.append(QString(" AWESAPI: %1").arg(AWESAPI)); - metadata.append(QString(" AWEUAPI: %1").arg(AWEUAPI)); - metadata.append(QString(" AWEWAPI: %1").arg(AWEWAPI)); - metadata.append(QString(" AWEFAPI: %1").arg(AWEFAPI)); + metadata.append(QString(" AW_GRAPHITEM_API: %1").arg(AW_GRAPHITEM_API)); + metadata.append(QString(" AW_EXTQUOTES_API: %1").arg(AW_EXTQUOTES_API)); + metadata.append(QString(" AW_EXTSCRIPT_API: %1").arg(AW_EXTSCRIPT_API)); + metadata.append( + QString(" AW_EXTUPGRADE_API: %1").arg(AW_EXTUPGRADE_API)); + metadata.append( + QString(" AW_EXTWEATHER_API: %1").arg(AW_EXTWEATHER_API)); + metadata.append(QString(" AW_FORMATTER_API: %1").arg(AW_FORMATTER_API)); metadata.append(QString(" REQUEST_TIMEOUT: %1").arg(REQUEST_TIMEOUT)); metadata.append(QString(" TIME_KEYS: %1").arg(TIME_KEYS)); metadata.append(QString(" STATIC_KEYS: %1").arg(STATIC_KEYS)); diff --git a/sources/awdebug.h b/sources/awdebug.h index bae3ba4..f24dab0 100644 --- a/sources/awdebug.h +++ b/sources/awdebug.h @@ -23,21 +23,25 @@ #include "version.h" -#ifndef LOG_FORMAT -#define LOG_FORMAT \ - "[%{time process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%{if-" \ - "warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{" \ - "category}][%{function}] %{message}" -#endif /* LOG_FORMAT */ +namespace AWDebug +{ +const char LOG_FORMAT[] = "[%{time " + "process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%" + "{if-warning}WW%{endif}%{if-critical}CC%{endif}%{if-" + "fatal}FF%{endif}][%{category}][%{function}] " + "%{message}"; + +QString getAboutText(const QString type); +QStringList getBuildData(); +} Q_DECLARE_LOGGING_CATEGORY(LOG_AW) +Q_DECLARE_LOGGING_CATEGORY(LOG_DBUS) Q_DECLARE_LOGGING_CATEGORY(LOG_DP) Q_DECLARE_LOGGING_CATEGORY(LOG_ESM) Q_DECLARE_LOGGING_CATEGORY(LOG_ESS) Q_DECLARE_LOGGING_CATEGORY(LOG_LIB) -const QStringList getBuildData(); - #endif /* AWDEBUG_H */ diff --git a/sources/awesome-widget/package/contents/config/main.xml b/sources/awesome-widget/package/contents/config/main.xml index 23d14c7..063a99e 100644 --- a/sources/awesome-widget/package/contents/config/main.xml +++ b/sources/awesome-widget/package/contents/config/main.xml @@ -62,6 +62,15 @@ ( ) + + 100 + + + false + + + + @@ -138,6 +147,12 @@ normal + + normal + + + #000000 + diff --git a/sources/awesome-widget/package/contents/ui/about.qml b/sources/awesome-widget/package/contents/ui/about.qml index e33237d..7f39ffe 100644 --- a/sources/awesome-widget/package/contents/ui/about.qml +++ b/sources/awesome-widget/package/contents/ui/about.qml @@ -16,112 +16,24 @@ ***************************************************************************/ import QtQuick 2.0 -import QtQuick.Controls 1.3 as QtControls -import QtQuick.Layouts 1.0 as QtLayouts import org.kde.plasma.private.awesomewidget 1.0 Item { id: aboutPage + // backend AWActions { id: awActions } width: childrenRect.width height: childrenRect.height - implicitWidth: pageColumn.implicitWidth - implicitHeight: pageColumn.implicitHeight - property bool debug: awActions.isDebugEnabled() - - - Column { - id: pageColumn - anchors.fill: parent - QtControls.TabView { - height: parent.height - width: parent.width - QtControls.Tab { - anchors.margins: 10.0 - title: i18n("About") - - QtLayouts.ColumnLayout { - QtControls.Label { - QtLayouts.Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - text: awActions.getAboutText("header") - } - - QtControls.Label { - QtLayouts.Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - text: awActions.getAboutText("version") - } - - QtControls.Label { - QtLayouts.Layout.fillWidth: true - horizontalAlignment: Text.AlignJustify - text: awActions.getAboutText("description") - } - - QtControls.Label { - QtLayouts.Layout.fillWidth: true - horizontalAlignment: Text.AlignLeft - textFormat: Text.RichText - text: awActions.getAboutText("links") - onLinkActivated: Qt.openUrlExternally(link) - } - - QtControls.Label { - QtLayouts.Layout.fillHeight: true - QtLayouts.Layout.fillWidth: true - font.capitalization: Font.SmallCaps - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignBottom - textFormat: Text.RichText - text: awActions.getAboutText("copy") - } - } - } - - QtControls.Tab { - anchors.margins: 10.0 - title: i18n("Acknowledgment") - - QtLayouts.ColumnLayout { - QtControls.Label { - QtLayouts.Layout.fillWidth: true - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignJustify - text: awActions.getAboutText("translators") - } - - QtControls.Label { - QtLayouts.Layout.fillWidth: true - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignJustify - textFormat: Text.RichText - text: awActions.getAboutText("3rdparty") - onLinkActivated: Qt.openUrlExternally(link) - } - - QtControls.Label { - QtLayouts.Layout.fillHeight: true - QtLayouts.Layout.fillWidth: true - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignJustify - verticalAlignment: Text.AlignTop - textFormat: Text.RichText - text: awActions.getAboutText("thanks") - onLinkActivated: Qt.openUrlExternally(link) - } - } - } - } + AboutTab { + textProvider: awActions } - Component.onCompleted: { if (debug) console.debug() } diff --git a/sources/awesome-widget/package/contents/ui/advanced.qml b/sources/awesome-widget/package/contents/ui/advanced.qml index d70eddb..a4d29a8 100644 --- a/sources/awesome-widget/package/contents/ui/advanced.qml +++ b/sources/awesome-widget/package/contents/ui/advanced.qml @@ -17,7 +17,6 @@ import QtQuick 2.0 import QtQuick.Controls 1.3 as QtControls -import QtQuick.Dialogs 1.2 as QtDialogs import org.kde.plasma.private.awesomewidget 1.0 @@ -28,9 +27,6 @@ Item { AWActions { id: awActions } - AWConfigHelper { - id: awConfig - } width: childrenRect.width height: childrenRect.height @@ -50,420 +46,210 @@ Item { property alias cfg_width: widgetWidth.value property alias cfg_interval: update.value property alias cfg_queueLimit: queueLimit.value - property string cfg_tempUnits: tempUnits.currentText - property alias cfg_customTime: customTime.text - property alias cfg_customUptime: customUptime.text - property alias cfg_acOnline: acOnline.text - property alias cfg_acOffline: acOffline.text + property string cfg_tempUnits: tempUnits.value + property alias cfg_customTime: customTime.value + property alias cfg_customUptime: customUptime.value + property alias cfg_acOnline: acOnline.value + property alias cfg_acOffline: acOffline.value + property alias cfg_telemetryCount: telemetryCount.value + property alias cfg_telemetryRemote: telemetryRemote.checked + property alias cfg_telemetryId: telemetryId.value Column { id: pageColumn anchors.fill: parent - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.heigth - width: parent.width * 2 / 5 - } - QtControls.CheckBox { - id: background - width: parent.width * 3 / 5 - text: i18n("Enable background") - } + + CheckBoxSelector { + id: background + text: i18n("Enable background") } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.heigth - width: parent.width * 2 / 5 - } - QtControls.CheckBox { - id: translate - width: parent.width * 3 / 5 - text: i18n("Translate strings") - } + CheckBoxSelector { + id: translate + text: i18n("Translate strings") } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.heigth - width: parent.width * 2 / 5 - } - QtControls.CheckBox { - id: wrapNewLines - width: parent.width * 3 / 5 - text: i18n("Wrap new lines") - } + CheckBoxSelector { + id: wrapNewLines + text: i18n("Wrap new lines") } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.heigth - width: parent.width * 2 / 5 - } - QtControls.CheckBox { - id: wordWrap - width: parent.width * 3 / 5 - text: i18n("Enable word wrap") - } + CheckBoxSelector { + id: wordWrap + text: i18n("Enable word wrap") } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.heigth - width: parent.width * 2 / 5 - } - QtControls.CheckBox { - id: notify - width: parent.width * 3 / 5 - text: i18n("Enable notifications") - } + CheckBoxSelector { + id: notify + text: i18n("Enable notifications") } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.heigth - width: parent.width * 2 / 5 - } - QtControls.CheckBox { - id: updates - width: parent.width * 3 / 5 - text: i18n("Check updates on startup") - } + CheckBoxSelector { + id: updates + text: i18n("Check updates on startup") } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.heigth - width: parent.width * 2 / 5 - } - QtControls.CheckBox { - id: optimize - width: parent.width * 3 / 5 - text: i18n("Optimize subscription") - } + CheckBoxSelector { + id: optimize + text: i18n("Optimize subscription") } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Widget height, px") - } - QtControls.SpinBox { - id: widgetHeight - width: parent.width * 3 / 5 - minimumValue: 0 - maximumValue: 4096 - stepSize: 50 - value: plasmoid.configuration.height - } + IntegerSelector { + id: widgetHeight + maximumValue: 4096 + minimumValue: 0 + stepSize: 50 + text: i18n("Widget height, px") + value: plasmoid.configuration.height } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Widget width, px") - } - QtControls.SpinBox { - id: widgetWidth - width: parent.width * 3 / 5 - minimumValue: 0 - maximumValue: 4096 - stepSize: 50 - value: plasmoid.configuration.width - } + IntegerSelector { + id: widgetWidth + maximumValue: 4096 + minimumValue: 0 + stepSize: 50 + text: i18n("Widget width, px") + value: plasmoid.configuration.width } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Time interval") - } - QtControls.SpinBox { - id: update - width: parent.width * 3 / 5 - minimumValue: 1000 - maximumValue: 10000 - stepSize: 500 - value: plasmoid.configuration.interval - } + IntegerSelector { + id: update + maximumValue: 10000 + minimumValue: 1000 + stepSize: 500 + text: i18n("Time interval") + value: plasmoid.configuration.interval } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Messages queue limit") - } - QtControls.SpinBox { - id: queueLimit - width: parent.width * 3 / 5 - minimumValue: 0 - maximumValue: 99 - stepSize: 1 - value: plasmoid.configuration.queueLimit - } + IntegerSelector { + id: queueLimit + maximumValue: 99 + minimumValue: 0 + stepSize: 1 + text: i18n("Messages queue limit") + value: plasmoid.configuration.queueLimit } - Row { + ComboBoxSelector { + id: tempUnits + model: [ + { + 'label': i18n("Celsius"), + 'name': "Celsius" + }, + { + 'label': i18n("Fahrenheit"), + 'name': "Fahrenheit" + }, + { + 'label': i18n("Kelvin"), + 'name': "Kelvin" + }, + { + 'label': i18n("Reaumur"), + 'name': "Reaumur" + }, + { + 'label': i18n("cm^-1"), + 'name': "cm^-1" + }, + { + 'label': i18n("kJ/mol"), + 'name': "kJ/mol" + }, + { + 'label': i18n("kcal/mol"), + 'name': "kcal/mol" + } + ] + text: i18n("Temperature units") + value: plasmoid.configuration.tempUnits + onValueEdited: cfg_tempUnits = newValue + } + + LineSelector { + id: customTime + text: i18n("Custom time format") + value: plasmoid.configuration.customTime + } + + LineSelector { + id: customUptime + text: i18n("Custom uptime format") + value: plasmoid.configuration.customUptime + } + + LineSelector { + id: acOnline + text: i18n("AC online tag") + value: plasmoid.configuration.acOnline + } + + LineSelector { + id: acOffline + text: i18n("AC offline tag") + value: plasmoid.configuration.acOffline + } + + QtControls.GroupBox { height: implicitHeight width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Temperature units") - } - QtControls.ComboBox { - id: tempUnits - width: parent.width * 3 / 5 - textRole: "label" - model: [ - { - 'label': i18n("Celsius"), - 'name': "Celsius" - }, - { - 'label': i18n("Fahrenheit"), - 'name': "Fahrenheit" - }, - { - 'label': i18n("Kelvin"), - 'name': "Kelvin" - }, - { - 'label': i18n("Reaumur"), - 'name': "Reaumur" - }, - { - 'label': i18n("cm^-1"), - 'name': "cm^-1" - }, - { - 'label': i18n("kJ/mol"), - 'name': "kJ/mol" - }, - { - 'label': i18n("kcal/mol"), - 'name': "kcal/mol" + title: i18n("Actions") + + Column { + height: implicitHeight + width: parent.width + ButtonSelector { + value: i18n("Drop key cache") + onButtonActivated: awActions.dropCache() + } + ButtonSelector { + ExportDialog { + id: saveConfigAs + configuration: plasmoid.configuration } - ] - onCurrentIndexChanged: cfg_tempUnits = model[currentIndex]["name"] - Component.onCompleted: { - if (debug) console.debug() - for (var i = 0; i < model.length; i++) { - if (model[i]["name"] == plasmoid.configuration.tempUnits) { - if (debug) console.info("Found", model[i]["name"], "on", i) - tempUnits.currentIndex = i + value: i18n("Export configuration") + onButtonActivated: saveConfigAs.open() + } + ButtonSelector { + ImportDialog { + id: loadConfigFrom + onConfigurationReceived: { + for (var key in configuration) + plasmoid.configuration[key] = configuration[key] } } + value: i18n("Import configuration") + onButtonActivated: loadConfigFrom.open() } } } - Row { + QtControls.GroupBox { height: implicitHeight width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Custom time format") - } - QtControls.TextField { - id: customTime - width: parent.width * 3 / 5 - text: plasmoid.configuration.customTime - } - } + title: i18n("Telemetry") - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Custom uptime format") - } - QtControls.TextField { - id: customUptime - width: parent.width * 3 / 5 - text: plasmoid.configuration.customUptime - } - } - - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("AC online tag") - } - QtControls.TextField { - id: acOnline - width: parent.width * 3 / 5 - text: plasmoid.configuration.acOnline - } - } - - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("AC offline tag") - } - QtControls.TextField { - id: acOffline - width: parent.width * 3 / 5 - text: plasmoid.configuration.acOffline - } - } - - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - } - QtControls.Button { - width: parent.width * 3 / 5 - text: i18n("Drop key cache") - onClicked: awActions.dropCache() - } - } - - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - } - QtControls.Button { - width: parent.width * 3 / 5 - text: i18n("Export configuration") - onClicked: saveConfigAs.open() - } - - QtDialogs.FileDialog { - id: saveConfigAs - selectExisting: false - title: i18n("Export") - folder: awConfig.configurationDirectory() - onAccepted: { - var status = awConfig.exportConfiguration( - plasmoid.configuration, - saveConfigAs.fileUrl.toString().replace("file://", "")) - if (status) { - messageDialog.title = i18n("Success") - messageDialog.text = i18n("Please note that binary files were not copied") - } else { - messageDialog.title = i18n("Ooops...") - messageDialog.text = i18n("Could not save configuration file") - } - messageDialog.open() + Column { + height: implicitHeight + width: parent.width + CheckBoxSelector { + id: telemetryRemote + text: i18n("Enable remote telemetry") } - } - - QtDialogs.MessageDialog { - id: messageDialog - standardButtons: QtDialogs.StandardButton.Ok - } - } - - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - } - QtControls.Button { - width: parent.width * 3 / 5 - text: i18n("Import configuration") - onClicked: openConfig.open() - } - - QtDialogs.FileDialog { - id: openConfig - title: i18n("Import") - folder: awConfig.configurationDirectory() - onAccepted: importSelection.open() - } - - QtDialogs.Dialog { - id: importSelection - - Column { - QtControls.CheckBox { - id: importPlasmoid - text: i18n("Import plasmoid settings") - } - - QtControls.CheckBox { - id: importExtensions - text: i18n("Import extensions") - } - - QtControls.CheckBox { - id: importAdds - text: i18n("Import additional files") - } + IntegerSelector { + id: telemetryCount + maximumValue: 10000 + minimumValue: 0 + stepSize: 50 + text: i18n("History count") + value: plasmoid.configuration.telemetryCount } - - onAccepted: { - if (debug) console.debug() - var importConfig = awConfig.importConfiguration( - openConfig.fileUrl.toString().replace("file://", ""), - importPlasmoid.checked, importExtensions.checked, - importAdds.checked) - for (var key in importConfig) - plasmoid.configuration[key] = importConfig[key] + LineSelector { + id: telemetryId + text: i18n("Telemetry ID") + value: plasmoid.configuration.telemetryId } } } diff --git a/sources/awesome-widget/package/contents/ui/appearance.qml b/sources/awesome-widget/package/contents/ui/appearance.qml index 6acfa72..620ec9b 100644 --- a/sources/awesome-widget/package/contents/ui/appearance.qml +++ b/sources/awesome-widget/package/contents/ui/appearance.qml @@ -16,11 +16,9 @@ ***************************************************************************/ import QtQuick 2.0 -import QtQuick.Controls 1.3 as QtControls -import QtQuick.Controls.Styles 1.3 as QtStyles -import QtQuick.Dialogs 1.1 as QtDialogs import org.kde.plasma.private.awesomewidget 1.0 +import "." Item { @@ -44,195 +42,68 @@ Item { 87: 5 } - property alias cfg_fontFamily: selectFont.text + property alias cfg_fontFamily: font.value property alias cfg_fontSize: fontSize.value - property string cfg_fontWeight: fontWeight.currentText - property string cfg_fontStyle: fontStyle.currentText - property alias cfg_fontColor: selectColor.text + property string cfg_fontWeight: fontWeight.value + property string cfg_fontStyle: fontStyle.value + property alias cfg_fontColor: selectColor.value + property alias cfg_textStyleColor: selectStyleColor.value + property string cfg_textStyle: textStyle.value Column { id: pageColumn anchors.fill: parent - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font") - } - QtControls.Button { - id: selectFont - width: parent.width * 2 / 3 - text: plasmoid.configuration.fontFamily - onClicked: { - if (debug) console.debug() - fontDialog.setFont() - fontDialog.visible = true - } - } + + FontSelector { + id: font + text: i18n("Font") + value: plasmoid.configuration.fontFamily } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font size") - } - QtControls.SpinBox { - id: fontSize - width: parent.width * 2 / 3 - minimumValue: 8 - maximumValue: 32 - stepSize: 1 - value: plasmoid.configuration.fontSize - } + IntegerSelector { + id: fontSize + maximumValue: 32 + minimumValue: 8 + stepSize: 1 + text: i18n("Font size") + value: plasmoid.configuration.fontSize } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font weight") - } - QtControls.ComboBox { - id: fontWeight - width: parent.width * 2 / 3 - textRole: "label" - model: [ - { - 'label': i18n("light"), - 'name': "light" - }, - { - 'label': i18n("normal"), - 'name': "normal" - }, - { - 'label': i18n("demi bold"), - 'name': "demibold" - }, - { - 'label': i18n("bold"), - 'name': "bold" - }, - { - 'label': i18n("black"), - 'name': "black" - } - ] - onCurrentIndexChanged: cfg_fontWeight = model[currentIndex]["name"] - Component.onCompleted: { - if (debug) console.debug() - for (var i = 0; i < model.length; i++) { - if (model[i]["name"] == plasmoid.configuration.fontWeight) { - if (debug) console.info("Found", model[i]["name"], "on", i) - fontWeight.currentIndex = i - } - } - } - } + ComboBoxSelector { + id: fontWeight + model: general.fontWeightModel + text: i18n("Font weight") + value: plasmoid.configuration.fontWeight + onValueEdited: cfg_fontWeight = newValue } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font style") - } - QtControls.ComboBox { - id: fontStyle - width: parent.width * 2 / 3 - textRole: "label" - model: [ - { - 'label': i18n("normal"), - 'name': "normal" - }, - { - 'label': i18n("italic"), - 'name': "italic" - } - ] - onCurrentIndexChanged: cfg_fontStyle = model[currentIndex]["name"] - Component.onCompleted: { - if (debug) console.debug() - for (var i = 0; i < model.length; i++) { - if (model[i]["name"] == plasmoid.configuration.fontStyle) { - if (debug) console.info("Found", model[i]["name"], "on", i) - fontStyle.currentIndex = i - } - } - } - } + ComboBoxSelector { + id: fontStyle + model: general.fontStyleModel + text: i18n("Font style") + value: plasmoid.configuration.fontStyle + onValueEdited: cfg_fontStyle = newValue } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font color") - } - QtControls.Button { - id: selectColor - width: parent.width * 2 / 3 - style: QtStyles.ButtonStyle { - background: Rectangle { - color: plasmoid.configuration.fontColor - } - } - text: plasmoid.configuration.fontColor - onClicked: colorDialog.visible = true - } + ColorSelector { + id: selectColor + text: i18n("Font color") + value: plasmoid.configuration.fontColor } - } - QtDialogs.ColorDialog { - id: colorDialog - title: i18n("Select a color") - color: selectColor.text - onAccepted: selectColor.text = colorDialog.color - } - - QtDialogs.FontDialog { - id: fontDialog - title: i18n("Select a font") - signal setFont - - onAccepted: { - if (debug) console.debug() - selectFont.text = fontDialog.font.family - fontSize.value = fontDialog.font.pointSize - fontStyle.currentIndex = fontDialog.font.italic ? 1 : 0 - fontWeight.currentIndex = weight[fontDialog.font.weight] + ComboBoxSelector { + id: textStyle + model: general.textStyleModel + text: i18n("Style") + value: plasmoid.configuration.textStyle + onValueEdited: cfg_textStyle = newValue } - onSetFont: { - if (debug) console.debug() - fontDialog.font = Qt.font({ - family: selectFont.text, - pointSize: fontSize.value > 0 ? fontSize.value : 12, - italic: fontStyle.currentIndex == 1, - weight: Font.Normal, - }) + + ColorSelector { + id: selectStyleColor + text: i18n("Style color") + value: plasmoid.configuration.textStyleColor } } diff --git a/sources/awesome-widget/package/contents/ui/dataengine.qml b/sources/awesome-widget/package/contents/ui/dataengine.qml index a536dee..6dcdf0d 100644 --- a/sources/awesome-widget/package/contents/ui/dataengine.qml +++ b/sources/awesome-widget/package/contents/ui/dataengine.qml @@ -52,21 +52,10 @@ Item { height: implicitHeight width: parent.width title: i18n("ACPI") - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("ACPI path") - } - QtControls.TextField { - width: parent.width * 3 / 5 - text: cfg_dataengine["ACPIPATH"] - onEditingFinished: cfg_dataengine["ACPIPATH"] = text - } + LineSelector { + text: i18n("ACPI path") + value: cfg_dataengine["ACPIPATH"] + onValueEdited: cfg_dataengine["ACPIPATH"] = newValue } } @@ -74,30 +63,28 @@ Item { height: implicitHeight width: parent.width title: i18n("GPU") - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("GPU device") - } - QtControls.ComboBox { - id: gpuDev - width: parent.width * 3 / 5 - model: ["auto", "disable", "ati", "nvidia"] - Component.onCompleted: { - if (debug) console.debug() - for (var i=0; iproject homepage") - onLinkActivated: Qt.openUrlExternally(link) + + AWInfoLabel {} + + HtmlDefaultFunctionsBar { + textArea: textPattern } - Row { - height: implicitHeight - width: parent.width - QtControls.Button { - width: parent.width * 3 / 15 - text: i18n("Bgcolor") - - onClicked: backgroundDialog.visible = true - - QtDialogs.ColorDialog { - id: backgroundDialog - title: i18n("Select a color") - onAccepted: { - var text = textPattern.text - textPattern.text = "" + - text + "" - } - } - } - QtControls.Button { - width: parent.width * 3 / 15 - text: i18n("Font") - iconName: "font" - - onClicked: { - if (debug) console.debug("Font button") - var defaultFont = { - "color": plasmoid.configuration.fontColor, - "family": plasmoid.configuration.fontFamily, - "size": plasmoid.configuration.fontSize - } - var font = awActions.getFont(defaultFont) - if (font.applied != 1) { - if (debug) console.debug("No font selected") - return - } - - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, - "" + - selected + "") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-indent-more" - - onClicked: { - if (debug) console.debug("Indent button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, selected + "
    \n") - } - } - - QtControls.Button { - width: parent.width / 15 - iconName: "format-text-bold" - - onClicked: { - if (debug) console.debug("Bold button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "" + selected + "") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-text-italic" - - onClicked: { - if (debug) console.debug("Italic button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "" + selected + "") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-text-underline" - - onClicked: { - if (debug) console.debug("Underline button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "" + selected + "") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-text-strikethrough" - - onClicked: { - if (debug) console.debug("Strike button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "" + selected + "") - } - } - - QtControls.Button { - width: parent.width / 15 - iconName: "format-justify-left" - - onClicked: { - if (debug) console.debug("Left button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "

    " + selected + "

    ") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-justify-center" - - onClicked: { - if (debug) console.debug("Center button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "

    " + selected + "

    ") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-justify-right" - - onClicked: { - if (debug) console.debug("Right button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "

    " + selected + "

    ") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-justify-fill" - - onClicked: { - if (debug) console.debug("Justify button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "

    " + selected + "

    ") - } - } + AWTagSelector { + backend: awKeys + notifyBackend: awActions + textArea: textPattern + groups: general.awTagRegexp } - Row { - height: implicitHeight - width: parent.width - QtControls.ComboBox { - width: parent.width * 2 / 5 - textRole: "label" - model: [ - { - 'label': i18n("AC"), - 'regexp': "^(ac|bat).*" - }, - { - 'label': i18n("Bars"), - 'regexp': "^bar.*" - }, - { - 'label': i18n("CPU"), - 'regexp': "^(cpu|gpu|la|ps|temp(?!erature)).*" - }, - { - 'label': i18n("Desktops"), - 'regexp': "^(n|t)?desktop(s)?" - }, - { - 'label': i18n("HDD"), - 'regexp': "^hdd.*" - }, - { - 'label': i18n("Memory"), - 'regexp': "^(mem|swap).*" - }, - { - 'label': i18n("Network"), - 'regexp': "^(netdev|(down|up(?!time)).*)" - }, - { - 'label': i18n("Music player"), - 'regexp': "(^|d|s)(album|artist|duration|progress|title)" - }, - { - 'label': i18n("Scripts"), - 'regexp': "^custom.*" - }, - { - 'label': i18n("Time"), - 'regexp': ".*time$" - }, - { - 'label': i18n("Quotes"), - 'regexp': "^(perc)?(ask|bid|price)(chg)?.*" - }, - { - 'label': i18n("Upgrades"), - 'regexp': "^pkgcount.*" - }, - { - 'label': i18n("Weathers"), - 'regexp': "^(weather(Id)?|humidity|pressure|temperature|timestamp)" - }, - { - 'label': i18n("Functions"), - 'regexp': "functions" - } - ] - onCurrentIndexChanged: { - if (debug) console.debug() - if (model[currentIndex]["regexp"] == "functions") - tags.model = ["{{\n\n}}", "template{{\n\n}}", - "aw_all<>{{}}", "aw_count<>{{}}", "aw_keys<>{{}}", - "aw_macro<>{{}}", "aw_names<>{{}}"] - else - tags.model = awKeys.dictKeys(true, model[currentIndex]["regexp"]) - if (debug) console.info("Init model", tags.model, "for", model[currentIndex]["label"]) - tags.currentIndex = -1 - } - } - QtControls.ComboBox { - id: tags - width: parent.width * 1 / 5 - } - QtControls.Button { - width: parent.width * 1 / 5 - text: i18n("Add") - - onClicked: { - if (!tags.currentText) return - if (debug) console.debug("Add tag button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, selected + "$" + tags.currentText) - } - } - QtControls.Button { - width: parent.width * 1 / 5 - text: i18n("Show value") - - onClicked: { - if (!tags.currentText) return - if (debug) console.debug("Show tag button") - var message = i18n("Tag: %1", tags.currentText) - message += "
    " - message += i18n("Value: %1", awKeys.valueByKey(tags.currentText)) - message += "
    " - message += i18n("Info: %1", awKeys.infoByKey(tags.currentText)) - awActions.sendNotification("tag", message) - } - } + AWExtensions { + id: extensions + backend: awKeys + textArea: textPattern + onUnlock: lock = false } - Row { - height: implicitHeight - width: parent.width - QtControls.Button { - width: parent.width * 3 / 10 - text: i18n("Edit bars") - onClicked: awKeys.editItem("graphicalitem") - } - QtControls.Button { - width: parent.width * 3 / 10 - text: i18n("Formatters") - onClicked: awFormatter.showDialog(awKeys.dictKeys(true)) - } - QtControls.Button { - width: parent.width * 5 / 15 - text: i18n("Preview") - onClicked: { - lock = false - awKeys.initKeys(textPattern.text, plasmoid.configuration.interval, - plasmoid.configuration.queueLimit, false) - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "view-history" - menu: QtControls.Menu { - id: historyConfig - Instantiator { - model: awTelemetryHandler.get("awwidgetconfig") - QtControls.MenuItem { - text: modelData - onTriggered: textPattern.text = modelData - } - onObjectAdded: historyConfig.insertItem(index, object) - onObjectRemoved: historyConfig.removeItem(object) - } - } - } - } - - QtControls.TextArea { + AWTextEditor { id: textPattern - width: parent.width - height: parent.height * 4 / 5 - textFormat: TextEdit.PlainText - text: plasmoid.configuration.text + backend: awKeys } } - QtDialogs.MessageDialog { - id: compiledText - modality: Qt.NonModal - title: i18n("Preview") - } - Component.onCompleted: { if (debug) console.debug() @@ -397,8 +94,7 @@ Item { if (lock) return if (debug) console.debug() - compiledText.text = newText.replace(/ /g, " ") - compiledText.open() + extensions.showMessage(newText) lock = true } } diff --git a/sources/awesome-widget/plugin/awabstractselector.cpp b/sources/awesome-widget/plugin/awabstractselector.cpp index 46215ac..2715974 100644 --- a/sources/awesome-widget/plugin/awabstractselector.cpp +++ b/sources/awesome-widget/plugin/awabstractselector.cpp @@ -21,13 +21,16 @@ #include "awdebug.h" -AWAbstractSelector::AWAbstractSelector(QWidget *parent) +AWAbstractSelector::AWAbstractSelector(QWidget *parent, + const QPair editable) : QWidget(parent) , ui(new Ui::AWAbstractSelector) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; ui->setupUi(this); + ui->comboBox_key->setEditable(editable.first); + ui->comboBox_value->setEditable(editable.second); connect(ui->comboBox_key, SIGNAL(currentIndexChanged(int)), this, SIGNAL(selectionChanged())); diff --git a/sources/awesome-widget/plugin/awabstractselector.h b/sources/awesome-widget/plugin/awabstractselector.h index 2dbc926..b421854 100644 --- a/sources/awesome-widget/plugin/awabstractselector.h +++ b/sources/awesome-widget/plugin/awabstractselector.h @@ -32,7 +32,9 @@ class AWAbstractSelector : public QWidget Q_OBJECT public: - explicit AWAbstractSelector(QWidget *parent = nullptr); + explicit AWAbstractSelector(QWidget *parent = nullptr, + const QPair editable + = {false, false}); virtual ~AWAbstractSelector(); QPair current() const; void init(const QStringList keys, const QStringList values, diff --git a/sources/awesome-widget/plugin/awactions.cpp b/sources/awesome-widget/plugin/awactions.cpp index e87ef7f..af3b50d 100644 --- a/sources/awesome-widget/plugin/awactions.cpp +++ b/sources/awesome-widget/plugin/awactions.cpp @@ -118,66 +118,7 @@ QString AWActions::getAboutText(const QString type) const { qCDebug(LOG_AW) << "Type" << type; - QString text; - if (type == QString("header")) { - text = QString(NAME); - } else if (type == QString("version")) { - text = i18n("Version %1 (build date %2)", QString(VERSION), - QString(BUILD_DATE)); - if (!QString(COMMIT_SHA).isEmpty()) - text += QString(" (%1)").arg(QString(COMMIT_SHA)); - } else if (type == QString("description")) { - text = i18n("A set of minimalistic plasmoid widgets"); - } else if (type == QString("links")) { - text = i18n("Links:") + QString("
    ") - + QString("%2
    ") - .arg(QString(HOMEPAGE)) - .arg(i18n("Homepage")) - + QString("%2
    ") - .arg(QString(REPOSITORY)) - .arg(i18n("Repository")) - + QString("%2
    ") - .arg(QString(BUGTRACKER)) - .arg(i18n("Bugtracker")) - + QString("%2
    ") - .arg(QString(TRANSLATION)) - .arg(i18n("Translation issue")) - + QString("%2
    ") - .arg(QString(AUR_PACKAGES)) - .arg(i18n("AUR packages")) - + QString("%2") - .arg(QString(OPENSUSE_PACKAGES)) - .arg(i18n("openSUSE packages")); - } else if (type == QString("copy")) { - text = QString("© %1 %3
    ") - .arg(QString(DATE)) - .arg(QString(EMAIL)) - .arg(QString(AUTHOR)) - + i18n("This software is licensed under %1", QString(LICENSE)) - + QString("
    "); - } else if (type == QString("translators")) { - text = i18n("Translators: %1", QString(TRANSLATORS)); - } else if (type == QString("3rdparty")) { - QStringList trdPartyList - = QString(TRDPARTY_LICENSE) - .split(QChar(';'), QString::SkipEmptyParts); - for (int i = 0; i < trdPartyList.count(); i++) - trdPartyList[i] = QString("%1 (%2 license)") - .arg(trdPartyList.at(i).split(QChar(','))[0]) - .arg(trdPartyList.at(i).split(QChar(','))[1]) - .arg(trdPartyList.at(i).split(QChar(','))[2]); - text = i18n("This software uses: %1", trdPartyList.join(QString(", "))); - } else if (type == QString("thanks")) { - QStringList thanks = QString(SPECIAL_THANKS) - .split(QChar(';'), QString::SkipEmptyParts); - for (int i = 0; i < thanks.count(); i++) - thanks[i] = QString("%1") - .arg(thanks.at(i).split(QChar(','))[0]) - .arg(thanks.at(i).split(QChar(','))[1]); - text = i18n("Special thanks to %1", thanks.join(QString(", "))); - } - - return text; + return AWDebug::getAboutText(type); } diff --git a/sources/awesome-widget/plugin/awbugreporter.cpp b/sources/awesome-widget/plugin/awbugreporter.cpp index fdd28be..cbc8ed1 100644 --- a/sources/awesome-widget/plugin/awbugreporter.cpp +++ b/sources/awesome-widget/plugin/awbugreporter.cpp @@ -66,7 +66,7 @@ QString AWBugReporter::generateText(const QString description, output += QString("**Step to reproduce**\n\n%1\n\n").arg(reproduce); output += QString("**Expected result**\n\n%1\n\n").arg(expected); output += QString("**Version**\n\n%1\n\n") - .arg(getBuildData().join(QString("\n"))); + .arg(AWDebug::getBuildData().join(QString("\n"))); // append logs output += QString("**Logs**\n\n%1").arg(logs); @@ -83,7 +83,7 @@ void AWBugReporter::sendBugReport(const QString title, const QString body) connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(issueReplyRecieved(QNetworkReply *))); - QNetworkRequest request(QUrl(BUGTRACKER_API)); + QNetworkRequest request = QNetworkRequest(QUrl(BUGTRACKER_API)); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); // generate payload diff --git a/sources/awesome-widget/plugin/awconfighelper.cpp b/sources/awesome-widget/plugin/awconfighelper.cpp index edcb201..91b37f7 100644 --- a/sources/awesome-widget/plugin/awconfighelper.cpp +++ b/sources/awesome-widget/plugin/awconfighelper.cpp @@ -69,13 +69,12 @@ bool AWConfigHelper::dropCache() const } -bool AWConfigHelper::exportConfiguration(const QObject *nativeConfig, +bool AWConfigHelper::exportConfiguration(QObject *nativeConfig, const QString fileName) const { qCDebug(LOG_AW) << "Selected filename" << fileName; QSettings settings(fileName, QSettings::IniFormat); - // plasmoid configuration const QQmlPropertyMap *configuration = static_cast(nativeConfig); diff --git a/sources/awesome-widget/plugin/awconfighelper.h b/sources/awesome-widget/plugin/awconfighelper.h index 4a71956..6747155 100644 --- a/sources/awesome-widget/plugin/awconfighelper.h +++ b/sources/awesome-widget/plugin/awconfighelper.h @@ -35,7 +35,7 @@ public: virtual ~AWConfigHelper(); Q_INVOKABLE QString configurationDirectory() const; Q_INVOKABLE bool dropCache() const; - Q_INVOKABLE bool exportConfiguration(const QObject *nativeConfig, + Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig, const QString fileName) const; Q_INVOKABLE QVariantMap importConfiguration(const QString fileName, const bool importPlasmoid, diff --git a/sources/awesome-widget/plugin/awdataaggregator.cpp b/sources/awesome-widget/plugin/awdataaggregator.cpp index 89f910c..2c4abd1 100644 --- a/sources/awesome-widget/plugin/awdataaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataaggregator.cpp @@ -143,9 +143,9 @@ QPixmap AWDataAggregator::tooltipImage() for (int j = 0; j < m_values[key].count() - 1; j++) { // some magic here float x1 = j * normX + shift; - float y1 = -fabs(m_values[key].at(j)) * normY + 5.0f; + float y1 = -std::fabs(m_values[key].at(j)) * normY + 5.0f; float x2 = (j + 1) * normX + shift; - float y2 = -fabs(m_values[key].at(j + 1)) * normY + 5.0f; + float y2 = -std::fabs(m_values[key].at(j + 1)) * normY + 5.0f; if (key == QString("batTooltip")) { if (m_values[key].at(j + 1) > 0) pen.setColor( diff --git a/sources/awesome-widget/plugin/awdbusadaptor.cpp b/sources/awesome-widget/plugin/awdbusadaptor.cpp new file mode 100644 index 0000000..01dfc28 --- /dev/null +++ b/sources/awesome-widget/plugin/awdbusadaptor.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#include "awdbusadaptor.h" + +#include "awdebug.h" +#include "awkeys.h" + + +AWDBusAdaptor::AWDBusAdaptor(AWKeys *parent) + : QDBusAbstractAdaptor(parent) + , m_plugin(parent) +{ + qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__; +} + + +AWDBusAdaptor::~AWDBusAdaptor() +{ + qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__; +} + + +QString AWDBusAdaptor::Info(const QString key) const +{ + return m_plugin->infoByKey(key); +} + + +QStringList AWDBusAdaptor::Keys(const QString regexp) const +{ + return m_plugin->dictKeys(true, regexp); +} + + +QString AWDBusAdaptor::Value(const QString key) const +{ + return m_plugin->valueByKey(key); +} + + +qlonglong AWDBusAdaptor::WhoAmI() const +{ + return reinterpret_cast(m_plugin); +} + + +void AWDBusAdaptor::SetLogLevel(const QString what, const int level) +{ + qCDebug(LOG_DBUS) << "Set log level" << level << "for" << what; + + if (level >= m_logLevels.count()) { + qCDebug(LOG_DBUS) << "Invalid logging level" << level + << "should be less than" << m_logLevels.count(); + return; + } + + for (auto lev : m_logLevels) + SetLogLevel(what, lev, m_logLevels.indexOf(lev) >= level); +} + + +void AWDBusAdaptor::SetLogLevel(const QString what, const QString level, + const bool enabled) +{ + qCDebug(LOG_DBUS) << "Set log level" << level << "enabled" << enabled + << "for" << what; + + if (!m_logLevels.contains(level)) { + qCDebug(LOG_DBUS) << "Invalid logging level" << level << "should be in" + << m_logLevels; + return; + } + + QString state = enabled ? QString("true") : QString("false"); + QLoggingCategory::setFilterRules( + QString("%1.%2=%3").arg(what).arg(level).arg(state)); +} diff --git a/sources/awesome-widget/plugin/awdbusadaptor.h b/sources/awesome-widget/plugin/awdbusadaptor.h new file mode 100644 index 0000000..18d736d --- /dev/null +++ b/sources/awesome-widget/plugin/awdbusadaptor.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#ifndef AWDBUSADAPTOR_H +#define AWDBUSADAPTOR_H + +#include + +#include "version.h" + + +class AWKeys; + +class AWDBusAdaptor : public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", AWDBUS_SERVICE_NAME) + +public: + explicit AWDBusAdaptor(AWKeys *parent = nullptr); + virtual ~AWDBusAdaptor(); + +public slots: + // get methods + QString Info(const QString key) const; + QStringList Keys(const QString regexp) const; + QString Value(const QString key) const; + qlonglong WhoAmI() const; + // set methods + void SetLogLevel(const QString what, const int level); + void SetLogLevel(const QString what, const QString level, + const bool enabled); + +private: + AWKeys *m_plugin = nullptr; + QStringList m_logLevels = QStringList() + << QString("debug") << QString("info") + << QString("warning") << QString("critical"); +}; + + +#endif /* AWDBUSADAPTOR_H */ diff --git a/sources/awesome-widget/plugin/awformatterconfig.cpp b/sources/awesome-widget/plugin/awformatterconfig.cpp index b7ab3ed..d91f66b 100644 --- a/sources/awesome-widget/plugin/awformatterconfig.cpp +++ b/sources/awesome-widget/plugin/awformatterconfig.cpp @@ -80,12 +80,14 @@ void AWFormatterConfig::updateUi() = m_selectors.indexOf(static_cast(sender())); if ((current.first.isEmpty()) && (current.second.isEmpty())) { + // remove current selector if it is empty and does not last if (sender() == m_selectors.last()) return; AWAbstractSelector *selector = m_selectors.takeAt(index); ui->verticalLayout->removeWidget(selector); selector->deleteLater(); } else { + // add new selector if something changed if (sender() != m_selectors.last()) return; auto keys = initKeys(); @@ -140,7 +142,7 @@ void AWFormatterConfig::execDialog() case 1: default: m_helper->writeFormatters(data); - m_helper->writeFormatters(data.keys()); + m_helper->removeUnusedFormatters(data.keys()); break; } } diff --git a/sources/awesome-widget/plugin/awformatterhelper.cpp b/sources/awesome-widget/plugin/awformatterhelper.cpp index 6a8f7f7..4ec9596 100644 --- a/sources/awesome-widget/plugin/awformatterhelper.cpp +++ b/sources/awesome-widget/plugin/awformatterhelper.cpp @@ -26,6 +26,7 @@ #include "awdatetimeformatter.h" #include "awdebug.h" #include "awfloatformatter.h" +#include "awjsonformatter.h" #include "awlistformatter.h" #include "awnoformatter.h" #include "awscriptformatter.h" @@ -37,6 +38,7 @@ AWFormatterHelper::AWFormatterHelper(QWidget *parent) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + m_filePath = QString("awesomewidgets/formatters/formatters.ini"); initItems(); } @@ -92,13 +94,14 @@ QStringList AWFormatterHelper::knownFormatters() const } -bool AWFormatterHelper::writeFormatters(const QStringList keys) const +bool AWFormatterHelper::removeUnusedFormatters(const QStringList keys) const { qCDebug(LOG_AW) << "Remove formatters" << keys; - QString fileName = QString("%1/awesomewidgets/formatters/formatters.ini") + QString fileName = QString("%1/%2") .arg(QStandardPaths::writableLocation( - QStandardPaths::GenericDataLocation)); + QStandardPaths::GenericDataLocation)) + .arg(m_filePath); QSettings settings(fileName, QSettings::IniFormat); qCInfo(LOG_AW) << "Configuration file" << fileName; @@ -122,9 +125,10 @@ bool AWFormatterHelper::writeFormatters( { qCDebug(LOG_AW) << "Write configuration" << configuration; - QString fileName = QString("%1/awesomewidgets/formatters/formatters.ini") + QString fileName = QString("%1/%2") .arg(QStandardPaths::writableLocation( - QStandardPaths::GenericDataLocation)); + QStandardPaths::GenericDataLocation)) + .arg(m_filePath); QSettings settings(fileName, QSettings::IniFormat); qCInfo(LOG_AW) << "Configuration file" << fileName; @@ -166,6 +170,8 @@ AWFormatterHelper::defineFormatterClass(const QString stringType) const formatter = AWAbstractFormatter::FormatterClass::Script; else if (stringType == QString("String")) formatter = AWAbstractFormatter::FormatterClass::String; + else if (stringType == QString("Json")) + formatter = AWAbstractFormatter::FormatterClass::Json; else qCWarning(LOG_AW) << "Unknown formatter" << stringType; @@ -213,6 +219,9 @@ void AWFormatterHelper::initFormatters() m_formattersClasses[name] = new AWStringFormatter(this, filePath); break; + case AWAbstractFormatter::FormatterClass::Json: + m_formattersClasses[name] = new AWJsonFormatter(this, filePath); + break; case AWAbstractFormatter::FormatterClass::NoFormat: m_formattersClasses[name] = new AWNoFormatter(this, filePath); break; @@ -227,8 +236,7 @@ void AWFormatterHelper::initKeys() m_formatters.clear(); QStringList configs = QStandardPaths::locateAll( - QStandardPaths::GenericDataLocation, - QString("awesomewidgets/formatters/formatters.ini")); + QStandardPaths::GenericDataLocation, m_filePath); for (auto fileName : configs) { QSettings settings(fileName, QSettings::IniFormat); @@ -245,8 +253,8 @@ void AWFormatterHelper::initKeys() continue; } if (!m_formattersClasses.contains(name)) { - qCWarning(LOG_AW) << "Invalid formatter" << name << "found in" - << key; + qCWarning(LOG_AW) + << "Invalid formatter" << name << "found in" << key; continue; } m_formatters[key] = m_formattersClasses[name]; @@ -294,7 +302,8 @@ void AWFormatterHelper::doCreateItem() QStringList selection = QStringList() << QString("NoFormat") << QString("DateTime") << QString("Float") << QString("List") - << QString("Script") << QString("String"); + << QString("Script") << QString("String") + << QString("Json"); bool ok; QString select = QInputDialog::getItem( this, i18n("Select type"), i18n("Type:"), selection, 0, false, &ok); @@ -317,6 +326,8 @@ void AWFormatterHelper::doCreateItem() return createItem(); case AWAbstractFormatter::FormatterClass::String: return createItem(); + case AWAbstractFormatter::FormatterClass::Json: + return createItem(); case AWAbstractFormatter::FormatterClass::NoFormat: return createItem(); } diff --git a/sources/awesome-widget/plugin/awformatterhelper.h b/sources/awesome-widget/plugin/awformatterhelper.h index 5ba16d6..42339d4 100644 --- a/sources/awesome-widget/plugin/awformatterhelper.h +++ b/sources/awesome-widget/plugin/awformatterhelper.h @@ -38,7 +38,7 @@ public: QHash getFormatters() const; QList items() const; QStringList knownFormatters() const; - bool writeFormatters(const QStringList keys) const; + bool removeUnusedFormatters(const QStringList keys) const; bool writeFormatters(const QHash configuration) const; public slots: @@ -58,6 +58,7 @@ private: void initItems(); // properties QStringList m_directories; + QString m_filePath; QHash m_formatters; QHash m_formattersClasses; }; diff --git a/sources/awesome-widget/plugin/awkeyoperations.cpp b/sources/awesome-widget/plugin/awkeyoperations.cpp index f1b11c1..d4cbd6c 100644 --- a/sources/awesome-widget/plugin/awkeyoperations.cpp +++ b/sources/awesome-widget/plugin/awkeyoperations.cpp @@ -26,6 +26,7 @@ #include "awkeycache.h" #include "awpatternfunctions.h" // extensions +#include "extnetworkrequest.h" #include "extquotes.h" #include "extscript.h" #include "extupgrade.h" @@ -46,6 +47,7 @@ AWKeyOperations::~AWKeyOperations() // extensions delete m_graphicalItems; + delete m_extNetRequest; delete m_extQuotes; delete m_extScripts; delete m_extUpgrade; @@ -151,13 +153,14 @@ QStringList AWKeyOperations::dictKeys() const // custom for (auto item : m_extScripts->activeItems()) allKeys.append(item->tag(QString("custom"))); + // network requests + for (auto item : m_extNetRequest->activeItems()) + allKeys.append(item->tag(QString("response"))); // bars for (auto item : m_graphicalItems->activeItems()) allKeys.append(item->tag(QString("bar"))); // static keys - QStringList staticKeys = QString(STATIC_KEYS).split(QChar(',')); - std::for_each(staticKeys.cbegin(), staticKeys.cend(), - [&allKeys](const QString &key) { allKeys.append(key); }); + allKeys.append(QString(STATIC_KEYS).split(QChar(','))); // sort in valid order allKeys.sort(); @@ -227,6 +230,10 @@ QString AWKeyOperations::infoByKey(QString key) const } else if (key.startsWith(QString("temp"))) { output = m_devices[QString("temp")][key.remove(QString("temp")).toInt()]; + } else if (key.startsWith(QString("response"))) { + AbstractExtItem *item = m_extNetRequest->itemByTag(key, stripped); + if (item) + output = item->uniq(); } else { output = QString("(none)"); } @@ -259,6 +266,8 @@ void AWKeyOperations::editItem(const QString type) keys.sort(); m_graphicalItems->setConfigArgs(keys); return m_graphicalItems->editItems(); + } else if (type == QString("extnetworkrequest")) { + return m_extNetRequest->editItems(); } else if (type == QString("extquotes")) { return m_extQuotes->editItems(); } else if (type == QString("extscript")) { @@ -310,6 +319,8 @@ void AWKeyOperations::reinitKeys() // delete them if any delete m_graphicalItems; m_graphicalItems = nullptr; + delete m_extNetRequest; + m_extNetRequest = nullptr; delete m_extQuotes; m_extQuotes = nullptr; delete m_extScripts; @@ -321,6 +332,8 @@ void AWKeyOperations::reinitKeys() // create m_graphicalItems = new ExtItemAggregator(nullptr, QString("desktops")); + m_extNetRequest = new ExtItemAggregator( + nullptr, QString("requests")); m_extQuotes = new ExtItemAggregator(nullptr, QString("quotes")); m_extScripts = new ExtItemAggregator(nullptr, QString("scripts")); diff --git a/sources/awesome-widget/plugin/awkeyoperations.h b/sources/awesome-widget/plugin/awkeyoperations.h index 9d92217..2a39c9c 100644 --- a/sources/awesome-widget/plugin/awkeyoperations.h +++ b/sources/awesome-widget/plugin/awkeyoperations.h @@ -30,6 +30,7 @@ class AWDataAggregator; class AWDataEngineAggregator; class AWKeysAggregator; +class ExtNetworkRequest; class ExtQuotes; class ExtScript; class ExtUpgrade; @@ -70,6 +71,7 @@ private: void reinitKeys(); // objects ExtItemAggregator *m_graphicalItems = nullptr; + ExtItemAggregator *m_extNetRequest = nullptr; ExtItemAggregator *m_extQuotes = nullptr; ExtItemAggregator *m_extScripts = nullptr; ExtItemAggregator *m_extUpgrade = nullptr; diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/plugin/awkeys.cpp index 794c39c..c9d4b1b 100644 --- a/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp @@ -17,7 +17,8 @@ #include "awkeys.h" -#include +#include +#include #include #include #include @@ -25,6 +26,7 @@ #include "awdataaggregator.h" #include "awdataengineaggregator.h" +#include "awdbusadaptor.h" #include "awdebug.h" #include "awkeycache.h" #include "awkeyoperations.h" @@ -36,9 +38,9 @@ AWKeys::AWKeys(QObject *parent) : QObject(parent) { - qSetMessagePattern(LOG_FORMAT); + qSetMessagePattern(AWDebug::LOG_FORMAT); qCDebug(LOG_AW) << __PRETTY_FUNCTION__; - for (auto metadata : getBuildData()) + for (auto &metadata : AWDebug::getBuildData()) qCDebug(LOG_AW) << metadata; // thread pool @@ -52,6 +54,8 @@ AWKeys::AWKeys(QObject *parent) m_timer = new QTimer(this); m_timer->setSingleShot(false); + createDBusInterface(); + // update key data if required connect(m_keyOperator, SIGNAL(updateKeys(QStringList)), this, SLOT(reinitKeys(QStringList))); @@ -74,6 +78,10 @@ AWKeys::~AWKeys() m_timer->stop(); delete m_timer; + // delete dbus session + qlonglong id = reinterpret_cast(this); + QDBusConnection::sessionBus().unregisterObject(QString("/%1").arg(id)); + // core delete m_dataEngineAggregator; delete m_threadPool; @@ -83,6 +91,12 @@ AWKeys::~AWKeys() } +bool AWKeys::isDBusActive() const +{ + return m_dbusActive; +} + + void AWKeys::initDataAggregator(const QVariantMap tooltipParams) { qCDebug(LOG_AW) << "Tooltip parameters" << tooltipParams; @@ -144,6 +158,10 @@ QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const qCDebug(LOG_AW) << "Should be sorted" << sorted << "and filter applied" << regexp; + // check if functions asked + if (regexp == QString("functions")) + return QString(STATIC_FUNCTIONS).split(QChar(',')); + QStringList allKeys = m_keyOperator->dictKeys(); // sort if required if (sorted) @@ -153,12 +171,21 @@ QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const } -QStringList AWKeys::getHddDevices() const +QVariantList AWKeys::getHddDevices() const { - QStringList devices = m_keyOperator->devices(QString("hdd")); + QStringList hddDevices = m_keyOperator->devices(QString("hdd")); // required by selector in the UI - devices.insert(0, QString("disable")); - devices.insert(0, QString("auto")); + hddDevices.insert(0, QString("disable")); + hddDevices.insert(0, QString("auto")); + + // build model + QVariantList devices; + for (auto device : hddDevices) { + QVariantMap model; + model[QString("label")] = device; + model[QString("name")] = device; + devices.append(model); + } return devices; } @@ -306,6 +333,27 @@ void AWKeys::calculateValues() } +void AWKeys::createDBusInterface() +{ + // get this object id + qlonglong id = reinterpret_cast(this); + + // create session + QDBusConnection bus = QDBusConnection::sessionBus(); + if (!bus.registerService(AWDBUS_SERVICE)) + qCWarning(LOG_AW) << "Could not register DBus service, last error" + << bus.lastError().message(); + if (!bus.registerObject(QString("/%1").arg(id), new AWDBusAdaptor(this), + QDBusConnection::ExportAllContents)) { + qCWarning(LOG_AW) << "Could not register DBus object, last error" + << bus.lastError().message(); + m_dbusActive = false; + } else { + m_dbusActive = true; + } +} + + QString AWKeys::parsePattern(QString pattern) const { // screen sign diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h index 257fe00..6b3cb4e 100644 --- a/sources/awesome-widget/plugin/awkeys.h +++ b/sources/awesome-widget/plugin/awkeys.h @@ -39,6 +39,7 @@ class AWKeys : public QObject public: explicit AWKeys(QObject *parent = nullptr); virtual ~AWKeys(); + bool isDBusActive() const; Q_INVOKABLE void initDataAggregator(const QVariantMap tooltipParams); Q_INVOKABLE void initKeys(const QString currentPattern, const int interval, const int limit, const bool optimize); @@ -51,7 +52,7 @@ public: // keys Q_INVOKABLE QStringList dictKeys(const bool sorted = false, const QString regexp = QString()) const; - Q_INVOKABLE QStringList getHddDevices() const; + Q_INVOKABLE QVariantList getHddDevices() const; // values Q_INVOKABLE QString infoByKey(QString key) const; Q_INVOKABLE QString valueByKey(QString key) const; @@ -76,6 +77,7 @@ private slots: private: // methods void calculateValues(); + void createDBusInterface(); QString parsePattern(QString pattern) const; void setDataBySource(const QString &sourceName, const QVariantMap &data); // objects @@ -85,6 +87,7 @@ private: AWKeyOperations *m_keyOperator = nullptr; QTimer *m_timer = nullptr; // variables + bool m_dbusActive = false; QVariantMap m_tooltipParams; QStringList m_foundBars, m_foundKeys, m_foundLambdas, m_requiredKeys; QVariantHash m_values; diff --git a/sources/awesome-widget/plugin/awkeysaggregator.cpp b/sources/awesome-widget/plugin/awkeysaggregator.cpp index 184cc04..7835418 100644 --- a/sources/awesome-widget/plugin/awkeysaggregator.cpp +++ b/sources/awesome-widget/plugin/awkeysaggregator.cpp @@ -441,6 +441,12 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // network device m_map[source] = QString("netdev"); m_formatter[QString("netdev")] = FormatterType::NoFormat; + } else if (source.startsWith(QString("network/response"))) { + // network response + QString key = source; + key.remove(QString("network/")); + m_map[source] = key; + m_formatter[key] = FormatterType::NoFormat; } else if (source.contains(netRegExp)) { // network speed QString type = source.contains(QString("receiver")) ? QString("down") diff --git a/sources/awesome-widget/plugin/awpatternfunctions.cpp b/sources/awesome-widget/plugin/awpatternfunctions.cpp index 70bd96c..0f76f49 100644 --- a/sources/awesome-widget/plugin/awpatternfunctions.cpp +++ b/sources/awesome-widget/plugin/awpatternfunctions.cpp @@ -234,9 +234,9 @@ QString AWPatternFunctions::insertMacros(QString code) QString("aw_macro_%1").arg(name), code); for (auto function : macroUsage) { if (function.args.count() != macro.args.count()) { - qCWarning(LOG_AW) << "Invalid args count found for call" - << function.what << "with macro" - << macro.what; + qCWarning(LOG_AW) + << "Invalid args count found for call" << function.what + << "with macro" << macro.what; continue; } // generate body to replace @@ -267,12 +267,14 @@ QStringList AWPatternFunctions::findKeys(const QString code, << keys; QStringList selectedKeys; + QString replacedCode = code; for (auto key : keys) if ((key.startsWith(QString("bar")) == isBars) - && (code.contains(QString("$%1").arg(key)))) { + && (replacedCode.contains(QString("$%1").arg(key)))) { qCInfo(LOG_AW) << "Found key" << key << "with bar enabled" << isBars; selectedKeys.append(key); + replacedCode.replace(QString("$%1").arg(key), ""); } if (selectedKeys.isEmpty()) qCWarning(LOG_AW) << "No keys found"; diff --git a/sources/awesome-widget/plugin/awtelemetryhandler.cpp b/sources/awesome-widget/plugin/awtelemetryhandler.cpp index 19b5345..194016c 100644 --- a/sources/awesome-widget/plugin/awtelemetryhandler.cpp +++ b/sources/awesome-widget/plugin/awtelemetryhandler.cpp @@ -34,14 +34,10 @@ AWTelemetryHandler::AWTelemetryHandler(QObject *parent, const QString clientId) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; - m_genericConfig = QString("%1/awesomewidgets/general.ini") - .arg(QStandardPaths::writableLocation( - QStandardPaths::GenericDataLocation)); m_localFile = QString("%1/awesomewidgets/telemetry.ini") .arg(QStandardPaths::writableLocation( QStandardPaths::GenericDataLocation)); - init(); // override client id if any if (!clientId.isEmpty()) m_clientId = clientId; @@ -78,6 +74,18 @@ QString AWTelemetryHandler::getLast(const QString group) const } +void AWTelemetryHandler::init(const int count, const bool enableRemote, + const QString clientId) +{ + qCDebug(LOG_AW) << "Init telemetry with count" << count << "enable remote" + << enableRemote << "client ID" << clientId; + + m_storeCount = count; + m_uploadEnabled = enableRemote; + m_clientId = clientId; +} + + bool AWTelemetryHandler::put(const QString group, const QString value) const { qCDebug(LOG_AW) << "Store data with group" << group << "and value" << value; @@ -130,13 +138,12 @@ void AWTelemetryHandler::uploadTelemetry(const QString group, SLOT(telemetryReplyRecieved(QNetworkReply *))); QUrl url(REMOTE_TELEMETRY_URL); - url.setPort(REMOTE_TELEMETRY_PORT); QNetworkRequest request(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); // generate payload QVariantMap payload; - payload[QString("api")] = AWTEAPI; + payload[QString("api")] = AW_TELEMETRY_API; payload[QString("client_id")] = m_clientId; payload[QString("metadata")] = value; payload[QString("type")] = group; @@ -181,44 +188,3 @@ QString AWTelemetryHandler::getKey(const int count) const return QString("%1").arg(count, 3, 10, QChar('0')); } - - -void AWTelemetryHandler::init() -{ - QSettings settings(m_genericConfig, QSettings::IniFormat); - settings.beginGroup(QString("Telemetry")); - - // unique client id - m_clientId - = settings.value(QString("ClientID"), QUuid::createUuid().toString()) - .toString(); - setConfiguration(QString("ClientID"), m_clientId, false); - // count items to store - m_storeCount = settings.value(QString("StoreHistory"), 100).toInt(); - setConfiguration(QString("StoreHistory"), m_storeCount, false); - // check if upload enabled - m_uploadEnabled = settings.value(QString("Upload"), false).toBool(); - setConfiguration(QString("Upload"), m_uploadEnabled, false); - - settings.endGroup(); -} - - -bool AWTelemetryHandler::setConfiguration(const QString key, - const QVariant value, - const bool override) const -{ - qCDebug(LOG_AW) << "Set configuration key" << key << "to value" << value - << "force override enabled" << override; - - QSettings settings(m_genericConfig, QSettings::IniFormat); - settings.beginGroup(QString("Telemetry")); - if (settings.childKeys().contains(key) && !override) - return true; - - settings.setValue(key, value); - settings.endGroup(); - settings.sync(); - - return (settings.status() == QSettings::NoError); -} diff --git a/sources/awesome-widget/plugin/awtelemetryhandler.h b/sources/awesome-widget/plugin/awtelemetryhandler.h index f8b11a0..8ce092c 100644 --- a/sources/awesome-widget/plugin/awtelemetryhandler.h +++ b/sources/awesome-widget/plugin/awtelemetryhandler.h @@ -31,14 +31,15 @@ class AWTelemetryHandler : public QObject Q_OBJECT public: - const char *REMOTE_TELEMETRY_URL = "http://arcanis.me/telemetry"; - const int REMOTE_TELEMETRY_PORT = 8080; + const char *REMOTE_TELEMETRY_URL = "https://arcanis.me/telemetry"; explicit AWTelemetryHandler(QObject *parent = nullptr, const QString clientId = QString()); virtual ~AWTelemetryHandler(); Q_INVOKABLE QStringList get(const QString group) const; Q_INVOKABLE QString getLast(const QString group) const; + Q_INVOKABLE void init(const int count, const bool enableRemote, + const QString clientId); Q_INVOKABLE bool put(const QString group, const QString value) const; Q_INVOKABLE void uploadTelemetry(const QString group, const QString value); @@ -50,11 +51,7 @@ private slots: private: QString getKey(const int count) const; - void init(); - bool setConfiguration(const QString key, const QVariant value, - const bool override) const; QString m_clientId; - QString m_genericConfig; QString m_localFile; int m_storeCount = 0; bool m_uploadEnabled = false; diff --git a/sources/awesomewidgets/CMakeLists.txt b/sources/awesomewidgets/CMakeLists.txt index a91ac8b..c8b6ef2 100644 --- a/sources/awesomewidgets/CMakeLists.txt +++ b/sources/awesomewidgets/CMakeLists.txt @@ -19,6 +19,7 @@ set(SUBPROJECT_FORMATTERS ${CMAKE_CURRENT_SOURCE_DIR}/formatters) set(SUBPROJECT_GRAPHITEMS ${CMAKE_CURRENT_SOURCE_DIR}/desktops) set(SUBPROJECT_QUOTES ${CMAKE_CURRENT_SOURCE_DIR}/quotes) set(SUBPROJECT_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/scripts) +set(SUBPROJECT_REQUESTS ${CMAKE_CURRENT_SOURCE_DIR}/requests) set(SUBPROJECT_UPGRADE ${CMAKE_CURRENT_SOURCE_DIR}/upgrade) set(SUBPROJECT_WEATHER ${CMAKE_CURRENT_SOURCE_DIR}/weather) file(GLOB SUBPROJECT_WEATHER_JSON_IN *.json) @@ -37,6 +38,7 @@ install(DIRECTORY ${SUBPROJECT_FORMATTERS} DESTINATION ${DATA_INSTALL_DIR}/${PRO install(DIRECTORY ${SUBPROJECT_GRAPHITEMS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_QUOTES} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_SCRIPTS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) +install(DIRECTORY ${SUBPROJECT_REQUESTS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_UPGRADE} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_WEATHER} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(FILES ${SUBPROJECT_INI} DESTINATION ${CONFIG_INSTALL_DIR}) diff --git a/sources/awesomewidgets/abstractextitem.cpp b/sources/awesomewidgets/abstractextitem.cpp index 69a3445..b0468f6 100644 --- a/sources/awesomewidgets/abstractextitem.cpp +++ b/sources/awesomewidgets/abstractextitem.cpp @@ -18,12 +18,14 @@ #include "abstractextitem.h" #include +#include #include #include #include #include "abstractextitemaggregator.h" #include "awdebug.h" +#include "qcronscheduler.h" AbstractExtItem::AbstractExtItem(QWidget *parent, const QString filePath) @@ -41,6 +43,12 @@ AbstractExtItem::AbstractExtItem(QWidget *parent, const QString filePath) AbstractExtItem::~AbstractExtItem() { qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + if (m_socket) { + m_socket->close(); + m_socket->removeServer(socket()); + delete m_socket; + } } @@ -63,8 +71,29 @@ void AbstractExtItem::copyDefaults(AbstractExtItem *_other) const _other->setActive(isActive()); _other->setApiVersion(apiVersion()); _other->setComment(comment()); + _other->setCron(cron()); _other->setInterval(interval()); _other->setName(name()); + _other->setSocket(socket()); +} + + +void AbstractExtItem::startTimer() +{ + if (!socket().isEmpty()) + // check if there is active socket setup + return; + else if (!cron().isEmpty()) + // check if there is active scheduler + return; + else if (m_times == 1) + // check if it is time to update + emit(requestDataUpdate()); + + // update counter value + if (m_times >= interval()) + m_times = 0; + m_times++; } @@ -95,6 +124,12 @@ QString AbstractExtItem::comment() const } +QString AbstractExtItem::cron() const +{ + return m_cron; +} + + QString AbstractExtItem::fileName() const { return m_fileName; @@ -125,6 +160,12 @@ int AbstractExtItem::number() const } +QString AbstractExtItem::socket() const +{ + return m_socketFile; +} + + QString AbstractExtItem::tag(const QString _type) const { qCDebug(LOG_LIB) << "Tag type" << _type; @@ -157,6 +198,28 @@ void AbstractExtItem::setComment(const QString _comment) } +void AbstractExtItem::setCron(const QString _cron) +{ + qCDebug(LOG_LIB) << "Cron string" << _cron; + // deinit module first + if (m_scheduler) { + disconnect(m_scheduler, SIGNAL(activated()), this, + SIGNAL(requestDataUpdate())); + delete m_scheduler; + } + + m_cron = _cron; + if (cron().isEmpty()) + return; + + // init scheduler + m_scheduler = new QCronScheduler(this); + m_scheduler->parse(cron()); + connect(m_scheduler, SIGNAL(activated()), this, + SIGNAL(requestDataUpdate())); +} + + void AbstractExtItem::setInterval(const int _interval) { qCDebug(LOG_LIB) << "Interval" << _interval; @@ -196,6 +259,42 @@ void AbstractExtItem::setNumber(int _number) } +void AbstractExtItem::setSocket(const QString _socket) +{ + qCDebug(LOG_LIB) << "Socket" << _socket; + // remove old socket first + deinitSocket(); + + m_socketFile = _socket; +} + + +void AbstractExtItem::deinitSocket() +{ + if (!m_socket) + return; + + m_socket->close(); + m_socket->removeServer(socket()); + delete m_socket; + disconnect(m_socket, SIGNAL(newConnection()), this, + SLOT(newConnectionReceived())); +} + + +void AbstractExtItem::initSocket() +{ + // remove old socket first + deinitSocket(); + + m_socket = new QLocalServer(this); + bool listening = m_socket->listen(socket()); + qCInfo(LOG_LIB) << "Server listening on" << socket() << listening; + connect(m_socket, SIGNAL(newConnection()), this, + SLOT(newConnectionReceived())); +} + + void AbstractExtItem::readConfiguration() { QSettings settings(m_fileName, QSettings::IniFormat); @@ -210,6 +309,8 @@ void AbstractExtItem::readConfiguration() == QString("true")); setInterval(settings.value(QString("X-AW-Interval"), interval()).toInt()); setNumber(settings.value(QString("X-AW-Number"), number()).toInt()); + setCron(settings.value(QString("X-AW-Schedule"), cron()).toString()); + setSocket(settings.value(QString("X-AW-Socket"), socket()).toString()); settings.endGroup(); } @@ -234,9 +335,19 @@ void AbstractExtItem::writeConfiguration() const settings.setValue(QString("Comment"), comment()); settings.setValue(QString("X-AW-ApiVersion"), apiVersion()); settings.setValue(QString("X-AW-Active"), QVariant(isActive()).toString()); - settings.setValue(QString("X-AW-Interval"), interval()); + settings.setValue(QString("X-AW-Interval"), + cron().isEmpty() ? QVariant(interval()) + : QVariant(cron())); settings.setValue(QString("X-AW-Number"), number()); + settings.setValue(QString("X-AW-Schedule"), cron()); + settings.setValue(QString("X-AW-Socket"), socket()); settings.endGroup(); settings.sync(); } + + +void AbstractExtItem::newConnectionReceived() +{ + emit(requestDataUpdate()); +} diff --git a/sources/awesomewidgets/abstractextitem.h b/sources/awesomewidgets/abstractextitem.h index 7bdb3a1..05bc6c4 100644 --- a/sources/awesomewidgets/abstractextitem.h +++ b/sources/awesomewidgets/abstractextitem.h @@ -22,16 +22,21 @@ #include +class QCronScheduler; +class QLocalServer; + class AbstractExtItem : public QDialog { Q_OBJECT Q_PROPERTY(bool active READ isActive WRITE setActive) Q_PROPERTY(int apiVersion READ apiVersion WRITE setApiVersion) Q_PROPERTY(QString comment READ comment WRITE setComment) + Q_PROPERTY(QString cron READ cron WRITE setCron) Q_PROPERTY(QString fileName READ fileName) Q_PROPERTY(int interval READ interval WRITE setInterval) Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(int number READ number WRITE setNumber) + Q_PROPERTY(QString socket READ socket WRITE setSocket) Q_PROPERTY(QString uniq READ uniq) public: @@ -42,45 +47,61 @@ public: virtual AbstractExtItem *copy(const QString _fileName, const int _number) = 0; virtual void copyDefaults(AbstractExtItem *_other) const; + virtual void startTimer(); QString writtableConfig() const; // get methods int apiVersion() const; QString comment() const; + QString cron() const; QString fileName() const; int interval() const; bool isActive() const; QString name() const; int number() const; + QString socket() const; QString tag(const QString _type) const; virtual QString uniq() const = 0; // set methods void setApiVersion(const int _apiVersion = 0); void setActive(const bool _state = true); void setComment(const QString _comment = QString("empty")); + void setCron(const QString _cron = ""); void setInterval(const int _interval = 1); void setName(const QString _name = QString("none")); void setNumber(int _number = -1); + void setSocket(const QString _socket = QString("")); signals: void dataReceived(const QVariantHash &data); + void requestDataUpdate(); public slots: + virtual void deinitSocket(); + virtual void initSocket(); virtual void readConfiguration(); virtual QVariantHash run() = 0; virtual int showConfiguration(const QVariant args = QVariant()) = 0; - bool tryDelete() const; + virtual bool tryDelete() const; virtual void writeConfiguration() const; +private slots: + void newConnectionReceived(); + private: + QCronScheduler *m_scheduler = nullptr; QString m_fileName = QString("/dev/null"); + int m_times = 0; virtual void translate() = 0; // properties int m_apiVersion = 0; bool m_active = true; QString m_comment = QString("empty"); + QString m_cron = ""; int m_interval = 1; QString m_name = QString("none"); int m_number = -1; + QLocalServer *m_socket = nullptr; + QString m_socketFile = QString(""); }; diff --git a/sources/awesomewidgets/awabstractformatter.cpp b/sources/awesomewidgets/awabstractformatter.cpp index af9e55e..b97a4e6 100644 --- a/sources/awesomewidgets/awabstractformatter.cpp +++ b/sources/awesomewidgets/awabstractformatter.cpp @@ -69,6 +69,9 @@ QString AWAbstractFormatter::strType() const case FormatterClass::String: value = QString("String"); break; + case FormatterClass::Json: + value = QString("Json"); + break; case FormatterClass::NoFormat: value = QString("NoFormat"); break; @@ -98,6 +101,8 @@ void AWAbstractFormatter::setStrType(const QString _type) m_type = FormatterClass::Script; else if (_type == QString("String")) m_type = FormatterClass::String; + else if (_type == QString("Json")) + m_type = FormatterClass::Json; else m_type = FormatterClass::NoFormat; } diff --git a/sources/awesomewidgets/awabstractformatter.h b/sources/awesomewidgets/awabstractformatter.h index 883314d..12db5e6 100644 --- a/sources/awesomewidgets/awabstractformatter.h +++ b/sources/awesomewidgets/awabstractformatter.h @@ -34,7 +34,8 @@ public: List, Script, String, - NoFormat + NoFormat, + Json }; explicit AWAbstractFormatter(QWidget *parent, diff --git a/sources/awesomewidgets/awdatetimeformatter.cpp b/sources/awesomewidgets/awdatetimeformatter.cpp index e83ccca..4680da6 100644 --- a/sources/awesomewidgets/awdatetimeformatter.cpp +++ b/sources/awesomewidgets/awdatetimeformatter.cpp @@ -115,7 +115,7 @@ void AWDateTimeFormatter::readConfiguration() settings.value(QString("X-AW-Translate"), translateString()).toBool()); settings.endGroup(); - bumpApi(AWEFAPI); + bumpApi(AW_FORMATTER_API); } @@ -135,7 +135,7 @@ int AWDateTimeFormatter::showConfiguration(const QVariant args) return ret; setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); - setApiVersion(AWEFAPI); + setApiVersion(AW_FORMATTER_API); setStrType(ui->label_typeValue->text()); setFormat(ui->lineEdit_format->text()); setTranslateString(ui->checkBox_translate->checkState() == Qt::Checked); diff --git a/sources/awesomewidgets/awfloatformatter.cpp b/sources/awesomewidgets/awfloatformatter.cpp index 24585bf..e39f8fd 100644 --- a/sources/awesomewidgets/awfloatformatter.cpp +++ b/sources/awesomewidgets/awfloatformatter.cpp @@ -210,7 +210,7 @@ void AWFloatFormatter::readConfiguration() setSummand(settings.value(QString("X-AW-Summand"), summand()).toDouble()); settings.endGroup(); - bumpApi(AWEFAPI); + bumpApi(AW_FORMATTER_API); } @@ -236,7 +236,7 @@ int AWFloatFormatter::showConfiguration(const QVariant args) return ret; setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); - setApiVersion(AWEFAPI); + setApiVersion(AW_FORMATTER_API); setStrType(ui->label_typeValue->text()); setFormat(ui->comboBox_format->currentText().at(0).toLatin1()); setPrecision(ui->spinBox_precision->value()); diff --git a/sources/awesomewidgets/awjsonformatter.cpp b/sources/awesomewidgets/awjsonformatter.cpp new file mode 100644 index 0000000..81d12ee --- /dev/null +++ b/sources/awesomewidgets/awjsonformatter.cpp @@ -0,0 +1,207 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#include "awjsonformatter.h" +#include "ui_awjsonformatter.h" + +#include + +#include +#include + +#include "awdebug.h" + + +AWJsonFormatter::AWJsonFormatter(QWidget *parent, const QString filePath) + : AWAbstractFormatter(parent, filePath) + , ui(new Ui::AWJsonFormatter) +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + if (!filePath.isEmpty()) + readConfiguration(); + ui->setupUi(this); + translate(); +} + + +AWJsonFormatter::~AWJsonFormatter() +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + delete ui; +} + + +QString AWJsonFormatter::convert(const QVariant &_value) const +{ + qCDebug(LOG_LIB) << "Convert value" << _value; + + // check if _value is string and parse first if required + QJsonDocument json + = _value.type() == QVariant::String + ? QJsonDocument::fromJson(_value.toString().toUtf8()) + : QJsonDocument::fromVariant(_value); + QVariant converted = json.toVariant(); + for (auto &element : m_splittedPath) + converted = getFromJson(converted, element); + + return converted.toString(); +} + + +AWJsonFormatter *AWJsonFormatter::copy(const QString _fileName, + const int _number) +{ + qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; + + AWJsonFormatter *item + = new AWJsonFormatter(static_cast(parent()), _fileName); + AWAbstractFormatter::copyDefaults(item); + item->setNumber(_number); + item->setPath(path()); + + return item; +} + + +QString AWJsonFormatter::path() const +{ + return m_path; +} + + +void AWJsonFormatter::setPath(const QString _path) +{ + qCDebug(LOG_LIB) << "Path" << _path; + + m_path = _path; + initPath(); +} + + +void AWJsonFormatter::readConfiguration() +{ + AWAbstractFormatter::readConfiguration(); + + QSettings settings(fileName(), QSettings::IniFormat); + + settings.beginGroup(QString("Desktop Entry")); + setPath(settings.value(QString("X-AW-Path"), path()).toString()); + settings.endGroup(); + + bumpApi(AW_FORMATTER_API); +} + + +int AWJsonFormatter::showConfiguration(const QVariant args) +{ + Q_UNUSED(args) + + ui->lineEdit_name->setText(name()); + ui->lineEdit_comment->setText(comment()); + ui->label_typeValue->setText(QString("Json")); + ui->lineEdit_path->setText(path()); + + int ret = exec(); + if (ret != 1) + return ret; + setName(ui->lineEdit_name->text()); + setComment(ui->lineEdit_comment->text()); + setApiVersion(AW_FORMATTER_API); + setStrType(ui->label_typeValue->text()); + setPath(ui->lineEdit_path->text()); + + writeConfiguration(); + return ret; +} + + +void AWJsonFormatter::writeConfiguration() const +{ + AWAbstractFormatter::writeConfiguration(); + + QSettings settings(writtableConfig(), QSettings::IniFormat); + qCInfo(LOG_LIB) << "Configuration file" << settings.fileName(); + + settings.beginGroup(QString("Desktop Entry")); + settings.setValue(QString("X-AW-Path"), path()); + settings.endGroup(); + + settings.sync(); +} + + +QVariant AWJsonFormatter::getFromJson(const QVariant &value, + const QVariant &element) const +{ + qCDebug(LOG_LIB) << "Looking for element" << element << "in" << value; + + if (element.type() == QVariant::String) { + return getFromMap(value, element.toString()); + } else if (element.type() == QVariant::Int) { + return getFromList(value, element.toInt()); + } else { + qCWarning(LOG_LIB) << "Unknown type" << element.typeName(); + return value; + } +} + + +QVariant AWJsonFormatter::getFromList(const QVariant &value, + const int index) const +{ + qCDebug(LOG_LIB) << "Looking for index" << index << "in" << value; + + return value.toList()[index]; +} + + +QVariant AWJsonFormatter::getFromMap(const QVariant &value, + const QString &key) const +{ + qCDebug(LOG_LIB) << "Looking for key" << key << "in" << value; + + return value.toMap()[key]; +} + + +void AWJsonFormatter::initPath() +{ + m_splittedPath.clear(); + QStringList splittedByDot + = m_path.split(QChar('.'), QString::SkipEmptyParts); + + for (auto &element : splittedByDot) { + bool ok; + int number = element.toInt(&ok); + if (ok) + m_splittedPath.append(number); + else + m_splittedPath.append(element); + } +} + + +void AWJsonFormatter::translate() +{ + ui->label_name->setText(i18n("Name")); + ui->label_comment->setText(i18n("Comment")); + ui->label_type->setText(i18n("Type")); + ui->label_path->setText(i18n("Path")); +} diff --git a/sources/awesomewidgets/awjsonformatter.h b/sources/awesomewidgets/awjsonformatter.h new file mode 100644 index 0000000..338d2d8 --- /dev/null +++ b/sources/awesomewidgets/awjsonformatter.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#ifndef AWJSONFORMATTER_H +#define AWJSONFORMATTER_H + +#include "awabstractformatter.h" + + +namespace Ui +{ +class AWJsonFormatter; +} + +class AWJsonFormatter : public AWAbstractFormatter +{ + Q_OBJECT + Q_PROPERTY(QString path READ path WRITE setPath) + +public: + explicit AWJsonFormatter(QWidget *parent, + const QString filePath = QString()); + virtual ~AWJsonFormatter(); + QString convert(const QVariant &_value) const; + AWJsonFormatter *copy(const QString _fileName, const int _number); + // properties + QString path() const; + void setPath(const QString _path); + +public slots: + void readConfiguration(); + int showConfiguration(const QVariant args = QVariant()); + void writeConfiguration() const; + +private: + Ui::AWJsonFormatter *ui = nullptr; + QVariant getFromJson(const QVariant &value, const QVariant &element) const; + QVariant getFromList(const QVariant &value, const int index) const; + QVariant getFromMap(const QVariant &value, const QString &key) const; + void initPath(); + void translate(); + // properties + QString m_path; + QVariantList m_splittedPath; +}; + + +#endif /* AWJSONFORMATTER_H */ diff --git a/sources/awesomewidgets/awjsonformatter.ui b/sources/awesomewidgets/awjsonformatter.ui new file mode 100644 index 0000000..f648fb4 --- /dev/null +++ b/sources/awesomewidgets/awjsonformatter.ui @@ -0,0 +1,167 @@ + + + AWJsonFormatter + + + + 0 + 0 + 420 + 128 + + + + Configuration + + + + + + + + + 0 + 0 + + + + Name + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + 0 + 0 + + + + Comment + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + Type + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Path + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AWJsonFormatter + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AWJsonFormatter + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/sources/awesomewidgets/awlistformatter.cpp b/sources/awesomewidgets/awlistformatter.cpp index 030db59..a72d97f 100644 --- a/sources/awesomewidgets/awlistformatter.cpp +++ b/sources/awesomewidgets/awlistformatter.cpp @@ -132,7 +132,7 @@ void AWListFormatter::readConfiguration() setSorted(settings.value(QString("X-AW-Sort"), isSorted()).toBool()); settings.endGroup(); - bumpApi(AWEFAPI); + bumpApi(AW_FORMATTER_API); } @@ -153,7 +153,7 @@ int AWListFormatter::showConfiguration(const QVariant args) return ret; setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); - setApiVersion(AWEFAPI); + setApiVersion(AW_FORMATTER_API); setStrType(ui->label_typeValue->text()); setFilter(ui->lineEdit_filter->text()); setSeparator(ui->lineEdit_separator->text()); diff --git a/sources/awesomewidgets/awnoformatter.cpp b/sources/awesomewidgets/awnoformatter.cpp index 9c1734f..1ca4946 100644 --- a/sources/awesomewidgets/awnoformatter.cpp +++ b/sources/awesomewidgets/awnoformatter.cpp @@ -79,7 +79,7 @@ int AWNoFormatter::showConfiguration(const QVariant args) return ret; setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); - setApiVersion(AWEFAPI); + setApiVersion(AW_FORMATTER_API); setStrType(ui->label_typeValue->text()); writeConfiguration(); diff --git a/sources/awesomewidgets/awscriptformatter.cpp b/sources/awesomewidgets/awscriptformatter.cpp index 3b15c9e..1393182 100644 --- a/sources/awesomewidgets/awscriptformatter.cpp +++ b/sources/awesomewidgets/awscriptformatter.cpp @@ -152,7 +152,7 @@ void AWScriptFormatter::readConfiguration() settings.value(QString("X-AW-HasReturn"), hasReturn()).toBool()); settings.endGroup(); - bumpApi(AWEFAPI); + bumpApi(AW_FORMATTER_API); } @@ -174,7 +174,7 @@ int AWScriptFormatter::showConfiguration(const QVariant args) return ret; setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); - setApiVersion(AWEFAPI); + setApiVersion(AW_FORMATTER_API); setStrType(ui->label_typeValue->text()); setAppendCode(ui->checkBox_appendCode->checkState() == Qt::Checked); setHasReturn(ui->checkBox_hasReturn->checkState() == Qt::Checked); diff --git a/sources/awesomewidgets/awstringformatter.cpp b/sources/awesomewidgets/awstringformatter.cpp index a15e416..0b26cc8 100644 --- a/sources/awesomewidgets/awstringformatter.cpp +++ b/sources/awesomewidgets/awstringformatter.cpp @@ -133,7 +133,7 @@ void AWStringFormatter::readConfiguration() settings.value(QString("X-AW-ForceWidth"), forceWidth()).toBool()); settings.endGroup(); - bumpApi(AWEFAPI); + bumpApi(AW_FORMATTER_API); } @@ -154,7 +154,7 @@ int AWStringFormatter::showConfiguration(const QVariant args) return ret; setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); - setApiVersion(AWEFAPI); + setApiVersion(AW_FORMATTER_API); setStrType(ui->label_typeValue->text()); setCount(ui->spinBox_width->value()); setFillChar(ui->lineEdit_fill->text().at(0)); diff --git a/sources/awesomewidgets/extitemaggregator.h b/sources/awesomewidgets/extitemaggregator.h index 7549383..83e367f 100644 --- a/sources/awesomewidgets/extitemaggregator.h +++ b/sources/awesomewidgets/extitemaggregator.h @@ -34,9 +34,9 @@ public: explicit ExtItemAggregator(QWidget *parent, const QString type) : AbstractExtItemAggregator(parent, type) { - qSetMessagePattern(LOG_FORMAT); + qSetMessagePattern(AWDebug::LOG_FORMAT); qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; - for (auto metadata : getBuildData()) + for (auto &metadata : AWDebug::getBuildData()) qCDebug(LOG_LIB) << metadata; qCDebug(LOG_LIB) << "Type" << type; @@ -61,6 +61,15 @@ public: qCInfo(LOG_LIB) << "Dialog returns" << ret; }; + void initSockets() + { + // HACK as soon as per one widget instance we have two objects each of + // them will try to control socket, whereas actually only one of them + // should be owner of the socket + for (auto item : m_items) + item->initSocket(); + } + T *itemByTag(const QString _tag, const QString _type) const { qCDebug(LOG_LIB) << "Tag" << _tag << "with used type" << _type; diff --git a/sources/awesomewidgets/extnetworkrequest.cpp b/sources/awesomewidgets/extnetworkrequest.cpp new file mode 100644 index 0000000..92e3203 --- /dev/null +++ b/sources/awesomewidgets/extnetworkrequest.cpp @@ -0,0 +1,216 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#include "extnetworkrequest.h" +#include "ui_extnetworkrequest.h" + +#include + +#include +#include +#include +#include +#include + +#include + +#include "awdebug.h" + + +ExtNetworkRequest::ExtNetworkRequest(QWidget *parent, const QString filePath) + : AbstractExtItem(parent, filePath) + , ui(new Ui::ExtNetworkRequest) +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + if (!filePath.isEmpty()) + readConfiguration(); + ui->setupUi(this); + translate(); + + m_values[tag(QString("response"))] = QString(); + + // HACK declare as child of nullptr to avoid crash with plasmawindowed + // in the destructor + m_manager = new QNetworkAccessManager(nullptr); + connect(m_manager, SIGNAL(finished(QNetworkReply *)), this, + SLOT(networkReplyReceived(QNetworkReply *))); + + connect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest())); +} + + +ExtNetworkRequest::~ExtNetworkRequest() +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + disconnect(m_manager, SIGNAL(finished(QNetworkReply *)), this, + SLOT(networkReplyReceived(QNetworkReply *))); + disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest())); + + m_manager->deleteLater(); + delete ui; +} + + +ExtNetworkRequest *ExtNetworkRequest::copy(const QString _fileName, + const int _number) +{ + qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; + + ExtNetworkRequest *item + = new ExtNetworkRequest(static_cast(parent()), _fileName); + copyDefaults(item); + item->setNumber(_number); + item->setStringUrl(stringUrl()); + + return item; +} + + +QString ExtNetworkRequest::stringUrl() const +{ + return m_stringUrl; +} + + +QString ExtNetworkRequest::uniq() const +{ + return m_url.toString(); +} + + +void ExtNetworkRequest::setStringUrl(const QString _url) +{ + qCDebug(LOG_LIB) << "Url" << _url; + + m_stringUrl = _url; + initUrl(); +} + + +void ExtNetworkRequest::readConfiguration() +{ + AbstractExtItem::readConfiguration(); + + QSettings settings(fileName(), QSettings::IniFormat); + + settings.beginGroup(QString("Desktop Entry")); + setStringUrl(settings.value(QString("X-AW-Url"), stringUrl()).toString()); + settings.endGroup(); + + bumpApi(AW_EXTNETREQUEST_API); +} + + +QVariantHash ExtNetworkRequest::run() +{ + if (m_isRunning) + return m_values; + startTimer(); + + return m_values; +} + + +int ExtNetworkRequest::showConfiguration(const QVariant args) +{ + Q_UNUSED(args) + + ui->lineEdit_name->setText(name()); + ui->lineEdit_comment->setText(comment()); + ui->label_numberValue->setText(QString("%1").arg(number())); + ui->lineEdit_url->setText(stringUrl()); + ui->checkBox_active->setCheckState(isActive() ? Qt::Checked + : Qt::Unchecked); + ui->lineEdit_schedule->setText(cron()); + ui->lineEdit_socket->setText(socket()); + ui->spinBox_interval->setValue(interval()); + + int ret = exec(); + if (ret != 1) + return ret; + setName(ui->lineEdit_name->text()); + setComment(ui->lineEdit_comment->text()); + setNumber(ui->label_numberValue->text().toInt()); + setApiVersion(AW_EXTNETREQUEST_API); + setStringUrl(ui->lineEdit_url->text()); + setActive(ui->checkBox_active->checkState() == Qt::Checked); + setCron(ui->lineEdit_schedule->text()); + setSocket(ui->lineEdit_socket->text()); + setInterval(ui->spinBox_interval->value()); + + writeConfiguration(); + return ret; +} + + +void ExtNetworkRequest::writeConfiguration() const +{ + AbstractExtItem::writeConfiguration(); + + QSettings settings(writtableConfig(), QSettings::IniFormat); + qCInfo(LOG_LIB) << "Configuration file" << settings.fileName(); + + settings.beginGroup(QString("Desktop Entry")); + settings.setValue(QString("X-AW-Url"), stringUrl()); + settings.endGroup(); + + settings.sync(); +} + +void ExtNetworkRequest::networkReplyReceived(QNetworkReply *reply) +{ + if (reply->error() != QNetworkReply::NoError) { + qCWarning(LOG_AW) << "An error occurs" << reply->error() + << "with message" << reply->errorString(); + return; + } + + m_isRunning = false; + m_values[tag(QString("response"))] + = QTextCodec::codecForMib(106)->toUnicode(reply->readAll()).trimmed(); + + emit(dataReceived(m_values)); +} + + +void ExtNetworkRequest::sendRequest() +{ + m_isRunning = true; + QNetworkReply *reply = m_manager->get(QNetworkRequest(m_url)); + new QReplyTimeout(reply, REQUEST_TIMEOUT); +} + + +void ExtNetworkRequest::initUrl() +{ + m_url = QUrl(m_stringUrl); +} + + +void ExtNetworkRequest::translate() +{ + ui->label_name->setText(i18n("Name")); + ui->label_comment->setText(i18n("Comment")); + ui->label_number->setText(i18n("Tag")); + ui->label_url->setText(i18n("URL")); + ui->checkBox_active->setText(i18n("Active")); + ui->label_schedule->setText(i18n("Schedule")); + ui->label_socket->setText(i18n("Socket")); + ui->label_interval->setText(i18n("Interval")); +} diff --git a/sources/awesomewidgets/extnetworkrequest.h b/sources/awesomewidgets/extnetworkrequest.h new file mode 100644 index 0000000..fb979c0 --- /dev/null +++ b/sources/awesomewidgets/extnetworkrequest.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#ifndef EXTNETWORKREQUEST_H +#define EXTNETWORKREQUEST_H + +#include + +#include "abstractextitem.h" + + +namespace Ui +{ +class ExtNetworkRequest; +} + +class ExtNetworkRequest : public AbstractExtItem +{ + Q_OBJECT + Q_PROPERTY(QString stringUrl READ stringUrl WRITE setStringUrl) + +public: + explicit ExtNetworkRequest(QWidget *parent, + const QString filePath = QString()); + virtual ~ExtNetworkRequest(); + ExtNetworkRequest *copy(const QString _fileName, const int _number); + // get methods + QString stringUrl() const; + QString uniq() const; + // set methods + void setStringUrl(const QString _url = QString("https://httpbin.org/get")); + +public slots: + void readConfiguration(); + QVariantHash run(); + int showConfiguration(const QVariant args = QVariant()); + void writeConfiguration() const; + +private slots: + void networkReplyReceived(QNetworkReply *reply); + void sendRequest(); + +private: + QNetworkAccessManager *m_manager = nullptr; + QUrl m_url; + bool m_isRunning = false; + Ui::ExtNetworkRequest *ui = nullptr; + void initUrl(); + void translate(); + // properties + QString m_stringUrl = QString("https://httpbin.org/get"); + // values + int m_times = 0; + QVariantHash m_values; +}; + + +#endif /* EXTNETWORKREQUEST_H */ diff --git a/sources/awesomewidgets/extnetworkrequest.ui b/sources/awesomewidgets/extnetworkrequest.ui new file mode 100644 index 0000000..d4dea4d --- /dev/null +++ b/sources/awesomewidgets/extnetworkrequest.ui @@ -0,0 +1,273 @@ + + + ExtNetworkRequest + + + + 0 + 0 + 420 + 301 + + + + Configuration + + + + + + + + + 0 + 0 + + + + Name + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + 0 + 0 + + + + Comment + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + Tag + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + URL + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Active + + + + + + + + + + + + 0 + 0 + + + + Schedule + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + 0 + 0 + + + + Socket + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + Interval + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 1 + + + 10000 + + + 10 + + + 60 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + ExtNetworkRequest + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ExtNetworkRequest + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/sources/awesomewidgets/extquotes.cpp b/sources/awesomewidgets/extquotes.cpp index de54b63..4f8096a 100644 --- a/sources/awesomewidgets/extquotes.cpp +++ b/sources/awesomewidgets/extquotes.cpp @@ -59,6 +59,8 @@ ExtQuotes::ExtQuotes(QWidget *parent, const QString filePath) m_manager = new QNetworkAccessManager(nullptr); connect(m_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(quotesReplyReceived(QNetworkReply *))); + + connect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest())); } @@ -68,6 +70,7 @@ ExtQuotes::~ExtQuotes() disconnect(m_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(quotesReplyReceived(QNetworkReply *))); + disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest())); m_manager->deleteLater(); delete ui; @@ -119,26 +122,15 @@ void ExtQuotes::readConfiguration() setTicker(settings.value(QString("X-AW-Ticker"), ticker()).toString()); settings.endGroup(); - bumpApi(AWEQAPI); + bumpApi(AW_EXTQUOTES_API); } QVariantHash ExtQuotes::run() { - if ((!isActive()) || (m_isRunning)) + if (m_isRunning) return m_values; - - if (m_times == 1) { - qCInfo(LOG_LIB) << "Send request"; - m_isRunning = true; - QNetworkReply *reply = m_manager->get(QNetworkRequest(m_url)); - new QReplyTimeout(reply, REQUEST_TIMEOUT); - } - - // update value - if (m_times >= interval()) - m_times = 0; - m_times++; + startTimer(); return m_values; } @@ -154,6 +146,8 @@ int ExtQuotes::showConfiguration(const QVariant args) ui->lineEdit_ticker->setText(ticker()); ui->checkBox_active->setCheckState(isActive() ? Qt::Checked : Qt::Unchecked); + ui->lineEdit_schedule->setText(cron()); + ui->lineEdit_socket->setText(socket()); ui->spinBox_interval->setValue(interval()); int ret = exec(); @@ -162,9 +156,11 @@ int ExtQuotes::showConfiguration(const QVariant args) setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); setNumber(ui->label_numberValue->text().toInt()); - setApiVersion(AWEQAPI); + setApiVersion(AW_EXTQUOTES_API); setTicker(ui->lineEdit_ticker->text()); setActive(ui->checkBox_active->checkState() == Qt::Checked); + setCron(ui->lineEdit_schedule->text()); + setSocket(ui->lineEdit_socket->text()); setInterval(ui->spinBox_interval->value()); writeConfiguration(); @@ -245,6 +241,14 @@ void ExtQuotes::quotesReplyReceived(QNetworkReply *reply) } +void ExtQuotes::sendRequest() +{ + m_isRunning = true; + QNetworkReply *reply = m_manager->get(QNetworkRequest(m_url)); + new QReplyTimeout(reply, REQUEST_TIMEOUT); +} + + void ExtQuotes::initUrl() { // init query @@ -271,5 +275,7 @@ get quotes for the instrument. Refer to \

    ")); ui->label_ticker->setText(i18n("Ticker")); ui->checkBox_active->setText(i18n("Active")); + ui->label_schedule->setText(i18n("Schedule")); + ui->label_socket->setText(i18n("Socket")); ui->label_interval->setText(i18n("Interval")); } diff --git a/sources/awesomewidgets/extquotes.h b/sources/awesomewidgets/extquotes.h index bf70c83..ac1fc42 100644 --- a/sources/awesomewidgets/extquotes.h +++ b/sources/awesomewidgets/extquotes.h @@ -22,10 +22,6 @@ #include "abstractextitem.h" -#define YAHOO_QUOTES_URL "https://query.yahooapis.com/v1/public/yql" -#define YAHOO_QUOTES_QUERY \ - "select * from yahoo.finance.quotes where symbol='%1'" - namespace Ui { @@ -38,6 +34,10 @@ class ExtQuotes : public AbstractExtItem Q_PROPERTY(QString ticker READ ticker WRITE setTicker) public: + const char *YAHOO_QUOTES_URL = "https://query.yahooapis.com/v1/public/yql"; + const char *YAHOO_QUOTES_QUERY + = "select * from yahoo.finance.quotes where symbol='%1'"; + explicit ExtQuotes(QWidget *parent, const QString filePath = QString()); virtual ~ExtQuotes(); ExtQuotes *copy(const QString _fileName, const int _number); @@ -55,6 +55,7 @@ public slots: private slots: void quotesReplyReceived(QNetworkReply *reply); + void sendRequest(); private: QNetworkAccessManager *m_manager = nullptr; diff --git a/sources/awesomewidgets/extquotes.ui b/sources/awesomewidgets/extquotes.ui index aef15a1..620e914 100644 --- a/sources/awesomewidgets/extquotes.ui +++ b/sources/awesomewidgets/extquotes.ui @@ -7,7 +7,7 @@ 0 0 420 - 301 + 339 @@ -150,6 +150,52 @@ + + + + + + + 0 + 0 + + + + Schedule + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + 0 + 0 + + + + Socket + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + diff --git a/sources/awesomewidgets/extscript.cpp b/sources/awesomewidgets/extscript.cpp index 781413b..acab312 100644 --- a/sources/awesomewidgets/extscript.cpp +++ b/sources/awesomewidgets/extscript.cpp @@ -48,6 +48,8 @@ ExtScript::ExtScript(QWidget *parent, const QString filePath) connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(updateValue())); m_process->waitForFinished(0); + + connect(this, SIGNAL(requestDataUpdate()), this, SLOT(startProcess())); } @@ -55,8 +57,11 @@ ExtScript::~ExtScript() { qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + disconnect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, + SLOT(updateValue())); m_process->kill(); m_process->deleteLater(); + disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(startProcess())); delete ui; } @@ -78,6 +83,18 @@ ExtScript *ExtScript::copy(const QString _fileName, const int _number) } +QString ExtScript::jsonFiltersFile() const +{ + QString fileName = QStandardPaths::locate( + QStandardPaths::GenericDataLocation, + QString( + "awesomewidgets/scripts/awesomewidgets-extscripts-filters.json")); + qCInfo(LOG_LIB) << "Filters file" << fileName; + + return fileName; +} + + QString ExtScript::executable() const { return m_executable; @@ -186,8 +203,8 @@ QString ExtScript::applyFilters(QString _value) const qCInfo(LOG_LIB) << "Found filter" << filt; QVariantMap filter = m_jsonFilters[filt].toMap(); if (filter.isEmpty()) { - qCWarning(LOG_LIB) << "Could not find filter" << _value - << "in the json"; + qCWarning(LOG_LIB) + << "Could not find filter" << _value << "in the json"; continue; } for (auto f : filter.keys()) @@ -229,17 +246,13 @@ void ExtScript::readConfiguration() .split(QChar(','), QString::SkipEmptyParts)); settings.endGroup(); - bumpApi(AWESAPI); + bumpApi(AW_EXTSCRIPT_API); } void ExtScript::readJsonFilters() { - QString fileName = QStandardPaths::locate( - QStandardPaths::GenericDataLocation, - QString( - "awesomewidgets/scripts/awesomewidgets-extscripts-filters.json")); - qCInfo(LOG_LIB) << "Filters file" << fileName; + QString fileName = jsonFiltersFile(); QFile jsonFile(fileName); if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) { qCWarning(LOG_LIB) << "Could not open" << fileName; @@ -262,25 +275,9 @@ void ExtScript::readJsonFilters() QVariantHash ExtScript::run() { - if (!isActive()) - return m_values; if (m_process->state() != QProcess::NotRunning) - qCWarning(LOG_LIB) << "Another process is already running" - << m_process->state(); - - if ((m_times == 1) && (m_process->state() == QProcess::NotRunning)) { - QStringList cmdList; - if (!prefix().isEmpty()) - cmdList.append(prefix()); - cmdList.append(executable()); - qCInfo(LOG_LIB) << "Run cmd" << cmdList.join(QChar(' ')); - m_process->start(cmdList.join(QChar(' '))); - } - - // update value - if (m_times >= interval()) - m_times = 0; - m_times++; + return m_values; + startTimer(); return m_values; } @@ -298,6 +295,8 @@ int ExtScript::showConfiguration(const QVariant args) ui->checkBox_active->setCheckState(isActive() ? Qt::Checked : Qt::Unchecked); ui->comboBox_redirect->setCurrentIndex(static_cast(redirect())); + ui->lineEdit_schedule->setText(cron()); + ui->lineEdit_socket->setText(socket()); ui->spinBox_interval->setValue(interval()); // filters ui->checkBox_colorFilter->setCheckState( @@ -313,11 +312,13 @@ int ExtScript::showConfiguration(const QVariant args) setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); setNumber(ui->label_numberValue->text().toInt()); - setApiVersion(AWESAPI); + setApiVersion(AW_EXTSCRIPT_API); setExecutable(ui->lineEdit_command->text()); setPrefix(ui->lineEdit_prefix->text()); setActive(ui->checkBox_active->checkState() == Qt::Checked); setRedirect(static_cast(ui->comboBox_redirect->currentIndex())); + setCron(ui->lineEdit_schedule->text()); + setSocket(ui->lineEdit_socket->text()); setInterval(ui->spinBox_interval->value()); // filters updateFilter(QString("color"), @@ -350,6 +351,17 @@ void ExtScript::writeConfiguration() const } +void ExtScript::startProcess() +{ + QStringList cmdList; + if (!prefix().isEmpty()) + cmdList.append(prefix()); + cmdList.append(executable()); + qCInfo(LOG_LIB) << "Run cmd" << cmdList.join(QChar(' ')); + m_process->start(cmdList.join(QChar(' '))); +} + + void ExtScript::updateValue() { qCInfo(LOG_LIB) << "Cmd returns" << m_process->exitCode(); @@ -392,6 +404,8 @@ void ExtScript::translate() ui->label_prefix->setText(i18n("Prefix")); ui->checkBox_active->setText(i18n("Active")); ui->label_redirect->setText(i18n("Redirect")); + ui->label_schedule->setText(i18n("Schedule")); + ui->label_socket->setText(i18n("Socket")); ui->label_interval->setText(i18n("Interval")); ui->groupBox_filters->setTitle(i18n("Additional filters")); ui->checkBox_colorFilter->setText(i18n("Wrap colors")); diff --git a/sources/awesomewidgets/extscript.h b/sources/awesomewidgets/extscript.h index e9dd192..002b716 100644 --- a/sources/awesomewidgets/extscript.h +++ b/sources/awesomewidgets/extscript.h @@ -47,6 +47,7 @@ public: explicit ExtScript(QWidget *parent, const QString filePath = QString()); virtual ~ExtScript(); ExtScript *copy(const QString _fileName, const int _number); + QString jsonFiltersFile() const; // get methods QString executable() const; QStringList filters() const; @@ -73,6 +74,7 @@ public slots: void writeConfiguration() const; private slots: + void startProcess(); void updateValue(); private: diff --git a/sources/awesomewidgets/extscript.ui b/sources/awesomewidgets/extscript.ui index 25c7c77..2445f9e 100644 --- a/sources/awesomewidgets/extscript.ui +++ b/sources/awesomewidgets/extscript.ui @@ -7,7 +7,7 @@ 0 0 420 - 424 + 473 @@ -195,6 +195,52 @@ + + + + + + + 0 + 0 + + + + Schedule + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + 0 + 0 + + + + Socket + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + diff --git a/sources/awesomewidgets/extupgrade.cpp b/sources/awesomewidgets/extupgrade.cpp index ef73a6d..c87da54 100644 --- a/sources/awesomewidgets/extupgrade.cpp +++ b/sources/awesomewidgets/extupgrade.cpp @@ -44,6 +44,8 @@ ExtUpgrade::ExtUpgrade(QWidget *parent, const QString filePath) m_process = new QProcess(nullptr); connect(m_process, SIGNAL(finished(int)), this, SLOT(updateValue())); m_process->waitForFinished(0); + + connect(this, SIGNAL(requestDataUpdate()), this, SLOT(startProcess())); } @@ -53,6 +55,7 @@ ExtUpgrade::~ExtUpgrade() m_process->kill(); m_process->deleteLater(); + disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(startProcess())); delete ui; } @@ -136,25 +139,15 @@ void ExtUpgrade::readConfiguration() setFilter(settings.value(QString("X-AW-Filter"), filter()).toString()); settings.endGroup(); - bumpApi(AWEUAPI); + bumpApi(AW_EXTUPGRADE_API); } QVariantHash ExtUpgrade::run() { - if (!isActive()) + if (m_process->state() != QProcess::NotRunning) return m_values; - - if ((m_times == 1) && (m_process->state() == QProcess::NotRunning)) { - QString cmd = QString("sh -c \"%1\"").arg(executable()); - qCInfo(LOG_LIB) << "Run cmd" << cmd; - m_process->start(cmd); - } - - // update value - if (m_times >= interval()) - m_times = 0; - m_times++; + startTimer(); return m_values; } @@ -172,6 +165,8 @@ int ExtUpgrade::showConfiguration(const QVariant args) ui->checkBox_active->setCheckState(isActive() ? Qt::Checked : Qt::Unchecked); ui->spinBox_null->setValue(null()); + ui->lineEdit_schedule->setText(cron()); + ui->lineEdit_socket->setText(socket()); ui->spinBox_interval->setValue(interval()); int ret = exec(); @@ -180,11 +175,13 @@ int ExtUpgrade::showConfiguration(const QVariant args) setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); setNumber(ui->label_numberValue->text().toInt()); - setApiVersion(AWEUAPI); + setApiVersion(AW_EXTUPGRADE_API); setExecutable(ui->lineEdit_command->text()); setFilter(ui->lineEdit_filter->text()); setActive(ui->checkBox_active->checkState() == Qt::Checked); setNull(ui->spinBox_null->value()); + setCron(ui->lineEdit_schedule->text()); + setSocket(ui->lineEdit_socket->text()); setInterval(ui->spinBox_interval->value()); writeConfiguration(); @@ -209,6 +206,14 @@ void ExtUpgrade::writeConfiguration() const } +void ExtUpgrade::startProcess() +{ + QString cmd = QString("sh -c \"%1\"").arg(executable()); + qCInfo(LOG_LIB) << "Run cmd" << cmd; + m_process->start(cmd); +} + + void ExtUpgrade::updateValue() { qCInfo(LOG_LIB) << "Cmd returns" << m_process->exitCode(); @@ -239,5 +244,7 @@ void ExtUpgrade::translate() ui->label_filter->setText(i18n("Filter")); ui->checkBox_active->setText(i18n("Active")); ui->label_null->setText(i18n("Null")); + ui->label_socket->setText(i18n("Socket")); + ui->label_schedule->setText(i18n("Schedule")); ui->label_interval->setText(i18n("Interval")); } diff --git a/sources/awesomewidgets/extupgrade.h b/sources/awesomewidgets/extupgrade.h index 673a4a4..d4c7c55 100644 --- a/sources/awesomewidgets/extupgrade.h +++ b/sources/awesomewidgets/extupgrade.h @@ -56,6 +56,7 @@ public slots: void writeConfiguration() const; private slots: + void startProcess(); void updateValue(); private: diff --git a/sources/awesomewidgets/extupgrade.ui b/sources/awesomewidgets/extupgrade.ui index 9b7e5ba..edf3517 100644 --- a/sources/awesomewidgets/extupgrade.ui +++ b/sources/awesomewidgets/extupgrade.ui @@ -7,7 +7,7 @@ 0 0 420 - 301 + 349 @@ -181,6 +181,52 @@ + + + + + + + 0 + 0 + + + + Schedule + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + 0 + 0 + + + + Socket + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + diff --git a/sources/awesomewidgets/extweather.cpp b/sources/awesomewidgets/extweather.cpp index 75da21d..0791edc 100644 --- a/sources/awesomewidgets/extweather.cpp +++ b/sources/awesomewidgets/extweather.cpp @@ -58,6 +58,8 @@ ExtWeather::ExtWeather(QWidget *parent, const QString filePath) m_manager = new QNetworkAccessManager(nullptr); connect(m_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(weatherReplyReceived(QNetworkReply *))); + + connect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest())); } @@ -67,6 +69,7 @@ ExtWeather::~ExtWeather() disconnect(m_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(weatherReplyReceived(QNetworkReply *))); + disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest())); m_manager->deleteLater(); delete m_providerObject; @@ -92,6 +95,17 @@ ExtWeather *ExtWeather::copy(const QString _fileName, const int _number) } +QString ExtWeather::jsonMapFile() const +{ + QString fileName = QStandardPaths::locate( + QStandardPaths::GenericDataLocation, + QString("awesomewidgets/weather/awesomewidgets-extweather-ids.json")); + qCInfo(LOG_LIB) << "Map file" << fileName; + + return fileName; +} + + QString ExtWeather::weatherFromInt(const int _id) const { qCDebug(LOG_LIB) << "Weather ID" << _id; @@ -227,16 +241,13 @@ void ExtWeather::readConfiguration() settings.value(QString("X-AW-Provider"), strProvider()).toString()); settings.endGroup(); - bumpApi(AWEWAPI); + bumpApi(AW_EXTWEATHER_API); } void ExtWeather::readJsonMap() { - QString fileName = QStandardPaths::locate( - QStandardPaths::GenericDataLocation, - QString("awesomewidgets/weather/awesomewidgets-extweather-ids.json")); - qCInfo(LOG_LIB) << "Map file" << fileName; + QString fileName = jsonMapFile(); QFile jsonFile(fileName); if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) { qCWarning(LOG_LIB) << "Could not open" << fileName; @@ -259,21 +270,9 @@ void ExtWeather::readJsonMap() QVariantHash ExtWeather::run() { - if ((!isActive()) || (m_isRunning)) + if (m_isRunning) return m_values; - - if (m_times == 1) { - qCInfo(LOG_LIB) << "Send request"; - m_isRunning = true; - QNetworkReply *reply - = m_manager->get(QNetworkRequest(m_providerObject->url())); - new QReplyTimeout(reply, REQUEST_TIMEOUT); - } - - // update value - if (m_times >= interval()) - m_times = 0; - m_times++; + startTimer(); return m_values; } @@ -293,6 +292,8 @@ int ExtWeather::showConfiguration(const QVariant args) ui->checkBox_image->setCheckState(image() ? Qt::Checked : Qt::Unchecked); ui->checkBox_active->setCheckState(isActive() ? Qt::Checked : Qt::Unchecked); + ui->lineEdit_schedule->setText(cron()); + ui->lineEdit_socket->setText(socket()); ui->spinBox_interval->setValue(interval()); int ret = exec(); @@ -301,13 +302,15 @@ int ExtWeather::showConfiguration(const QVariant args) setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); setNumber(ui->label_numberValue->text().toInt()); - setApiVersion(AWEWAPI); + setApiVersion(AW_EXTWEATHER_API); setCity(ui->lineEdit_city->text()); setCountry(ui->lineEdit_country->text()); setProvider(static_cast(ui->comboBox_provider->currentIndex())); setTs(ui->spinBox_timestamp->value()); setImage(ui->checkBox_image->checkState() == Qt::Checked); setActive(ui->checkBox_active->checkState() == Qt::Checked); + setCron(ui->lineEdit_schedule->text()); + setSocket(ui->lineEdit_socket->text()); setInterval(ui->spinBox_interval->value()); writeConfiguration(); @@ -334,6 +337,15 @@ void ExtWeather::writeConfiguration() const } +void ExtWeather::sendRequest() +{ + m_isRunning = true; + QNetworkReply *reply + = m_manager->get(QNetworkRequest(m_providerObject->url())); + new QReplyTimeout(reply, REQUEST_TIMEOUT); +} + + void ExtWeather::weatherReplyReceived(QNetworkReply *reply) { if (reply->error() != QNetworkReply::NoError) { @@ -390,5 +402,7 @@ void ExtWeather::translate() ui->label_timestamp->setText(i18n("Timestamp")); ui->checkBox_image->setText(i18n("Use images")); ui->checkBox_active->setText(i18n("Active")); + ui->label_schedule->setText(i18n("Schedule")); + ui->label_socket->setText(i18n("Socket")); ui->label_interval->setText(i18n("Interval")); } diff --git a/sources/awesomewidgets/extweather.h b/sources/awesomewidgets/extweather.h index 3a775ce..201758c 100644 --- a/sources/awesomewidgets/extweather.h +++ b/sources/awesomewidgets/extweather.h @@ -45,6 +45,7 @@ public: explicit ExtWeather(QWidget *parent, const QString filePath = QString()); virtual ~ExtWeather(); ExtWeather *copy(const QString _fileName, const int _number); + QString jsonMapFile() const; QString weatherFromInt(const int _id) const; // get methods QString city() const; @@ -70,6 +71,7 @@ public slots: void writeConfiguration() const; private slots: + void sendRequest(); void weatherReplyReceived(QNetworkReply *reply); private: diff --git a/sources/awesomewidgets/extweather.ui b/sources/awesomewidgets/extweather.ui index 0b5bb43..19010d3 100644 --- a/sources/awesomewidgets/extweather.ui +++ b/sources/awesomewidgets/extweather.ui @@ -7,7 +7,7 @@ 0 0 420 - 333 + 413 @@ -248,6 +248,52 @@ + + + + + + + 0 + 0 + + + + Schedule + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + 0 + 0 + + + + Socket + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + diff --git a/sources/awesomewidgets/formatters/default-float.desktop b/sources/awesomewidgets/formatters/default-float.desktop index f83a304..5627f3f 100644 --- a/sources/awesomewidgets/formatters/default-float.desktop +++ b/sources/awesomewidgets/formatters/default-float.desktop @@ -3,7 +3,7 @@ Comment=Default float formatter Encoding=UTF-8 Name=Float X-AW-Active=true -X-AW-ApiVersion=2 +X-AW-ApiVersion=3 X-AW-FillChar=@Variant(\0\0\0\a\0\0) X-AW-ForceWidth=false X-AW-Format=f diff --git a/sources/awesomewidgets/formatters/default-integer.desktop b/sources/awesomewidgets/formatters/default-integer.desktop index 1c36748..fdddc9a 100644 --- a/sources/awesomewidgets/formatters/default-integer.desktop +++ b/sources/awesomewidgets/formatters/default-integer.desktop @@ -3,7 +3,7 @@ Comment=Default integer formatter Encoding=UTF-8 Name=Integer X-AW-Active=true -X-AW-ApiVersion=2 +X-AW-ApiVersion=3 X-AW-FillChar=@Variant(\0\0\0\a\0\0) X-AW-ForceWidth=false X-AW-Format=f diff --git a/sources/awesomewidgets/formatters/default-list.desktop b/sources/awesomewidgets/formatters/default-list.desktop index da6c740..4932483 100644 --- a/sources/awesomewidgets/formatters/default-list.desktop +++ b/sources/awesomewidgets/formatters/default-list.desktop @@ -3,7 +3,7 @@ Comment=Default list formatter Encoding=UTF-8 Name=List X-AW-Active=true -X-AW-ApiVersion=2 +X-AW-ApiVersion=3 X-AW-Filter= X-AW-Interval=1 X-AW-Number=5 diff --git a/sources/awesomewidgets/formatters/float-two-symbols.desktop b/sources/awesomewidgets/formatters/float-two-symbols.desktop index 29e2a2a..ad45e78 100644 --- a/sources/awesomewidgets/formatters/float-two-symbols.desktop +++ b/sources/awesomewidgets/formatters/float-two-symbols.desktop @@ -3,7 +3,7 @@ Comment=Float formatter with two symbols Encoding=UTF-8 Name=FloatTwoSymbols X-AW-Active=true -X-AW-ApiVersion=2 +X-AW-ApiVersion=3 X-AW-FillChar=@Variant(\0\0\0\a\0\0) X-AW-ForceWidth=false X-AW-Format=f diff --git a/sources/awesomewidgets/formatters/long-integer.desktop b/sources/awesomewidgets/formatters/long-integer.desktop index e3aabd0..7d64520 100644 --- a/sources/awesomewidgets/formatters/long-integer.desktop +++ b/sources/awesomewidgets/formatters/long-integer.desktop @@ -3,7 +3,7 @@ Comment=Long integer formatter Encoding=UTF-8 Name=LongInteger X-AW-Active=true -X-AW-ApiVersion=2 +X-AW-ApiVersion=3 X-AW-FillChar=@Variant(\0\0\0\a\0\0) X-AW-ForceWidth=false X-AW-Format=f diff --git a/sources/awesomewidgets/formatters/memory-gb.desktop b/sources/awesomewidgets/formatters/memory-gb.desktop index f7de14d..da8398b 100644 --- a/sources/awesomewidgets/formatters/memory-gb.desktop +++ b/sources/awesomewidgets/formatters/memory-gb.desktop @@ -3,7 +3,7 @@ Comment=Memory in GB formatter Encoding=UTF-8 Name=MemGB X-AW-Active=true -X-AW-ApiVersion=2 +X-AW-ApiVersion=3 X-AW-FillChar=@Variant(\0\0\0\a\0\0) X-AW-ForceWidth=false X-AW-Format=f diff --git a/sources/awesomewidgets/formatters/memory-mb.desktop b/sources/awesomewidgets/formatters/memory-mb.desktop index a54d376..8882740 100644 --- a/sources/awesomewidgets/formatters/memory-mb.desktop +++ b/sources/awesomewidgets/formatters/memory-mb.desktop @@ -3,7 +3,7 @@ Comment=Memory in MB formatter Encoding=UTF-8 Name=MemMB X-AW-Active=true -X-AW-ApiVersion=2 +X-AW-ApiVersion=3 X-AW-FillChar=@Variant(\0\0\0\a\0\0) X-AW-ForceWidth=false X-AW-Format=f diff --git a/sources/awesomewidgets/formatters/short-integer.desktop b/sources/awesomewidgets/formatters/short-integer.desktop index 28e398d..da2665d 100644 --- a/sources/awesomewidgets/formatters/short-integer.desktop +++ b/sources/awesomewidgets/formatters/short-integer.desktop @@ -3,7 +3,7 @@ Comment=Short integer formatter Encoding=UTF-8 Name=ShortInteger X-AW-Active=true -X-AW-ApiVersion=2 +X-AW-ApiVersion=3 X-AW-FillChar=@Variant(\0\0\0\a\0\0) X-AW-ForceWidth=false X-AW-Format=f diff --git a/sources/awesomewidgets/graphicalitem.cpp b/sources/awesomewidgets/graphicalitem.cpp index 8a9c32c..596cb17 100644 --- a/sources/awesomewidgets/graphicalitem.cpp +++ b/sources/awesomewidgets/graphicalitem.cpp @@ -455,7 +455,7 @@ void GraphicalItem::readConfiguration() } settings.endGroup(); - bumpApi(AWGIAPI); + bumpApi(AW_GRAPHITEM_API); initScene(); } @@ -504,7 +504,7 @@ int GraphicalItem::showConfiguration(const QVariant args) return ret; setName(ui->lineEdit_name->text()); setComment(ui->lineEdit_comment->text()); - setApiVersion(AWGIAPI); + setApiVersion(AW_GRAPHITEM_API); setCount(ui->spinBox_count->value()); setCustom(ui->checkBox_custom->isChecked()); setBar(m_custom ? ui->lineEdit_customValue->text() diff --git a/sources/awesomewidgets/owmweatherprovider.h b/sources/awesomewidgets/owmweatherprovider.h index 409b7b0..c25d791 100644 --- a/sources/awesomewidgets/owmweatherprovider.h +++ b/sources/awesomewidgets/owmweatherprovider.h @@ -20,17 +20,17 @@ #include "abstractweatherprovider.h" -// we are using own server to pass requests to OpenWeatherMap because it -// requires specific APPID which belongs to developer not user -#define OWM_WEATHER_URL "http://arcanis.me/weather" -#define OWM_FORECAST_URL "http://arcanis.me/forecast" - class OWMWeatherProvider : public AbstractWeatherProvider { Q_OBJECT public: + // we are using own server to pass requests to OpenWeatherMap because it + // requires specific APPID which belongs to developer not user + const char *OWM_WEATHER_URL = "https://arcanis.me/weather"; + const char *OWM_FORECAST_URL = "https://arcanis.me/forecast"; + explicit OWMWeatherProvider(QObject *parent, const int number); virtual ~OWMWeatherProvider(); void initUrl(const QString city, const QString country, const int); diff --git a/sources/awesomewidgets/qcronscheduler.cpp b/sources/awesomewidgets/qcronscheduler.cpp new file mode 100644 index 0000000..09275d6 --- /dev/null +++ b/sources/awesomewidgets/qcronscheduler.cpp @@ -0,0 +1,158 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#include "qcronscheduler.h" + +#include +#include + +#include "awdebug.h" + + +QCronScheduler::QCronScheduler(QObject *parent) + : QObject(parent) +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + m_timer = new QTimer(this); + m_timer->setSingleShot(false); + m_timer->setInterval(60 * 1000); + + connect(m_timer, SIGNAL(timeout()), this, SLOT(expired())); + + m_timer->start(); +} + + +QCronScheduler::~QCronScheduler() +{ + qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; + + m_timer->stop(); + delete m_timer; +} + + +void QCronScheduler::parse(const QString &timer) +{ + qCDebug(LOG_LIB) << "Parse timer string" << timer; + + QStringList fields = timer.split(' '); + if (fields.count() != 5) + return; + + m_schedule.minutes = parseField(fields.at(0), 0, 59); + m_schedule.hours = parseField(fields.at(1), 0, 23); + m_schedule.days = parseField(fields.at(2), 1, 31); + m_schedule.months = parseField(fields.at(3), 1, 12); + m_schedule.weekdays = parseField(fields.at(4), 1, 7); +} + + +void QCronScheduler::expired() +{ + QDateTime now = QDateTime::currentDateTime(); + + if (m_schedule.minutes.contains(now.time().minute()) + && m_schedule.hours.contains(now.time().hour()) + && m_schedule.days.contains(now.date().day()) + && m_schedule.months.contains(now.date().month()) + && m_schedule.weekdays.contains(now.date().dayOfWeek())) + emit(activated()); +} + + +QList QCronScheduler::parseField(const QString &value, const int min, + const int max) const +{ + qCDebug(LOG_LIB) << "Parse field" << value << "with corner values" << min + << max; + + QList parsed; + auto fields = value.split(','); + for (auto &field : fields) { + QCronField parsedField; + parsedField.fromRange(field.split('/').first(), min, max); + if (field.contains('/')) { + bool status; + parsedField.div = field.split('/', QString::SkipEmptyParts) + .at(1) + .toInt(&status); + if (!status) + parsedField.div = 1; + } + // append + parsed.append(parsedField.toList()); + } + + return parsed; +} + + +void QCronScheduler::QCronField::fromRange(const QString &range, const int min, + const int max) +{ + qCDebug(LOG_LIB) << "Parse field from range" << range + << "with corner values" << min << max; + + if (range == '*') { + minValue = min; + maxValue = max; + } else if (range.contains('-')) { + auto interval = range.split('-', QString::SkipEmptyParts); + if (interval.count() != 2) + return; + bool status; + // minimal value + minValue = std::max(min, interval.at(0).toInt(&status)); + if (!status) + minValue = -1; + // maximal value + maxValue = std::min(max, interval.at(1).toInt(&status)); + if (!status) + maxValue = -1; + // error check + if (minValue > maxValue) + std::swap(minValue, maxValue); + } else { + bool status; + int value = range.toInt(&status); + if (!status || (value < min) || (value > max)) + value = -1; + minValue = value; + maxValue = value; + } +} + + +QList QCronScheduler::QCronField::toList() +{ + // error checking + if ((minValue == -1) || (maxValue == -1)) + return QList(); + + QList output; + for (auto i = minValue; i <= maxValue; ++i) { + if (i % div != 0) + continue; + output.append(i); + } + + std::sort(output.begin(), output.end()); + return output; +} diff --git a/sources/awesomewidgets/qcronscheduler.h b/sources/awesomewidgets/qcronscheduler.h new file mode 100644 index 0000000..e03d34c --- /dev/null +++ b/sources/awesomewidgets/qcronscheduler.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#ifndef QCRONSCHEDULER_H +#define QCRONSCHEDULER_H + +#include "QObject" + + +class QTimer; + +class QCronScheduler : public QObject +{ + Q_OBJECT + +public: + typedef struct { + QList minutes; + QList hours; + QList days; + QList months; + QList weekdays; + } QCronRunSchedule; + typedef struct { + int minValue = -1; + int maxValue = -1; + int div = 1; + void fromRange(const QString &range, const int min, const int max); + QList toList(); + } QCronField; + + explicit QCronScheduler(QObject *parent); + virtual ~QCronScheduler(); + void parse(const QString &timer); + +signals: + void activated(); + +private slots: + void expired(); + +private: + QCronRunSchedule m_schedule; + QTimer *m_timer = nullptr; + QList parseField(const QString &value, const int min, + const int max) const; +}; + + +#endif /* QCRONSCHEDULER_H */ diff --git a/sources/awesomewidgets/requests/httpbin.desktop b/sources/awesomewidgets/requests/httpbin.desktop new file mode 100644 index 0000000..b7d729e --- /dev/null +++ b/sources/awesomewidgets/requests/httpbin.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=httpbin +Comment=httpbin example +X-AW-Ticker=https://httpbin.org/get +X-AW-Active=false +X-AW-ApiVersion=1 +X-AW-Interval=10 +X-AW-Number=0 diff --git a/sources/awesomewidgets/yahooweatherprovider.cpp b/sources/awesomewidgets/yahooweatherprovider.cpp index 569a269..8d4c7e2 100644 --- a/sources/awesomewidgets/yahooweatherprovider.cpp +++ b/sources/awesomewidgets/yahooweatherprovider.cpp @@ -93,8 +93,9 @@ YahooWeatherProvider::parseCurrent(const QVariantMap &json, = json[QString("condition")].toMap()[QString("date")].toString(); values[QString("humidity%1").arg(number())] = atmosphere[QString("humidity")].toInt(); - values[QString("pressure%1").arg(number())] - = static_cast(atmosphere[QString("pressure")].toFloat()); + // HACK temporary fix of invalid values on Yahoo! side + values[QString("pressure%1").arg(number())] = static_cast( + atmosphere[QString("pressure")].toFloat() / 33.863753); return values; } diff --git a/sources/awesomewidgets/yahooweatherprovider.h b/sources/awesomewidgets/yahooweatherprovider.h index d8cfa76..4c31c1d 100644 --- a/sources/awesomewidgets/yahooweatherprovider.h +++ b/sources/awesomewidgets/yahooweatherprovider.h @@ -20,17 +20,17 @@ #include "abstractweatherprovider.h" -#define YAHOO_WEATHER_URL "https://query.yahooapis.com/v1/public/yql" -#define YAHOO_WEATHER_QUERY \ - "select * from weather.forecast where u='c' and woeid in (select woeid " \ - "from geo.places(1) where text='%1, %2')" - class YahooWeatherProvider : public AbstractWeatherProvider { Q_OBJECT public: + const char *YAHOO_WEATHER_URL = "https://query.yahooapis.com/v1/public/yql"; + const char *YAHOO_WEATHER_QUERY = "select * from weather.forecast where " + "u='c' and woeid in (select woeid from " + "geo.places(1) where text='%1, %2')"; + explicit YahooWeatherProvider(QObject *parent, const int number); virtual ~YahooWeatherProvider(); void initUrl(const QString city, const QString country, const int); diff --git a/sources/cppcheck.cmake b/sources/cppcheck.cmake index 3a38881..d739028 100644 --- a/sources/cppcheck.cmake +++ b/sources/cppcheck.cmake @@ -14,7 +14,8 @@ endforeach () add_custom_target( cppcheck COMMAND ${CPPCHECK_EXECUTABLE} - --enable=warning,performance,portability,information,missingInclude + --enable=warning,performance,portability + --error-exitcode=1 --std=c++11 --language=c++ --library=qt.cfg diff --git a/sources/desktop-panel/package/contents/config/main.xml b/sources/desktop-panel/package/contents/config/main.xml index 03a71b6..606d7ba 100644 --- a/sources/desktop-panel/package/contents/config/main.xml +++ b/sources/desktop-panel/package/contents/config/main.xml @@ -60,6 +60,12 @@ normal + + normal + + + #000000 + center @@ -79,6 +85,12 @@ normal + + normal + + + #000000 + diff --git a/sources/desktop-panel/package/contents/ui/about.qml b/sources/desktop-panel/package/contents/ui/about.qml index 723dea3..352cf42 100644 --- a/sources/desktop-panel/package/contents/ui/about.qml +++ b/sources/desktop-panel/package/contents/ui/about.qml @@ -16,8 +16,6 @@ ***************************************************************************/ import QtQuick 2.0 -import QtQuick.Controls 1.3 as QtControls -import QtQuick.Layouts 1.0 as QtLayouts import org.kde.plasma.private.desktoppanel 1.0 @@ -31,98 +29,11 @@ Item { width: childrenRect.width height: childrenRect.height - implicitWidth: pageColumn.implicitWidth - implicitHeight: pageColumn.implicitHeight - property bool debug: dpAdds.isDebugEnabled() - - - Column { - id: pageColumn - anchors.fill: parent - QtControls.TabView { - height: parent.height - width: parent.width - QtControls.Tab { - anchors.margins: 10.0 - title: i18n("About") - - QtLayouts.ColumnLayout { - QtControls.Label { - QtLayouts.Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - text: dpAdds.getAboutText("header") - } - - QtControls.Label { - QtLayouts.Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - text: dpAdds.getAboutText("version") - } - - QtControls.Label { - QtLayouts.Layout.fillWidth: true - horizontalAlignment: Text.AlignJustify - text: dpAdds.getAboutText("description") - } - - QtControls.Label { - QtLayouts.Layout.fillWidth: true - horizontalAlignment: Text.AlignLeft - textFormat: Text.RichText - text: dpAdds.getAboutText("links") - onLinkActivated: Qt.openUrlExternally(link) - } - - QtControls.Label { - QtLayouts.Layout.fillHeight: true - QtLayouts.Layout.fillWidth: true - font.capitalization: Font.SmallCaps - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignBottom - textFormat: Text.RichText - text: dpAdds.getAboutText("copy") - } - } - } - - QtControls.Tab { - anchors.margins: 10.0 - title: i18n("Acknowledgment") - - QtLayouts.ColumnLayout { - QtControls.Label { - QtLayouts.Layout.fillWidth: true - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignJustify - text: dpAdds.getAboutText("translators") - } - - QtControls.Label { - QtLayouts.Layout.fillWidth: true - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignJustify - textFormat: Text.RichText - text: dpAdds.getAboutText("3rdparty") - onLinkActivated: Qt.openUrlExternally(link) - } - - QtControls.Label { - QtLayouts.Layout.fillHeight: true - QtLayouts.Layout.fillWidth: true - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignJustify - verticalAlignment: Text.AlignTop - textFormat: Text.RichText - text: dpAdds.getAboutText("thanks") - onLinkActivated: Qt.openUrlExternally(link) - } - } - } - } + AboutTab { + textProvider: dpAdds } - Component.onCompleted: { if (debug) console.debug() } diff --git a/sources/desktop-panel/package/contents/ui/activeapp.qml b/sources/desktop-panel/package/contents/ui/activeapp.qml index 865352d..da070a8 100644 --- a/sources/desktop-panel/package/contents/ui/activeapp.qml +++ b/sources/desktop-panel/package/contents/ui/activeapp.qml @@ -16,11 +16,9 @@ ***************************************************************************/ import QtQuick 2.0 -import QtQuick.Controls 1.3 as QtControls -import QtQuick.Controls.Styles 1.3 as QtStyles -import QtQuick.Dialogs 1.1 as QtDialogs import org.kde.plasma.private.desktoppanel 1.0 +import "." Item { @@ -36,203 +34,69 @@ Item { implicitHeight: pageColumn.implicitHeight property bool debug: dpAdds.isDebugEnabled() - property variant weight: { - 25: 0, - 50: 1, - 63: 3, - 75: 4, - 87: 5 - } - property alias cfg_currentFontFamily: selectFont.text + property alias cfg_currentFontFamily: font.value property alias cfg_currentFontSize: fontSize.value - property string cfg_currentFontWeight: fontWeight.currentText - property string cfg_currentFontStyle: fontStyle.currentText + property string cfg_currentFontWeight: fontWeight.value + property string cfg_currentFontStyle: fontStyle.value property alias cfg_currentFontColor: selectColor.text + property alias cfg_currentTextStyleColor: selectStyleColor.text + property string cfg_currentTextStyle: textStyle.value Column { id: pageColumn anchors.fill: parent - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font") - } - QtControls.Button { - id: selectFont - width: parent.width * 2 / 3 - text: plasmoid.configuration.currentFontFamily - onClicked: { - if (debug) console.debug() - fontDialog.setFont() - fontDialog.visible = true - } - } + + FontSelector { + id: font + text: i18n("Font") + value: plasmoid.configuration.currentFontFamily } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font size") - } - QtControls.SpinBox { - id: fontSize - width: parent.width * 2 / 3 - minimumValue: 8 - maximumValue: 32 - stepSize: 1 - value: plasmoid.configuration.currentFontSize - } + IntegerSelector { + id: fontSize + maximumValue: 32 + minimumValue: 8 + stepSize: 1 + text: i18n("Font size") + value: plasmoid.configuration.currentFontSize } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font weight") - } - QtControls.ComboBox { - id: fontWeight - width: parent.width * 2 / 3 - textRole: "label" - model: [ - { - 'label': i18n("light"), - 'name': "light" - }, - { - 'label': i18n("normal"), - 'name': "normal" - }, - { - 'label': i18n("demi bold"), - 'name': "demibold" - }, - { - 'label': i18n("bold"), - 'name': "bold" - }, - { - 'label': i18n("black"), - 'name': "black" - } - ] - onCurrentIndexChanged: cfg_currentFontWeight = model[currentIndex]["name"] - Component.onCompleted: { - if (debug) console.debug() - for (var i = 0; i < model.length; i++) { - if (model[i]["name"] == plasmoid.configuration.currentFontWeight) { - if (debug) console.info("Found", model[i]["name"], "on", i) - fontWeight.currentIndex = i - } - } - } - } + ComboBoxSelector { + id: fontWeight + model: general.fontWeightModel + text: i18n("Font weight") + value: plasmoid.configuration.currentFontWeight + onValueEdited: cfg_currentFontWeight = newValue } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font style") - } - QtControls.ComboBox { - id: fontStyle - width: parent.width * 2 / 3 - textRole: "label" - model: [ - { - 'label': i18n("normal"), - 'name': "normal" - }, - { - 'label': i18n("italic"), - 'name': "italic" - } - ] - onCurrentIndexChanged: cfg_currentFontStyle = model[currentIndex]["name"] - Component.onCompleted: { - if (debug) console.debug() - for (var i = 0; i < model.length; i++) { - if (model[i]["name"] == plasmoid.configuration.currentFontStyle) { - if (debug) console.info("Found", model[i]["name"], "on", i) - fontStyle.currentIndex = i - } - } - } - } + ComboBoxSelector { + id: fontStyle + model: general.fontStyleModel + text: i18n("Font style") + value: plasmoid.configuration.currentFontStyle + onValueEdited: cfg_currentFontStyle = newValue } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font color") - } - QtControls.Button { - id: selectColor - width: parent.width * 2 / 3 - style: QtStyles.ButtonStyle { - background: Rectangle { - color: plasmoid.configuration.currentFontColor - } - } - text: plasmoid.configuration.currentFontColor - onClicked: colorDialog.visible = true - } + ColorSelector { + id: selectColor + text: i18n("Font color") + value: plasmoid.configuration.currentFontColor } - } - QtDialogs.ColorDialog { - id: colorDialog - title: i18n("Select a color") - color: selectColor.text - onAccepted: selectColor.text = colorDialog.color - } - - QtDialogs.FontDialog { - id: fontDialog - title: i18n("Select a font") - signal setFont - - onAccepted: { - if (debug) console.debug() - selectFont.text = fontDialog.font.family - fontSize.value = fontDialog.font.pointSize - fontStyle.currentIndex = fontDialog.font.italic ? 1 : 0 - fontWeight.currentIndex = weight[fontDialog.font.weight] + ComboBoxSelector { + id: textStyle + model: general.textStyleModel + text: i18n("Style") + value: plasmoid.configuration.currentTextStyle + onValueEdited: cfg_currentTextStyle = newValue } - onSetFont: { - if (debug) console.debug() - fontDialog.font = Qt.font({ - family: selectFont.text, - pointSize: fontSize.value > 0 ? fontSize.value : 12, - italic: fontStyle.currentIndex == 1, - weight: Font.Normal, - }) + + ColorSelector { + id: selectStyleColor + text: i18n("Style color") + value: plasmoid.configuration.currentTextStyleColor } } diff --git a/sources/desktop-panel/package/contents/ui/advanced.qml b/sources/desktop-panel/package/contents/ui/advanced.qml index 256281f..84a5dd3 100644 --- a/sources/desktop-panel/package/contents/ui/advanced.qml +++ b/sources/desktop-panel/package/contents/ui/advanced.qml @@ -17,8 +17,6 @@ import QtQuick 2.0 import QtQuick.Controls 1.3 as QtControls -import QtQuick.Controls.Styles 1.3 as QtStyles -import QtQuick.Dialogs 1.1 as QtDialogs import org.kde.plasma.private.desktoppanel 1.0 @@ -41,213 +39,154 @@ Item { property alias cfg_verticalLayout: verticalLayout.checked property alias cfg_height: widgetHeight.value property alias cfg_width: widgetWidth.value - property string cfg_mark: mark.currentText - property string cfg_tooltipType: tooltipType.currentText + property string cfg_mark: mark.value + property string cfg_tooltipType: tooltipType.value property alias cfg_tooltipWidth: tooltipWidth.value - property alias cfg_tooltipColor: tooltipColor.text + property alias cfg_tooltipColor: tooltipColor.value Column { id: pageColumn anchors.fill: parent - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.heigth - width: parent.width * 2 / 5 - } - QtControls.CheckBox { - id: background - width: parent.width * 3 / 5 - text: i18n("Enable background") - } + + CheckBoxSelector { + id: background + text: i18n("Enable background") } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.heigth - width: parent.width * 2 / 5 - } - QtControls.CheckBox { - id: verticalLayout - width: parent.width * 3 / 5 - text: i18n("Vertical layout") - } + CheckBoxSelector { + id: verticalLayout + text: i18n("Vertical layout") } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Widget height, px") - } - QtControls.SpinBox { - id: widgetHeight - width: parent.width * 3 / 5 - minimumValue: 0 - maximumValue: 4096 - stepSize: 50 - value: plasmoid.configuration.height - } + IntegerSelector { + id: widgetHeight + maximumValue: 4096 + minimumValue: 0 + stepSize: 50 + text: i18n("Widget height, px") + value: plasmoid.configuration.height } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Widget width, px") - } - QtControls.SpinBox { - id: widgetWidth - width: parent.width * 3 / 5 - minimumValue: 0 - maximumValue: 4096 - stepSize: 50 - value: plasmoid.configuration.width - } + IntegerSelector { + id: widgetWidth + maximumValue: 4096 + minimumValue: 0 + stepSize: 50 + text: i18n("Widget width, px") + value: plasmoid.configuration.width } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Mark") - } - QtControls.ComboBox { - id: mark - width: parent.width * 3 / 5 - editable: true - model: ["#", "$", "%", "&", "*", "@", "¤", "¶", "·", "º", - plasmoid.configuration.mark] - currentIndex: model.length - 1 - onCurrentIndexChanged: cfg_mark = currentText - } + ComboBoxSelector { + id: mark + editable: true + model: [ + { + 'label': '#', + 'name': '#' + }, + { + 'label': '$', + 'name': '$' + }, + { + 'label': '%', + 'name': '%' + }, + { + 'label': '&', + 'name': '&' + }, + { + 'label': '*', + 'name': '*' + }, + { + 'label': '@', + 'name': '@' + }, + { + 'label': '¤', + 'name': '¤' + }, + { + 'label': '¶', + 'name': '¶' + }, + { + 'label': '·', + 'name': '·' + }, + { + 'label': 'º', + 'name': 'º' + }, + { + 'label': plasmoid.configuration.mark, + 'name': plasmoid.configuration.mark + } + ] + text: i18n("Mark") + currentIndex: model.length - 1 + onValueEdited: cfg_mark = newValue } QtControls.GroupBox { height: implicitHeight width: parent.width title: i18n("Tooltip") + Column { height: implicitHeight width: parent.width - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Tooltip type") - } - QtControls.ComboBox { - id: tooltipType - width: parent.width * 3 / 5 - textRole: "label" - model: [ - { - 'label': i18n("contours"), - 'name': "contours" - }, - { - 'label': i18n("windows"), - 'name': "windows" - }, - { - 'label': i18n("clean desktop"), - 'name': "clean" - }, - { - 'label': i18n("names"), - 'name': "names" - }, - { - 'label': i18n("none"), - 'name': "none" - } - ] - onCurrentIndexChanged: cfg_tooltipType = model[currentIndex]["name"] - Component.onCompleted: { - if (debug) console.debug() - for (var i = 0; i < model.length; i++) { - if (model[i]["name"] == plasmoid.configuration.tooltipType) { - if (debug) console.info("Found", model[i]["name"], "on", i) - tooltipType.currentIndex = i - } - } + + ComboBoxSelector { + id: tooltipType + model: [ + { + 'label': i18n("contours"), + 'name': "contours" + }, + { + 'label': i18n("windows"), + 'name': "windows" + }, + { + 'label': i18n("clean desktop"), + 'name': "clean" + }, + { + 'label': i18n("names"), + 'name': "names" + }, + { + 'label': i18n("none"), + 'name': "none" } - } + ] + text: i18n("Tooltip type") + value: plasmoid.configuration.tooltipType + onValueEdited: cfg_tooltipType = newValue } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Tooltip width") - } - QtControls.SpinBox { - id: tooltipWidth - width: parent.width * 3 / 5 - minimumValue: 100 - maximumValue: 1000 - stepSize: 50 - value: plasmoid.configuration.tooltipWidth - } + IntegerSelector { + id: tooltipWidth + maximumValue: 1000 + minimumValue: 100 + stepSize: 50 + text: i18n("Tooltip width") + value: plasmoid.configuration.tooltipWidth } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width * 2 / 5 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font color") - } - QtControls.Button { - id: tooltipColor - width: parent.width * 3 / 5 - style: QtStyles.ButtonStyle { - background: Rectangle { - color: plasmoid.configuration.tooltipColor - } - } - text: plasmoid.configuration.tooltipColor - onClicked: colorDialog.visible = true - } + ColorSelector { + id: tooltipColor + text: i18n("Font color") + value: plasmoid.configuration.tooltipColor } } } } - QtDialogs.ColorDialog { - id: colorDialog - title: i18n("Select a color") - color: tooltipColor.text - onAccepted: tooltipColor.text = colorDialog.color - } - Component.onCompleted: { if (debug) console.debug() } diff --git a/sources/desktop-panel/package/contents/ui/inactiveapp.qml b/sources/desktop-panel/package/contents/ui/inactiveapp.qml index 391240a..7174d9a 100644 --- a/sources/desktop-panel/package/contents/ui/inactiveapp.qml +++ b/sources/desktop-panel/package/contents/ui/inactiveapp.qml @@ -16,11 +16,9 @@ ***************************************************************************/ import QtQuick 2.0 -import QtQuick.Controls 1.3 as QtControls -import QtQuick.Controls.Styles 1.3 as QtStyles -import QtQuick.Dialogs 1.1 as QtDialogs import org.kde.plasma.private.desktoppanel 1.0 +import "." Item { @@ -36,203 +34,69 @@ Item { implicitHeight: pageColumn.implicitHeight property bool debug: dpAdds.isDebugEnabled() - property variant weight: { - 25: 0, - 50: 1, - 63: 3, - 75: 4, - 87: 5 - } - property alias cfg_fontFamily: selectFont.text + property alias cfg_fontFamily: font.value property alias cfg_fontSize: fontSize.value - property string cfg_fontWeight: fontWeight.currentText - property string cfg_fontStyle: fontStyle.currentText - property alias cfg_fontColor: selectColor.text + property string cfg_fontWeight: fontWeight.value + property string cfg_fontStyle: fontStyle.value + property alias cfg_fontColor: selectColor.value + property alias cfg_textStyleColor: selectStyleColor.value + property string cfg_textStyle: textStyle.value Column { id: pageColumn anchors.fill: parent - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font") - } - QtControls.Button { - id: selectFont - width: parent.width * 2 / 3 - text: plasmoid.configuration.fontFamily - onClicked: { - if (debug) console.debug() - fontDialog.setFont() - fontDialog.visible = true - } - } + + FontSelector { + id: font + text: i18n("Font") + value: plasmoid.configuration.fontFamily } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font size") - } - QtControls.SpinBox { - id: fontSize - width: parent.width * 2 / 3 - minimumValue: 8 - maximumValue: 32 - stepSize: 1 - value: plasmoid.configuration.fontSize - } + IntegerSelector { + id: fontSize + maximumValue: 32 + minimumValue: 8 + stepSize: 1 + text: i18n("Font size") + value: plasmoid.configuration.fontSize } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font weight") - } - QtControls.ComboBox { - id: fontWeight - width: parent.width * 2 / 3 - textRole: "label" - model: [ - { - 'label': i18n("light"), - 'name': "light" - }, - { - 'label': i18n("normal"), - 'name': "normal" - }, - { - 'label': i18n("demi bold"), - 'name': "demibold" - }, - { - 'label': i18n("bold"), - 'name': "bold" - }, - { - 'label': i18n("black"), - 'name': "black" - } - ] - onCurrentIndexChanged: cfg_fontWeight = model[currentIndex]["name"] - Component.onCompleted: { - if (debug) console.debug() - for (var i = 0; i < model.length; i++) { - if (model[i]["name"] == plasmoid.configuration.fontWeight) { - if (debug) console.info("Found", model[i]["name"], "on", i) - fontWeight.currentIndex = i - } - } - } - } + ComboBoxSelector { + id: fontWeight + model: general.fontWeightModel + text: i18n("Font weight") + value: plasmoid.configuration.fontWeight + onValueEdited: cfg_fontWeight = newValue } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font style") - } - QtControls.ComboBox { - id: fontStyle - width: parent.width * 2 / 3 - textRole: "label" - model: [ - { - 'label': i18n("normal"), - 'name': "normal" - }, - { - 'label': i18n("italic"), - 'name': "italic" - } - ] - onCurrentIndexChanged: cfg_fontStyle = model[currentIndex]["name"] - Component.onCompleted: { - if (debug) console.debug() - for (var i = 0; i < model.length; i++) { - if (model[i]["name"] == plasmoid.configuration.fontStyle) { - if (debug) console.info("Found", model[i]["name"], "on", i) - fontStyle.currentIndex = i - } - } - } - } + ComboBoxSelector { + id: fontStyle + model: general.fontStyleModel + text: i18n("Font style") + value: plasmoid.configuration.fontStyle + onValueEdited: cfg_fontStyle = newValue } - Row { - height: implicitHeight - width: parent.width - QtControls.Label { - height: parent.height - width: parent.width / 3 - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - text: i18n("Font color") - } - QtControls.Button { - id: selectColor - width: parent.width * 2 / 3 - style: QtStyles.ButtonStyle { - background: Rectangle { - color: plasmoid.configuration.fontColor - } - } - text: plasmoid.configuration.fontColor - onClicked: colorDialog.visible = true - } + ColorSelector { + id: selectColor + text: i18n("Font color") + value: plasmoid.configuration.fontColor } - } - QtDialogs.ColorDialog { - id: colorDialog - title: i18n("Select a color") - color: selectColor.text - onAccepted: selectColor.text = colorDialog.color - } - - QtDialogs.FontDialog { - id: fontDialog - title: i18n("Select a font") - signal setFont - - onAccepted: { - if (debug) console.debug() - selectFont.text = fontDialog.font.family - fontSize.value = fontDialog.font.pointSize - fontStyle.currentIndex = fontDialog.font.italic ? 1 : 0 - fontWeight.currentIndex = weight[fontDialog.font.weight] + ComboBoxSelector { + id: textStyle + model: general.textStyleModel + text: i18n("Style") + value: plasmoid.configuration.textStyle + onValueEdited: cfg_textStyle = newValue } - onSetFont: { - if (debug) console.debug() - fontDialog.font = Qt.font({ - family: selectFont.text, - pointSize: fontSize.value > 0 ? fontSize.value : 12, - italic: fontStyle.currentIndex == 1, - weight: Font.Normal, - }) + + ColorSelector { + id: selectStyleColor + text: i18n("Style color") + value: plasmoid.configuration.textStyleColor } } diff --git a/sources/desktop-panel/package/contents/ui/main.qml b/sources/desktop-panel/package/contents/ui/main.qml index 40efb02..8847dfe 100644 --- a/sources/desktop-panel/package/contents/ui/main.qml +++ b/sources/desktop-panel/package/contents/ui/main.qml @@ -124,12 +124,16 @@ Item { repeater.itemAt(i).font.italic = plasmoid.configuration.currentFontStyle == "italic" ? true : false repeater.itemAt(i).font.pointSize = plasmoid.configuration.currentFontSize repeater.itemAt(i).font.weight = general.fontWeight[plasmoid.configuration.currentFontWeight] + repeater.itemAt(i).style = general.textStyle[plasmoid.configuration.currentTextStyle] + repeater.itemAt(i).styleColor = plasmoid.configuration.currentTextStyleColor } else { repeater.itemAt(i).color = plasmoid.configuration.fontColor repeater.itemAt(i).font.family = plasmoid.configuration.fontFamily repeater.itemAt(i).font.italic = plasmoid.configuration.fontStyle == "italic" ? true : false repeater.itemAt(i).font.pointSize = plasmoid.configuration.fontSize repeater.itemAt(i).font.weight = general.fontWeight[plasmoid.configuration.fontWeight] + repeater.itemAt(i).style = general.textStyle[plasmoid.configuration.textStyle] + repeater.itemAt(i).styleColor = plasmoid.configuration.textStyleColor } repeater.itemAt(i).update() } diff --git a/sources/desktop-panel/package/contents/ui/qmldir b/sources/desktop-panel/package/contents/ui/qmldir index c5315a3..e64b8f0 100644 --- a/sources/desktop-panel/package/contents/ui/qmldir +++ b/sources/desktop-panel/package/contents/ui/qmldir @@ -1 +1,27 @@ -singleton general 1.0 general.qml +# Do not edit qmldir directly it will be overrided during compilation, +# edit qml/qmldir.in file instead. + + +# common QML constants +singleton general 1.0 file:///usr/share/awesomewidgets/qml/general.qml + +# custom QML UI classes +AboutTab file:///usr/share/awesomewidgets/qml/AboutTab.qml +AWExtensions file:///usr/share/awesomewidgets/qml/AWExtensions.qml +AWInfoLabel file:///usr/share/awesomewidgets/qml/AWInfoLabel.qml +AWTagSelector file:///usr/share/awesomewidgets/qml/AWTagSelector.qml +AWTextEditor file:///usr/share/awesomewidgets/qml/AWTextEditor.qml +BugReport file:///usr/share/awesomewidgets/qml/BugReport.qml +ButtonSelector file:///usr/share/awesomewidgets/qml/ButtonSelector.qml +CheckBoxSelector file:///usr/share/awesomewidgets/qml/CheckBoxSelector.qml +ColorSelector file:///usr/share/awesomewidgets/qml/ColorSelector.qml +ComboBoxSelector file:///usr/share/awesomewidgets/qml/ComboBoxSelector.qml +ExportDialog file:///usr/share/awesomewidgets/qml/ExportDialog.qml +FontSelector file:///usr/share/awesomewidgets/qml/FontSelector.qml +HtmlDefaultFunctionsBar file:///usr/share/awesomewidgets/qml/HtmlDefaultFunctionsBar.qml +HtmlEditorButton file:///usr/share/awesomewidgets/qml/HtmlEditorButton.qml +HtmlEditorColor file:///usr/share/awesomewidgets/qml/HtmlEditorColor.qml +HtmlEditorFont file:///usr/share/awesomewidgets/qml/HtmlEditorFont.qml +ImportDialog file:///usr/share/awesomewidgets/qml/ImportDialog.qml +IntegerSelector file:///usr/share/awesomewidgets/qml/IntegerSelector.qml +LineSelector file:///usr/share/awesomewidgets/qml/LineSelector.qml diff --git a/sources/desktop-panel/package/contents/ui/widget.qml b/sources/desktop-panel/package/contents/ui/widget.qml index 5f235ce..66ab15b 100644 --- a/sources/desktop-panel/package/contents/ui/widget.qml +++ b/sources/desktop-panel/package/contents/ui/widget.qml @@ -16,10 +16,9 @@ ***************************************************************************/ import QtQuick 2.0 -import QtQuick.Controls 1.3 as QtControls -import QtQuick.Dialogs 1.2 as QtDialogs import org.kde.plasma.private.desktoppanel 1.0 +import "." Item { @@ -42,204 +41,23 @@ Item { Column { id: pageColumn anchors.fill: parent - QtControls.Label { - width: parent.width - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - wrapMode: Text.WordWrap - text: i18n("Detailed information may be found on project homepage") - onLinkActivated: Qt.openUrlExternally(link) + + AWInfoLabel {} + + HtmlDefaultFunctionsBar { + textArea: textPattern } - Row { - height: implicitHeight - width: parent.width - QtControls.Button { - width: parent.width * 3 / 15 - text: i18n("Bgcolor") - - onClicked: backgroundDialog.visible = true - - QtDialogs.ColorDialog { - id: backgroundDialog - title: i18n("Select a color") - onAccepted: { - var text = textPattern.text - textPattern.text = "" + - text + "" - } - } - } - QtControls.Button { - width: parent.width * 3 / 15 - text: i18n("Font") - iconName: "font" - - onClicked: { - if (debug) console.debug("Font button") - var defaultFont = { - "color": plasmoid.configuration.fontColor, - "family": plasmoid.configuration.fontFamily, - "size": plasmoid.configuration.fontSize - } - var font = dpAdds.getFont(defaultFont) - if (font.applied != 1) { - if (debug) console.debug("No font selected") - return - } - - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, - "" + - selected + "") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-indent-more" - - onClicked: { - if (debug) console.debug("Indent button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, selected + "
    \n") - } - } - - QtControls.Button { - width: parent.width / 15 - iconName: "format-text-bold" - - onClicked: { - if (debug) console.debug("Bold button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "" + selected + "") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-text-italic" - - onClicked: { - if (debug) console.debug("Italic button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "" + selected + "") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-text-underline" - - onClicked: { - if (debug) console.debug("Underline button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "" + selected + "") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-text-strikethrough" - - onClicked: { - if (debug) console.debug("Strike button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "" + selected + "") - } - } - - QtControls.Button { - width: parent.width / 15 - iconName: "format-justify-left" - - onClicked: { - if (debug) console.debug("Left button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "

    " + selected + "

    ") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-justify-center" - - onClicked: { - if (debug) console.debug("Center button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "

    " + selected + "

    ") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-justify-right" - - onClicked: { - if (debug) console.debug("Right button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "

    " + selected + "

    ") - } - } - QtControls.Button { - width: parent.width / 15 - iconName: "format-justify-fill" - - onClicked: { - if (debug) console.debug("Justify button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, "

    " + selected + "

    ") - } - } + AWTagSelector { + backend: dpAdds + notifyBackend: dpAdds + textArea: textPattern + groups: general.dpTagRegexp } - Row { - height: implicitHeight - width: parent.width - QtControls.ComboBox { - id: tags - width: parent.width - addTagButton.width - showValueButton.width - model: dpAdds.dictKeys() - } - QtControls.Button { - id: addTagButton - text: i18n("Add") - - onClicked: { - if (debug) console.debug("Add tag button") - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(textPattern.cursorPosition, selected + "$" + tags.currentText) - } - } - QtControls.Button { - id: showValueButton - text: i18n("Show value") - - onClicked: { - if (debug) console.debug("Show tag button") - var message = i18n("Tag: %1", tags.currentText) - message += "
    " - message += i18n("Value: %1", dpAdds.valueByKey(tags.currentText)) - dpAdds.sendNotification("tag", message) - } - } - } - - QtControls.TextArea { + AWTextEditor { id: textPattern - width: parent.width - height: parent.height * 4 / 5 - textFormat: TextEdit.PlainText - text: plasmoid.configuration.text + backend: dpAdds } } diff --git a/sources/desktop-panel/plugin/dpadds.cpp b/sources/desktop-panel/plugin/dpadds.cpp index ee25dae..d2a953a 100644 --- a/sources/desktop-panel/plugin/dpadds.cpp +++ b/sources/desktop-panel/plugin/dpadds.cpp @@ -39,9 +39,9 @@ DPAdds::DPAdds(QObject *parent) : QObject(parent) { - qSetMessagePattern(LOG_FORMAT); + qSetMessagePattern(AWDebug::LOG_FORMAT); qCDebug(LOG_DP) << __PRETTY_FUNCTION__; - for (auto metadata : getBuildData()) + for (auto &metadata : AWDebug::getBuildData()) qCDebug(LOG_DP) << metadata; connect(KWindowSystem::self(), SIGNAL(currentDesktopChanged(int)), this, @@ -72,15 +72,21 @@ int DPAdds::currentDesktop() const } -QStringList DPAdds::dictKeys() const +QStringList DPAdds::dictKeys(const bool sorted, const QString regexp) const { + qCDebug(LOG_DP) << "Should be sorted" << sorted << "and filter applied" + << regexp; + QStringList allKeys; allKeys.append(QString("mark")); allKeys.append(QString("name")); allKeys.append(QString("number")); allKeys.append(QString("total")); - return allKeys; + if (sorted) + allKeys.sort(); + + return allKeys.filter(QRegExp(regexp)); } @@ -220,6 +226,14 @@ void DPAdds::setToolTipData(const QVariantMap tooltipData) } +QString DPAdds::infoByKey(QString key) const +{ + qCDebug(LOG_AW) << "Requested info for key" << key; + + return QString("(none)"); +} + + QString DPAdds::valueByKey(const QString key, int desktop) const { qCDebug(LOG_DP) << "Requested key" << key << "for desktop" << desktop; @@ -248,67 +262,7 @@ QString DPAdds::getAboutText(const QString type) const { qCDebug(LOG_DP) << "Type" << type; - QString text; - if (type == QString("header")) { - text = QString(NAME); - } else if (type == QString("version")) { - text = i18n("Version %1 (build date %2)", QString(VERSION), - QString(BUILD_DATE)); - if (!QString(COMMIT_SHA).isEmpty()) - text += QString(" (%1)").arg(QString(COMMIT_SHA)); - } else if (type == QString("description")) { - text = i18n("A set of minimalistic plasmoid widgets"); - } else if (type == QString("links")) { - text = i18n("Links:") + QString("
    ") - + QString("%2
    ") - .arg(QString(HOMEPAGE)) - .arg(i18n("Homepage")) - + QString("%2
    ") - .arg(QString(REPOSITORY)) - .arg(i18n("Repository")) - + QString("%2
    ") - .arg(QString(BUGTRACKER)) - .arg(i18n("Bugtracker")) - + QString("%2
    ") - .arg(QString(TRANSLATION)) - .arg(i18n("Translation issue")) - + QString("%2
    ") - .arg(QString(AUR_PACKAGES)) - .arg(i18n("AUR packages")) - + QString("%2") - .arg(QString(OPENSUSE_PACKAGES)) - .arg(i18n("openSUSE packages")); - } else if (type == QString("copy")) { - text = QString("© %1 %3
    ") - .arg(QString(DATE)) - .arg(QString(EMAIL)) - .arg(QString(AUTHOR)) - + i18n("This software is licensed under %1", QString(LICENSE)) - + QString("
    "); - } else if (type == QString("translators")) { - text = i18n("Translators: %1", QString(TRANSLATORS)); - } else if (type == QString("3rdparty")) { - QStringList trdPartyList - = QString(TRDPARTY_LICENSE) - .split(QChar(';'), QString::SkipEmptyParts); - for (int i = 0; i < trdPartyList.count(); i++) - trdPartyList[i] - = QString("%1 (%2 license)") - .arg(trdPartyList.at(i).split(QChar(',')).at(0)) - .arg(trdPartyList.at(i).split(QChar(',')).at(1)) - .arg(trdPartyList.at(i).split(QChar(',')).at(2)); - text = i18n("This software uses: %1", trdPartyList.join(QString(", "))); - } else if (type == QString("thanks")) { - QStringList thanks = QString(SPECIAL_THANKS) - .split(QChar(';'), QString::SkipEmptyParts); - for (int i = 0; i < thanks.count(); i++) - thanks[i] = QString("%1") - .arg(thanks.at(i).split(QChar(','))[0]) - .arg(thanks.at(i).split(QChar(','))[1]); - text = i18n("Special thanks to %1", thanks.join(QString(", "))); - } - - return text; + return AWDebug::getAboutText(type); } @@ -364,9 +318,10 @@ DPAdds::DesktopWindowsInfo DPAdds::getInfoByDesktop(const int desktop) const for (auto id : KWindowSystem::windows()) { KWindowInfo winInfo = KWindowInfo( - id, NET::Property::WMDesktop | NET::Property::WMGeometry - | NET::Property::WMState | NET::Property::WMWindowType - | NET::Property::WMVisibleName); + id, + NET::Property::WMDesktop | NET::Property::WMGeometry + | NET::Property::WMState | NET::Property::WMWindowType + | NET::Property::WMVisibleName); if (!winInfo.isOnDesktop(desktop)) continue; WindowData data; diff --git a/sources/desktop-panel/plugin/dpadds.h b/sources/desktop-panel/plugin/dpadds.h index 3c85a6b..f645c02 100644 --- a/sources/desktop-panel/plugin/dpadds.h +++ b/sources/desktop-panel/plugin/dpadds.h @@ -45,7 +45,8 @@ public: virtual ~DPAdds(); Q_INVOKABLE bool isDebugEnabled() const; Q_INVOKABLE int currentDesktop() const; - Q_INVOKABLE QStringList dictKeys() const; + Q_INVOKABLE QStringList dictKeys(const bool sorted = true, + const QString regexp = QString()) const; Q_INVOKABLE int numberOfDesktops() const; Q_INVOKABLE QString toolTipImage(const int desktop) const; Q_INVOKABLE QString parsePattern(const QString pattern, @@ -53,6 +54,7 @@ public: // values Q_INVOKABLE void setMark(const QString newMark); Q_INVOKABLE void setToolTipData(const QVariantMap tooltipData); + Q_INVOKABLE QString infoByKey(QString key) const; Q_INVOKABLE QString valueByKey(const QString key, int desktop = -1) const; // configuration slots Q_INVOKABLE QString getAboutText(const QString type = "header") const; diff --git a/sources/extsysmon/extsysmon.cpp b/sources/extsysmon/extsysmon.cpp index 154289f..4b0b579 100644 --- a/sources/extsysmon/extsysmon.cpp +++ b/sources/extsysmon/extsysmon.cpp @@ -32,9 +32,9 @@ ExtendedSysMon::ExtendedSysMon(QObject *parent, const QVariantList &args) : Plasma::DataEngine(parent, args) { Q_UNUSED(args) - qSetMessagePattern(LOG_FORMAT); + qSetMessagePattern(AWDebug::LOG_FORMAT); qCDebug(LOG_ESM) << __PRETTY_FUNCTION__; - for (auto metadata : getBuildData()) + for (auto &metadata : AWDebug::getBuildData()) qCDebug(LOG_ESM) << metadata; setMinimumPollingInterval(333); diff --git a/sources/extsysmon/extsysmonaggregator.cpp b/sources/extsysmon/extsysmonaggregator.cpp index 050a748..3c7a130 100644 --- a/sources/extsysmon/extsysmonaggregator.cpp +++ b/sources/extsysmon/extsysmonaggregator.cpp @@ -29,6 +29,7 @@ #include "playersource.h" #include "processessource.h" #include "quotessource.h" +#include "requestsource.h" #include "upgradesource.h" #include "weathersource.h" @@ -112,8 +113,9 @@ void ExtSysMonAggregator::init(const QHash config) m_map[source] = gpuTempItem; // hdd temperature AbstractExtSysMonSource *hddTempItem = new HDDTemperatureSource( - this, QStringList() << config[QString("HDDDEV")] - << config[QString("HDDTEMPCMD")]); + this, + QStringList() << config[QString("HDDDEV")] + << config[QString("HDDTEMPCMD")]); for (auto source : hddTempItem->sources()) m_map[source] = hddTempItem; // network @@ -123,10 +125,11 @@ void ExtSysMonAggregator::init(const QHash config) m_map[source] = networkItem; // player AbstractExtSysMonSource *playerItem = new PlayerSource( - this, QStringList() - << config[QString("PLAYER")] << config[QString("MPDADDRESS")] - << config[QString("MPDPORT")] << config[QString("MPRIS")] - << config[QString("PLAYERSYMBOLS")]); + this, + QStringList() << config[QString("PLAYER")] + << config[QString("MPDADDRESS")] + << config[QString("MPDPORT")] << config[QString("MPRIS")] + << config[QString("PLAYERSYMBOLS")]); for (auto source : playerItem->sources()) m_map[source] = playerItem; // processes @@ -134,6 +137,11 @@ void ExtSysMonAggregator::init(const QHash config) = new ProcessesSource(this, QStringList()); for (auto source : processesItem->sources()) m_map[source] = processesItem; + // network request + AbstractExtSysMonSource *requestItem + = new RequestSource(this, QStringList()); + for (auto source : requestItem->sources()) + m_map[source] = requestItem; // quotes AbstractExtSysMonSource *quotesItem = new QuotesSource(this, QStringList()); for (auto source : quotesItem->sources()) diff --git a/sources/extsysmonsources/customsource.cpp b/sources/extsysmonsources/customsource.cpp index 2180b14..abfe4a0 100644 --- a/sources/extsysmonsources/customsource.cpp +++ b/sources/extsysmonsources/customsource.cpp @@ -30,6 +30,7 @@ CustomSource::CustomSource(QObject *parent, const QStringList args) m_extScripts = new ExtItemAggregator(nullptr, QString("scripts")); + m_extScripts->initSockets(); m_sources = getSources(); } diff --git a/sources/extsysmonsources/playersource.cpp b/sources/extsysmonsources/playersource.cpp index 9a7b85e..b5d4320 100644 --- a/sources/extsysmonsources/playersource.cpp +++ b/sources/extsysmonsources/playersource.cpp @@ -240,9 +240,9 @@ QString PlayerSource::buildString(const QString ¤t, const QString &value, int index = value.indexOf(current); if ((current.isEmpty()) || ((index + s + 1) > value.count())) - return QString("%1").arg(value.left(s), s, QLatin1Char(' ')); + return QString("%1").arg(value.left(s), -s, QLatin1Char(' ')); else - return QString("%1").arg(value.mid(index + 1, s), s, QLatin1Char(' ')); + return QString("%1").arg(value.mid(index + 1, s), -s, QLatin1Char(' ')); } @@ -255,6 +255,12 @@ QString PlayerSource::stripString(const QString &value, const int s) } +bool PlayerSource::isMpdSocketConnected() const +{ + return (m_mpdSocket.state() == QAbstractSocket::ConnectedState); +} + + void PlayerSource::mpdSocketConnected() { qCDebug(LOG_ESS) << "MPD socket connected to" << m_mpdSocket.peerName() @@ -323,8 +329,8 @@ QVariantHash PlayerSource::getPlayerMpdInfo() } else if (m_mpdSocket.state() == QAbstractSocket::ConnectedState) { // send request if (m_mpdSocket.write(MPD_STATUS_REQUEST) == -1) - qCWarning(LOG_ESS) << "Could not write request to" - << m_mpdSocket.peerName(); + qCWarning(LOG_ESS) + << "Could not write request to" << m_mpdSocket.peerName(); } return m_mpdCached; diff --git a/sources/extsysmonsources/playersource.h b/sources/extsysmonsources/playersource.h index 4474a37..b7b80a7 100644 --- a/sources/extsysmonsources/playersource.h +++ b/sources/extsysmonsources/playersource.h @@ -24,8 +24,6 @@ #include "abstractextsysmonsource.h" -#define MPD_STATUS_REQUEST "currentsong\nstatus\n" - class QProcess; @@ -34,6 +32,8 @@ class PlayerSource : public AbstractExtSysMonSource Q_OBJECT public: + const char *MPD_STATUS_REQUEST = "currentsong\nstatus\n"; + explicit PlayerSource(QObject *parent, const QStringList args); virtual ~PlayerSource(); QVariant data(QString source); @@ -45,6 +45,8 @@ public: static QString buildString(const QString ¤t, const QString &value, const int s); static QString stripString(const QString &value, const int s); + // additional test method + bool isMpdSocketConnected() const; private slots: void mpdSocketConnected(); @@ -64,9 +66,9 @@ private: QMutex m_dbusMutex; QString m_player; int m_symbols; - QStringList m_metadata = QStringList() << QString("album") - << QString("artist") - << QString("title"); + QStringList m_metadata = QStringList() + << QString("album") << QString("artist") + << QString("title"); QVariantHash m_values; }; diff --git a/sources/extsysmonsources/quotessource.cpp b/sources/extsysmonsources/quotessource.cpp index 2bc8950..1e57c89 100644 --- a/sources/extsysmonsources/quotessource.cpp +++ b/sources/extsysmonsources/quotessource.cpp @@ -29,6 +29,7 @@ QuotesSource::QuotesSource(QObject *parent, const QStringList args) qCDebug(LOG_ESS) << __PRETTY_FUNCTION__; m_extQuotes = new ExtItemAggregator(nullptr, QString("quotes")); + m_extQuotes->initSockets(); m_sources = getSources(); } diff --git a/sources/extsysmonsources/requestsource.cpp b/sources/extsysmonsources/requestsource.cpp new file mode 100644 index 0000000..976b9c8 --- /dev/null +++ b/sources/extsysmonsources/requestsource.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#include "requestsource.h" + +#include "awdebug.h" +#include "extnetworkrequest.h" + + +RequestSource::RequestSource(QObject *parent, const QStringList args) + : AbstractExtSysMonSource(parent, args) +{ + Q_ASSERT(args.count() == 0); + qCDebug(LOG_ESS) << __PRETTY_FUNCTION__; + + m_extNetRequest = new ExtItemAggregator( + nullptr, QString("requests")); + m_extNetRequest->initSockets(); + m_sources = getSources(); +} + + +RequestSource::~RequestSource() +{ + qCDebug(LOG_ESS) << __PRETTY_FUNCTION__; + + delete m_extNetRequest; +} + + +QVariant RequestSource::data(QString source) +{ + qCDebug(LOG_ESS) << "Source" << source; + + int ind = index(source); + source.remove(QString("network/")); + if (!m_values.contains(source)) { + QVariantHash data = m_extNetRequest->itemByTagNumber(ind)->run(); + for (auto key : data.keys()) + m_values[key] = data[key]; + } + QVariant value = m_values.take(source); + return value; +} + + +QVariantMap RequestSource::initialData(QString source) const +{ + qCDebug(LOG_ESS) << "Source" << source; + + int ind = index(source); + QVariantMap data; + if (source.startsWith(QString("network/response"))) { + data[QString("min")] = QString(""); + data[QString("max")] = QString(""); + data[QString("name")] + = QString("Network response for %1") + .arg(m_extNetRequest->itemByTagNumber(ind)->uniq()); + data[QString("type")] = QString("QString"); + data[QString("units")] = QString(""); + } + + return data; +} + + +QStringList RequestSource::sources() const +{ + return m_sources; +} + + +QStringList RequestSource::getSources() +{ + QStringList sources; + for (auto item : m_extNetRequest->activeItems()) + sources.append( + QString("network/%1").arg(item->tag(QString("response")))); + + return sources; +} diff --git a/sources/extsysmonsources/requestsource.h b/sources/extsysmonsources/requestsource.h new file mode 100644 index 0000000..02cb47c --- /dev/null +++ b/sources/extsysmonsources/requestsource.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#ifndef REQUESTSOURCE_H +#define REQUESTSOURCE_H + +#include + +#include "abstractextsysmonsource.h" +#include "extitemaggregator.h" + + +class ExtNetworkRequest; + +class RequestSource : public AbstractExtSysMonSource +{ + Q_OBJECT + +public: + explicit RequestSource(QObject *parent, const QStringList args); + virtual ~RequestSource(); + QVariant data(QString source); + QVariantMap initialData(QString source) const; + void run(){}; + QStringList sources() const; + +private: + QStringList getSources(); + // configuration and values + ExtItemAggregator *m_extNetRequest = nullptr; + QStringList m_sources; + QVariantHash m_values; +}; + + +#endif /* REQUESTSOURCE_H */ diff --git a/sources/extsysmonsources/upgradesource.cpp b/sources/extsysmonsources/upgradesource.cpp index 5d7a3e2..a402ff6 100644 --- a/sources/extsysmonsources/upgradesource.cpp +++ b/sources/extsysmonsources/upgradesource.cpp @@ -30,6 +30,7 @@ UpgradeSource::UpgradeSource(QObject *parent, const QStringList args) m_extUpgrade = new ExtItemAggregator(nullptr, QString("upgrade")); + m_extUpgrade->initSockets(); m_sources = getSources(); } diff --git a/sources/extsysmonsources/weathersource.cpp b/sources/extsysmonsources/weathersource.cpp index 9806c2b..1abe824 100644 --- a/sources/extsysmonsources/weathersource.cpp +++ b/sources/extsysmonsources/weathersource.cpp @@ -30,6 +30,7 @@ WeatherSource::WeatherSource(QObject *parent, const QStringList args) m_extWeather = new ExtItemAggregator(nullptr, QString("weather")); + m_extWeather->initSockets(); m_sources = getSources(); } diff --git a/sources/qml/AWExtensions.qml b/sources/qml/AWExtensions.qml new file mode 100644 index 0000000..c2bba77 --- /dev/null +++ b/sources/qml/AWExtensions.qml @@ -0,0 +1,92 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.3 as QtControls +import QtQuick.Dialogs 1.2 as QtDialogs + +import org.kde.plasma.private.awesomewidget 1.0 + + +Row { + height: implicitHeight + width: parent.width + + // backend + property var backend + AWFormatterConfigFactory { + id: awFormatter + } + AWTelemetryHandler { + id: awTelemetryHandler + } + // parent object in which text will be replaced + property var textArea + + signal unlock + signal showMessage(string message) + + QtControls.Button { + width: parent.width * 3 / 10 + text: i18n("Edit bars") + onClicked: backend.editItem("graphicalitem") + } + + QtControls.Button { + width: parent.width * 3 / 10 + text: i18n("Formatters") + onClicked: awFormatter.showDialog(backend.dictKeys(true)) + } + + QtControls.Button { + width: parent.width * 5 / 15 + text: i18n("Preview") + onClicked: { + unlock() + backend.initKeys(textArea.text, plasmoid.configuration.interval, + plasmoid.configuration.queueLimit, false) + } + } + + QtControls.Button { + width: parent.width / 15 + iconName: "view-history" + menu: QtControls.Menu { + id: historyConfig + Instantiator { + model: awTelemetryHandler.get("awwidgetconfig") + QtControls.MenuItem { + text: modelData + onTriggered: textArea.text = modelData + } + onObjectAdded: historyConfig.insertItem(index, object) + onObjectRemoved: historyConfig.removeItem(object) + } + } + } + + QtDialogs.MessageDialog { + id: compiledText + modality: Qt.NonModal + title: i18n("Preview") + } + + onShowMessage: { + compiledText.text = message.replace(" ", " ") + compiledText.open() + } +} diff --git a/sources/desktop-panel/package/contents/ui/general.qml b/sources/qml/AWInfoLabel.qml similarity index 74% rename from sources/desktop-panel/package/contents/ui/general.qml rename to sources/qml/AWInfoLabel.qml index dc26a78..7e8d16e 100644 --- a/sources/desktop-panel/package/contents/ui/general.qml +++ b/sources/qml/AWInfoLabel.qml @@ -15,22 +15,15 @@ * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * ***************************************************************************/ -pragma Singleton -import QtQuick 2.0 +import QtQuick 2.2 +import QtQuick.Controls 1.3 as QtControls -QtObject { - property variant fontWeight: { - "light": Font.Light, - "normal": Font.Normal, - "demibold": Font.DemiBold, - "bold": Font.Bold, - "black": Font.Black - } - property variant align: { - "left": Text.AlignLeft, - "center": Text.AlignHCenter, - "right": Text.AlignRight, - "justify": Text.AlignJustify - } +QtControls.Label { + width: parent.width + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + text: i18n("Detailed information may be found on project homepage") + onLinkActivated: Qt.openUrlExternally(link) } diff --git a/sources/qml/AWTagSelector.qml b/sources/qml/AWTagSelector.qml new file mode 100644 index 0000000..1d30894 --- /dev/null +++ b/sources/qml/AWTagSelector.qml @@ -0,0 +1,77 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.3 as QtControls + + +Row { + height: implicitHeight + width: parent.width + + // backend + property var backend + property var notifyBackend + // parent object in which text will be replaced + property var textArea + property alias groups: tagGroups.model + + QtControls.ComboBox { + id: tagGroups + width: parent.width * 2 / 5 + textRole: "label" + + onCurrentIndexChanged: { + tags.model = backend.dictKeys(true, model[currentIndex]["regexp"]) + tags.currentIndex = -1 + } + } + + QtControls.ComboBox { + id: tags + width: parent.width * 1 / 5 + } + + QtControls.Button { + width: parent.width * 1 / 5 + text: i18n("Add") + + onClicked: { + if (!tags.currentText) + return + textArea.insert(textArea.cursorPosition, "$" + tags.currentText) + } + } + + QtControls.Button { + width: parent.width * 1 / 5 + text: i18n("Show value") + + onClicked: { + if ((!notifyBackend) + || (!tags.currentText)) + return + // generate message + var message = i18n("Tag: %1", tags.currentText) + message += "
    " + message += i18n("Value: %1", backend.valueByKey(tags.currentText)) + message += "
    " + message += i18n("Info: %1", backend.infoByKey(tags.currentText)) + notifyBackend.sendNotification("tag", message) + } + } +} diff --git a/sources/qml/AWTextEditor.qml b/sources/qml/AWTextEditor.qml new file mode 100644 index 0000000..b084b53 --- /dev/null +++ b/sources/qml/AWTextEditor.qml @@ -0,0 +1,94 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls 2.0 as QtControls + + +Item { + width: parent.width + height: parent.height * 4 / 5 + + property var backend + property alias text: textArea.text + + QtControls.TextArea { + id: textArea + anchors.fill: parent + background: Rectangle { + color: "white" + } + textFormat: TextEdit.PlainText + + Column { + id: tooltip + + property string substring + + Repeater { + id: tags + Text { + id: text + text: modelData + MouseArea { + anchors.fill: parent + onClicked: appendTag(text.text, tooltip.substring) + } + } + } + } + + onTextChanged: { + var currentTag = getLastTag() + // exit if there are spaces or empty + if ((currentTag.indexOf(" ") != -1) || (currentTag.length == 0)) { + tooltip.visible = false + return + } + // update tooltip and show it + tooltip.substring = currentTag + tags.model = backend.dictKeys(true, "^" + tooltip.substring) + changeTooltipPosition() + // show tooltip if found more than 1 or current text does not match + // tag found + tooltip.visible = ((tags.count > 1) + || ((tags.count == 1) && (tags.model[0] != tooltip.substring))) + } + } + + function appendTag(tag, substring) { + textArea.insert(textArea.cursorPosition, tag.substring(substring.length)) + } + + function changeTooltipPosition() { + tooltip.x = textArea.cursorRectangle.x + tooltip.y = textArea.cursorRectangle.y + } + + function getLastTag() { + // get substring to analyze + var substring = textArea.getText(0, textArea.cursorPosition) + // find last position of index in the given substring + var signIndex = substring.lastIndexOf('$') + 1 + if ((signIndex == 0) || (signIndex == textArea.cursorPosition)) + return "" + // get current tag text + return substring.substr(signIndex) + } +} + + diff --git a/sources/qml/AboutTab.qml b/sources/qml/AboutTab.qml new file mode 100644 index 0000000..0f6eae0 --- /dev/null +++ b/sources/qml/AboutTab.qml @@ -0,0 +1,109 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls 1.3 as QtControls +import QtQuick.Layouts 1.0 as QtLayouts + + +Column { + anchors.fill: parent + + property var textProvider + + QtControls.TabView { + height: parent.height + width: parent.width + + QtControls.Tab { + anchors.margins: 10.0 + title: i18n("About") + + QtLayouts.ColumnLayout { + QtControls.Label { + QtLayouts.Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + text: textProvider.getAboutText("header") + } + + QtControls.Label { + QtLayouts.Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + text: textProvider.getAboutText("version") + } + + QtControls.Label { + QtLayouts.Layout.fillWidth: true + horizontalAlignment: Text.AlignJustify + text: textProvider.getAboutText("description") + } + + QtControls.Label { + QtLayouts.Layout.fillWidth: true + horizontalAlignment: Text.AlignLeft + textFormat: Text.RichText + text: textProvider.getAboutText("links") + onLinkActivated: Qt.openUrlExternally(link) + } + + QtControls.Label { + QtLayouts.Layout.fillHeight: true + QtLayouts.Layout.fillWidth: true + font.capitalization: Font.SmallCaps + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignBottom + textFormat: Text.RichText + text: textProvider.getAboutText("copy") + } + } + } + + QtControls.Tab { + anchors.margins: 10.0 + title: i18n("Acknowledgment") + + QtLayouts.ColumnLayout { + QtControls.Label { + QtLayouts.Layout.fillWidth: true + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignJustify + text: textProvider.getAboutText("translators") + } + + QtControls.Label { + QtLayouts.Layout.fillWidth: true + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignJustify + textFormat: Text.RichText + text: textProvider.getAboutText("3rdparty") + onLinkActivated: Qt.openUrlExternally(link) + } + + QtControls.Label { + QtLayouts.Layout.fillHeight: true + QtLayouts.Layout.fillWidth: true + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignJustify + verticalAlignment: Text.AlignTop + textFormat: Text.RichText + text: textProvider.getAboutText("thanks") + onLinkActivated: Qt.openUrlExternally(link) + } + } + } + } +} diff --git a/sources/awesome-widget/package/contents/ui/BugReport.qml b/sources/qml/BugReport.qml similarity index 99% rename from sources/awesome-widget/package/contents/ui/BugReport.qml rename to sources/qml/BugReport.qml index 10f27b6..44080a7 100644 --- a/sources/awesome-widget/package/contents/ui/BugReport.qml +++ b/sources/qml/BugReport.qml @@ -49,7 +49,7 @@ QtDialogs.Dialog { width: parent.width anchors.top: title.bottom anchors.bottom: parent.bottom - + QtControls.GroupBox { width: parent.width height: parent.height / 5 @@ -122,7 +122,7 @@ QtDialogs.Dialog { QtDialogs.FileDialog { id: logPath title: i18n("Open log file") - onAccepted: + onAccepted: logBody.text = awActions.getFileContent(logPath.fileUrl.toString().replace("file://", "")) } } diff --git a/sources/qml/ButtonSelector.qml b/sources/qml/ButtonSelector.qml new file mode 100644 index 0000000..854bda5 --- /dev/null +++ b/sources/qml/ButtonSelector.qml @@ -0,0 +1,44 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls 1.3 as QtControls + + +Row { + height: implicitHeight + width: parent.width + + property alias text: label.text + property alias value: button.text + property alias style: button.style + + signal buttonActivated + + QtControls.Label { + id: label + height: parent.height + width: parent.width * 2 / 5 + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + } + QtControls.Button { + id: button + width: parent.width * 3 / 5 + onClicked: buttonActivated() + } +} diff --git a/sources/qml/CMakeLists.txt b/sources/qml/CMakeLists.txt new file mode 100644 index 0000000..1834fef --- /dev/null +++ b/sources/qml/CMakeLists.txt @@ -0,0 +1,12 @@ +set(SUBPROJECT awesomewidgets-qml) +message(STATUS "Subproject ${SUBPROJECT}") + +file(GLOB SUBPROJECT_SOURCE *.qml) +file(GLOB SUBPROJECT_QMLDIR_IN qmldir.in) + +# prepare +configure_file(${SUBPROJECT_QMLDIR_IN} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/package/contents/ui/qmldir) +configure_file(${SUBPROJECT_QMLDIR_IN} ${CMAKE_CURRENT_SOURCE_DIR}/../desktop-panel/package/contents/ui/qmldir) + +# install +install(FILES ${SUBPROJECT_SOURCE} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/qml) diff --git a/sources/awesome-widget/package/contents/ui/general.qml b/sources/qml/CheckBoxSelector.qml similarity index 76% rename from sources/awesome-widget/package/contents/ui/general.qml rename to sources/qml/CheckBoxSelector.qml index dc26a78..e9b265c 100644 --- a/sources/awesome-widget/package/contents/ui/general.qml +++ b/sources/qml/CheckBoxSelector.qml @@ -15,22 +15,23 @@ * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * ***************************************************************************/ -pragma Singleton import QtQuick 2.0 +import QtQuick.Controls 1.3 as QtControls -QtObject { - property variant fontWeight: { - "light": Font.Light, - "normal": Font.Normal, - "demibold": Font.DemiBold, - "bold": Font.Bold, - "black": Font.Black +Row { + height: implicitHeight + width: parent.width + + property alias text: checkBox.text + property alias checked: checkBox.checked + + QtControls.Label { + height: parent.heigth + width: parent.width * 2 / 5 } - property variant align: { - "left": Text.AlignLeft, - "center": Text.AlignHCenter, - "right": Text.AlignRight, - "justify": Text.AlignJustify + QtControls.CheckBox { + id: checkBox + width: parent.width * 3 / 5 } } diff --git a/sources/qml/ColorSelector.qml b/sources/qml/ColorSelector.qml new file mode 100644 index 0000000..1ecaac0 --- /dev/null +++ b/sources/qml/ColorSelector.qml @@ -0,0 +1,46 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls.Styles 1.3 as QtStyles +import QtQuick.Dialogs 1.1 as QtDialogs + + +Row { + height: implicitHeight + width: parent.width + + property alias text: selector.text + property alias value: selector.value + + ButtonSelector { + id: selector + style: QtStyles.ButtonStyle { + background: Rectangle { + color: value + } + } + onButtonActivated: colorDialog.visible = true + } + + QtDialogs.ColorDialog { + id: colorDialog + title: i18n("Select a color") + color: value + onAccepted: value = colorDialog.color + } +} diff --git a/sources/qml/ComboBoxSelector.qml b/sources/qml/ComboBoxSelector.qml new file mode 100644 index 0000000..19929d4 --- /dev/null +++ b/sources/qml/ComboBoxSelector.qml @@ -0,0 +1,55 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls 1.3 as QtControls + + +Row { + height: implicitHeight + width: parent.width + + property alias currentIndex: comboBox.currentIndex + property alias editable: comboBox.editable + property alias editText: comboBox.editText + property alias model: comboBox.model + property alias text: label.text + property string value + + signal valueEdited(string newValue) + + QtControls.Label { + id: label + height: parent.height + width: parent.width * 2 / 5 + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + } + QtControls.ComboBox { + id: comboBox + width: parent.width * 3 / 5 + textRole: 'label' + onCurrentIndexChanged: valueEdited(comboBox.model[comboBox.currentIndex]['name']) + Component.onCompleted: { + var total = comboBox.model.length + for (var i = 0; i < total; i++) { + if (comboBox.model[i]["name"] == value) + comboBox.currentIndex = i + } + } + } +} diff --git a/sources/qml/ExportDialog.qml b/sources/qml/ExportDialog.qml new file mode 100644 index 0000000..db136d5 --- /dev/null +++ b/sources/qml/ExportDialog.qml @@ -0,0 +1,59 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Dialogs 1.2 as QtDialogs + +import org.kde.plasma.private.awesomewidget 1.0 + + +Item { + property var configuration + + AWConfigHelper { + id: awConfig + } + + QtDialogs.MessageDialog { + id: messageDialog + standardButtons: QtDialogs.StandardButton.Ok + } + + QtDialogs.FileDialog { + id: fileDialog + selectExisting: false + title: i18n("Export") + folder: awConfig.configurationDirectory() + onAccepted: { + var status = awConfig.exportConfiguration( + configuration, + fileDialog.fileUrl.toString().replace("file://", "")) + if (status) { + messageDialog.title = i18n("Success") + messageDialog.text = i18n("Please note that binary files were not copied") + } else { + messageDialog.title = i18n("Ooops...") + messageDialog.text = i18n("Could not save configuration file") + } + messageDialog.open() + } + } + + function open() { + return fileDialog.open() + } +} diff --git a/sources/qml/FontSelector.qml b/sources/qml/FontSelector.qml new file mode 100644 index 0000000..aed4731 --- /dev/null +++ b/sources/qml/FontSelector.qml @@ -0,0 +1,54 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Dialogs 1.1 as QtDialogs + + +Row { + height: implicitHeight + width: parent.width + + property alias text: selector.text + property alias value: selector.value + + ButtonSelector { + id: selector + text: label.text + onButtonActivated: { + fontDialog.setFont() + fontDialog.visible = true + } + } + + QtDialogs.FontDialog { + id: fontDialog + title: i18n("Select a font") + + signal setFont + + onAccepted: value = fontDialog.font.family + onSetFont: { + fontDialog.font = Qt.font({ + family: value, + pointSize: 12, + italic: false, + weight: Font.Normal, + }) + } + } +} diff --git a/sources/qml/HtmlDefaultFunctionsBar.qml b/sources/qml/HtmlDefaultFunctionsBar.qml new file mode 100644 index 0000000..97cee45 --- /dev/null +++ b/sources/qml/HtmlDefaultFunctionsBar.qml @@ -0,0 +1,107 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.2 + + +Row { + height: implicitHeight + width: parent.width + + property var textArea + + // selectors + HtmlEditorColor { + width: parent.width * 3 / 15 + text: i18n("Bgcolor") + textField: textArea + } + HtmlEditorFont { + width: parent.width * 3 / 15 + textField: textArea + defaultFontColor: plasmoid.configuration.fontColor + defaultFontFamily: plasmoid.configuration.fontFamily + defaultFontSize: plasmoid.configuration.fontSize + } + + // new line + HtmlEditorButton { + width: parent.width / 15 + iconName: "format-indent-more" + textField: textArea + end: "
    \n" + } + // font properties + HtmlEditorButton { + width: parent.width / 15 + iconName: "format-text-bold" + textField: textArea + start: "" + end: "" + } + HtmlEditorButton { + width: parent.width / 15 + iconName: "format-text-italic" + textField: textArea + start: "" + end: "" + } + HtmlEditorButton { + width: parent.width / 15 + iconName: "format-text-underline" + textField: textArea + start: "" + end: "" + } + HtmlEditorButton { + width: parent.width / 15 + iconName: "format-text-strikethrough" + textField: textArea + start: "" + end: "" + } + + // indentation + HtmlEditorButton { + width: parent.width / 15 + iconName: "format-justify-left" + textField: textArea + start: "

    " + end: "

    " + } + HtmlEditorButton { + width: parent.width / 15 + iconName: "format-justify-center" + textField: textArea + start: "

    " + end: "

    " + } + HtmlEditorButton { + width: parent.width / 15 + iconName: "format-justify-right" + textField: textArea + start: "

    " + end: "

    " + } + HtmlEditorButton { + width: parent.width / 15 + iconName: "format-justify-fill" + textField: textArea + start: "

    " + end: "

    " + } +} diff --git a/sources/qml/HtmlEditorButton.qml b/sources/qml/HtmlEditorButton.qml new file mode 100644 index 0000000..588d73d --- /dev/null +++ b/sources/qml/HtmlEditorButton.qml @@ -0,0 +1,40 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.3 as QtControls + + +QtControls.Button { + // parent object in which text will be replaced + property var textField + // start and end tags + property string start: "" + property string end: "" + + property var clickedEvent: function() { return updateText() } + onClicked: clickedEvent() + + function updateText() { + // get selected text + var selected = textField.selectedText + // remove it from widget + textField.remove(textField.selectionStart, textField.selectionEnd) + // insert edited text + textField.insert(textField.cursorPosition, start + selected + end) + } +} diff --git a/sources/qml/HtmlEditorColor.qml b/sources/qml/HtmlEditorColor.qml new file mode 100644 index 0000000..45365dc --- /dev/null +++ b/sources/qml/HtmlEditorColor.qml @@ -0,0 +1,38 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 as QtDialogs + + +HtmlEditorButton { + end: "" + + clickedEvent: function() { return colorDialog.open() } + + QtDialogs.ColorDialog { + id: colorDialog + title: i18n("Select a color") + + onAccepted: { + start = "" + textField.selectAll() + updateText() + } + } +} diff --git a/sources/qml/HtmlEditorFont.qml b/sources/qml/HtmlEditorFont.qml new file mode 100644 index 0000000..590a172 --- /dev/null +++ b/sources/qml/HtmlEditorFont.qml @@ -0,0 +1,57 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.2 + +import org.kde.plasma.private.awesomewidget 1.0 + + +HtmlEditorButton { + end: "" + iconName: "font" + text: i18n("Font") + + // backend + AWActions { + id: awActions + } + // default font properties + property string defaultFontColor + property string defaultFontFamily + property int defaultFontSize + + clickedEvent: function() { + // get new font + var defaultFont = { + "color": defaultFontColor, + "family": defaultFontFamily, + "size": defaultFontSize + } + // we are using custom selector as soon as we need to select color as well + var font = awActions.getFont(defaultFont) + + // check status + if (!font.applied) + return + + // apply font + start = "" + updateText() + } +} diff --git a/sources/qml/ImportDialog.qml b/sources/qml/ImportDialog.qml new file mode 100644 index 0000000..0ebdaad --- /dev/null +++ b/sources/qml/ImportDialog.qml @@ -0,0 +1,71 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls 1.3 as QtControls +import QtQuick.Dialogs 1.2 as QtDialogs + +import org.kde.plasma.private.awesomewidget 1.0 + + +Item { + AWConfigHelper { + id: awConfig + } + + signal configurationReceived(var configuration) + + QtDialogs.FileDialog { + id: fileDialog + title: i18n("Import") + folder: awConfig.configurationDirectory() + onAccepted: importSelection.open() + } + + QtDialogs.Dialog { + id: importSelection + + Column { + QtControls.CheckBox { + id: importPlasmoid + text: i18n("Import plasmoid settings") + } + + QtControls.CheckBox { + id: importExtensions + text: i18n("Import extensions") + } + + QtControls.CheckBox { + id: importAdds + text: i18n("Import additional files") + } + } + + onAccepted: { + var importConfig = awConfig.importConfiguration( + fileDialog.fileUrl.toString().replace("file://", ""), + importPlasmoid.checked, importExtensions.checked, + importAdds.checked) + configurationReceived(importConfig) + } + } + + function open() { + return fileDialog.open() + } +} diff --git a/sources/qml/IntegerSelector.qml b/sources/qml/IntegerSelector.qml new file mode 100644 index 0000000..dea9443 --- /dev/null +++ b/sources/qml/IntegerSelector.qml @@ -0,0 +1,47 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls 1.3 as QtControls + + +Row { + height: implicitHeight + width: parent.width + + property alias text: label.text + property alias value: spinBox.value + + property alias maximumValue: spinBox.maximumValue + property alias minimumValue: spinBox.minimumValue + property alias stepSize: spinBox.stepSize + + signal valueEdited(int newValue) + + QtControls.Label { + id: label + height: parent.height + width: parent.width * 2 / 5 + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + } + QtControls.SpinBox { + id: spinBox + width: parent.width * 3 / 5 + onEditingFinished: valueEdited(spinBox.value) + } +} diff --git a/sources/qml/LineSelector.qml b/sources/qml/LineSelector.qml new file mode 100644 index 0000000..ab21728 --- /dev/null +++ b/sources/qml/LineSelector.qml @@ -0,0 +1,43 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls 1.3 as QtControls + + +Row { + height: implicitHeight + width: parent.width + + property alias text: label.text + property alias value: textField.text + + signal valueEdited(string newValue) + + QtControls.Label { + id: label + height: parent.height + width: parent.width * 2 / 5 + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + } + QtControls.TextField { + id: textField + width: parent.width * 3 / 5 + onEditingFinished: valueEdited(textField.text) + } +} diff --git a/sources/qml/general.qml b/sources/qml/general.qml new file mode 100644 index 0000000..6a38431 --- /dev/null +++ b/sources/qml/general.qml @@ -0,0 +1,158 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +pragma Singleton +import QtQuick 2.0 + + +QtObject { + property variant fontWeight: { + "light": Font.Light, + "normal": Font.Normal, + "demibold": Font.DemiBold, + "bold": Font.Bold, + "black": Font.Black + } + property variant align: { + "left": Text.AlignLeft, + "center": Text.AlignHCenter, + "right": Text.AlignRight, + "justify": Text.AlignJustify + } + property variant textStyle: { + "normal": Text.Normal, + "outline": Text.Outline, + "raised": Text.Raised, + "sunken": Text.Sunken + } + + // models + property variant awTagRegexp: [ + { + "label": i18n("AC"), + "regexp": "^(ac|bat).*" + }, + { + "label": i18n("Bars"), + "regexp": "^bar.*" + }, + { + "label": i18n("CPU"), + "regexp": "^(cpu|gpu|la|ps|temp(?!erature)).*" + }, + { + "label": i18n("Desktops"), + "regexp": "^(n|t)?desktop(s)?" + }, + { + "label": i18n("HDD"), + "regexp": "^hdd.*" + }, + { + "label": i18n("Memory"), + "regexp": "^(mem|swap).*" + }, + { + "label": i18n("Network"), + "regexp": "^(netdev|(down|up(?!time)).*)" + }, + { + "label": i18n("Music player"), + "regexp": "(^|d|s)(album|artist|duration|progress|title)" + }, + { + "label": i18n("Scripts"), + "regexp": "^custom.*" + }, + { + "label": i18n("Time"), + "regexp": ".*time$" + }, + { + "label": i18n("Quotes"), + "regexp": "^(perc)?(ask|bid|price)(chg)?.*" + }, + { + "label": i18n("Upgrades"), + "regexp": "^pkgcount.*" + }, + { + "label": i18n("Weathers"), + "regexp": "^(weather(Id)?|humidity|pressure|temperature|timestamp)" + }, + { + "label": i18n("Functions"), + "regexp": "functions" + } + ] + property variant dpTagRegexp: [ + { + "label": i18n("All"), + "regexp": ".*" + } + ] + property variant fontStyleModel: [ + { + "label": i18n("normal"), + "name": "normal" + }, + { + "label": i18n("italic"), + "name": "italic" + } + ] + property variant fontWeightModel: [ + { + "label": i18n("light"), + "name": "light" + }, + { + "label": i18n("normal"), + "name": "normal" + }, + { + "label": i18n("demi bold"), + "name": "demibold" + }, + { + "label": i18n("bold"), + "name": "bold" + }, + { + "label": i18n("black"), + "name": "black" + } + ] + property variant textStyleModel: [ + { + "label": i18n("normal"), + "name": "normal" + }, + { + "label": i18n("outline"), + "name": "outline" + }, + { + "label": i18n("raised"), + "name": "raised" + }, + { + "label": i18n("sunken"), + "name": "sunken" + } + ] +} diff --git a/sources/qml/qmldir.in b/sources/qml/qmldir.in new file mode 100644 index 0000000..ab26eb6 --- /dev/null +++ b/sources/qml/qmldir.in @@ -0,0 +1,27 @@ +# Do not edit qmldir directly it will be overrided during compilation, +# edit qml/qmldir.in file instead. + + +# common QML constants +singleton general 1.0 file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/general.qml + +# custom QML UI classes +AboutTab file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/AboutTab.qml +AWExtensions file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/AWExtensions.qml +AWInfoLabel file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/AWInfoLabel.qml +AWTagSelector file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/AWTagSelector.qml +AWTextEditor file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/AWTextEditor.qml +BugReport file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/BugReport.qml +ButtonSelector file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/ButtonSelector.qml +CheckBoxSelector file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/CheckBoxSelector.qml +ColorSelector file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/ColorSelector.qml +ComboBoxSelector file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/ComboBoxSelector.qml +ExportDialog file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/ExportDialog.qml +FontSelector file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/FontSelector.qml +HtmlDefaultFunctionsBar file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/HtmlDefaultFunctionsBar.qml +HtmlEditorButton file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/HtmlEditorButton.qml +HtmlEditorColor file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/HtmlEditorColor.qml +HtmlEditorFont file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/HtmlEditorFont.qml +ImportDialog file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/ImportDialog.qml +IntegerSelector file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/IntegerSelector.qml +LineSelector file://@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/qml/LineSelector.qml diff --git a/sources/test/CMakeLists.txt b/sources/test/CMakeLists.txt index 2a903bf..b2788e6 100644 --- a/sources/test/CMakeLists.txt +++ b/sources/test/CMakeLists.txt @@ -20,14 +20,14 @@ include_directories( set(AWTESTLIBRARY_HEADERS awtestlibrary.h) set(AWTESTLIBRARY_SOURCES awtestlibrary.cpp) add_library(${SUBPROJECT}-awtest STATIC ${AWTESTLIBRARY_SOURCES} ${AWTESTLIBRARY_HEADERS}) -target_link_libraries(${SUBPROJECT}-awtest ${Qt_LIBRARIES} ${Qt5Test_LIBRARIES}) +target_link_libraries(${SUBPROJECT}-awtest ${Qt_LIBRARIES} ${Qt5Test_LIBRARIES} ${Kf5_LIBRARIES}) set(LIBRARY_TEST_SET ${SUBPROJECT}-awtest ${PROJECT_LIBRARY} ${PROJECT_MONITORSOURCES} ${Qt_LIBRARIES} ${Kf5_LIBRARIES} ${Qt5Test_LIBRARIES}) # modules set(TEST_MODULES abstractextitem extquotes extscript extupgrade extweather - abstractformatter datetimeformatter floatformatter listformatter noformatter scriptformatter stringformatter + abstractformatter datetimeformatter floatformatter jsonformatter listformatter noformatter scriptformatter stringformatter extitemaggregator batterysource desktopsource gpuloadsource gputempsource hddtempsource networksource playersource processessource awbugreporter awconfighelper awkeycache awkeys awpatternfunctions awtelemetryhandler awupdatehelper @@ -45,6 +45,7 @@ foreach (TEST_MODULE ${TEST_MODULES}) set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awactions.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awdataaggregator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awdataengineaggregator.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awdbusadaptor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awformatterhelper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awkeycache.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awkeyoperations.cpp diff --git a/sources/test/awtestlibrary.cpp b/sources/test/awtestlibrary.cpp index a36c589..d602173 100644 --- a/sources/test/awtestlibrary.cpp +++ b/sources/test/awtestlibrary.cpp @@ -18,19 +18,42 @@ #include "awtestlibrary.h" +#include +#include #include #include +#include +#include + + +void AWTestLibrary::init() +{ + qsrand(static_cast(QTime::currentTime().msec())); +} + + +bool AWTestLibrary::isKWinActive() +{ + QSignalSpy spy(KWindowSystem::self(), SIGNAL(showingDesktopChanged(bool))); + KWindowSystem::setShowingDesktop(true); + spy.wait(5000); + + bool state = KWindowSystem::showingDesktop(); + KWindowSystem::setShowingDesktop(false); + + return state; +} char AWTestLibrary::randomChar() { - return 'A' + (rand() % static_cast('Z' - 'A')); + return 'A' + (qrand() % static_cast('Z' - 'A')); } double AWTestLibrary::randomDouble() { - return static_cast(rand()) / static_cast(RAND_MAX); + return static_cast(qrand()) / static_cast(RAND_MAX); } @@ -42,7 +65,7 @@ QPair AWTestLibrary::randomFilenames() .arg(QStandardPaths::writableLocation( QStandardPaths::GenericDataLocation)); - QString name = randomString(20); + QString name = randomString(1, 20); fileName += name; writeFileName += name; @@ -52,15 +75,15 @@ QPair AWTestLibrary::randomFilenames() int AWTestLibrary::randomInt(const int max) { - return rand() % max; + return qrand() % max; } -QString AWTestLibrary::randomString(const int max) +QString AWTestLibrary::randomString(const int min, const int max) { QString output; - int count = 1 + randomInt(max); + int count = min + randomInt(max - min); for (int i = 0; i < count; i++) output += QChar(randomChar()); diff --git a/sources/test/awtestlibrary.h b/sources/test/awtestlibrary.h index a8e80bb..d422344 100644 --- a/sources/test/awtestlibrary.h +++ b/sources/test/awtestlibrary.h @@ -25,11 +25,13 @@ namespace AWTestLibrary { +void init(); +bool isKWinActive(); char randomChar(); double randomDouble(); QPair randomFilenames(); int randomInt(const int max = 100); -QString randomString(const int max = 100); +QString randomString(const int min = 1, const int max = 100); QStringList randomStringList(const int max = 100); QStringList randomSelect(const QStringList available); }; diff --git a/sources/test/testabstractextitem.cpp b/sources/test/testabstractextitem.cpp index 379b186..e4bc093 100644 --- a/sources/test/testabstractextitem.cpp +++ b/sources/test/testabstractextitem.cpp @@ -26,16 +26,23 @@ void TestAbstractExtItem::initTestCase() { + AWTestLibrary::init(); auto names = AWTestLibrary::randomFilenames(); fileName = names.first; writeFileName = names.second; + name = AWTestLibrary::randomString(); + comment = AWTestLibrary::randomString(); + socket = AWTestLibrary::randomString(); + extItem = new ExtUpgrade(nullptr, fileName); extItem->setActive(false); extItem->setApiVersion(1); extItem->setComment(comment); + extItem->setCron(cron); extItem->setName(name); extItem->setNumber(-1); + extItem->setSocket(socket); } @@ -54,6 +61,7 @@ void TestAbstractExtItem::test_values() QCOMPARE(extItem->fileName(), fileName); QCOMPARE(extItem->name(), name); QVERIFY((extItem->number() > 0) && (extItem->number() < 1000)); + QCOMPARE(extItem->socket(), socket); } @@ -73,6 +81,8 @@ void TestAbstractExtItem::test_configuration() QCOMPARE(newExtItem->fileName(), writeFileName); QCOMPARE(newExtItem->name(), extItem->name()); QCOMPARE(newExtItem->number(), extItem->number()); + QCOMPARE(newExtItem->socket(), extItem->socket()); + QCOMPARE(newExtItem->cron(), extItem->cron()); delete newExtItem; } @@ -105,6 +115,8 @@ void TestAbstractExtItem::test_copy() QCOMPARE(newExtItem->apiVersion(), extItem->apiVersion()); QCOMPARE(newExtItem->comment(), extItem->comment()); QCOMPARE(newExtItem->name(), extItem->name()); + QCOMPARE(newExtItem->socket(), extItem->socket()); + QCOMPARE(newExtItem->cron(), extItem->cron()); delete newExtItem; } diff --git a/sources/test/testabstractextitem.h b/sources/test/testabstractextitem.h index 43f1ea0..a6be4a8 100644 --- a/sources/test/testabstractextitem.h +++ b/sources/test/testabstractextitem.h @@ -42,8 +42,10 @@ private slots: private: ExtUpgrade *extItem = nullptr; - QString comment = QString("A comment"); - QString name = QString("A name"); + QString comment; + QString cron = "* * * * *"; + QString name; + QString socket; QString fileName; QString writeFileName; }; diff --git a/sources/test/testabstractformatter.cpp b/sources/test/testabstractformatter.cpp index a8c6905..ba27ed9 100644 --- a/sources/test/testabstractformatter.cpp +++ b/sources/test/testabstractformatter.cpp @@ -26,6 +26,7 @@ void TestAbstractFormatter::initTestCase() { + AWTestLibrary::init(); formatter = new AWNoFormatter(nullptr); } diff --git a/sources/test/testawbugreporter.cpp b/sources/test/testawbugreporter.cpp index a2c116d..071b20d 100644 --- a/sources/test/testawbugreporter.cpp +++ b/sources/test/testawbugreporter.cpp @@ -26,6 +26,7 @@ void TestAWBugReporter::initTestCase() { + AWTestLibrary::init(); plugin = new AWBugReporter(this); } @@ -49,7 +50,7 @@ void TestAWBugReporter::test_generateText() void TestAWBugReporter::test_sendBugReport() { - QSignalSpy spy(plugin, SIGNAL(replyReceived(bool, QString))); + QSignalSpy spy(plugin, SIGNAL(replyReceived(int, QString))); plugin->sendBugReport( AWTestLibrary::randomString(), plugin->generateText(data.at(0), data.at(1), data.at(2), data.at(3))); diff --git a/sources/test/testawconfighelper.cpp b/sources/test/testawconfighelper.cpp index ac9716e..daa9525 100644 --- a/sources/test/testawconfighelper.cpp +++ b/sources/test/testawconfighelper.cpp @@ -26,6 +26,7 @@ void TestAWConfigHelper::initTestCase() { + AWTestLibrary::init(); plugin = new AWConfigHelper(this); } diff --git a/sources/test/testawkeycache.cpp b/sources/test/testawkeycache.cpp index df8ac05..2be9b0e 100644 --- a/sources/test/testawkeycache.cpp +++ b/sources/test/testawkeycache.cpp @@ -26,6 +26,7 @@ void TestAWKeyCache::initTestCase() { + AWTestLibrary::init(); } diff --git a/sources/test/testawkeys.cpp b/sources/test/testawkeys.cpp index 84d7beb..d4c597d 100644 --- a/sources/test/testawkeys.cpp +++ b/sources/test/testawkeys.cpp @@ -18,14 +18,18 @@ #include "testawkeys.h" +#include +#include #include #include "awkeys.h" #include "awtestlibrary.h" +#include "version.h" void TestAWKeys::initTestCase() { + AWTestLibrary::init(); plugin = new AWKeys(this); // tooltip init @@ -72,7 +76,7 @@ void TestAWKeys::cleanupTestCase() void TestAWKeys::test_hddDevices() { - QVERIFY(!plugin->getHddDevices().isEmpty()); + QVERIFY(plugin->getHddDevices().count() > 2); } @@ -109,6 +113,9 @@ void TestAWKeys::test_pattern() void TestAWKeys::test_tooltip() { + if (!AWTestLibrary::isKWinActive()) + QSKIP("KWin inactive, skip tooltip test"); + QSignalSpy spy(plugin, SIGNAL(needToolTipToBeUpdated(const QString))); QVERIFY(spy.wait(5 * interval)); @@ -159,4 +166,27 @@ void TestAWKeys::test_valueByKey() } +void TestAWKeys::test_dbus() +{ + if (!plugin->isDBusActive()) + QSKIP("No DBus session created, skip DBus test"); + + // get id + qlonglong id = reinterpret_cast(plugin); + + // create connection and message + QDBusConnection bus = QDBusConnection::sessionBus(); + QDBusMessage request + = QDBusMessage::createMethodCall(AWDBUS_SERVICE, QString("/%1").arg(id), + AWDBUS_SERVICE, QString("WhoAmI")); + // send message to dbus + QDBusMessage response = bus.call(request, QDBus::BlockWithGui); + + // parse result + QList arguments = response.arguments(); + QVERIFY(!arguments.isEmpty()); + QCOMPARE(arguments.at(0).toLongLong(), id); +} + + QTEST_MAIN(TestAWKeys); diff --git a/sources/test/testawkeys.h b/sources/test/testawkeys.h index 3c5a2fd..7a6c730 100644 --- a/sources/test/testawkeys.h +++ b/sources/test/testawkeys.h @@ -40,6 +40,7 @@ private slots: void test_wrapNewLines(); void test_infoByKey(); void test_valueByKey(); + void test_dbus(); private: AWKeys *plugin = nullptr; diff --git a/sources/test/testawpatternfunctions.cpp b/sources/test/testawpatternfunctions.cpp index 7e6a0d6..0a47d43 100644 --- a/sources/test/testawpatternfunctions.cpp +++ b/sources/test/testawpatternfunctions.cpp @@ -26,6 +26,7 @@ void TestAWPatternFunctions::initTestCase() { + AWTestLibrary::init(); } @@ -36,8 +37,8 @@ void TestAWPatternFunctions::cleanupTestCase() void TestAWPatternFunctions::test_findFunctionCalls() { - QString name = QString("aw_%1").arg(AWTestLibrary::randomString(10)); - QString code = AWTestLibrary::randomString(20); + QString name = QString("aw_%1").arg(AWTestLibrary::randomString(1, 10)); + QString code = AWTestLibrary::randomString(1, 20); QStringList args = AWTestLibrary::randomStringList(20); QString function = QString("$%1<%2>{{%3}}") .arg(name) @@ -59,18 +60,29 @@ void TestAWPatternFunctions::test_findFunctionCalls() void TestAWPatternFunctions::test_findKeys() { - QStringList keys = AWTestLibrary::randomStringList(20); - QStringList bars = AWTestLibrary::randomStringList(20); + int count = AWTestLibrary::randomInt(200); + QStringList allKeys; + for (int i = 0; i < count; i++) { + auto key = AWTestLibrary::randomString(1, 20); + while (allKeys.indexOf(QRegExp(QString("^%1.*").arg(key))) != -1) + key = AWTestLibrary::randomString(1, 20); + allKeys.append(key); + } + + auto keys = AWTestLibrary::randomSelect(allKeys); + auto bars = AWTestLibrary::randomSelect(allKeys); std::for_each(bars.begin(), bars.end(), [](QString &bar) { bar.prepend(QString("bar")); }); - QStringList noise = AWTestLibrary::randomStringList(200); - QStringList allKeys = keys + bars + noise; QString pattern = QString("$%1 $%2") .arg(keys.join(QString(" $"))) .arg(bars.join(QString(" $"))); + allKeys.append(bars); + allKeys.sort(); + std::reverse(allKeys.begin(), allKeys.end()); keys.sort(); bars.sort(); + QStringList foundKeys = AWPatternFunctions::findKeys(pattern, allKeys, false); foundKeys.sort(); diff --git a/sources/test/testawtelemetryhandler.cpp b/sources/test/testawtelemetryhandler.cpp index 9d2f04a..6c914c0 100644 --- a/sources/test/testawtelemetryhandler.cpp +++ b/sources/test/testawtelemetryhandler.cpp @@ -26,7 +26,9 @@ void TestAWTelemetryHandler::initTestCase() { - plugin = new AWTelemetryHandler(this, telemetryId); + AWTestLibrary::init(); + plugin = new AWTelemetryHandler(this); + plugin->init(1, true, telemetryId); telemetryData = AWTestLibrary::randomString(); telemetryGroup = AWTestLibrary::randomString(); } diff --git a/sources/test/testawupdatehelper.cpp b/sources/test/testawupdatehelper.cpp index 4b96b56..2585b83 100644 --- a/sources/test/testawupdatehelper.cpp +++ b/sources/test/testawupdatehelper.cpp @@ -26,6 +26,7 @@ void TestAWUpdateHelper::initTestCase() { + AWTestLibrary::init(); plugin = new AWUpdateHelper(this); } diff --git a/sources/test/testbatterysource.cpp b/sources/test/testbatterysource.cpp index 74f1f9f..8e1640a 100644 --- a/sources/test/testbatterysource.cpp +++ b/sources/test/testbatterysource.cpp @@ -26,6 +26,7 @@ void TestBatterySource::initTestCase() { + AWTestLibrary::init(); source = new BatterySource(this, QStringList() << acpiPath); } diff --git a/sources/test/testdatetimeformatter.cpp b/sources/test/testdatetimeformatter.cpp index c97b570..62050f2 100644 --- a/sources/test/testdatetimeformatter.cpp +++ b/sources/test/testdatetimeformatter.cpp @@ -27,6 +27,7 @@ void TestAWDateTimeFormatter::initTestCase() { + AWTestLibrary::init(); format = AWTestLibrary::randomSelect(QString(TIME_KEYS).split(QChar(','))) .join(QChar(' ')); diff --git a/sources/test/testdesktopsource.cpp b/sources/test/testdesktopsource.cpp index 36831e6..2471ca5 100644 --- a/sources/test/testdesktopsource.cpp +++ b/sources/test/testdesktopsource.cpp @@ -26,6 +26,7 @@ void TestDesktopSource::initTestCase() { + AWTestLibrary::init(); source = new DesktopSource(this, QStringList()); } diff --git a/sources/test/testdpplugin.cpp b/sources/test/testdpplugin.cpp index e7b4b75..0db977f 100644 --- a/sources/test/testdpplugin.cpp +++ b/sources/test/testdpplugin.cpp @@ -27,7 +27,9 @@ void TestDPPlugin::initTestCase() { + AWTestLibrary::init(); plugin = new DPAdds(this); + m_isKwinActive = AWTestLibrary::isKWinActive(); } @@ -39,6 +41,9 @@ void TestDPPlugin::cleanupTestCase() void TestDPPlugin::test_desktops() { + if (!m_isKwinActive) + QSKIP("KWin inactive, skip Destkop panel tests"); + int current = plugin->currentDesktop(); int total = plugin->numberOfDesktops(); QVERIFY(total != 0); @@ -62,13 +67,29 @@ void TestDPPlugin::test_desktops() void TestDPPlugin::test_dictKeys() { + if (!m_isKwinActive) + QSKIP("KWin inactive, skip Destkop panel tests"); + QCOMPARE(plugin->dictKeys().count(), 4); pattern += plugin->dictKeys().join(QString(" $")); } +void TestDPPlugin::test_infoByKey() +{ + if (!m_isKwinActive) + QSKIP("KWin inactive, skip Destkop panel tests"); + + // nothing to test here yet + QVERIFY(true); +} + + void TestDPPlugin::test_parsePattern() { + if (!m_isKwinActive) + QSKIP("KWin inactive, skip Destkop panel tests"); + QString result = plugin->parsePattern(pattern, plugin->currentDesktop()); QVERIFY(!result.isEmpty()); QVERIFY(result != pattern); @@ -79,6 +100,9 @@ void TestDPPlugin::test_parsePattern() void TestDPPlugin::test_tooltipImage() { + if (!m_isKwinActive) + QSKIP("KWin inactive, skip Destkop panel tests"); + QVariantMap data; data[QString("tooltipColor")] = QString("#000000"); data[QString("tooltipType")] = QString("windows"); diff --git a/sources/test/testdpplugin.h b/sources/test/testdpplugin.h index 71d89d6..65dd9b7 100644 --- a/sources/test/testdpplugin.h +++ b/sources/test/testdpplugin.h @@ -35,11 +35,13 @@ private slots: // test void test_desktops(); void test_dictKeys(); + void test_infoByKey(); void test_tooltipImage(); void test_parsePattern(); private: DPAdds *plugin = nullptr; + bool m_isKwinActive = false; QString pattern = QString("$"); }; diff --git a/sources/test/testextitemaggregator.cpp b/sources/test/testextitemaggregator.cpp index ddd681f..631e169 100644 --- a/sources/test/testextitemaggregator.cpp +++ b/sources/test/testextitemaggregator.cpp @@ -27,6 +27,7 @@ void TestExtItemAggregator::initTestCase() { + AWTestLibrary::init(); aggregator = new ExtItemAggregator(nullptr, type); } diff --git a/sources/test/testextquotes.cpp b/sources/test/testextquotes.cpp index 095f5d4..71fa3ed 100644 --- a/sources/test/testextquotes.cpp +++ b/sources/test/testextquotes.cpp @@ -20,11 +20,13 @@ #include +#include "awtestlibrary.h" #include "extquotes.h" void TestExtQuotes::initTestCase() { + AWTestLibrary::init(); extQuotes = new ExtQuotes(nullptr); extQuotes->setInterval(1); extQuotes->setTicker(ticker); @@ -57,18 +59,11 @@ void TestExtQuotes::test_run() // check values QVERIFY(spy.wait(5000)); QList arguments = spy.takeFirst(); - cache[QString("ask")] - = arguments.at(0).toHash()[extQuotes->tag(QString("ask"))]; - cache[QString("bid")] - = arguments.at(0).toHash()[extQuotes->tag(QString("bid"))]; - cache[QString("price")] - = arguments.at(0).toHash()[extQuotes->tag(QString("price"))]; + for (auto &type : types) + cache[type] = arguments.at(0).toHash()[extQuotes->tag(type)]; - QCOMPARE(firstValue[extQuotes->tag(QString("ask"))].toDouble(), 0.0); - QCOMPARE(firstValue[extQuotes->tag(QString("bid"))].toDouble(), 0.0); - QCOMPARE(firstValue[extQuotes->tag(QString("price"))].toDouble(), 0.0); for (auto type : types) { - qDebug() << "Test type" << type; + QCOMPARE(firstValue[extQuotes->tag(type)].toDouble(), 0.0); QVERIFY((cache[type].toDouble() > price.first) && (cache[type].toDouble() < price.second)); } @@ -85,25 +80,14 @@ void TestExtQuotes::test_derivatives() QVERIFY(spy.wait(5000)); QList arguments = spy.takeFirst(); QVariantHash values; - values[QString("ask")] - = arguments.at(0).toHash()[extQuotes->tag(QString("ask"))]; - values[QString("bid")] - = arguments.at(0).toHash()[extQuotes->tag(QString("bid"))]; - values[QString("price")] - = arguments.at(0).toHash()[extQuotes->tag(QString("price"))]; + for (auto type : types) + values[type] = arguments.at(0).toHash()[extQuotes->tag(type)]; for (auto type : types) { - qDebug() << "Test type" << type; QCOMPARE(arguments.at(0) .toHash()[extQuotes->tag(QString("%1chg").arg(type))] .toDouble(), (values[type].toDouble() - cache[type].toDouble())); - QWARN("Possible round error"); - QCOMPARE(arguments.at(0) - .toHash()[extQuotes->tag(QString("perc%1chg").arg(type))] - .toDouble(), - 100.0 * (values[type].toDouble() - cache[type].toDouble()) - / values[type].toDouble()); } } diff --git a/sources/test/testextquotes.h b/sources/test/testextquotes.h index 1b07163..5eed05d 100644 --- a/sources/test/testextquotes.h +++ b/sources/test/testextquotes.h @@ -43,8 +43,8 @@ private: ExtQuotes *extQuotes = nullptr; QVariantHash cache; QString ticker = QString("EURUSD=X"); - QStringList types = QStringList() << QString("ask") << QString("bid") - << QString("price"); + QStringList types = QStringList() + << QString("ask") << QString("bid") << QString("price"); // we assume that price will not be differ more than in 2 times QPair price = QPair(0.5, 2.0); }; diff --git a/sources/test/testextscript.cpp b/sources/test/testextscript.cpp index 959593f..5198946 100644 --- a/sources/test/testextscript.cpp +++ b/sources/test/testextscript.cpp @@ -26,6 +26,7 @@ void TestExtScript::initTestCase() { + AWTestLibrary::init(); randomString = AWTestLibrary::randomString(); extScript = new ExtScript(nullptr); @@ -75,6 +76,9 @@ void TestExtScript::test_run() void TestExtScript::test_filters() { + if (extScript->jsonFiltersFile().isEmpty()) + QSKIP("No json filters found for scripts, skip fitlers test"); + extScript->setFilters(QStringList() << QString("newline")); // init spy QSignalSpy spy(extScript, SIGNAL(dataReceived(const QVariantHash &))); diff --git a/sources/test/testextupgrade.cpp b/sources/test/testextupgrade.cpp index fb0e0d3..b87ca0f 100644 --- a/sources/test/testextupgrade.cpp +++ b/sources/test/testextupgrade.cpp @@ -26,6 +26,7 @@ void TestExtUpgrade::initTestCase() { + AWTestLibrary::init(); randomStrings = AWTestLibrary::randomStringList(); cmd = QString("echo -e '%1'").arg(randomStrings.join(QString("\n"))); diff --git a/sources/test/testextweather.cpp b/sources/test/testextweather.cpp index 825ee26..0ffa2b1 100644 --- a/sources/test/testextweather.cpp +++ b/sources/test/testextweather.cpp @@ -20,11 +20,13 @@ #include +#include "awtestlibrary.h" #include "extweather.h" void TestExtWeather::initTestCase() { + AWTestLibrary::init(); extWeather = new ExtWeather(nullptr); extWeather->setInterval(1); extWeather->setCity(city); @@ -75,6 +77,9 @@ void TestExtWeather::test_ts() void TestExtWeather::test_image() { + if (extWeather->jsonMapFile().isEmpty()) + QSKIP("No json map found for weather, skip image test"); + extWeather->setImage(true); // init spy QSignalSpy spy(extWeather, SIGNAL(dataReceived(const QVariantHash &))); @@ -120,9 +125,6 @@ void TestExtWeather::run() >= humidity.first) && (arguments[extWeather->tag(QString("humidity"))].toInt() <= humidity.second)); - QWARN("May fail here for Yahoo! Weather, see " - "https://yahoo.uservoice.com/forums/207813-us-weather/suggestions/" - "14209233-invalid-pressure-calculation"); QVERIFY((arguments[extWeather->tag(QString("pressure"))].toInt() > pressure.first) && (arguments[extWeather->tag(QString("pressure"))].toInt() @@ -132,6 +134,8 @@ void TestExtWeather::run() && (arguments[extWeather->tag(QString("temperature"))].toFloat() < temp.second)); // image should be only one symbol here + if (extWeather->jsonMapFile().isEmpty()) + QSKIP("No json map found for weather, skip image test"); QCOMPARE(arguments[extWeather->tag(QString("weather"))].toString().count(), 1); } diff --git a/sources/test/testfloatformatter.cpp b/sources/test/testfloatformatter.cpp index dbe75c7..2a8993d 100644 --- a/sources/test/testfloatformatter.cpp +++ b/sources/test/testfloatformatter.cpp @@ -26,6 +26,7 @@ void TestAWFloatFormatter::initTestCase() { + AWTestLibrary::init(); formatter = new AWFloatFormatter(nullptr); } diff --git a/sources/test/testgpuloadsource.cpp b/sources/test/testgpuloadsource.cpp index 0bdc1ec..311428e 100644 --- a/sources/test/testgpuloadsource.cpp +++ b/sources/test/testgpuloadsource.cpp @@ -26,6 +26,7 @@ void TestGPULoadSource::initTestCase() { + AWTestLibrary::init(); device = GPULoadSource::autoGpu(); QVERIFY(!device.isEmpty()); diff --git a/sources/test/testgputempsource.cpp b/sources/test/testgputempsource.cpp index a73546c..aaa08c9 100644 --- a/sources/test/testgputempsource.cpp +++ b/sources/test/testgputempsource.cpp @@ -26,6 +26,7 @@ void TestGPUTemperatureSource::initTestCase() { + AWTestLibrary::init(); device = GPUTemperatureSource::autoGpu(); QVERIFY(!device.isEmpty()); diff --git a/sources/test/testhddtempsource.cpp b/sources/test/testhddtempsource.cpp index bccd587..0be6c7a 100644 --- a/sources/test/testhddtempsource.cpp +++ b/sources/test/testhddtempsource.cpp @@ -26,6 +26,7 @@ void TestHDDTemperatureSource::initTestCase() { + AWTestLibrary::init(); devices = HDDTemperatureSource::allHdd(); QVERIFY(devices.count() > 0); diff --git a/sources/test/testjsonformatter.cpp b/sources/test/testjsonformatter.cpp new file mode 100644 index 0000000..c1611ff --- /dev/null +++ b/sources/test/testjsonformatter.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#include "testjsonformatter.h" + +#include + +#include "awjsonformatter.h" +#include "awtestlibrary.h" + + +void TestAWJsonFormatter::initTestCase() +{ + AWTestLibrary::init(); + formatter = new AWJsonFormatter(nullptr); + + generate(); + formatter->setPath(path); +} + + +void TestAWJsonFormatter::cleanupTestCase() +{ + delete formatter; +} + + +void TestAWJsonFormatter::test_values() +{ + QCOMPARE(formatter->path(), path); +} + + +void TestAWJsonFormatter::test_conversion() +{ + QCOMPARE(formatter->convert(json), value); +} + + +void TestAWJsonFormatter::test_copy() +{ + AWJsonFormatter *newFormatter = formatter->copy(QString("/dev/null"), 1); + + QCOMPARE(newFormatter->path(), formatter->path()); + QCOMPARE(newFormatter->number(), 1); + + delete newFormatter; +} + + +void TestAWJsonFormatter::generate() +{ + value = AWTestLibrary::randomString(); + + QVariantMap first; + QString firstKey = AWTestLibrary::randomString(); + first[firstKey] = value; + + int listCount = AWTestLibrary::randomInt(5) + 1; + int validCount = AWTestLibrary::randomInt(listCount); + QVariantList second; + for (int i = 0; i < listCount; i++) { + if (i == validCount) { + second.append(first); + } else { + QString key = AWTestLibrary::randomString(); + QString val = AWTestLibrary::randomString(); + QVariantMap dict; + dict[key] = val; + second.append(dict); + } + } + + QString thirdKey = AWTestLibrary::randomString(); + QVariantMap output; + output[thirdKey] = second; + + json = output; + path = QString("%1.%2.%3").arg(thirdKey).arg(validCount).arg(firstKey); +} + + +QTEST_MAIN(TestAWJsonFormatter); diff --git a/sources/test/testjsonformatter.h b/sources/test/testjsonformatter.h new file mode 100644 index 0000000..12ec8a6 --- /dev/null +++ b/sources/test/testjsonformatter.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#ifndef TESTJSONFORMATTER_H +#define TESTJSONFORMATTER_H + +#include +#include + + +class AWJsonFormatter; + +class TestAWJsonFormatter : public QObject +{ + Q_OBJECT + +private slots: + // initialization + void initTestCase(); + void cleanupTestCase(); + // test + void test_values(); + void test_conversion(); + void test_copy(); + +private: + void generate(); + AWJsonFormatter *formatter = nullptr; + QVariant json; + QString path; + QString value; +}; + + +#endif /* TESTJSONFORMATTER_Hl */ diff --git a/sources/test/testlistformatter.cpp b/sources/test/testlistformatter.cpp index 9522dae..e85a3fa 100644 --- a/sources/test/testlistformatter.cpp +++ b/sources/test/testlistformatter.cpp @@ -26,7 +26,8 @@ void TestAWListFormatter::initTestCase() { - separator = AWTestLibrary::randomString(10); + AWTestLibrary::init(); + separator = AWTestLibrary::randomString(9, 10); formatter = new AWListFormatter(nullptr); formatter->setSeparator(separator); diff --git a/sources/test/testnetworksource.cpp b/sources/test/testnetworksource.cpp index 9f2994b..878e258 100644 --- a/sources/test/testnetworksource.cpp +++ b/sources/test/testnetworksource.cpp @@ -26,6 +26,7 @@ void TestNetworkSource::initTestCase() { + AWTestLibrary::init(); source = new NetworkSource(this, QStringList()); } diff --git a/sources/test/testnoformatter.cpp b/sources/test/testnoformatter.cpp index a1ed6ce..7eda3c0 100644 --- a/sources/test/testnoformatter.cpp +++ b/sources/test/testnoformatter.cpp @@ -26,6 +26,7 @@ void TestAWNoFormatter::initTestCase() { + AWTestLibrary::init(); formatter = new AWNoFormatter(nullptr); } diff --git a/sources/test/testplayersource.cpp b/sources/test/testplayersource.cpp index b7c968e..e932941 100644 --- a/sources/test/testplayersource.cpp +++ b/sources/test/testplayersource.cpp @@ -26,6 +26,7 @@ void TestPlayerSource::initTestCase() { + AWTestLibrary::init(); } @@ -42,16 +43,15 @@ void TestPlayerSource::_test_sources(const PlayerSource *source) void TestPlayerSource::test_buildString() { - QString randomString = AWTestLibrary::randomString(40); + QString randomString = AWTestLibrary::randomString(1, 40); QString str = PlayerSource::buildString(QString(), randomString, 20); QCOMPARE(str.count(), 20); str = PlayerSource::buildString(str, randomString, 20); QCOMPARE(str.count(), 20); - QCOMPARE(randomString.indexOf(str), 1); - str = PlayerSource::buildString(QString(), AWTestLibrary::randomString(10), - 20); + str = PlayerSource::buildString(QString(), + AWTestLibrary::randomString(1, 10), 20); QCOMPARE(str.count(), 20); } @@ -59,11 +59,11 @@ void TestPlayerSource::test_buildString() void TestPlayerSource::test_stripString() { QString str = PlayerSource::buildString( - QString(), AWTestLibrary::randomString(40), 20); + QString(), AWTestLibrary::randomString(1, 40), 20); QCOMPARE(str.count(), 20); - str = PlayerSource::buildString(QString(), AWTestLibrary::randomString(10), - 20); + str = PlayerSource::buildString(QString(), + AWTestLibrary::randomString(1, 10), 20); QCOMPARE(str.count(), 20); } @@ -75,22 +75,27 @@ void TestPlayerSource::test_autoMpris() << QString("auto") << QString::number(10)); PlayerSource *source = new PlayerSource(this, args); - QWARN("Will fail if no MPRIS supported player is run"); - QVERIFY(!source->getAutoMpris().isEmpty()); + bool empty = source->getAutoMpris().isEmpty(); + if (empty) + QWARN("No MPRIS found, manual check required"); + else + QVERIFY(!empty); } void TestPlayerSource::test_mpd() { - QStringList args(QStringList() << QString("mpd") << mpdAddress - << QString::number(mpdPort) - << QString("auto") << QString::number(10)); + QStringList args(QStringList() + << QString("mpd") << mpdAddress << QString::number(mpdPort) + << QString("auto") << QString::number(10)); PlayerSource *source = new PlayerSource(this, args); _test_sources(source); // init spy QSignalSpy spy(source, SIGNAL(dataReceived(const QVariantHash &))); QVariant firstValue = source->data(QString("player/title")); + if (!source->isMpdSocketConnected()) + QSKIP("No mpd found"); // check values QVERIFY(spy.wait(5000)); @@ -98,12 +103,11 @@ void TestPlayerSource::test_mpd() QVariantHash secondValue = arguments.at(0).toHash(); // actually nothing to test here just print warning if no information found - if (secondValue[QString("player/title")].toString() == QString("unknown")) { - QWARN("No mpd found"); - } else { - QVERIFY(secondValue[QString("player/progress")].toInt() - < secondValue[QString("player/duration")].toInt()); - } + if (secondValue[QString("player/title")].toString() == QString("unknown")) + QSKIP("No mpd found"); + + QVERIFY(secondValue[QString("player/progress")].toInt() + < secondValue[QString("player/duration")].toInt()); } @@ -120,11 +124,10 @@ void TestPlayerSource::test_mpris() int duration = source->data(QString("player/duration")).toInt(); // actually nothing to test here just print warning if no information found - if (value == QString("unknown")) { - QWARN("No mpris found"); - } else { - QVERIFY(progress < duration); - } + if (value == QString("unknown")) + QSKIP("No mpris found"); + + QVERIFY(progress < duration); } diff --git a/sources/test/testprocessessource.cpp b/sources/test/testprocessessource.cpp index fef1bf1..a6a3180 100644 --- a/sources/test/testprocessessource.cpp +++ b/sources/test/testprocessessource.cpp @@ -26,6 +26,7 @@ void TestProcessesSource::initTestCase() { + AWTestLibrary::init(); source = new ProcessesSource(this, QStringList()); } diff --git a/sources/test/testscriptformatter.cpp b/sources/test/testscriptformatter.cpp index d2e0adc..22b02ae 100644 --- a/sources/test/testscriptformatter.cpp +++ b/sources/test/testscriptformatter.cpp @@ -26,6 +26,7 @@ void TestAWScriptFormatter::initTestCase() { + AWTestLibrary::init(); formatter = new AWScriptFormatter(nullptr); formatter->setCode(fullCode); formatter->setAppendCode(false); diff --git a/sources/test/testscriptformatter.h b/sources/test/testscriptformatter.h index ed81823..6b23e71 100644 --- a/sources/test/testscriptformatter.h +++ b/sources/test/testscriptformatter.h @@ -47,4 +47,4 @@ private: }; -#endif /* TESTNOFORMATTER_H */ +#endif /* TESTSCRIPTFORMATTER_H */ diff --git a/sources/test/teststringformatter.cpp b/sources/test/teststringformatter.cpp index a7f98b6..1619cba 100644 --- a/sources/test/teststringformatter.cpp +++ b/sources/test/teststringformatter.cpp @@ -26,6 +26,7 @@ void TestAWStringFormatter::initTestCase() { + AWTestLibrary::init(); formatter = new AWStringFormatter(nullptr); } @@ -49,7 +50,10 @@ void TestAWStringFormatter::test_count() QCOMPARE(formatter->count(), count); // test - QString output = formatter->convert(AWTestLibrary::randomString()); + auto testString = AWTestLibrary::randomString(); + while (testString.count() > count) + testString = AWTestLibrary::randomString(); + QString output = formatter->convert(testString); QCOMPARE(output.count(), count); // reset diff --git a/sources/version.h.in b/sources/version.h.in index 74319cc..fd39d2e 100644 --- a/sources/version.h.in +++ b/sources/version.h.in @@ -3,103 +3,115 @@ // information -#define NAME "Awesome Widgets" -#define VERSION "@PROJECT_VERSION@" -#define COMMIT_SHA "@PROJECT_COMMIT_SHA@" -#define AUTHOR "@PROJECT_AUTHOR@" -#define TRANSLATORS \ - "Ernesto Aviles Vzqz (Spanish), Mermouy (French), underr (Brazillian " \ - "Portuguese), Viktor Slobodyan (Ukrainian), Lemueler (Chinese), Heimen " \ - "Stoffels (Dutch), Mariusz Kocoń (Polish)" -#define EMAIL "@PROJECT_CONTACT@" -#define LICENSE "@PROJECT_LICENSE@" -#define TRDPARTY_LICENSE \ - "QReplyTimeout " \ - "wrapper,no,http://codereview.stackexchange.com/questions/30031/" \ - "qnetworkreply-network-reply-timeout-helper" -#define SPECIAL_THANKS \ - "Yahoo! Finance,https://finance.yahoo.com/;Yahoo! " \ - "Weather,https://weather.yahoo.com/;JetBrains,https://www.jetbrains.com/" \ - ";OpenWeatherMap,http://openweathermap.org/" -#define CHANGELOG "@PROJECT_CHANGELOG@" +const char NAME[] = "Awesome Widgets"; +const char VERSION[] = "@PROJECT_VERSION@"; +const char COMMIT_SHA[] = "@PROJECT_COMMIT_SHA@"; +const char AUTHOR[] = "@PROJECT_AUTHOR@"; +const char TRANSLATORS[] = "Ernesto Aviles Vzqz (Spanish),Mermouy " + "(French),underr (Brazillian Portuguese),Viktor " + "Slobodyan (Ukrainian),Lemueler (Chinese),Heimen " + "Stoffels (Dutch), Mariusz Kocoń (Polish)"; +const char EMAIL[] = "@PROJECT_CONTACT@"; +const char LICENSE[] = "@PROJECT_LICENSE@"; +const char TRDPARTY_LICENSE[] = "QReplyTimeout " + "wrapper,no,http://" + "codereview.stackexchange.com/questions/30031/" + "qnetworkreply-network-reply-timeout-helper"; +const char SPECIAL_THANKS[] + = "Yahoo! Finance,https://finance.yahoo.com/;Yahoo! " + "Weather,https://weather.yahoo.com/;JetBrains,https://www.jetbrains.com/" + ";OpenWeatherMap,http://openweathermap.org/"; +const char CHANGELOG[] = "@PROJECT_CHANGELOG@"; // configuraion // graphical items api version -#define AWGIAPI 5 +const int AW_GRAPHITEM_API = 5; // extquotes api version -#define AWEQAPI 3 +const int AW_EXTQUOTES_API = 3; // extscript api version -#define AWESAPI 4 +const int AW_EXTSCRIPT_API = 4; // extupgrade api version -#define AWEUAPI 3 +const int AW_EXTUPGRADE_API = 3; // extweather api version -#define AWEWAPI 3 +const int AW_EXTWEATHER_API = 3; +// extnetworkrequest api version +const int AW_EXTNETREQUEST_API = 1; // formatter api version -#define AWEFAPI 2 +const int AW_FORMATTER_API = 3; // telemetry api version -#define AWTEAPI 1 +const int AW_TELEMETRY_API = 1; +// dbus adaptor properties +// use define here instead of normal const definition for moc +#define AWDBUS_SERVICE_NAME "org.kde.plasma.awesomewidget" +const char AWDBUS_SERVICE[] = AWDBUS_SERVICE_NAME; // network requests timeout, ms -#define REQUEST_TIMEOUT 3000 +const int REQUEST_TIMEOUT = 3000; // available time keys -#define TIME_KEYS \ - "d,dd,ddd,dddd,M,MM,MMM,MMMM,yy,yyyy,h,hh,H,HH,m,mm,s,ss,t,a,ap,A,AP" +const char TIME_KEYS[] + = "d,dd,ddd,dddd,M,MM,MMM,MMMM,yy,yyyy,h,hh,H,HH,m,mm,s,ss,t,a,ap,A,AP"; // static keys -#define STATIC_KEYS \ - "time,isotime,shorttime,longtime,tstime,ctime,uptime,cuptime,cpucl,cpu," \ - "gputemp,gpu,memmb,memgb,memfreemb,memfreegb,memtotmb,memtotgb,memusedmb," \ - "memusedgb,mem,swapmb,swapgb,swapfreemb,swapfreegb,swaptotmb,swaptotgb," \ - "swap,downunits,upunits,downkb,downtotalkb,downtotal,down,uptotalkb," \ - "uptotal,upkb,up,netdev,ac,bat,album,artist,duration,progress,title," \ - "dalbum,dartist,dtitle,salbum,sartist,stitle,pscount,pstotal,ps,desktop," \ - "ndesktop,tdesktops,la15,la5,la1" +const char STATIC_FUNCTIONS[] = "{{\n\n}},template{{\n\n}},aw_all<>{{}},aw_" + "count<>{{}},aw_keys<>{{}},aw_macro<>{{}},aw_" + "names<>{{}}"; +const char STATIC_KEYS[] + = "time,isotime,shorttime,longtime,tstime,ctime,uptime,cuptime,cpucl,cpu," + "gputemp,gpu,memmb,memgb,memfreemb,memfreegb,memtotmb,memtotgb,memusedmb," + "memusedgb,mem,swapmb,swapgb,swapfreemb,swapfreegb,swaptotmb,swaptotgb," + "swap,downunits,upunits,downkb,downtotalkb,downtotal,down,uptotalkb," + "uptotal,upkb,up,netdev,ac,bat,album,artist,duration,progress,title," + "dalbum,dartist,dtitle,salbum,sartist,stitle,pscount,pstotal,ps,desktop," + "ndesktop,tdesktops,la15,la5,la1"; #cmakedefine BUILD_FUTURE #cmakedefine BUILD_LOAD #cmakedefine BUILD_TESTING // links -#define HOMEPAGE "https://arcanis.me/projects/awesome-widgets/" -#define REPOSITORY "https://github.com/arcan1s/awesome-widgets" -#define RELEASES "https://github.com/arcan1s/awesome-widgets/releases/tag/V." -#define VERSION_API \ - "https://api.github.com/repos/arcan1s/awesome-widgets/releases" -#define BUGTRACKER "https://github.com/arcan1s/awesome-widgets/issues" -#define BUGTRACKER_API "http://arcanis.me/repos/arcan1s/awesome-widgets/issues" -#define TRANSLATION "https://github.com/arcan1s/awesome-widgets/issues/14" -#define AUR_PACKAGES \ - "https://aur.archlinux.org/packages/plasma5-applet-awesome-widgets/" -#define OPENSUSE_PACKAGES "http://software.opensuse.org/package/awesome-widgets" +const char HOMEPAGE[] = "https://arcanis.me/projects/awesome-widgets"; +const char REPOSITORY[] = "https://github.com/arcan1s/awesome-widgets"; +const char RELEASES[] + = "https://github.com/arcan1s/awesome-widgets/releases/tag/V."; +const char VERSION_API[] + = "https://api.github.com/repos/arcan1s/awesome-widgets/releases"; +const char BUGTRACKER[] = "https://github.com/arcan1s/awesome-widgets/issues"; +const char BUGTRACKER_API[] + = "https://arcanis.me/repos/arcan1s/awesome-widgets/issues"; +const char TRANSLATION[] + = "https://github.com/arcan1s/awesome-widgets/issues/14"; +const char AUR_PACKAGES[] + = "https://aur.archlinux.org/packages/plasma5-applet-awesome-widgets/"; +const char OPENSUSE_PACKAGES[] + = "http://software.opensuse.org/package/plasma5-awesome-widgets"; // build information -#define BUILD_DATE "@CURRENT_DATE@" -#define DATE "2013-@CURRENT_YEAR@" +const char BUILD_DATE[] = "@CURRENT_DATE@"; +const char DATE[] = "2013-@CURRENT_YEAR@"; // cmake properties -#define CMAKE_BUILD_TYPE "@CMAKE_BUILD_TYPE@" -#define CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@" -#define CMAKE_CXX_FLAGS "@CMAKE_CXX_FLAGS@" -#define CMAKE_CXX_FLAGS_DEBUG "@CMAKE_CXX_FLAGS_DEBUG@" -#define CMAKE_CXX_FLAGS_RELEASE "@CMAKE_CXX_FLAGS_RELEASE@" -#define CMAKE_CXX_FLAGS_OPTIMIZATION "@CMAKE_CXX_FLAGS_OPTIMIZATION@" -#define CMAKE_DEFINITIONS "@CMAKE_DEFINITIONS@" -#define CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@" -#define CMAKE_MODULE_LINKER_FLAGS "@CMAKE_MODULE_LINKER_FLAGS@" -#define CMAKE_SHARED_LINKER_FLAGS "@CMAKE_SHARED_LINKER_FLAGS@" +const char CMAKE_BUILD_TYPE[] = "@CMAKE_BUILD_TYPE@"; +const char CMAKE_CXX_COMPILER[] = "@CMAKE_CXX_COMPILER@"; +const char CMAKE_CXX_FLAGS[] = "@CMAKE_CXX_FLAGS@"; +const char CMAKE_CXX_FLAGS_DEBUG[] = "@CMAKE_CXX_FLAGS_DEBUG@"; +const char CMAKE_CXX_FLAGS_RELEASE[] = "@CMAKE_CXX_FLAGS_RELEASE@"; +const char CMAKE_CXX_FLAGS_OPTIMIZATION[] = "@CMAKE_CXX_FLAGS_OPTIMIZATION@"; +const char CMAKE_DEFINITIONS[] = "@CMAKE_DEFINITIONS@"; +const char CMAKE_INSTALL_PREFIX[] = "@CMAKE_INSTALL_PREFIX@"; +const char CMAKE_MODULE_LINKER_FLAGS[] = "@CMAKE_MODULE_LINKER_FLAGS@"; +const char CMAKE_SHARED_LINKER_FLAGS[] = "@CMAKE_SHARED_LINKER_FLAGS@"; // components -#define BUILD_COVERAGE "@BUILD_COVERAGE@" -#define BUILD_PLASMOIDS "@BUILD_PLASMOIDS@" -#define BUILD_DEB_PACKAGE "@BUILD_DEB_PACKAGE@" -#define BUILD_RPM_PACKAGE "@BUILD_RPM_PACKAGE@" -#define CLANGFORMAT_EXECUTABLE "@CLANGFORMAT_EXECUTABLE@" -#define COVERITY_COMMENT "@COVERITY_COMMENT@" -#define COVERITY_DIRECTORY "@COVERITY_DIRECTORY@" -#define COVERITY_EMAIL "@COVERITY_EMAIL@" -#define COVERITY_EXECUTABLE "@COVERITY_EXECUTABLE@" -#define COVERITY_URL "@COVERITY_URL@" -#define CPPCHECK_EXECUTABLE "@CPPCHECK_EXECUTABLE@" +const char BUILD_PLASMOIDS[] = "@BUILD_PLASMOIDS@"; +const char BUILD_DEB_PACKAGE[] = "@BUILD_DEB_PACKAGE@"; +const char BUILD_RPM_PACKAGE[] = "@BUILD_RPM_PACKAGE@"; +const char CLANGFORMAT_EXECUTABLE[] = "@CLANGFORMAT_EXECUTABLE@"; +const char COVERITY_COMMENT[] = "@COVERITY_COMMENT@"; +const char COVERITY_DIRECTORY[] = "@COVERITY_DIRECTORY@"; +const char COVERITY_EMAIL[] = "@COVERITY_EMAIL@"; +const char COVERITY_EXECUTABLE[] = "@COVERITY_EXECUTABLE@"; +const char COVERITY_URL[] = "@COVERITY_URL@"; +const char CPPCHECK_EXECUTABLE[] = "@CPPCHECK_EXECUTABLE@"; // additional functions -#define PROP_FUTURE "@BUILD_FUTURE@" -#define PROP_LOAD "@BUILD_LOAD@" -#define PROP_TEST "@BUILD_TESTING@" +const char PROP_FUTURE[] = "@BUILD_FUTURE@"; +const char PROP_LOAD[] = "@BUILD_LOAD@"; +const char PROP_TEST[] = "@BUILD_TESTING@"; #endif /* VERSION_H */