From 5be3f9246bbda212c5d53895d81a92ecb3bcd273 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Mon, 2 Nov 2015 09:53:49 +0300 Subject: [PATCH 01/17] try use travis ci again --- .travis.yml.bckp => .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) rename .travis.yml.bckp => .travis.yml (83%) diff --git a/.travis.yml.bckp b/.travis.yml similarity index 83% rename from .travis.yml.bckp rename to .travis.yml index 33c3dac..1157113 100644 --- a/.travis.yml.bckp +++ b/.travis.yml @@ -1,7 +1,10 @@ +sudo: required +dist: trusty + install: + - sudo apt-add-repository ppa:kubuntu-ppa/next - sudo apt-get update -qq - sudo apt-get install -y cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev - - git submobule update --init - rm -rf build - mkdir build From c24e41d5579e9dab286a6d2faaf6968f1030a09c Mon Sep 17 00:00:00 2001 From: arcan1s Date: Mon, 2 Nov 2015 09:56:48 +0300 Subject: [PATCH 02/17] edit adding repo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1157113..18363a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: required dist: trusty install: - - sudo apt-add-repository ppa:kubuntu-ppa/next + - sudo apt-add-repository -r ppa:kubuntu-ppa/next - sudo apt-get update -qq - sudo apt-get install -y cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev - rm -rf build From aece0e2effba22b37b0a218d881a5ac53068592c Mon Sep 17 00:00:00 2001 From: arcan1s Date: Mon, 2 Nov 2015 10:06:20 +0300 Subject: [PATCH 03/17] rename ppa accoring to pkgs.org search --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 18363a4..64a3d9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: required dist: trusty install: - - sudo apt-add-repository -r ppa:kubuntu-ppa/next + - sudo apt-add-repository ppa:kubuntu-ppa/backports - sudo apt-get update -qq - sudo apt-get install -y cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev - rm -rf build From 02305b93d974ed50832608029b7fd66a828e1714 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Mon, 2 Nov 2015 10:10:11 +0300 Subject: [PATCH 04/17] skip asking --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 64a3d9d..642c62a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: required dist: trusty install: - - sudo apt-add-repository ppa:kubuntu-ppa/backports + - sudo apt-add-repository -y ppa:kubuntu-ppa/backports - sudo apt-get update -qq - sudo apt-get install -y cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev - rm -rf build From 2c1aa1a4c998f13ad51257fdc3c5efc80571dede Mon Sep 17 00:00:00 2001 From: arcan1s Date: Tue, 3 Nov 2015 04:40:00 +0300 Subject: [PATCH 05/17] add dist upgrade before --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 642c62a..384cc7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ dist: trusty install: - sudo apt-add-repository -y ppa:kubuntu-ppa/backports - sudo apt-get update -qq + - sudo apt-get dist-upgrade - sudo apt-get install -y cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev - rm -rf build - mkdir build From 809936a5632aae11f56f90472d3127178204f1c5 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Tue, 3 Nov 2015 04:41:56 +0300 Subject: [PATCH 06/17] add --yes --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 384cc7e..93ce4c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ dist: trusty install: - sudo apt-add-repository -y ppa:kubuntu-ppa/backports - sudo apt-get update -qq - - sudo apt-get dist-upgrade + - sudo apt-get dist-upgrade -y - sudo apt-get install -y cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev - rm -rf build - mkdir build From d8d2311621fa5e02679ca82b85939f0208e2a0b1 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Tue, 3 Nov 2015 04:51:19 +0300 Subject: [PATCH 07/17] edit dpkg options --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 93ce4c8..a2047b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,8 @@ dist: trusty install: - sudo apt-add-repository -y ppa:kubuntu-ppa/backports - sudo apt-get update -qq - - sudo apt-get dist-upgrade -y - - sudo apt-get install -y cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev + - sudo apt-get -y -q -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew dist-upgrade + - sudo apt-get install -y -q cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev - rm -rf build - mkdir build From 4b679ff570cb8a9ad35d0be127d8b5c20810ee27 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Thu, 28 Jan 2016 12:44:45 +0300 Subject: [PATCH 08/17] fix #74 Unfortunately there is no good way to resize tooptip dynamically if html image is used. In other hand if tooltip type set to "names" it is possible to resize tooptips to content size. + update gitignore --- .gitignore | 1 + sources/desktop-panel/package/contents/ui/main.qml | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9561581..9a0d19c 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ build *pkg.tar.[gx]z src pkg +*.deb # clion settings .idea diff --git a/sources/desktop-panel/package/contents/ui/main.qml b/sources/desktop-panel/package/contents/ui/main.qml index 684f05a..20f8732 100644 --- a/sources/desktop-panel/package/contents/ui/main.qml +++ b/sources/desktop-panel/package/contents/ui/main.qml @@ -113,7 +113,7 @@ Item { for (var i=0; i Date: Fri, 29 Jan 2016 01:31:00 +0700 Subject: [PATCH 09/17] fix #73 I suppose the better way is to move weather adaptor to another open weather engine despite the fact that OWM has provided me a special FOSS permissions. I've changed weather provider to Yahoo! Weather because there is no good way to provide my own API key to end-users except for being compiled to the source code. In other hand this solution leads to the fact that humidity and atmosphere pressure is not available for forecast more. And moreover pressure units has been changed for current weather. + fix possible memory leak in dataengine aggregator + add "special thanks" group to acknoledgment tab --- .../package/contents/ui/about.qml | 11 +- sources/awesome-widget/plugin/awactions.cpp | 8 + .../plugin/awdataengineaggregator.cpp | 11 +- .../plugin/awdataengineaggregator.h | 2 + .../awesomewidgets-extweather-ids.json | 226 ++++++++---------- sources/awesomewidgets/extquotes.cpp | 3 +- sources/awesomewidgets/extquotes.h | 4 +- sources/awesomewidgets/extweather.cpp | 91 ++++--- sources/awesomewidgets/extweather.h | 13 +- sources/awesomewidgets/weather/0.gif | Bin 0 -> 2694 bytes sources/awesomewidgets/weather/01d.png | Bin 2859 -> 0 bytes sources/awesomewidgets/weather/02d.png | Bin 2969 -> 0 bytes sources/awesomewidgets/weather/03d.png | Bin 2565 -> 0 bytes sources/awesomewidgets/weather/04d.png | Bin 2773 -> 0 bytes sources/awesomewidgets/weather/09d.png | Bin 3818 -> 0 bytes sources/awesomewidgets/weather/1.gif | Bin 0 -> 2477 bytes sources/awesomewidgets/weather/10.gif | Bin 0 -> 2465 bytes sources/awesomewidgets/weather/10d.png | Bin 3793 -> 0 bytes sources/awesomewidgets/weather/11.gif | Bin 0 -> 2336 bytes sources/awesomewidgets/weather/11d.png | Bin 3777 -> 0 bytes sources/awesomewidgets/weather/12.gif | Bin 0 -> 2358 bytes sources/awesomewidgets/weather/13.gif | Bin 0 -> 2004 bytes sources/awesomewidgets/weather/13d.png | Bin 3901 -> 0 bytes sources/awesomewidgets/weather/14.gif | Bin 0 -> 2251 bytes sources/awesomewidgets/weather/15.gif | Bin 0 -> 1834 bytes sources/awesomewidgets/weather/16.gif | Bin 0 -> 2483 bytes sources/awesomewidgets/weather/17.gif | Bin 0 -> 2694 bytes sources/awesomewidgets/weather/18.gif | Bin 0 -> 2459 bytes sources/awesomewidgets/weather/19.gif | Bin 0 -> 2066 bytes sources/awesomewidgets/weather/2.gif | Bin 0 -> 2477 bytes sources/awesomewidgets/weather/20.gif | Bin 0 -> 1858 bytes sources/awesomewidgets/weather/21.gif | Bin 0 -> 2102 bytes sources/awesomewidgets/weather/22.gif | Bin 0 -> 2182 bytes sources/awesomewidgets/weather/23.gif | Bin 0 -> 1857 bytes sources/awesomewidgets/weather/24.gif | Bin 0 -> 1857 bytes sources/awesomewidgets/weather/25.gif | Bin 0 -> 2034 bytes sources/awesomewidgets/weather/26.gif | Bin 0 -> 2127 bytes sources/awesomewidgets/weather/27.gif | Bin 0 -> 2777 bytes sources/awesomewidgets/weather/28.gif | Bin 0 -> 2675 bytes sources/awesomewidgets/weather/29.gif | Bin 0 -> 2443 bytes sources/awesomewidgets/weather/3.gif | Bin 0 -> 2694 bytes sources/awesomewidgets/weather/30.gif | Bin 0 -> 2480 bytes sources/awesomewidgets/weather/31.gif | Bin 0 -> 2764 bytes sources/awesomewidgets/weather/32.gif | Bin 0 -> 2389 bytes sources/awesomewidgets/weather/3200.gif | Bin 0 -> 2117 bytes sources/awesomewidgets/weather/33.gif | Bin 0 -> 2874 bytes sources/awesomewidgets/weather/34.gif | Bin 0 -> 2417 bytes sources/awesomewidgets/weather/35.gif | Bin 0 -> 2694 bytes sources/awesomewidgets/weather/36.gif | Bin 0 -> 2424 bytes sources/awesomewidgets/weather/37.gif | Bin 0 -> 2400 bytes sources/awesomewidgets/weather/38.gif | Bin 0 -> 2400 bytes sources/awesomewidgets/weather/39.gif | Bin 0 -> 2358 bytes sources/awesomewidgets/weather/4.gif | Bin 0 -> 2694 bytes sources/awesomewidgets/weather/40.gif | Bin 0 -> 2358 bytes sources/awesomewidgets/weather/41.gif | Bin 0 -> 2483 bytes sources/awesomewidgets/weather/42.gif | Bin 0 -> 2483 bytes sources/awesomewidgets/weather/43.gif | Bin 0 -> 2789 bytes sources/awesomewidgets/weather/44.gif | Bin 0 -> 2480 bytes sources/awesomewidgets/weather/45.gif | Bin 0 -> 980 bytes sources/awesomewidgets/weather/46.gif | Bin 0 -> 996 bytes sources/awesomewidgets/weather/47.gif | Bin 0 -> 972 bytes sources/awesomewidgets/weather/5.gif | Bin 0 -> 2393 bytes sources/awesomewidgets/weather/50d.png | Bin 3328 -> 0 bytes sources/awesomewidgets/weather/6.gif | Bin 0 -> 2459 bytes sources/awesomewidgets/weather/7.gif | Bin 0 -> 2523 bytes sources/awesomewidgets/weather/8.gif | Bin 0 -> 2145 bytes sources/awesomewidgets/weather/9.gif | Bin 0 -> 2041 bytes .../package/contents/ui/about.qml | 11 +- sources/desktop-panel/plugin/dpadds.cpp | 8 + sources/extsysmon/sources/weathersource.cpp | 12 +- sources/translations/awesome-widgets.pot | 59 ++--- sources/translations/en.po | 63 ++--- sources/translations/es.po | 63 ++--- sources/translations/fr.po | 59 ++--- sources/translations/nl.po | 61 ++--- sources/translations/pt_BR.po | 61 ++--- sources/translations/ru.po | 63 ++--- sources/translations/uk.po | 65 ++--- sources/translations/zh.po | 59 ++--- sources/version.h.in | 1 + 80 files changed, 497 insertions(+), 457 deletions(-) create mode 100644 sources/awesomewidgets/weather/0.gif delete mode 100644 sources/awesomewidgets/weather/01d.png delete mode 100644 sources/awesomewidgets/weather/02d.png delete mode 100644 sources/awesomewidgets/weather/03d.png delete mode 100644 sources/awesomewidgets/weather/04d.png delete mode 100644 sources/awesomewidgets/weather/09d.png create mode 100644 sources/awesomewidgets/weather/1.gif create mode 100644 sources/awesomewidgets/weather/10.gif delete mode 100644 sources/awesomewidgets/weather/10d.png create mode 100644 sources/awesomewidgets/weather/11.gif delete mode 100644 sources/awesomewidgets/weather/11d.png create mode 100644 sources/awesomewidgets/weather/12.gif create mode 100644 sources/awesomewidgets/weather/13.gif delete mode 100644 sources/awesomewidgets/weather/13d.png create mode 100644 sources/awesomewidgets/weather/14.gif create mode 100644 sources/awesomewidgets/weather/15.gif create mode 100644 sources/awesomewidgets/weather/16.gif create mode 100644 sources/awesomewidgets/weather/17.gif create mode 100644 sources/awesomewidgets/weather/18.gif create mode 100644 sources/awesomewidgets/weather/19.gif create mode 100644 sources/awesomewidgets/weather/2.gif create mode 100644 sources/awesomewidgets/weather/20.gif create mode 100644 sources/awesomewidgets/weather/21.gif create mode 100644 sources/awesomewidgets/weather/22.gif create mode 100644 sources/awesomewidgets/weather/23.gif create mode 100644 sources/awesomewidgets/weather/24.gif create mode 100644 sources/awesomewidgets/weather/25.gif create mode 100644 sources/awesomewidgets/weather/26.gif create mode 100644 sources/awesomewidgets/weather/27.gif create mode 100644 sources/awesomewidgets/weather/28.gif create mode 100644 sources/awesomewidgets/weather/29.gif create mode 100644 sources/awesomewidgets/weather/3.gif create mode 100644 sources/awesomewidgets/weather/30.gif create mode 100644 sources/awesomewidgets/weather/31.gif create mode 100644 sources/awesomewidgets/weather/32.gif create mode 100644 sources/awesomewidgets/weather/3200.gif create mode 100644 sources/awesomewidgets/weather/33.gif create mode 100644 sources/awesomewidgets/weather/34.gif create mode 100644 sources/awesomewidgets/weather/35.gif create mode 100644 sources/awesomewidgets/weather/36.gif create mode 100644 sources/awesomewidgets/weather/37.gif create mode 100644 sources/awesomewidgets/weather/38.gif create mode 100644 sources/awesomewidgets/weather/39.gif create mode 100644 sources/awesomewidgets/weather/4.gif create mode 100644 sources/awesomewidgets/weather/40.gif create mode 100644 sources/awesomewidgets/weather/41.gif create mode 100644 sources/awesomewidgets/weather/42.gif create mode 100644 sources/awesomewidgets/weather/43.gif create mode 100644 sources/awesomewidgets/weather/44.gif create mode 100644 sources/awesomewidgets/weather/45.gif create mode 100644 sources/awesomewidgets/weather/46.gif create mode 100644 sources/awesomewidgets/weather/47.gif create mode 100644 sources/awesomewidgets/weather/5.gif delete mode 100644 sources/awesomewidgets/weather/50d.png create mode 100644 sources/awesomewidgets/weather/6.gif create mode 100644 sources/awesomewidgets/weather/7.gif create mode 100644 sources/awesomewidgets/weather/8.gif create mode 100644 sources/awesomewidgets/weather/9.gif diff --git a/sources/awesome-widget/package/contents/ui/about.qml b/sources/awesome-widget/package/contents/ui/about.qml index 0440de8..6cde341 100644 --- a/sources/awesome-widget/package/contents/ui/about.qml +++ b/sources/awesome-widget/package/contents/ui/about.qml @@ -97,6 +97,15 @@ Item { 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 @@ -104,7 +113,7 @@ Item { horizontalAlignment: Text.AlignJustify verticalAlignment: Text.AlignTop textFormat: Text.RichText - text: awActions.getAboutText("3rdparty") + text: awActions.getAboutText("thanks") onLinkActivated: Qt.openUrlExternally(link); } } diff --git a/sources/awesome-widget/plugin/awactions.cpp b/sources/awesome-widget/plugin/awactions.cpp index 6a181c5..399219b 100644 --- a/sources/awesome-widget/plugin/awactions.cpp +++ b/sources/awesome-widget/plugin/awactions.cpp @@ -144,6 +144,14 @@ QString AWActions::getAboutText(const QString type) const .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; diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.cpp b/sources/awesome-widget/plugin/awdataengineaggregator.cpp index eeb7e44..1e313f7 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataengineaggregator.cpp @@ -17,8 +17,6 @@ #include "awdataengineaggregator.h" -#include - #include "awdebug.h" #include "awkeys.h" @@ -41,6 +39,7 @@ AWDataEngineAggregator::~AWDataEngineAggregator() // disconnect sources first disconnectSources(); m_dataEngines.clear(); + delete m_consumer; } @@ -84,12 +83,12 @@ void AWDataEngineAggregator::reconnectSources() void AWDataEngineAggregator::initDataEngines() { - Plasma::DataEngineConsumer *deConsumer = new Plasma::DataEngineConsumer(); + m_consumer = new Plasma::DataEngineConsumer(); m_dataEngines[QString("systemmonitor")] - = deConsumer->dataEngine(QString("systemmonitor")); + = m_consumer->dataEngine(QString("systemmonitor")); m_dataEngines[QString("extsysmon")] - = deConsumer->dataEngine(QString("extsysmon")); - m_dataEngines[QString("time")] = deConsumer->dataEngine(QString("time")); + = m_consumer->dataEngine(QString("extsysmon")); + m_dataEngines[QString("time")] = m_consumer->dataEngine(QString("time")); // additional method required by systemmonitor structure connect(m_dataEngines[QString("systemmonitor")], diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.h b/sources/awesome-widget/plugin/awdataengineaggregator.h index 5a86ab6..1f030b2 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.h +++ b/sources/awesome-widget/plugin/awdataengineaggregator.h @@ -20,6 +20,7 @@ #define AWDATAENGINEAGGREGATOR_H #include +#include #include @@ -43,6 +44,7 @@ public slots: private: void initDataEngines(); + Plasma::DataEngineConsumer *m_consumer = nullptr; QHash m_dataEngines; int m_interval; }; diff --git a/sources/awesomewidgets/awesomewidgets-extweather-ids.json b/sources/awesomewidgets/awesomewidgets-extweather-ids.json index 094ce99..69f9085 100644 --- a/sources/awesomewidgets/awesomewidgets-extweather-ids.json +++ b/sources/awesomewidgets/awesomewidgets-extweather-ids.json @@ -1,139 +1,113 @@ { - "__url": "http://openweathermap.org/weather-conditions", + "__url": "https://developer.yahoo.com/weather/documentation.html", "image": { "__comment": "should be described as html image with full path inside", - "default": "", + "default": "", - "800": "", - - "801": "", - - "802": "", - "803": "", - - "804": "", - - "300": "", - "301": "", - "302": "", - "310": "", - "311": "", - "312": "", - "313": "", - "314": "", - "321": "", - "520": "", - "521": "", - "522": "", - "531": "", - - "500": "", - "501": "", - "502": "", - "503": "", - "504": "", - - "200": "", - "201": "", - "202": "", - "210": "", - "211": "", - "212": "", - "221": "", - "230": "", - "231": "", - "232": "", - - "511": "", - "600": "", - "601": "", - "602": "", - "611": "", - "612": "", - "615": "", - "616": "", - "620": "", - "621": "", - "622": "", - - "701": "", - "711": "", - "721": "", - "731": "", - "741": "", - "751": "", - "761": "", - "762": "", - "771": "", - "781": "" + "0": "", + "1": "", + "2": "", + "3": "", + "4": "", + "5": "", + "6": "", + "7": "", + "8": "", + "9": "", + "10": "", + "11": "", + "12": "", + "13": "", + "14": "", + "15": "", + "16": "", + "17": "", + "18": "", + "19": "", + "20": "", + "21": "", + "22": "", + "23": "", + "24": "", + "25": "", + "26": "", + "27": "", + "28": "", + "29": "", + "30": "", + "31": "", + "32": "", + "33": "", + "34": "", + "35": "", + "36": "", + "37": "", + "38": "", + "39": "", + "40": "", + "41": "", + "42": "", + "43": "", + "44": "", + "45": "", + "46": "", + "47": "", + "3200": "" }, "text": { "default": "\u2604", + "3200": "\u2604", - "800": "\u2600", - - "801": "\u26C5", - - "802": "\u2601", - "803": "\u2601", - - "804": "\u2601", - - "300": "\u2602", - "301": "\u2602", - "302": "\u2602", - "310": "\u2602", - "311": "\u2602", - "312": "\u2602", - "313": "\u2602", - "314": "\u2602", - "321": "\u2602", - "520": "\u2602", - "521": "\u2602", - "522": "\u2602", - "531": "\u2602", - - "500": "\u2614", - "501": "\u2614", - "502": "\u2614", - "503": "\u2614", - "504": "\u2614", - - "200": "\u2608", - "201": "\u2608", - "202": "\u2608", - "210": "\u2608", - "211": "\u2608", - "212": "\u2608", - "221": "\u2608", - "230": "\u2608", - "231": "\u2608", - "232": "\u2608", - - "511": "\u2603", - "600": "\u2603", - "601": "\u2603", - "602": "\u2603", - "611": "\u2603", - "612": "\u2603", - "615": "\u2603", - "616": "\u2603", - "620": "\u2603", - "621": "\u2603", - "622": "\u2603", - - "701": "\u26C5", - "711": "\u26C5", - "721": "\u26C5", - "731": "\u26C5", - "741": "\u26C5", - "751": "\u26C5", - "761": "\u26C5", - "762": "\u26C5", - "771": "\u26C5", - "781": "\u26C5" + "0": "\u2604", + "1": "\u2604", + "2": "\u2604", + "3": "\u26C8", + "4": "\u26C8", + "5": "\u2614", + "6": "\u2614", + "7": "\u2614", + "8": "\u2614", + "9": "\u2614", + "10": "\u2614", + "11": "\u2614", + "12": "\u2614", + "13": "\u26C4", + "14": "\u26C7", + "15": "\u26C7", + "16": "\u2614", + "17": "\u2614", + "18": "\u2614", + "19": "\u26C5", + "20": "\u26C5", + "21": "\u26C5", + "22": "\u26C5", + "23": "\u26C5", + "24": "\u26C5", + "25": "\u26C5", + "26": "\u2601", + "27": "\u2601", + "28": "\u2601", + "29": "\u2601", + "30": "\u2601", + "31": "\u263D", + "32": "\u2600", + "33": "\u263D", + "34": "\u2600", + "35": "\u2614", + "36": "\u2600", + "37": "\u26C8", + "38": "\u26C8", + "39": "\u26C8", + "40": "\u26C7", + "41": "\u26C7", + "42": "\u26C7", + "43": "\u26C7", + "44": "\u2601", + "45": "\u26C8", + "46": "\u26C7", + "47": "\u26C8" } } diff --git a/sources/awesomewidgets/extquotes.cpp b/sources/awesomewidgets/extquotes.cpp index dc26994..5a7f326 100644 --- a/sources/awesomewidgets/extquotes.cpp +++ b/sources/awesomewidgets/extquotes.cpp @@ -279,8 +279,7 @@ get quotes for the instrument. Refer to \ QString ExtQuotes::url() const { - QString apiUrl = QString(YAHOO_URL); - apiUrl.replace(QString("$TICKER"), m_ticker); + QString apiUrl = QString(YAHOO_QUOTES_URL).arg(m_ticker); qCInfo(LOG_LIB) << "API url" << apiUrl; return apiUrl; diff --git a/sources/awesomewidgets/extquotes.h b/sources/awesomewidgets/extquotes.h index c271b8c..0c16351 100644 --- a/sources/awesomewidgets/extquotes.h +++ b/sources/awesomewidgets/extquotes.h @@ -22,10 +22,10 @@ #include "abstractextitem.h" -#define YAHOO_URL \ +#define YAHOO_QUOTES_URL \ "https://query.yahooapis.com/v1/public/yql?q=select * from " \ "yahoo.finance.quotes where " \ - "symbol=\"$TICKER\"&env=store://datatables.org/" \ + "symbol=\"%1\"&env=store://datatables.org/" \ "alltableswithkeys&format=json" diff --git a/sources/awesomewidgets/extweather.cpp b/sources/awesomewidgets/extweather.cpp index 6245af4..d6342fa 100644 --- a/sources/awesomewidgets/extweather.cpp +++ b/sources/awesomewidgets/extweather.cpp @@ -235,9 +235,8 @@ QVariantHash ExtWeather::run() if (times == 1) { qCInfo(LOG_LIB) << "Send request"; isRunning = true; - QNetworkReply *reply - = manager->get(QNetworkRequest(QUrl(url(m_ts != 0)))); - new QReplyTimeout(reply, 1000); + QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url()))); + new QReplyTimeout(reply, 5000); } // update value @@ -319,51 +318,52 @@ void ExtWeather::weatherReplyReceived(QNetworkReply *reply) } // convert to map - QVariantMap json = jsonDoc.toVariant().toMap(); - if (json[QString("cod")].toInt() != 200) { - qCWarning(LOG_LIB) << "Invalid OpenWeatherMap return code" - << json[QString("cod")].toInt(); + QVariantMap json = jsonDoc.toVariant().toMap()[QString("query")].toMap(); + if (json[QString("count")].toInt() != 1) { + qCWarning(LOG_LIB) << "Found data count" + << json[QString("count")].toInt() << "is not 1"; return; } + QVariantMap results + = json[QString("results")].toMap()[QString("channel")].toMap(); + QVariantMap item = results[QString("item")].toMap(); - QVariantHash data; if (m_ts == 0) { - data = parseSingleJson(json); + // current weather + int id = item[QString("condition")].toMap()[QString("code")].toInt(); + values[tag(QString("weatherId"))] = id; + values[tag(QString("weather"))] = weatherFromInt(id); + values[tag(QString("temperature"))] + = item[QString("condition")].toMap()[QString("temp")].toInt(); + values[tag(QString("timestamp"))] + = item[QString("condition")].toMap()[QString("date")].toString(); + values[tag(QString("humidity"))] = results[QString("atmosphere")] + .toMap()[QString("humidity")] + .toInt(); + values[tag(QString("pressure"))] + = static_cast(results[QString("atmosphere")] + .toMap()[QString("pressure")] + .toFloat()); } else { - QVariantList list = json[QString("list")].toList(); - data = parseSingleJson(list.count() <= m_ts ? list.at(m_ts - 1).toMap() - : list.last().toMap()); + // forecast weather + QVariantList weatherList = item[QString("forecast")].toList(); + QVariantMap weatherMap = weatherList.count() < m_ts + ? weatherList.last().toMap() + : weatherList.at(m_ts).toMap(); + int id = weatherMap[QString("code")].toInt(); + values[tag(QString("weatherId"))] = id; + values[tag(QString("weather"))] = weatherFromInt(id); + values[tag(QString("timestamp"))] + = weatherMap[QString("date")].toString(); + // yahoo provides high and low temperatures. Lets calculate average one + values[tag(QString("temperature"))] + = (weatherMap[QString("high")].toFloat() + + weatherMap[QString("low")].toFloat()) + / 2.0; + // ... and no forecast data for humidity and pressure + values[tag(QString("humidity"))] = 0; + values[tag(QString("pressure"))] = 0.0; } - foreach (QString key, data.keys()) - values[tag(key)] = data[key]; -} - - -QVariantHash ExtWeather::parseSingleJson(const QVariantMap json) const -{ - qCDebug(LOG_LIB) << "Single json data" << json; - - QVariantHash output; - - // weather status - QVariantList weather = json[QString("weather")].toList(); - if (!weather.isEmpty()) { - int _id = weather.first().toMap()[QString("id")].toInt(); - output[QString("weatherId")] = _id; - output[QString("weather")] = weatherFromInt(_id); - } - - // main data - QVariantMap mainWeather = json[QString("main")].toMap(); - if (!weather.isEmpty()) { - output[QString("humidity")] - = mainWeather[QString("humidity")].toFloat(); - output[QString("pressure")] - = mainWeather[QString("pressure")].toFloat(); - output[QString("temperature")] = mainWeather[QString("temp")].toFloat(); - } - - return output; } @@ -381,13 +381,10 @@ void ExtWeather::translate() } -QString ExtWeather::url(const bool isForecast) const +QString ExtWeather::url() const { - qCDebug(LOG_LIB) << "Is forecast" << isForecast; - QString apiUrl = isForecast ? QString(OWM_FORECAST_URL) : QString(OWM_URL); - apiUrl.replace(QString("$CITY"), m_city); - apiUrl.replace(QString("$COUNTRY"), m_country); + QString apiUrl = QString(YAHOO_WEATHER_URL).arg(m_city).arg(m_country); qCInfo(LOG_LIB) << "API url" << apiUrl; return apiUrl; diff --git a/sources/awesomewidgets/extweather.h b/sources/awesomewidgets/extweather.h index 0639314..eafac3e 100644 --- a/sources/awesomewidgets/extweather.h +++ b/sources/awesomewidgets/extweather.h @@ -22,12 +22,10 @@ #include "abstractextitem.h" -#define OWM_URL \ - "http://api.openweathermap.org/data/2.5/" \ - "weather?q=$CITY,$COUNTRY&units=metric" -#define OWM_FORECAST_URL \ - "http://api.openweathermap.org/data/2.5/" \ - "forecast?q=$CITY,$COUNTRY&units=metric" +#define YAHOO_WEATHER_URL \ + "https://query.yahooapis.com/v1/public/yql?format=json&q=select * from " \ + "weather.forecast where u='c' and woeid in (select woeid from " \ + "geo.places(1) where text='%1, %2')" namespace Ui @@ -76,9 +74,8 @@ private: QNetworkAccessManager *manager; bool isRunning = false; Ui::ExtWeather *ui; - QVariantHash parseSingleJson(const QVariantMap json) const; void translate(); - QString url(const bool isForecast = false) const; + QString url() const; // properties QString m_city = QString("London"); QString m_country = QString("uk"); diff --git a/sources/awesomewidgets/weather/0.gif b/sources/awesomewidgets/weather/0.gif new file mode 100644 index 0000000000000000000000000000000000000000..7db05801e7664c41adf44f68d600e163de0ec43d GIT binary patch literal 2694 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/01d.png b/sources/awesomewidgets/weather/01d.png deleted file mode 100644 index 7d2f792c324408eaccb8a13e0cd16fd502dd51cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2859 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 diff --git a/sources/awesomewidgets/weather/03d.png b/sources/awesomewidgets/weather/03d.png deleted file mode 100644 index 8a4a8e9fa75b5b860ff33f84cd6bf65a9ad04e54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2565 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-&H|6fVg?3oVGw3ym^DX&fq~U0 zGbExU!q>+tIX_n~F(p4KRj(qq0H~UQ!KT6r$jnVGNmQuF&B-gas<2f8tFQvHLBje< z3ScEA*|tg%z5xo(`9-M;rh0~YMoM;E3JMA~MJZ`kK`w4k?LeNbQbtKhft9{~d3m{B zxv^e;QM$gNrKP35fswwEkuFe$ZgFK^Nn(X=Ua>O75STeGsl~}fnFS@8`FRQ;a}$&D zOG|8(lt3220o0wj1#pYv;5=hU{aFdS+1b8CnV*`x_BM_jXmG!D8x zRw`Az%UZayTWQM$*YHIwE*yEH7h^R&7Oqp7-Ozo>EAy?B$R$2Eb=9LsQWl;~ne#pE z-u~w{dp*S-SLeSwb6DtJ>&)_<_V;b?|2${;y{PZ;gufSl{B>ZmbaDBY@8#Cz($(^$ zQDci!k&bcB5{}KUoo?;O7ZKe3Kq0TR^lNa%=D8bnt8bNch;(=EmuxGZE%3R2;zYr< z-044@3g+5K&A0jaJVWVNyqL?wB`ThUr?+)JzR~iWHEGter#H^kCRvJmA6|ODR`+EA zqw&P4Q>VV1A+mq&xi4ZD+4>&eo5j?hDSaYhnrlU$`l?lV=3AeIA3l88zBFU?^D;Fh z0WbN^JwLkVO!Yp{(6Q)&kfYHGgMT>z#|?PO_bfE~XRQ1A$b$zDlKr!-W~7{*nE!N6 zjMHJoB^?THgdC$Mu>32KQR;c}X=lvdxc}=mMOdoKiP^Jl^>PSmSo-?$ZN_j%WrUkDLhHDTTB^`*Z5xjAZ-x{_pyIyAbHBDa;M zW@o>?_T)Q+wFX7{8-Q8`odn%YJUTv83SPWmAQ!`Hx;$?AkEN z>C=shMs=nyroQU6wLg>BpIBXNP;+%|$`9@(CoWwIGP^nXkK?&i|F2(EVnj3Iwp6RB zwuJIN;yP{OV6kLj=K0rKZ;6C#fBrV<(JzOt6PZ7Q_UYGiy}IbqD(YtzLmaT&YHJ}=F!w>LHWw(IJ@y~+DrR$aYi{&7bMufBN> zn@Z;PjsWKg9C3>#H0LP>NNWkS7;^02wJ0QO>)V^1ot^F_wX4^^Uo3df*WG|;!<9#g zb)5HJ3G6rQdma;WMw};JrDeL#wh%4TB87=N0wZI3svrJ%#-Z{wnB_qCd4m#j$Gr^J za~D5sJIe6eYD%`I*#Df}{~vfB*!SD6CSK`k)>pZfAltcq%Qu7^QhiqSzP4d*-({so z`}j7jVpM$NJ?X-iL*G=5OiV)J;^Ou(Z<_C_P{Fcm-Y2HF$7F;K&1cZhJZy43^lId% zLtj;yX20FKbt|_+0#C#84~iappRwNQwLIf~Mx5hywz0AC>$n;FLc8yu4fI#zZBZIPPNqB_1>Gr5@}PN&FZ!qgu)J&=)=KZ~FqD@Jdej{z~6x Rf*Poy=IQF^vd$@?2>@Ou)Or8_ diff --git a/sources/awesomewidgets/weather/04d.png b/sources/awesomewidgets/weather/04d.png deleted file mode 100644 index 4677b8596acb4bed4fc8c62633e673567e8af6db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2773 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 diff --git a/sources/awesomewidgets/weather/1.gif b/sources/awesomewidgets/weather/1.gif new file mode 100644 index 0000000000000000000000000000000000000000..bdf5a7ab987199700cff06b5edc63a5ea19b5de9 GIT binary patch literal 2477 zcmWmDk3Z9iAHea?ewdA6TULu)^P|qUADW-3#5NK_%OSab40WhzeqBq{KHD&s8i|F| z{QRbzrXAKd5BHgwR%pvqirgsbG(C3ZTj{uceV_lq`^RfE%)vdqE?sneaNe_vL zI$C?9rMI`YzP|p;moLS|#S04ykA}4QT;cWV>ee|UxA1c4PbYKFool{*H~+$gYuB!| zwzm52qR-9EB_*ddPklI@o~=|pT3lQ_m(Tkh>ihQX+o7W;KYaLb{g%vNFyx%$1qFv) zSKG6gB6b+8V$H)Kq=bsgo z)#3YN&t9z_9v;5m+jk)5a9U>GiPW6v_|!wZqVkE?E6OFmR;oriWL=&2dUJAePMkQw zFR2jJG*-QNpPZgMF)>kBS6AJq%go5s>-BQEe0+TTKx|^`w|{Eif9&k+eDL5w%#SB{ zJYHgAQv1TP>!vNSv9TQ{Q+j&(_{WKya6M|989Sy?)r?qpr# z;PB(B>P9zDZ>{!83cEm~(L^1Hs%~sLn#9Wdnfv0!3x!g(X{$$fclVH1$Ki0o_Q(6} z_CIy%bZl_02aldPY>7 zbkTHY(Ug#!Jvcacz2+D19lP$|zn_9iX0y+qKcAa-F)LSahF_E|EWOyP5)=tnl$Kt)R9Y$$iOR2( zi>t&H;u|$JHDGf~RoA_?wzk%`w)z%n#~oRB*S(&ep8xdxF7E2D?0(oFgE)}-m*Mf! zXRpe}UUflz4KMz=c=XW$&(t`HW_v{Rfa(AP^ zC+7jjMI;OWOu!ak#s4b-&?}i>)`dtV3LbjZro(D!y|M`B99A3B(V!BNJWo!DDVzW& zl5Zsc`@jLhMss>ewtTOW5A!Yeb)9BHVf_DYL=v9OBdZ^yK-7gB75 zaUJ?88d4MK;!s;D8LM1aUl<)gbxG(bwYX-xg+*l>ne)!>n==hcG?`lLflhhjdlj_@ zZ=1R^N6w@3yll_nu=1p!GLo|jM+SIP+LB}jBuVI+VR8VffM2{}Z~xBiDzS>rXeJeS zp~Z)?Jm;^2qeCcH8pWy@+!@o7Q5<7f3wPOtzG=J!I||~D)#2%BuPwO_<1K&P;=Wls zmv%-RV`^2Ncp!@#M~&6|G(#1?e-9ZOh@5k6sk+1`>f{CsylYG}sKB9p1N*IG$kcxS zH3q2-TooP|M2sEF1mHy6RH6NL9DXnpl^=}s8ybUDJ{@wr5_W700dU4rl7v>X__A^$ zqMs1tbW9s%=?TdHy5zl;Nkwi$-W+`sz>j8e%+Prm)Gg1j#}P67+E5S$LHpR36t9Yc>rsKCundfSPl(Xw&hu1o{*U!(UUSoUsWZ? zqi8;DM!@Hmn!L}w2U%~KL_2Ou=@DX&HpOh4Cxae}bJ>!JcDtSea`E{$90f?o zE5jU*#Jj7Bd;IhO(g)4tVlcJ!d_shr3<2g93a&TU*RJSK4j*A7@nVUJT;iHhxM3e! z&&8avJstr+D3t`Fe4BtiWB{wdY*mE7(Zc%k7>IB*vXT&fW26cmX`dL1ww}!bom}*AOc0a6{YqQj$PgwOVDN@GF6l8D+;^Cc=i>O5 zUQ)iNn2K-{E38qF3zrFObMxhzbD2m&c%S(x3KHW%gFCCwpz!(v!ji##I6KbS}heV!zt`N z24LSCrvbizX8TeP`g;eNNl1anTU0c-1fq1(2LYc!jE4~h+x^uX8$1O%j8Vx!@?c^e zexI3i8Y5#5SlYp1-slAUVJU$6oN>uc{QQ~w5xDOdX5%3JjJ2xyAC`q&>}XG;;fx6b|5S&MuW(9 zfWvAICk@5C`W*`qoDq8etQ&Iuly4ChyIA1n2ikb)YyH(z#jagsizFk>J#4KIg@zGy za>XV*Ua0Xs4!@)35z{f;199a|rmqTDyQ$8L$9V`nb@sW>L&Rp1#GfLV+ZA?8l+Si{ zkhvCay2>#NbAel!qsqln;H{Z|MbDdk$O!vVYg2TTcTng9R* literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/10.gif b/sources/awesomewidgets/weather/10.gif new file mode 100644 index 0000000000000000000000000000000000000000..94673cb23d6710ebdc6f47744ecea5005719daea GIT binary patch literal 2465 zcmV;S310R`Nk%w1VKe|V0Qdg@ljZ;F>guxT{$!o{tgNhY$MSo7e8a`cgM)*#-SGea z|DL0(prx#JsQ!wIjGCRIjFX(PwY&EA_I-hilarL3oSl`Lqt@2dJ9qF;LZa`^Lt{iKN-OzQn=7!F+y!%HID~RaL#cy>fSiEH+ANlBfCk`L?*d($m#c zS!7*eY+GAgTZh=Xy1Lof*`lJNKz;N-Ktfk%d+`7NOifbO*Vto%l8c$5UwesGk^F_S z$fc>Sf}pR)$<2$Uv5t_FwYU_HRa|P@+}>nlZ6Yp4fQOMNDJ~-`JKWsd z4halTM@K$HQ%6{OOlo{*XJ=w)csXUjXn2@Sft^;Au}_=6Wq_=9h^uFquxz2cT8`;P zhyHe<=ZTM-gOHbkkeZj6nSzy|hMcF1pQ)FfrkbFso}QqWqNtjov6!&CsHdl|sHU^B zvaqwZy1c%htiqnP!JM$yu(rXhz~-*O$Fs-Lkjdnk!vCJz_^ZhMpyK_(!^z3X$ji*n z+uPgO+1%jZ;Kgnj{=;-9=?d$^82^>hU zpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+?cSRzk2>SO7zEKhmas!Zi#%@CPxbfTBa~) z@qmHKl?MH3VIktmf*Ksy-CA)$1q2}%a1xZjVowJKJPvTUKsC^X1JYeHXR3&oe@F52}J@~MKD-c~E!~%7g62SrQMIgd9Ul{O= z0CucGhX5Z~;!6&u$z1~h^^14%T3d~n4!E!RR7}-1bR&14<0_Wu!cM+ z@Q}kDvr?kO4bpTF#udd8bbt^=thPWE5lqkl1R`7z$OcnLGJz;M1TlvKi|k-SJqmE3 zi2_ETFh>i{C~$-U?6k1}D?xy8gq#A^L({3Irdk99H(c;u9se%jM;L=puz~{yRB*%; z?`iSwwg#-ARvR^R5JV85?4Y7Ri@3N)Cl+vU3p*Fg(SZu47;vnSUOK@B(H0p%7th`~TRw;Zv8 z0xM+mzy=a1pg=tbAOZ^r53JqE1YG-}10n`|{7(y}-T$zRBe&ebz!h{au|+4BEWtzI zw@guiKW9wwfEFTfKmh_r=u!y?EhwkqQG` zz!fWS0ua*RfB-N=0a)PT7>ppN3uxm4{_sZ>elSKO{9^;kfC3BjK@0i##}gPa zgDeohFAGtC2Tq`eyltQl#ZZ#doWM*3F!CQ4K!6Rj;13Br!5X*l$Uj_B4rUr)dJL&Y z5rQy=Bm9E{9)Q9Th9D4okl_!;%tt=zasLbVl;;yofC2$VArJ{5V+P{^WJ88l4++2n z1AMT7G$l|28#sUj{xAVDb}@vI_yZnj;6lanr34gsvLX7Q!Ut4Tk9eZUl-=9_4LVwn zMqr=^1n7z~-)P8zVCw=3O^5;-fd&v5K>`wp2L^1>3ry|<3mUMMK%~G3C}5%j67WJ4 z&@c-WaMK@9Wx+$%5CUyom%zz>e}r zV34~62@y2Fg)wkbAR}-NK_%b>LTnnq9jAN(8t_SgU>3w5_(;YW6X6PfctHyYAPz#P zTFhgfasy{T0Rq_3sctXPEULf$n;C6lk-rSN6-_{`&X701j|Q0s;U#q{nl; literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/10d.png b/sources/awesomewidgets/weather/10d.png deleted file mode 100644 index b1e1f8305ef7558bad0ab12e5298db59229d69a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3793 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 G1OPh?Q9P>v literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/11d.png b/sources/awesomewidgets/weather/11d.png deleted file mode 100644 index f3ce6541e2377910bee2e6c447835e3d686cee89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3777 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 diff --git a/sources/awesomewidgets/weather/12.gif b/sources/awesomewidgets/weather/12.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f412db624e1b8f7cf30bd7801598c41c391d553 GIT binary patch literal 2358 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/13.gif b/sources/awesomewidgets/weather/13.gif new file mode 100644 index 0000000000000000000000000000000000000000..4befd50f924385d433861eae3f77f9011ca92965 GIT binary patch literal 2004 zcmV;_2P^nTNk%w1VKe|V0Qdg@|NsBi*4ATVW45-onVGW2#>TzB(ygwo$;#c<+U4r( z^|`sZ@A3S_$=ao*tnKaX^7Z=q`ue`X)2ph%s;a8P!^6tW+4c4H+S=Om_xGGDAmi_(x-r?%}{r`c1fz8g|v$n=*X=>i#?d0e3`1=3z^Yf;p!rtKF_V)Jh^7`lJ z=fcL;nwp!ju*Tuy>fGGi;N$M6r>E@i_HAu#&CuMbs=oR8`JJA&$jaBHq`ZE9ezvyF zl98$8=I*_{yt%s3;o;%qk$5`~3dR(c-PH#?#g1(b3Vly2{Vb&$64t@(j*gJd&)d<`+Sisxz2lemG}Gp z-QVi6vdG@v-iC&T)Ys)%Sy}h^`=q3#*V*au^Y@{lp^=WNnw+wWiKW@y=(Dr6r>nWm z&f(kN>y?wOo}RM#`Tw1px82|E+uiDIY;)7o(`##N?(p^7-sh8*t&fhV#>w2g!Op9# zy_%V}j*O?x&CSWl$)KOO<>lr3{{L53SJ2SV>+9?M{QXZ)PhVePXJ=<d&1t*^JFqPwT3yrZJLrK7;7r@*JIxvZ?Yu&=PLu)wjgvb(#xtg6APt-!Fc z#Idr$vbDpvwZgZ$$GyJCv$V;$w#d7^%ecGDyuHo4z0tkB)xf~O!^O+W%F4>i&cMRb z#KqX%-QC^Y;n>^e)79$Q-Ra!n=;-I?$^82^>hU zpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+{m$`$BY3yoxAqnqeC78Fzm2Tq)WAOK(h&%`UB|JDdWfI#U{0Ap~pf*_&UhF}3$ zePp8r00^rPTEqenOJ0k9Q=_3e=HME~SOpI7SP=s!88{8#2;oG7h5`UMP6+xC&B=gN zb}%YgbeJvMSSiXFc=BYzgix_SNjlNXk0?K=P1v<~EdhkSY#{)GQ%1s*Bv}rRVSvB@ z6hU>&9K$87gV>4(6pSH*gYE1RR1Ki83P6E`3C^^YsAOQmv17W1RR5$FOP_)kM$*FB zUg89kwPRY0n6Szj0tV|#JUQl!Lj;Kr4Dbp7a3G<85G62@03!%AAi)Xpq)-AoPpnc0 z4JkmN2u=_X0ZJ~fyuibM3$fA;J`~_I1{^5tAcO=GG|<2k&UkhLDVsSniUG0oh!ZF& ztPl$vzZ_7&0IMB@QaY^2fdK$KgdzkNp&%em11Puw1r+?1V}LVD9FxT$S5?=55C90F zR16GE0|XBT4bXx=86*WjC`m};1_CXBqChFxKw-==5-5NGJ6WK4RcH_-AWsbau+@TQ zyd3a?K?AgfL@6i4gTOYXctg)x1fsCS9mnKzS(!NTV*v>y5dQ%Isq$n|2sXKtL=Xk_ z2tk7z+=QY41fkG?K#vee!VWmc43mTcvCQfh1fa+RiV)QtBZ>q$rEr30G}Mv~L3X4A zKnczqQvyY2pzvKXP-Fo|I5qr4&;SA8lpzEV$WsDzJ|A;O z5-G&Cs60Pp3kejcjPk(*>{K$ruS8_RPA67iU{DALod5Gp32iWez!W6&_rV<}t64%U z^MJyZgg;CG#Uqc@5zPz;zySvd?g-IMEv_7Jfk7zcVnqi6h_Q5h%Ph4N z803NQV=AV8IJI!Ufmhzy*>=fe3_v0tXO)DxYcy6eWaU0gKQ=EM&0=4~oGSxu^vi zE(H}dgdhND$VK}?-~&h0;sA>{zz~QS6CO0t3No;QAr?`KH5_07UbvqLE9in+gaC(P z@B#+_a0n}mYmWbTfdf_X04uDa2v(?t6J!QRHn>0zdd!6joN$N(zyy#Mgaro#a0C|w mAOMDV0Esa94<6W$6>tJ1LSjKhRl4$(u#BZFXStDp0027=x)Nmo literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/13d.png b/sources/awesomewidgets/weather/13d.png deleted file mode 100644 index 7b64a6cfd080465634c92f56e1eba8a5a3166c4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3901 zcmb_fdpOhkAD?SlF00A4V{~DuuVTbO#?M0I&|ca)|)W<|+XI5>6CPZS6N*R+H6V~^ z`^g5JP`c0?06=q4!pBfDivZ<>Qp1=i4n||u10{T3fngfZRTowWM#J0L4QfMUkfFu~ z2m_=B76^qx(F{@m${lC-Ib8UL(FkI(=qMPB&1M_04Gn0FKp4Wz%nSxc!jMRPp@%** zGK@vw=!Y>iKPCA)501Vhq81pkLAwL+0 zK!+g=;IJ>5g@I@xN0c*-L^ZBRdYP1c5 zOkmL%o-`U2>qg;_si7;cP^1Ce!1z<_*B+mP(XbU3U$I)1Y^9;^@c+k_MG5#v*Kg>q zSbpTYf}&g*6tYm~6*aL4H0%fLD~78!A9pg7MvYkYHxUZ*1NeP_4K0+;ATyaO1%x83 z`hSgm@BdGJuP_ShOHbdy-$!}>W5<4J>ud0Hz`rIonM3&>Vy{?!6nh0lt)2;Q93_+- z_DK&o8unieU(s8&+t8>qh6kNMBxAQ58ygCB{2u;3Vzrdd|0?yB;ola9MEo*x^auuZ zb+SoB7@0~IvSu-b${@ZSI}#Dapacf7n17%9PeZ(V`mLy}Z_&TUf=XH0B`7K(ED)o? z(I=4u2oY4423Ci-73wbBT?`ftVP;|ije_EYGa1Tc2{ktmPX4FgpGx^Q>nHTvVrbY8 zjs5q-^9dDhH!M&%<9}~TEU^9zRJe23{_2Rc@(hxg-o1|M@p2<}o?zZ|WHUZuTS1U@z{(#!{%1Wi3NX<$F zUh0t2imi~|(4MLup4%!IXlgRQk(u)=wY@-8H_N|%Nzk~w(1RIWxMQ}A(3TQK%f%j1 zvjjenSoH@-0t`loU#e2Sd1i4F|Nlu9-_q+SmmL>x#!(1qBCh=nnXkT>fye zD z4<1O?LeiB>%FAm&MRU`S*@hXZL4rhy)-ihbCCWh=$den6cRkT8lipnkWZm?!kHGl- z(Fp#-a#x%tjXG3|=nt;GdBG+TpbWUb{+hFHwrCxwce1;?8=|fwX1mk({#$@gy`oHX z?Od(pQ4iYASnZH{K?}QO+9v@9SUMGRM zqYhRlD*dG^VrhUhP4(z{KI``rEaF1~nz+x&5?=-egKfsfSqJPPYm0e`DtcB$(xzQA zqS6m{N{w%ssGUzvPA0Q>#_2qW`GKi8 z9mSthTM1|U5^}1a7J0vPklcTsS0BNLT3A3T&c@#XGm3BxaCU)Kx5MivXod2_UBAM5 zHiRnc+7~_hgWbDkVPe>Ad;5lmxJdSEk7l9@eApbZrM2hjQL5gCZM&{SZ`*wpaBXXT;p0n_UnNlyyLZL9HP+GLrgRwl9A?wx)Ai)C}Jl z=%98xZY~)wwWp(_BRWy*{(}di3K_j9Ggk+7rC^XfKE5iML1269DP)a}+zpba6yP$_ zlB$wbHE)ZzT9l)nj7yknmH3pDGh5n=56|>Iji0u4%+E3eOJ{f5|WOK}_!g=7uCdFx~oGC7sn@qk|i!5}H8NKL$QGA}5>vQUu>z&8>q`b8m z?Ql@L$eahdps-_%%bmj$szC`aOpEotgM6Q$BbsmM5->U zZ5yClH;9 z#Anf&SUt^&LLe^J^_9tG-B@sLZAWs#(Svv7yo^P=&${sD{ZBB#byV<(XBT9cSEmys)kl%(A*+L``uwrU3OCCD|zt2T97j|QvNtp_PpCI5( z?A+8jb1QwFcaf??w49DhpLn5hJ7C5RMX10xV@MK2(r5P@SBU8!#k;v3i<6-Nv+&HHFMB5T6)E+ zSF_Pzudv5sZOb5068UcWX{XpXB1m_c^lX_KYm`LM=I92tc<-dhf!9ebL(pQlj7Y|? zCn)MPsPgQTYXN z#ocX;(Hu5Jy1<)uk5hj#w9%cl#hrGsw{@efZP7g~g620{p(F;O>bC z94Stxxm4Z0&7y5&qFs%K-|Kho)N?WEdn2iKkCl!LabV9XnE4NCFH~B|s&FAW4ZEyv z0(r;5+<~$ATBQiTW#l@&0E|vQ*6s41yHB81*uJr4MTI|{IY|IMyxUvOj&~z#$Md=2 z2DX37M)8x$K%8e4o+nqu%RgLtdvigNi+4KLoxF7O`4!9v)uqcA>sFYWL!vo2BX{-n zT`r&Dy=U`-dq&(k4xgJCI=?=@`vn?B`Ea8DTq@@Z?|Pe&O+%40M8G)Y%Ma1D*ygD0 z(Pns}N^G${$Jp2y;ibFN{0vdlT6}b1Fn8`&5IVS$RRJ3RO|Vp~ZyIu-Z?4{#KWGYErL*fvwY<3?fA8pbDF!j zJfQ2589(-$yiSuDmxaR2ybtqEbDp}xuSN6xXKqoiZ*Qo6@t}W^d;hueZ(xggx2d~n zBROgI#8K1PrHhhL!2=c3PLle6Mm=g?M!xpDxObS4-nJ z!VJ910(AMZ(N_MDH6Q8)od_Ck7=ChG{}%Ri5z V(K#=GDl30*9c^83SFQ2K{sUPJTaN$$ diff --git a/sources/awesomewidgets/weather/14.gif b/sources/awesomewidgets/weather/14.gif new file mode 100644 index 0000000000000000000000000000000000000000..b68e55a6ad5caeadd088d75e84b4002e3ae271d0 GIT binary patch literal 2251 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�)Vm6Wi+!PStCsq60dz`(%D z&e_7n+R@Y9&CcDeufLm_rr+c3jEs%l-QCgB)upGnlarI(;p?26wEFx0`1<|z_y4)R z%Z-bs!NbOvma4kC(ed;ChlHbvh^32(qQb-2+urW8w8(ODb<57+`}_Tslda$3?Ww7& z^!54L-si=}(x|7tk&vwT`TU!mwC3sUW@c%FgM)y8f{BNdhK8S#l9rd3n3$NGiHDUu`si~@~tgNo3rM9G`x}>4Ms;axGth%nP zxvZ?es;s=PvA40Yv9hzawzjpkwYI6K!m6ynu&&6nwZpf&$hy45y}!@Bz170P!pX|c z!NSkN#L>;p+tbw3+}zyJ&f?M1A^!_OL{CCRI!RJ7E-(V#?EoS91OWg5{{Soi0000q05kvq2>$^82^>hU zpuvL(6DnNDu%W|;5F<*QNRc8FZ&9YHtH@E{25&Bk6afII0SPD_A#UKa0oq6a0E*Bl z;_uwFlne<_v!Trf5STEFT#!l6#vznA5nj1qK*9x}KtF)_VBi{_WZ;evNJ@|b6#zA! z0=QtSpGaFtCQT4A#!m%o$3So$FoTKAmql#FkzinuIXpkf5<7*bLJ4m_wsHg!4M9)< zABs#e5Qzha2oYY4wI$)plL~GnxhkfZq9Z^gDo?&B*d}s6DEc@Z{BQ^XC@8@JYSUEq!=-5sdUwFM&)#%LN5Y(}E|{ zyo1mL(|`a#3oZbF%MH0`V1NO8+)w}xsZ>xwAsobk$1`6TVgghEkkXV;jsY-vV75d#%r2U(2ZQ4Sy= z5CB908bpQxfE+wiff}30)Jsqom|%-7lNiE710E7kwSYVAHHN z161T8OblrZ;e-^&1Vg+N!gS#P1x%da02Iq36o3bEp>co%zZF67KO10zBVe$F0B+zA zCjh|_O0WUvZD0WZ*Z~MiFoPDfpad>ph$B33h<|wF1TpyEKu*vA7f>Mp!6*R?05A5KK5k6#s(J1rju13j!g)38>Ho4*);`P?*LB zhHwNY7(pNZZ~+W{umKlr048CuL){oM03&!{0uBITCk{a{7xcgdT~NReI)MfXIHClO zaD)pW_zw_-ZyG_F!U}ve#)D))9Z~=!05+h25|n@natXi@Vi1fb{Gba?NP`zVKm{ip zpdfh^0|-tajA=MR3Pe!IA^hkCCTxHTPz1pMmgfjNke~;YP(TZuP=qMNU;+ez0u!JR z25(Tp3F_Kzpm2y4c!POFI0Ovl;Qs|jP@x4=5TO80U<7ptKpk6fK>ZjJg#a)B z1p4sC;s~;`A0UAV9%$!5KtQkqSh0r=X+aE}5XprS1Ox$CnE+&vL4<6e1t4_@2!gP( z18iUe6bM2~55fc&I02ZBz#dlwGJ|P2!2#Zw13VDIf)@0k3IB)!07?)9u7F^bMp%Ii zI+>6JI>B3Wz+h5}(0~(IailSD02K-Xf((KH4OeJ@H}b#-uC!np(`Wz{px_NB^uPi7 z8At0e%!=2qiFrH%b7^l=xHzb6^4$?iPfY4#XQ27=kxI z(SiZ6018d3ND;iS10%rTm~&`st*F2P2duyeEa2r(|3QIi#DEGjaKbhXA_i9~zyp={0A^5vX%K*{4G`ye9|D32(CPq0fI>3|{1DPIc&GsZ06XG~rVjuB literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/17.gif b/sources/awesomewidgets/weather/17.gif new file mode 100644 index 0000000000000000000000000000000000000000..7db05801e7664c41adf44f68d600e163de0ec43d GIT binary patch literal 2694 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/18.gif b/sources/awesomewidgets/weather/18.gif new file mode 100644 index 0000000000000000000000000000000000000000..e8f808b24b1ed9e7773620a8a57018cb90505f43 GIT binary patch literal 2459 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/20.gif b/sources/awesomewidgets/weather/20.gif new file mode 100644 index 0000000000000000000000000000000000000000..0aa42a24d72f2f96c973dacff03d39ae560006c3 GIT binary patch literal 1858 zcmV-I2fg@5Nk%w1VKe|V0Qdg@|NsBj*VozE+11t6$;rvf%gfBn%+b-&+S=OO+}z*a z-_Fj?;NalW($ePU=HlYw^Yiol{r&0b>Fn(6_xJb5$H(#U@%j1r^z`)l`ugkZ>%_#w z<>lqW!^6SB!SC<*53GLW_ZWP%g4vbyTH-DzQ4J- zzqq-%PETW%o3WjppO=`NadU@CNL{e7vBAN^)YR0%%jMzW_i+_HOcY2U}f0KHDm4$?lfq;;Nhme7Umxzg#i;I?wjhBLj zor{W@i;bO-kC~5=n2wO1kddC1l$@59pNf#6l#`*7mY|fEr<U3S$j89I$-~3R!NbeM!^_6S%EZRY$H~pg%F4;f%FN5p&dtot&d$Qc)5puz%F58l z%GJZk-^$O}%g@`;&(hG(*3Q!0($dh-(9+Y?)6>({*x1<8(%9D4+u7RL+1lFJ+27vY z-oVJ=#mwf(&fvw*?9kQZ)!F9I*XrBe=*!je%+~bJ+4k1q{o3LA+2Q-z}|KsE1 z;Nt1)?C+SIC@Ac#9|K{xc$^82^>hU zpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+{m$`$B!UGiX2I@q{)90L|76bqLMIy7DNmg zV(9}x4?XA%ht{+_C~9VKl(Y3V4tK3KPjhVFL*O zK!QauxO70_5yCKFK?W-fM8OgY2yj4s!5FZ>0V%S>PZqie$G|86kRpQzzyRC!p}l4k#330Fe(D&_Dtj^fpkR0yx_M5)0I6fRzng zqW}ZzT(-^<5=ii~&ktmVP0S4#P{DZ{06gsk7%(Xi0P$J8E};#~jKlx}XoFb-2xybQ z(J^n0L<9Z`Q}fB^b+7?0!4Qhg14~e_r&Aa#A)f+ZQ~$GWZU|7^?*abST&LPK6G}J| zC!1)Zm0Ldm!JYs_KmoT)aIg;Fa-QukHR=u!K&XEYKsEwni;az((IPQA#o90+fy)9# zKpCr1u8X$KgAy8m0HFfEb?d()fB@E7Q-cl1JUfu*-78qI4mJTaU|+1VW=}wU3oKw| z_XZSzJpm2ZjD3~D%p7e12}oe~KoLN&1Ow{M>3so#Y9DBwfr@`z1>-V~tPXdd-kA*> z8hD>T^mG9VV88OX5DkYCB;h)7K0M*;!>J5C+dlmGw# literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/21.gif b/sources/awesomewidgets/weather/21.gif new file mode 100644 index 0000000000000000000000000000000000000000..47b00153db8208a92d9949ceaffa8ff24f13f852 GIT binary patch literal 2102 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/23.gif b/sources/awesomewidgets/weather/23.gif new file mode 100644 index 0000000000000000000000000000000000000000..66daadbe949d328b7605761609c648e438c051f6 GIT binary patch literal 1857 zcmbW$`#;ltAHea?&YMFwP33mEyEccg%VA>`E{_buwjAaVa`SLV<$=18BKK%!F@$OE zoHHg0)rL;$x*8^DiLR2Q6_s46Ido9U{oQ^42lw;+`uY9S`|Zi}uy=@}0xI~t0X8-^ ze*F0H{rmUz_4RMxzJ2}rb!~0!%a<>oA)h{f`t<4J$B(P4t1Bxj%gf74OG_#!6_o13 zhY#=Hzh8t}TzvQL-CvM}zZMo2-oAZ1ulD8*)SEZ2U%!6!>ebxb-0a*e7;si~cQC9*!}zWM@L6TMxaK9hlhuTh6V=*2L=ZE)%qa!?%nI{?NulgJv}|$-Q8VXU2?hn z?%lh8sQnJP1EqEw(%IR0>(;HCH*em!apU^+>({Pb>*(lcZ*OmFYm>=jQmORn)vH&o zUV&VOw5qkVv@|z2U%GUusi~>4vGKx%3k?v-|J46i9Yib^*VfjaKYzZarlz{Ox~i(G zva+(GqN2RKysWJ3+_`h5rKKW~=gc)YAEs4Om*d+OAw%*@P;j0_G3it{hE^mM57^pht~rlqB& zrly`aapL&#<0&aA$BrFKPEJlrf=WtEO#ChJH^|YWM~@smqLu*7k%WYV`1trZsJOV; z*x18|4<9;o=-|PFF)=X*4jhPzii(VkjEIN`4-XFu3kwYm-M@c-NJvO*lf11udk1fkGHqCmzNid#bPp%F5i_96Dq0e<5yY zy3l=H-5r_!6l*ekW)TqAkT3uifu(w%`bz+I13bkUGNj_JY%HD>)-SE=$<;AtRWoGu zy#@Mqant=WNnbI+E#HvY)-WJ458ySZXoPG{ZKO}^llL$bd=VQWWs7TIni!%v&@2sFmvCS#P=Y0Z^=Os_R$g)s(T5acc2*#}0J($;<5Da2qmcj@))#JruWvYT zQ66_-J@6Zb?7nSIi3s`6ZpbJfi(-&Oqn-?d%Pk`~1T47CS!TfeTU`fHq}GXkqB9`y z94caIIxzP3Xe3sOl=5M~lnB45GTc$ULq-1a?TzhXemxmge^TPs>5Uv4|gewC^ zyDWby#Lu#T+qR60(jE!2R5>g`G;l|)4%6UrQ<)c!r!jBXwXo%Bj1d}CH;kh|zZN3L zbZdujlt{(#77+Z=V8}dK10=E$$QH>eTm!Q!Of&@hwOq1S zzZ!`9sC2ysn0DBgB@8O<4vdRd1TJ?VpCe~IZjz}RcnlH9qYM59^i;#!{|!_c28gA7A4T|64&KYni<`Nrk&MBID3)qvX{w3xxbeA9c<4KNvJO=u)58# zWttA~SFl>adLpLvlvCDN#7`}Q4_gMsq;g@3-=(>f|?`j-WqTxg* z>NcAXnJIOuV00J!WgR5eAepPl7MnS*DQkCt(i7%NxRxpp#hxsJzf-{V$iQW5WENV% jGPNJB+mzbhv;C_om!?&(qm|207#S=H7)T}!fM5RuA(Tkz literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/24.gif b/sources/awesomewidgets/weather/24.gif new file mode 100644 index 0000000000000000000000000000000000000000..66daadbe949d328b7605761609c648e438c051f6 GIT binary patch literal 1857 zcmbW$`#;ltAHea?&YMFwP33mEyEccg%VA>`E{_buwjAaVa`SLV<$=18BKK%!F@$OE zoHHg0)rL;$x*8^DiLR2Q6_s46Ido9U{oQ^42lw;+`uY9S`|Zi}uy=@}0xI~t0X8-^ ze*F0H{rmUz_4RMxzJ2}rb!~0!%a<>oA)h{f`t<4J$B(P4t1Bxj%gf74OG_#!6_o13 zhY#=Hzh8t}TzvQL-CvM}zZMo2-oAZ1ulD8*)SEZ2U%!6!>ebxb-0a*e7;si~cQC9*!}zWM@L6TMxaK9hlhuTh6V=*2L=ZE)%qa!?%nI{?NulgJv}|$-Q8VXU2?hn z?%lh8sQnJP1EqEw(%IR0>(;HCH*em!apU^+>({Pb>*(lcZ*OmFYm>=jQmORn)vH&o zUV&VOw5qkVv@|z2U%GUusi~>4vGKx%3k?v-|J46i9Yib^*VfjaKYzZarlz{Ox~i(G zva+(GqN2RKysWJ3+_`h5rKKW~=gc)YAEs4Om*d+OAw%*@P;j0_G3it{hE^mM57^pht~rlqB& zrly`aapL&#<0&aA$BrFKPEJlrf=WtEO#ChJH^|YWM~@smqLu*7k%WYV`1trZsJOV; z*x18|4<9;o=-|PFF)=X*4jhPzii(VkjEIN`4-XFu3kwYm-M@c-NJvO*lf11udk1fkGHqCmzNid#bPp%F5i_96Dq0e<5yY zy3l=H-5r_!6l*ekW)TqAkT3uifu(w%`bz+I13bkUGNj_JY%HD>)-SE=$<;AtRWoGu zy#@Mqant=WNnbI+E#HvY)-WJ458ySZXoPG{ZKO}^llL$bd=VQWWs7TIni!%v&@2sFmvCS#P=Y0Z^=Os_R$g)s(T5acc2*#}0J($;<5Da2qmcj@))#JruWvYT zQ66_-J@6Zb?7nSIi3s`6ZpbJfi(-&Oqn-?d%Pk`~1T47CS!TfeTU`fHq}GXkqB9`y z94caIIxzP3Xe3sOl=5M~lnB45GTc$ULq-1a?TzhXemxmge^TPs>5Uv4|gewC^ zyDWby#Lu#T+qR60(jE!2R5>g`G;l|)4%6UrQ<)c!r!jBXwXo%Bj1d}CH;kh|zZN3L zbZdujlt{(#77+Z=V8}dK10=E$$QH>eTm!Q!Of&@hwOq1S zzZ!`9sC2ysn0DBgB@8O<4vdRd1TJ?VpCe~IZjz}RcnlH9qYM59^i;#!{|!_c28gA7A4T|64&KYni<`Nrk&MBID3)qvX{w3xxbeA9c<4KNvJO=u)58# zWttA~SFl>adLpLvlvCDN#7`}Q4_gMsq;g@3-=(>f|?`j-WqTxg* z>NcAXnJIOuV00J!WgR5eAepPl7MnS*DQkCt(i7%NxRxpp#hxsJzf-{V$iQW5WENV% jGPNJB+mzbhv;C_om!?&(qm|207#S=H7)T}!fM5RuA(Tkz literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/25.gif b/sources/awesomewidgets/weather/25.gif new file mode 100644 index 0000000000000000000000000000000000000000..6d8e2a1d56a0925377cf16a8b6a6614e980cac68 GIT binary patch literal 2034 zcmVU2ce0;I7u`a09 z;o;$JZEaqr$H?gPxx~m2e5Nmy#ERbiN1430w#cQ^gwt+HAhHyi6mKxE4}mF{{M=KimtA%M_Y!B;{W*g z_!+Y7o7L=E&G>Y5beONVcB{xqNJy%xx)f1{%k}^F_xD(WkQt1-TU%SD#@evj=&Gu! zxVX3~wdjt&(az4>6TSVBlatxm+57wZT%5VZ_Wx6&zoMd`hKHIXYlu@=d<(1Sca5rD zWNKMxixIBrj*gC%wY-a#n7+Qg94JV(wzkjD&wIw>I(L}N%*@Hj$#Q#}CMHC!t-OVf zqnf(WX=rx!_4O3C^Hfw-W}~@jbCo%Dil(Ql{r&wsKt<8=`(|m9^Z)vBWjw7v%X(nU?L(e*Zlt{aEh<6 zz{tYCY=@=}v+}X-|B~weL_Sa+OLj<9URGFESXfq4T3lOUUO-iSOk`XKHY9aB6aSdU$wzfPW}=lVD$kRdkhpZh&fegnW3C4}YvBgQ+x+uq~3eX^4+b zjjLUTpi7Rlbe+0;tG<1(z8R<9F0kK3uh>bl+E}*RLb>K>zu|ks-CM!vZ^`S2h=+)b zkCBj%k(;xgprE6pqo}2&w6n9ix3;{zyPdSag}>If$=Zz1>5$9eh}H9y-1w;7@SNxW zsp0mc=lrkl|IEzD&CJlt-QnKZ+1}dR-Rtex?DFm8>ih2R_VV%f_w@Po_W1br{QUX( z|Ns5}|NsC0A^!_OL{CCRI!RJ7E-(V#?EoS91OWg5{{Soi0000q05kvq2>$^82^>hU zpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+{m$`$B!UGiX2I@q{)*52_#U%QcW8NG!m>- zli&iMe*|8%d2vPHg)}>$To9p=DLMD|UphpnWNH7l*Bn06C98l<2jV2!0V1p82gn^AF$tZ$_CMqPN02V7~fq(}q zEK@@f9h^c*5qD^@!h<%fPz@XhB)I|!2prJUKnJXW&Imn>u!;nIKmth*tMp(^BMS6^ zM-Lt#&_WMbjG{;j1K^=ZE(7#{2Leirum&1JR4~8@SR?{NU09ye&LFj5f=MJb06_r} z%8)|=Iek>n3?YIb;0z&yAaDx>=@7z04WAOh=Q`$~(ZK@|Q2#Ih0y@+Yoe3!bGYmfZ zgwuyQDHKA78SJDm%ORnp5CH-aq#(#B6$k@_Dm;vmY^TVm0tBEiNZ}4Mv=R`V6N{iy zLjeR((uX8Sh%rnr?DC*M8H>z;Kp9yyF$x*kn2-ez_hzxI1z9)&Xa`PYfl4Aeh>K-B zfqoev<6O-0hbTf=QIG>}7*PTY6VUKa8}JwrM+FBYV1yBeXdwC_Iuww=9)@tih2eKh zpm`@cKymu%QxL$!0XqxigAV`z00RuR5Hu30Puu6qyak9>p%vqpcW>)1OP(Nf#(uHh6xxC0~y#s0-oT!&t1WO7pQ;^+7P^f zIDi0TctCyxQh*CEVF&+6fDSTH0HathGzECV0lf%thXd#U0~grA0rKMj2lzt=XUG5s zT1XHFaLxwJ8dViH~;_u literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/26.gif b/sources/awesomewidgets/weather/26.gif new file mode 100644 index 0000000000000000000000000000000000000000..8ed0378510ec415a2b87518f5f1cc749c22acf91 GIT binary patch literal 2127 zcmV-V2(b4@Nk%w1VKe|V0Qdg@|NsBW%+&Gm@$K;Ro12{O?(X^f{-dL$`uzUn>F(j- z;mys?;^pp&ij1kNyVu&~y}i-(`TmTHrF3+3!otIbhmx_evBt^NgM*pb-sRfe>FMqE zwzh^TgT~3)v9iXWp{s+0i?6Z6@Ib>80IR8&;a(b2!d(v*~=nVGTH*4F0f_44)ky1Ke;ZEy1R{m9JN=jrjSuEM6L zzTM&K@$&kdo};z5%ATIJmX?Kydw%uz{Yy(s zd3%hzy~AN)ZNS3T*V*E;waKQYs>;mWFMk9&(h+irn`!Vq>_@V>h1Eu!qaSRdhYP~k&%+1p|<+^ z`l_q0;N$J=@Ak*Y&uVLd!p7Bne3Rqm>Z7H((bnFFikqUNxnyN>{r&yU&f&MZ#Np)T z^7i)L;o_>Qs!vZ+>+9>Msk-6f>FetEl9I0U_WPQdw9L-lmzJ>OlvTt#D!p6_h)aB38-M+un+urQ1uCB($$ef+BoSL_ony;s-v7w`~ z-{k1s-|EZI*i}|)kB_Oew#>4z$%loZo1U|mn6ErMKkDo6@bdTg`TSsDV0U?db90J| ziJ+L7osN*Dl9Z{GmZ_JRvz(i=pP{Ltp{}Q=ucxS~rKPc>qqd@?xTL4HqM*E_q`a=L zv9hwYxVX5brNOAC!>p{ss;R`Qti`jo!?w4=v$w^xw9CA`%)rCS!o)YQ??)Y8-1*4p3M+uzXB;MCdU*4*OQ+U?!o@8IR{;N$S;=ji0<^X%>V@bmoh z`TP0%`~Uy{A^!_OL{CCRI!RJ7E-(V#?EoS91OWg5{{Soi0000q05kvq2>$^82^>hU zpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+{m$`$Bd&22>1w5!2t>}C>)SOa-o6+761SO z1fbA?ku3=VQt*PCop|>WOabxXMgwj+2U3_L%UwR118|L414)LhRSS|@PynE-%o_vv zIG{m;)3-LtVzi9GCxSg(G-uk=bm~F|J`e6)!Sn*q$7ui(1Q-Bd13d*(veBUD6~K)p z2mE@plHi^I0fl665HuputpI$^U2w%`#RNnG+O;dNan6G%0us3T_RU6ZP5lp0XxlAgjji-V_MbG+;_a3Is7n06(-)O)Ytl@rM*raMcwcHw0FV z6e8GiiUO`cpg{{(eDRO~C|F^IGWMh>0|>!j@P{E0&-6| zYy1&KToc;Ef;kYBlg&DS5TgMId91O91Q>+T#TqV9u#faKi}` zvRT3h=6nOfjD>wr&Mz2zlZ_f`xL}C`Ng$%o3+QASK>*5DlSl;tC{g1~HfS)$IxGx3 zAqnMtlLiZ8OyMLAVFZx_HxbnAU4>#0SV#;vJM0roZuD& zihV=E2KSJ#&K4jXa|jWmB&2{9_P7hh9hQ)?iwm+yIz<8rtb@iFV?Y1_2kU6C@HdcT z^8h~;I`&2cL42};Aq&)7kOg75L548GhycYQT-{K|6!VP1febQ~;|C4dlw<6>R(f>< zcqeFJ!3)EfKpsM-Ot1nBG1Vkf08_N!N+o0PF#-*|K>w1;2Z_;OPS_LT`2YZf0boNt zGc+KrL0`N;0TB_{@IYSoh+|74ZOt^rRJ?$C!v@1-=~V(6*mF)4p0TO@%zs0oy1m8f=L=y@eqyRSnpaI=IGXX-+ z2Y_sV#+%tpF~$Z6)Mvm3Kdd9e6b_sU!RYb?i_JGVtWdN;G1LG6y5ood;xcd#4QPM` z<)A?@4%Zl&ykQ>eP!E0EdRQ)fg9XlA7dy%AVBa9XZ)fZ6#|43 zyaI@jjRg|JqX9V9F@|!KV+!G8!X}I{q=N{62n`?t3NCo5?GKkQGBm^@FIY6c{jqyp-C}R!>uz&>;sQ{KR1Q10Ki2xMPfdXiu1`05P zND!d_1&Ble?TCRpwXgtgSO6tvxJ(fQP#OepCIyJye$s6rRY(2E2F F06V5)Jw^Zk literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/27.gif b/sources/awesomewidgets/weather/27.gif new file mode 100644 index 0000000000000000000000000000000000000000..17461bdcf0a1fc03d8117a39a8f16a8cbc2d8448 GIT binary patch literal 2777 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/28.gif b/sources/awesomewidgets/weather/28.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b14b7aa29345a801a24271c4e95615729a0f6c9 GIT binary patch literal 2675 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 JFGB(X06Q*c^cVmD literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/3.gif b/sources/awesomewidgets/weather/3.gif new file mode 100644 index 0000000000000000000000000000000000000000..7db05801e7664c41adf44f68d600e163de0ec43d GIT binary patch literal 2694 zcmWlZizAZ@1Bc&tHoKa4ZcVvtsD@7FQc0Y)nOkm?>8MmwoubrPq8u$}vth|)R8omq zgs2Zm?rm<(B{pYCk*1__IyI+!>2%rG_xuab@A(A;`Fn1R^#DA8PkMmIJN@bv@Z{<9 ztL0Uv`Pn1thg$87`r+f++PcNX#k|7Hg%?Vi#;59Ae|kFe@=h~)ette8!g2iZ(_OI% zdOg4wq}M11I=k=J+-%IrIh&ZwV=zOqE^-bXNnW+e>3CAo(C2@jJbCgvFSE4yOm^;t zk&%&@m|X)8#ugS9yf*nBh);e#_ojVnE;xk!TOw~~%-);zcdpmozEpDU%a<>q5mAQ^ zC&cbQs(AOl@lI=7XLnYmth;|OGrO>|vNB7&=VYqrO6m1)-@fhL_iJ2^mNhn&Ydx4&!4||`}XbN;9%G5`Kf0w_8mwpuc#?1x;XddZCP2F zAR{}k;QWb{Q@?DF?Hg22OimXUUwZZo78x12umJq2*UPTgZ}Rpz!ac#>wm16F;qyh; z;u2DN=ia+e*N==nI-7sFxvksHeM4XWh;ryp>9rcw*m!sUgMc8mtmFuZEY?0ath0C+-hyS+tJrQSY2JMoqg5b(dp;s*Lb_-*SLhHyPbZaVQ>C= zuNi-$);ub?it+Jw%*@QOBwDTW^e#Mqfx%=8L=t(A@=D3ohQ{W}$;r!CN`^)?1H+?D zciTnc{O{ktt27gui78hvS05j@qesn;opRZ{naN_&{R6_nckB!e-yP11jox{1H|I!r z?1??eCl4Ns+ndVE%STn!+4c5d-|39Md;$B1NIQ>b9zAn5LzI=7ne~S-C+}+Ml`9v8 z+0{iQH*#*>Dr~x2d9AwQdRY4#qF+!+g+XQ@*h+*^|s$r%38#Sb?&xa2m7C-6rda@o%XNEKU zyn?p6uBF1J{|3mP;UEC$fi=Jn{$B}z(gS+5RbahTAw-!v#VG5`d$QoBv;U?ar02Wr zfk?>n56u$)zEYiuhCDq9E^9_P&f|6RfI-CyWLjP6Yf~3&W=e-4yShF=3;{l+4#jHS zS;7cM@Dg*PTamrX`Rh%+VpH+h8L#RPxSJwv5ee+5vo#unMiDnQ_3KSvxd3&Z(r+%E{DhMBWQEr=Xe7MgLMdVszhU}eQ) z#SskfCUDNzI-=KJoxdoa7=o?fk><(_;-w&ND{iL3Yaxb9$GJHaX2fsTaxr+Kn9i(B z;OMG=j(y zPdS7jY!=f*Hlb!9t*&vKBG8nX(xn67YK zSoV*Z8E_y3S%d?&;INQ1-6&h7%78%qrC`D?t8QQG-x#~SRy zSOwk7G~dvGeNl%LG+B@eu%RC<0+vGowIY}+g~sd&g!D65V`~+;8|J1d7+7tmYRGYO z3ZeO7U1$+>*uFF_6K~K$3$VGUqpe3fkQNfHx67%3maR$*beFX27?}B4903zbNf(mY zv$q)T>=s(0b=44LVCV*w3+%E~GLW#gnkGcrvU9hh9hX=l(Fb}d+BOD&^%f%SpM;l*!4Cd5kq8;=|m8Jq$uaQGVaiA?e7PdsM zz>p3r{(P;%t)S4@j}Gnrkft-J5QM=$*)za1QkT_D0Jbp_b=rv~vY4PD!nD5F9W)V{ zLjyO*^}|b4IkpfTZk?oX(^ujU6BhoN+AL z?qA)n@OnB@OoQ2|W{?=E&~?2e-A46*6cz#i>uL9ms%3~QZa2AFCBVz;5s@AuBM&Lk zhkw`@&ZQ%x4Kr<9__>Y~au}rw`l*5>aHKE@M8d%Rbu);cUNZ<=`IzN2g&_dQv8n!| zRSD937n&b(exl2UWkOZ~+X)^7Y$!j6aCtx6-lH6CoM5t_C8bkN4|JJT@GnYOeUwPx zj2+dPJkMvW%WVzbYXMqbQD!1<3=Bo5@QdfzB2SDuIFL&x9N;j?Ap|iE^+UlXrAv-V zZ{Tf3$B$B&q(dx0xC2O7rD7PnNd=)?h0$0_AC?HDGf;wc%xJg)1_a=20s0uHXCJ;% z=0xS##w^K~CA#8s2W2pFG2J|xD_qMG!tQ%AOojo3_bd!%pbbEV=rZ2GXL2zEOp_!I z##=ID+e+h;MY@c0kR5s=1wo=vGfv>rvFmh^uwIqXKnBSXEmo{ztHI=!K=cPzz{6>k zp>>M_Yo=phiBcgWj-INgfUqsxU@>LphgQJqJ0YKp1MnX|XKnPXkHWCz=AlXeaFXVc zXmaoqHQi+EYYFM=9R2*M9L_@tSg!RMqv2O2*^=-rNV9v_nAZAzUA}l{0zTC{6i=Mj8C*W z`J9?Iwq6AN_yv(Y90QR)V)cAqrDz8-m;a3~)}ynVJ0FV#a(68bcKxcs(ke zpyNt65J4lbJ^`+i@R>PMVhq=b9V@*oTZKScP<;!ReUWW!F@(j{*Evr?;tQohL<~RE zO9DeCE2DzkDFTZoR(e5~A_7UD<0IdFhOZ>jv9_;4&L77#n^yubF86rRv%hkT;$qR7 y2$*A<*VqATruA+B?ivyy#1RGUdAm`TZd3$$KY+~}XewmM;mM*M8aNsSZ2BLaldseO literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/30.gif b/sources/awesomewidgets/weather/30.gif new file mode 100644 index 0000000000000000000000000000000000000000..8178a2e9f3952484725cbdcfba3e245d12f961ce GIT binary patch literal 2480 zcmV;h2~YM%Nk%w1VKe|V0Qdg@(xNovOnq zdH?_ax3{I|r84*UX@PuX|NpCXb$FzuyXx)q{r;S^eJK0oX#d+(?Cgn?ic+?#R{sB@ zrKEMivuWAd+5Y~M{HHYM=eXR*T9uTrXlGXJ?Ck5~lmGh0iHU~T)vURVF_WZdvxwm(^yOr|EQuFou%FNsU|Aznm^2Wt_z`coCSWoz?Hmj?`!^G6>w>bX& z(prDGPzdWNv0W_V)I^z|*s}!SnLu=H+Ker{MMl$2?-waJr{lK<6ChG;9qgd>z{{U)!5?V-m3TUZ{^Eq=;-Fk&f@X$ z@cjJz#+*8YgKF;U%Iod&`DD#5^{`TG5*rk?1oN6E>> zgcJ*!iN9P#g92?xCG-|M$r1##PwZ+v3-c{oG&U zm@nJg7$NDl7T>+c{$6?)tq%F{Qm!^orA>2 z+RxG9oSc^R>#^6`=>7MN{_>>!{r|zg>ZF2SYd;kCa zuCA;{ITrNuuixS9@bdSMji=4f+_$;Q$I08Dp|@XOUjP4c`@m7+;LCAnYUc*q(92AQu(evzW?~a@b1{|@7eeD(CF&$^z`)i z`2GF;`~Uy{A^!_OL{CCRI!RJ7E-(V#?EoS91OWg5{{Soi0000q05kvq2>$^82^>hU zpuvH+5*}R0u%SbO32!}|NU`BQBK#_9-1u*hnE)I^K70a&h{%%*4KR3uGUObE|0LdG z@h5>qf^+7yY*-?Uq=YV9;6qdl#g(8x{=vZo@*vEIHx2q@fG6LU6N*geQk0?1i7rT7 zv}-2G>C=Zqm_&`~0$m~%2VyAz0s%sXJ+TO|8iMZFm4dgJ)YDm!$rGjmUHIt2?ZcNt z7g_)j@L?9MGZ(T6fZm^8pM~ zr0`itE}RfcHPT4qq5v^c_5l`2TtiL?3oOt|3H6kM%pO>b0Szli9O#fFPq1Le0ooJ- zKr(yOAmaxgP=EykR#-u0mA8;`3ozjAV>oU%oyhe z>!>h65Hl<=L#DSxF~crg^wP{402pFI8%-q8ltZ^Hm5D9G%>PosH*Zp~!6h*;LP{$O z+@cCFY@D)#Cksq4!UzLA@W?f#)Dp;X6Ws#IHJ|LE3;?xmfCvLo^xA6_ad2V94no`l z#wo#Ug6tBtET66+u)vffEu)KtmN0jBv~! zVlH%x8k$&8$O}4rgD(V&r~tDQ4s(UPn?4e zB8v#%MJNJbfCCHXFtR`tmbk)36+G}U0J2<^(XuO58vlICEq6??z#Za*kr6?I1Tsi5 zoLsd*4QC5*gAg-BF#$ga%Y$hYWem`Z6BAhCOTm4E0dUHihAT`H1(onbAmfBn$1^b8 zkVz<5{1HVJR`3u65qz+*04XaEu!Ioa_6o=hdib&fAKkXHOBq~5fQy)b+~P)Ql`@QYv|s~0q-3pu2tVAB0vLP&6w2^JB&0BfcI6-fIVeIAgdvO^kf0ew z=mZJIfdUecz!;m@L~)U!X$+8UO+XsKW~|fI%iWzyUIl zfdk}F!6V3!2{Rr66t74|BXW@oJs!ghOb~@6sL&98)B_HjUyApkefA{wy>rWS@-mvU|(m>Y=2 zGmC_n&$Y2;y20bNBN5J1s1^kJBYD8&^PIgvpi0TB$=3BtjFQ6_bRt zp$^V4fn0zv1S34+6AC!M5O6>a275e(A7Ow3X`^+ELk+|QxQIY8kkAE9q@oR7sDlb1 zu>~I#0~Js>&>TuY%bk<}6$bi2P+af_Bt(D(L6Jyq0}Gg)+#&#nQ^*rI5doX=!>~IM uEDORx-uQ+@61WftN$ookewZNvfZ*>*<}e782>2vtIk18k%;13p1OPkbtF=4; literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/31.gif b/sources/awesomewidgets/weather/31.gif new file mode 100644 index 0000000000000000000000000000000000000000..e0c709f23639e586eb3610b5c86760d804403638 GIT binary patch literal 2764 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 Hz~=t}z5GDe literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/32.gif b/sources/awesomewidgets/weather/32.gif new file mode 100644 index 0000000000000000000000000000000000000000..203ad8b55ced3a4d94b0e6a7dbc8141b68a44dfa GIT binary patch literal 2389 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 a+cKbmN5SX{J+HYh=~UtV*?IziMgIe)uuEV7 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/33.gif b/sources/awesomewidgets/weather/33.gif new file mode 100644 index 0000000000000000000000000000000000000000..f67352d50c6254ad581aac22ba2d22a25eddf997 GIT binary patch literal 2874 zcmWmDiC>Zj1Hkd;;TA+u@yr!?6fJY;v{~(SfESgPE-hW=t1GQ6H*4y;_kek1S!CJD ztl@oRii(MOfuJH@h$x5$U}k2u?6!IE?*07Co;=~0e;qP0s>uF-U? ze3?|MT8ncMaxR3oJj%Wa9a#NGZ&?1@u=4KH+y0)m!tz@u4Xa=JWwpC*(v*n6-|>9LanB?srI&ZLewX^-zzEA>bu*TxjLQr+Jy-1 zL|bQ5-jr5ce*dgqD_(p*^h_^)cqciJeNZ{XpVYKzRL#x28v}iOjk#$c6|X$ zF;HJ~|J>cISed9uJt7dd6--Tbc0S2(Yr6l4dvRLZG2F+?%RH2Pe8;$^T{Xo2=i{(; zyuDXi{o=W_v#msFRJm)4hM4E6FF zic=*m4_X^?)6YeYD+RYN$2_0wt-N=3d{mH~8l_S+jtuahY8sUNHS#{**l1I8MLPSp zJ$c!&X{W=qlN|!yb^VlZa!TC!q(D8=tQc$>>aQP?RxQ38(Q73&_b!g9TSpX)s-gOU z?yA1-x_(K4Rx2{Bew@^_s)q%Np*Gc!U}&IT(O)kWmvxA$pYU^ejeWCM=wyNBVoZO4ypu2k66Yk>R(0Rn&lZ~^}9 z|4IPNzf6qmnLMrt00By5IiWz5L2&dA%%lQvl;!5112H5>a@~C6J`aWjlW~)>V(SJg z{5gO_MW#rO)=437%dhj2rc<%IGTa;;4s+Pd8xAnUQ7(kUwVNzYQMVO<6%gpX5#^~i zyA)Eq!t6aKeDSfT4cIwq-fK3zkH>3L!yiArYM}a(r@lvSSsG}(DSr5;xX~s zFC>MzFcR?1#!ycETywXMT|leYPme(QDUQB+*|5=?i2ik}hY5BJ6NOeRyx!#J6M>19 z&0h#vA8r>dZb;0?YcxjpuX1-3hg!t zR=QnY6TB$*Ut>j72=R)yM*uQ?<`AWjXMXu6+(RDXQ=EEcefFBvksq%(dm|i!5a~*V zFV$NPlfinG3!T=UiyU!&ic?okfV-P+j~Q|9+upPXBW8irV4K2-n%VV6eva0oyj^&l z3pL=PCyh+U?_g*tnyR_ki{XR~m?@`M0#luOL8 z$S$K}k5JfGdk^AKEkzM!!6f@EWO0=tF^1wk6HK@8q&!|C;FO1L5QLR+F{IxKVi;CxVfG{Zwuo40vq6!cPC$f-B<=__Y(A=j^m5$XX0na}O*Oo?T zIT>(2d>#baMnhtU~lA-ovI-k7ZT zg-WaDqX3Z;k{UV}K$V^DeK=s8{U02cj8U%yry z79lThlFFy}DmDn`gY+uBx_*&q0G41zJwNL59I6;rdj&L@h6cSUrDN8Xi&mySWCr+h z@0EqWr)D~?1$(w0OP=jE_jN-O0X;hTlJJ5P5_vL=hC`=!SjNj!EBOhs>!t4xdyq^+ zo!9`uMr0KyFGGe3Ek>zs=l0meR#nAqIvCLtLJ=Yn5&*UXfT8@UsrEBED@Q4PdkWd8 z(Y~akJPyyAZvpXM(U#wz_VbEMJmxS6;Y_$dT0#elD2;XHVN-4(cpeEyb%+)n(rR}i zdqd<>fIYRVMt_i#b!&(7uBFC~BP}^s3Fmz=Ab9^W4Urq(;Bg8b%7Bn$>@{~uLzaV-D< literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/34.gif b/sources/awesomewidgets/weather/34.gif new file mode 100644 index 0000000000000000000000000000000000000000..8e593e9cd83655c0962cc7ce6b652cd48a36df86 GIT binary patch literal 2417 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/35.gif b/sources/awesomewidgets/weather/35.gif new file mode 100644 index 0000000000000000000000000000000000000000..7db05801e7664c41adf44f68d600e163de0ec43d GIT binary patch literal 2694 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/36.gif b/sources/awesomewidgets/weather/36.gif new file mode 100644 index 0000000000000000000000000000000000000000..d7daaf4118e39f74df2ed13ea565a63143beadf1 GIT binary patch literal 2424 zcmV-;35WJaNk%w1VKe|V0Qdg@k#HE3icbIj)7hpqsHmrOba1w$QU0_5_V)Fdn3n76 z+xpJ{{{74R%2(LfxBmR(tB4K${=Dq$>;C?<{{F=Ix=HAnF#i8~_3M?#tr!0Op{*uSdbqj`PD*ylV{{ES@w5RRKY5x7${K`nt#8UbB`RnM4xx0)0 z<7IMtN#^F|)YHfP{qFz&`G<#y+uO(P*LKOrxBQ6$<;Y#dxOM*i{>Y|A^XH`g?T!Ba zo#^Mh_1t;wzDUi@&H9-Dyr^UF$zlHf>f77f+S!HvYeI_KJ}{{E(HRw3BVg8%=OshL;P)6xF)g!`p5{m@#;#cYdoGwR)xsgp|m@td== zvADOGnU-hi>6-oXvHbFliic{frDodJuhg11_1uH-?a2K6{Os)EzP+^k(qiP$cjv!n z|Ns2x=*Rx4G{T8A{_&L7saMyvU-Z;o^zFC&^SbG%DYu;k_VB@^i%IjaNBZ{Bms}C? z({26gfx^9)n1ecxkb?E~t@V5px3F^Coh;Y0Oz*Kc?W#n&y14JqTL0t#$%QSVqM*jc zqmq()$eT^&yiv!lX!7##_vCo<^X9daKJdd!_VR)7pf&gP+3@d+-QCi5WFPMXhA_mO8ajB?{f#>e;L4iBY}Qib%koj zo;&cVGxDiF)4Bk-m{FFDVT+4;k&Je(oNtu zV%gkr&cJ-(*=zaGZ1Ui0{N8cz>to{IdhzLh{postfPasVj;yDRu&$^82^>hU zph1Eg$GMDap`uzymVFpXK?yCbPEeQvWL%afuNu_IlI;ncKy278;f00| zj~FBV&?qqj=|&Z$PW&(h0#S=F>)e@1_N>Z9;7l02}DGr07xnvHUd96h?B)EXqce^2^*`-2cGEFV4(CSYHnz5DG6V za6n}blJTj*1YO+lK?ffUK}iThl)=d!Lo`!ICqsk~z&q0vP>OL6sqlaqXhdOvHCb?w zg%28d5rH*B4DrDS2T%gQ0cGGazz`dN;mH9Z923AXHXyK|0EkHG%4{5fIspaT@GFcP z2LKSl0kvGRF95itz%MWcyzzj73^_Fd13e@GP7&mMN`?{A8D1=Wf;t%hU``Gh)c=x+0U0p!NEye>lENbZNTY-% zAUFVs7HPZy@(ZPu07D@HP%uFjUl;((8CSAQfdD6rWJ4>V!O#afcpO6q66GF($u>dPoQpw<2$&$kJQRQcq8&s9 z46pTml9L zJctAcP!1{NVFv?HMl9HHBNw7EjcwH51eEYV64+u5hUmlwFoB0mWFkQm@q+{;;EzVw z0tJiE1}VT%$R$qTl&3snA=My;ASB}x(D?x^LJ1r6ju7bn=_ zN%Ww(Jd~jW%J5(XY;gxY?a3BwFa#v`fd7U%C;=Z*aMMZBaDqY{BN#hC0Tf=LjXhXE z3>6TABqU)7eO3Smhk(KW;Ghlx=ph|>e8>wF5Q<jPyj6;AO;LzjWWwH04R6>78huT2s{9V9eg1G+OUHF zVsL~6&>#W0sz_H8z&k>W-~l|SLof`$hA_Nh7a9PA2wvd}Z6JXcmoUNzB!U1rB%lY$oG&*8AJyqC;%-IBY;U% zK>(*X$0RC>M#~YG>0028gI)q*T literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/37.gif b/sources/awesomewidgets/weather/37.gif new file mode 100644 index 0000000000000000000000000000000000000000..75b00e557fae2abc4b1344082e1be621ba36c740 GIT binary patch literal 2400 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 Skb~0%SGf%k>2vuM5CA*Pd`l?+ literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/38.gif b/sources/awesomewidgets/weather/38.gif new file mode 100644 index 0000000000000000000000000000000000000000..75b00e557fae2abc4b1344082e1be621ba36c740 GIT binary patch literal 2400 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 Skb~0%SGf%k>2vuM5CA*Pd`l?+ literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/39.gif b/sources/awesomewidgets/weather/39.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f412db624e1b8f7cf30bd7801598c41c391d553 GIT binary patch literal 2358 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/4.gif b/sources/awesomewidgets/weather/4.gif new file mode 100644 index 0000000000000000000000000000000000000000..7db05801e7664c41adf44f68d600e163de0ec43d GIT binary patch literal 2694 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/40.gif b/sources/awesomewidgets/weather/40.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f412db624e1b8f7cf30bd7801598c41c391d553 GIT binary patch literal 2358 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/41.gif b/sources/awesomewidgets/weather/41.gif new file mode 100644 index 0000000000000000000000000000000000000000..f805f62fa94d1127ad353ed251c1a08f9e7bb7bd GIT binary patch literal 2483 zcmV;k2~74!Nk%w1VKe|V0Qdg@|NsB|{QUa*`t|ko`1ts`z0TFv=JWIO=IQdz(c*i1 zd+F`=f`Wpos;ZThm4kzel#`sTt;5RA-tqDA=;-K{maeg~#`5&}?(zBM<>kf6)avT$ zwzkc+x60Ys+5P|j_V)Js{QleB>ZYZ=#KgpjiHYv<_N}e0c6NN@gDI|#>U3O!^51MoPBzY z+uGW$uCBYgyW-;Fyu7@Df0FR?`nb5bSy@{5`v17P&EetU$jR2p$;qXqrJI?u`TPHE zZEo-H@4mj$v9ZbN>-N^z=woAKwzjr&b91AmxT2%J=j!#))8UVgmaD43#m3CV#@dpS zshgXd_W1p-uEeIMrf+X?rlr4+kB@0-YrewH-{0TG$=i*LsiC2}*xTjY;O(EDxzp9< z>Fe{IowdTn)uExGy}ii9#@5Np-ShSQuCc?Jm$J{#�)Vm6Wi+!PStCsq60dz`(%D z&e_7n+R@Y9&CcDeufLm_rr+c3jEs%l-QCgB)upGnlarI(;p?26wEFx0`1<|z_y4)R z%Z-bs!NbOvma4kC(ed;ChlHbvh^32(qQb-2+urW8w8(ODb<57+`}_Tslda$3?Ww7& z^!54L-si=}(x|7tk&vwT`TU!mwC3sUW@c%FgM)y8f{BNdhK8S#l9rd3n3$NGiHDUu`si~@~tgNo3rM9G`x}>4Ms;axGth%nP zxvZ?es;s=PvA40Yv9hzawzjpkwYI6K!m6ynu&&6nwZpf&$hy45y}!@Bz170P!pX|c z!NSkN#L>;p+tbw3+}zyJ&f?M1A^!_OL{CCRI!RJ7E-(V#?EoS91OWg5{{Soi0000q05kvq2>$^82^>hU zpuvL(6DnNDu%W|;5F<*QNRc8FZ&9YHtH@E{25&Bk6afII0SPD_A#UKa0oq6a0E*Bl z;_uwFlne<_v!Trf5STEFT#!l6#vznA5nj1qK*9x}KtF)_VBi{_WZ;evNJ@|b6#zA! z0=QtSpGaFtCQT4A#!m%o$3So$FoTKAmql#FkzinuIXpkf5<7*bLJ4m_wsHg!4M9)< zABs#e5Qzha2oYY4wI$)plL~GnxhkfZq9Z^gDo?&B*d}s6DEc@Z{BQ^XC@8@JYSUEq!=-5sdUwFM&)#%LN5Y(}E|{ zyo1mL(|`a#3oZbF%MH0`V1NO8+)w}xsZ>xwAsobk$1`6TVgghEkkXV;jsY-vV75d#%r2U(2ZQ4Sy= z5CB908bpQxfE+wiff}30)Jsqom|%-7lNiE710E7kwSYVAHHN z161T8OblrZ;e-^&1Vg+N!gS#P1x%da02Iq36o3bEp>co%zZF67KO10zBVe$F0B+zA zCjh|_O0WUvZD0WZ*Z~MiFoPDfpad>ph$B33h<|wF1TpyEKu*vA7f>Mp!6*R?05A5KK5k6#s(J1rju13j!g)38>Ho4*);`P?*LB zhHwNY7(pNZZ~+W{umKlr048CuL){oM03&!{0uBITCk{a{7xcgdT~NReI)MfXIHClO zaD)pW_zw_-ZyG_F!U}ve#)D))9Z~=!05+h25|n@natXi@Vi1fb{Gba?NP`zVKm{ip zpdfh^0|-tajA=MR3Pe!IA^hkCCTxHTPz1pMmgfjNke~;YP(TZuP=qMNU;+ez0u!JR z25(Tp3F_Kzpm2y4c!POFI0Ovl;Qs|jP@x4=5TO80U<7ptKpk6fK>ZjJg#a)B z1p4sC;s~;`A0UAV9%$!5KtQkqSh0r=X+aE}5XprS1Ox$CnE+&vL4<6e1t4_@2!gP( z18iUe6bM2~55fc&I02ZBz#dlwGJ|P2!2#Zw13VDIf)@0k3IB)!07?)9u7F^bMp%Ii zI+>6JI>B3Wz+h5}(0~(IailSD02K-Xf((KH4OeJ@H}b#-uC!np(`Wz{px_NB^uPi7 z8At0e%!=2qiFrH%b7^l=xHzb6^4$?iPfY4#XQ27=kxI z(SiZ6018d3ND;iS10%rTm~&`st*F2P2duyeEa2r(|3QIi#DEGjaKbhXA_i9~zyp={0A^5vX%K*{4G`ye9|D32(CPq0fI>3|{1DPIc&GsZ06XG~rVjuB literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/42.gif b/sources/awesomewidgets/weather/42.gif new file mode 100644 index 0000000000000000000000000000000000000000..f805f62fa94d1127ad353ed251c1a08f9e7bb7bd GIT binary patch literal 2483 zcmV;k2~74!Nk%w1VKe|V0Qdg@|NsB|{QUa*`t|ko`1ts`z0TFv=JWIO=IQdz(c*i1 zd+F`=f`Wpos;ZThm4kzel#`sTt;5RA-tqDA=;-K{maeg~#`5&}?(zBM<>kf6)avT$ zwzkc+x60Ys+5P|j_V)Js{QleB>ZYZ=#KgpjiHYv<_N}e0c6NN@gDI|#>U3O!^51MoPBzY z+uGW$uCBYgyW-;Fyu7@Df0FR?`nb5bSy@{5`v17P&EetU$jR2p$;qXqrJI?u`TPHE zZEo-H@4mj$v9ZbN>-N^z=woAKwzjr&b91AmxT2%J=j!#))8UVgmaD43#m3CV#@dpS zshgXd_W1p-uEeIMrf+X?rlr4+kB@0-YrewH-{0TG$=i*LsiC2}*xTjY;O(EDxzp9< z>Fe{IowdTn)uExGy}ii9#@5Np-ShSQuCc?Jm$J{#�)Vm6Wi+!PStCsq60dz`(%D z&e_7n+R@Y9&CcDeufLm_rr+c3jEs%l-QCgB)upGnlarI(;p?26wEFx0`1<|z_y4)R z%Z-bs!NbOvma4kC(ed;ChlHbvh^32(qQb-2+urW8w8(ODb<57+`}_Tslda$3?Ww7& z^!54L-si=}(x|7tk&vwT`TU!mwC3sUW@c%FgM)y8f{BNdhK8S#l9rd3n3$NGiHDUu`si~@~tgNo3rM9G`x}>4Ms;axGth%nP zxvZ?es;s=PvA40Yv9hzawzjpkwYI6K!m6ynu&&6nwZpf&$hy45y}!@Bz170P!pX|c z!NSkN#L>;p+tbw3+}zyJ&f?M1A^!_OL{CCRI!RJ7E-(V#?EoS91OWg5{{Soi0000q05kvq2>$^82^>hU zpuvL(6DnNDu%W|;5F<*QNRc8FZ&9YHtH@E{25&Bk6afII0SPD_A#UKa0oq6a0E*Bl z;_uwFlne<_v!Trf5STEFT#!l6#vznA5nj1qK*9x}KtF)_VBi{_WZ;evNJ@|b6#zA! z0=QtSpGaFtCQT4A#!m%o$3So$FoTKAmql#FkzinuIXpkf5<7*bLJ4m_wsHg!4M9)< zABs#e5Qzha2oYY4wI$)plL~GnxhkfZq9Z^gDo?&B*d}s6DEc@Z{BQ^XC@8@JYSUEq!=-5sdUwFM&)#%LN5Y(}E|{ zyo1mL(|`a#3oZbF%MH0`V1NO8+)w}xsZ>xwAsobk$1`6TVgghEkkXV;jsY-vV75d#%r2U(2ZQ4Sy= z5CB908bpQxfE+wiff}30)Jsqom|%-7lNiE710E7kwSYVAHHN z161T8OblrZ;e-^&1Vg+N!gS#P1x%da02Iq36o3bEp>co%zZF67KO10zBVe$F0B+zA zCjh|_O0WUvZD0WZ*Z~MiFoPDfpad>ph$B33h<|wF1TpyEKu*vA7f>Mp!6*R?05A5KK5k6#s(J1rju13j!g)38>Ho4*);`P?*LB zhHwNY7(pNZZ~+W{umKlr048CuL){oM03&!{0uBITCk{a{7xcgdT~NReI)MfXIHClO zaD)pW_zw_-ZyG_F!U}ve#)D))9Z~=!05+h25|n@natXi@Vi1fb{Gba?NP`zVKm{ip zpdfh^0|-tajA=MR3Pe!IA^hkCCTxHTPz1pMmgfjNke~;YP(TZuP=qMNU;+ez0u!JR z25(Tp3F_Kzpm2y4c!POFI0Ovl;Qs|jP@x4=5TO80U<7ptKpk6fK>ZjJg#a)B z1p4sC;s~;`A0UAV9%$!5KtQkqSh0r=X+aE}5XprS1Ox$CnE+&vL4<6e1t4_@2!gP( z18iUe6bM2~55fc&I02ZBz#dlwGJ|P2!2#Zw13VDIf)@0k3IB)!07?)9u7F^bMp%Ii zI+>6JI>B3Wz+h5}(0~(IailSD02K-Xf((KH4OeJ@H}b#-uC!np(`Wz{px_NB^uPi7 z8At0e%!=2qiFrH%b7^l=xHzb6^4$?iPfY4#XQ27=kxI z(SiZ6018d3ND;iS10%rTm~&`st*F2P2duyeEa2r(|3QIi#DEGjaKbhXA_i9~zyp={0A^5vX%K*{4G`ye9|D32(CPq0fI>3|{1DPIc&GsZ06XG~rVjuB literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/43.gif b/sources/awesomewidgets/weather/43.gif new file mode 100644 index 0000000000000000000000000000000000000000..1db832e7a1bc62ea06865fc4110cffb3158bad0e GIT binary patch literal 2789 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/45.gif b/sources/awesomewidgets/weather/45.gif new file mode 100644 index 0000000000000000000000000000000000000000..593964013fbb9006bde2ed412476c58264b7dc3a GIT binary patch literal 980 zcmV;_11tPTNk%w1VKe|V0J8u9pQETKDlPr}_xktU)z#P1&$W@s*Q1ztg^QE7y1-*) zZ@{{p;^D=5dUv7k{Qv*|A^8LW000jFEC2ui05kwJ000F4@X1N5y*TTAh5z8kja)bk zW=O7+dA=~JvKtr|Os>ZuoqaH!P&i<`dcF$qgd65?g+bGJ6eL@M*K;c@Oc`G9NtE3`KH)FvESLazpPFxHJ2T)*X1#e>>D`qD;O*01XWY+-?i7se6Xi9j)Sf1quKO1n&t6-ipPQ2S$#`=zGHm2=VU%64<8T z(z86|%E?I93m1b1000C`P#|7{b^s74sAX_bLRAa@e`Hxk3IWE5|KhcSr!hc5KAVgI zFsCF-m;(w-M!cBuq`(9X6etJ~pn*YJG${nav@RvU0t7Bvyyy?WP@zN*;h`4N+6g{5 z-2oIBk!&}18if|zR48eSNDFdKeb=)r-Jo(awp_~xWIk(waP}M+v9QT_-qhN)xUH`$ zGJpphXh(IR&Y;}%sueg;rBH5uH4w}<15eFk1g-)BR)MBD`gG~fVHM5PF0j5A&}BYrsE$XX2!IIv)k zF1Z+^kS-zcqDuxGN#p@Sy0an%LXH<@0Y(OZlLH30bbyblDOqI$3?!+*0Z(F(WKk$2 zU<&~+78Io+2WS~(4om{o<^p9}V5CL>gdilC#*Jx&5Iv4r#g_@z;NgBR5+FdKeF{JT z4njr|;NL}Y8AR0u*t0zA4G|)MmuKV0g$Ll+AOQ-YFojn9we}U zqZIf{T)5zluy literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/46.gif b/sources/awesomewidgets/weather/46.gif new file mode 100644 index 0000000000000000000000000000000000000000..55b5126522a02a4043b8fb3854ff58fc05641ca3 GIT binary patch literal 996 zcmV%~$gq8L6_5c6>A^8LW000jFEC2ui05kwJ000F4@X1N5ognLdyZ_ZDjsR$a zqM)wpc)nQ1&UBl>rZy{lFDO422iMuC20dVJz(n$FC1ObSTQ;vw#UPP@N@IXyQjuV4 z$691rrTOZrOI{g^odX4J+#5YcZkuF&e{44}R91aw26K#m0|o;vhG8maP6-AE2L=k6 zihYPC&Vw|G$>ls}IS1kuqB48a7vypW86j|RyeIy?d9zXSvb49^JW2MyI0IpRXA z3pa0+66lkL?-?}$=I||mMRAe4Q1LG4825_-f`-)pTJ8I{;2Eq11dnmaXn_hjU>^@S zD~Etu0DR7DrUb<@#0p^fJbr8#ttPJn`pz*3aA3iwPVm?utS9Uo&YBK$@@lY9B!dJ2 zxNI?4$bti23V`j)=g=lEXIsm$;`q@V1E)P7oMZSbU&CtEo~e^I_kcZN4Ho1LfMBRT zbsQZC<_e6kxyE}7^NLhoowcC<@p3FB<`D;&|L%wXj_=A_mD zDFe8?3M6pw8o=ezbI)O|Hd~r*-hgkadwU?kYYB$^u|CS&a_z0v0J>%RZ+JHfUHj>4 zyu7zuk-RAalwQqTfC2}uVIffTwoZWOnzG~gW>T4?FF=^#i_gRPLO~};;}-3Gp@9fZoU=F1^{lXkjpJ$nHWYe z28oq1P6GRM(^O)u+zac&JqBc|J{9=CsEE literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/47.gif b/sources/awesomewidgets/weather/47.gif new file mode 100644 index 0000000000000000000000000000000000000000..aac25aaca3ea41a0ab727f76a7b7fdab6d104554 GIT binary patch literal 972 zcmV;-12gI|!MdG?ijTCp zzG-W6mWN*A;KbkJSI}A?=$n^MH#@fpWps<6>9GPQl2!jn}S9V=bZ7_aERdWpi3}p-fgKA}pd?$^7 zNN|M#mXwoqTcTf#Z&#uL39hfNunVGt47Z1Ld3&4#4gm%V!Uhh-#KjKB1_rLTlXrt& zLOBBg!^p|X%f`#XtqZTv0eXu?4#UgG$OFp73htr_3zgBf(&ZP`-Rj23>B7SlxLQDP zRJ2KoLY(84ZJV!j!30PoNKqD^F1V(F5T#%n#EuaEg9Q+9OVXfGg)pAHx5|0YIVN5(pM3N&qcqmU<$hgG!?X z2ZjY(s|pgJJi%Ng-m*2fO0;o5EhI3^v8vz7M=5GXJlB#EG)+VEm3TUEJXr$?PRzTx zz%x)xWm8BRS+McrnB}P^>5RaoEp-z)rU2P6xXa3~W2UIv@UuHy3MgQ6;iWaCv%s}d zZe4dtEOZg&k&bVIys8A1BSmVuz3TaOg%#HS8p2HwS7y2qCRuu2$)gzpCJm@YffAtQ zpJ7KOcN|yXNF-5WhIF9?fndxw5k->)z}%o7b~rJe1(|txVwFf{=VNvVVqwFOCR!=xnBCntriUb! z=)p*5E^xq^9{M2;ERf+E*ixHztGabq6?flC}yMiV? z`sT6QPEe>}s`e=>u{H%zDFfbio36PB$oecn23R|&1GQEwX*C3udoQq{(r7>f#16W^ u00$&RZjr$Vd+z`ONh*W2)k3+dU%XyijsfA?G^?8TD&(+V2B+*n1OPk2%eF=U literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/5.gif b/sources/awesomewidgets/weather/5.gif new file mode 100644 index 0000000000000000000000000000000000000000..7881d4114e5cdcfbcfae41b7151848703a54b9df GIT binary patch literal 2393 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 AO#lD@ diff --git a/sources/awesomewidgets/weather/6.gif b/sources/awesomewidgets/weather/6.gif new file mode 100644 index 0000000000000000000000000000000000000000..e8f808b24b1ed9e7773620a8a57018cb90505f43 GIT binary patch literal 2459 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 literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/8.gif b/sources/awesomewidgets/weather/8.gif new file mode 100644 index 0000000000000000000000000000000000000000..63645a60bdda5974b199e0b989810cb367e1224b GIT binary patch literal 2145 zcmV-n2%h&xNk%w1VKe|V0Qdg@{{H^`{r&g%_xk$!>FMd}>gr~U=Xs*GmX?;TuCDX{ z|5k*W^Yin*zP_WQqk4LJmZq((t*wZrv{h<#Y;A3As>t~G_^Yd{q@<*{xVW*gvGw)! zTUuJRwYBEv=clHowzjs2-T&X;-;0=>e1?mLhKAJC)XvV%(fI$IoSlM#f?1BJ;Naly z?(SrIg)=-&?d|RG@bI9Zpv}$AWs<17ySu!+yu-u8+1c4RHZ)30O0%=G(9qDRsHkOS zW#r`K%*xSUlmB^=oZQ^po}Qk>#KekG|XLUw!#;K{PZ*g+?`T86tI7LH3B0qRgNku|OR8vt< zTvk(HUteTlUr%LkT4Qc%XlP|+W@c+_acX99aByC1abYjop>mX^dycbjh|hY9 zz-ffhT%^W)x6oXW{%XJHZO8I^+W&gu|Ad5ujEs$ola`c}l#`Q`n3a>2mztHCnwy%L zot~bcpr3}Fr-+fdhMBycpR~4tE#N6t*o}9sJN@Hy05XbvaqnSva+|dvaz+dx3;#px3;~xx4gQzy}iALzuULA zz__)*v9!s$zslq&>gwt0>g@0E@a^^Z?f?Jr z@$>or|NsC0A^!_OL{CCRI!RJ7E-(V#?EoS91OWg5{{Soi0000q05kvq2>$^82^>hU zpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+{m$`$B!T%0tf(LV1Nx91dc2zFaXJq7D!;? z#NeNdOPexr!VwFTixdB%xo`mj;z*YR0$32Rfho!j7VfQZwE)|)6=PV9S+!-67%`FL zZE1yyPRfJ;01RM&Po9<;XX2ijF+odqW-u*a$w51Y*Cijh*x01 zWJJJLH(oq>)ef`)bw&CiLk^bcXhh*#IZ@{s8 z!Q)J{3o>vyxDYK`11?8Ih^T@M7&;+WNKnrNiOir5H4V`61R7|V0|y5(>=8{7ESyD9 z05RNy16&|PfPoAjMze!`Jjip;J#!F)0)W7v;0OhCBy&s=b3j543cA2SM+Y_BV8T5c z1W=Fw1+WlL8Q3J?04{6bf{P42M4$mSCzx;qG{G|vvU1F}fr1|4t6f&~W4VRObUR46b)6eRdlOB9RnLyrz?EFq2p zgD4W^4j^E|LjiqUcv1`a3~@pO5fIUZ5w93QM`sbRX#*X|1pi=56pbjbj|}MqFij4! zB*IPrig56ugc+Pb0GuXmP=E+p6cJ5)ve2Pw7YHba&3&C!F-s0~L?Dko_%!hf2N66F z%{@zS;G_&7G$Bt6EG3K2hBoX$1TM04_9UR#+)%~|7ep`zHWXkX4+t{I&;$>XbnwcI zGWdYS1!WxZ13m)8+mZnI7Ej4yy6B7F1Zv>2{Nc~L;xl% zAwvRZ$WsLj8))p305L3k0yY_d>_Bo6G#yP1N#gQ=07OVp!Wlc@(|~ePL|_Cq0nG3~ z!qJ?eg$VF^DgXm>;=ltJ*hJ%Dav03l0SE~sAc;JjME@Ye61X$~AqELFfB_cKB=AN8 z(J-flJS_+vzyL(wGsKZLfE*tYBPVdT4N@pW2R7IwtOXsWHW0TPOZd4%1~<%bL={07 z#_o#>k zYO#bObnqW66NqmT@(c=SKmZmAzz>#45N{ZO5%ycU=e(j!V`SJ2SNf+hcM(|4;DB`0HB}-LCB+x3;}`_!0^C?2*7J7JcvCEkcL0l zz=aTD02Pv8gfu2305AZfBC~*qCB%^;eK@Spo0k(G7^PELlS4$=0gMk16o#O X04?xmNG3|ridyud7|m!#0s;U#1EuwI literal 0 HcmV?d00001 diff --git a/sources/awesomewidgets/weather/9.gif b/sources/awesomewidgets/weather/9.gif new file mode 100644 index 0000000000000000000000000000000000000000..b08ac3b2840bf313182ecc6e88f7484597c68802 GIT binary patch literal 2041 zcmdUuk3Z811INGLZES2~C`MEB6b(|+thdtbM>L>xX=`g6A0HnY8hZKiWq*JF z#KeSDDt*29dTMHVVPT=HtnBI2r}ysN)9G~G-QBR4X=!OqP0iTY*z)r7ojZ3%M@RGX^NWj%S65e;mX=mlR_f~N^m=_kK|ynKb3;SJ z?c2ANN+plS6N|-jb91w^v(KJAgE-Le@NjN!E)2t&nVGeXCPEJ--UeWRV>zDW?*>w#WEz--fyXmsKX*~~e2G#sR9{>7vUP%eBxU}TPjnbN% zf{Mz@ib`QkZB=c3&F9{?T5i?1RZ5y}iaTpX^6J+9`mP7up8k^Feo5o))+T9ldq-2J zw6ndvwN={D(b4piOww|7v^$vfnCI=cH>?%wa{AG&kzVa44?wcYCKo=3NabVCCQ zct8OuM;nHxE5|14f1SM#D?}=tNcX$&nNjlVe_Ljk>gWEfd;Yq?_^x^GZPUW4=+*lc zm92m`Kn2_VN$6-JO6n^tJP>me|bDUrqhkk|7 zhwRs__e%hb3E)_eSTd0! z4`b&UqmhYKg#@?II+naq%_r_ooYlxBBc)`3<%!L<05*+7mI|9PLEJ$!r)Ph!3!!=J(Y!ZQG-FVxIC9F*D?9!pN%1(liOw>s%F%8-BM zx7qmW+VY_(D<`Xm=Tz3Du`&dXc3!}tBw28|7Jed#gLflokT^G>Y&vDDkV^Fa_;DJE z+A1JcMx%DX5I&n53!>e)FyKANUC>)nm^37kv`l6ag4O^A-d;cjkVI}80<@(nX`oqv z7835mQSKYTS^@?OpXV7&b80W5u;@XB_ z6ottBI382H&Cdj5EcU|5;;Zhk{UbR@Y=6?n`aH;W>Du zwa*p@7dCjj-3cN#_c_6qgELsrP5#HXNHpmK6+$@G3FbllR_972@aF{v=8_)Eu(ZdC zK+C;LS9&OZiy~0vG5Nk4^P!x~IBF|wXZ44Nia>BzAI!lVnu=navJ5>)0L(v_QdN(5 zKLNRpXJ^zZ!$zBkj=!W?9vLjY5lB~g7@Wpa_l_$hahQJtkTEPOAonRT{a*r zTmW#7jxrh-vgJ7KuQ|SSAriecDhr~UQv!6#cFe%&7V3}H-DXyUYfAdcpu2#E<->Eq z1bhIS^LDle!hZ1s%$9&4Kov3uVwBhIdT}QR-ucl6B?XgE9_kcgq(^!;W{cHkmRgRv ztNu{#vBu4j)p?X1x!mJL2DBHAwE{(!b2|W=ct0BG_9Pd5flV%1<2pydf_nC_gAg#Q z_HrwV+yjE!Pz7FJq+t0(!{(DPEf43*VfTSp?2c39VRlMBo~pBHk5%IQ1q4eS#~MMy zQ2cGso{J(^c{F456#|2!_bS+#fg+XzFwckpt!Wxd_c*?@eZ-gEA`NP;g%BpB<8jGu zK>*C>lj8{W5L1nNg8n8T&g$(!mXEKZ!1h=?@;0QhxhN2@2nb8FB7@5@7c(q1#g!1N z-o&M8=PDr3k%b|L%Tb2}$*wzDCMw|J2|g*R>Eo?*#)#F&NBrt)~;y2TJu$t QZ%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; diff --git a/sources/extsysmon/sources/weathersource.cpp b/sources/extsysmon/sources/weathersource.cpp index f805432..5ff30a0 100644 --- a/sources/extsysmon/sources/weathersource.cpp +++ b/sources/extsysmon/sources/weathersource.cpp @@ -92,7 +92,7 @@ QVariantMap WeatherSource::initialData(QString source) const = QString("Atmospheric pressure for '%1'") .arg(extWeather->itemByTagNumber(ind)->uniq()); data[QString("type")] = QString("integer"); - data[QString("units")] = QString("hPa"); + data[QString("units")] = QString("mb"); } else if (source.startsWith(QString("weather/temperature"))) { data[QString("min")] = 0.0; data[QString("max")] = 0.0; @@ -101,6 +101,14 @@ QVariantMap WeatherSource::initialData(QString source) const .arg(extWeather->itemByTagNumber(ind)->uniq()); data[QString("type")] = QString("float"); data[QString("units")] = QString("°C"); + } else if (source.startsWith(QString("weather/timestamp"))) { + data[QString("min")] = QString(""); + data[QString("max")] = QString(""); + data[QString("name")] + = QString("Timestamp for '%1'") + .arg(extWeather->itemByTagNumber(ind)->uniq()); + data[QString("type")] = QString("QString"); + data[QString("units")] = QString(""); } return data; @@ -127,6 +135,8 @@ QStringList WeatherSource::getSources() QString("weather/%1").arg(item->tag(QString("pressure")))); sources.append( QString("weather/%1").arg(item->tag(QString("temperature")))); + sources.append( + QString("weather/%1").arg(item->tag(QString("timestamp")))); } return sources; diff --git a/sources/translations/awesome-widgets.pot b/sources/translations/awesome-widgets.pot index 8f500e6..437a528 100644 --- a/sources/translations/awesome-widgets.pot +++ b/sources/translations/awesome-widgets.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2015-10-20 01:21+0300\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -110,9 +110,36 @@ msgstr "" msgid "Export configuration" msgstr "" +msgid "Export" +msgstr "" + +msgid "Success" +msgstr "" + +msgid "Please note that binary files were not copied" +msgstr "" + +msgid "Ooops..." +msgstr "" + +msgid "Could not save configuration file" +msgstr "" + msgid "Import configuration" msgstr "" +msgid "Import" +msgstr "" + +msgid "Import plasmoid settings" +msgstr "" + +msgid "Import extensions" +msgstr "" + +msgid "Import additional files" +msgstr "" + msgid "Font" msgstr "" @@ -378,6 +405,9 @@ msgstr "" msgid "This software uses: %1" msgstr "" +msgid "Special thanks to %1" +msgstr "" + msgid "Select font" msgstr "" @@ -399,33 +429,6 @@ msgstr "" msgid "There are updates" msgstr "" -msgid "Export" -msgstr "" - -msgid "Success" -msgstr "" - -msgid "Please note that binary files were not copied" -msgstr "" - -msgid "Ooops..." -msgstr "" - -msgid "Could not save configuration file" -msgstr "" - -msgid "Import" -msgstr "" - -msgid "Import plasmoid settings" -msgstr "" - -msgid "Import extensions" -msgstr "" - -msgid "Import additional files" -msgstr "" - msgid "AC online" msgstr "" diff --git a/sources/translations/en.po b/sources/translations/en.po index 42d6afa..c40d104 100644 --- a/sources/translations/en.po +++ b/sources/translations/en.po @@ -1,13 +1,13 @@ # Copyright (C) 2014 # This file is distributed under the same license as the PyTextMonitor package. # -# Evgeniy Alekseev , 2014, 2015. +# Evgeniy Alekseev , 2014, 2015, 2016. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2015-10-20 01:21+0300\n" -"PO-Revision-Date: 2015-10-20 01:21+0300\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" +"PO-Revision-Date: 2016-01-26 21:48+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: English \n" "Language: ru\n" @@ -111,9 +111,36 @@ msgstr "Drop key cache" msgid "Export configuration" msgstr "Export configuration" +msgid "Export" +msgstr "Export" + +msgid "Success" +msgstr "Success" + +msgid "Please note that binary files were not copied" +msgstr "Please note that binary files were not copied" + +msgid "Ooops..." +msgstr "Ooops..." + +msgid "Could not save configuration file" +msgstr "Could not save configuration file" + msgid "Import configuration" msgstr "Import configuration" +msgid "Import" +msgstr "Import" + +msgid "Import plasmoid settings" +msgstr "Import plasmoid settings" + +msgid "Import extensions" +msgstr "Import extensions" + +msgid "Import additional files" +msgstr "Import additional files" + msgid "Font" msgstr "Font" @@ -383,6 +410,9 @@ msgstr "Translators: %1" msgid "This software uses: %1" msgstr "This software uses: %1" +msgid "Special thanks to %1" +msgstr "Special thanks to %1" + msgid "Select font" msgstr "Select font" @@ -404,33 +434,6 @@ msgstr "Click \"Ok\" to download" msgid "There are updates" msgstr "There are updates" -msgid "Export" -msgstr "Export" - -msgid "Success" -msgstr "Success" - -msgid "Please note that binary files were not copied" -msgstr "Please note that binary files were not copied" - -msgid "Ooops..." -msgstr "Ooops..." - -msgid "Could not save configuration file" -msgstr "Could not save configuration file" - -msgid "Import" -msgstr "Import" - -msgid "Import plasmoid settings" -msgstr "Import plasmoid settings" - -msgid "Import extensions" -msgstr "Import extensions" - -msgid "Import additional files" -msgstr "Import additional files" - msgid "AC online" msgstr "AC online" diff --git a/sources/translations/es.po b/sources/translations/es.po index 4984b2a..b1b6c63 100644 --- a/sources/translations/es.po +++ b/sources/translations/es.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Awesome widgets\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2015-10-20 01:21+0300\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" "PO-Revision-Date: 2015-09-26 22:07+0000\n" "Last-Translator: Ernesto Avilés Vázquez \n" "Language-Team: Spanish (http://www.transifex.com/arcanis/awesome-widgets/" @@ -113,9 +113,38 @@ msgstr "Borrar caché de claves" msgid "Export configuration" msgstr "" +msgid "Export" +msgstr "" + +msgid "Success" +msgstr "" + +msgid "Please note that binary files were not copied" +msgstr "" + +msgid "Ooops..." +msgstr "" + +msgid "Could not save configuration file" +msgstr "" + msgid "Import configuration" msgstr "" +msgid "Import" +msgstr "" + +msgid "Import plasmoid settings" +msgstr "" + +#, fuzzy +msgid "Import extensions" +msgstr "Extensiones" + +#, fuzzy +msgid "Import additional files" +msgstr "Filtros adicionales" + msgid "Font" msgstr "Tipo de letra" @@ -386,6 +415,9 @@ msgstr "Traductores: %1" msgid "This software uses: %1" msgstr "Este software usa: %1" +msgid "Special thanks to %1" +msgstr "" + msgid "Select font" msgstr "Elegir tipo de letra" @@ -407,35 +439,6 @@ msgstr "Haz clic en «Ok» para descargar" msgid "There are updates" msgstr "Hay actualizaciones disponibles" -msgid "Export" -msgstr "" - -msgid "Success" -msgstr "" - -msgid "Please note that binary files were not copied" -msgstr "" - -msgid "Ooops..." -msgstr "" - -msgid "Could not save configuration file" -msgstr "" - -msgid "Import" -msgstr "" - -msgid "Import plasmoid settings" -msgstr "" - -#, fuzzy -msgid "Import extensions" -msgstr "Extensiones" - -#, fuzzy -msgid "Import additional files" -msgstr "Filtros adicionales" - msgid "AC online" msgstr "Alimentación conectada" diff --git a/sources/translations/fr.po b/sources/translations/fr.po index c11dd66..34ddcf5 100644 --- a/sources/translations/fr.po +++ b/sources/translations/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2015-10-20 01:21+0300\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" "PO-Revision-Date: 2015-07-31 22:16+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: French \n" @@ -115,9 +115,36 @@ msgstr "" msgid "Export configuration" msgstr "" +msgid "Export" +msgstr "" + +msgid "Success" +msgstr "" + +msgid "Please note that binary files were not copied" +msgstr "" + +msgid "Ooops..." +msgstr "" + +msgid "Could not save configuration file" +msgstr "" + msgid "Import configuration" msgstr "" +msgid "Import" +msgstr "" + +msgid "Import plasmoid settings" +msgstr "" + +msgid "Import extensions" +msgstr "" + +msgid "Import additional files" +msgstr "" + msgid "Font" msgstr "Police" @@ -398,6 +425,9 @@ msgstr "Traducteurs: %1" msgid "This software uses: %1" msgstr "Ce logiciel utilise: %1" +msgid "Special thanks to %1" +msgstr "" + msgid "Select font" msgstr "Sélectionner une couleur" @@ -422,33 +452,6 @@ msgstr "Cliquer sur \"Valider\" pour télécharger" msgid "There are updates" msgstr "Des mises à jour sont disponibles" -msgid "Export" -msgstr "" - -msgid "Success" -msgstr "" - -msgid "Please note that binary files were not copied" -msgstr "" - -msgid "Ooops..." -msgstr "" - -msgid "Could not save configuration file" -msgstr "" - -msgid "Import" -msgstr "" - -msgid "Import plasmoid settings" -msgstr "" - -msgid "Import extensions" -msgstr "" - -msgid "Import additional files" -msgstr "" - msgid "AC online" msgstr "Alimentation branchée" diff --git a/sources/translations/nl.po b/sources/translations/nl.po index aaaadaf..9c4a562 100644 --- a/sources/translations/nl.po +++ b/sources/translations/nl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Awesome widgets\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2015-10-20 01:21+0300\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" "PO-Revision-Date: 2015-08-20 22:52+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Dutch \n" @@ -116,10 +116,38 @@ msgstr "" msgid "Export configuration" msgstr "Configuratie" +msgid "Export" +msgstr "" + +msgid "Success" +msgstr "" + +msgid "Please note that binary files were not copied" +msgstr "" + +msgid "Ooops..." +msgstr "" + +#, fuzzy +msgid "Could not save configuration file" +msgstr "Configuratie" + #, fuzzy msgid "Import configuration" msgstr "Configuratie" +msgid "Import" +msgstr "" + +msgid "Import plasmoid settings" +msgstr "" + +msgid "Import extensions" +msgstr "" + +msgid "Import additional files" +msgstr "" + msgid "Font" msgstr "Lettertype" @@ -402,6 +430,9 @@ msgstr "Vertalers: %1" msgid "This software uses: %1" msgstr "Deze software gebruikt: %1" +msgid "Special thanks to %1" +msgstr "" + msgid "Select font" msgstr "Lettertype selecteren" @@ -424,34 +455,6 @@ msgstr "Klik op \"OK\" om te downloaden" msgid "There are updates" msgstr "Er zijn updates" -msgid "Export" -msgstr "" - -msgid "Success" -msgstr "" - -msgid "Please note that binary files were not copied" -msgstr "" - -msgid "Ooops..." -msgstr "" - -#, fuzzy -msgid "Could not save configuration file" -msgstr "Configuratie" - -msgid "Import" -msgstr "" - -msgid "Import plasmoid settings" -msgstr "" - -msgid "Import extensions" -msgstr "" - -msgid "Import additional files" -msgstr "" - msgid "AC online" msgstr "AC online" diff --git a/sources/translations/pt_BR.po b/sources/translations/pt_BR.po index 24bf696..9cb71f1 100644 --- a/sources/translations/pt_BR.po +++ b/sources/translations/pt_BR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2015-10-20 01:21+0300\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" "PO-Revision-Date: 2015-07-31 22:21+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Russian \n" @@ -115,10 +115,38 @@ msgstr "" msgid "Export configuration" msgstr "Configuração" +msgid "Export" +msgstr "" + +msgid "Success" +msgstr "" + +msgid "Please note that binary files were not copied" +msgstr "" + +msgid "Ooops..." +msgstr "" + +#, fuzzy +msgid "Could not save configuration file" +msgstr "Configuração" + #, fuzzy msgid "Import configuration" msgstr "Configuração" +msgid "Import" +msgstr "" + +msgid "Import plasmoid settings" +msgstr "" + +msgid "Import extensions" +msgstr "" + +msgid "Import additional files" +msgstr "" + msgid "Font" msgstr "Tamanho da fonte" @@ -398,6 +426,9 @@ msgstr "Tradutores: %1" msgid "This software uses: %1" msgstr "Este software usa: %1" +msgid "Special thanks to %1" +msgstr "" + msgid "Select font" msgstr "Selecionar fonte" @@ -420,34 +451,6 @@ msgstr "Clique \"Ok\" para baixar" msgid "There are updates" msgstr "Há atualizações disponíveis" -msgid "Export" -msgstr "" - -msgid "Success" -msgstr "" - -msgid "Please note that binary files were not copied" -msgstr "" - -msgid "Ooops..." -msgstr "" - -#, fuzzy -msgid "Could not save configuration file" -msgstr "Configuração" - -msgid "Import" -msgstr "" - -msgid "Import plasmoid settings" -msgstr "" - -msgid "Import extensions" -msgstr "" - -msgid "Import additional files" -msgstr "" - msgid "AC online" msgstr "Carregador conectado" diff --git a/sources/translations/ru.po b/sources/translations/ru.po index d6125a1..97a8e6b 100644 --- a/sources/translations/ru.po +++ b/sources/translations/ru.po @@ -1,13 +1,13 @@ # Copyright (C) 2014 # This file is distributed under the same license as the PyTextMonitor package. # -# Evgeniy Alekseev , 2014, 2015. +# Evgeniy Alekseev , 2014, 2015, 2016. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2015-10-20 01:21+0300\n" -"PO-Revision-Date: 2015-10-20 01:22+0300\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" +"PO-Revision-Date: 2016-01-26 21:49+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Russian \n" "Language: ru\n" @@ -111,9 +111,36 @@ msgstr "Сбросить кеш ключей" msgid "Export configuration" msgstr "Экспорт настроек" +msgid "Export" +msgstr "Экспорт" + +msgid "Success" +msgstr "Успешно" + +msgid "Please note that binary files were not copied" +msgstr "Пожалуйста, обратите внимание, что бинарные файлы не были скопированы" + +msgid "Ooops..." +msgstr "Ууупс..." + +msgid "Could not save configuration file" +msgstr "Не могу сохранить файл настроек" + msgid "Import configuration" msgstr "Импорт настроек" +msgid "Import" +msgstr "Импорт" + +msgid "Import plasmoid settings" +msgstr "Импорт настроек плазмоида" + +msgid "Import extensions" +msgstr "Импорт расширений" + +msgid "Import additional files" +msgstr "Импорт дополнительных файлов" + msgid "Font" msgstr "Шрифт" @@ -383,6 +410,9 @@ msgstr "Переводчики: %1" msgid "This software uses: %1" msgstr "Данное приложение использует: %1" +msgid "Special thanks to %1" +msgstr "Отдельно спасибо %1" + msgid "Select font" msgstr "Выберете шрифт" @@ -404,33 +434,6 @@ msgstr "Нажмите \"Ok\" для загрузки" msgid "There are updates" msgstr "Найдены обновления" -msgid "Export" -msgstr "Экспорт" - -msgid "Success" -msgstr "Успешно" - -msgid "Please note that binary files were not copied" -msgstr "Пожалуйста, обратите внимание, что бинарные файлы не были скопированы" - -msgid "Ooops..." -msgstr "Ууупс..." - -msgid "Could not save configuration file" -msgstr "Не могу сохранить файл настроек" - -msgid "Import" -msgstr "Импорт" - -msgid "Import plasmoid settings" -msgstr "Импорт настроек плазмоида" - -msgid "Import extensions" -msgstr "Импорт расширений" - -msgid "Import additional files" -msgstr "Импорт дополнительных файлов" - msgid "AC online" msgstr "AC подключен" diff --git a/sources/translations/uk.po b/sources/translations/uk.po index 07013d9..330f72e 100644 --- a/sources/translations/uk.po +++ b/sources/translations/uk.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2015-10-20 01:21+0300\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" "PO-Revision-Date: 2015-09-27 12:37+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Ukrainian \n" @@ -114,10 +114,40 @@ msgstr "Скинути кеш ключів" msgid "Export configuration" msgstr "Налаштування" +msgid "Export" +msgstr "" + +msgid "Success" +msgstr "" + +msgid "Please note that binary files were not copied" +msgstr "" + +msgid "Ooops..." +msgstr "" + +#, fuzzy +msgid "Could not save configuration file" +msgstr "Налаштування" + #, fuzzy msgid "Import configuration" msgstr "Налаштування" +msgid "Import" +msgstr "" + +msgid "Import plasmoid settings" +msgstr "" + +#, fuzzy +msgid "Import extensions" +msgstr "Розширення" + +#, fuzzy +msgid "Import additional files" +msgstr "Додаткові фільтри" + msgid "Font" msgstr "Шрифт" @@ -398,6 +428,9 @@ msgstr "Перекладачі: %1" msgid "This software uses: %1" msgstr "Ця програма використовує: %1" +msgid "Special thanks to %1" +msgstr "" + msgid "Select font" msgstr "Оберіть шрифт" @@ -420,36 +453,6 @@ msgstr "Натисніть \"Ok\" для завантаження" msgid "There are updates" msgstr "Знайдені оновлення" -msgid "Export" -msgstr "" - -msgid "Success" -msgstr "" - -msgid "Please note that binary files were not copied" -msgstr "" - -msgid "Ooops..." -msgstr "" - -#, fuzzy -msgid "Could not save configuration file" -msgstr "Налаштування" - -msgid "Import" -msgstr "" - -msgid "Import plasmoid settings" -msgstr "" - -#, fuzzy -msgid "Import extensions" -msgstr "Розширення" - -#, fuzzy -msgid "Import additional files" -msgstr "Додаткові фільтри" - msgid "AC online" msgstr "AC підключений" diff --git a/sources/translations/zh.po b/sources/translations/zh.po index 5a11637..20de05f 100644 --- a/sources/translations/zh.po +++ b/sources/translations/zh.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2015-10-20 01:21+0300\n" +"POT-Creation-Date: 2016-01-26 21:48+0300\n" "PO-Revision-Date: 2015-07-31 22:24+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Russian \n" @@ -111,9 +111,36 @@ msgstr "" msgid "Export configuration" msgstr "" +msgid "Export" +msgstr "" + +msgid "Success" +msgstr "" + +msgid "Please note that binary files were not copied" +msgstr "" + +msgid "Ooops..." +msgstr "" + +msgid "Could not save configuration file" +msgstr "" + msgid "Import configuration" msgstr "" +msgid "Import" +msgstr "" + +msgid "Import plasmoid settings" +msgstr "" + +msgid "Import extensions" +msgstr "" + +msgid "Import additional files" +msgstr "" + msgid "Font" msgstr "字体" @@ -397,6 +424,9 @@ msgstr "" msgid "This software uses: %1" msgstr "" +msgid "Special thanks to %1" +msgstr "" + msgid "Select font" msgstr "选择字体" @@ -418,33 +448,6 @@ msgstr "" msgid "There are updates" msgstr "" -msgid "Export" -msgstr "" - -msgid "Success" -msgstr "" - -msgid "Please note that binary files were not copied" -msgstr "" - -msgid "Ooops..." -msgstr "" - -msgid "Could not save configuration file" -msgstr "" - -msgid "Import" -msgstr "" - -msgid "Import plasmoid settings" -msgstr "" - -msgid "Import extensions" -msgstr "" - -msgid "Import additional files" -msgstr "" - #, fuzzy msgid "AC online" msgstr "外接电源使用中标签" diff --git a/sources/version.h.in b/sources/version.h.in index eec6074..10ab084 100644 --- a/sources/version.h.in +++ b/sources/version.h.in @@ -11,6 +11,7 @@ #define EMAIL "@PROJECT_CONTACT@" #define LICENSE "@PROJECT_LICENSE@" #define TRDPARTY_LICENSE "tasks,BSD,https://github.com/mhogomchungu/tasks;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/" // configuraion // graphical items api version From 1c78e0d779e9e9fdf4e0b597f99e597f681c3b75 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Sat, 30 Jan 2016 00:07:47 +0700 Subject: [PATCH 10/17] Initial support of templates and so on (#71) * Initial syntax is the following: * $template{{ some JS code here }} - simple template based on JS code inside. It works the same as lambda functions, but calculates only once. * aw_count(regex) - keys count found for given regex * aw_keys(regex, [separator]) - keys found for given regex and joined by using given separator * aw_names(regex, [separator]) - key names found for given regex and joined by using given separator (the same as previous but w\o $) The template and function syntax may be changed before release. * replace `foreach` to `for (auto foo : bar)` and update CONTRIBUTING.md accordingly --- CONTRIBUTING.md | 9 +- sources/awdebug.h | 6 - .../awesome-widget/plugin/awconfighelper.cpp | 14 +- .../plugin/awdataaggregator.cpp | 2 +- .../plugin/awdataengineaggregator.cpp | 4 +- sources/awesome-widget/plugin/awkeys.cpp | 192 ++++++++++++++---- sources/awesome-widget/plugin/awkeys.h | 4 + .../plugin/awkeysaggregator.cpp | 2 +- sources/awesomewidgets/abstractextitem.cpp | 4 +- sources/awesomewidgets/extscript.cpp | 4 +- sources/desktop-panel/plugin/dpadds.cpp | 8 +- sources/extsysmon/extsysmon.cpp | 8 +- sources/extsysmon/extsysmonaggregator.cpp | 28 +-- sources/extsysmon/sources/customsource.cpp | 2 +- sources/extsysmon/sources/gpuloadsource.cpp | 8 +- sources/extsysmon/sources/gputempsource.cpp | 8 +- sources/extsysmon/sources/hddtempsource.cpp | 5 +- sources/extsysmon/sources/networksource.cpp | 2 +- sources/extsysmon/sources/playersource.cpp | 8 +- sources/extsysmon/sources/processessource.cpp | 2 +- sources/extsysmon/sources/quotessource.cpp | 4 +- sources/extsysmon/sources/upgradesource.cpp | 2 +- sources/extsysmon/sources/weathersource.cpp | 4 +- 23 files changed, 224 insertions(+), 106 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3f94a57..88feee2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,14 +36,15 @@ for more details. To avoid manual labor there is automatic cmake target named ``` * `Q_PROPERTY` macro is allowed and recommended for QObject based classes. -* Qt macros (e.g. `signals`, `slots`, `Q_OBJECT`, etc) are allowed. +* Qt macros (e.g. `signals`, `slots`, `Q_OBJECT`, etc) are allowed. In other hand +`Q_FOREACH` (`foreach`) is not allowed use `for (auto foo : bar)` instead. * Current project standard is **C++11**. * Do not use C-like code: - * C-like style iteration if possible. Use `Q_FOREACH` (`foreach`) and + * C-like style iteration if possible. Use `for (auto foo : bar)` and `std::for_each` instead if possible. It is also recommended to use iterators. * C-like casts, use `const_cast`, `static_cast`, `dymanic_Cast` instead. Using of `reinterpret_cast` is not recommended. It is highly recommended to use - `dynamic_Cast` with the exception catching. It is also possible to use + `dynamic_cast` with the exception catching. It is also possible to use `qvariant_cast` if required. Exception is class constructors, e.g.: ``` @@ -81,7 +82,7 @@ for more details. To avoid manual labor there is automatic cmake target named * Create one file (source and header) per class. * `else if` construction is allowed and recommended. * 'true ? foo : bar' construction is allowed and recommended for one-line assignment. -* any global pointer should be assign to `nullptr` after deletion and before +* Any global pointer should be assign to `nullptr` after deletion and before initialization. Exception: if object is deleted into class destructor. Comments diff --git a/sources/awdebug.h b/sources/awdebug.h index 48dc580..43944ce 100644 --- a/sources/awdebug.h +++ b/sources/awdebug.h @@ -28,12 +28,6 @@ "category}][%{function}] %{message}" #endif /* LOG_FORMAT */ -// redefine info because it doesn't log properly -#ifdef qCInfo -#undef qCInfo -#endif /* qCInfo */ -#define qCInfo qCDebug - Q_DECLARE_LOGGING_CATEGORY(LOG_AW) Q_DECLARE_LOGGING_CATEGORY(LOG_DP) diff --git a/sources/awesome-widget/plugin/awconfighelper.cpp b/sources/awesome-widget/plugin/awconfighelper.cpp index 6263b30..2961d13 100644 --- a/sources/awesome-widget/plugin/awconfighelper.cpp +++ b/sources/awesome-widget/plugin/awconfighelper.cpp @@ -61,7 +61,7 @@ bool AWConfigHelper::exportConfiguration(QObject *nativeConfig, QQmlPropertyMap *configuration = static_cast(nativeConfig); settings.beginGroup(QString("plasmoid")); - foreach (QString key, configuration->keys()) { + for (auto key : configuration->keys()) { QVariant value = configuration->value(key); if (!value.isValid()) continue; @@ -70,13 +70,13 @@ bool AWConfigHelper::exportConfiguration(QObject *nativeConfig, settings.endGroup(); // extensions - foreach (QString item, m_dirs) { + for (auto item : m_dirs) { QStringList items = QDir(QString("%1/%2").arg(m_baseDir).arg(item)) .entryList(QStringList() << QString("*.desktop"), QDir::Files); settings.beginGroup(item); - foreach (QString it, items) + for (auto it : items) copyExtensions(it, item, settings, false); settings.endGroup(); } @@ -112,9 +112,9 @@ QVariantMap AWConfigHelper::importConfiguration(const QString fileName, // extensions if (importExtensions) { - foreach (QString item, m_dirs) { + for (auto item : m_dirs) { settings.beginGroup(item); - foreach (QString it, settings.childGroups()) + for (auto it : settings.childGroups()) copyExtensions(it, item, settings, true); settings.endGroup(); } @@ -137,7 +137,7 @@ QVariantMap AWConfigHelper::importConfiguration(const QString fileName, // plasmoid configuration if (importPlasmoid) { settings.beginGroup(QString("plasmoid")); - foreach (QString key, settings.childKeys()) + for (auto key : settings.childKeys()) configuration[key] = settings.value(key); settings.endGroup(); } @@ -239,7 +239,7 @@ void AWConfigHelper::copyExtensions(const QString item, const QString type, void AWConfigHelper::copySettings(QSettings &from, QSettings &to) const { - foreach (QString key, from.childKeys()) + for (auto key : from.childKeys()) to.setValue(key, from.value(key)); } diff --git a/sources/awesome-widget/plugin/awdataaggregator.cpp b/sources/awesome-widget/plugin/awdataaggregator.cpp index 0464d8e..701b922 100644 --- a/sources/awesome-widget/plugin/awdataaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataaggregator.cpp @@ -131,7 +131,7 @@ QPixmap AWDataAggregator::tooltipImage() toolTipScene->clear(); QPen pen; bool down = false; - foreach (QString key, requiredKeys) { + for (auto key : requiredKeys) { // create frame float normX = 100.0 / static_cast(data[key].count()); float normY = 100.0 / (1.5 * boundaries[key]); diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.cpp b/sources/awesome-widget/plugin/awdataengineaggregator.cpp index 1e313f7..9669c56 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataengineaggregator.cpp @@ -45,8 +45,8 @@ AWDataEngineAggregator::~AWDataEngineAggregator() void AWDataEngineAggregator::disconnectSources() { - foreach (QString dataengine, m_dataEngines.keys()) - foreach (QString source, m_dataEngines[dataengine]->sources()) + for (auto dataengine : m_dataEngines.keys()) + for (auto source : m_dataEngines[dataengine]->sources()) m_dataEngines[dataengine]->disconnectSource(source, parent()); } diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/plugin/awkeys.cpp index 39e0647..8a87bd6 100644 --- a/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp @@ -44,13 +44,11 @@ AWKeys::AWKeys(QObject *parent) { qSetMessagePattern(LOG_FORMAT); qCDebug(LOG_AW) << __PRETTY_FUNCTION__; - foreach (const QString metadata, getBuildData()) + for (auto metadata : getBuildData()) qCDebug(LOG_AW) << metadata; -#ifdef BUILD_FUTURE // thread pool m_threadPool = new QThreadPool(this); -#endif /* BUILD_FUTURE */ aggregator = new AWKeysAggregator(this); dataAggregator = new AWDataAggregator(this); @@ -103,10 +101,8 @@ void AWKeys::initKeys(const QString currentPattern, const int interval, dataEngineAggregator, SLOT(dropSource(QString))); } else dataEngineAggregator->setInterval(interval); -#ifdef BUILD_FUTURE m_threadPool->setMaxThreadCount(limit == 0 ? QThread::idealThreadCount() : limit); -#endif /* BUILD_FUTURE */ updateCache(); return dataEngineAggregator->reconnectSources(); @@ -292,7 +288,7 @@ QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const allKeys.append(QString("la1")); // bars QStringList graphicalItemsKeys; - foreach (GraphicalItem *item, graphicalItems->items()) + for (auto item : graphicalItems->items()) graphicalItemsKeys.append(item->tag()); graphicalItemsKeys.sort(); for (int i = graphicalItemsKeys.count() - 1; i >= 0; i--) @@ -430,13 +426,9 @@ void AWKeys::dataUpdated(const QString &sourceName, return emit(needToBeUpdated()); } -#ifdef BUILD_FUTURE // run concurrent data update QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, sourceName, data); -#else /* BUILD_FUTURE */ - return setDataBySource(sourceName, data); -#endif /* BUILD_FUTURE */ } @@ -448,10 +440,10 @@ void AWKeys::loadKeysFromCache() qCInfo(LOG_AW) << "Cache file" << fileName; QSettings cache(fileName, QSettings::IniFormat); - foreach (QString group, cache.childGroups()) { + for (auto group : cache.childGroups()) { cache.beginGroup(group); m_devices.remove(group); - foreach (QString key, cache.allKeys()) + for (auto key : cache.allKeys()) m_devices[group].append(cache.value(key).toString()); cache.endGroup(); } @@ -489,17 +481,24 @@ void AWKeys::reinitKeys() // not documented feature - place all available tags m_pattern = m_pattern.replace(QString("$ALL"), [allKeys]() { QStringList strings; - foreach (QString tag, allKeys) + for (auto tag : allKeys) strings.append(QString("%1: $%1").arg(tag)); return strings.join(QString(" | ")); }()); #endif /* BUILD_TESTING */ + // apply aw_* functions + m_pattern = insertKeyCount(m_pattern); + m_pattern = insertKeyNames(m_pattern); + m_pattern = insertKeys(m_pattern); + // wrap templates + expandTemplates(); + // append lists // bars - m_foundBars = [allKeys](QString pattern) { + m_foundBars = [allKeys](const QString pattern) { QStringList selectedKeys; - foreach (QString key, allKeys) + for (auto key : allKeys) if ((key.startsWith(QString("bar"))) && (pattern.contains(QString("$%1").arg(key)))) { qCInfo(LOG_AW) << "Found bar" << key; @@ -511,9 +510,9 @@ void AWKeys::reinitKeys() }(m_pattern); // main key list - m_foundKeys = [allKeys](QString pattern) { + m_foundKeys = [allKeys](const QString pattern) { QStringList selectedKeys; - foreach (QString key, allKeys) + for (auto key : allKeys) if ((!key.startsWith(QString("bar"))) && (pattern.contains(QString("$%1").arg(key)))) { qCInfo(LOG_AW) << "Found key" << key; @@ -525,7 +524,7 @@ void AWKeys::reinitKeys() }(m_pattern); // lambdas - m_foundLambdas = [](QString pattern) { + m_foundLambdas = [](const QString pattern) { QStringList selectedKeys; // substring inside ${{ }} (with brackets) which should not contain ${{ QRegularExpression lambdaRegexp( @@ -556,15 +555,10 @@ void AWKeys::reinitKeys() void AWKeys::updateTextData() { -#ifdef BUILD_FUTURE QFuture text = QtConcurrent::run(m_threadPool, [this]() { calculateValues(); return parsePattern(m_pattern); }); -#else /* BUILD_FUTURE */ - calculateValues(); - QString text = parsePattern(m_pattern); -#endif /* BUILD_FUTURE */ emit(needTextToBeUpdated(text)); emit(dataAggregator->updateData(values)); @@ -584,7 +578,7 @@ void AWKeys::addKeyToCache(const QString type, const QString key) cache.beginGroup(type); QStringList cachedValues; - foreach (QString key, cache.allKeys()) + for (auto key : cache.allKeys()) cachedValues.append(cache.value(key).toString()); if (type == QString("hdd")) { @@ -592,7 +586,7 @@ void AWKeys::addKeyToCache(const QString type, const QString key) = QDir(QString("/dev")).entryList(QDir::System, QDir::Name); QStringList devices = allDevices.filter(QRegExp(QString("^[hms]d[a-z]$"))); - foreach (QString dev, devices) { + for (auto dev : devices) { QString device = QString("/dev/%1").arg(dev); if (cachedValues.contains(device)) continue; @@ -604,7 +598,7 @@ void AWKeys::addKeyToCache(const QString type, const QString key) } else if (type == QString("net")) { QList rawInterfaceList = QNetworkInterface::allInterfaces(); - foreach (QNetworkInterface interface, rawInterfaceList) { + for (auto interface : rawInterfaceList) { QString device = interface.name(); if (cachedValues.contains(device)) continue; @@ -632,7 +626,7 @@ void AWKeys::addKeyToCache(const QString type, const QString key) void AWKeys::calculateValues() { // hddtot* - foreach (QString device, m_devices[QString("mount")]) { + for (auto device : m_devices[QString("mount")]) { int index = m_devices[QString("mount")].indexOf(device); values[QString("hddtotmb%1").arg(index)] = QString("%1").arg( values[QString("hddfreemb%1").arg(index)].toFloat() @@ -684,12 +678,12 @@ void AWKeys::calculateValues() 5, 'f', 1); // lambdas - foreach (QString key, m_foundLambdas) + for (auto key : m_foundLambdas) values[key] = [this](QString key) { QJSEngine engine; // apply $this values key.replace(QString("$this"), values[key]); - foreach (QString lambdaKey, m_foundKeys) + for (auto lambdaKey : m_foundKeys) key.replace(QString("$%1").arg(lambdaKey), values[lambdaKey]); qCInfo(LOG_AW) << "Expression" << key; QJSValue result = engine.evaluate(key); @@ -705,17 +699,147 @@ void AWKeys::calculateValues() } +void AWKeys::expandTemplates() +{ + // match the following construction $template{{some code here}} + QRegularExpression templatesRegexp( + QString("\\$template\\{\\{((?!\\$template\\{\\{).)*?\\}\\}")); + templatesRegexp.setPatternOptions( + QRegularExpression::DotMatchesEverythingOption); + + QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(m_pattern); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + QString fullTemplate = match.captured(); + + // drop additional markers + QString templ = fullTemplate; + templ.remove(QRegExp(QString("^\\$template\\{\\{"))); + templ.remove(QRegExp(QString("\\}\\}$"))); + + QJSEngine engine; + qCInfo(LOG_AW) << "Expression" << templ; + QJSValue result = engine.evaluate(templ); + QString templateResult = QString(""); + if (result.isError()) { + qCWarning(LOG_AW) << "Uncaught exception at line" + << result.property("lineNumber").toInt() << ":" + << result.toString(); + } else { + templateResult = result.toString(); + } + + // replace template + m_pattern.replace(fullTemplate, templateResult); + } +} + + +QString AWKeys::insertKeyCount(QString code) const +{ + qCDebug(LOG_AW) << "Looking for count in code" << code; + + QRegularExpression countRegexp(QString("aw_count\\(((?!\\aw_count\\().)*?\\)")); + countRegexp.setPatternOptions( + QRegularExpression::DotMatchesEverythingOption); + + QRegularExpressionMatchIterator it = countRegexp.globalMatch(code); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + QString count = match.captured(); + + // get regexp to search + QString regex = count; + regex.remove(QRegExp(QString("^aw_count\\("))); + regex.remove(QRegExp(QString("\\)$"))); + qCInfo(LOG_AW) << "Looking for" << regex; + + code.replace(count, QString::number(dictKeys(false, regex).count())); + } + + return code; +} + + +QString AWKeys::insertKeyNames(QString code) const +{ + qCDebug(LOG_AW) << "Looking for keys in code" << code; + + QRegularExpression keysRegexp(QString("aw_names\\(((?!\\aw_names\\().)*?\\)")); + keysRegexp.setPatternOptions( + QRegularExpression::DotMatchesEverythingOption); + + QRegularExpressionMatchIterator it = keysRegexp.globalMatch(code); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + QString keys = match.captured(); + + // get regexp to search + QString condition = keys; + condition.remove(QRegExp(QString("^aw_names\\("))); + condition.remove(QRegExp(QString("\\)$"))); + QStringList conditionList = condition.split(QChar(',')); + // regexp + QString regex = conditionList.at(0); + // separator to join + QString separator = conditionList.size() == 1 ? QString("") : conditionList.at(1); + qCInfo(LOG_AW) << "Looking for" << regex << "with separator" << separator; + + code.replace(keys, dictKeys(true, regex).join(separator)); + } + + return code; +} + + +QString AWKeys::insertKeys(QString code) const +{ + qCDebug(LOG_AW) << "Looking for keys in code" << code; + + QRegularExpression keysRegexp(QString("aw_keys\\(((?!\\aw_keys\\().)*?\\)")); + keysRegexp.setPatternOptions( + QRegularExpression::DotMatchesEverythingOption); + + QRegularExpressionMatchIterator it = keysRegexp.globalMatch(code); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + QString keys = match.captured(); + + // get regexp to search + QString condition = keys; + condition.remove(QRegExp(QString("^aw_keys\\("))); + condition.remove(QRegExp(QString("\\)$"))); + QStringList conditionList = condition.split(QChar(',')); + // regexp + QString regex = conditionList.at(0); + // separator to join + QString separator = conditionList.size() == 1 ? QString("") : conditionList.at(1); + qCInfo(LOG_AW) << "Looking for" << regex << "with separator" << separator; + + // find keys and add $ at the beginning of the line + QStringList foundKeys = dictKeys(true, regex); + std::for_each(foundKeys.begin(), foundKeys.end(), [](QString &value) { + value = QString("$%1").arg(value); + }); + + code.replace(keys, foundKeys.join(separator)); + } + + return code; +} + + QString AWKeys::parsePattern(QString pattern) const { // screen sign pattern.replace(QString("$$"), QString("$\\$\\")); // lambdas - foreach (QString key, m_foundLambdas) + for (auto key : m_foundLambdas) pattern.replace(QString("${{%1}}").arg(key), values[key]); // main keys - foreach (QString key, m_foundKeys) + for (auto key : m_foundKeys) pattern.replace(QString("$%1").arg(key), [](QString key, QString value) { if ((!key.startsWith(QString("custom"))) @@ -725,7 +849,7 @@ QString AWKeys::parsePattern(QString pattern) const }(key, values[key])); // bars - foreach (QString bar, m_foundBars) { + for (auto bar : m_foundBars) { GraphicalItem *item = graphicalItems->itemByTag(bar); QString key = bar; key.remove(QRegExp(QString("^bar[0-9]{1,}"))); @@ -763,9 +887,7 @@ void AWKeys::setDataBySource(const QString &sourceName, const QVariantMap &data) qCDebug(LOG_AW) << "Source" << sourceName << "not found"; emit(dropSourceFromDataengine(sourceName)); } else { -#ifdef BUILD_FUTURE m_mutex.lock(); -#endif /* BUILD_FUTURE */ // HACK workaround for time values which are stored in the different // path QVariant value = sourceName == QString("Local") @@ -775,8 +897,6 @@ void AWKeys::setDataBySource(const QString &sourceName, const QVariantMap &data) [this, value](const QString tag) { values[tag] = aggregator->formater(value, tag); }); -#ifdef BUILD_FUTURE m_mutex.unlock(); -#endif /* BUILD_FUTURE */ } } diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h index a8300f1..321a4cb 100644 --- a/sources/awesome-widget/plugin/awkeys.h +++ b/sources/awesome-widget/plugin/awkeys.h @@ -83,6 +83,10 @@ private: // methods void addKeyToCache(const QString type, const QString key = QString("")); void calculateValues(); + void expandTemplates(); + QString insertKeyCount(QString code) const; + QString insertKeyNames(QString code) const; + QString insertKeys(QString code) const; QString parsePattern(QString pattern) const; void setDataBySource(const QString &sourceName, const QVariantMap &data); // objects diff --git a/sources/awesome-widget/plugin/awkeysaggregator.cpp b/sources/awesome-widget/plugin/awkeysaggregator.cpp index 0ac20a1..c61db0c 100644 --- a/sources/awesome-widget/plugin/awkeysaggregator.cpp +++ b/sources/awesome-widget/plugin/awkeysaggregator.cpp @@ -102,7 +102,7 @@ QString AWKeysAggregator::formater(const QVariant &data, case TimeCustom: output = m_customTime; [&output, loc, this](const QDateTime dt) { - foreach (QString key, timeKeys) + for (auto key : timeKeys) output.replace(QString("$%1").arg(key), loc.toString(dt, key)); }(data.toDateTime()); break; diff --git a/sources/awesomewidgets/abstractextitem.cpp b/sources/awesomewidgets/abstractextitem.cpp index 4249bc5..6986bfe 100644 --- a/sources/awesomewidgets/abstractextitem.cpp +++ b/sources/awesomewidgets/abstractextitem.cpp @@ -193,14 +193,14 @@ void AbstractExtItem::readConfiguration() bool AbstractExtItem::tryDelete() const { - foreach (QString dir, m_dirs) { + for (auto dir : m_dirs) { bool status = QFile::remove(QString("%1/%2").arg(dir).arg(m_fileName)); qCInfo(LOG_LIB) << "Remove file" << QString("%1/%2").arg(dir).arg(m_fileName) << status; } // check if exists - foreach (QString dir, m_dirs) + for (auto dir : m_dirs) if (QFile::exists(QString("%1/%2").arg(dir).arg(m_fileName))) return false; return true; diff --git a/sources/awesomewidgets/extscript.cpp b/sources/awesomewidgets/extscript.cpp index 51ed024..a016fda 100644 --- a/sources/awesomewidgets/extscript.cpp +++ b/sources/awesomewidgets/extscript.cpp @@ -188,7 +188,7 @@ QString ExtScript::applyFilters(QString _value) const { qCDebug(LOG_LIB) << "Value" << _value; - foreach (QString filt, m_filters) { + for (auto filt : m_filters) { qCInfo(LOG_LIB) << "Found filter" << filt; QVariantMap filter = jsonFilters[filt].toMap(); if (filter.isEmpty()) { @@ -196,7 +196,7 @@ QString ExtScript::applyFilters(QString _value) const << "in the json"; continue; } - foreach (QString f, filter.keys()) + for (auto f : filter.keys()) _value.replace(f, filter[f].toString()); } diff --git a/sources/desktop-panel/plugin/dpadds.cpp b/sources/desktop-panel/plugin/dpadds.cpp index f54c3d2..bf852fb 100644 --- a/sources/desktop-panel/plugin/dpadds.cpp +++ b/sources/desktop-panel/plugin/dpadds.cpp @@ -42,7 +42,7 @@ DPAdds::DPAdds(QObject *parent) { qSetMessagePattern(LOG_FORMAT); qCDebug(LOG_DP) << __PRETTY_FUNCTION__; - foreach (const QString metadata, getBuildData()) + for (auto metadata : getBuildData()) qCDebug(LOG_DP) << metadata; connect(KWindowSystem::self(), SIGNAL(currentDesktopChanged(int)), this, @@ -137,7 +137,7 @@ QString DPAdds::toolTipImage(const int desktop) const QPen pen = QPen(); pen.setWidthF(2.0 * info.desktop.width() / 400.0); pen.setColor(QColor(m_tooltipColor)); - foreach (WindowData data, info.windowsData) { + for (auto data : info.windowsData) { QRect rect = data.rect; toolTipScene->addLine(rect.left() + margin, rect.bottom() + margin, rect.left() + margin, rect.top() + margin, @@ -196,7 +196,7 @@ QString DPAdds::parsePattern(const QString pattern, const int desktop) const QString parsed = pattern; parsed.replace(QString("$$"), QString("$\\$\\")); - foreach (QString key, dictKeys()) + for (auto key : dictKeys()) parsed.replace(QString("$%1").arg(key), valueByKey(key, desktop)); parsed.replace(QString("$\\$\\"), QString("$$")); @@ -363,7 +363,7 @@ DPAdds::DesktopWindowsInfo DPAdds::getInfoByDesktop(const int desktop) const DesktopWindowsInfo info; info.desktop = KWindowSystem::workArea(desktop); - foreach (WId id, KWindowSystem::windows()) { + for (auto id : KWindowSystem::windows()) { KWindowInfo winInfo = KWindowInfo( id, NET::Property::WMDesktop | NET::Property::WMGeometry | NET::Property::WMState | NET::Property::WMWindowType diff --git a/sources/extsysmon/extsysmon.cpp b/sources/extsysmon/extsysmon.cpp index 019533e..818f9a3 100644 --- a/sources/extsysmon/extsysmon.cpp +++ b/sources/extsysmon/extsysmon.cpp @@ -34,7 +34,7 @@ ExtendedSysMon::ExtendedSysMon(QObject *parent, const QVariantList &args) Q_UNUSED(args) qSetMessagePattern(LOG_FORMAT); qCDebug(LOG_ESM) << __PRETTY_FUNCTION__; - foreach (const QString metadata, getBuildData()) + for (auto metadata : getBuildData()) qCDebug(LOG_ESM) << metadata; setMinimumPollingInterval(333); @@ -42,7 +42,7 @@ ExtendedSysMon::ExtendedSysMon(QObject *parent, const QVariantList &args) // init aggregator aggregator = new ExtSysMonAggregator(this, configuration); - foreach (QString source, aggregator->sources()) + for (auto source : aggregator->sources()) setData(source, aggregator->initialData(source)); } @@ -177,7 +177,7 @@ ExtendedSysMon::updateConfiguration(QHash rawConfig) const QChar(','), QString::SkipEmptyParts); QStringList devices; QRegExp diskRegexp = QRegExp("^/dev/[hms]d[a-z]$"); - foreach (QString device, deviceList) + for (auto device : deviceList) if ((QFile::exists(device)) && (device.contains(diskRegexp))) devices.append(device); if (devices.isEmpty()) @@ -194,7 +194,7 @@ ExtendedSysMon::updateConfiguration(QHash rawConfig) const if (rawConfig[QString("PLAYERSYMBOLS")].toInt() <= 0) rawConfig[QString("PLAYERSYMBOLS")] = QString("10"); - foreach (QString key, rawConfig.keys()) + for (auto key : rawConfig.keys()) qCInfo(LOG_ESM) << key << "=" << rawConfig[key]; return rawConfig; } diff --git a/sources/extsysmon/extsysmonaggregator.cpp b/sources/extsysmon/extsysmonaggregator.cpp index bd14e95..44f33cd 100644 --- a/sources/extsysmon/extsysmonaggregator.cpp +++ b/sources/extsysmon/extsysmonaggregator.cpp @@ -91,37 +91,37 @@ void ExtSysMonAggregator::init(const QHash config) // battery AbstractExtSysMonSource *batteryItem = new BatterySource(this, QStringList() << config[QString("ACPIPATH")]); - foreach (QString source, batteryItem->sources()) + for (auto source : batteryItem->sources()) m_map[source] = batteryItem; // custom AbstractExtSysMonSource *customItem = new CustomSource(this, QStringList()); - foreach (QString source, customItem->sources()) + for (auto source : customItem->sources()) m_map[source] = customItem; // desktop AbstractExtSysMonSource *desktopItem = new DesktopSource(this, QStringList()); - foreach (QString source, desktopItem->sources()) + for (auto source : desktopItem->sources()) m_map[source] = desktopItem; // gpu load AbstractExtSysMonSource *gpuLoadItem = new GPULoadSource(this, QStringList() << config[QString("GPUDEV")]); - foreach (QString source, gpuLoadItem->sources()) + for (auto source : gpuLoadItem->sources()) m_map[source] = gpuLoadItem; // gpu temperature AbstractExtSysMonSource *gpuTempItem = new GPUTemperatureSource( this, QStringList() << config[QString("GPUDEV")]); - foreach (QString source, gpuTempItem->sources()) + for (auto source : gpuTempItem->sources()) m_map[source] = gpuTempItem; // hdd temperature AbstractExtSysMonSource *hddTempItem = new HDDTemperatureSource( this, QStringList() << config[QString("HDDDEV")] << config[QString("HDDTEMPCMD")]); - foreach (QString source, hddTempItem->sources()) + for (auto source : hddTempItem->sources()) m_map[source] = hddTempItem; // network AbstractExtSysMonSource *networkItem = new NetworkSource(this, QStringList()); - foreach (QString source, networkItem->sources()) + for (auto source : networkItem->sources()) m_map[source] = networkItem; // player AbstractExtSysMonSource *playerItem = new PlayerSource( @@ -129,35 +129,35 @@ void ExtSysMonAggregator::init(const QHash config) << config[QString("PLAYER")] << config[QString("MPDADDRESS")] << config[QString("MPDPORT")] << config[QString("MPRIS")] << config[QString("PLAYERSYMBOLS")]); - foreach (QString source, playerItem->sources()) + for (auto source : playerItem->sources()) m_map[source] = playerItem; // processes AbstractExtSysMonSource *processesItem = new ProcessesSource(this, QStringList()); - foreach (QString source, processesItem->sources()) + for (auto source : processesItem->sources()) m_map[source] = processesItem; // quotes AbstractExtSysMonSource *quotesItem = new QuotesSource(this, QStringList()); - foreach (QString source, quotesItem->sources()) + for (auto source : quotesItem->sources()) m_map[source] = quotesItem; // update AbstractExtSysMonSource *updateItem = new UpdateSource(this, QStringList()); - foreach (QString source, updateItem->sources()) + for (auto source : updateItem->sources()) m_map[source] = updateItem; // upgrade AbstractExtSysMonSource *upgradeItem = new UpgradeSource(this, QStringList()); - foreach (QString source, upgradeItem->sources()) + for (auto source : upgradeItem->sources()) m_map[source] = upgradeItem; // weather AbstractExtSysMonSource *weatherItem = new WeatherSource(this, QStringList()); - foreach (QString source, weatherItem->sources()) + for (auto source : weatherItem->sources()) m_map[source] = weatherItem; #ifdef BUILD_TESTING // additional load source AbstractExtSysMonSource *loadItem = new LoadSource(this, QStringList()); - foreach (QString source, loadItem->sources()) + for (auto source : loadItem->sources()) m_map[source] = loadItem; #endif /* BUILD_TESTING */ } diff --git a/sources/extsysmon/sources/customsource.cpp b/sources/extsysmon/sources/customsource.cpp index 68c9c7d..26ad6e8 100644 --- a/sources/extsysmon/sources/customsource.cpp +++ b/sources/extsysmon/sources/customsource.cpp @@ -76,7 +76,7 @@ QStringList CustomSource::sources() const QStringList CustomSource::getSources() { QStringList sources; - foreach (ExtScript *item, extScripts->activeItems()) + for (auto item : extScripts->activeItems()) sources.append(QString("custom/%1").arg(item->tag(QString("custom")))); return sources; diff --git a/sources/extsysmon/sources/gpuloadsource.cpp b/sources/extsysmon/sources/gpuloadsource.cpp index c4d0c12..6150bda 100644 --- a/sources/extsysmon/sources/gpuloadsource.cpp +++ b/sources/extsysmon/sources/gpuloadsource.cpp @@ -61,8 +61,8 @@ QVariant GPULoadSource::data(QString source) QString qoutput = QTextCodec::codecForMib(106)->toUnicode(process.output).trimmed(); if (m_device == QString("nvidia")) { - foreach (QString str, - qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + for (auto str : + qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { if (!str.contains(QString(""))) continue; QString load = str.remove(QString("")) @@ -72,8 +72,8 @@ QVariant GPULoadSource::data(QString source) break; } } else if (m_device == QString("ati")) { - foreach (QString str, - qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + for (auto str : + qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { if (!str.contains(QString("load"))) continue; QString load diff --git a/sources/extsysmon/sources/gputempsource.cpp b/sources/extsysmon/sources/gputempsource.cpp index c02ec81..3c83258 100644 --- a/sources/extsysmon/sources/gputempsource.cpp +++ b/sources/extsysmon/sources/gputempsource.cpp @@ -62,8 +62,8 @@ QVariant GPUTemperatureSource::data(QString source) QString qoutput = QTextCodec::codecForMib(106)->toUnicode(process.output).trimmed(); if (m_device == QString("nvidia")) { - foreach (QString str, - qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + for (auto str : + qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { if (!str.contains(QString(""))) continue; QString temp = str.remove(QString("")) @@ -72,8 +72,8 @@ QVariant GPUTemperatureSource::data(QString source) break; } } else if (m_device == QString("ati")) { - foreach (QString str, - qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + for (auto str : + qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { if (!str.contains(QString("Temperature"))) continue; QString temp diff --git a/sources/extsysmon/sources/hddtempsource.cpp b/sources/extsysmon/sources/hddtempsource.cpp index 2816e3b..92b9b22 100644 --- a/sources/extsysmon/sources/hddtempsource.cpp +++ b/sources/extsysmon/sources/hddtempsource.cpp @@ -61,8 +61,7 @@ QVariant HDDTemperatureSource::data(QString source) QString qoutput = QTextCodec::codecForMib(106)->toUnicode(process.output).trimmed(); if (m_smartctl) { - foreach (QString str, - qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { if (!str.startsWith(QString("194"))) continue; if (str.split(QChar(' '), QString::SkipEmptyParts).count() < 9) @@ -104,7 +103,7 @@ QVariantMap HDDTemperatureSource::initialData(QString source) const QStringList HDDTemperatureSource::sources() const { QStringList sources; - foreach (QString device, m_devices) + for (auto device : m_devices) sources.append(QString("hdd/temperature%1").arg(device)); return sources; diff --git a/sources/extsysmon/sources/networksource.cpp b/sources/extsysmon/sources/networksource.cpp index 2203000..45a27ef 100644 --- a/sources/extsysmon/sources/networksource.cpp +++ b/sources/extsysmon/sources/networksource.cpp @@ -46,7 +46,7 @@ QVariant NetworkSource::data(QString source) QList rawInterfaceList = QNetworkInterface::allInterfaces(); qCInfo(LOG_ESM) << "Devices" << rawInterfaceList; - foreach (QNetworkInterface interface, rawInterfaceList) { + for (auto interface : rawInterfaceList) { if ((interface.flags().testFlag(QNetworkInterface::IsLoopBack)) || (interface.flags().testFlag( QNetworkInterface::IsPointToPoint))) diff --git a/sources/extsysmon/sources/playersource.cpp b/sources/extsysmon/sources/playersource.cpp index 61b4814..f1f1c41 100644 --- a/sources/extsysmon/sources/playersource.cpp +++ b/sources/extsysmon/sources/playersource.cpp @@ -150,13 +150,13 @@ void PlayerSource::run() if (m_player == QString("mpd")) { // mpd QHash data = getPlayerMpdInfo(m_mpdAddress); - foreach (QString key, data.keys()) + for (auto key : data.keys()) values[key] = data[key]; } else if (m_player == QString("mpris")) { // players which supports mpris QString mpris = m_mpris == QString("auto") ? getAutoMpris() : m_mpris; QHash data = getPlayerMprisInfo(mpris); - foreach (QString key, data.keys()) + for (auto key : data.keys()) values[key] = data[key]; } @@ -221,7 +221,7 @@ QString PlayerSource::getAutoMpris() const return QString(); QStringList arguments = listServices.arguments().first().toStringList(); - foreach (QString arg, arguments) { + for (auto arg : arguments) { if (!arg.startsWith(QString("org.mpris.MediaPlayer2."))) continue; qCInfo(LOG_ESM) << "Service found" << arg; @@ -251,7 +251,7 @@ QVariantHash PlayerSource::getPlayerMpdInfo(const QString mpdAddress) const QString qoutput = QTextCodec::codecForMib(106)->toUnicode(process.output).trimmed(); - foreach (QString str, qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { + for (auto str : qoutput.split(QChar('\n'), QString::SkipEmptyParts)) { if (str.split(QString(": "), QString::SkipEmptyParts).count() == 2) { // "Metadata: data" QString metadata = str.split(QString(": "), QString::SkipEmptyParts) diff --git a/sources/extsysmon/sources/processessource.cpp b/sources/extsysmon/sources/processessource.cpp index 4a01b81..4f41cb9 100644 --- a/sources/extsysmon/sources/processessource.cpp +++ b/sources/extsysmon/sources/processessource.cpp @@ -84,7 +84,7 @@ void ProcessesSource::run() QStringList directories = allDirectories.filter(QRegExp(QString("(\\d+)"))); QStringList running; - foreach (QString dir, directories) { + for (auto dir : directories) { QFile statusFile(QString("/proc/%1/status").arg(dir)); if (!statusFile.open(QIODevice::ReadOnly)) continue; diff --git a/sources/extsysmon/sources/quotessource.cpp b/sources/extsysmon/sources/quotessource.cpp index d2f7e90..a9d8129 100644 --- a/sources/extsysmon/sources/quotessource.cpp +++ b/sources/extsysmon/sources/quotessource.cpp @@ -47,7 +47,7 @@ QVariant QuotesSource::data(QString source) if (source.startsWith(QString("quotes/percpricechg"))) { QVariantHash data = extQuotes->itemByTagNumber(index(source))->run(); - foreach (QString key, data.keys()) + for (auto key : data.keys()) values[key] = data[key]; } QString key = QString(source).remove(QString("quotes/")); @@ -148,7 +148,7 @@ QStringList QuotesSource::sources() const QStringList QuotesSource::getSources() { QStringList sources; - foreach (ExtQuotes *item, extQuotes->activeItems()) { + for (auto item : extQuotes->activeItems()) { sources.append(QString("quotes/%1").arg(item->tag(QString("ask")))); sources.append(QString("quotes/%1").arg(item->tag(QString("askchg")))); sources.append( diff --git a/sources/extsysmon/sources/upgradesource.cpp b/sources/extsysmon/sources/upgradesource.cpp index 84bb579..243c0bd 100644 --- a/sources/extsysmon/sources/upgradesource.cpp +++ b/sources/extsysmon/sources/upgradesource.cpp @@ -76,7 +76,7 @@ QStringList UpgradeSource::sources() const QStringList UpgradeSource::getSources() { QStringList sources; - foreach (ExtUpgrade *item, extUpgrade->activeItems()) + for (auto item : extUpgrade->activeItems()) sources.append( QString("upgrade/%1").arg(item->tag(QString("pkgcount")))); diff --git a/sources/extsysmon/sources/weathersource.cpp b/sources/extsysmon/sources/weathersource.cpp index 5ff30a0..9a57851 100644 --- a/sources/extsysmon/sources/weathersource.cpp +++ b/sources/extsysmon/sources/weathersource.cpp @@ -47,7 +47,7 @@ QVariant WeatherSource::data(QString source) if (source.startsWith(QString("weather/weatherId"))) { QVariantHash data = extWeather->itemByTagNumber(index(source))->run(); - foreach (QString key, data.keys()) + for (auto key : data.keys()) values[key] = data[key]; } QString key = QString(source).remove(QString("weather/")); @@ -124,7 +124,7 @@ QStringList WeatherSource::sources() const QStringList WeatherSource::getSources() { QStringList sources; - foreach (ExtWeather *item, extWeather->activeItems()) { + for (auto item : extWeather->activeItems()) { sources.append( QString("weather/%1").arg(item->tag(QString("weatherId")))); sources.append( From 966c6059a04a44a4908683175087cf1f2e45f1da Mon Sep 17 00:00:00 2001 From: arcan1s Date: Sun, 31 Jan 2016 00:00:12 +0700 Subject: [PATCH 11/17] split some classes to different namespaces to improve code base No significant changes applied. * function syntax has been changed to another one, any function may be called by using the following construction: $aw_function_name{{function body if any}} * rewrite travis.yml --- .travis.yml | 30 +- sources/CMakeLists.txt | 4 +- sources/awesome-widget/plugin/awactions.cpp | 8 +- sources/awesome-widget/plugin/awkeycache.cpp | 101 ++++ sources/awesome-widget/plugin/awkeycache.h | 33 ++ .../awesome-widget/plugin/awkeyoperations.cpp | 412 +++++++++++++ .../awesome-widget/plugin/awkeyoperations.h | 81 +++ sources/awesome-widget/plugin/awkeys.cpp | 542 ++---------------- sources/awesome-widget/plugin/awkeys.h | 26 +- .../plugin/awpatternfunctions.cpp | 160 ++++++ .../plugin/awpatternfunctions.h | 36 ++ 11 files changed, 892 insertions(+), 541 deletions(-) create mode 100644 sources/awesome-widget/plugin/awkeycache.cpp create mode 100644 sources/awesome-widget/plugin/awkeycache.h create mode 100644 sources/awesome-widget/plugin/awkeyoperations.cpp create mode 100644 sources/awesome-widget/plugin/awkeyoperations.h create mode 100644 sources/awesome-widget/plugin/awpatternfunctions.cpp create mode 100644 sources/awesome-widget/plugin/awpatternfunctions.h diff --git a/.travis.yml b/.travis.yml index a2047b0..5615fd4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,33 @@ sudo: required dist: trusty -install: - - sudo apt-add-repository -y ppa:kubuntu-ppa/backports +language: cpp +os: + - linux + +before_install: + - sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list - sudo apt-get update -qq - - sudo apt-get -y -q -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew dist-upgrade - - sudo apt-get install -y -q cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev + - sudo apt-get upgrade + +addons: + apt: + sources: + - kubuntu-backports + packages: + - cmake + - extra-cmake-modules + - g++ + - git + - libkf5i18n-dev + - libkf5notifications-dev + - libkf5service-dev + - libkf5windowsystem-dev + - plasma-framework-dev + - qtbase5-dev + - qtdeclarative5-dev + +before_script: - rm -rf build - mkdir build diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt index bc96fb9..1ff1734 100644 --- a/sources/CMakeLists.txt +++ b/sources/CMakeLists.txt @@ -41,14 +41,14 @@ set(CPPCHECK_EXECUTABLE "/usr/bin/cppcheck" CACHE STRING "Path to cppcheck execu # flags if (CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_CXX_FLAGS "-Wall -Wno-cpp -std=c++11") + set(CMAKE_CXX_FLAGS "-Wall -Wno-cpp -std=c++14") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG") # 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++14 -stdlib=libc++") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG") diff --git a/sources/awesome-widget/plugin/awactions.cpp b/sources/awesome-widget/plugin/awactions.cpp index 399219b..8ac7a4d 100644 --- a/sources/awesome-widget/plugin/awactions.cpp +++ b/sources/awesome-widget/plugin/awactions.cpp @@ -235,12 +235,12 @@ void AWActions::versionReplyRecieved(QNetworkReply *reply, QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error); - reply->deleteLater(); if ((reply->error() != QNetworkReply::NoError) || (error.error != QJsonParseError::NoError)) { qCWarning(LOG_AW) << "Parse error" << error.errorString(); return; } + reply->deleteLater(); // convert to map QVariantMap firstRelease = jsonDoc.toVariant().toList().first().toMap(); @@ -252,9 +252,9 @@ void AWActions::versionReplyRecieved(QNetworkReply *reply, int old_major = QString(VERSION).split(QChar('.')).at(0).toInt(); int old_minor = QString(VERSION).split(QChar('.')).at(1).toInt(); int old_patch = QString(VERSION).split(QChar('.')).at(2).toInt(); - int new_major = QString(version).split(QChar('.')).at(0).toInt(); - int new_minor = QString(version).split(QChar('.')).at(1).toInt(); - int new_patch = QString(version).split(QChar('.')).at(2).toInt(); + int new_major = version.split(QChar('.')).at(0).toInt(); + int new_minor = version.split(QChar('.')).at(1).toInt(); + int new_patch = version.split(QChar('.')).at(2).toInt(); if ((old_major < new_major) || ((old_major == new_major) && (old_minor < new_minor)) || ((old_major == new_major) && (old_minor == new_minor) diff --git a/sources/awesome-widget/plugin/awkeycache.cpp b/sources/awesome-widget/plugin/awkeycache.cpp new file mode 100644 index 0000000..6d3e45a --- /dev/null +++ b/sources/awesome-widget/plugin/awkeycache.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** + * 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 "awkeycache.h" + +#include +#include +#include +#include +#include + +#include "awdebug.h" + + +void AWKeyCache::addKeyToCache(const QString type, const QString key) +{ + qCDebug(LOG_AW) << "Key type" << type; + qCDebug(LOG_AW) << "Key" << key; + + QString fileName = QString("%1/awesomewidgets.ndx") + .arg(QStandardPaths::writableLocation( + QStandardPaths::GenericCacheLocation)); + qCInfo(LOG_AW) << "Cache file" << fileName; + QSettings cache(fileName, QSettings::IniFormat); + + cache.beginGroup(type); + QStringList cachedValues; + for (auto key : cache.allKeys()) + cachedValues.append(cache.value(key).toString()); + + if (type == QString("hdd")) { + QStringList allDevices + = QDir(QString("/dev")).entryList(QDir::System, QDir::Name); + QStringList devices + = allDevices.filter(QRegExp(QString("^[hms]d[a-z]$"))); + for (auto dev : devices) { + QString device = QString("/dev/%1").arg(dev); + if (cachedValues.contains(device)) + continue; + qCInfo(LOG_AW) << "Found new key" << device << "for type" << type; + cache.setValue( + QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), + device); + } + } else if (type == QString("net")) { + QList rawInterfaceList + = QNetworkInterface::allInterfaces(); + for (auto interface : rawInterfaceList) { + QString device = interface.name(); + if (cachedValues.contains(device)) + continue; + qCInfo(LOG_AW) << "Found new key" << device << "for type" << type; + cache.setValue( + QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), + device); + } + } else { + if (cachedValues.contains(key)) + return; + qCInfo(LOG_AW) << "Found new key" << key << "for type" << type; + cache.setValue( + QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), key); + } + cache.endGroup(); + + cache.sync(); +} + + +QHash AWKeyCache::loadKeysFromCache() +{ + QString fileName = QString("%1/awesomewidgets.ndx") + .arg(QStandardPaths::writableLocation( + QStandardPaths::GenericCacheLocation)); + qCInfo(LOG_AW) << "Cache file" << fileName; + QSettings cache(fileName, QSettings::IniFormat); + + QHash devices; + for (auto group : cache.childGroups()) { + cache.beginGroup(group); + for (auto key : cache.allKeys()) + devices[group].append(cache.value(key).toString()); + cache.endGroup(); + } + + return devices; +} diff --git a/sources/awesome-widget/plugin/awkeycache.h b/sources/awesome-widget/plugin/awkeycache.h new file mode 100644 index 0000000..040a43e --- /dev/null +++ b/sources/awesome-widget/plugin/awkeycache.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * 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 AWKEYCACHE_H +#define AWKEYCACHE_H + +#include +#include + + +namespace AWKeyCache +{ +void addKeyToCache(const QString type, const QString key = QString("")); +QHash loadKeysFromCache(); +}; + + +#endif /* AWKEYCACHE_H */ diff --git a/sources/awesome-widget/plugin/awkeyoperations.cpp b/sources/awesome-widget/plugin/awkeyoperations.cpp new file mode 100644 index 0000000..e1210da --- /dev/null +++ b/sources/awesome-widget/plugin/awkeyoperations.cpp @@ -0,0 +1,412 @@ +/*************************************************************************** + * 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 "awkeyoperations.h" + +#include +#include +#include +#include + +#include "awdebug.h" +#include "awkeycache.h" +#include "awpatternfunctions.h" +#include "version.h" +// extensions +#include "extquotes.h" +#include "extscript.h" +#include "extupgrade.h" +#include "extweather.h" +#include "graphicalitem.h" + + +AWKeyOperations::AWKeyOperations(QObject *parent) + : QObject(parent) +{ + qCDebug(LOG_AW) << __PRETTY_FUNCTION__; +} + + +AWKeyOperations::~AWKeyOperations() +{ + qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + + // extensions + delete graphicalItems; + delete extQuotes; + delete extScripts; + delete extUpgrade; + delete extWeather; +} + + +void AWKeyOperations::addDevice(const QString source) +{ + qCDebug(LOG_AW) << "Source" << source; + + QRegExp diskRegexp + = QRegExp(QString("disk/(?:md|sd|hd)[a-z|0-9]_.*/Rate/(?:rblk)")); + QRegExp mountRegexp = QRegExp(QString("partitions/.*/filllevel")); + + if (source.contains(diskRegexp)) { + QString device = source; + device.remove(QString("/Rate/rblk")); + addKeyToCache(QString("disk"), device); + } else if (source.contains(mountRegexp)) { + QString device = source; + device.remove(QString("partitions")).remove(QString("/filllevel")); + addKeyToCache(QString("mount"), device); + } else if (source.startsWith(QString("lmsensors"))) { + addKeyToCache(QString("temp"), source); + } +} + + +QStringList AWKeyOperations::devices(const QString type) const +{ + qCDebug(LOG_AW) << "Looking for type" << type; + + return m_devices[type]; +} + + +QHash AWKeyOperations::devices() const +{ + return m_devices; +} + + +void AWKeyOperations::updateCache() +{ + // update network and hdd list + addKeyToCache(QString("hdd")); + addKeyToCache(QString("net")); +} + + +QStringList AWKeyOperations::dictKeys() const +{ + QStringList allKeys; + // weather + for (int i = extWeather->activeItems().count() - 1; i >= 0; i--) { + allKeys.append( + extWeather->activeItems().at(i)->tag(QString("weatherId"))); + allKeys.append( + extWeather->activeItems().at(i)->tag(QString("weather"))); + allKeys.append( + extWeather->activeItems().at(i)->tag(QString("humidity"))); + allKeys.append( + extWeather->activeItems().at(i)->tag(QString("pressure"))); + allKeys.append( + extWeather->activeItems().at(i)->tag(QString("temperature"))); + allKeys.append( + extWeather->activeItems().at(i)->tag(QString("timestamp"))); + } + // time + allKeys.append(QString("time")); + allKeys.append(QString("isotime")); + allKeys.append(QString("shorttime")); + allKeys.append(QString("longtime")); + allKeys.append(QString("ctime")); + // uptime + allKeys.append(QString("uptime")); + allKeys.append(QString("cuptime")); + // cpuclock & cpu + for (int i = QThread::idealThreadCount() - 1; i >= 0; i--) { + allKeys.append(QString("cpucl%1").arg(i)); + allKeys.append(QString("cpu%1").arg(i)); + } + allKeys.append(QString("cpucl")); + allKeys.append(QString("cpu")); + // temperature + for (int i = m_devices[QString("temp")].count() - 1; i >= 0; i--) + allKeys.append(QString("temp%1").arg(i)); + // gputemp + allKeys.append(QString("gputemp")); + // gpu + allKeys.append(QString("gpu")); + // memory + allKeys.append(QString("memmb")); + allKeys.append(QString("memgb")); + allKeys.append(QString("memfreemb")); + allKeys.append(QString("memfreegb")); + allKeys.append(QString("memtotmb")); + allKeys.append(QString("memtotgb")); + allKeys.append(QString("memusedmb")); + allKeys.append(QString("memusedgb")); + allKeys.append(QString("mem")); + // swap + allKeys.append(QString("swapmb")); + allKeys.append(QString("swapgb")); + allKeys.append(QString("swapfreemb")); + allKeys.append(QString("swapfreegb")); + allKeys.append(QString("swaptotmb")); + allKeys.append(QString("swaptotgb")); + allKeys.append(QString("swap")); + // hdd + for (int i = m_devices[QString("mount")].count() - 1; i >= 0; i--) { + allKeys.append(QString("hddmb%1").arg(i)); + allKeys.append(QString("hddgb%1").arg(i)); + allKeys.append(QString("hddfreemb%1").arg(i)); + allKeys.append(QString("hddfreegb%1").arg(i)); + allKeys.append(QString("hddtotmb%1").arg(i)); + allKeys.append(QString("hddtotgb%1").arg(i)); + allKeys.append(QString("hdd%1").arg(i)); + } + // hdd speed + for (int i = m_devices[QString("disk")].count() - 1; i >= 0; i--) { + allKeys.append(QString("hddr%1").arg(i)); + allKeys.append(QString("hddw%1").arg(i)); + } + // hdd temp + for (int i = m_devices[QString("hdd")].count() - 1; i >= 0; i--) + allKeys.append(QString("hddtemp%1").arg(i)); + // network + for (int i = m_devices[QString("net")].count() - 1; i >= 0; i--) { + allKeys.append(QString("downunits%1").arg(i)); + allKeys.append(QString("upunits%1").arg(i)); + allKeys.append(QString("downkb%1").arg(i)); + allKeys.append(QString("down%1").arg(i)); + allKeys.append(QString("upkb%1").arg(i)); + allKeys.append(QString("up%1").arg(i)); + } + allKeys.append(QString("downunits")); + allKeys.append(QString("upunits")); + allKeys.append(QString("downkb")); + allKeys.append(QString("down")); + allKeys.append(QString("upkb")); + allKeys.append(QString("up")); + allKeys.append(QString("netdev")); + // battery + allKeys.append(QString("ac")); + QStringList allBatteryDevices + = QDir(QString("/sys/class/power_supply")) + .entryList(QStringList() << QString("BAT*"), + QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); + for (int i = allBatteryDevices.count() - 1; i >= 0; i--) + allKeys.append(QString("bat%1").arg(i)); + allKeys.append(QString("bat")); + // player + allKeys.append(QString("album")); + allKeys.append(QString("artist")); + allKeys.append(QString("duration")); + allKeys.append(QString("progress")); + allKeys.append(QString("title")); + allKeys.append(QString("dalbum")); + allKeys.append(QString("dartist")); + allKeys.append(QString("dtitle")); + allKeys.append(QString("salbum")); + allKeys.append(QString("sartist")); + allKeys.append(QString("stitle")); + // ps + allKeys.append(QString("pscount")); + allKeys.append(QString("pstotal")); + allKeys.append(QString("ps")); + // package manager + for (int i = extUpgrade->activeItems().count() - 1; i >= 0; i--) + allKeys.append( + extUpgrade->activeItems().at(i)->tag(QString("pkgcount"))); + // quotes + for (int i = extQuotes->activeItems().count() - 1; i >= 0; i--) { + allKeys.append(extQuotes->activeItems().at(i)->tag(QString("ask"))); + allKeys.append(extQuotes->activeItems().at(i)->tag(QString("askchg"))); + allKeys.append( + extQuotes->activeItems().at(i)->tag(QString("percaskchg"))); + allKeys.append(extQuotes->activeItems().at(i)->tag(QString("bid"))); + allKeys.append(extQuotes->activeItems().at(i)->tag(QString("bidchg"))); + allKeys.append( + extQuotes->activeItems().at(i)->tag(QString("percbidchg"))); + allKeys.append(extQuotes->activeItems().at(i)->tag(QString("price"))); + allKeys.append( + extQuotes->activeItems().at(i)->tag(QString("pricechg"))); + allKeys.append( + extQuotes->activeItems().at(i)->tag(QString("percpricechg"))); + } + // custom + for (int i = extScripts->activeItems().count() - 1; i >= 0; i--) + allKeys.append(extScripts->activeItems().at(i)->tag(QString("custom"))); + // desktop + allKeys.append(QString("desktop")); + allKeys.append(QString("ndesktop")); + allKeys.append(QString("tdesktops")); + // load average + allKeys.append(QString("la15")); + allKeys.append(QString("la5")); + allKeys.append(QString("la1")); + // bars + QStringList graphicalItemsKeys; + for (auto item : graphicalItems->items()) + graphicalItemsKeys.append(item->tag()); + graphicalItemsKeys.sort(); + for (int i = graphicalItemsKeys.count() - 1; i >= 0; i--) + allKeys.append(graphicalItemsKeys.at(i)); + + return allKeys; +} + + +GraphicalItem *AWKeyOperations::giByKey(const QString key) const +{ + qCDebug(LOG_AW) << "Looking for item" << key; + + return graphicalItems->itemByTag(key); +} + + +QString AWKeyOperations::infoByKey(QString key) const +{ + qCDebug(LOG_AW) << "Requested key" << key; + + key.remove(QRegExp(QString("^bar[0-9]{1,}"))); + if (key.startsWith(QString("custom"))) + return extScripts->itemByTagNumber( + key.remove(QString("custom")).toInt()) + ->uniq(); + else if (key.contains(QRegExp(QString("^hdd[rw]")))) + return QString("%1").arg(m_devices[QString( + "disk")][key.remove(QRegExp(QString("hdd[rw]"))).toInt()]); + else if (key.contains(QRegExp( + QString("^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)")))) + return QString("%1").arg(m_devices[QString( + "mount")][key + .remove(QRegExp(QString( + "^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)"))) + .toInt()]); + else if (key.startsWith(QString("hddtemp"))) + return QString("%1").arg( + m_devices[QString("hdd")][key.remove(QString("hddtemp")).toInt()]); + else if (key.contains(QRegExp(QString("^(down|up)[0-9]")))) + return QString("%1").arg(m_devices[QString( + "net")][key.remove(QRegExp(QString("^(down|up)"))).toInt()]); + else if (key.startsWith(QString("pkgcount"))) + return extUpgrade->itemByTagNumber( + key.remove(QString("pkgcount")).toInt()) + ->uniq(); + else if (key.contains(QRegExp(QString("(^|perc)(ask|bid|price)(chg|)")))) + return extQuotes->itemByTagNumber( + key.remove(QRegExp(QString( + "(^|perc)(ask|bid|price)(chg|)"))) + .toInt()) + ->uniq(); + else if (key.contains(QRegExp( + QString("(weather|weatherId|humidity|pressure|temperature)")))) + return extWeather + ->itemByTagNumber( + key + .remove(QRegExp(QString( + "(weather|weatherId|humidity|pressure|temperature)"))) + .toInt()) + ->uniq(); + else if (key.startsWith(QString("temp"))) + return QString("%1").arg( + m_devices[QString("temp")][key.remove(QString("temp")).toInt()]); + + return QString("(none)"); +} + + +QString AWKeyOperations::pattern() const +{ + return m_pattern; +} + + +void AWKeyOperations::setPattern(const QString currentPattern) +{ + qCDebug(LOG_AW) << "Set pattern" << currentPattern; + + m_pattern = currentPattern; +} + + +void AWKeyOperations::editItem(const QString type) +{ + qCDebug(LOG_AW) << "Item type" << type; + + if (type == QString("graphicalitem")) { + QStringList keys = dictKeys().filter(QRegExp( + QString("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)"))); + keys.sort(); + graphicalItems->setConfigArgs(keys); + return graphicalItems->editItems(); + } else if (type == QString("extquotes")) { + return extQuotes->editItems(); + } else if (type == QString("extscript")) { + return extScripts->editItems(); + } else if (type == QString("extupgrade")) { + return extUpgrade->editItems(); + } else if (type == QString("extweather")) { + return extWeather->editItems(); + } +} + + +void AWKeyOperations::addKeyToCache(const QString type, const QString key) +{ + qCDebug(LOG_AW) << "Key type" << type; + qCDebug(LOG_AW) << "Key" << key; + + AWKeyCache::addKeyToCache(type, key); + m_devices = AWKeyCache::loadKeysFromCache(); + reinitKeys(); +} + + +void AWKeyOperations::reinitKeys() +{ + // renew extensions + // delete them if any + delete graphicalItems; + graphicalItems = nullptr; + delete extQuotes; + extQuotes = nullptr; + delete extScripts; + extScripts = nullptr; + delete extUpgrade; + extUpgrade = nullptr; + delete extWeather; + extWeather = nullptr; + // create + graphicalItems + = new ExtItemAggregator(nullptr, QString("desktops")); + extQuotes = new ExtItemAggregator(nullptr, QString("quotes")); + extScripts = new ExtItemAggregator(nullptr, QString("scripts")); + extUpgrade = new ExtItemAggregator(nullptr, QString("upgrade")); + extWeather = new ExtItemAggregator(nullptr, QString("weather")); + + // init + QStringList allKeys = dictKeys(); + +#ifdef BUILD_TESTING + // not documented feature - place all available tags + m_pattern = m_pattern.replace(QString("$ALL"), [allKeys]() { + QStringList strings; + for (auto tag : allKeys) + strings.append(QString("%1: $%1").arg(tag)); + return strings.join(QString(" | ")); + }()); +#endif /* BUILD_TESTING */ + + // apply aw_* functions + m_pattern = AWPatternFunctions::insertKeyCount(m_pattern, allKeys); + m_pattern = AWPatternFunctions::insertKeyNames(m_pattern, allKeys); + m_pattern = AWPatternFunctions::insertKeys(m_pattern, allKeys); + // wrap templates + m_pattern = AWPatternFunctions::expandTemplates(m_pattern); + + emit(updateKeys(allKeys)); +} diff --git a/sources/awesome-widget/plugin/awkeyoperations.h b/sources/awesome-widget/plugin/awkeyoperations.h new file mode 100644 index 0000000..8510914 --- /dev/null +++ b/sources/awesome-widget/plugin/awkeyoperations.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * 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 AWKEYOPERATIONS_H +#define AWKEYOPERATIONS_H + +#include + +#include +#include + +#include "extitemaggregator.h" + + +class AWDataAggregator; +class AWDataEngineAggregator; +class AWKeysAggregator; +class ExtQuotes; +class ExtScript; +class ExtUpgrade; +class ExtWeather; +class GraphicalItem; +class QThreadPool; + +class AWKeyOperations : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString pattern READ pattern WRITE setPattern) + +public: + explicit AWKeyOperations(QObject *parent = nullptr); + virtual ~AWKeyOperations(); + void addDevice(const QString source); + QStringList devices(const QString type) const; + QHash devices() const; + void updateCache(); + // keys + QStringList dictKeys() const; + GraphicalItem *giByKey(const QString key) const; + // values + QString infoByKey(QString key) const; + QString pattern() const; + void setPattern(const QString currentPattern); + // configuration + void editItem(const QString type); + +signals: + void updateKeys(const QStringList currentKeys); + +private: + // methods + void addKeyToCache(const QString type, const QString key = QString("")); + void reinitKeys(); + // objects + ExtItemAggregator *graphicalItems = nullptr; + ExtItemAggregator *extQuotes = nullptr; + ExtItemAggregator *extScripts = nullptr; + ExtItemAggregator *extUpgrade = nullptr; + ExtItemAggregator *extWeather = nullptr; + // variables + QHash m_devices; + QString m_pattern; +}; + + +#endif /* AWKEYOPERATIONS_H */ diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/plugin/awkeys.cpp index 8a87bd6..f329c71 100644 --- a/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp @@ -18,23 +18,15 @@ #include "awkeys.h" #include -#include -#include #include -#include #include -#include -#include #include #include "awdataaggregator.h" #include "awdataengineaggregator.h" #include "awdebug.h" +#include "awkeyoperations.h" #include "awkeysaggregator.h" -#include "extquotes.h" -#include "extscript.h" -#include "extupgrade.h" -#include "extweather.h" #include "graphicalitem.h" #include "version.h" @@ -52,6 +44,10 @@ AWKeys::AWKeys(QObject *parent) aggregator = new AWKeysAggregator(this); dataAggregator = new AWDataAggregator(this); + keyOperator = new AWKeyOperations(this); + // update key data if required + connect(keyOperator, SIGNAL(updateKeys(QStringList)), this, + SLOT(reinitKeys(QStringList))); // transfer signal from AWDataAggregator object to QML ui connect(dataAggregator, SIGNAL(toolTipPainted(const QString)), this, SIGNAL(needToolTipToBeUpdated(const QString))); @@ -63,18 +59,12 @@ AWKeys::~AWKeys() { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; - // extensions - delete graphicalItems; - delete extQuotes; - delete extScripts; - delete extUpgrade; - delete extWeather; - // core delete dataEngineAggregator; delete m_threadPool; delete aggregator; delete dataAggregator; + delete keyOperator; } @@ -94,7 +84,7 @@ void AWKeys::initKeys(const QString currentPattern, const int interval, qCDebug(LOG_AW) << "Queue limit" << limit; // init - m_pattern = currentPattern; + keyOperator->setPattern(currentPattern); if (dataEngineAggregator == nullptr) { dataEngineAggregator = new AWDataEngineAggregator(this, interval); connect(this, SIGNAL(dropSourceFromDataengine(QString)), @@ -103,7 +93,7 @@ void AWKeys::initKeys(const QString currentPattern, const int interval, dataEngineAggregator->setInterval(interval); m_threadPool->setMaxThreadCount(limit == 0 ? QThread::idealThreadCount() : limit); - updateCache(); + keyOperator->updateCache(); return dataEngineAggregator->reconnectSources(); } @@ -128,9 +118,7 @@ void AWKeys::setWrapNewLines(const bool wrap) void AWKeys::updateCache() { - // update network and hdd list - addKeyToCache(QString("hdd")); - addKeyToCache(QString("net")); + return keyOperator->updateCache(); } @@ -139,161 +127,7 @@ QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const qCDebug(LOG_AW) << "Should be sorted" << sorted; qCDebug(LOG_AW) << "Filter" << regexp; - QStringList allKeys; - // weather - for (int i = extWeather->activeItems().count() - 1; i >= 0; i--) { - allKeys.append( - extWeather->activeItems().at(i)->tag(QString("weatherId"))); - allKeys.append( - extWeather->activeItems().at(i)->tag(QString("weather"))); - allKeys.append( - extWeather->activeItems().at(i)->tag(QString("humidity"))); - allKeys.append( - extWeather->activeItems().at(i)->tag(QString("pressure"))); - allKeys.append( - extWeather->activeItems().at(i)->tag(QString("temperature"))); - allKeys.append( - extWeather->activeItems().at(i)->tag(QString("timestamp"))); - } - // time - allKeys.append(QString("time")); - allKeys.append(QString("isotime")); - allKeys.append(QString("shorttime")); - allKeys.append(QString("longtime")); - allKeys.append(QString("ctime")); - // uptime - allKeys.append(QString("uptime")); - allKeys.append(QString("cuptime")); - // cpuclock & cpu - for (int i = QThread::idealThreadCount() - 1; i >= 0; i--) { - allKeys.append(QString("cpucl%1").arg(i)); - allKeys.append(QString("cpu%1").arg(i)); - } - allKeys.append(QString("cpucl")); - allKeys.append(QString("cpu")); - // temperature - for (int i = m_devices[QString("temp")].count() - 1; i >= 0; i--) - allKeys.append(QString("temp%1").arg(i)); - // gputemp - allKeys.append(QString("gputemp")); - // gpu - allKeys.append(QString("gpu")); - // memory - allKeys.append(QString("memmb")); - allKeys.append(QString("memgb")); - allKeys.append(QString("memfreemb")); - allKeys.append(QString("memfreegb")); - allKeys.append(QString("memtotmb")); - allKeys.append(QString("memtotgb")); - allKeys.append(QString("memusedmb")); - allKeys.append(QString("memusedgb")); - allKeys.append(QString("mem")); - // swap - allKeys.append(QString("swapmb")); - allKeys.append(QString("swapgb")); - allKeys.append(QString("swapfreemb")); - allKeys.append(QString("swapfreegb")); - allKeys.append(QString("swaptotmb")); - allKeys.append(QString("swaptotgb")); - allKeys.append(QString("swap")); - // hdd - for (int i = m_devices[QString("mount")].count() - 1; i >= 0; i--) { - allKeys.append(QString("hddmb%1").arg(i)); - allKeys.append(QString("hddgb%1").arg(i)); - allKeys.append(QString("hddfreemb%1").arg(i)); - allKeys.append(QString("hddfreegb%1").arg(i)); - allKeys.append(QString("hddtotmb%1").arg(i)); - allKeys.append(QString("hddtotgb%1").arg(i)); - allKeys.append(QString("hdd%1").arg(i)); - } - // hdd speed - for (int i = m_devices[QString("disk")].count() - 1; i >= 0; i--) { - allKeys.append(QString("hddr%1").arg(i)); - allKeys.append(QString("hddw%1").arg(i)); - } - // hdd temp - for (int i = m_devices[QString("hdd")].count() - 1; i >= 0; i--) - allKeys.append(QString("hddtemp%1").arg(i)); - // network - for (int i = m_devices[QString("net")].count() - 1; i >= 0; i--) { - allKeys.append(QString("downunits%1").arg(i)); - allKeys.append(QString("upunits%1").arg(i)); - allKeys.append(QString("downkb%1").arg(i)); - allKeys.append(QString("down%1").arg(i)); - allKeys.append(QString("upkb%1").arg(i)); - allKeys.append(QString("up%1").arg(i)); - } - allKeys.append(QString("downunits")); - allKeys.append(QString("upunits")); - allKeys.append(QString("downkb")); - allKeys.append(QString("down")); - allKeys.append(QString("upkb")); - allKeys.append(QString("up")); - allKeys.append(QString("netdev")); - // battery - allKeys.append(QString("ac")); - QStringList allBatteryDevices - = QDir(QString("/sys/class/power_supply")) - .entryList(QStringList() << QString("BAT*"), - QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); - for (int i = allBatteryDevices.count() - 1; i >= 0; i--) - allKeys.append(QString("bat%1").arg(i)); - allKeys.append(QString("bat")); - // player - allKeys.append(QString("album")); - allKeys.append(QString("artist")); - allKeys.append(QString("duration")); - allKeys.append(QString("progress")); - allKeys.append(QString("title")); - allKeys.append(QString("dalbum")); - allKeys.append(QString("dartist")); - allKeys.append(QString("dtitle")); - allKeys.append(QString("salbum")); - allKeys.append(QString("sartist")); - allKeys.append(QString("stitle")); - // ps - allKeys.append(QString("pscount")); - allKeys.append(QString("pstotal")); - allKeys.append(QString("ps")); - // package manager - for (int i = extUpgrade->activeItems().count() - 1; i >= 0; i--) - allKeys.append( - extUpgrade->activeItems().at(i)->tag(QString("pkgcount"))); - // quotes - for (int i = extQuotes->activeItems().count() - 1; i >= 0; i--) { - allKeys.append(extQuotes->activeItems().at(i)->tag(QString("ask"))); - allKeys.append(extQuotes->activeItems().at(i)->tag(QString("askchg"))); - allKeys.append( - extQuotes->activeItems().at(i)->tag(QString("percaskchg"))); - allKeys.append(extQuotes->activeItems().at(i)->tag(QString("bid"))); - allKeys.append(extQuotes->activeItems().at(i)->tag(QString("bidchg"))); - allKeys.append( - extQuotes->activeItems().at(i)->tag(QString("percbidchg"))); - allKeys.append(extQuotes->activeItems().at(i)->tag(QString("price"))); - allKeys.append( - extQuotes->activeItems().at(i)->tag(QString("pricechg"))); - allKeys.append( - extQuotes->activeItems().at(i)->tag(QString("percpricechg"))); - } - // custom - for (int i = extScripts->activeItems().count() - 1; i >= 0; i--) - allKeys.append(extScripts->activeItems().at(i)->tag(QString("custom"))); - // desktop - allKeys.append(QString("desktop")); - allKeys.append(QString("ndesktop")); - allKeys.append(QString("tdesktops")); - // load average - allKeys.append(QString("la15")); - allKeys.append(QString("la5")); - allKeys.append(QString("la1")); - // bars - QStringList graphicalItemsKeys; - for (auto item : graphicalItems->items()) - graphicalItemsKeys.append(item->tag()); - graphicalItemsKeys.sort(); - for (int i = graphicalItemsKeys.count() - 1; i >= 0; i--) - allKeys.append(graphicalItemsKeys.at(i)); - + QStringList allKeys = keyOperator->dictKeys(); // sort if required if (sorted) allKeys.sort(); @@ -304,7 +138,7 @@ QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const QStringList AWKeys::getHddDevices() const { - QStringList devices = m_devices[QString("hdd")]; + QStringList devices = keyOperator->devices(QString("hdd")); // required by selector in the UI devices.insert(0, QString("disable")); devices.insert(0, QString("auto")); @@ -317,51 +151,7 @@ QString AWKeys::infoByKey(QString key) const { qCDebug(LOG_AW) << "Requested key" << key; - key.remove(QRegExp(QString("^bar[0-9]{1,}"))); - if (key.startsWith(QString("custom"))) - return extScripts->itemByTagNumber( - key.remove(QString("custom")).toInt()) - ->uniq(); - else if (key.contains(QRegExp(QString("^hdd[rw]")))) - return QString("%1").arg(m_devices[QString( - "disk")][key.remove(QRegExp(QString("hdd[rw]"))).toInt()]); - else if (key.contains(QRegExp( - QString("^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)")))) - return QString("%1").arg(m_devices[QString( - "mount")][key - .remove(QRegExp(QString( - "^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)"))) - .toInt()]); - else if (key.startsWith(QString("hddtemp"))) - return QString("%1").arg( - m_devices[QString("hdd")][key.remove(QString("hddtemp")).toInt()]); - else if (key.contains(QRegExp(QString("^(down|up)[0-9]")))) - return QString("%1").arg(m_devices[QString( - "net")][key.remove(QRegExp(QString("^(down|up)"))).toInt()]); - else if (key.startsWith(QString("pkgcount"))) - return extUpgrade->itemByTagNumber( - key.remove(QString("pkgcount")).toInt()) - ->uniq(); - else if (key.contains(QRegExp(QString("(^|perc)(ask|bid|price)(chg|)")))) - return extQuotes->itemByTagNumber( - key.remove(QRegExp(QString( - "(^|perc)(ask|bid|price)(chg|)"))) - .toInt()) - ->uniq(); - else if (key.contains(QRegExp( - QString("(weather|weatherId|humidity|pressure|temperature)")))) - return extWeather - ->itemByTagNumber( - key - .remove(QRegExp(QString( - "(weather|weatherId|humidity|pressure|temperature)"))) - .toInt()) - ->uniq(); - else if (key.startsWith(QString("temp"))) - return QString("%1").arg( - m_devices[QString("temp")][key.remove(QString("temp")).toInt()]); - - return QString("(none)"); + return keyOperator->infoByKey(key); } @@ -379,19 +169,7 @@ void AWKeys::editItem(const QString type) { qCDebug(LOG_AW) << "Item type" << type; - if (type == QString("graphicalitem")) { - graphicalItems->setConfigArgs(dictKeys( - true, QString("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)"))); - return graphicalItems->editItems(); - } else if (type == QString("extquotes")) { - return extQuotes->editItems(); - } else if (type == QString("extscript")) { - return extScripts->editItems(); - } else if (type == QString("extupgrade")) { - return extUpgrade->editItems(); - } else if (type == QString("extweather")) { - return extWeather->editItems(); - } + return keyOperator->editItem(type); } @@ -399,21 +177,7 @@ void AWKeys::addDevice(const QString source) { qCDebug(LOG_AW) << "Source" << source; - QRegExp diskRegexp - = QRegExp(QString("disk/(?:md|sd|hd)[a-z|0-9]_.*/Rate/(?:rblk)")); - QRegExp mountRegexp = QRegExp(QString("partitions/.*/filllevel")); - - if (source.contains(diskRegexp)) { - QString device = source; - device.remove(QString("/Rate/rblk")); - addKeyToCache(QString("disk"), device); - } else if (source.contains(mountRegexp)) { - QString device = source; - device.remove(QString("partitions")).remove(QString("/filllevel")); - addKeyToCache(QString("mount"), device); - } else if (source.startsWith(QString("lmsensors"))) { - addKeyToCache(QString("temp"), source); - } + return keyOperator->addDevice(source); } @@ -432,73 +196,15 @@ void AWKeys::dataUpdated(const QString &sourceName, } -void AWKeys::loadKeysFromCache() +void AWKeys::reinitKeys(const QStringList currentKeys) { - QString fileName = QString("%1/awesomewidgets.ndx") - .arg(QStandardPaths::writableLocation( - QStandardPaths::GenericCacheLocation)); - qCInfo(LOG_AW) << "Cache file" << fileName; - QSettings cache(fileName, QSettings::IniFormat); - - for (auto group : cache.childGroups()) { - cache.beginGroup(group); - m_devices.remove(group); - for (auto key : cache.allKeys()) - m_devices[group].append(cache.value(key).toString()); - cache.endGroup(); - } - - return reinitKeys(); -} - - -void AWKeys::reinitKeys() -{ - // renew extensions - // delete them if any - delete graphicalItems; - graphicalItems = nullptr; - delete extQuotes; - extQuotes = nullptr; - delete extScripts; - extScripts = nullptr; - delete extUpgrade; - extUpgrade = nullptr; - delete extWeather; - extWeather = nullptr; - // create - graphicalItems - = new ExtItemAggregator(nullptr, QString("desktops")); - extQuotes = new ExtItemAggregator(nullptr, QString("quotes")); - extScripts = new ExtItemAggregator(nullptr, QString("scripts")); - extUpgrade = new ExtItemAggregator(nullptr, QString("upgrade")); - extWeather = new ExtItemAggregator(nullptr, QString("weather")); - - // init - QStringList allKeys = dictKeys(); - -#ifdef BUILD_TESTING - // not documented feature - place all available tags - m_pattern = m_pattern.replace(QString("$ALL"), [allKeys]() { - QStringList strings; - for (auto tag : allKeys) - strings.append(QString("%1: $%1").arg(tag)); - return strings.join(QString(" | ")); - }()); -#endif /* BUILD_TESTING */ - - // apply aw_* functions - m_pattern = insertKeyCount(m_pattern); - m_pattern = insertKeyNames(m_pattern); - m_pattern = insertKeys(m_pattern); - // wrap templates - expandTemplates(); + qCDebug(LOG_AW) << "Update found keys by using list" << currentKeys; // append lists // bars - m_foundBars = [allKeys](const QString pattern) { + m_foundBars = [currentKeys](const QString pattern) { QStringList selectedKeys; - for (auto key : allKeys) + for (auto key : currentKeys) if ((key.startsWith(QString("bar"))) && (pattern.contains(QString("$%1").arg(key)))) { qCInfo(LOG_AW) << "Found bar" << key; @@ -507,12 +213,12 @@ void AWKeys::reinitKeys() if (selectedKeys.isEmpty()) qCWarning(LOG_AW) << "No bars found"; return selectedKeys; - }(m_pattern); + }(keyOperator->pattern()); // main key list - m_foundKeys = [allKeys](const QString pattern) { + m_foundKeys = [currentKeys](const QString pattern) { QStringList selectedKeys; - for (auto key : allKeys) + for (auto key : currentKeys) if ((!key.startsWith(QString("bar"))) && (pattern.contains(QString("$%1").arg(key)))) { qCInfo(LOG_AW) << "Found key" << key; @@ -521,7 +227,7 @@ void AWKeys::reinitKeys() if (selectedKeys.isEmpty()) qCWarning(LOG_AW) << "No keys found"; return selectedKeys; - }(m_pattern); + }(keyOperator->pattern()); // lambdas m_foundLambdas = [](const QString pattern) { @@ -536,7 +242,7 @@ void AWKeys::reinitKeys() while (it.hasNext()) { QRegularExpressionMatch match = it.next(); QString lambda = match.captured(); - // drop brakets + // drop brackets lambda.remove(QRegExp(QString("^\\$\\{\\{"))); lambda.remove(QRegExp(QString("\\}\\}$"))); // append @@ -546,10 +252,10 @@ void AWKeys::reinitKeys() if (selectedKeys.isEmpty()) qCWarning(LOG_AW) << "No lambdas found"; return selectedKeys; - }(m_pattern); + }(keyOperator->pattern()); // set key data to aggregator - aggregator->setDevices(m_devices); + aggregator->setDevices(keyOperator->devices()); } @@ -557,7 +263,7 @@ void AWKeys::updateTextData() { QFuture text = QtConcurrent::run(m_threadPool, [this]() { calculateValues(); - return parsePattern(m_pattern); + return parsePattern(keyOperator->pattern()); }); emit(needTextToBeUpdated(text)); @@ -565,69 +271,14 @@ void AWKeys::updateTextData() } -void AWKeys::addKeyToCache(const QString type, const QString key) -{ - qCDebug(LOG_AW) << "Key type" << type; - qCDebug(LOG_AW) << "Key" << key; - - QString fileName = QString("%1/awesomewidgets.ndx") - .arg(QStandardPaths::writableLocation( - QStandardPaths::GenericCacheLocation)); - qCInfo(LOG_AW) << "Cache file" << fileName; - QSettings cache(fileName, QSettings::IniFormat); - - cache.beginGroup(type); - QStringList cachedValues; - for (auto key : cache.allKeys()) - cachedValues.append(cache.value(key).toString()); - - if (type == QString("hdd")) { - QStringList allDevices - = QDir(QString("/dev")).entryList(QDir::System, QDir::Name); - QStringList devices - = allDevices.filter(QRegExp(QString("^[hms]d[a-z]$"))); - for (auto dev : devices) { - QString device = QString("/dev/%1").arg(dev); - if (cachedValues.contains(device)) - continue; - qCInfo(LOG_AW) << "Found new key" << device << "for type" << type; - cache.setValue( - QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), - device); - } - } else if (type == QString("net")) { - QList rawInterfaceList - = QNetworkInterface::allInterfaces(); - for (auto interface : rawInterfaceList) { - QString device = interface.name(); - if (cachedValues.contains(device)) - continue; - qCInfo(LOG_AW) << "Found new key" << device << "for type" << type; - cache.setValue( - QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), - device); - } - } else { - if (cachedValues.contains(key)) - return; - qCInfo(LOG_AW) << "Found new key" << key << "for type" << type; - cache.setValue( - QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), key); - } - cache.endGroup(); - - cache.sync(); - return loadKeysFromCache(); -} - - // HACK this method is required since I could not define some values by using // specified pattern. Usually they are values which depend on several others void AWKeys::calculateValues() { // hddtot* - for (auto device : m_devices[QString("mount")]) { - int index = m_devices[QString("mount")].indexOf(device); + QStringList mountDevices = keyOperator->devices(QString("mount")); + for (auto device : mountDevices) { + int index = mountDevices.indexOf(device); values[QString("hddtotmb%1").arg(index)] = QString("%1").arg( values[QString("hddfreemb%1").arg(index)].toFloat() + values[QString("hddmb%1").arg(index)].toFloat(), @@ -654,7 +305,8 @@ void AWKeys::calculateValues() 5, 'f', 1); // up, down, upkb, downkb, upunits, downunits - int netIndex = m_devices[QString("net")].indexOf(values[QString("netdev")]); + int netIndex = keyOperator->devices(QString("net")) + .indexOf(values[QString("netdev")]); values[QString("down")] = values[QString("down%1").arg(netIndex)]; values[QString("downkb")] = values[QString("downkb%1").arg(netIndex)]; values[QString("downunits")] = values[QString("downunits%1").arg(netIndex)]; @@ -699,136 +351,6 @@ void AWKeys::calculateValues() } -void AWKeys::expandTemplates() -{ - // match the following construction $template{{some code here}} - QRegularExpression templatesRegexp( - QString("\\$template\\{\\{((?!\\$template\\{\\{).)*?\\}\\}")); - templatesRegexp.setPatternOptions( - QRegularExpression::DotMatchesEverythingOption); - - QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(m_pattern); - while (it.hasNext()) { - QRegularExpressionMatch match = it.next(); - QString fullTemplate = match.captured(); - - // drop additional markers - QString templ = fullTemplate; - templ.remove(QRegExp(QString("^\\$template\\{\\{"))); - templ.remove(QRegExp(QString("\\}\\}$"))); - - QJSEngine engine; - qCInfo(LOG_AW) << "Expression" << templ; - QJSValue result = engine.evaluate(templ); - QString templateResult = QString(""); - if (result.isError()) { - qCWarning(LOG_AW) << "Uncaught exception at line" - << result.property("lineNumber").toInt() << ":" - << result.toString(); - } else { - templateResult = result.toString(); - } - - // replace template - m_pattern.replace(fullTemplate, templateResult); - } -} - - -QString AWKeys::insertKeyCount(QString code) const -{ - qCDebug(LOG_AW) << "Looking for count in code" << code; - - QRegularExpression countRegexp(QString("aw_count\\(((?!\\aw_count\\().)*?\\)")); - countRegexp.setPatternOptions( - QRegularExpression::DotMatchesEverythingOption); - - QRegularExpressionMatchIterator it = countRegexp.globalMatch(code); - while (it.hasNext()) { - QRegularExpressionMatch match = it.next(); - QString count = match.captured(); - - // get regexp to search - QString regex = count; - regex.remove(QRegExp(QString("^aw_count\\("))); - regex.remove(QRegExp(QString("\\)$"))); - qCInfo(LOG_AW) << "Looking for" << regex; - - code.replace(count, QString::number(dictKeys(false, regex).count())); - } - - return code; -} - - -QString AWKeys::insertKeyNames(QString code) const -{ - qCDebug(LOG_AW) << "Looking for keys in code" << code; - - QRegularExpression keysRegexp(QString("aw_names\\(((?!\\aw_names\\().)*?\\)")); - keysRegexp.setPatternOptions( - QRegularExpression::DotMatchesEverythingOption); - - QRegularExpressionMatchIterator it = keysRegexp.globalMatch(code); - while (it.hasNext()) { - QRegularExpressionMatch match = it.next(); - QString keys = match.captured(); - - // get regexp to search - QString condition = keys; - condition.remove(QRegExp(QString("^aw_names\\("))); - condition.remove(QRegExp(QString("\\)$"))); - QStringList conditionList = condition.split(QChar(',')); - // regexp - QString regex = conditionList.at(0); - // separator to join - QString separator = conditionList.size() == 1 ? QString("") : conditionList.at(1); - qCInfo(LOG_AW) << "Looking for" << regex << "with separator" << separator; - - code.replace(keys, dictKeys(true, regex).join(separator)); - } - - return code; -} - - -QString AWKeys::insertKeys(QString code) const -{ - qCDebug(LOG_AW) << "Looking for keys in code" << code; - - QRegularExpression keysRegexp(QString("aw_keys\\(((?!\\aw_keys\\().)*?\\)")); - keysRegexp.setPatternOptions( - QRegularExpression::DotMatchesEverythingOption); - - QRegularExpressionMatchIterator it = keysRegexp.globalMatch(code); - while (it.hasNext()) { - QRegularExpressionMatch match = it.next(); - QString keys = match.captured(); - - // get regexp to search - QString condition = keys; - condition.remove(QRegExp(QString("^aw_keys\\("))); - condition.remove(QRegExp(QString("\\)$"))); - QStringList conditionList = condition.split(QChar(',')); - // regexp - QString regex = conditionList.at(0); - // separator to join - QString separator = conditionList.size() == 1 ? QString("") : conditionList.at(1); - qCInfo(LOG_AW) << "Looking for" << regex << "with separator" << separator; - - // find keys and add $ at the beginning of the line - QStringList foundKeys = dictKeys(true, regex); - std::for_each(foundKeys.begin(), foundKeys.end(), [](QString &value) { - value = QString("$%1").arg(value); - }); - - code.replace(keys, foundKeys.join(separator)); - } - - return code; -} - - QString AWKeys::parsePattern(QString pattern) const { // screen sign @@ -850,7 +372,7 @@ QString AWKeys::parsePattern(QString pattern) const // bars for (auto bar : m_foundBars) { - GraphicalItem *item = graphicalItems->itemByTag(bar); + GraphicalItem *item = keyOperator->giByKey(bar); QString key = bar; key.remove(QRegExp(QString("^bar[0-9]{1,}"))); if (item->type() == GraphicalItem::Graph) diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h index 321a4cb..36c99c2 100644 --- a/sources/awesome-widget/plugin/awkeys.h +++ b/sources/awesome-widget/plugin/awkeys.h @@ -24,17 +24,11 @@ #include #include -#include "extitemaggregator.h" - class AWDataAggregator; class AWDataEngineAggregator; +class AWKeyOperations; class AWKeysAggregator; -class ExtQuotes; -class ExtScript; -class ExtUpgrade; -class ExtWeather; -class GraphicalItem; class QThreadPool; class AWKeys : public QObject @@ -50,6 +44,8 @@ public: Q_INVOKABLE void setAggregatorProperty(const QString key, const QVariant value); Q_INVOKABLE void setWrapNewLines(const bool wrap = false); + // additional method to force load keys from Qml UI. Used in some + // configuration pages Q_INVOKABLE void updateCache(); // keys Q_INVOKABLE QStringList dictKeys(const bool sorted = false, @@ -75,33 +71,21 @@ signals: void needToBeUpdated(); private slots: - void loadKeysFromCache(); - void reinitKeys(); + void reinitKeys(const QStringList currentKeys); void updateTextData(); private: // methods - void addKeyToCache(const QString type, const QString key = QString("")); void calculateValues(); - void expandTemplates(); - QString insertKeyCount(QString code) const; - QString insertKeyNames(QString code) const; - QString insertKeys(QString code) const; QString parsePattern(QString pattern) const; void setDataBySource(const QString &sourceName, const QVariantMap &data); // objects AWDataAggregator *dataAggregator = nullptr; AWDataEngineAggregator *dataEngineAggregator = nullptr; AWKeysAggregator *aggregator = nullptr; - ExtItemAggregator *graphicalItems = nullptr; - ExtItemAggregator *extQuotes = nullptr; - ExtItemAggregator *extScripts = nullptr; - ExtItemAggregator *extUpgrade = nullptr; - ExtItemAggregator *extWeather = nullptr; + AWKeyOperations *keyOperator = nullptr; // variables - QHash m_devices; QStringList m_foundBars, m_foundKeys, m_foundLambdas; - QString m_pattern; QHash values; bool m_wrapNewLines = false; // multithread features diff --git a/sources/awesome-widget/plugin/awpatternfunctions.cpp b/sources/awesome-widget/plugin/awpatternfunctions.cpp new file mode 100644 index 0000000..333700c --- /dev/null +++ b/sources/awesome-widget/plugin/awpatternfunctions.cpp @@ -0,0 +1,160 @@ +/*************************************************************************** + * 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 "awpatternfunctions.h" + +#include +#include + +#include "awdebug.h" + + +QVariantList AWPatternFunctions::findFunctionCalls(const QString function, + const QString code) +{ + qCDebug(LOG_AW) << "Looking for function" << function << "in" << code; + + QRegularExpression regex( + QString("%1\\<(?.*?)\\>\\((?.*?)\\)").arg(function)); + regex.setPatternOptions(QRegularExpression::DotMatchesEverythingOption); + + QVariantList foundFunctions; + QRegularExpressionMatchIterator it = regex.globalMatch(code); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + + QVariantHash metadata; + metadata[QString("args")] + = match.captured(QString("args")).split(QChar(',')); + metadata[QString("body")] = match.captured(QString("body")); + metadata[QString("what")] = match.captured(); + foundFunctions.append(metadata); + } + + return foundFunctions; +} + + +QString AWPatternFunctions::expandTemplates(QString code) +{ + qCDebug(LOG_AW) << "Expand tempaltes in" << code; + + // match the following construction $template{{some code here}} + QRegularExpression templatesRegexp( + QString("\\$template\\{\\{((?!\\$template\\{\\{).)*?\\}\\}")); + templatesRegexp.setPatternOptions( + QRegularExpression::DotMatchesEverythingOption); + + QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(code); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + QString fullTemplate = match.captured(); + + // drop additional markers + QString templ = fullTemplate; + templ.remove(QRegExp(QString("^\\$template\\{\\{"))); + templ.remove(QRegExp(QString("\\}\\}$"))); + + QJSEngine engine; + qCInfo(LOG_AW) << "Expression" << templ; + QJSValue result = engine.evaluate(templ); + QString templateResult = QString(""); + if (result.isError()) { + qCWarning(LOG_AW) << "Uncaught exception at line" + << result.property("lineNumber").toInt() << ":" + << result.toString(); + } else { + templateResult = result.toString(); + } + + // replace template + code.replace(fullTemplate, templateResult); + } + + return code; +} + + +QString AWPatternFunctions::insertKeyCount(QString code, const QStringList keys) +{ + qCDebug(LOG_AW) << "Looking for count in code" << code << "using list" + << keys; + + QVariantList found + = AWPatternFunctions::findFunctionCalls(QString("aw_count"), code); + for (auto function : found) { + QVariantHash metadata = function.toHash(); + int count = keys.filter(QRegExp(metadata[QString("body")].toString())) + .count(); + + code.replace(metadata[QString("what")].toString(), + QString::number(count)); + } + + return code; +} + + +QString AWPatternFunctions::insertKeyNames(QString code, const QStringList keys) +{ + qCDebug(LOG_AW) << "Looking for keys in code" << code << "using list" + << keys; + + QVariantList found + = AWPatternFunctions::findFunctionCalls(QString("aw_names"), code); + for (auto function : found) { + QVariantHash metadata = function.toHash(); + QString separator + = metadata[QString("args")].toStringList().isEmpty() + ? QString(",") + : metadata[QString("args")].toStringList().at(0); + QStringList required + = keys.filter(QRegExp(metadata[QString("body")].toString())); + + code.replace(metadata[QString("what")].toString(), + required.join(separator)); + } + + return code; +} + + +QString AWPatternFunctions::insertKeys(QString code, const QStringList keys) +{ + qCDebug(LOG_AW) << "Looking for keys in code" << code << "using list" + << keys; + + QVariantList found + = AWPatternFunctions::findFunctionCalls(QString("aw_keys"), code); + for (auto function : found) { + QVariantHash metadata = function.toHash(); + QString separator + = metadata[QString("args")].toStringList().isEmpty() + ? QString(",") + : metadata[QString("args")].toStringList().at(0); + QStringList required + = keys.filter(QRegExp(metadata[QString("body")].toString())); + std::for_each(required.begin(), required.end(), [](QString &value) { + value = QString("$%1").arg(value); + }); + + code.replace(metadata[QString("what")].toString(), + required.join(separator)); + } + + return code; +} diff --git a/sources/awesome-widget/plugin/awpatternfunctions.h b/sources/awesome-widget/plugin/awpatternfunctions.h new file mode 100644 index 0000000..c53d77a --- /dev/null +++ b/sources/awesome-widget/plugin/awpatternfunctions.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * 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 AWPATTERNFUNCTIONS_H +#define AWPATTERNFUNCTIONS_H + +#include +#include + + +namespace AWPatternFunctions +{ +QString expandTemplates(QString code); +QVariantList findFunctionCalls(const QString function, const QString code); +QString insertKeyCount(QString code, const QStringList keys); +QString insertKeyNames(QString code, const QStringList keys); +QString insertKeys(QString code, const QStringList keys); +}; + + +#endif /* AWPATTERNFUNCTIONS_H */ From bfac30c304d43993d623a0612c40ee6e14088ba7 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Sun, 31 Jan 2016 00:07:40 +0700 Subject: [PATCH 12/17] add dpkg options to travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5615fd4..0859021 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ os: before_install: - sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list - sudo apt-get update -qq - - sudo apt-get upgrade + - sudo apt-get -y -q -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew upgrade addons: apt: From 210415cdffeec98513967d4a926a743051bf3ab8 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Sun, 31 Jan 2016 00:19:04 +0700 Subject: [PATCH 13/17] more correct work with kubuntu ppa, less output messages --- .travis.yml | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0859021..18090a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,26 +8,12 @@ os: before_install: - sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list - sudo apt-get update -qq - - sudo apt-get -y -q -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew upgrade - -addons: - apt: - sources: - - kubuntu-backports - packages: - - cmake - - extra-cmake-modules - - g++ - - git - - libkf5i18n-dev - - libkf5notifications-dev - - libkf5service-dev - - libkf5windowsystem-dev - - plasma-framework-dev - - qtbase5-dev - - qtdeclarative5-dev + - sudo apt-get -y -qq -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew upgrade before_script: + - sudo apt-add-repository -y ppa:kubuntu-ppa/backports + - sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list.d/kubuntu-ppa-backports-trusty.list + - sudo apt-get -y -qq install libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev extra-cmake-modules cmake g++ - rm -rf build - mkdir build From fb7fc4a10448bb4e4f6af0652ced2d429d9ee04e Mon Sep 17 00:00:00 2001 From: arcan1s Date: Sun, 31 Jan 2016 00:28:39 +0700 Subject: [PATCH 14/17] one more edit travis.yml --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 18090a3..c9684d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,13 +5,9 @@ language: cpp os: - linux -before_install: - - sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list - - sudo apt-get update -qq - - sudo apt-get -y -qq -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew upgrade - before_script: - sudo apt-add-repository -y ppa:kubuntu-ppa/backports + - sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list - sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list.d/kubuntu-ppa-backports-trusty.list - sudo apt-get -y -qq install libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev extra-cmake-modules cmake g++ - rm -rf build From c1cf8185a3fbd22f212c194dafef49f17d7fd667 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Sun, 31 Jan 2016 00:34:31 +0700 Subject: [PATCH 15/17] ...and another edit travis.yml --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c9684d7..0ddd9af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,8 @@ before_script: - sudo apt-add-repository -y ppa:kubuntu-ppa/backports - sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list - sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list.d/kubuntu-ppa-backports-trusty.list - - sudo apt-get -y -qq install libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev extra-cmake-modules cmake g++ + - sudo apt-get -qq update + - sudo apt-get -y -qq -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew install libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev extra-cmake-modules cmake g++ - rm -rf build - mkdir build From beb2682b04f49e9e791b912291e4a695168c14b5 Mon Sep 17 00:00:00 2001 From: arcan1s Date: Mon, 1 Feb 2016 00:25:28 +0700 Subject: [PATCH 16/17] Stabilizing commit * move request timeout settings to the configuration header * initial support of requiredby dictionary * add AWPatternFunctions namespace * improve components communication * update UI to recent abilities * rewrite qCDebug messages and update CONTRIBUTING.md accordingly --- .travis.yml => .travis.yml.bckp | 0 CONTRIBUTING.md | 7 +- .../package/contents/ui/widget.qml | 25 ++-- sources/awesome-widget/plugin/awactions.cpp | 8 +- .../awesome-widget/plugin/awconfighelper.cpp | 11 +- .../plugin/awdataaggregator.cpp | 28 ++-- .../plugin/awdataengineaggregator.cpp | 8 +- .../plugin/awdataengineaggregator.h | 3 + .../awesome-widget/plugin/awesomewidget.cpp | 1 + sources/awesome-widget/plugin/awkeycache.cpp | 8 +- sources/awesome-widget/plugin/awkeycache.h | 2 +- .../awesome-widget/plugin/awkeyoperations.cpp | 67 ++++----- .../awesome-widget/plugin/awkeyoperations.h | 4 +- sources/awesome-widget/plugin/awkeys.cpp | 119 ++++----------- sources/awesome-widget/plugin/awkeys.h | 1 - .../plugin/awkeysaggregator.cpp | 59 +++++++- .../awesome-widget/plugin/awkeysaggregator.h | 2 + .../plugin/awpatternfunctions.cpp | 137 ++++++++++++++++-- .../plugin/awpatternfunctions.h | 6 + sources/awesomewidgets/abstractextitem.cpp | 5 +- .../abstractextitemaggregator.cpp | 4 +- .../abstractextitemaggregator.h | 2 +- sources/awesomewidgets/extitemaggregator.h | 19 +-- sources/awesomewidgets/extquotes.cpp | 6 +- sources/awesomewidgets/extscript.cpp | 6 +- sources/awesomewidgets/extupgrade.cpp | 3 +- sources/awesomewidgets/extweather.cpp | 7 +- sources/awesomewidgets/graphicalitem.cpp | 3 +- sources/desktop-panel/plugin/dpadds.cpp | 9 +- sources/extsysmon/sources/playersource.cpp | 8 +- sources/version.h.in | 2 + 31 files changed, 326 insertions(+), 244 deletions(-) rename .travis.yml => .travis.yml.bckp (100%) diff --git a/.travis.yml b/.travis.yml.bckp similarity index 100% rename from .travis.yml rename to .travis.yml.bckp diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 88feee2..c024dd9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -147,13 +147,12 @@ For logging please use [QLoggingCategory](http://doc.qt.io/qt-5/qloggingcategory Available categories should be declared in `awdebug.*` files. The following log levels should be used: -* **debug** (`qCDebug()`) - method arguments information. +* **debug** (`qCDebug()`) - method arguments information. Please note that it + is recommended to logging all arguments in the one line. * **info** (`qCInfo()`) - additional information inside methods. * **warning** (`qCWarning()`) - not critical information, which may be caused by mistakes in configuration for example. -* **error** (`qCError()`) - an error which has been captured in runtime. All errors - should have own callback methods. -* **critical** (`qCCritical()`) - a critical error. After this error program will +* **critical** (`qCCritical()`) - a critical error. After this error program may be terminated. The empty log string (e.g. `qCDebug();`) is not allowed because the method names diff --git a/sources/awesome-widget/package/contents/ui/widget.qml b/sources/awesome-widget/package/contents/ui/widget.qml index 2787c5e..4c7c508 100644 --- a/sources/awesome-widget/package/contents/ui/widget.qml +++ b/sources/awesome-widget/package/contents/ui/widget.qml @@ -198,7 +198,7 @@ Item { height: implicitHeight width: parent.width QtControls.ComboBox { - width: parent.width * 1 / 5 + width: parent.width * 2 / 5 textRole: "label" model: [ { @@ -252,11 +252,20 @@ Item { { 'label': i18n("Weathers"), 'regexp': "^(weather(Id)?|humidity|pressure|temperature|timestamp)" + }, + { + 'label': i18n("Functions"), + 'regexp': "functions" } ] onCurrentIndexChanged: { if (debug) console.debug() - tags.model = awKeys.dictKeys(true, model[currentIndex]["regexp"]) + if (model[currentIndex]["regexp"] == "functions") + tags.model = ["{{\n\n}}", "template{{\n\n}}", + "aw_all<>()", "aw_count<>()", "aw_keys<>()", + "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 } @@ -293,18 +302,6 @@ Item { awActions.sendNotification("tag", message) } } - QtControls.Button { - width: parent.width * 1 / 5 - text: i18n("Add lambda") - - onClicked: { - if (debug) console.debug("Lambda button") - var pos = textPattern.cursorPosition - var selected = textPattern.selectedText - textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd) - textPattern.insert(pos, selected + "${{\n\n}}") - } - } } Row { diff --git a/sources/awesome-widget/plugin/awactions.cpp b/sources/awesome-widget/plugin/awactions.cpp index 8ac7a4d..f519632 100644 --- a/sources/awesome-widget/plugin/awactions.cpp +++ b/sources/awesome-widget/plugin/awactions.cpp @@ -179,8 +179,7 @@ QVariantMap AWActions::getFont(const QVariantMap defaultFont) const // to avoid additional object definition this method is static void AWActions::sendNotification(const QString eventId, const QString message) { - qCDebug(LOG_AW) << "Event" << eventId; - qCDebug(LOG_AW) << "Message" << message; + qCDebug(LOG_AW) << "Event" << eventId << "with message" << message; KNotification *notification = KNotification::event( eventId, QString("Awesome Widget ::: %1").arg(eventId), message); @@ -229,9 +228,8 @@ void AWActions::showUpdates(const QString version) const void AWActions::versionReplyRecieved(QNetworkReply *reply, const bool showAnyway) const { - qCDebug(LOG_AW) << "Return code" << reply->error(); - qCDebug(LOG_AW) << "Reply error message" << reply->errorString(); - qCDebug(LOG_AW) << "Show anyway" << showAnyway; + qCDebug(LOG_AW) << "Return code" << reply->error() << "with message" + << reply->errorString() << "and show anyway" << showAnyway; QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error); diff --git a/sources/awesome-widget/plugin/awconfighelper.cpp b/sources/awesome-widget/plugin/awconfighelper.cpp index 2961d13..2dd0259 100644 --- a/sources/awesome-widget/plugin/awconfighelper.cpp +++ b/sources/awesome-widget/plugin/awconfighelper.cpp @@ -216,9 +216,8 @@ void AWConfigHelper::copyExtensions(const QString item, const QString type, QSettings &settings, const bool inverse) const { - qCDebug(LOG_AW) << "Extension" << item; - qCDebug(LOG_AW) << "Type" << type; - qCDebug(LOG_AW) << "Inverse" << inverse; + qCDebug(LOG_AW) << "Extension" << item << "has type" << type + << "inverse copying" << inverse; settings.beginGroup(item); QSettings itemSettings( @@ -247,8 +246,7 @@ void AWConfigHelper::copySettings(QSettings &from, QSettings &to) const void AWConfigHelper::readFile(QSettings &settings, const QString key, const QString fileName) const { - qCDebug(LOG_AW) << "Key" << key; - qCDebug(LOG_AW) << "File" << fileName; + qCDebug(LOG_AW) << "Key" << key << "from file" << fileName; QFile file(fileName); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -264,8 +262,7 @@ void AWConfigHelper::readFile(QSettings &settings, const QString key, void AWConfigHelper::writeFile(QSettings &settings, const QString key, const QString fileName) const { - qCDebug(LOG_AW) << "Key" << key; - qCDebug(LOG_AW) << "File" << fileName; + qCDebug(LOG_AW) << "Key" << key << "to file" << fileName; if (!settings.contains(key)) return; diff --git a/sources/awesome-widget/plugin/awdataaggregator.cpp b/sources/awesome-widget/plugin/awdataaggregator.cpp index 701b922..01b358c 100644 --- a/sources/awesome-widget/plugin/awdataaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataaggregator.cpp @@ -90,7 +90,7 @@ void AWDataAggregator::setParameters(QVariantMap settings) counts += configuration[QString("downTooltip")].toInt(); counts += configuration[QString("batTooltip")].toInt(); // resize tooltip image - toolTipView->resize(100.0 * counts, 105.0); + toolTipView->resize(100 * counts, 105); boundaries[QString("cpuTooltip")] = 100.0; boundaries[QString("cpuclTooltip")] = 4000.0; @@ -179,9 +179,8 @@ void AWDataAggregator::dataUpdate(const QHash &values) void AWDataAggregator::checkValue(const QString source, const float value, const float extremum) const { - qCDebug(LOG_AW) << "Notification source" << source; - qCDebug(LOG_AW) << "Value" << value; - qCDebug(LOG_AW) << "Called with extremum" << extremum; + qCDebug(LOG_AW) << "Notification source" << source << "with value" << value + << "called with extremum" << extremum; if (value >= 0.0) { if ((m_enablePopup) && (value > extremum) @@ -200,9 +199,8 @@ void AWDataAggregator::checkValue(const QString source, const float value, void AWDataAggregator::checkValue(const QString source, const QString current, const QString received) const { - qCDebug(LOG_AW) << "Notification source" << source; - qCDebug(LOG_AW) << "Current value" << current; - qCDebug(LOG_AW) << "Received value" << received; + qCDebug(LOG_AW) << "Notification source" << source << "with current value" + << current << "and received one" << received; if ((m_enablePopup) && (current != received) && (!received.isEmpty())) return AWActions::sendNotification(QString("event"), @@ -225,8 +223,7 @@ void AWDataAggregator::initScene() QString AWDataAggregator::notificationText(const QString source, const float value) const { - qCDebug(LOG_AW) << "Notification source" << source; - qCDebug(LOG_AW) << "Value" << value; + qCDebug(LOG_AW) << "Notification source" << source << "with value" << value; QString output; if (source == QString("batTooltip")) @@ -247,8 +244,7 @@ QString AWDataAggregator::notificationText(const QString source, QString AWDataAggregator::notificationText(const QString source, const QString value) const { - qCDebug(LOG_AW) << "Notification source" << source; - qCDebug(LOG_AW) << "Value" << value; + qCDebug(LOG_AW) << "Notification source" << source << "with value" << value; QString output; if (source == QString("netdev")) @@ -287,9 +283,8 @@ void AWDataAggregator::setData(const QHash &values) void AWDataAggregator::setData(const QString &source, float value, const float extremum) { - qCDebug(LOG_AW) << "Source" << source; - qCDebug(LOG_AW) << "Value" << value; - qCDebug(LOG_AW) << "Called with extremum" << extremum; + qCDebug(LOG_AW) << "Source" << source << "to value" << value + << "with extremum" << extremum; if (data[source].count() == 0) data[source].append(0.0); @@ -316,9 +311,8 @@ void AWDataAggregator::setData(const QString &source, float value, void AWDataAggregator::setData(const bool dontInvert, const QString &source, float value) { - qCDebug(LOG_AW) << "Do not invert value" << dontInvert; - qCDebug(LOG_AW) << "Source" << source; - qCDebug(LOG_AW) << "Value" << value; + qCDebug(LOG_AW) << "Do not invert" << dontInvert << "value" << value + << "for source" << source; // invert values for different battery colours value = dontInvert ? value : -value; diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.cpp b/sources/awesome-widget/plugin/awdataengineaggregator.cpp index 9669c56..7ff6642 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataengineaggregator.cpp @@ -45,9 +45,9 @@ AWDataEngineAggregator::~AWDataEngineAggregator() void AWDataEngineAggregator::disconnectSources() { - for (auto dataengine : m_dataEngines.keys()) - for (auto source : m_dataEngines[dataengine]->sources()) - m_dataEngines[dataengine]->disconnectSource(source, parent()); + for (auto dataengine : m_dataEngines.values()) + for (auto source : dataengine->sources()) + dataengine->disconnectSource(source, parent()); } @@ -93,7 +93,7 @@ void AWDataEngineAggregator::initDataEngines() // additional method required by systemmonitor structure connect(m_dataEngines[QString("systemmonitor")], &Plasma::DataEngine::sourceAdded, [this](const QString source) { - static_cast(parent())->addDevice(source); + emit(deviceAdded(source)); m_dataEngines[QString("systemmonitor")]->connectSource( source, parent(), m_interval); }); diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.h b/sources/awesome-widget/plugin/awdataengineaggregator.h index 1f030b2..229fce1 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.h +++ b/sources/awesome-widget/plugin/awdataengineaggregator.h @@ -38,6 +38,9 @@ public: // properties void setInterval(const int _interval); +signals: + void deviceAdded(const QString &source); + public slots: void dropSource(const QString source); void reconnectSources(); diff --git a/sources/awesome-widget/plugin/awesomewidget.cpp b/sources/awesome-widget/plugin/awesomewidget.cpp index f306bf2..6d6233b 100644 --- a/sources/awesome-widget/plugin/awesomewidget.cpp +++ b/sources/awesome-widget/plugin/awesomewidget.cpp @@ -21,6 +21,7 @@ #include "awactions.h" #include "awconfighelper.h" +#include "awdataengineaggregator.h" #include "awkeys.h" diff --git a/sources/awesome-widget/plugin/awkeycache.cpp b/sources/awesome-widget/plugin/awkeycache.cpp index 6d3e45a..4002f7d 100644 --- a/sources/awesome-widget/plugin/awkeycache.cpp +++ b/sources/awesome-widget/plugin/awkeycache.cpp @@ -26,10 +26,9 @@ #include "awdebug.h" -void AWKeyCache::addKeyToCache(const QString type, const QString key) +bool AWKeyCache::addKeyToCache(const QString type, const QString key) { - qCDebug(LOG_AW) << "Key type" << type; - qCDebug(LOG_AW) << "Key" << key; + qCDebug(LOG_AW) << "Key" << key << "with type" << type; QString fileName = QString("%1/awesomewidgets.ndx") .arg(QStandardPaths::writableLocation( @@ -70,7 +69,7 @@ void AWKeyCache::addKeyToCache(const QString type, const QString key) } } else { if (cachedValues.contains(key)) - return; + return false; qCInfo(LOG_AW) << "Found new key" << key << "for type" << type; cache.setValue( QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), key); @@ -78,6 +77,7 @@ void AWKeyCache::addKeyToCache(const QString type, const QString key) cache.endGroup(); cache.sync(); + return true; } diff --git a/sources/awesome-widget/plugin/awkeycache.h b/sources/awesome-widget/plugin/awkeycache.h index 040a43e..806e61d 100644 --- a/sources/awesome-widget/plugin/awkeycache.h +++ b/sources/awesome-widget/plugin/awkeycache.h @@ -25,7 +25,7 @@ namespace AWKeyCache { -void addKeyToCache(const QString type, const QString key = QString("")); +bool addKeyToCache(const QString type, const QString key = QString("")); QHash loadKeysFromCache(); }; diff --git a/sources/awesome-widget/plugin/awkeyoperations.cpp b/sources/awesome-widget/plugin/awkeyoperations.cpp index e1210da..135d6f2 100644 --- a/sources/awesome-widget/plugin/awkeyoperations.cpp +++ b/sources/awesome-widget/plugin/awkeyoperations.cpp @@ -54,28 +54,6 @@ AWKeyOperations::~AWKeyOperations() } -void AWKeyOperations::addDevice(const QString source) -{ - qCDebug(LOG_AW) << "Source" << source; - - QRegExp diskRegexp - = QRegExp(QString("disk/(?:md|sd|hd)[a-z|0-9]_.*/Rate/(?:rblk)")); - QRegExp mountRegexp = QRegExp(QString("partitions/.*/filllevel")); - - if (source.contains(diskRegexp)) { - QString device = source; - device.remove(QString("/Rate/rblk")); - addKeyToCache(QString("disk"), device); - } else if (source.contains(mountRegexp)) { - QString device = source; - device.remove(QString("partitions")).remove(QString("/filllevel")); - addKeyToCache(QString("mount"), device); - } else if (source.startsWith(QString("lmsensors"))) { - addKeyToCache(QString("temp"), source); - } -} - - QStringList AWKeyOperations::devices(const QString type) const { qCDebug(LOG_AW) << "Looking for type" << type; @@ -259,6 +237,8 @@ QStringList AWKeyOperations::dictKeys() const } +// this method is required to provide GraphicalItem functions (e.g. paint()) to +// parent classes GraphicalItem *AWKeyOperations::giByKey(const QString key) const { qCDebug(LOG_AW) << "Looking for item" << key; @@ -355,14 +335,36 @@ void AWKeyOperations::editItem(const QString type) } +void AWKeyOperations::addDevice(const QString &source) +{ + qCDebug(LOG_AW) << "Source" << source; + + QRegExp diskRegexp + = QRegExp(QString("disk/(?:md|sd|hd)[a-z|0-9]_.*/Rate/(?:rblk)")); + QRegExp mountRegexp = QRegExp(QString("partitions/.*/filllevel")); + + if (source.contains(diskRegexp)) { + QString device = source; + device.remove(QString("/Rate/rblk")); + addKeyToCache(QString("disk"), device); + } else if (source.contains(mountRegexp)) { + QString device = source; + device.remove(QString("partitions")).remove(QString("/filllevel")); + addKeyToCache(QString("mount"), device); + } else if (source.startsWith(QString("lmsensors"))) { + addKeyToCache(QString("temp"), source); + } +} + + void AWKeyOperations::addKeyToCache(const QString type, const QString key) { - qCDebug(LOG_AW) << "Key type" << type; - qCDebug(LOG_AW) << "Key" << key; + qCDebug(LOG_AW) << "Key" << key << "with type" << type; - AWKeyCache::addKeyToCache(type, key); - m_devices = AWKeyCache::loadKeysFromCache(); - reinitKeys(); + if (AWKeyCache::addKeyToCache(type, key)) { + m_devices = AWKeyCache::loadKeysFromCache(); + reinitKeys(); + } } @@ -391,17 +393,8 @@ void AWKeyOperations::reinitKeys() // init QStringList allKeys = dictKeys(); -#ifdef BUILD_TESTING - // not documented feature - place all available tags - m_pattern = m_pattern.replace(QString("$ALL"), [allKeys]() { - QStringList strings; - for (auto tag : allKeys) - strings.append(QString("%1: $%1").arg(tag)); - return strings.join(QString(" | ")); - }()); -#endif /* BUILD_TESTING */ - // apply aw_* functions + m_pattern = AWPatternFunctions::insertAllKeys(m_pattern, allKeys); m_pattern = AWPatternFunctions::insertKeyCount(m_pattern, allKeys); m_pattern = AWPatternFunctions::insertKeyNames(m_pattern, allKeys); m_pattern = AWPatternFunctions::insertKeys(m_pattern, allKeys); diff --git a/sources/awesome-widget/plugin/awkeyoperations.h b/sources/awesome-widget/plugin/awkeyoperations.h index 8510914..11c9161 100644 --- a/sources/awesome-widget/plugin/awkeyoperations.h +++ b/sources/awesome-widget/plugin/awkeyoperations.h @@ -45,7 +45,6 @@ class AWKeyOperations : public QObject public: explicit AWKeyOperations(QObject *parent = nullptr); virtual ~AWKeyOperations(); - void addDevice(const QString source); QStringList devices(const QString type) const; QHash devices() const; void updateCache(); @@ -62,6 +61,9 @@ public: signals: void updateKeys(const QStringList currentKeys); +public slots: + void addDevice(const QString &source); + private: // methods void addKeyToCache(const QString type, const QString key = QString("")); diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/plugin/awkeys.cpp index f329c71..23ccd90 100644 --- a/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp @@ -27,6 +27,7 @@ #include "awdebug.h" #include "awkeyoperations.h" #include "awkeysaggregator.h" +#include "awpatternfunctions.h" #include "graphicalitem.h" #include "version.h" @@ -79,9 +80,8 @@ void AWKeys::initDataAggregator(const QVariantMap tooltipParams) void AWKeys::initKeys(const QString currentPattern, const int interval, const int limit) { - qCDebug(LOG_AW) << "Pattern" << currentPattern; - qCDebug(LOG_AW) << "Interval" << interval; - qCDebug(LOG_AW) << "Queue limit" << limit; + qCDebug(LOG_AW) << "Pattern" << currentPattern << "with interval" + << interval << "and queue limit" << limit; // init keyOperator->setPattern(currentPattern); @@ -89,6 +89,9 @@ void AWKeys::initKeys(const QString currentPattern, const int interval, dataEngineAggregator = new AWDataEngineAggregator(this, interval); connect(this, SIGNAL(dropSourceFromDataengine(QString)), dataEngineAggregator, SLOT(dropSource(QString))); + // transfer signal from dataengine to update source list + connect(dataEngineAggregator, SIGNAL(deviceAdded(const QString &)), + keyOperator, SLOT(addDevice(const QString &))); } else dataEngineAggregator->setInterval(interval); m_threadPool->setMaxThreadCount(limit == 0 ? QThread::idealThreadCount() @@ -101,8 +104,7 @@ void AWKeys::initKeys(const QString currentPattern, const int interval, void AWKeys::setAggregatorProperty(const QString key, const QVariant value) { - qCDebug(LOG_AW) << "Key" << key; - qCDebug(LOG_AW) << "Value" << value; + qCDebug(LOG_AW) << "Key" << key << "with value" << value; aggregator->setProperty(key.toUtf8().constData(), value); } @@ -124,8 +126,8 @@ void AWKeys::updateCache() QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const { - qCDebug(LOG_AW) << "Should be sorted" << sorted; - qCDebug(LOG_AW) << "Filter" << regexp; + qCDebug(LOG_AW) << "Should be sorted" << sorted << "and filter applied" + << regexp; QStringList allKeys = keyOperator->dictKeys(); // sort if required @@ -149,7 +151,7 @@ QStringList AWKeys::getHddDevices() const QString AWKeys::infoByKey(QString key) const { - qCDebug(LOG_AW) << "Requested key" << key; + qCDebug(LOG_AW) << "Requested info for key" << key; return keyOperator->infoByKey(key); } @@ -158,7 +160,7 @@ QString AWKeys::infoByKey(QString key) const // HACK this method requires to define tag value from bar from UI interface QString AWKeys::valueByKey(QString key) const { - qCDebug(LOG_AW) << "Requested key" << key; + qCDebug(LOG_AW) << "Requested value for key" << key; return values.value(key.remove(QRegExp(QString("^bar[0-9]{1,}"))), QString("")); @@ -173,14 +175,6 @@ void AWKeys::editItem(const QString type) } -void AWKeys::addDevice(const QString source) -{ - qCDebug(LOG_AW) << "Source" << source; - - return keyOperator->addDevice(source); -} - - void AWKeys::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data) { @@ -201,58 +195,11 @@ void AWKeys::reinitKeys(const QStringList currentKeys) qCDebug(LOG_AW) << "Update found keys by using list" << currentKeys; // append lists - // bars - m_foundBars = [currentKeys](const QString pattern) { - QStringList selectedKeys; - for (auto key : currentKeys) - if ((key.startsWith(QString("bar"))) - && (pattern.contains(QString("$%1").arg(key)))) { - qCInfo(LOG_AW) << "Found bar" << key; - selectedKeys.append(key); - } - if (selectedKeys.isEmpty()) - qCWarning(LOG_AW) << "No bars found"; - return selectedKeys; - }(keyOperator->pattern()); - - // main key list - m_foundKeys = [currentKeys](const QString pattern) { - QStringList selectedKeys; - for (auto key : currentKeys) - if ((!key.startsWith(QString("bar"))) - && (pattern.contains(QString("$%1").arg(key)))) { - qCInfo(LOG_AW) << "Found key" << key; - selectedKeys.append(key); - } - if (selectedKeys.isEmpty()) - qCWarning(LOG_AW) << "No keys found"; - return selectedKeys; - }(keyOperator->pattern()); - - // lambdas - m_foundLambdas = [](const QString pattern) { - QStringList selectedKeys; - // substring inside ${{ }} (with brackets) which should not contain ${{ - QRegularExpression lambdaRegexp( - QString("\\$\\{\\{((?!\\$\\{\\{).)*?\\}\\}")); - lambdaRegexp.setPatternOptions( - QRegularExpression::DotMatchesEverythingOption); - - QRegularExpressionMatchIterator it = lambdaRegexp.globalMatch(pattern); - while (it.hasNext()) { - QRegularExpressionMatch match = it.next(); - QString lambda = match.captured(); - // drop brackets - lambda.remove(QRegExp(QString("^\\$\\{\\{"))); - lambda.remove(QRegExp(QString("\\}\\}$"))); - // append - qCInfo(LOG_AW) << "Found lambda" << lambda; - selectedKeys.append(lambda); - } - if (selectedKeys.isEmpty()) - qCWarning(LOG_AW) << "No lambdas found"; - return selectedKeys; - }(keyOperator->pattern()); + m_foundBars + = AWPatternFunctions::findBars(keyOperator->pattern(), currentKeys); + m_foundKeys + = AWPatternFunctions::findKeys(keyOperator->pattern(), currentKeys); + m_foundLambdas = AWPatternFunctions::findLambdas(keyOperator->pattern()); // set key data to aggregator aggregator->setDevices(keyOperator->devices()); @@ -354,7 +301,7 @@ void AWKeys::calculateValues() QString AWKeys::parsePattern(QString pattern) const { // screen sign - pattern.replace(QString("$$"), QString("$\\$\\")); + pattern.replace(QString("$$"), QString(0x1d)); // lambdas for (auto key : m_foundLambdas) @@ -385,7 +332,7 @@ QString AWKeys::parsePattern(QString pattern) const } // prepare strings - pattern.replace(QString("$\\$\\"), QString("$$")); + pattern.replace(QString(0x1d), QString("$")); if (m_wrapNewLines) pattern.replace(QString("\n"), QString("
")); @@ -395,8 +342,7 @@ QString AWKeys::parsePattern(QString pattern) const void AWKeys::setDataBySource(const QString &sourceName, const QVariantMap &data) { - qCDebug(LOG_AW) << "Source" << sourceName; - qCDebug(LOG_AW) << "Data" << data; + qCDebug(LOG_AW) << "Source" << sourceName << "with data" << data; // first list init QStringList tags = aggregator->keysFromSource(sourceName); @@ -404,21 +350,18 @@ void AWKeys::setDataBySource(const QString &sourceName, const QVariantMap &data) tags = aggregator->registerSource(sourceName, data[QString("units")].toString()); - // update data or drop source if there are no matches + // update data or drop source if there are no matches and exit if (tags.isEmpty()) { - qCDebug(LOG_AW) << "Source" << sourceName << "not found"; - emit(dropSourceFromDataengine(sourceName)); - } else { - m_mutex.lock(); - // HACK workaround for time values which are stored in the different - // path - QVariant value = sourceName == QString("Local") - ? data[QString("DateTime")] - : data[QString("value")]; - std::for_each(tags.cbegin(), tags.cend(), - [this, value](const QString tag) { - values[tag] = aggregator->formater(value, tag); - }); - m_mutex.unlock(); + qCInfo(LOG_AW) << "Source" << sourceName << "not found"; + return emit(dropSourceFromDataengine(sourceName)); } + + m_mutex.lock(); + // HACK workaround for time values which are stored in the different path + QVariant value = sourceName == QString("Local") ? data[QString("DateTime")] + : data[QString("value")]; + std::for_each(tags.cbegin(), tags.cend(), [this, value](const QString tag) { + values[tag] = aggregator->formater(value, tag); + }); + m_mutex.unlock(); } diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h index 36c99c2..c3c0ff9 100644 --- a/sources/awesome-widget/plugin/awkeys.h +++ b/sources/awesome-widget/plugin/awkeys.h @@ -58,7 +58,6 @@ public: Q_INVOKABLE void editItem(const QString type); public slots: - void addDevice(const QString source); void dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data); // dummy method required by DataEngine connections diff --git a/sources/awesome-widget/plugin/awkeysaggregator.cpp b/sources/awesome-widget/plugin/awkeysaggregator.cpp index c61db0c..f846b72 100644 --- a/sources/awesome-widget/plugin/awkeysaggregator.cpp +++ b/sources/awesome-widget/plugin/awkeysaggregator.cpp @@ -42,8 +42,7 @@ AWKeysAggregator::~AWKeysAggregator() QString AWKeysAggregator::formater(const QVariant &data, const QString &key) const { - qCDebug(LOG_AW) << "Data" << data; - qCDebug(LOG_AW) << "Key" << key; + qCDebug(LOG_AW) << "Data" << data << "for key" << key; QString output; QLocale loc = m_translate ? QLocale::system() : QLocale::c(); @@ -135,7 +134,7 @@ QString AWKeysAggregator::formater(const QVariant &data, return source; }(m_formater[key] == Uptime ? QString("$ddd$hhh$mmm") : m_customUptime, - data.toFloat()); + static_cast(data.toFloat())); break; case NoFormat: default: @@ -155,6 +154,15 @@ QStringList AWKeysAggregator::keysFromSource(const QString &source) const } +QStringList +AWKeysAggregator::requiredByKeysFromSource(const QString &source) const +{ + qCDebug(LOG_AW) << "Search for source" << source; + + return m_requiredByMap.values(source); +} + + void AWKeysAggregator::setAcOffline(const QString inactive) { qCDebug(LOG_AW) << "Inactive AC string" << inactive; @@ -216,8 +224,7 @@ void AWKeysAggregator::setTranslate(const bool translate) QStringList AWKeysAggregator::registerSource(const QString &source, const QString &units) { - qCDebug(LOG_AW) << "Source" << source; - qCDebug(LOG_AW) << "Units" << units; + qCDebug(LOG_AW) << "Source" << source << "with units" << units; // regular expressions QRegExp cpuRegExp = QRegExp(QString("cpu/cpu.*/TotalLoad")); @@ -331,6 +338,11 @@ QStringList AWKeysAggregator::registerSource(const QString &source, key = QString("hddfreegb%1").arg(index); m_map.insertMulti(source, key); m_formater[key] = MemGBFormat; + // fill required by list + m_requiredByMap.insertMulti(source, + QString("hddtotmb%1").arg(index)); + m_requiredByMap.insertMulti(source, + QString("hddtotgb%1").arg(index)); } } else if (source.contains(mountUsedRegExp)) { // used @@ -346,6 +358,11 @@ QStringList AWKeysAggregator::registerSource(const QString &source, key = QString("hddgb%1").arg(index); m_map.insertMulti(source, key); m_formater[key] = MemGBFormat; + // fill required by list + m_requiredByMap.insertMulti(source, + QString("hddtotmb%1").arg(index)); + m_requiredByMap.insertMulti(source, + QString("hddtotgb%1").arg(index)); } } else if (source.startsWith(QString("hdd/temperature"))) { // hdd temperature @@ -372,6 +389,8 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("memgb")); m_formater[QString("memgb")] = MemGBFormat; + // fill required by list + m_requiredByMap.insertMulti(source, QString("mem")); } else if (source == QString("mem/physical/free")) { // free memory // mb @@ -380,6 +399,10 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("memfreegb")); m_formater[QString("memfreegb")] = MemGBFormat; + // fill required by list + m_requiredByMap.insertMulti(source, QString("memtotmb")); + m_requiredByMap.insertMulti(source, QString("memtotgb")); + m_requiredByMap.insertMulti(source, QString("mem")); } else if (source == QString("mem/physical/used")) { // used memory // mb @@ -388,10 +411,21 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("memusedgb")); m_formater[QString("memusedgb")] = MemGBFormat; + // fill required by list + m_requiredByMap.insertMulti(source, QString("memtotmb")); + m_requiredByMap.insertMulti(source, QString("memtotgb")); + m_requiredByMap.insertMulti(source, QString("mem")); } else if (source == QString("network/current/name")) { // network device m_map[source] = QString("netdev"); m_formater[QString("netdev")] = NoFormat; + // fill required by list + m_requiredByMap.insertMulti(source, QString("down")); + m_requiredByMap.insertMulti(source, QString("downkb")); + m_requiredByMap.insertMulti(source, QString("downunits")); + m_requiredByMap.insertMulti(source, QString("up")); + m_requiredByMap.insertMulti(source, QString("upkb")); + m_requiredByMap.insertMulti(source, QString("upunits")); } else if (source.contains(netRegExp)) { // network speed QString type = source.contains(QString("receiver")) ? QString("down") @@ -412,6 +446,13 @@ QStringList AWKeysAggregator::registerSource(const QString &source, m_map.insertMulti(source, key); m_formater[key] = NetSmartUnits; } + // fill required by list + m_requiredByMap.insertMulti(source, QString("%1").arg(type)); + m_requiredByMap.insertMulti(source, QString("%1kb").arg(type)); + m_requiredByMap.insertMulti(source, QString("%1units").arg(type)); + m_requiredByMap.insertMulti(source, QString("%1").arg(type)); + m_requiredByMap.insertMulti(source, QString("%1kb").arg(type)); + m_requiredByMap.insertMulti(source, QString("%1units").arg(type)); } else if (source.startsWith(QString("upgrade"))) { // package manager QString key = source; @@ -450,6 +491,10 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("swapfreegb")); m_formater[QString("swapfreegb")] = MemGBFormat; + // fill required by list + m_requiredByMap.insertMulti(source, QString("swaptotmb")); + m_requiredByMap.insertMulti(source, QString("swaptotgb")); + m_requiredByMap.insertMulti(source, QString("swap")); } else if (source == QString("mem/swap/used")) { // used swap // mb @@ -458,6 +503,10 @@ QStringList AWKeysAggregator::registerSource(const QString &source, // gb m_map.insertMulti(source, QString("swapgb")); m_formater[QString("swapgb")] = MemGBFormat; + // fill required by list + m_requiredByMap.insertMulti(source, QString("swaptotmb")); + m_requiredByMap.insertMulti(source, QString("swaptotgb")); + m_requiredByMap.insertMulti(source, QString("swap")); } else if (source.startsWith(QString("lmsensors/"))) { // temperature int index = m_devices[QString("temp")].indexOf(source); diff --git a/sources/awesome-widget/plugin/awkeysaggregator.h b/sources/awesome-widget/plugin/awkeysaggregator.h index f808d03..37bfc77 100644 --- a/sources/awesome-widget/plugin/awkeysaggregator.h +++ b/sources/awesome-widget/plugin/awkeysaggregator.h @@ -67,6 +67,7 @@ public: // get methods QString formater(const QVariant &data, const QString &key) const; QStringList keysFromSource(const QString &source) const; + QStringList requiredByKeysFromSource(const QString &source) const; // set methods void setAcOffline(const QString inactive); void setAcOnline(const QString active); @@ -90,6 +91,7 @@ private: QHash m_devices; QHash m_formater; QHash m_map; + QHash m_requiredByMap; QString m_tempUnits; bool m_translate = false; }; diff --git a/sources/awesome-widget/plugin/awpatternfunctions.cpp b/sources/awesome-widget/plugin/awpatternfunctions.cpp index 333700c..60e9b30 100644 --- a/sources/awesome-widget/plugin/awpatternfunctions.cpp +++ b/sources/awesome-widget/plugin/awpatternfunctions.cpp @@ -28,8 +28,15 @@ QVariantList AWPatternFunctions::findFunctionCalls(const QString function, { qCDebug(LOG_AW) << "Looking for function" << function << "in" << code; + // I suggest the following regex for the internal functions + // $aw_function_name{{function body}} + // * args should be always comma separated (e.g. commas are not supported + // in this field if they are not screened by $, i.e. '$,' + // * body depends on the function name, double brackets (i.e. {{ or }}) are + // not supported QRegularExpression regex( - QString("%1\\<(?.*?)\\>\\((?.*?)\\)").arg(function)); + QString("\\$%1\\<(?.*?)\\>\\{\\{(?.*?)\\}\\}") + .arg(function)); regex.setPatternOptions(QRegularExpression::DotMatchesEverythingOption); QVariantList foundFunctions; @@ -38,8 +45,20 @@ QVariantList AWPatternFunctions::findFunctionCalls(const QString function, QRegularExpressionMatch match = it.next(); QVariantHash metadata; - metadata[QString("args")] - = match.captured(QString("args")).split(QChar(',')); + // work with args + QString argsString = match.captured(QString("args")); + if (argsString.isEmpty()) { + metadata[QString("args")] = QStringList(); + } else { + // replace '$,' to 0x1d + argsString.replace(QString("$,"), QString(0x1d)); + QStringList args = argsString.split(QChar(',')); + std::for_each(args.begin(), args.end(), [](QString &arg) { + arg.replace(QString(0x1d), QString(",")); + }); + metadata[QString("args")] = args; + } + // other variables metadata[QString("body")] = match.captured(QString("body")); metadata[QString("what")] = match.captured(); foundFunctions.append(metadata); @@ -51,27 +70,22 @@ QVariantList AWPatternFunctions::findFunctionCalls(const QString function, QString AWPatternFunctions::expandTemplates(QString code) { - qCDebug(LOG_AW) << "Expand tempaltes in" << code; + qCDebug(LOG_AW) << "Expand templates in" << code; // match the following construction $template{{some code here}} QRegularExpression templatesRegexp( - QString("\\$template\\{\\{((?!\\$template\\{\\{).)*?\\}\\}")); + QString("\\$template\\{\\{(?.*?)\\}\\}")); templatesRegexp.setPatternOptions( QRegularExpression::DotMatchesEverythingOption); QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(code); while (it.hasNext()) { QRegularExpressionMatch match = it.next(); - QString fullTemplate = match.captured(); - - // drop additional markers - QString templ = fullTemplate; - templ.remove(QRegExp(QString("^\\$template\\{\\{"))); - templ.remove(QRegExp(QString("\\}\\}$"))); + QString body = match.captured(QString("body")); QJSEngine engine; - qCInfo(LOG_AW) << "Expression" << templ; - QJSValue result = engine.evaluate(templ); + qCInfo(LOG_AW) << "Expression" << body; + QJSValue result = engine.evaluate(body); QString templateResult = QString(""); if (result.isError()) { qCWarning(LOG_AW) << "Uncaught exception at line" @@ -82,7 +96,34 @@ QString AWPatternFunctions::expandTemplates(QString code) } // replace template - code.replace(fullTemplate, templateResult); + code.replace(match.captured(), templateResult); + } + + return code; +} + + +QString AWPatternFunctions::insertAllKeys(QString code, const QStringList keys) +{ + qCDebug(LOG_AW) << "Looking for keys in code" << code << "using list" + << keys; + + QVariantList found + = AWPatternFunctions::findFunctionCalls(QString("aw_all"), code); + for (auto function : found) { + QVariantHash metadata = function.toHash(); + QString separator + = metadata[QString("args")].toStringList().isEmpty() + ? QString(",") + : metadata[QString("args")].toStringList().at(0); + QStringList required + = keys.filter(QRegExp(metadata[QString("body")].toString())); + std::for_each(required.begin(), required.end(), [](QString &value) { + value = QString("%1: $%1").arg(value); + }); + + code.replace(metadata[QString("what")].toString(), + required.join(separator)); } return code; @@ -111,7 +152,7 @@ QString AWPatternFunctions::insertKeyCount(QString code, const QStringList keys) QString AWPatternFunctions::insertKeyNames(QString code, const QStringList keys) { - qCDebug(LOG_AW) << "Looking for keys in code" << code << "using list" + qCDebug(LOG_AW) << "Looking for key names in code" << code << "using list" << keys; QVariantList found @@ -158,3 +199,69 @@ QString AWPatternFunctions::insertKeys(QString code, const QStringList keys) return code; } + + +QStringList AWPatternFunctions::findBars(const QString code, + const QStringList keys) +{ + qCDebug(LOG_AW) << "Looking for bars in code" << code << "using list" + << keys; + + QStringList selectedKeys; + for (auto key : keys) + if ((key.startsWith(QString("bar"))) + && (code.contains(QString("$%1").arg(key)))) { + qCInfo(LOG_AW) << "Found bar" << key; + selectedKeys.append(key); + } + if (selectedKeys.isEmpty()) + qCWarning(LOG_AW) << "No bars found"; + + return selectedKeys; +} + + +QStringList AWPatternFunctions::findKeys(const QString code, + const QStringList keys) +{ + qCDebug(LOG_AW) << "Looking for keys in code" << code << "using list" + << keys; + + QStringList selectedKeys; + for (auto key : keys) + if ((!key.startsWith(QString("bar"))) + && (code.contains(QString("$%1").arg(key)))) { + qCInfo(LOG_AW) << "Found key" << key; + selectedKeys.append(key); + } + if (selectedKeys.isEmpty()) + qCWarning(LOG_AW) << "No keys found"; + + return selectedKeys; +} + + +QStringList AWPatternFunctions::findLambdas(const QString code) +{ + qCDebug(LOG_AW) << "Looking for lambdas in code" << code; + + QStringList selectedKeys; + // match the following construction ${{some code here}} + QRegularExpression lambdaRegexp(QString("\\$\\{\\{(?.*?)\\}\\}")); + lambdaRegexp.setPatternOptions( + QRegularExpression::DotMatchesEverythingOption); + + QRegularExpressionMatchIterator it = lambdaRegexp.globalMatch(code); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + QString lambda = match.captured(QString("body")); + + // append + qCInfo(LOG_AW) << "Found lambda" << lambda; + selectedKeys.append(lambda); + } + if (selectedKeys.isEmpty()) + qCWarning(LOG_AW) << "No lambdas found"; + + return selectedKeys; +} diff --git a/sources/awesome-widget/plugin/awpatternfunctions.h b/sources/awesome-widget/plugin/awpatternfunctions.h index c53d77a..d5d362f 100644 --- a/sources/awesome-widget/plugin/awpatternfunctions.h +++ b/sources/awesome-widget/plugin/awpatternfunctions.h @@ -25,11 +25,17 @@ namespace AWPatternFunctions { +// insert methods QString expandTemplates(QString code); QVariantList findFunctionCalls(const QString function, const QString code); +QString insertAllKeys(QString code, const QStringList keys); QString insertKeyCount(QString code, const QStringList keys); QString insertKeyNames(QString code, const QStringList keys); QString insertKeys(QString code, const QStringList keys); +// find methods +QStringList findBars(const QString code, const QStringList keys); +QStringList findKeys(const QString code, const QStringList keys); +QStringList findLambdas(const QString code); }; diff --git a/sources/awesomewidgets/abstractextitem.cpp b/sources/awesomewidgets/abstractextitem.cpp index 6986bfe..6691f10 100644 --- a/sources/awesomewidgets/abstractextitem.cpp +++ b/sources/awesomewidgets/abstractextitem.cpp @@ -33,8 +33,9 @@ AbstractExtItem::AbstractExtItem(QWidget *parent, const QString desktopName, , m_dirs(directories) { qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; - qCDebug(LOG_LIB) << "Desktop name" << desktopName; - qCDebug(LOG_LIB) << "Directories" << directories; + + qCDebug(LOG_LIB) << "Desktop name" << desktopName << "directories" + << directories; m_name = m_fileName; } diff --git a/sources/awesomewidgets/abstractextitemaggregator.cpp b/sources/awesomewidgets/abstractextitemaggregator.cpp index a9159e9..69113c7 100644 --- a/sources/awesomewidgets/abstractextitemaggregator.cpp +++ b/sources/awesomewidgets/abstractextitemaggregator.cpp @@ -91,10 +91,8 @@ void AbstractExtItemAggregator::setConfigArgs(const QVariant _configArgs) } -void AbstractExtItemAggregator::editItemActivated(QListWidgetItem *item) +void AbstractExtItemAggregator::editItemActivated(QListWidgetItem *) { - Q_UNUSED(item) - return editItem(); } diff --git a/sources/awesomewidgets/abstractextitemaggregator.h b/sources/awesomewidgets/abstractextitemaggregator.h index c10b202..54724a2 100644 --- a/sources/awesomewidgets/abstractextitemaggregator.h +++ b/sources/awesomewidgets/abstractextitemaggregator.h @@ -48,7 +48,7 @@ public: void setConfigArgs(const QVariant _configArgs); private slots: - void editItemActivated(QListWidgetItem *item); + void editItemActivated(QListWidgetItem *); void editItemButtonPressed(QAbstractButton *button); private: diff --git a/sources/awesomewidgets/extitemaggregator.h b/sources/awesomewidgets/extitemaggregator.h index ecb4f1d..5e0b9ea 100644 --- a/sources/awesomewidgets/extitemaggregator.h +++ b/sources/awesomewidgets/extitemaggregator.h @@ -37,8 +37,9 @@ public: { qSetMessagePattern(LOG_FORMAT); qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; - foreach (const QString metadata, getBuildData()) + for (auto metadata : getBuildData()) qCDebug(LOG_LIB) << metadata; + qCDebug(LOG_LIB) << "Type" << type; initItems(); @@ -66,7 +67,7 @@ public: qCDebug(LOG_LIB) << "Tag" << _tag; T *found = nullptr; - foreach (T *item, m_items) { + for (auto item : m_items) { if (item->tag() != _tag) continue; found = item; @@ -83,7 +84,7 @@ public: qCDebug(LOG_LIB) << "Number" << _number; T *found = nullptr; - foreach (T *item, m_items) { + for (auto item : m_items) { if (item->number() != _number) continue; found = item; @@ -102,7 +103,7 @@ public: return nullptr; T *found = nullptr; - foreach (T *item, m_items) { + for (auto item : m_items) { if (item->fileName() != widgetItem->text()) continue; found = item; @@ -120,7 +121,7 @@ public: int uniqNumber() const { QList tagList; - foreach (T *item, m_items) + for (auto item : m_items) tagList.append(item->number()); int number = 0; while (tagList.contains(number)) @@ -152,9 +153,9 @@ private: QStandardPaths::LocateDirectory); QStringList names; QList items; - foreach (QString dir, dirs) { + for (auto dir : dirs) { QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name); - foreach (QString file, files) { + for (auto file : files) { if ((!file.endsWith(QString(".desktop"))) || (names.contains(file))) continue; @@ -177,7 +178,7 @@ private: m_activeItems.clear(); m_items = getItems(); - foreach (T *item, m_items) { + for (auto item : m_items) { if (!item->isActive()) continue; m_activeItems.append(item); @@ -187,7 +188,7 @@ private: void repaint() { widgetDialog->clear(); - foreach (T *_item, m_items) { + for (auto _item : m_items) { QListWidgetItem *item = new QListWidgetItem(_item->fileName(), widgetDialog); QStringList tooltip; diff --git a/sources/awesomewidgets/extquotes.cpp b/sources/awesomewidgets/extquotes.cpp index 5a7f326..49e9725 100644 --- a/sources/awesomewidgets/extquotes.cpp +++ b/sources/awesomewidgets/extquotes.cpp @@ -150,7 +150,7 @@ QVariantHash ExtQuotes::run() qCInfo(LOG_LIB) << "Send request"; isRunning = true; QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url()))); - new QReplyTimeout(reply, 1000); + new QReplyTimeout(reply, REQUEST_TIMEOUT); } // update value @@ -208,8 +208,8 @@ void ExtQuotes::writeConfiguration() const void ExtQuotes::quotesReplyReceived(QNetworkReply *reply) { - qCDebug(LOG_LIB) << "Return code" << reply->error(); - qCDebug(LOG_LIB) << "Reply error message" << reply->errorString(); + qCDebug(LOG_LIB) << "Return code" << reply->error() << "with message" + << reply->errorString(); isRunning = false; QJsonParseError error; diff --git a/sources/awesomewidgets/extscript.cpp b/sources/awesomewidgets/extscript.cpp index a016fda..6c114a0 100644 --- a/sources/awesomewidgets/extscript.cpp +++ b/sources/awesomewidgets/extscript.cpp @@ -64,8 +64,7 @@ ExtScript::~ExtScript() ExtScript *ExtScript::copy(const QString _fileName, const int _number) { - qCDebug(LOG_LIB) << "File" << _fileName; - qCDebug(LOG_LIB) << "Number" << _number; + qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; ExtScript *item = new ExtScript(static_cast(parent()), _fileName, directories()); @@ -206,8 +205,7 @@ QString ExtScript::applyFilters(QString _value) const void ExtScript::updateFilter(const QString _filter, const bool _add) { - qCDebug(LOG_LIB) << "Filter" << _filter; - qCDebug(LOG_LIB) << "Should be added" << _add; + qCDebug(LOG_LIB) << "Should be added filters" << _add << "from" << _filter; if (_add) { if (m_filters.contains(_filter)) diff --git a/sources/awesomewidgets/extupgrade.cpp b/sources/awesomewidgets/extupgrade.cpp index 06b9515..2fe6a4f 100644 --- a/sources/awesomewidgets/extupgrade.cpp +++ b/sources/awesomewidgets/extupgrade.cpp @@ -60,8 +60,7 @@ ExtUpgrade::~ExtUpgrade() ExtUpgrade *ExtUpgrade::copy(const QString _fileName, const int _number) { - qCDebug(LOG_LIB) << "File" << _fileName; - qCDebug(LOG_LIB) << "Number" << _number; + qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; ExtUpgrade *item = new ExtUpgrade(static_cast(parent()), _fileName, directories()); diff --git a/sources/awesomewidgets/extweather.cpp b/sources/awesomewidgets/extweather.cpp index d6342fa..8e865d5 100644 --- a/sources/awesomewidgets/extweather.cpp +++ b/sources/awesomewidgets/extweather.cpp @@ -74,8 +74,7 @@ ExtWeather::~ExtWeather() ExtWeather *ExtWeather::copy(const QString _fileName, const int _number) { - qCDebug(LOG_LIB) << "File" << _fileName; - qCDebug(LOG_LIB) << "Number" << _number; + qCDebug(LOG_LIB) << "File" << _fileName << "number" << _number; ExtWeather *item = new ExtWeather(static_cast(parent()), _fileName, directories()); @@ -236,7 +235,7 @@ QVariantHash ExtWeather::run() qCInfo(LOG_LIB) << "Send request"; isRunning = true; QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url()))); - new QReplyTimeout(reply, 5000); + new QReplyTimeout(reply, REQUEST_TIMEOUT); } // update value @@ -304,7 +303,7 @@ void ExtWeather::writeConfiguration() const void ExtWeather::weatherReplyReceived(QNetworkReply *reply) { - qCDebug(LOG_LIB) << "Return code" << reply->error(); + qCDebug(LOG_LIB) << "Return code" << reply->error() << "with messa"; qCDebug(LOG_LIB) << "Reply error message" << reply->errorString(); isRunning = false; diff --git a/sources/awesomewidgets/graphicalitem.cpp b/sources/awesomewidgets/graphicalitem.cpp index 1f4cabf..843da2b 100644 --- a/sources/awesomewidgets/graphicalitem.cpp +++ b/sources/awesomewidgets/graphicalitem.cpp @@ -65,8 +65,7 @@ GraphicalItem::~GraphicalItem() GraphicalItem *GraphicalItem::copy(const QString _fileName, const int _number) { - qCDebug(LOG_LIB) << "File" << _fileName; - qCDebug(LOG_LIB) << "Number" << _number; + qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; GraphicalItem *item = new GraphicalItem(static_cast(parent()), _fileName, directories()); diff --git a/sources/desktop-panel/plugin/dpadds.cpp b/sources/desktop-panel/plugin/dpadds.cpp index bf852fb..2c48887 100644 --- a/sources/desktop-panel/plugin/dpadds.cpp +++ b/sources/desktop-panel/plugin/dpadds.cpp @@ -191,8 +191,7 @@ QString DPAdds::toolTipImage(const int desktop) const QString DPAdds::parsePattern(const QString pattern, const int desktop) const { - qCDebug(LOG_DP) << "Pattern" << pattern; - qCDebug(LOG_DP) << "Desktop number" << desktop; + qCDebug(LOG_DP) << "Pattern" << pattern << "for desktop" << desktop; QString parsed = pattern; parsed.replace(QString("$$"), QString("$\\$\\")); @@ -224,8 +223,7 @@ void DPAdds::setToolTipData(const QVariantMap tooltipData) QString DPAdds::valueByKey(const QString key, int desktop) const { - qCDebug(LOG_DP) << "Requested key" << key; - qCDebug(LOG_DP) << "Desktop number" << desktop; + qCDebug(LOG_DP) << "Requested key" << key << "for desktop" << desktop; if (desktop == -1) desktop = currentDesktop(); @@ -336,8 +334,7 @@ QVariantMap DPAdds::getFont(const QVariantMap defaultFont) const // to avoid additional object definition this method is static void DPAdds::sendNotification(const QString eventId, const QString message) { - qCDebug(LOG_DP) << "Event" << eventId; - qCDebug(LOG_DP) << "Message" << message; + qCDebug(LOG_DP) << "Event" << eventId << "with message" << message; KNotification *notification = KNotification::event( eventId, QString("Desktop Panel ::: %1").arg(eventId), message); diff --git a/sources/extsysmon/sources/playersource.cpp b/sources/extsysmon/sources/playersource.cpp index f1f1c41..c580a2d 100644 --- a/sources/extsysmon/sources/playersource.cpp +++ b/sources/extsysmon/sources/playersource.cpp @@ -346,9 +346,8 @@ QVariantHash PlayerSource::getPlayerMprisInfo(const QString mpris) const QString PlayerSource::buildString(const QString current, const QString value, const int s) const { - qCDebug(LOG_ESM) << "Current value" << current; - qCDebug(LOG_ESM) << "New value" << value; - qCDebug(LOG_ESM) << "Strip after" << s; + qCDebug(LOG_ESM) << "Current value" << current << "received" << value + << "will be stripped after" << s; int index = value.indexOf(current); if ((current.isEmpty()) || ((index + s + 1) > value.count())) { @@ -361,8 +360,7 @@ QString PlayerSource::buildString(const QString current, const QString value, QString PlayerSource::stripString(const QString value, const int s) const { - qCDebug(LOG_ESM) << "New value" << value; - qCDebug(LOG_ESM) << "Strip after" << s; + qCDebug(LOG_ESM) << "New value" << value << "will be stripped after" << s; return value.count() > s ? QString("%1\u2026").arg(value.left(s - 1)) : value.leftJustified(s, QLatin1Char(' ')); diff --git a/sources/version.h.in b/sources/version.h.in index 10ab084..b9fdfb6 100644 --- a/sources/version.h.in +++ b/sources/version.h.in @@ -24,6 +24,8 @@ #define AWEUAPI 3 // extweather api version #define AWEWAPI 2 +// network requests timeout, ms +#define REQUEST_TIMEOUT 5000 // available time keys #define TIME_KEYS "dddd,ddd,dd,d,MMMM,MMM,MM,M,yyyy,yy,hh,h,HH,H,mm,m,ss,s,t,ap,a,AP,A" #cmakedefine BUILD_FUTURE From 5ddf720a57fea47b1bdea8ef3d478b4454c796cd Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Sun, 31 Jan 2016 23:34:09 +0600 Subject: [PATCH 17/17] Revert "Master update"