Compare commits

..

57 Commits

Author SHA1 Message Date
d216ee1f79 fix invalid copied file 2016-04-06 01:40:13 +03:00
81ceaa8160 backport zh translation from master for merge 2016-04-06 01:35:07 +03:00
d4c7095d61 release 3.1.0 2016-04-06 01:25:31 +03:00
d9409c25f4 Preparing to prerelease
* apply clangformat
* fix yahoo weather api
2016-04-05 00:24:37 +03:00
7d1e035240 replace own workaround for version checking to QVersionNumber
QVersionNumber has been introduced since Qt-5.6 and it is better to use
it instead of custom version checking
2016-04-04 10:47:12 +03:00
fa795121aa drop task from source tree
Latest commits have removed links to task
2016-03-29 17:01:57 +03:00
b9fda3e1cd drop task library from build, cosmetic changes 2016-03-27 15:39:37 +03:00
1187c43e57 Move to QProcess from Task in GPU and player sources 2016-03-26 12:17:24 +03:00
4a6aaa95b0 Move hddtemp engine to qprocess
in lieu of #83
2016-03-25 18:19:26 +03:00
7e42c8cb49 Improve performance with image generation
To avoid pen creation on each update class properties is used.
2016-03-24 15:53:07 +03:00
88f0ebfe96 Revert bd65e44002 2016-03-23 16:27:05 +03:00
86458b8238 push Polish translation (thanks to Mariusz Kocoń) 2016-03-22 14:37:40 +03:00
bd65e44002 add delayed initialization
This workaround probably will fix issue with the recent plasma when
plasmashell fails to load sometimes.
2016-03-21 12:10:27 +03:00
fe7f82373b Start work on adding ability to use custom image for bars instead of
color
2016-03-19 17:50:51 +03:00
3a6033e676 Cosmetic changes
* fix invalid graph painting - for some reasons graphs are not normed as
  expected.
* fix cppcheck warnings related to no default values
2016-03-18 16:23:53 +03:00
453d4d5149 Small changes
* move logging ini file from dataengine to library
* improve dataengine desktop file
* fix configuration warnings with the newest plasma
2016-03-17 19:19:10 +03:00
07c753b703 add default config to directory
(it mostly requires by current build system)
2016-03-16 18:23:31 +03:00
52b1255d3f move graph data store to graphical item helper
It is required by custom graphs. X-AW-Count parameter (which is only
    recognized by Graph item type) has been introduced
2016-03-14 12:04:38 +03:00
7f665fef77 update to the newest Qt
First it crashes with the newest Qt due to nan values in graphs.
Second it produces several warnings
2016-03-13 22:20:22 +03:00
7ff1515c94 Merge branch 'development' of github.com:arcan1s/awesome-widgets into development 2016-03-11 20:51:19 +03:00
162708295d improve configuration import and export
Special directory for configuration store has been created. In
particular it will allow to realize #72
2016-03-11 20:48:36 +03:00
4a59acae09 change urls in forgotten files 2016-03-08 17:29:54 +03:00
be9203e816 update project url
For some time my site has been moved from arcanis.name to arcanis.me.
Also https protocol forced.
2016-03-05 19:39:26 +03:00
5af4b0c40c fix bug introduced by lazy subscription
Sources in custom dataengine updated only if user subscribe on specified
source. I've implemented drop returing value so if no requested value
found it will return force update event.
2016-03-04 15:06:12 +03:00
071d7fdb78 bump default gi configuration
Bump API version and add new parameters. Also:

1. Fix function combobox in configuration UI.
2. Drop datasource from time engine as well.
3. Small edit abstractdesources class
2016-03-03 19:57:31 +03:00
89d573450a fix #81
As it was found the issue has been caused by parallel access to
QGraphicsScene so it has been cleared before convertion to pixmap. It
has been resolved by deletion concurrent updates in this place (it makes
sense anyway).
2016-03-01 00:58:37 +03:00
50f3ef5bba move gihelper to own class from namespace
This action will allow to store data in the helper class. Also
notification for high memory usage has been changed from 90 to 80.
2016-02-26 20:04:27 +03:00
8cae273ffb split gi to helper and core
Also internal data format has been changed
2016-02-24 20:40:55 +03:00
15d4d7667d change formating
* add *h.in to clang-format configuration
* move static keys definition to header. Probably it may break something
  with key parsing
2016-02-17 09:31:11 +03:00
95a5eec108 Cosmetic commit
* apply clangformat settings
* update translations
* rename settings
2016-02-16 08:46:43 +03:00
362f1fd87e prepare to move to generic bars
This commits series introduces bars which may be calculated from any
custom formula. For a start I've renamed $bar*tag to $bar* and add new
configuration parameters to graphical items.
2016-02-12 09:23:30 +03:00
5c474e822b one more optimization
The previous versions stored values as string, so any (even if they are
not used) values being converted into string, and then (if required)
being converted back to float/int/etc. I've changed the mechanism, so
they are stored as QVariant (native value).

Please note that it is possible that this rewrite may cause crash in
some cases (if I've missed smth).
2016-02-10 10:51:01 +03:00
d856fa8e97 possible fix #75
I've added 'optimize' option (by default true). If it options is set
then sources will be checked if they are required (with dependencies if
any). And if they are not required they will be dropped by using common
mechanism.

Please note that if this option enabled the following features (at the
    moment) will be unavailable:

* key request from context menu (from configuration interface it still works)
* notifications event if sources on which notification is not connected

I suppose this commit will increase performance in about 4-5 times.
2016-02-05 11:08:09 +03:00
54e1545bb1 create update helper class
Move old chechUpdates() method to this class. Create ability to show
ChangeLog after updates (by using global config with version). Changelog
(only for the latest version) will be written to version.h during cmake
run.
2016-02-04 00:02:49 +07:00
384097625c Merge pull request #77 from arcan1s/revert-76-master
Revert "Master update"
2016-01-31 23:35:28 +06:00
5ddf720a57 Revert "Master update" 2016-01-31 23:34:09 +06:00
1610c190b4 Merge pull request #76 from arcan1s/master
Master update
2016-01-31 23:32:29 +06:00
beb2682b04 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
2016-02-01 00:25:28 +07:00
c1cf8185a3 ...and another edit travis.yml 2016-01-31 00:34:31 +07:00
fb7fc4a104 one more edit travis.yml 2016-01-31 00:28:39 +07:00
210415cdff more correct work with kubuntu ppa, less output messages 2016-01-31 00:19:04 +07:00
bfac30c304 add dpkg options to travis.yml 2016-01-31 00:07:40 +07:00
966c6059a0 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<some args here if any>{{function body if any}}

* rewrite travis.yml
2016-01-31 00:00:12 +07:00
1c78e0d779 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
2016-01-30 00:07:47 +07:00
fba58c27e8 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
2016-01-29 01:31:00 +07:00
4b679ff570 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
2016-01-28 12:44:45 +03:00
d8d2311621 edit dpkg options 2015-11-03 04:51:19 +03:00
809936a563 add --yes 2015-11-03 04:41:56 +03:00
2c1aa1a4c9 add dist upgrade before 2015-11-03 04:40:00 +03:00
02305b93d9 skip asking 2015-11-02 10:10:11 +03:00
aece0e2eff rename ppa accoring to pkgs.org search 2015-11-02 10:06:20 +03:00
c24e41d557 edit adding repo 2015-11-02 09:56:48 +03:00
5be3f9246b try use travis ci again 2015-11-02 09:53:49 +03:00
81d99e66b9 Merge branch 'development' 2015-10-26 18:44:20 +03:00
940ef13ffa add patches to tarball 2015-10-23 05:59:51 +03:00
5ee1cec909 authors update 2015-10-23 00:55:16 +03:00
83ec82debd Merge pull request #70 from arcan1s/development
Master update
2015-10-23 00:27:16 +03:00
176 changed files with 4847 additions and 2254 deletions

1
.gitignore vendored
View File

@ -43,6 +43,7 @@ build
*pkg.tar.[gx]z *pkg.tar.[gx]z
src src
pkg pkg
*.deb
# clion settings # clion settings
.idea .idea

6
.gitmodules vendored
View File

@ -1,9 +1,3 @@
[submodule "sources/3rdparty/task"]
path = sources/3rdparty/task
url = https://github.com/arcan1s/qtadds-taskadds-qprocess.git
[submodule "sources/3rdparty/tasks"]
path = sources/3rdparty/tasks
url = https://github.com/mhogomchungu/tasks.git
[submodule "sources/3rdparty/fontdialog"] [submodule "sources/3rdparty/fontdialog"]
path = sources/3rdparty/fontdialog path = sources/3rdparty/fontdialog
url = https://github.com/arcan1s/qtadds-fontdialog.git url = https://github.com/arcan1s/qtadds-fontdialog.git

View File

@ -1,7 +1,16 @@
install: sudo: required
- sudo apt-get update -qq dist: trusty
- 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 language: cpp
os:
- linux
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 -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 - rm -rf build
- mkdir build - mkdir build

View File

@ -1,6 +1,9 @@
Current developers: Current developers:
Evgeniy Alekseev aka arcanis <esalexeev (at) gmail (dot) com> Evgeniy Alekseev aka arcanis <esalexeev (at) gmail (dot) com>
Packagers:
Konstantin Voinov (openSuSe)
Translators: Translators:
@Mermouy (French translation) @Mermouy (French translation)
Ernesto Avilés Vzqz (Spanish translation) Ernesto Avilés Vzqz (Spanish translation)

View File

@ -1,3 +1,24 @@
Ver.3.1.0:
+ implement templates support (#71)
+ implement special functions (#71)
+ special directory for configs (#72)
+ custom bar images (#80)
+ custom bar values (#80)
+ show changelog after updates
+ add Polish translation (thanks to Mariusz Kocoń)
+ use Qt-5.6 features
- fix invalid tooltip resize in desktop panel (#74)
- fix graphical items blinking (#81)
- drop tasks and move to native QProcess to avoid crash (#83)
- the newest Qt (5.6) fixes
- the newest Plasma fixes
* move from OWM to Yahoo! Weather (#73)
* improve performance by using optimized subscriptions (#75)
* improve performance by storing QVariant instead of frequent casting (#75)
* change bar names semantic to the simplest one (#80, breaking changes)
* high memory usage notifications have been changed from 90 to 80 perc
* a large part of refactoring
Ver.3.0.1: Ver.3.0.1:
+ add patches for old Qt versions + add patches for old Qt versions
- drop `nullptr` checking - drop `nullptr` checking

View File

@ -1,3 +1,24 @@
Вер.3.1.0:
+ добавлена поддержка шаблонов (#71)
+ добавлена поддержка специальных функций (#71)
+ добавлена отдельная директория для настроек (#72)
+ произвольные картинки для баров (#80)
+ произвольные значения для баров (#80)
+ показывать ченджлог после обновления
+ добавлен польский перевод (спасибо Mariusz Kocoń)
+ использование Qt-5.6 плюшек
- исправлено неправильное обновление размера тултипа в desktop panel (#74)
- исправлено мигание баров (#81)
- убрано использование tasks в пользу QProcess, чтобы избежать падения (#83)
- исправления, вызванные новым Qt (5.6)
- исправления, вызванные новой Plasma
* вместо OWM теперь используется Yahoo! Weather (#73)
* улучшена производительность путем оптимизированной подписки (#75)
* улучшена производительность путем хранения QVariant вместо частых кастов (#75)
* изменен принцип наименования баров (#80, ломает совместимость)
* уведомление о большом использовании памяти изменено с 90 на 80 процентов
* много рефакторинга
Вер.3.0.1: Вер.3.0.1:
+ добавлены патчи для старых версий Qt + добавлены патчи для старых версий Qt
- убрана проверка на nullptr - убрана проверка на nullptr

View File

@ -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. * `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**. * Current project standard is **C++11**.
* Do not use C-like code: * 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. `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 * C-like casts, use `const_cast`, `static_cast`, `dymanic_Cast` instead. Using
of `reinterpret_cast` is not recommended. It is highly recommended to use 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.: `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. * Create one file (source and header) per class.
* `else if` construction is allowed and recommended. * `else if` construction is allowed and recommended.
* 'true ? foo : bar' construction is allowed and recommended for one-line assignment. * '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. initialization. Exception: if object is deleted into class destructor.
Comments Comments
@ -146,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 Available categories should be declared in `awdebug.*` files. The following log
levels should be used: 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. * **info** (`qCInfo()`) - additional information inside methods.
* **warning** (`qCWarning()`) - not critical information, which may be caused by * **warning** (`qCWarning()`) - not critical information, which may be caused by
mistakes in configuration for example. mistakes in configuration for example.
* **error** (`qCError()`) - an error which has been captured in runtime. All errors * **critical** (`qCCritical()`) - a critical error. After this error program may
should have own callback methods.
* **critical** (`qCCritical()`) - a critical error. After this error program will
be terminated. be terminated.
The empty log string (e.g. `qCDebug();`) is not allowed because the method names The empty log string (e.g. `qCDebug();`) is not allowed because the method names

View File

@ -66,9 +66,9 @@ See [milestones](https://github.com/arcan1s/awesome-widgets/milestones) for more
Links Links
----- -----
* [Homepage](http://arcanis.name/projects/awesome-widgets/) * [Homepage](https://arcanis.me/projects/awesome-widgets/)
* [Migration to 2.*](http://arcanis.name/en/2014/09/04/migration-to-v2/) * [Migration to 2.*](https://arcanis.me/en/2014/09/04/migration-to-v2/)
* [Scripts and bars](http://arcanis.name/en/2014/12/19/aw-v21-bells-and-whistles/) * [Scripts and bars](https://arcanis.me/en/2014/12/19/aw-v21-bells-and-whistles/)
* Plasmoid on [kde-look](http://kde-look.org/content/show.php/Awesome+Widgets?content=157124) * Plasmoid on [kde-look](http://kde-look.org/content/show.php/Awesome+Widgets?content=157124)
* DataEngine on [kde-look](http://kde-look.org/content/show.php/Extended+Systemmonitor+DataEngine?content=158773) * DataEngine on [kde-look](http://kde-look.org/content/show.php/Extended+Systemmonitor+DataEngine?content=158773)
* Archlinux [AUR](https://aur.archlinux.org/packages/plasma5-applet-awesome-widgets/) package * Archlinux [AUR](https://aur.archlinux.org/packages/plasma5-applet-awesome-widgets/) package

View File

@ -11,8 +11,8 @@ git submodule update --init --recursive
# build widget # build widget
ARCHIVE="awesome-widgets" ARCHIVE="awesome-widgets"
FILES="AUTHORS CHANGELOG CHANGELOG-RU COPYING" FILES="AUTHORS CHANGELOG CHANGELOG-RU COPYING packages patches"
IGNORELIST="build usr .kdev4 *.kdev4 .idea" IGNORELIST="build usr .kdev4 *.kdev4 .idea packages/*src.tar.xz"
# create archive # create archive
[[ -e ${ARCHIVE}-${VERSION}-src.tar.xz ]] && rm -f "${ARCHIVE}-${VERSION}-src.tar.xz" [[ -e ${ARCHIVE}-${VERSION}-src.tar.xz ]] && rm -f "${ARCHIVE}-${VERSION}-src.tar.xz"
[[ -d ${ARCHIVE} ]] && rm -rf "${ARCHIVE}" [[ -d ${ARCHIVE} ]] && rm -rf "${ARCHIVE}"

View File

@ -2,11 +2,11 @@
pkgname=plasma5-applet-awesome-widgets pkgname=plasma5-applet-awesome-widgets
_pkgname=awesome-widgets _pkgname=awesome-widgets
pkgver=3.0.1 pkgver=3.1.0
pkgrel=1 pkgrel=1
pkgdesc="Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor)" pkgdesc="Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor)"
arch=('i686' 'x86_64') arch=('i686' 'x86_64')
url="http://arcanis.name/projects/awesome-widgets" url="https://arcanis.me/projects/awesome-widgets"
license=('GPL3') license=('GPL3')
depends=('plasma-framework') depends=('plasma-framework')
optdepends=("catalyst: for GPU monitor" optdepends=("catalyst: for GPU monitor"
@ -17,7 +17,7 @@ optdepends=("catalyst: for GPU monitor"
makedepends=('cmake' 'extra-cmake-modules') makedepends=('cmake' 'extra-cmake-modules')
source=(https://github.com/arcan1s/awesome-widgets/releases/download/V.${pkgver}/${_pkgname}-${pkgver}-src.tar.xz) source=(https://github.com/arcan1s/awesome-widgets/releases/download/V.${pkgver}/${_pkgname}-${pkgver}-src.tar.xz)
install=${pkgname}.install install=${pkgname}.install
md5sums=('71f5b358d443075540377284ee868a93') md5sums=('08d1c0b3995ae6003a5b552a7ae7b93d')
backup=('etc/xdg/plasma-dataengine-extsysmon.conf') backup=('etc/xdg/plasma-dataengine-extsysmon.conf')
prepare() { prepare() {

View File

@ -6,7 +6,7 @@ pkgver=2.2.1.r15.g78931b3
pkgrel=1 pkgrel=1
pkgdesc="Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor). Git version" pkgdesc="Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor). Git version"
arch=('i686' 'x86_64') arch=('i686' 'x86_64')
url="http://arcanis.name/projects/awesome-widgets" url="https://arcanis.me/projects/awesome-widgets"
license=('GPL3') license=('GPL3')
depends=('plasma-framework') depends=('plasma-framework')
optdepends=("amarok: for music player monitor" optdepends=("amarok: for music player monitor"

7
patches/PATCHING.md Normal file
View File

@ -0,0 +1,7 @@
* Using git tree from root git directory:
git apply path/to/patch
* Using release tarball from root directory:
patch -p2 -i path/to/patch

View File

@ -24,24 +24,12 @@ diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/p
index e5b9861..eb73073 100644 index e5b9861..eb73073 100644
--- a/sources/awesome-widget/plugin/awkeys.cpp --- a/sources/awesome-widget/plugin/awkeys.cpp
+++ b/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp
@@ -439,7 +439,7 @@ void AWKeys::dataUpdated(const QString &sourceName, @@ -439,4 +439,4 @@ void AWKeys::dataUpdated(const QString &sourceName,
#ifdef BUILD_FUTURE
// run concurrent data update // run concurrent data update
- QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, sourceName, - QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, sourceName,
+ QtConcurrent::run(this, &AWKeys::setDataBySource, sourceName, + QtConcurrent::run(this, &AWKeys::setDataBySource, sourceName,
data); data);
#else /* BUILD_FUTURE */
return setDataBySource(sourceName, data);
@@ -564,7 +564,7 @@ void AWKeys::reinitKeys()
void AWKeys::updateTextData()
{
#ifdef BUILD_FUTURE
- QFuture<QString> text = QtConcurrent::run(m_threadPool, [this]() {
+ QFuture<QString> text = QtConcurrent::run([this]() {
calculateValues();
return parsePattern(m_pattern);
});
diff --git a/sources/libraries.cmake b/sources/libraries.cmake diff --git a/sources/libraries.cmake b/sources/libraries.cmake
index 33192f7..46e2b1e 100644 index 33192f7..46e2b1e 100644
--- a/sources/libraries.cmake --- a/sources/libraries.cmake

View File

@ -10,7 +10,7 @@ index 01bcd58..1ec7ba6 100644
import org.kde.plasma.private.awesomewidget 1.0 import org.kde.plasma.private.awesomewidget 1.0
@@ -372,31 +371,7 @@ Item { @@ -372,32 +371,7 @@ Item {
QtControls.Button { QtControls.Button {
width: parent.width * 3 / 5 width: parent.width * 3 / 5
text: i18n("Export configuration") text: i18n("Export configuration")
@ -21,6 +21,7 @@ index 01bcd58..1ec7ba6 100644
- id: saveConfigAs - id: saveConfigAs
- selectExisting: false - selectExisting: false
- title: i18n("Export") - title: i18n("Export")
- folder: awConfig.configurationDirectory()
- onAccepted: { - onAccepted: {
- var status = awConfig.exportConfiguration( - var status = awConfig.exportConfiguration(
- plasmoid.configuration, - plasmoid.configuration,
@ -43,7 +44,7 @@ index 01bcd58..1ec7ba6 100644
} }
} }
@@ -410,41 +385,9 @@ Item { @@ -410,42 +385,9 @@ Item {
QtControls.Button { QtControls.Button {
width: parent.width * 3 / 5 width: parent.width * 3 / 5
text: i18n("Import configuration") text: i18n("Import configuration")
@ -53,6 +54,7 @@ index 01bcd58..1ec7ba6 100644
- QtDialogs.FileDialog { - QtDialogs.FileDialog {
- id: openConfig - id: openConfig
- title: i18n("Import") - title: i18n("Import")
- folder: awConfig.configurationDirectory()
- onAccepted: importSelection.open() - onAccepted: importSelection.open()
- } - }
- -
@ -219,9 +221,9 @@ index 6263b30..5f61d2a 100644
// extensions // extensions
- if (importExtensions) { - if (importExtensions) {
+ if (selection[QString("extensions")]) { + if (selection[QString("extensions")]) {
foreach (QString item, m_dirs) { for (auto item : m_dirs) {
settings.beginGroup(item); settings.beginGroup(item);
foreach (QString it, settings.childGroups()) for (auto it : settings.childGroups())
@@ -121,7 +139,7 @@ QVariantMap AWConfigHelper::importConfiguration(const QString fileName, @@ -121,7 +139,7 @@ QVariantMap AWConfigHelper::importConfiguration(const QString fileName,
} }
@ -238,7 +240,7 @@ index 6263b30..5f61d2a 100644
- if (importPlasmoid) { - if (importPlasmoid) {
+ if (selection[QString("plasmoid")]) { + if (selection[QString("plasmoid")]) {
settings.beginGroup(QString("plasmoid")); settings.beginGroup(QString("plasmoid"));
foreach (QString key, settings.childKeys()) for (auto key : settings.childKeys())
configuration[key] = settings.value(key); configuration[key] = settings.value(key);
@@ -261,6 +279,50 @@ void AWConfigHelper::readFile(QSettings &settings, const QString key, @@ -261,6 +279,50 @@ void AWConfigHelper::readFile(QSettings &settings, const QString key,
} }
@ -295,9 +297,10 @@ diff --git a/sources/awesome-widget/plugin/awconfighelper.h b/sources/awesome-wi
index 912ac3d..dc51dfb 100644 index 912ac3d..dc51dfb 100644
--- a/sources/awesome-widget/plugin/awconfighelper.h --- a/sources/awesome-widget/plugin/awconfighelper.h
+++ b/sources/awesome-widget/plugin/awconfighelper.h +++ b/sources/awesome-widget/plugin/awconfighelper.h
@@ -33,12 +33,8 @@ public: @@ -33,13 +33,9 @@ public:
explicit AWConfigHelper(QObject *parent = nullptr); explicit AWConfigHelper(QObject *parent = nullptr);
virtual ~AWConfigHelper(); virtual ~AWConfigHelper();
Q_INVOKABLE QString configurationDirectory() const;
Q_INVOKABLE bool dropCache() const; Q_INVOKABLE bool dropCache() const;
- Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig, - Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig,
- const QString fileName) const; - const QString fileName) const;
@ -322,10 +325,11 @@ diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/p
index e5b9861..039d24e 100644 index e5b9861..039d24e 100644
--- a/sources/awesome-widget/plugin/awkeys.cpp --- a/sources/awesome-widget/plugin/awkeys.cpp
+++ b/sources/awesome-widget/plugin/awkeys.cpp +++ b/sources/awesome-widget/plugin/awkeys.cpp
@@ -324,6 +324,13 @@ QStringList AWKeys::getHddDevices() const @@ -324,6 +324,14 @@ QStringList AWKeys::getHddDevices() const
} }
+#include <QInputDialog>
+QString AWKeys::graphicalKey() const +QString AWKeys::graphicalKey() const
+{ +{
+ return QInputDialog::getItem(nullptr, i18n("Select tag"), QString(), + return QInputDialog::getItem(nullptr, i18n("Select tag"), QString(),
@ -335,7 +339,7 @@ index e5b9861..039d24e 100644
+ +
QString AWKeys::infoByKey(QString key) const QString AWKeys::infoByKey(QString key) const
{ {
qCDebug(LOG_AW) << "Requested key" << key; qCDebug(LOG_AW) << "Requested info for key" << key;
diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h
index a8300f1..8edc3bd 100644 index a8300f1..8edc3bd 100644
--- a/sources/awesome-widget/plugin/awkeys.h --- a/sources/awesome-widget/plugin/awkeys.h

View File

@ -11,19 +11,21 @@ index f808d03..a056b3f 100644
#include "version.h" #include "version.h"
diff --git a/sources/awdebug.h b/sources/awdebug.h diff --git a/sources/awdebug.h b/sources/awdebug.h
index 48dc580..530c0d6 100644 index 43944ce..c679281 100644
--- a/sources/awdebug.h --- a/sources/awdebug.h
+++ b/sources/awdebug.h +++ b/sources/awdebug.h
@@ -23,9 +23,9 @@ @@ -21,9 +21,13 @@
#include <QLoggingCategory>
+#ifndef qCInfo
+#define qCInfo qCDebug
+#endif
+
#ifndef LOG_FORMAT #ifndef LOG_FORMAT
#define LOG_FORMAT \ #define LOG_FORMAT \
- "[%{time process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%{if-" \ - "[%{time process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%{if-" \
- "warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{" \ + "[%{time process}][%{if-debug}DD%{endif}%{if-" \
- "category}][%{function}] %{message}" "warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{" \
+ "[%{time process}][%{if-debug}DD%{endif}%{if-warning}WW%{endif}%{if-" \ "category}][%{function}] %{message}"
+ "critical}CC%{endif}%{if-fatal}FF%{endif}][%{category}][%{function}] " \
+ "%{message}"
#endif /* LOG_FORMAT */ #endif /* LOG_FORMAT */
// redefine info because it doesn't log properly

View File

@ -0,0 +1,134 @@
diff --git a/sources/awesome-widget/plugin/awupdatehelper.cpp b/sources/awesome-widget/plugin/awupdatehelper.cpp
index 3698602..42871c8 100644
--- a/sources/awesome-widget/plugin/awupdatehelper.cpp
+++ b/sources/awesome-widget/plugin/awupdatehelper.cpp
@@ -37,7 +37,7 @@ AWUpdateHelper::AWUpdateHelper(QObject *parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
- m_foundVersion = QVersionNumber::fromString(VERSION);
+ m_foundVersion = QString(VERSION);
m_genericConfig = QString("%1/awesomewidgets/general.ini")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation));
@@ -69,14 +69,14 @@ void AWUpdateHelper::checkUpdates(const bool showAnyway)
bool AWUpdateHelper::checkVersion()
{
QSettings settings(m_genericConfig, QSettings::IniFormat);
- QVersionNumber version = QVersionNumber::fromString(
- settings.value(QString("Version"), QString(VERSION)).toString());
+ QString version
+ = settings.value(QString("Version"), QString(VERSION)).toString();
// update version
settings.setValue(QString("Version"), QString(VERSION));
settings.sync();
qCInfo(LOG_AW) << "Found version" << version << "actual one is" << VERSION;
- if (version != QVersionNumber::fromString(VERSION)) {
+ if (version != QString(VERSION)) {
genMessageBox(i18n("Changelog of %1", QString(VERSION)),
QString(CHANGELOG).replace(QChar('@'), QChar('\n')),
QMessageBox::Ok)
@@ -90,12 +90,11 @@ bool AWUpdateHelper::checkVersion()
}
-void AWUpdateHelper::showInfo(const QVersionNumber version)
+void AWUpdateHelper::showInfo(const QString version)
{
qCDebug(LOG_AW) << "Version" << version;
- QString text
- = i18n("You are using the actual version %1", version.toString());
+ QString text = i18n("You are using the actual version %1", version);
if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(QString(COMMIT_SHA));
return genMessageBox(i18n("No new version found"), text, QMessageBox::Ok)
@@ -103,7 +102,7 @@ void AWUpdateHelper::showInfo(const QVersionNumber version)
}
-void AWUpdateHelper::showUpdates(const QVersionNumber version)
+void AWUpdateHelper::showUpdates(const QString version)
{
qCDebug(LOG_AW) << "Version" << version;
@@ -112,7 +111,7 @@ void AWUpdateHelper::showUpdates(const QVersionNumber version)
text += QString(COMMIT_SHA).isEmpty()
? QString("\n")
: QString(" (%1)\n").arg(QString(COMMIT_SHA));
- text += i18n("New version : %1", version.toString()) + QString("\n\n");
+ text += i18n("New version : %1", version) + QString("\n\n");
text += i18n("Click \"Ok\" to download");
genMessageBox(i18n("There are updates"), text,
@@ -128,8 +127,7 @@ void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *button)
switch (ret) {
case QMessageBox::Ok:
- QDesktopServices::openUrl(QString(RELEASES)
- + m_foundVersion.toString());
+ QDesktopServices::openUrl(QString(RELEASES) + m_foundVersion);
break;
case QMessageBox::Cancel:
default:
@@ -157,14 +155,23 @@ void AWUpdateHelper::versionReplyRecieved(QNetworkReply *reply,
QVariantMap firstRelease = jsonDoc.toVariant().toList().first().toMap();
QString version = firstRelease[QString("tag_name")].toString();
version.remove(QString("V."));
- m_foundVersion = QVersionNumber::fromString(version);
+ m_foundVersion = version;
qCInfo(LOG_AW) << "Update found version to" << m_foundVersion;
- QVersionNumber oldVersion = QVersionNumber::fromString(VERSION);
- if (oldVersion < m_foundVersion)
- return showUpdates(m_foundVersion);
+ // FIXME: possible there is a better way to check versions
+ 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 = 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)
+ && (old_patch < new_patch)))
+ return showUpdates(version);
else if (showAnyway)
- return showInfo(m_foundVersion);
+ return showInfo(version);
}
diff --git a/sources/awesome-widget/plugin/awupdatehelper.h b/sources/awesome-widget/plugin/awupdatehelper.h
index 359cdb2..9c6a42d 100644
--- a/sources/awesome-widget/plugin/awupdatehelper.h
+++ b/sources/awesome-widget/plugin/awupdatehelper.h
@@ -21,7 +21,6 @@
#include <QMessageBox>
#include <QObject>
-#include <QVersionNumber>
class QNetworkReply;
@@ -37,15 +36,15 @@ public:
bool checkVersion();
private slots:
- void showInfo(const QVersionNumber version);
- void showUpdates(const QVersionNumber version);
+ void showInfo(const QString version);
+ void showUpdates(const QString version);
void userReplyOnUpdates(QAbstractButton *button);
void versionReplyRecieved(QNetworkReply *reply, const bool showAnyway);
private:
QMessageBox *genMessageBox(const QString title, const QString body,
const QMessageBox::StandardButtons buttons);
- QVersionNumber m_foundVersion;
+ QString m_foundVersion;
QString m_genericConfig;
};

Submodule sources/3rdparty/task deleted from d2798204a1

Submodule sources/3rdparty/tasks deleted from 230bdecd2c

View File

@ -14,8 +14,8 @@ set(PROJECT_AUTHOR "Evgeniy Alekseev")
set(PROJECT_CONTACT "esalexeev@gmail.com") set(PROJECT_CONTACT "esalexeev@gmail.com")
set(PROJECT_LICENSE "GPL3") set(PROJECT_LICENSE "GPL3")
set(PROJECT_VERSION_MAJOR "3") set(PROJECT_VERSION_MAJOR "3")
set(PROJECT_VERSION_MINOR "0") set(PROJECT_VERSION_MINOR "1")
set(PROJECT_VERSION_PATCH "1") set(PROJECT_VERSION_PATCH "0")
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
# append git version if any # append git version if any
set(PROJECT_COMMIT_SHA "Commit hash" CACHE INTERNAL "") set(PROJECT_COMMIT_SHA "Commit hash" CACHE INTERNAL "")
@ -39,16 +39,20 @@ option(BUILD_TESTING "Build with additional test abilities" OFF)
set(CLANGFORMAT_EXECUTABLE "/usr/bin/clang-format" CACHE STRING "Path to clang-format executable") set(CLANGFORMAT_EXECUTABLE "/usr/bin/clang-format" CACHE STRING "Path to clang-format executable")
set(CPPCHECK_EXECUTABLE "/usr/bin/cppcheck" CACHE STRING "Path to cppcheck executable") set(CPPCHECK_EXECUTABLE "/usr/bin/cppcheck" CACHE STRING "Path to cppcheck executable")
# generate changelog
set(PROJECT_CHANGELOG "Changelog" CACHE INTERNAL "")
include(changelog.cmake)
# flags # flags
if (CMAKE_COMPILER_IS_GNUCXX) 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_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG") set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG")
# avoid newer gcc warnings # avoid newer gcc warnings
add_definitions(-D_DEFAULT_SOURCE) add_definitions(-D_DEFAULT_SOURCE)
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 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_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG") set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG")

View File

@ -78,7 +78,7 @@ const QStringList getBuildData()
metadata.append( metadata.append(
QString(" CPPCHECK_EXECUTABLE: %1").arg(CPPCHECK_EXECUTABLE)); QString(" CPPCHECK_EXECUTABLE: %1").arg(CPPCHECK_EXECUTABLE));
metadata.append(QString(" PROP_FUTURE: %1").arg(PROP_FUTURE)); metadata.append(QString(" PROP_FUTURE: %1").arg(PROP_FUTURE));
metadata.append(QString(" PROP_FUTURE: %1").arg(PROP_FUTURE)); metadata.append(QString(" PROP_TEST: %1").arg(PROP_TEST));
return metadata; return metadata;
} }

View File

@ -28,12 +28,6 @@
"category}][%{function}] %{message}" "category}][%{function}] %{message}"
#endif /* LOG_FORMAT */ #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_AW)
Q_DECLARE_LOGGING_CATEGORY(LOG_DP) Q_DECLARE_LOGGING_CATEGORY(LOG_DP)

View File

@ -21,7 +21,7 @@ X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis
X-KDE-PluginInfo-Email=esalexeev@gmail.com X-KDE-PluginInfo-Email=esalexeev@gmail.com
X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget
X-KDE-PluginInfo-Version=@PROJECT_VERSION@ X-KDE-PluginInfo-Version=@PROJECT_VERSION@
X-KDE-PluginInfo-Website=http://arcanis.name/projects/awesome-widgets/ X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/
X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Category=System Information
X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPLv3 X-KDE-PluginInfo-License=GPLv3

View File

@ -32,6 +32,9 @@
<entry name="checkUpdates" type="bool"> <entry name="checkUpdates" type="bool">
<default>true</default> <default>true</default>
</entry> </entry>
<entry name="optimize" type="bool">
<default>true</default>
</entry>
<entry name="height" type="int"> <entry name="height" type="int">
<default>0</default> <default>0</default>
</entry> </entry>
@ -95,13 +98,13 @@
<entry name="swapTooltipColor" type="string"> <entry name="swapTooltipColor" type="string">
<default>#ffff00</default> <default>#ffff00</default>
</entry> </entry>
<entry name="downTooltip" type="bool"> <entry name="downkbTooltip" type="bool">
<default>true</default> <default>true</default>
</entry> </entry>
<entry name="downTooltipColor" type="string"> <entry name="downkbTooltipColor" type="string">
<default>#00ffff</default> <default>#00ffff</default>
</entry> </entry>
<entry name="upTooltipColor" type="string"> <entry name="upkbTooltipColor" type="string">
<default>#ff00ff</default> <default>#ff00ff</default>
</entry> </entry>
<entry name="batTooltip" type="bool"> <entry name="batTooltip" type="bool">

View File

@ -97,6 +97,15 @@ Item {
text: awActions.getAboutText("translators") 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 { QtControls.Label {
QtLayouts.Layout.fillHeight: true QtLayouts.Layout.fillHeight: true
QtLayouts.Layout.fillWidth: true QtLayouts.Layout.fillWidth: true
@ -104,7 +113,7 @@ Item {
horizontalAlignment: Text.AlignJustify horizontalAlignment: Text.AlignJustify
verticalAlignment: Text.AlignTop verticalAlignment: Text.AlignTop
textFormat: Text.RichText textFormat: Text.RichText
text: awActions.getAboutText("3rdparty") text: awActions.getAboutText("thanks")
onLinkActivated: Qt.openUrlExternally(link); onLinkActivated: Qt.openUrlExternally(link);
} }
} }

View File

@ -45,6 +45,7 @@ Item {
property alias cfg_wrapText: wordWrap.checked property alias cfg_wrapText: wordWrap.checked
property alias cfg_notify: notify.checked property alias cfg_notify: notify.checked
property alias cfg_checkUpdates: updates.checked property alias cfg_checkUpdates: updates.checked
property alias cfg_optimize: optimize.checked
property alias cfg_height: widgetHeight.value property alias cfg_height: widgetHeight.value
property alias cfg_width: widgetWidth.value property alias cfg_width: widgetWidth.value
property alias cfg_interval: update.value property alias cfg_interval: update.value
@ -143,6 +144,20 @@ Item {
} }
} }
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: optimize
width: parent.width * 3 / 5
text: i18n("Optimize subscription")
}
}
Row { Row {
height: implicitHeight height: implicitHeight
width: parent.width width: parent.width
@ -379,6 +394,7 @@ Item {
id: saveConfigAs id: saveConfigAs
selectExisting: false selectExisting: false
title: i18n("Export") title: i18n("Export")
folder: awConfig.configurationDirectory()
onAccepted: { onAccepted: {
var status = awConfig.exportConfiguration( var status = awConfig.exportConfiguration(
plasmoid.configuration, plasmoid.configuration,
@ -416,6 +432,7 @@ Item {
QtDialogs.FileDialog { QtDialogs.FileDialog {
id: openConfig id: openConfig
title: i18n("Import") title: i18n("Import")
folder: awConfig.configurationDirectory()
onAccepted: importSelection.open() onAccepted: importSelection.open()
} }

View File

@ -46,15 +46,15 @@ Item {
"cpuclTooltip": plasmoid.configuration.cpuclTooltip, "cpuclTooltip": plasmoid.configuration.cpuclTooltip,
"memTooltip": plasmoid.configuration.memTooltip, "memTooltip": plasmoid.configuration.memTooltip,
"swapTooltip": plasmoid.configuration.swapTooltip, "swapTooltip": plasmoid.configuration.swapTooltip,
"downTooltip": plasmoid.configuration.downTooltip, "downkbTooltip": plasmoid.configuration.downkbTooltip,
"upTooltip": plasmoid.configuration.downTooltip, "upkbTooltip": plasmoid.configuration.downkbTooltip,
"batTooltip": plasmoid.configuration.batTooltip, "batTooltip": plasmoid.configuration.batTooltip,
"cpuTooltipColor": plasmoid.configuration.cpuTooltipColor, "cpuTooltipColor": plasmoid.configuration.cpuTooltipColor,
"cpuclTooltipColor": plasmoid.configuration.cpuclTooltipColor, "cpuclTooltipColor": plasmoid.configuration.cpuclTooltipColor,
"memTooltipColor": plasmoid.configuration.memTooltipColor, "memTooltipColor": plasmoid.configuration.memTooltipColor,
"swapTooltipColor": plasmoid.configuration.swapTooltipColor, "swapTooltipColor": plasmoid.configuration.swapTooltipColor,
"downTooltipColor": plasmoid.configuration.downTooltipColor, "downkbTooltipColor": plasmoid.configuration.downkbTooltipColor,
"upTooltipColor": plasmoid.configuration.upTooltipColor, "upkbTooltipColor": plasmoid.configuration.upkbTooltipColor,
"batTooltipColor": plasmoid.configuration.batTooltipColor, "batTooltipColor": plasmoid.configuration.batTooltipColor,
"batInTooltipColor": plasmoid.configuration.batInTooltipColor, "batInTooltipColor": plasmoid.configuration.batInTooltipColor,
// additional field to parse AC status // additional field to parse AC status
@ -136,6 +136,8 @@ Item {
if (debug) console.debug() if (debug) console.debug()
// actions // actions
// it makes no sense to use this field with optimization enable
if (!plasmoid.configuration.optimize)
plasmoid.setAction("requestKey", i18n("Request key"), "utilities-system-monitor") plasmoid.setAction("requestKey", i18n("Request key"), "utilities-system-monitor")
plasmoid.setAction("showReadme", i18n("Show README"), "text-x-readme") plasmoid.setAction("showReadme", i18n("Show README"), "text-x-readme")
plasmoid.setAction("checkUpdates", i18n("Check updates"), "system-software-update") plasmoid.setAction("checkUpdates", i18n("Check updates"), "system-software-update")
@ -187,9 +189,9 @@ Item {
if (debug) console.debug() if (debug) console.debug()
// init submodule // init submodule
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit)
awKeys.initDataAggregator(tooltipSettings) awKeys.initDataAggregator(tooltipSettings)
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit, plasmoid.configuration.optimize)
awKeys.setWrapNewLines(plasmoid.configuration.wrapNewLines) awKeys.setWrapNewLines(plasmoid.configuration.wrapNewLines)
// configure aggregator // configure aggregator
awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline) awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline)

View File

@ -48,9 +48,9 @@ Item {
property alias cfg_memTooltipColor: memTooltipColor.text property alias cfg_memTooltipColor: memTooltipColor.text
property alias cfg_swapTooltip: swapTooltip.checked property alias cfg_swapTooltip: swapTooltip.checked
property alias cfg_swapTooltipColor: swapTooltipColor.text property alias cfg_swapTooltipColor: swapTooltipColor.text
property alias cfg_downTooltip: downTooltip.checked property alias cfg_downkbTooltip: downkbTooltip.checked
property alias cfg_downTooltipColor: downTooltipColor.text property alias cfg_downkbTooltipColor: downkbTooltipColor.text
property alias cfg_upTooltipColor: upTooltipColor.text property alias cfg_upkbTooltipColor: upkbTooltipColor.text
property alias cfg_batTooltip: batTooltip.checked property alias cfg_batTooltip: batTooltip.checked
property alias cfg_batTooltipColor: batTooltipColor.text property alias cfg_batTooltipColor: batTooltipColor.text
property alias cfg_batInTooltipColor: batInTooltipColor.text property alias cfg_batInTooltipColor: batInTooltipColor.text
@ -273,7 +273,7 @@ Item {
} }
QtControls.GroupBox { QtControls.GroupBox {
id: downTooltip id: downkbTooltip
height: implicitHeight height: implicitHeight
width: parent.width width: parent.width
checkable: true checkable: true
@ -292,22 +292,22 @@ Item {
text: i18n("Download speed color") text: i18n("Download speed color")
} }
QtControls.Button { QtControls.Button {
id: downTooltipColor id: downkbTooltipColor
width: parent.width * 3 / 5 width: parent.width * 3 / 5
style: QtStyles.ButtonStyle { style: QtStyles.ButtonStyle {
background: Rectangle { background: Rectangle {
color: plasmoid.configuration.downTooltipColor color: plasmoid.configuration.downkbTooltipColor
} }
} }
text: plasmoid.configuration.downTooltipColor text: plasmoid.configuration.downkbTooltipColor
onClicked: downTooltipColorDialog.visible = true onClicked: downkbTooltipColorDialog.visible = true
} }
QtDialogs.ColorDialog { QtDialogs.ColorDialog {
id: downTooltipColorDialog id: downkbTooltipColorDialog
title: i18n("Select a color") title: i18n("Select a color")
color: downTooltipColor.text color: downkbTooltipColor.text
onAccepted: downTooltipColor.text = downTooltipColorDialog.color onAccepted: downkbTooltipColor.text = downkbTooltipColorDialog.color
} }
} }
Row { Row {
@ -321,22 +321,22 @@ Item {
text: i18n("Upload speed color") text: i18n("Upload speed color")
} }
QtControls.Button { QtControls.Button {
id: upTooltipColor id: upkbTooltipColor
width: parent.width * 3 / 5 width: parent.width * 3 / 5
style: QtStyles.ButtonStyle { style: QtStyles.ButtonStyle {
background: Rectangle { background: Rectangle {
color: plasmoid.configuration.upTooltipColor color: plasmoid.configuration.upkbTooltipColor
} }
} }
text: plasmoid.configuration.upTooltipColor text: plasmoid.configuration.upkbTooltipColor
onClicked: upTooltipColorDialog.visible = true onClicked: upkbTooltipColorDialog.visible = true
} }
QtDialogs.ColorDialog { QtDialogs.ColorDialog {
id: upTooltipColorDialog id: upkbTooltipColorDialog
title: i18n("Select a color") title: i18n("Select a color")
color: upTooltipColor.text color: upkbTooltipColor.text
onAccepted: upTooltipColor.text = upTooltipColorDialog.color onAccepted: upkbTooltipColor.text = upkbTooltipColorDialog.color
} }
} }
} }

View File

@ -53,7 +53,7 @@ Item {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: i18n("Detailed information may be found on <a href=\"http://arcanis.name/projects/awesome-widgets/\">project homepage</a>") text: i18n("Detailed information may be found on <a href=\"https://arcanis.me/projects/awesome-widgets/\">project homepage</a>")
onLinkActivated: Qt.openUrlExternally(link); onLinkActivated: Qt.openUrlExternally(link);
} }
@ -198,7 +198,7 @@ Item {
height: implicitHeight height: implicitHeight
width: parent.width width: parent.width
QtControls.ComboBox { QtControls.ComboBox {
width: parent.width * 1 / 5 width: parent.width * 2 / 5
textRole: "label" textRole: "label"
model: [ model: [
{ {
@ -252,10 +252,19 @@ Item {
{ {
'label': i18n("Weathers"), 'label': i18n("Weathers"),
'regexp': "^(weather(Id)?|humidity|pressure|temperature|timestamp)" 'regexp': "^(weather(Id)?|humidity|pressure|temperature|timestamp)"
},
{
'label': i18n("Functions"),
'regexp': "functions"
} }
] ]
onCurrentIndexChanged: { onCurrentIndexChanged: {
if (debug) console.debug() if (debug) console.debug()
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"]) tags.model = awKeys.dictKeys(true, model[currentIndex]["regexp"])
if (debug) console.info("Init model", tags.model, "for", model[currentIndex]["label"]) if (debug) console.info("Init model", tags.model, "for", model[currentIndex]["label"])
tags.currentIndex = -1 tags.currentIndex = -1
@ -293,18 +302,6 @@ Item {
awActions.sendNotification("tag", message) 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 { Row {
@ -321,7 +318,7 @@ Item {
onClicked: { onClicked: {
lock = false lock = false
awKeys.initKeys(textPattern.text, plasmoid.configuration.interval, awKeys.initKeys(textPattern.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit) plasmoid.configuration.queueLimit, false)
awKeys.needToBeUpdated() awKeys.needToBeUpdated()
} }
} }
@ -349,7 +346,7 @@ Item {
awKeys.needTextToBeUpdated.connect(needTextUpdate) awKeys.needTextToBeUpdated.connect(needTextUpdate)
// init submodule // init submodule
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval, awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit) plasmoid.configuration.queueLimit, false)
awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline) awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline)
awKeys.setAggregatorProperty("acOnline", plasmoid.configuration.acOnline) awKeys.setAggregatorProperty("acOnline", plasmoid.configuration.acOnline)
awKeys.setAggregatorProperty("customTime", plasmoid.configuration.customTime) awKeys.setAggregatorProperty("customTime", plasmoid.configuration.customTime)

View File

@ -21,7 +21,7 @@ X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis
X-KDE-PluginInfo-Email=esalexeev@gmail.com X-KDE-PluginInfo-Email=esalexeev@gmail.com
X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget
X-KDE-PluginInfo-Version=3.0.1 X-KDE-PluginInfo-Version=3.0.1
X-KDE-PluginInfo-Website=http://arcanis.name/projects/awesome-widgets/ X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/
X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Category=System Information
X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPLv3 X-KDE-PluginInfo-License=GPLv3

View File

@ -21,19 +21,13 @@
#include <KNotifications/KNotification> #include <KNotifications/KNotification>
#include <QDesktopServices> #include <QDesktopServices>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QProcess> #include <QProcess>
#include <QProcessEnvironment> #include <QUrl>
#include <QStandardPaths>
#include <fontdialog/fontdialog.h> #include <fontdialog/fontdialog.h>
#include "awdebug.h" #include "awdebug.h"
#include "awupdatehelper.h"
#include "version.h" #include "version.h"
@ -41,12 +35,16 @@ AWActions::AWActions(QObject *parent)
: QObject(parent) : QObject(parent)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_updateHelper = new AWUpdateHelper(this);
} }
AWActions::~AWActions() AWActions::~AWActions()
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
delete m_updateHelper;
} }
@ -54,15 +52,8 @@ void AWActions::checkUpdates(const bool showAnyway)
{ {
qCDebug(LOG_AW) << "Show anyway" << showAnyway; qCDebug(LOG_AW) << "Show anyway" << showAnyway;
// showAnyway options requires to show message if no updates found on direct if (!m_updateHelper->checkVersion())
// request. In case of automatic check no message will be shown m_updateHelper->checkUpdates(showAnyway);
QNetworkAccessManager *manager = new QNetworkAccessManager(nullptr);
connect(manager, &QNetworkAccessManager::finished,
[showAnyway, this](QNetworkReply *reply) {
return versionReplyRecieved(reply, showAnyway);
});
manager->get(QNetworkRequest(QUrl(VERSION_API)));
} }
@ -86,7 +77,7 @@ bool AWActions::runCmd(const QString cmd) const
// HACK: this method uses variable from version.h // HACK: this method uses variable from version.h
void AWActions::showReadme() const void AWActions::showReadme() const
{ {
QDesktopServices::openUrl(QString(HOMEPAGE)); QDesktopServices::openUrl(QUrl(HOMEPAGE));
} }
@ -144,6 +135,14 @@ QString AWActions::getAboutText(const QString type) const
.arg(trdPartyList.at(i).split(QChar(','))[1]) .arg(trdPartyList.at(i).split(QChar(','))[1])
.arg(trdPartyList.at(i).split(QChar(','))[2]); .arg(trdPartyList.at(i).split(QChar(','))[2]);
text = i18n("This software uses: %1", trdPartyList.join(QString(", "))); 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("<a href=\"%2\">%1</a>")
.arg(thanks.at(i).split(QChar(','))[0])
.arg(thanks.at(i).split(QChar(','))[1]);
text = i18n("Special thanks to %1", thanks.join(QString(", ")));
} }
return text; return text;
@ -171,87 +170,10 @@ QVariantMap AWActions::getFont(const QVariantMap defaultFont) const
// to avoid additional object definition this method is static // to avoid additional object definition this method is static
void AWActions::sendNotification(const QString eventId, const QString message) void AWActions::sendNotification(const QString eventId, const QString message)
{ {
qCDebug(LOG_AW) << "Event" << eventId; qCDebug(LOG_AW) << "Event" << eventId << "with message" << message;
qCDebug(LOG_AW) << "Message" << message;
KNotification *notification = KNotification::event( KNotification *notification = KNotification::event(
eventId, QString("Awesome Widget ::: %1").arg(eventId), message); eventId, QString("Awesome Widget ::: %1").arg(eventId), message);
notification->setComponentName( notification->setComponentName(
QString("plasma-applet-org.kde.plasma.awesome-widget")); QString("plasma-applet-org.kde.plasma.awesome-widget"));
} }
void AWActions::showInfo(const QString version) const
{
qCDebug(LOG_AW) << "Version" << version;
QString text = i18n("You are using the actual version %1", version);
if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(QString(COMMIT_SHA));
QMessageBox::information(nullptr, i18n("No new version found"), text);
}
void AWActions::showUpdates(const QString version) const
{
qCDebug(LOG_AW) << "Version" << version;
QString text;
text += i18n("Current version : %1", QString(VERSION));
text += QString(COMMIT_SHA).isEmpty()
? QString("\n")
: QString(" (%1)\n").arg(QString(COMMIT_SHA));
text += i18n("New version : %1", version) + QString("\n\n");
text += i18n("Click \"Ok\" to download");
int select
= QMessageBox::information(nullptr, i18n("There are updates"), text,
QMessageBox::Ok | QMessageBox::Cancel);
switch (select) {
case QMessageBox::Ok:
QDesktopServices::openUrl(QString(RELEASES) + version);
break;
case QMessageBox::Cancel:
default:
break;
}
}
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;
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;
}
// convert to map
QVariantMap firstRelease = jsonDoc.toVariant().toList().first().toMap();
QString version = firstRelease[QString("tag_name")].toString();
version.remove(QString("V."));
qCInfo(LOG_AW) << "Found version" << version;
// FIXME: possible there is a better way to check versions
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();
if ((old_major < new_major)
|| ((old_major == new_major) && (old_minor < new_minor))
|| ((old_major == new_major) && (old_minor == new_minor)
&& (old_patch < new_patch)))
return showUpdates(version);
else if (showAnyway)
return showInfo(version);
}

View File

@ -22,7 +22,7 @@
#include <QObject> #include <QObject>
class QNetworkReply; class AWUpdateHelper;
class AWActions : public QObject class AWActions : public QObject
{ {
@ -44,11 +44,8 @@ public slots:
Q_INVOKABLE static void sendNotification(const QString eventId, Q_INVOKABLE static void sendNotification(const QString eventId,
const QString message); const QString message);
private slots: private:
void showInfo(const QString version) const; AWUpdateHelper *m_updateHelper = nullptr;
void showUpdates(const QString version) const;
void versionReplyRecieved(QNetworkReply *reply,
const bool showAnyway) const;
}; };

View File

@ -40,6 +40,25 @@ AWConfigHelper::~AWConfigHelper()
} }
QString AWConfigHelper::configurationDirectory() const
{
// get readable directory
QString localDir = QString("%1/awesomewidgets/configs")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation));
// create directory and copy files from default settings
QDir localDirectory;
if ((!localDirectory.exists(localDir))
&& (localDirectory.mkpath(localDir))) {
qCInfo(LOG_AW) << "Created directory" << localDir;
copyConfigs(localDir);
}
return localDir;
}
bool AWConfigHelper::dropCache() const bool AWConfigHelper::dropCache() const
{ {
QString fileName = QString("%1/awesomewidgets.ndx") QString fileName = QString("%1/awesomewidgets.ndx")
@ -61,7 +80,7 @@ bool AWConfigHelper::exportConfiguration(QObject *nativeConfig,
QQmlPropertyMap *configuration QQmlPropertyMap *configuration
= static_cast<QQmlPropertyMap *>(nativeConfig); = static_cast<QQmlPropertyMap *>(nativeConfig);
settings.beginGroup(QString("plasmoid")); settings.beginGroup(QString("plasmoid"));
foreach (QString key, configuration->keys()) { for (auto key : configuration->keys()) {
QVariant value = configuration->value(key); QVariant value = configuration->value(key);
if (!value.isValid()) if (!value.isValid())
continue; continue;
@ -70,13 +89,13 @@ bool AWConfigHelper::exportConfiguration(QObject *nativeConfig,
settings.endGroup(); settings.endGroup();
// extensions // extensions
foreach (QString item, m_dirs) { for (auto item : m_dirs) {
QStringList items QStringList items
= QDir(QString("%1/%2").arg(m_baseDir).arg(item)) = QDir(QString("%1/%2").arg(m_baseDir).arg(item))
.entryList(QStringList() << QString("*.desktop"), .entryList(QStringList() << QString("*.desktop"),
QDir::Files); QDir::Files);
settings.beginGroup(item); settings.beginGroup(item);
foreach (QString it, items) for (auto it : items)
copyExtensions(it, item, settings, false); copyExtensions(it, item, settings, false);
settings.endGroup(); settings.endGroup();
} }
@ -112,9 +131,9 @@ QVariantMap AWConfigHelper::importConfiguration(const QString fileName,
// extensions // extensions
if (importExtensions) { if (importExtensions) {
foreach (QString item, m_dirs) { for (auto item : m_dirs) {
settings.beginGroup(item); settings.beginGroup(item);
foreach (QString it, settings.childGroups()) for (auto it : settings.childGroups())
copyExtensions(it, item, settings, true); copyExtensions(it, item, settings, true);
settings.endGroup(); settings.endGroup();
} }
@ -137,7 +156,7 @@ QVariantMap AWConfigHelper::importConfiguration(const QString fileName,
// plasmoid configuration // plasmoid configuration
if (importPlasmoid) { if (importPlasmoid) {
settings.beginGroup(QString("plasmoid")); settings.beginGroup(QString("plasmoid"));
foreach (QString key, settings.childKeys()) for (auto key : settings.childKeys())
configuration[key] = settings.value(key); configuration[key] = settings.value(key);
settings.endGroup(); settings.endGroup();
} }
@ -212,13 +231,34 @@ void AWConfigHelper::writeDataEngineConfiguration(
} }
void AWConfigHelper::copyConfigs(const QString localDir) const
{
qCDebug(LOG_AW) << "Local directory" << localDir;
QStringList dirs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation, QString("awesomewidgets/configs"),
QStandardPaths::LocateDirectory);
for (auto dir : dirs) {
if (dir == localDir)
continue;
QStringList files = QDir(dir).entryList(QDir::Files);
for (auto source : files) {
QString destination = QString("%1/%2").arg(localDir).arg(source);
bool status = QFile::copy(QString("%1/%2").arg(dir).arg(source),
destination);
qCInfo(LOG_AW) << "File" << source << "has been copied to"
<< destination << "with status" << status;
}
}
}
void AWConfigHelper::copyExtensions(const QString item, const QString type, void AWConfigHelper::copyExtensions(const QString item, const QString type,
QSettings &settings, QSettings &settings,
const bool inverse) const const bool inverse) const
{ {
qCDebug(LOG_AW) << "Extension" << item; qCDebug(LOG_AW) << "Extension" << item << "has type" << type
qCDebug(LOG_AW) << "Type" << type; << "inverse copying" << inverse;
qCDebug(LOG_AW) << "Inverse" << inverse;
settings.beginGroup(item); settings.beginGroup(item);
QSettings itemSettings( QSettings itemSettings(
@ -239,7 +279,7 @@ void AWConfigHelper::copyExtensions(const QString item, const QString type,
void AWConfigHelper::copySettings(QSettings &from, QSettings &to) const void AWConfigHelper::copySettings(QSettings &from, QSettings &to) const
{ {
foreach (QString key, from.childKeys()) for (auto key : from.childKeys())
to.setValue(key, from.value(key)); to.setValue(key, from.value(key));
} }
@ -247,8 +287,7 @@ void AWConfigHelper::copySettings(QSettings &from, QSettings &to) const
void AWConfigHelper::readFile(QSettings &settings, const QString key, void AWConfigHelper::readFile(QSettings &settings, const QString key,
const QString fileName) const const QString fileName) const
{ {
qCDebug(LOG_AW) << "Key" << key; qCDebug(LOG_AW) << "Key" << key << "from file" << fileName;
qCDebug(LOG_AW) << "File" << fileName;
QFile file(fileName); QFile file(fileName);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
@ -264,8 +303,7 @@ void AWConfigHelper::readFile(QSettings &settings, const QString key,
void AWConfigHelper::writeFile(QSettings &settings, const QString key, void AWConfigHelper::writeFile(QSettings &settings, const QString key,
const QString fileName) const const QString fileName) const
{ {
qCDebug(LOG_AW) << "Key" << key; qCDebug(LOG_AW) << "Key" << key << "to file" << fileName;
qCDebug(LOG_AW) << "File" << fileName;
if (!settings.contains(key)) if (!settings.contains(key))
return; return;

View File

@ -32,6 +32,7 @@ class AWConfigHelper : public QObject
public: public:
explicit AWConfigHelper(QObject *parent = nullptr); explicit AWConfigHelper(QObject *parent = nullptr);
virtual ~AWConfigHelper(); virtual ~AWConfigHelper();
Q_INVOKABLE QString configurationDirectory() const;
Q_INVOKABLE bool dropCache() const; Q_INVOKABLE bool dropCache() const;
Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig, Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig,
const QString fileName) const; const QString fileName) const;
@ -46,6 +47,7 @@ public:
private: private:
// methods // methods
void copyConfigs(const QString localDir) const;
void copyExtensions(const QString item, const QString type, void copyExtensions(const QString item, const QString type,
QSettings &settings, const bool inverse) const; QSettings &settings, const bool inverse) const;
void copySettings(QSettings &from, QSettings &to) const; void copySettings(QSettings &from, QSettings &to) const;

View File

@ -25,7 +25,7 @@
#include <QGraphicsView> #include <QGraphicsView>
#include <QPixmap> #include <QPixmap>
#include <math.h> #include <cmath>
#include "awactions.h" #include "awactions.h"
#include "awdebug.h" #include "awdebug.h"
@ -35,12 +35,18 @@ AWDataAggregator::AWDataAggregator(QObject *parent)
: QObject(parent) : QObject(parent)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
// required by signals
qRegisterMetaType<QHash<QString, QString>>("QHash<QString, QString>"); boundaries[QString("cpuTooltip")] = 100.0;
boundaries[QString("cpuclTooltip")] = 4000.0;
boundaries[QString("memTooltip")] = 100.0;
boundaries[QString("swapTooltip")] = 100.0;
boundaries[QString("downkbTooltip")] = 1.0;
boundaries[QString("upkbTooltip")] = 1.0;
boundaries[QString("batTooltip")] = 100.0;
initScene(); initScene();
connect(this, SIGNAL(updateData(const QHash<QString, QString> &)), this, connect(this, SIGNAL(updateData(const QVariantHash &)), this,
SLOT(dataUpdate(const QHash<QString, QString> &))); SLOT(dataUpdate(const QVariantHash &)));
} }
@ -87,18 +93,10 @@ void AWDataAggregator::setParameters(QVariantMap settings)
counts += configuration[QString("cpuclTooltip")].toInt(); counts += configuration[QString("cpuclTooltip")].toInt();
counts += configuration[QString("memTooltip")].toInt(); counts += configuration[QString("memTooltip")].toInt();
counts += configuration[QString("swapTooltip")].toInt(); counts += configuration[QString("swapTooltip")].toInt();
counts += configuration[QString("downTooltip")].toInt(); counts += configuration[QString("downkbTooltip")].toInt();
counts += configuration[QString("batTooltip")].toInt(); counts += configuration[QString("batTooltip")].toInt();
// resize tooltip image // 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;
boundaries[QString("memTooltip")] = 100.0;
boundaries[QString("swapTooltip")] = 100.0;
boundaries[QString("downTooltip")] = 1.0;
boundaries[QString("upTooltip")] = 1.0;
boundaries[QString("batTooltip")] = 100.0;
requiredKeys.clear(); requiredKeys.clear();
if (configuration[QString("cpuTooltip")].toBool()) if (configuration[QString("cpuTooltip")].toBool())
@ -109,10 +107,10 @@ void AWDataAggregator::setParameters(QVariantMap settings)
requiredKeys.append(QString("memTooltip")); requiredKeys.append(QString("memTooltip"));
if (configuration[QString("swapTooltip")].toBool()) if (configuration[QString("swapTooltip")].toBool())
requiredKeys.append(QString("swapTooltip")); requiredKeys.append(QString("swapTooltip"));
if (configuration[QString("downTooltip")].toBool()) if (configuration[QString("downkbTooltip")].toBool())
requiredKeys.append(QString("downTooltip")); requiredKeys.append(QString("downkbTooltip"));
if (configuration[QString("upTooltip")].toBool()) if (configuration[QString("upkbTooltip")].toBool())
requiredKeys.append(QString("upTooltip")); requiredKeys.append(QString("upkbTooltip"));
if (configuration[QString("batTooltip")].toBool()) if (configuration[QString("batTooltip")].toBool())
requiredKeys.append(QString("batTooltip")); requiredKeys.append(QString("batTooltip"));
@ -131,11 +129,11 @@ QPixmap AWDataAggregator::tooltipImage()
toolTipScene->clear(); toolTipScene->clear();
QPen pen; QPen pen;
bool down = false; bool down = false;
foreach (QString key, requiredKeys) { for (auto key : requiredKeys) {
// create frame // create frame
float normX = 100.0 / static_cast<float>(data[key].count()); float normX = 100.0f / static_cast<float>(data[key].count());
float normY = 100.0 / (1.5 * boundaries[key]); float normY = 100.0f / (1.5f * boundaries[key]);
float shift = requiredKeys.indexOf(key) * 100.0; float shift = requiredKeys.indexOf(key) * 100.0f;
if (down) if (down)
shift -= 100.0; shift -= 100.0;
// apply pen color // apply pen color
@ -146,9 +144,9 @@ QPixmap AWDataAggregator::tooltipImage()
for (int j = 0; j < data[key].count() - 1; j++) { for (int j = 0; j < data[key].count() - 1; j++) {
// some magic here // some magic here
float x1 = j * normX + shift; float x1 = j * normX + shift;
float y1 = -fabs(data[key].at(j)) * normY + 5.0; float y1 = -fabs(data[key].at(j)) * normY + 5.0f;
float x2 = (j + 1) * normX + shift; float x2 = (j + 1) * normX + shift;
float y2 = -fabs(data[key].at(j + 1)) * normY + 5.0; float y2 = -fabs(data[key].at(j + 1)) * normY + 5.0f;
if (key == QString("batTooltip")) { if (key == QString("batTooltip")) {
if (data[key].at(j + 1) > 0) if (data[key].at(j + 1) > 0)
pen.setColor(QColor( pen.setColor(QColor(
@ -160,7 +158,7 @@ QPixmap AWDataAggregator::tooltipImage()
} }
toolTipScene->addLine(x1, y1, x2, y2, pen); toolTipScene->addLine(x1, y1, x2, y2, pen);
} }
if (key == QString("downTooltip")) if (key == QString("downkbTooltip"))
down = true; down = true;
} }
@ -168,7 +166,7 @@ QPixmap AWDataAggregator::tooltipImage()
} }
void AWDataAggregator::dataUpdate(const QHash<QString, QString> &values) void AWDataAggregator::dataUpdate(const QVariantHash &values)
{ {
// do not log these arguments // do not log these arguments
setData(values); setData(values);
@ -179,9 +177,8 @@ void AWDataAggregator::dataUpdate(const QHash<QString, QString> &values)
void AWDataAggregator::checkValue(const QString source, const float value, void AWDataAggregator::checkValue(const QString source, const float value,
const float extremum) const const float extremum) const
{ {
qCDebug(LOG_AW) << "Notification source" << source; qCDebug(LOG_AW) << "Notification source" << source << "with value" << value
qCDebug(LOG_AW) << "Value" << value; << "called with extremum" << extremum;
qCDebug(LOG_AW) << "Called with extremum" << extremum;
if (value >= 0.0) { if (value >= 0.0) {
if ((m_enablePopup) && (value > extremum) if ((m_enablePopup) && (value > extremum)
@ -200,9 +197,8 @@ void AWDataAggregator::checkValue(const QString source, const float value,
void AWDataAggregator::checkValue(const QString source, const QString current, void AWDataAggregator::checkValue(const QString source, const QString current,
const QString received) const const QString received) const
{ {
qCDebug(LOG_AW) << "Notification source" << source; qCDebug(LOG_AW) << "Notification source" << source << "with current value"
qCDebug(LOG_AW) << "Current value" << current; << current << "and received one" << received;
qCDebug(LOG_AW) << "Received value" << received;
if ((m_enablePopup) && (current != received) && (!received.isEmpty())) if ((m_enablePopup) && (current != received) && (!received.isEmpty()))
return AWActions::sendNotification(QString("event"), return AWActions::sendNotification(QString("event"),
@ -225,8 +221,7 @@ void AWDataAggregator::initScene()
QString AWDataAggregator::notificationText(const QString source, QString AWDataAggregator::notificationText(const QString source,
const float value) const const float value) const
{ {
qCDebug(LOG_AW) << "Notification source" << source; qCDebug(LOG_AW) << "Notification source" << source << "with value" << value;
qCDebug(LOG_AW) << "Value" << value;
QString output; QString output;
if (source == QString("batTooltip")) if (source == QString("batTooltip"))
@ -247,8 +242,7 @@ QString AWDataAggregator::notificationText(const QString source,
QString AWDataAggregator::notificationText(const QString source, QString AWDataAggregator::notificationText(const QString source,
const QString value) const const QString value) const
{ {
qCDebug(LOG_AW) << "Notification source" << source; qCDebug(LOG_AW) << "Notification source" << source << "with value" << value;
qCDebug(LOG_AW) << "Value" << value;
QString output; QString output;
if (source == QString("netdev")) if (source == QString("netdev"))
@ -258,24 +252,25 @@ QString AWDataAggregator::notificationText(const QString source,
} }
void AWDataAggregator::setData(const QHash<QString, QString> &values) void AWDataAggregator::setData(const QVariantHash &values)
{ {
// do not log these arguments // do not log these arguments
// battery update requires info is AC online or not // battery update requires info is AC online or not
setData(values[QString("ac")] == configuration[QString("acOnline")], setData(values[QString("ac")].toString()
== configuration[QString("acOnline")],
QString("batTooltip"), values[QString("bat")].toFloat()); QString("batTooltip"), values[QString("bat")].toFloat());
// usual case // usual case
setData(QString("cpuTooltip"), values[QString("cpu")].toFloat(), 90.0); setData(QString("cpuTooltip"), values[QString("cpu")].toFloat(), 90.0);
setData(QString("cpuclTooltip"), values[QString("cpucl")].toFloat()); setData(QString("cpuclTooltip"), values[QString("cpucl")].toFloat());
setData(QString("memTooltip"), values[QString("mem")].toFloat(), 90.0); setData(QString("memTooltip"), values[QString("mem")].toFloat(), 80.0);
setData(QString("swapTooltip"), values[QString("swap")].toFloat(), 0.0); setData(QString("swapTooltip"), values[QString("swap")].toFloat(), 0.0);
setData(QString("downTooltip"), values[QString("downkb")].toFloat()); setData(QString("downkbTooltip"), values[QString("downkb")].toFloat());
setData(QString("upTooltip"), values[QString("upkb")].toFloat()); setData(QString("upkbTooltip"), values[QString("upkb")].toFloat());
// additional check for network device // additional check for network device
[this](const QString value) { [this](const QString value) {
checkValue(QString("netdev"), currentNetworkDevice, value); checkValue(QString("netdev"), currentNetworkDevice, value);
currentNetworkDevice = value; currentNetworkDevice = value;
}(values[QString("netdev")]); }(values[QString("netdev")].toString());
// additional check for GPU load // additional check for GPU load
[this](const float value) { [this](const float value) {
checkValue(QString("gpu"), value, 90.0); checkValue(QString("gpu"), value, 90.0);
@ -287,9 +282,8 @@ void AWDataAggregator::setData(const QHash<QString, QString> &values)
void AWDataAggregator::setData(const QString &source, float value, void AWDataAggregator::setData(const QString &source, float value,
const float extremum) const float extremum)
{ {
qCDebug(LOG_AW) << "Source" << source; qCDebug(LOG_AW) << "Source" << source << "to value" << value
qCDebug(LOG_AW) << "Value" << value; << "with extremum" << extremum;
qCDebug(LOG_AW) << "Called with extremum" << extremum;
if (data[source].count() == 0) if (data[source].count() == 0)
data[source].append(0.0); data[source].append(0.0);
@ -303,12 +297,15 @@ void AWDataAggregator::setData(const QString &source, float value,
checkValue(source, value, extremum); checkValue(source, value, extremum);
data[source].append(value); data[source].append(value);
if (source == QString("downTooltip")) { if (source == QString("downkbTooltip")) {
QList<float> netValues QList<float> netValues
= data[QString("downTooltip")] + data[QString("upTooltip")]; = data[QString("downkbTooltip")] + data[QString("upkbTooltip")];
boundaries[QString("downTooltip")] // to avoid inf value of normY
= 1.2 * *std::max_element(netValues.cbegin(), netValues.cend()); netValues << 1.0;
boundaries[QString("upTooltip")] = boundaries[QString("downTooltip")]; boundaries[QString("downkbTooltip")]
= 1.2f * *std::max_element(netValues.cbegin(), netValues.cend());
boundaries[QString("upkbTooltip")]
= boundaries[QString("downkbTooltip")];
} }
} }
@ -316,9 +313,8 @@ void AWDataAggregator::setData(const QString &source, float value,
void AWDataAggregator::setData(const bool dontInvert, const QString &source, void AWDataAggregator::setData(const bool dontInvert, const QString &source,
float value) float value)
{ {
qCDebug(LOG_AW) << "Do not invert value" << dontInvert; qCDebug(LOG_AW) << "Do not invert" << dontInvert << "value" << value
qCDebug(LOG_AW) << "Source" << source; << "for source" << source;
qCDebug(LOG_AW) << "Value" << value;
// invert values for different battery colours // invert values for different battery colours
value = dontInvert ? value : -value; value = dontInvert ? value : -value;

View File

@ -41,11 +41,11 @@ public:
QPixmap tooltipImage(); QPixmap tooltipImage();
signals: signals:
void updateData(const QHash<QString, QString> &values); void updateData(const QVariantHash &values);
void toolTipPainted(const QString image) const; void toolTipPainted(const QString image) const;
public slots: private slots:
void dataUpdate(const QHash<QString, QString> &values); void dataUpdate(const QVariantHash &values);
private: private:
// ui // ui
@ -59,9 +59,9 @@ private:
QString notificationText(const QString source, const float value) const; QString notificationText(const QString source, const float value) const;
QString notificationText(const QString source, const QString value) const; QString notificationText(const QString source, const QString value) const;
// main method // main method
void setData(const QHash<QString, QString> &values); void setData(const QVariantHash &values);
void setData(const QString &source, float value, void setData(const QString &source, float value,
const float extremum = -1.0); const float extremum = -1.0f);
// different signature for battery device // different signature for battery device
void setData(const bool dontInvert, const QString &source, float value); void setData(const bool dontInvert, const QString &source, float value);
// variables // variables

View File

@ -17,20 +17,14 @@
#include "awdataengineaggregator.h" #include "awdataengineaggregator.h"
#include <Plasma/DataEngineConsumer>
#include "awdebug.h" #include "awdebug.h"
#include "awkeys.h" #include "awkeys.h"
AWDataEngineAggregator::AWDataEngineAggregator(QObject *parent, AWDataEngineAggregator::AWDataEngineAggregator(QObject *parent)
const int interval)
: QObject(parent) : QObject(parent)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
setInterval(interval);
initDataEngines();
} }
@ -38,25 +32,49 @@ AWDataEngineAggregator::~AWDataEngineAggregator()
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
clear();
}
void AWDataEngineAggregator::clear()
{
// disconnect sources first // disconnect sources first
disconnectSources(); disconnectSources();
m_dataEngines.clear(); m_dataEngines.clear();
delete m_consumer;
m_consumer = nullptr;
} }
void AWDataEngineAggregator::disconnectSources() void AWDataEngineAggregator::disconnectSources()
{ {
foreach (QString dataengine, m_dataEngines.keys()) for (auto dataengine : m_dataEngines.values())
foreach (QString source, m_dataEngines[dataengine]->sources()) for (auto source : dataengine->sources())
m_dataEngines[dataengine]->disconnectSource(source, parent()); dataengine->disconnectSource(source, parent());
} }
void AWDataEngineAggregator::setInterval(const int _interval) void AWDataEngineAggregator::initDataEngines(const int interval)
{ {
qCDebug(LOG_AW) << "Interval" << _interval; qCDebug(LOG_AW) << "Init dataengines with interval" << interval;
m_interval = _interval; m_consumer = new Plasma::DataEngineConsumer();
m_dataEngines[QString("systemmonitor")]
= m_consumer->dataEngine(QString("systemmonitor"));
m_dataEngines[QString("extsysmon")]
= 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")],
&Plasma::DataEngine::sourceAdded,
[this, interval](const QString source) {
emit(deviceAdded(source));
m_dataEngines[QString("systemmonitor")]->connectSource(
source, parent(), interval);
});
return reconnectSources(interval);
} }
@ -68,34 +86,17 @@ void AWDataEngineAggregator::dropSource(const QString source)
// connected we will try to disconnect it from systemmonitor and extsysmon // connected we will try to disconnect it from systemmonitor and extsysmon
m_dataEngines[QString("systemmonitor")]->disconnectSource(source, parent()); m_dataEngines[QString("systemmonitor")]->disconnectSource(source, parent());
m_dataEngines[QString("extsysmon")]->disconnectSource(source, parent()); m_dataEngines[QString("extsysmon")]->disconnectSource(source, parent());
m_dataEngines[QString("time")]->disconnectSource(source, parent());
} }
void AWDataEngineAggregator::reconnectSources() void AWDataEngineAggregator::reconnectSources(const int interval)
{ {
qCDebug(LOG_AW) << "Reconnect sources with interval" << interval;
m_dataEngines[QString("systemmonitor")]->connectAllSources(parent(), m_dataEngines[QString("systemmonitor")]->connectAllSources(parent(),
m_interval); interval);
m_dataEngines[QString("extsysmon")]->connectAllSources(parent(), m_dataEngines[QString("extsysmon")]->connectAllSources(parent(), interval);
m_interval);
m_dataEngines[QString("time")]->connectSource(QString("Local"), parent(), m_dataEngines[QString("time")]->connectSource(QString("Local"), parent(),
1000); 1000);
} }
void AWDataEngineAggregator::initDataEngines()
{
Plasma::DataEngineConsumer *deConsumer = new Plasma::DataEngineConsumer();
m_dataEngines[QString("systemmonitor")]
= deConsumer->dataEngine(QString("systemmonitor"));
m_dataEngines[QString("extsysmon")]
= deConsumer->dataEngine(QString("extsysmon"));
m_dataEngines[QString("time")] = deConsumer->dataEngine(QString("time"));
// additional method required by systemmonitor structure
connect(m_dataEngines[QString("systemmonitor")],
&Plasma::DataEngine::sourceAdded, [this](const QString source) {
static_cast<AWKeys *>(parent())->addDevice(source);
m_dataEngines[QString("systemmonitor")]->connectSource(
source, parent(), m_interval);
});
}

View File

@ -20,6 +20,7 @@
#define AWDATAENGINEAGGREGATOR_H #define AWDATAENGINEAGGREGATOR_H
#include <Plasma/DataEngine> #include <Plasma/DataEngine>
#include <Plasma/DataEngineConsumer>
#include <QObject> #include <QObject>
@ -27,24 +28,24 @@
class AWDataEngineAggregator : public QObject class AWDataEngineAggregator : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int interval MEMBER m_interval WRITE setInterval);
public: public:
explicit AWDataEngineAggregator(QObject *parent = nullptr, explicit AWDataEngineAggregator(QObject *parent = nullptr);
const int interval = 1000);
virtual ~AWDataEngineAggregator(); virtual ~AWDataEngineAggregator();
void clear();
void disconnectSources(); void disconnectSources();
// properties void initDataEngines(const int interval);
void setInterval(const int _interval);
signals:
void deviceAdded(const QString &source);
public slots: public slots:
void dropSource(const QString source); void dropSource(const QString source);
void reconnectSources(); void reconnectSources(const int interval);
private: private:
void initDataEngines(); Plasma::DataEngineConsumer *m_consumer = nullptr;
QHash<QString, Plasma::DataEngine *> m_dataEngines; QHash<QString, Plasma::DataEngine *> m_dataEngines;
int m_interval;
}; };

View File

@ -21,6 +21,7 @@
#include "awactions.h" #include "awactions.h"
#include "awconfighelper.h" #include "awconfighelper.h"
#include "awdataengineaggregator.h"
#include "awkeys.h" #include "awkeys.h"

View File

@ -0,0 +1,184 @@
/***************************************************************************
* 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 <QDir>
#include <QNetworkInterface>
#include <QRegExp>
#include <QSettings>
#include <QStandardPaths>
#include "awdebug.h"
bool AWKeyCache::addKeyToCache(const QString type, const QString key)
{
qCDebug(LOG_AW) << "Key" << key << "with type" << type;
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<QNetworkInterface> 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 false;
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 true;
}
QStringList AWKeyCache::getRequiredKeys(const QStringList &keys,
const QStringList &bars,
const QVariantMap &tooltip,
const QStringList &allKeys)
{
qCDebug(LOG_AW) << "Looking for required keys in" << keys << bars
<< "using tooltip settings" << tooltip;
// initial copy
QSet<QString> used = QSet<QString>::fromList(keys);
used.unite(QSet<QString>::fromList(bars));
// insert keys from tooltip
for (auto key : tooltip.keys()) {
if ((key.endsWith(QString("Tooltip"))) && (tooltip[key].toBool())) {
key.remove(QString("Tooltip"));
used << key;
}
}
// insert depending keys, refer to AWKeys::calculateValues()
// hddtotmb*
for (auto key : allKeys.filter(QRegExp(QString("^hddtotmb")))) {
if (!used.contains(key))
continue;
key.remove(QString("hddtotmb"));
int index = key.toInt();
used << QString("hddfreemb%1").arg(index)
<< QString("hddmb%1").arg(index);
}
// hddtotgb*
for (auto key : allKeys.filter(QRegExp(QString("^hddtotgb")))) {
if (!used.contains(key))
continue;
key.remove(QString("hddtotgb"));
int index = key.toInt();
used << QString("hddfreegb%1").arg(index)
<< QString("hddgb%1").arg(index);
}
// mem
if (used.contains(QString("mem")))
used << QString("memmb") << QString("memtotmb");
// memtotmb
if (used.contains(QString("memtotmb")))
used << QString("memusedmb") << QString("memfreemb");
// memtotgb
if (used.contains(QString("memtotgb")))
used << QString("memusedgb") << QString("memfreegb");
// swap
if (used.contains(QString("swap")))
used << QString("swapmb") << QString("swaptotmb");
// swaptotmb
if (used.contains(QString("swaptotmb")))
used << QString("swapmb") << QString("swapfreemb");
// memtotgb
if (used.contains(QString("swaptotgb")))
used << QString("swapgb") << QString("swapfreegb");
// network keys
QStringList netKeys(QStringList() << QString("up") << QString("upkb")
<< QString("upunits") << QString("down")
<< QString("downkb")
<< QString("downunits"));
for (auto key : netKeys) {
if (!used.contains(key))
continue;
QStringList filt
= allKeys.filter(QRegExp(QString("^%1[0-9]{1,}").arg(key)));
for (auto filtered : filt)
used << filtered;
}
// netdev key
if (std::any_of(netKeys.cbegin(), netKeys.cend(),
[&used](const QString &key) { return used.contains(key); }))
used << QString("netdev");
// HACK append dummy if there are no other keys. This hack is required
// because empty list leads to the same behaviour as skip checking
if (used.isEmpty())
used << QString("dummy");
return used.toList();
}
QHash<QString, QStringList> 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<QString, QStringList> 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;
}

View File

@ -0,0 +1,37 @@
/***************************************************************************
* 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 <QHash>
#include <QString>
#include <QVariant>
namespace AWKeyCache
{
bool addKeyToCache(const QString type, const QString key = QString(""));
QStringList getRequiredKeys(const QStringList &keys, const QStringList &bars,
const QVariantMap &tooltip,
const QStringList &allKeys);
QHash<QString, QStringList> loadKeysFromCache();
};
#endif /* AWKEYCACHE_H */

View File

@ -0,0 +1,327 @@
/***************************************************************************
* 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 <QDir>
#include <QJSEngine>
#include <QRegExp>
#include <QThread>
#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;
}
QStringList AWKeyOperations::devices(const QString type) const
{
qCDebug(LOG_AW) << "Looking for type" << type;
return m_devices[type];
}
QHash<QString, QStringList> 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")));
}
// 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));
}
// temperature
for (int i = m_devices[QString("temp")].count() - 1; i >= 0; i--)
allKeys.append(QString("temp%1").arg(i));
// 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));
}
// battery
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));
// 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")));
// bars
for (int i = graphicalItems->activeItems().count() - 1; i >= 0; i--)
allKeys.append(
graphicalItems->activeItems().at(i)->tag(QString("bar")));
// static keys
QStringList staticKeys = QString(STATIC_KEYS).split(QChar(','));
std::for_each(staticKeys.cbegin(), staticKeys.cend(),
[&allKeys](const QString &key) { allKeys.append(key); });
return allKeys;
}
// 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;
return graphicalItems->itemByTag(key, QString("bar"));
}
QString AWKeyOperations::infoByKey(QString key) const
{
qCDebug(LOG_AW) << "Requested key" << key;
if (key.startsWith(QString("bar")))
return graphicalItems->itemByTag(key, QString("bar"))->uniq();
else if (key.startsWith(QString("custom")))
return extScripts->itemByTag(key, QString("custom"))->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->itemByTag(key, QString("pkgcount"))->uniq();
else if (key.contains(QRegExp(QString("(^|perc)(ask|bid|price)(chg|)"))))
return extQuotes->itemByTag(key, QString("ask"))->uniq();
else if (key.contains(QRegExp(
QString("(weather|weatherId|humidity|pressure|temperature)"))))
return extWeather->itemByTag(key, QString("weather"))->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::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" << key << "with type" << type;
if (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<GraphicalItem>(nullptr, QString("desktops"));
extQuotes = new ExtItemAggregator<ExtQuotes>(nullptr, QString("quotes"));
extScripts = new ExtItemAggregator<ExtScript>(nullptr, QString("scripts"));
extUpgrade = new ExtItemAggregator<ExtUpgrade>(nullptr, QString("upgrade"));
extWeather = new ExtItemAggregator<ExtWeather>(nullptr, QString("weather"));
// init
QStringList allKeys = dictKeys();
// 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);
// wrap templates
m_pattern = AWPatternFunctions::expandTemplates(m_pattern);
emit(updateKeys(allKeys));
}

View File

@ -0,0 +1,83 @@
/***************************************************************************
* 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 <Plasma/DataEngine>
#include <QMutex>
#include <QObject>
#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();
QStringList devices(const QString type) const;
QHash<QString, QStringList> 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);
public slots:
void addDevice(const QString &source);
private:
// methods
void addKeyToCache(const QString type, const QString key = QString(""));
void reinitKeys();
// objects
ExtItemAggregator<GraphicalItem> *graphicalItems = nullptr;
ExtItemAggregator<ExtQuotes> *extQuotes = nullptr;
ExtItemAggregator<ExtScript> *extScripts = nullptr;
ExtItemAggregator<ExtUpgrade> *extUpgrade = nullptr;
ExtItemAggregator<ExtWeather> *extWeather = nullptr;
// variables
QHash<QString, QStringList> m_devices;
QString m_pattern;
};
#endif /* AWKEYOPERATIONS_H */

View File

@ -18,23 +18,17 @@
#include "awkeys.h" #include "awkeys.h"
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#include <QDir>
#include <QInputDialog>
#include <QJSEngine> #include <QJSEngine>
#include <QNetworkInterface>
#include <QRegExp> #include <QRegExp>
#include <QSettings>
#include <QStandardPaths>
#include <QThread> #include <QThread>
#include "awdataaggregator.h" #include "awdataaggregator.h"
#include "awdataengineaggregator.h" #include "awdataengineaggregator.h"
#include "awdebug.h" #include "awdebug.h"
#include "awkeycache.h"
#include "awkeyoperations.h"
#include "awkeysaggregator.h" #include "awkeysaggregator.h"
#include "extquotes.h" #include "awpatternfunctions.h"
#include "extscript.h"
#include "extupgrade.h"
#include "extweather.h"
#include "graphicalitem.h" #include "graphicalitem.h"
#include "version.h" #include "version.h"
@ -44,20 +38,29 @@ AWKeys::AWKeys(QObject *parent)
{ {
qSetMessagePattern(LOG_FORMAT); qSetMessagePattern(LOG_FORMAT);
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
foreach (const QString metadata, getBuildData()) for (auto metadata : getBuildData())
qCDebug(LOG_AW) << metadata; qCDebug(LOG_AW) << metadata;
#ifdef BUILD_FUTURE
// thread pool // thread pool
m_threadPool = new QThreadPool(this); m_threadPool = new QThreadPool(this);
#endif /* BUILD_FUTURE */
aggregator = new AWKeysAggregator(this); aggregator = new AWKeysAggregator(this);
dataAggregator = new AWDataAggregator(this); dataAggregator = new AWDataAggregator(this);
dataEngineAggregator = new AWDataEngineAggregator(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 // transfer signal from AWDataAggregator object to QML ui
connect(dataAggregator, SIGNAL(toolTipPainted(const QString)), this, connect(dataAggregator, SIGNAL(toolTipPainted(const QString)), this,
SIGNAL(needToolTipToBeUpdated(const QString))); SIGNAL(needToolTipToBeUpdated(const QString)));
connect(this, SIGNAL(needToBeUpdated()), this, SLOT(updateTextData())); connect(this, SIGNAL(needToBeUpdated()), this, SLOT(updateTextData()));
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 &)));
} }
@ -65,18 +68,12 @@ AWKeys::~AWKeys()
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
// extensions
delete graphicalItems;
delete extQuotes;
delete extScripts;
delete extUpgrade;
delete extWeather;
// core // core
delete dataEngineAggregator; delete dataEngineAggregator;
delete m_threadPool; delete m_threadPool;
delete aggregator; delete aggregator;
delete dataAggregator; delete dataAggregator;
delete keyOperator;
} }
@ -84,39 +81,35 @@ void AWKeys::initDataAggregator(const QVariantMap tooltipParams)
{ {
qCDebug(LOG_AW) << "Tooltip parameters" << tooltipParams; qCDebug(LOG_AW) << "Tooltip parameters" << tooltipParams;
dataAggregator->setParameters(tooltipParams); // store parameters to generate m_requiredKeys
m_tooltipParams = tooltipParams;
dataAggregator->setParameters(m_tooltipParams);
} }
void AWKeys::initKeys(const QString currentPattern, const int interval, void AWKeys::initKeys(const QString currentPattern, const int interval,
const int limit) const int limit, const bool optimize)
{ {
qCDebug(LOG_AW) << "Pattern" << currentPattern; qCDebug(LOG_AW) << "Pattern" << currentPattern << "with interval"
qCDebug(LOG_AW) << "Interval" << interval; << interval << "and queue limit" << limit
qCDebug(LOG_AW) << "Queue limit" << limit; << "with optimization" << optimize;
// init // init
m_pattern = currentPattern; m_optimize = optimize;
if (dataEngineAggregator == nullptr) {
dataEngineAggregator = new AWDataEngineAggregator(this, interval);
connect(this, SIGNAL(dropSourceFromDataengine(QString)),
dataEngineAggregator, SLOT(dropSource(QString)));
} else
dataEngineAggregator->setInterval(interval);
#ifdef BUILD_FUTURE
m_threadPool->setMaxThreadCount(limit == 0 ? QThread::idealThreadCount() m_threadPool->setMaxThreadCount(limit == 0 ? QThread::idealThreadCount()
: limit); : limit);
#endif /* BUILD_FUTURE */ // child objects
updateCache(); keyOperator->setPattern(currentPattern);
keyOperator->updateCache();
dataEngineAggregator->clear();
return dataEngineAggregator->reconnectSources(); return dataEngineAggregator->initDataEngines(interval);
} }
void AWKeys::setAggregatorProperty(const QString key, const QVariant value) void AWKeys::setAggregatorProperty(const QString key, const QVariant value)
{ {
qCDebug(LOG_AW) << "Key" << key; qCDebug(LOG_AW) << "Key" << key << "with value" << value;
qCDebug(LOG_AW) << "Value" << value;
aggregator->setProperty(key.toUtf8().constData(), value); aggregator->setProperty(key.toUtf8().constData(), value);
} }
@ -132,172 +125,16 @@ void AWKeys::setWrapNewLines(const bool wrap)
void AWKeys::updateCache() void AWKeys::updateCache()
{ {
// update network and hdd list return keyOperator->updateCache();
addKeyToCache(QString("hdd"));
addKeyToCache(QString("net"));
} }
QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const
{ {
qCDebug(LOG_AW) << "Should be sorted" << sorted; qCDebug(LOG_AW) << "Should be sorted" << sorted << "and filter applied"
qCDebug(LOG_AW) << "Filter" << regexp; << 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;
foreach (GraphicalItem *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 // sort if required
if (sorted) if (sorted)
allKeys.sort(); allKeys.sort();
@ -308,7 +145,7 @@ QStringList AWKeys::dictKeys(const bool sorted, const QString regexp) const
QStringList AWKeys::getHddDevices() const QStringList AWKeys::getHddDevices() const
{ {
QStringList devices = m_devices[QString("hdd")]; QStringList devices = keyOperator->devices(QString("hdd"));
// required by selector in the UI // required by selector in the UI
devices.insert(0, QString("disable")); devices.insert(0, QString("disable"));
devices.insert(0, QString("auto")); devices.insert(0, QString("auto"));
@ -319,63 +156,19 @@ QStringList AWKeys::getHddDevices() const
QString AWKeys::infoByKey(QString key) const QString AWKeys::infoByKey(QString key) const
{ {
qCDebug(LOG_AW) << "Requested key" << key; qCDebug(LOG_AW) << "Requested info for key" << key;
key.remove(QRegExp(QString("^bar[0-9]{1,}"))); return keyOperator->infoByKey(key);
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)");
} }
// HACK this method requires to define tag value from bar from UI interface // HACK this method requires to define tag value from bar from UI interface
QString AWKeys::valueByKey(QString key) const 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,}"))), key.remove(QRegExp(QString("^bar[0-9]{1,}")));
QString("")); return aggregator->formater(values[key], key);
} }
@ -383,41 +176,7 @@ void AWKeys::editItem(const QString type)
{ {
qCDebug(LOG_AW) << "Item type" << type; qCDebug(LOG_AW) << "Item type" << type;
if (type == QString("graphicalitem")) { return keyOperator->editItem(type);
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();
}
}
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);
}
} }
@ -430,237 +189,83 @@ void AWKeys::dataUpdated(const QString &sourceName,
return emit(needToBeUpdated()); return emit(needToBeUpdated());
} }
#ifdef BUILD_FUTURE
// run concurrent data update // run concurrent data update
QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, sourceName, QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, sourceName,
data); data);
#else /* BUILD_FUTURE */
return setDataBySource(sourceName, data);
#endif /* BUILD_FUTURE */
} }
void AWKeys::loadKeysFromCache() void AWKeys::reinitKeys(const QStringList currentKeys)
{ {
QString fileName = QString("%1/awesomewidgets.ndx") qCDebug(LOG_AW) << "Update found keys by using list" << currentKeys;
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericCacheLocation));
qCInfo(LOG_AW) << "Cache file" << fileName;
QSettings cache(fileName, QSettings::IniFormat);
foreach (QString group, cache.childGroups()) {
cache.beginGroup(group);
m_devices.remove(group);
foreach (QString 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<GraphicalItem>(nullptr, QString("desktops"));
extQuotes = new ExtItemAggregator<ExtQuotes>(nullptr, QString("quotes"));
extScripts = new ExtItemAggregator<ExtScript>(nullptr, QString("scripts"));
extUpgrade = new ExtItemAggregator<ExtUpgrade>(nullptr, QString("upgrade"));
extWeather = new ExtItemAggregator<ExtWeather>(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;
foreach (QString tag, allKeys)
strings.append(QString("%1: $%1").arg(tag));
return strings.join(QString(" | "));
}());
#endif /* BUILD_TESTING */
// append lists // append lists
// bars m_foundBars
m_foundBars = [allKeys](QString pattern) { = AWPatternFunctions::findBars(keyOperator->pattern(), currentKeys);
QStringList selectedKeys; m_foundKeys
foreach (QString key, allKeys) = AWPatternFunctions::findKeys(keyOperator->pattern(), currentKeys);
if ((key.startsWith(QString("bar"))) m_foundLambdas = AWPatternFunctions::findLambdas(keyOperator->pattern());
&& (pattern.contains(QString("$%1").arg(key)))) { // generate list of required keys for bars
qCInfo(LOG_AW) << "Found bar" << key; QStringList barKeys;
selectedKeys.append(key); for (auto bar : m_foundBars) {
GraphicalItem *item = keyOperator->giByKey(bar);
if (item->isCustom())
item->setUsedKeys(
AWPatternFunctions::findKeys(item->bar(), currentKeys));
else
item->setUsedKeys(QStringList() << item->bar());
barKeys.append(item->usedKeys());
} }
if (selectedKeys.isEmpty()) // get required keys
qCWarning(LOG_AW) << "No bars found"; m_requiredKeys
return selectedKeys; = m_optimize ? AWKeyCache::getRequiredKeys(m_foundKeys, barKeys,
}(m_pattern); m_tooltipParams, currentKeys)
: QStringList();
// main key list
m_foundKeys = [allKeys](QString pattern) {
QStringList selectedKeys;
foreach (QString key, allKeys)
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;
}(m_pattern);
// lambdas
m_foundLambdas = [](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 brakets
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;
}(m_pattern);
// set key data to aggregator // set key data to aggregator
aggregator->setDevices(m_devices); aggregator->setDevices(keyOperator->devices());
} }
void AWKeys::updateTextData() void AWKeys::updateTextData()
{ {
#ifdef BUILD_FUTURE // do not do it in parallel to avoid race condition
QFuture<QString> text = QtConcurrent::run(m_threadPool, [this]() {
calculateValues(); calculateValues();
return parsePattern(m_pattern); QString text = parsePattern(keyOperator->pattern());
});
#else /* BUILD_FUTURE */
calculateValues();
QString text = parsePattern(m_pattern);
#endif /* BUILD_FUTURE */
emit(needTextToBeUpdated(text)); emit(needTextToBeUpdated(text));
emit(dataAggregator->updateData(values)); emit(dataAggregator->updateData(values));
} }
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;
foreach (QString 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]$")));
foreach (QString 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<QNetworkInterface> rawInterfaceList
= QNetworkInterface::allInterfaces();
foreach (QNetworkInterface 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 // 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 // specified pattern. Usually they are values which depend on several others
void AWKeys::calculateValues() void AWKeys::calculateValues()
{ {
// hddtot* // hddtot*
foreach (QString device, m_devices[QString("mount")]) { QStringList mountDevices = keyOperator->devices(QString("mount"));
int index = m_devices[QString("mount")].indexOf(device); for (auto device : mountDevices) {
values[QString("hddtotmb%1").arg(index)] = QString("%1").arg( int index = mountDevices.indexOf(device);
values[QString("hddfreemb%1").arg(index)].toFloat() values[QString("hddtotmb%1").arg(index)]
+ values[QString("hddmb%1").arg(index)].toFloat(), = values[QString("hddfreemb%1").arg(index)].toFloat()
5, 'f', 0); + values[QString("hddmb%1").arg(index)].toFloat();
values[QString("hddtotgb%1").arg(index)] = QString("%1").arg( values[QString("hddtotgb%1").arg(index)]
values[QString("hddfreegb%1").arg(index)].toFloat() = values[QString("hddfreegb%1").arg(index)].toFloat()
+ values[QString("hddgb%1").arg(index)].toFloat(), + values[QString("hddgb%1").arg(index)].toFloat();
5, 'f', 1);
} }
// memtot* // memtot*
values[QString("memtotmb")] values[QString("memtotmb")] = values[QString("memusedmb")].toInt()
= QString("%1").arg(values[QString("memusedmb")].toInt() + values[QString("memfreemb")].toInt();
+ values[QString("memfreemb")].toInt(), values[QString("memtotgb")] = values[QString("memusedgb")].toFloat()
5); + values[QString("memfreegb")].toFloat();
values[QString("memtotgb")]
= QString("%1").arg(values[QString("memusedgb")].toFloat()
+ values[QString("memfreegb")].toFloat(),
5, 'f', 1);
// mem // mem
values[QString("mem")] values[QString("mem")] = 100.0f * values[QString("memmb")].toFloat()
= QString("%1").arg(100.0 * values[QString("memmb")].toFloat() / values[QString("memtotmb")].toFloat();
/ values[QString("memtotmb")].toFloat(),
5, 'f', 1);
// up, down, upkb, downkb, upunits, downunits // 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")].toString());
values[QString("down")] = values[QString("down%1").arg(netIndex)]; values[QString("down")] = values[QString("down%1").arg(netIndex)];
values[QString("downkb")] = values[QString("downkb%1").arg(netIndex)]; values[QString("downkb")] = values[QString("downkb%1").arg(netIndex)];
values[QString("downunits")] = values[QString("downunits%1").arg(netIndex)]; values[QString("downunits")] = values[QString("downunits%1").arg(netIndex)];
@ -669,77 +274,56 @@ void AWKeys::calculateValues()
values[QString("upunits")] = values[QString("upunits%1").arg(netIndex)]; values[QString("upunits")] = values[QString("upunits%1").arg(netIndex)];
// swaptot* // swaptot*
values[QString("swaptotmb")] values[QString("swaptotmb")] = values[QString("swapmb")].toInt()
= QString("%1").arg(values[QString("swapmb")].toInt() + values[QString("swapfreemb")].toInt();
+ values[QString("swapfreemb")].toInt(), values[QString("swaptotgb")] = values[QString("swapgb")].toFloat()
5); + values[QString("swapfreegb")].toFloat();
values[QString("swaptotgb")]
= QString("%1").arg(values[QString("swapgb")].toFloat()
+ values[QString("swapfreegb")].toFloat(),
5, 'f', 1);
// swap // swap
values[QString("swap")] values[QString("swap")] = 100.0f * values[QString("swapmb")].toFloat()
= QString("%1").arg(100.0 * values[QString("swapmb")].toFloat() / values[QString("swaptotmb")].toFloat();
/ values[QString("swaptotmb")].toFloat(),
5, 'f', 1);
// lambdas // lambdas
foreach (QString key, m_foundLambdas) for (auto key : m_foundLambdas)
values[key] = [this](QString key) { values[key] = AWPatternFunctions::expandLambdas(key, aggregator, values,
QJSEngine engine; m_foundKeys);
// apply $this values
key.replace(QString("$this"), values[key]);
foreach (QString lambdaKey, m_foundKeys)
key.replace(QString("$%1").arg(lambdaKey), values[lambdaKey]);
qCInfo(LOG_AW) << "Expression" << key;
QJSValue result = engine.evaluate(key);
if (result.isError()) {
qCWarning(LOG_AW) << "Uncaught exception at line"
<< result.property("lineNumber").toInt()
<< ":" << result.toString();
return QString();
} else {
return result.toString();
}
}(key);
} }
QString AWKeys::parsePattern(QString pattern) const QString AWKeys::parsePattern(QString pattern) const
{ {
// screen sign // screen sign
pattern.replace(QString("$$"), QString("$\\$\\")); pattern.replace(QString("$$"), QString(0x1d));
// lambdas // lambdas
foreach (QString key, m_foundLambdas) for (auto key : m_foundLambdas)
pattern.replace(QString("${{%1}}").arg(key), values[key]); pattern.replace(QString("${{%1}}").arg(key), values[key].toString());
// main keys // main keys
foreach (QString key, m_foundKeys) for (auto key : m_foundKeys)
pattern.replace(QString("$%1").arg(key), pattern.replace(QString("$%1").arg(key), [this](const QString &tag,
[](QString key, QString value) { const QVariant &value) {
if ((!key.startsWith(QString("custom"))) QString strValue = aggregator->formater(value, tag);
&& (!key.startsWith(QString("weather")))) if ((!tag.startsWith(QString("custom")))
value.replace(QString(" "), QString("&nbsp;")); && (!tag.startsWith(QString("weather"))))
return value; strValue.replace(QString(" "), QString("&nbsp;"));
return strValue;
}(key, values[key])); }(key, values[key]));
// bars // bars
foreach (QString bar, m_foundBars) { for (auto bar : m_foundBars) {
GraphicalItem *item = graphicalItems->itemByTag(bar); GraphicalItem *item = keyOperator->giByKey(bar);
QString key = bar; if (item->isCustom())
key.remove(QRegExp(QString("^bar[0-9]{1,}"))); pattern.replace(
if (item->type() == GraphicalItem::Graph) QString("$%1").arg(bar),
pattern.replace(QString("$%1").arg(bar), item->image(AWPatternFunctions::expandLambdas(
item->image([](const QList<float> data) { item->bar(), aggregator, values, item->usedKeys())));
return QVariant::fromValue<QList<float>>(data);
}(dataAggregator->getData(key))));
else else
pattern.replace(QString("$%1").arg(bar), item->image(values[key])); pattern.replace(QString("$%1").arg(bar),
item->image(values[item->bar()]));
} }
// prepare strings // prepare strings
pattern.replace(QString("$\\$\\"), QString("$$")); pattern.replace(QString(0x1d), QString("$"));
if (m_wrapNewLines) if (m_wrapNewLines)
pattern.replace(QString("\n"), QString("<br>")); pattern.replace(QString("\n"), QString("<br>"));
@ -749,34 +333,27 @@ QString AWKeys::parsePattern(QString pattern) const
void AWKeys::setDataBySource(const QString &sourceName, const QVariantMap &data) void AWKeys::setDataBySource(const QString &sourceName, const QVariantMap &data)
{ {
qCDebug(LOG_AW) << "Source" << sourceName; qCDebug(LOG_AW) << "Source" << sourceName << "with data" << data;
qCDebug(LOG_AW) << "Data" << data;
// first list init // first list init
QStringList tags = aggregator->keysFromSource(sourceName); QStringList tags = aggregator->keysFromSource(sourceName);
if (tags.isEmpty()) if (tags.isEmpty())
tags = aggregator->registerSource(sourceName, tags = aggregator->registerSource(
data[QString("units")].toString()); sourceName, data[QString("units")].toString(), m_requiredKeys);
// 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()) { if (tags.isEmpty()) {
qCDebug(LOG_AW) << "Source" << sourceName << "not found"; qCInfo(LOG_AW) << "Source" << sourceName << "not found";
emit(dropSourceFromDataengine(sourceName)); return emit(dropSourceFromDataengine(sourceName));
} else { }
#ifdef BUILD_FUTURE
m_mutex.lock(); m_mutex.lock();
#endif /* BUILD_FUTURE */ // HACK workaround for time values which are stored in the different path
// HACK workaround for time values which are stored in the different std::for_each(tags.cbegin(), tags.cend(),
// path [this, &data, &sourceName](const QString &tag) {
QVariant value = sourceName == QString("Local") values[tag] = sourceName == QString("Local")
? data[QString("DateTime")] ? data[QString("DateTime")]
: data[QString("value")]; : data[QString("value")];
std::for_each(tags.cbegin(), tags.cend(),
[this, value](const QString tag) {
values[tag] = aggregator->formater(value, tag);
}); });
#ifdef BUILD_FUTURE
m_mutex.unlock(); m_mutex.unlock();
#endif /* BUILD_FUTURE */
}
} }

View File

@ -24,17 +24,11 @@
#include <QMutex> #include <QMutex>
#include <QObject> #include <QObject>
#include "extitemaggregator.h"
class AWDataAggregator; class AWDataAggregator;
class AWDataEngineAggregator; class AWDataEngineAggregator;
class AWKeyOperations;
class AWKeysAggregator; class AWKeysAggregator;
class ExtQuotes;
class ExtScript;
class ExtUpgrade;
class ExtWeather;
class GraphicalItem;
class QThreadPool; class QThreadPool;
class AWKeys : public QObject class AWKeys : public QObject
@ -46,10 +40,12 @@ public:
virtual ~AWKeys(); virtual ~AWKeys();
Q_INVOKABLE void initDataAggregator(const QVariantMap tooltipParams); Q_INVOKABLE void initDataAggregator(const QVariantMap tooltipParams);
Q_INVOKABLE void initKeys(const QString currentPattern, const int interval, Q_INVOKABLE void initKeys(const QString currentPattern, const int interval,
const int limit); const int limit, const bool optimize);
Q_INVOKABLE void setAggregatorProperty(const QString key, Q_INVOKABLE void setAggregatorProperty(const QString key,
const QVariant value); const QVariant value);
Q_INVOKABLE void setWrapNewLines(const bool wrap = false); 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(); Q_INVOKABLE void updateCache();
// keys // keys
Q_INVOKABLE QStringList dictKeys(const bool sorted = false, Q_INVOKABLE QStringList dictKeys(const bool sorted = false,
@ -62,7 +58,6 @@ public:
Q_INVOKABLE void editItem(const QString type); Q_INVOKABLE void editItem(const QString type);
public slots: public slots:
void addDevice(const QString source);
void dataUpdated(const QString &sourceName, void dataUpdated(const QString &sourceName,
const Plasma::DataEngine::Data &data); const Plasma::DataEngine::Data &data);
// dummy method required by DataEngine connections // dummy method required by DataEngine connections
@ -75,13 +70,11 @@ signals:
void needToBeUpdated(); void needToBeUpdated();
private slots: private slots:
void loadKeysFromCache(); void reinitKeys(const QStringList currentKeys);
void reinitKeys();
void updateTextData(); void updateTextData();
private: private:
// methods // methods
void addKeyToCache(const QString type, const QString key = QString(""));
void calculateValues(); void calculateValues();
QString parsePattern(QString pattern) const; QString parsePattern(QString pattern) const;
void setDataBySource(const QString &sourceName, const QVariantMap &data); void setDataBySource(const QString &sourceName, const QVariantMap &data);
@ -89,16 +82,12 @@ private:
AWDataAggregator *dataAggregator = nullptr; AWDataAggregator *dataAggregator = nullptr;
AWDataEngineAggregator *dataEngineAggregator = nullptr; AWDataEngineAggregator *dataEngineAggregator = nullptr;
AWKeysAggregator *aggregator = nullptr; AWKeysAggregator *aggregator = nullptr;
ExtItemAggregator<GraphicalItem> *graphicalItems = nullptr; AWKeyOperations *keyOperator = nullptr;
ExtItemAggregator<ExtQuotes> *extQuotes = nullptr;
ExtItemAggregator<ExtScript> *extScripts = nullptr;
ExtItemAggregator<ExtUpgrade> *extUpgrade = nullptr;
ExtItemAggregator<ExtWeather> *extWeather = nullptr;
// variables // variables
QHash<QString, QStringList> m_devices; QVariantMap m_tooltipParams;
QStringList m_foundBars, m_foundKeys, m_foundLambdas; QStringList m_foundBars, m_foundKeys, m_foundLambdas, m_requiredKeys;
QString m_pattern; QVariantHash values;
QHash<QString, QString> values; bool m_optimize = false;
bool m_wrapNewLines = false; bool m_wrapNewLines = false;
// multithread features // multithread features
QThreadPool *m_threadPool = nullptr; QThreadPool *m_threadPool = nullptr;

View File

@ -30,6 +30,23 @@ AWKeysAggregator::AWKeysAggregator(QObject *parent)
: QObject(parent) : QObject(parent)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
// default formaters
// memory
m_formater[QString("mem")] = Float;
m_formater[QString("memtotmb")] = IntegerFive;
m_formater[QString("memtotgb")] = Float;
// network
m_formater[QString("down")] = NetSmartFormat;
m_formater[QString("downkb")] = Integer;
m_formater[QString("downunits")] = NetSmartUnits;
m_formater[QString("up")] = NetSmartFormat;
m_formater[QString("upkb")] = Integer;
m_formater[QString("upunits")] = NetSmartUnits;
// swap
m_formater[QString("swap")] = Float;
m_formater[QString("swaptotmb")] = IntegerFive;
m_formater[QString("swaptotgb")] = Float;
} }
@ -42,8 +59,7 @@ AWKeysAggregator::~AWKeysAggregator()
QString AWKeysAggregator::formater(const QVariant &data, QString AWKeysAggregator::formater(const QVariant &data,
const QString &key) const const QString &key) const
{ {
qCDebug(LOG_AW) << "Data" << data; qCDebug(LOG_AW) << "Data" << data << "for key" << key;
qCDebug(LOG_AW) << "Key" << key;
QString output; QString output;
QLocale loc = m_translate ? QLocale::system() : QLocale::c(); QLocale loc = m_translate ? QLocale::system() : QLocale::c();
@ -58,6 +74,9 @@ QString AWKeysAggregator::formater(const QVariant &data,
case Integer: case Integer:
output = QString("%1").arg(data.toFloat(), 4, 'f', 0); output = QString("%1").arg(data.toFloat(), 4, 'f', 0);
break; break;
case IntegerFive:
output = QString("%1").arg(data.toFloat(), 5, 'f', 0);
break;
case IntegerThree: case IntegerThree:
output = QString("%1").arg(data.toFloat(), 3, 'f', 0); output = QString("%1").arg(data.toFloat(), 3, 'f', 0);
break; break;
@ -102,7 +121,7 @@ QString AWKeysAggregator::formater(const QVariant &data,
case TimeCustom: case TimeCustom:
output = m_customTime; output = m_customTime;
[&output, loc, this](const QDateTime dt) { [&output, loc, this](const QDateTime dt) {
foreach (QString key, timeKeys) for (auto key : timeKeys)
output.replace(QString("$%1").arg(key), loc.toString(dt, key)); output.replace(QString("$%1").arg(key), loc.toString(dt, key));
}(data.toDateTime()); }(data.toDateTime());
break; break;
@ -135,12 +154,14 @@ QString AWKeysAggregator::formater(const QVariant &data,
return source; return source;
}(m_formater[key] == Uptime ? QString("$ddd$hhh$mmm") }(m_formater[key] == Uptime ? QString("$ddd$hhh$mmm")
: m_customUptime, : m_customUptime,
data.toFloat()); static_cast<int>(data.toFloat()));
break; break;
case NoFormat: case NoFormat:
default:
output = data.toString(); output = data.toString();
break; break;
default:
output = QString();
break;
} }
return output; return output;
@ -214,10 +235,10 @@ void AWKeysAggregator::setTranslate(const bool translate)
// HACK units required to define should the value be calculated as temperature // HACK units required to define should the value be calculated as temperature
// or fan data // or fan data
QStringList AWKeysAggregator::registerSource(const QString &source, QStringList AWKeysAggregator::registerSource(const QString &source,
const QString &units) const QString &units,
const QStringList &keys)
{ {
qCDebug(LOG_AW) << "Source" << source; qCDebug(LOG_AW) << "Source" << source << "with units" << units;
qCDebug(LOG_AW) << "Units" << units;
// regular expressions // regular expressions
QRegExp cpuRegExp = QRegExp(QString("cpu/cpu.*/TotalLoad")); QRegExp cpuRegExp = QRegExp(QString("cpu/cpu.*/TotalLoad"));
@ -316,6 +337,9 @@ QStringList AWKeysAggregator::registerSource(const QString &source,
QString key = QString("hdd%1").arg(index); QString key = QString("hdd%1").arg(index);
m_map[source] = key; m_map[source] = key;
m_formater[key] = Float; m_formater[key] = Float;
// additional keys
m_formater[QString("hddtotmb%1").arg(index)] = IntegerFive;
m_formater[QString("hddtotgb%1").arg(index)] = Float;
} }
} else if (source.contains(mountFreeRegExp)) { } else if (source.contains(mountFreeRegExp)) {
// free space // free space
@ -512,6 +536,19 @@ QStringList AWKeysAggregator::registerSource(const QString &source,
m_formater[key] = Temperature; m_formater[key] = Temperature;
} }
// drop key from dictionary if no one user requested key required it
QStringList foundKeys = keysFromSource(source);
qCInfo(LOG_AW) << "Looking for keys" << foundKeys << "in" << keys;
// this source is required if list is empty (which means skip checking)
// or if key in required key list
bool required
= keys.isEmpty() || std::any_of(foundKeys.cbegin(), foundKeys.cend(),
[&keys](const QString &key) {
return keys.contains(key);
});
if (!required)
m_map.remove(source);
return keysFromSource(source); return keysFromSource(source);
} }
@ -523,17 +560,17 @@ float AWKeysAggregator::temperature(const float temp) const
float converted = temp; float converted = temp;
if (m_tempUnits == QString("Celsius")) { if (m_tempUnits == QString("Celsius")) {
} else if (m_tempUnits == QString("Fahrenheit")) { } else if (m_tempUnits == QString("Fahrenheit")) {
converted = temp * 9.0 / 5.0 + 32.0; converted = temp * 9.0f / 5.0f + 32.0f;
} else if (m_tempUnits == QString("Kelvin")) { } else if (m_tempUnits == QString("Kelvin")) {
converted = temp + 273.15; converted = temp + 273.15f;
} else if (m_tempUnits == QString("Reaumur")) { } else if (m_tempUnits == QString("Reaumur")) {
converted = temp * 0.8; converted = temp * 0.8f;
} else if (m_tempUnits == QString("cm^-1")) { } else if (m_tempUnits == QString("cm^-1")) {
converted = (temp + 273.15) * 0.695; converted = (temp + 273.15f) * 0.695f;
} else if (m_tempUnits == QString("kJ/mol")) { } else if (m_tempUnits == QString("kJ/mol")) {
converted = (temp + 273.15) * 8.31; converted = (temp + 273.15f) * 8.31f;
} else if (m_tempUnits == QString("kcal/mol")) { } else if (m_tempUnits == QString("kcal/mol")) {
converted = (temp + 273.15) * 1.98; converted = (temp + 273.15f) * 1.98f;
} else { } else {
qCWarning(LOG_AW) << "Invalid units" << m_tempUnits; qCWarning(LOG_AW) << "Invalid units" << m_tempUnits;
} }

View File

@ -42,6 +42,7 @@ class AWKeysAggregator : public QObject
Float, Float,
FloatTwoSymbols, FloatTwoSymbols,
Integer, Integer,
IntegerFive,
IntegerThree, IntegerThree,
List, List,
// unit specific formaters // unit specific formaters
@ -77,7 +78,8 @@ public:
void setTranslate(const bool translate); void setTranslate(const bool translate);
public slots: public slots:
QStringList registerSource(const QString &source, const QString &units); QStringList registerSource(const QString &source, const QString &units,
const QStringList &keys);
private: private:
float temperature(const float temp) const; float temperature(const float temp) const;

View File

@ -0,0 +1,295 @@
/***************************************************************************
* 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 <QJSEngine>
#include <QRegularExpression>
#include "awdebug.h"
#include "awkeysaggregator.h"
QString AWPatternFunctions::expandLambdas(QString code,
AWKeysAggregator *aggregator,
const QVariantHash &metadata,
const QStringList &usedKeys)
{
qCDebug(LOG_AW) << "Expand lamdas in" << code;
QJSEngine engine;
// apply $this values
code.replace(QString("$this"), metadata[code].toString());
// parsed values
for (auto lambdaKey : usedKeys)
code.replace(QString("$%1").arg(lambdaKey),
aggregator->formater(metadata[lambdaKey], lambdaKey));
qCInfo(LOG_AW) << "Expression" << code;
QJSValue result = engine.evaluate(code);
if (result.isError()) {
qCWarning(LOG_AW) << "Uncaught exception at line"
<< result.property("lineNumber").toInt() << ":"
<< result.toString();
return QString();
} else {
return result.toString();
}
}
QString AWPatternFunctions::expandTemplates(QString code)
{
qCDebug(LOG_AW) << "Expand templates in" << code;
// match the following construction $template{{some code here}}
QRegularExpression templatesRegexp(
QString("\\$template\\{\\{(?<body>.*?)\\}\\}"));
templatesRegexp.setPatternOptions(
QRegularExpression::DotMatchesEverythingOption);
QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(code);
while (it.hasNext()) {
QRegularExpressionMatch match = it.next();
QString body = match.captured(QString("body"));
QJSEngine engine;
qCInfo(LOG_AW) << "Expression" << body;
QJSValue result = engine.evaluate(body);
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(match.captured(), templateResult);
}
return code;
}
QVariantList AWPatternFunctions::findFunctionCalls(const QString function,
const QString code)
{
qCDebug(LOG_AW) << "Looking for function" << function << "in" << code;
// I suggest the following regex for the internal functions
// $aw_function_name<some args here if any>{{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\\<(?<args>.*?)\\>\\{\\{(?<body>.*?)\\}\\}")
.arg(function));
regex.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
QVariantList foundFunctions;
QRegularExpressionMatchIterator it = regex.globalMatch(code);
while (it.hasNext()) {
QRegularExpressionMatch match = it.next();
QVariantHash metadata;
// 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);
}
return foundFunctions;
}
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;
}
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 key names 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;
}
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("\\$\\{\\{(?<body>.*?)\\}\\}"));
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;
}

View File

@ -0,0 +1,47 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWPATTERNFUNCTIONS_H
#define AWPATTERNFUNCTIONS_H
#include <QString>
#include <QVariant>
class AWKeysAggregator;
namespace AWPatternFunctions
{
// insert methods
QString expandLambdas(QString code, AWKeysAggregator *aggregator,
const QVariantHash &metadata,
const QStringList &usedKeys);
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);
};
#endif /* AWPATTERNFUNCTIONS_H */

View File

@ -0,0 +1,188 @@
/***************************************************************************
* 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 "awupdatehelper.h"
#include <KI18n/KLocalizedString>
#include <QtConcurrent/QtConcurrent>
#include <QDesktopServices>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QSettings>
#include "awdebug.h"
#include "version.h"
AWUpdateHelper::AWUpdateHelper(QObject *parent)
: QObject(parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_foundVersion = QVersionNumber::fromString(VERSION);
m_genericConfig = QString("%1/awesomewidgets/general.ini")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation));
}
AWUpdateHelper::~AWUpdateHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWUpdateHelper::checkUpdates(const bool showAnyway)
{
qCDebug(LOG_AW) << "Show anyway" << showAnyway;
// showAnyway options requires to show message if no updates found on direct
// request. In case of automatic check no message will be shown
QNetworkAccessManager *manager = new QNetworkAccessManager(nullptr);
connect(manager, &QNetworkAccessManager::finished,
[showAnyway, this](QNetworkReply *reply) {
return versionReplyRecieved(reply, showAnyway);
});
manager->get(QNetworkRequest(QUrl(VERSION_API)));
}
bool AWUpdateHelper::checkVersion()
{
QSettings settings(m_genericConfig, QSettings::IniFormat);
QVersionNumber version = QVersionNumber::fromString(
settings.value(QString("Version"), QString(VERSION)).toString());
// update version
settings.setValue(QString("Version"), QString(VERSION));
settings.sync();
qCInfo(LOG_AW) << "Found version" << version << "actual one is" << VERSION;
if (version != QVersionNumber::fromString(VERSION)) {
genMessageBox(i18n("Changelog of %1", QString(VERSION)),
QString(CHANGELOG).replace(QChar('@'), QChar('\n')),
QMessageBox::Ok)
->open();
return true;
} else {
qCInfo(LOG_AW) << "No need to update version";
}
return false;
}
void AWUpdateHelper::showInfo(const QVersionNumber version)
{
qCDebug(LOG_AW) << "Version" << version;
QString text
= i18n("You are using the actual version %1", version.toString());
if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(QString(COMMIT_SHA));
return genMessageBox(i18n("No new version found"), text, QMessageBox::Ok)
->open();
}
void AWUpdateHelper::showUpdates(const QVersionNumber version)
{
qCDebug(LOG_AW) << "Version" << version;
QString text;
text += i18n("Current version : %1", QString(VERSION));
text += QString(COMMIT_SHA).isEmpty()
? QString("\n")
: QString(" (%1)\n").arg(QString(COMMIT_SHA));
text += i18n("New version : %1", version.toString()) + QString("\n\n");
text += i18n("Click \"Ok\" to download");
genMessageBox(i18n("There are updates"), text,
QMessageBox::Ok | QMessageBox::Cancel)
->open(this, SLOT(userReplyOnUpdates(QAbstractButton *)));
}
void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *button)
{
int ret = static_cast<QMessageBox *>(sender())->buttonRole(button);
qCInfo(LOG_AW) << "User select" << ret;
switch (ret) {
case QMessageBox::Ok:
QDesktopServices::openUrl(QString(RELEASES)
+ m_foundVersion.toString());
break;
case QMessageBox::Cancel:
default:
break;
}
}
void AWUpdateHelper::versionReplyRecieved(QNetworkReply *reply,
const bool 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);
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();
QString version = firstRelease[QString("tag_name")].toString();
version.remove(QString("V."));
m_foundVersion = QVersionNumber::fromString(version);
qCInfo(LOG_AW) << "Update found version to" << m_foundVersion;
QVersionNumber oldVersion = QVersionNumber::fromString(VERSION);
if (oldVersion < m_foundVersion)
return showUpdates(m_foundVersion);
else if (showAnyway)
return showInfo(m_foundVersion);
}
// additional method which is used to show message box which does not block UI
QMessageBox *
AWUpdateHelper::genMessageBox(const QString title, const QString body,
const QMessageBox::StandardButtons buttons)
{
qCDebug(LOG_AW) << "Construct message box with title" << title << "and body"
<< body;
QMessageBox *msgBox = new QMessageBox(nullptr);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setModal(false);
msgBox->setWindowTitle(title);
msgBox->setText(body);
msgBox->setStandardButtons(buttons);
msgBox->setIcon(QMessageBox::Information);
return msgBox;
}

View File

@ -0,0 +1,53 @@
/***************************************************************************
* 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 AWUPDATEHELPER_H
#define AWUPDATEHELPER_H
#include <QMessageBox>
#include <QObject>
#include <QVersionNumber>
class QNetworkReply;
class AWUpdateHelper : public QObject
{
Q_OBJECT
public:
explicit AWUpdateHelper(QObject *parent = nullptr);
virtual ~AWUpdateHelper();
void checkUpdates(const bool showAnyway = false);
bool checkVersion();
private slots:
void showInfo(const QVersionNumber version);
void showUpdates(const QVersionNumber version);
void userReplyOnUpdates(QAbstractButton *button);
void versionReplyRecieved(QNetworkReply *reply, const bool showAnyway);
private:
QMessageBox *genMessageBox(const QString title, const QString body,
const QMessageBox::StandardButtons buttons);
QVersionNumber m_foundVersion;
QString m_genericConfig;
};
#endif /* AWUPDATEHELPER_H */

View File

@ -13,6 +13,8 @@ include_directories(
file(GLOB SUBPROJECT_SOURCE *.cpp ${PROJECT_TRDPARTY_DIR}/qreplytimeout/*.cpp ${CMAKE_SOURCE_DIR}/*.cpp) file(GLOB SUBPROJECT_SOURCE *.cpp ${PROJECT_TRDPARTY_DIR}/qreplytimeout/*.cpp ${CMAKE_SOURCE_DIR}/*.cpp)
file(GLOB SUBPROJECT_HEADER *.h ${PROJECT_TRDPARTY_DIR}/qreplytimeout/*.h) file(GLOB SUBPROJECT_HEADER *.h ${PROJECT_TRDPARTY_DIR}/qreplytimeout/*.h)
file(GLOB SUBPROJECT_UI *.ui) file(GLOB SUBPROJECT_UI *.ui)
file(GLOB SUBPROJECT_INI *.ini)
set(SUBPROJECT_CONFIGS ${CMAKE_CURRENT_SOURCE_DIR}/configs)
set(SUBPROJECT_GRAPHITEMS ${CMAKE_CURRENT_SOURCE_DIR}/desktops) set(SUBPROJECT_GRAPHITEMS ${CMAKE_CURRENT_SOURCE_DIR}/desktops)
set(SUBPROJECT_QUOTES ${CMAKE_CURRENT_SOURCE_DIR}/quotes) set(SUBPROJECT_QUOTES ${CMAKE_CURRENT_SOURCE_DIR}/quotes)
set(SUBPROJECT_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/scripts) set(SUBPROJECT_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/scripts)
@ -29,9 +31,11 @@ add_library(${SUBPROJECT} STATIC ${SUBPROJECT_SOURCE} ${SUBPROJECT_HEADER} ${SUB
target_link_libraries(${SUBPROJECT} ${Qt_LIBRARIES} ${Kf5_LIBRARIES}) target_link_libraries(${SUBPROJECT} ${Qt_LIBRARIES} ${Kf5_LIBRARIES})
# install # install
install(DIRECTORY ${SUBPROJECT_CONFIGS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_GRAPHITEMS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_GRAPHITEMS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_QUOTES} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_QUOTES} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_SCRIPTS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_SCRIPTS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_UPGRADE} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_UPGRADE} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_WEATHER} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}) install(DIRECTORY ${SUBPROJECT_WEATHER} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(FILES ${SUBPROJECT_INI} DESTINATION ${CONFIG_INSTALL_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/weather) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/weather)

View File

@ -24,6 +24,7 @@
#include "awdebug.h" #include "awdebug.h"
#include "version.h" #include "version.h"
#include "abstractextitemaggregator.h"
AbstractExtItem::AbstractExtItem(QWidget *parent, const QString desktopName, AbstractExtItem::AbstractExtItem(QWidget *parent, const QString desktopName,
@ -33,8 +34,9 @@ AbstractExtItem::AbstractExtItem(QWidget *parent, const QString desktopName,
, m_dirs(directories) , m_dirs(directories)
{ {
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; 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; m_name = m_fileName;
} }
@ -46,10 +48,13 @@ AbstractExtItem::~AbstractExtItem()
} }
template <class T> T *AbstractExtItem::copy(const QString, const int) void AbstractExtItem::copyDefaults(AbstractExtItem *_other) const
{ {
// an analog of pure virtual method _other->setActive(m_active);
return new T(); _other->setApiVersion(m_apiVersion);
_other->setComment(m_comment);
_other->setInterval(m_interval);
_other->setName(m_name);
} }
@ -193,14 +198,14 @@ void AbstractExtItem::readConfiguration()
bool AbstractExtItem::tryDelete() const 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)); bool status = QFile::remove(QString("%1/%2").arg(dir).arg(m_fileName));
qCInfo(LOG_LIB) << "Remove file" qCInfo(LOG_LIB) << "Remove file"
<< QString("%1/%2").arg(dir).arg(m_fileName) << status; << QString("%1/%2").arg(dir).arg(m_fileName) << status;
} }
// check if exists // check if exists
foreach (QString dir, m_dirs) for (auto dir : m_dirs)
if (QFile::exists(QString("%1/%2").arg(dir).arg(m_fileName))) if (QFile::exists(QString("%1/%2").arg(dir).arg(m_fileName)))
return false; return false;
return true; return true;

View File

@ -40,7 +40,9 @@ public:
const QString desktopName = QString(), const QString desktopName = QString(),
const QStringList directories = QStringList()); const QStringList directories = QStringList());
virtual ~AbstractExtItem(); virtual ~AbstractExtItem();
template <class T> T *copy(const QString, const int); virtual AbstractExtItem *copy(const QString _fileName, const int _number)
= 0;
void copyDefaults(AbstractExtItem *_other) const;
// get methods // get methods
int apiVersion() const; int apiVersion() const;
QString comment() const; QString comment() const;

View File

@ -91,10 +91,8 @@ void AbstractExtItemAggregator::setConfigArgs(const QVariant _configArgs)
} }
void AbstractExtItemAggregator::editItemActivated(QListWidgetItem *item) void AbstractExtItemAggregator::editItemActivated(QListWidgetItem *)
{ {
Q_UNUSED(item)
return editItem(); return editItem();
} }

View File

@ -48,7 +48,7 @@ public:
void setConfigArgs(const QVariant _configArgs); void setConfigArgs(const QVariant _configArgs);
private slots: private slots:
void editItemActivated(QListWidgetItem *item); void editItemActivated(QListWidgetItem *);
void editItemButtonPressed(QAbstractButton *button); void editItemButtonPressed(QAbstractButton *button);
private: private:

View File

@ -1,139 +1,113 @@
{ {
"__url": "http://openweathermap.org/weather-conditions", "__url": "https://developer.yahoo.com/weather/documentation.html",
"image": { "image": {
"__comment": "should be described as html image with full path inside", "__comment": "should be described as html image with full path inside",
"default": "", "default": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/3200.gif\">",
"800": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/01d.png\">", "0": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/0.gif\">",
"1": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/1.gif\">",
"801": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/02d.png\">", "2": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/2.gif\">",
"3": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/3.gif\">",
"802": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/03d.png\">", "4": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/4.gif\">",
"803": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/03d.png\">", "5": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/5.gif\">",
"6": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/6.gif\">",
"804": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/04d.png\">", "7": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/7.gif\">",
"8": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/8.gif\">",
"300": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "9": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/9.gif\">",
"301": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "10": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10.gif\">",
"302": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "11": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11.gif\">",
"310": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "12": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/12.gif\">",
"311": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "13": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13.gif\">",
"312": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "14": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/14.gif\">",
"313": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "15": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/15.gif\">",
"314": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "16": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/16.gif\">",
"321": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "17": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/17.gif\">",
"520": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "18": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/18.gif\">",
"521": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "19": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/19.gif\">",
"522": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "20": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/20.gif\">",
"531": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">", "21": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/21.gif\">",
"22": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/22.gif\">",
"500": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">", "23": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/23.gif\">",
"501": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">", "24": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/24.gif\">",
"502": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">", "25": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/25.gif\">",
"503": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">", "26": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/26.gif\">",
"504": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">", "27": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/27.gif\">",
"28": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/28.gif\">",
"200": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "29": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/29.gif\">",
"201": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "30": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/30.gif\">",
"202": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "31": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/31.gif\">",
"210": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "32": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/32.gif\">",
"211": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "33": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/33.gif\">",
"212": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "34": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/34.gif\">",
"221": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "35": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/35.gif\">",
"230": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "36": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/36.gif\">",
"231": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "37": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/37.gif\">",
"232": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">", "38": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/38.gif\">",
"39": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/39.gif\">",
"511": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">", "40": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/40.gif\">",
"600": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">", "41": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/41.gif\">",
"601": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">", "42": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/42.gif\">",
"602": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">", "43": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/43.gif\">",
"611": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">", "44": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/44.gif\">",
"612": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">", "45": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/45.gif\">",
"615": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">", "46": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/46.gif\">",
"616": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">", "47": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/47.gif\">",
"620": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">", "3200": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/3200.gif\">"
"621": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"622": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"701": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"711": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"721": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"731": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"741": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"751": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"761": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"762": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"771": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"781": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">"
}, },
"text": { "text": {
"default": "\u2604", "default": "\u2604",
"3200": "\u2604",
"800": "\u2600", "0": "\u2604",
"1": "\u2604",
"801": "\u26C5", "2": "\u2604",
"3": "\u26C8",
"802": "\u2601", "4": "\u26C8",
"803": "\u2601", "5": "\u2614",
"6": "\u2614",
"804": "\u2601", "7": "\u2614",
"8": "\u2614",
"300": "\u2602", "9": "\u2614",
"301": "\u2602", "10": "\u2614",
"302": "\u2602", "11": "\u2614",
"310": "\u2602", "12": "\u2614",
"311": "\u2602", "13": "\u26C4",
"312": "\u2602", "14": "\u26C7",
"313": "\u2602", "15": "\u26C7",
"314": "\u2602", "16": "\u2614",
"321": "\u2602", "17": "\u2614",
"520": "\u2602", "18": "\u2614",
"521": "\u2602", "19": "\u26C5",
"522": "\u2602", "20": "\u26C5",
"531": "\u2602", "21": "\u26C5",
"22": "\u26C5",
"500": "\u2614", "23": "\u26C5",
"501": "\u2614", "24": "\u26C5",
"502": "\u2614", "25": "\u26C5",
"503": "\u2614", "26": "\u2601",
"504": "\u2614", "27": "\u2601",
"28": "\u2601",
"200": "\u2608", "29": "\u2601",
"201": "\u2608", "30": "\u2601",
"202": "\u2608", "31": "\u263D",
"210": "\u2608", "32": "\u2600",
"211": "\u2608", "33": "\u263D",
"212": "\u2608", "34": "\u2600",
"221": "\u2608", "35": "\u2614",
"230": "\u2608", "36": "\u2600",
"231": "\u2608", "37": "\u26C8",
"232": "\u2608", "38": "\u26C8",
"39": "\u26C8",
"511": "\u2603", "40": "\u26C7",
"600": "\u2603", "41": "\u26C7",
"601": "\u2603", "42": "\u26C7",
"602": "\u2603", "43": "\u26C7",
"611": "\u2603", "44": "\u2601",
"612": "\u2603", "45": "\u26C8",
"615": "\u2603", "46": "\u26C7",
"616": "\u2603", "47": "\u26C8"
"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"
} }
} }

View File

@ -0,0 +1,41 @@
[plasmoid]
acOffline=( )
acOnline=(*)
background=true
batInTooltipColor=#880000
batTooltip=true
batTooltipColor=#008800
checkUpdates=true
cpuTooltip=true
cpuTooltipColor=#ff0000
cpuclTooltip=true
cpuclTooltipColor=#00ff00
customTime=$hh:$mm
customUptime="$dd,$hh,$mm"
downkbTooltip=true
downkbTooltipColor=#00ffff
fontColor=#000000
fontFamily=Terminus
fontSize=12
fontStyle=normal
fontWeight=normal
height=0
interval=1000
memTooltip=true
memTooltipColor=#0000ff
notify=true
optimize=true
queueLimit=0
swapTooltip=true
swapTooltipColor=#ffff00
tempUnits=Celsius
text=[cpu: $cpu%] [mem: $mem%] [swap: $swap%] [$netdev: $down/$upKB/s]
textAlign=center
tooltipBackground=#ffffff
tooltipNumber=100
translateStrings=true
upkbTooltipColor=#ff00ff
useTooltipBackground=true
width=0
wrapNewLines=false
wrapText=false

View File

@ -3,11 +3,14 @@ Encoding=UTF-8
Name=bar3 Name=bar3
Comment=Simple bat bar Comment=Simple bat bar
X-AW-Value=bat X-AW-Value=bat
X-AW-Custom=false
X-AW-Max=100.0
X-AW-Min=0.0
X-AW-ActiveColor="0,0,0,255" X-AW-ActiveColor="0,0,0,255"
X-AW-InactiveColor="255,255,255,255" X-AW-InactiveColor="255,255,255,255"
X-AW-Type=Horizontal X-AW-Type=Horizontal
X-AW-Direction=LeftToRight X-AW-Direction=LeftToRight
X-AW-Height=25 X-AW-Height=25
X-AW-Width=100 X-AW-Width=100
X-AW-ApiVersion=3 X-AW-ApiVersion=4
X-AW-Number=3 X-AW-Number=3

View File

@ -3,11 +3,14 @@ Encoding=UTF-8
Name=bar0 Name=bar0
Comment=Simple cpu bar Comment=Simple cpu bar
X-AW-Value=cpu X-AW-Value=cpu
X-AW-Custom=false
X-AW-Max=100.0
X-AW-Min=0.0
X-AW-ActiveColor="0,0,0,255" X-AW-ActiveColor="0,0,0,255"
X-AW-InactiveColor="255,255,255,255" X-AW-InactiveColor="255,255,255,255"
X-AW-Type=Horizontal X-AW-Type=Horizontal
X-AW-Direction=LeftToRight X-AW-Direction=LeftToRight
X-AW-Height=25 X-AW-Height=25
X-AW-Width=100 X-AW-Width=100
X-AW-ApiVersion=3 X-AW-ApiVersion=4
X-AW-Number=0 X-AW-Number=0

View File

@ -3,11 +3,14 @@ Encoding=UTF-8
Name=bar1 Name=bar1
Comment=Simple mem bar Comment=Simple mem bar
X-AW-Value=mem X-AW-Value=mem
X-AW-Custom=false
X-AW-Max=100.0
X-AW-Min=0.0
X-AW-ActiveColor="0,0,0,255" X-AW-ActiveColor="0,0,0,255"
X-AW-InactiveColor="255,255,255,255" X-AW-InactiveColor="255,255,255,255"
X-AW-Type=Horizontal X-AW-Type=Horizontal
X-AW-Direction=LeftToRight X-AW-Direction=LeftToRight
X-AW-Height=25 X-AW-Height=25
X-AW-Width=100 X-AW-Width=100
X-AW-ApiVersion=3 X-AW-ApiVersion=4
X-AW-Number=1 X-AW-Number=1

View File

@ -3,11 +3,14 @@ Encoding=UTF-8
Name=bar2 Name=bar2
Comment=Simple swap bar Comment=Simple swap bar
X-AW-Value=swap X-AW-Value=swap
X-AW-Custom=false
X-AW-Max=100.0
X-AW-Min=0.0
X-AW-ActiveColor="0,0,0,255" X-AW-ActiveColor="0,0,0,255"
X-AW-InactiveColor="255,255,255,255" X-AW-InactiveColor="255,255,255,255"
X-AW-Type=Horizontal X-AW-Type=Horizontal
X-AW-Direction=LeftToRight X-AW-Direction=LeftToRight
X-AW-Height=25 X-AW-Height=25
X-AW-Width=100 X-AW-Width=100
X-AW-ApiVersion=3 X-AW-ApiVersion=4
X-AW-Number=2 X-AW-Number=2

View File

@ -37,8 +37,9 @@ public:
{ {
qSetMessagePattern(LOG_FORMAT); qSetMessagePattern(LOG_FORMAT);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
foreach (const QString metadata, getBuildData()) for (auto metadata : getBuildData())
qCDebug(LOG_LIB) << metadata; qCDebug(LOG_LIB) << metadata;
qCDebug(LOG_LIB) << "Type" << type; qCDebug(LOG_LIB) << "Type" << type;
initItems(); initItems();
@ -61,13 +62,13 @@ public:
qCInfo(LOG_LIB) << "Dialog returns" << ret; qCInfo(LOG_LIB) << "Dialog returns" << ret;
}; };
T *itemByTag(const QString _tag) const T *itemByTag(const QString _tag, const QString _type) const
{ {
qCDebug(LOG_LIB) << "Tag" << _tag; qCDebug(LOG_LIB) << "Tag" << _tag << "with used type" << _type;
T *found = nullptr; T *found = nullptr;
foreach (T *item, m_items) { for (auto item : m_items) {
if (item->tag() != _tag) if (item->tag(_type) != _tag)
continue; continue;
found = item; found = item;
break; break;
@ -83,7 +84,7 @@ public:
qCDebug(LOG_LIB) << "Number" << _number; qCDebug(LOG_LIB) << "Number" << _number;
T *found = nullptr; T *found = nullptr;
foreach (T *item, m_items) { for (auto item : m_items) {
if (item->number() != _number) if (item->number() != _number)
continue; continue;
found = item; found = item;
@ -102,7 +103,7 @@ public:
return nullptr; return nullptr;
T *found = nullptr; T *found = nullptr;
foreach (T *item, m_items) { for (auto item : m_items) {
if (item->fileName() != widgetItem->text()) if (item->fileName() != widgetItem->text())
continue; continue;
found = item; found = item;
@ -120,7 +121,7 @@ public:
int uniqNumber() const int uniqNumber() const
{ {
QList<int> tagList; QList<int> tagList;
foreach (T *item, m_items) for (auto item : m_items)
tagList.append(item->number()); tagList.append(item->number());
int number = 0; int number = 0;
while (tagList.contains(number)) while (tagList.contains(number))
@ -152,9 +153,9 @@ private:
QStandardPaths::LocateDirectory); QStandardPaths::LocateDirectory);
QStringList names; QStringList names;
QList<T *> items; QList<T *> items;
foreach (QString dir, dirs) { for (auto dir : dirs) {
QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name); QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name);
foreach (QString file, files) { for (auto file : files) {
if ((!file.endsWith(QString(".desktop"))) if ((!file.endsWith(QString(".desktop")))
|| (names.contains(file))) || (names.contains(file)))
continue; continue;
@ -177,7 +178,7 @@ private:
m_activeItems.clear(); m_activeItems.clear();
m_items = getItems(); m_items = getItems();
foreach (T *item, m_items) { for (auto item : m_items) {
if (!item->isActive()) if (!item->isActive())
continue; continue;
m_activeItems.append(item); m_activeItems.append(item);
@ -187,7 +188,7 @@ private:
void repaint() void repaint()
{ {
widgetDialog->clear(); widgetDialog->clear();
foreach (T *_item, m_items) { for (auto _item : m_items) {
QListWidgetItem *item QListWidgetItem *item
= new QListWidgetItem(_item->fileName(), widgetDialog); = new QListWidgetItem(_item->fileName(), widgetDialog);
QStringList tooltip; QStringList tooltip;
@ -210,7 +211,7 @@ private:
return; return;
} }
T *newItem = source->copy(fileName, number); T *newItem = static_cast<T *>(source->copy(fileName, number));
if (newItem->showConfiguration(configArgs()) == 1) { if (newItem->showConfiguration(configArgs()) == 1) {
initItems(); initItems();
repaint(); repaint();

View File

@ -81,11 +81,7 @@ ExtQuotes *ExtQuotes::copy(const QString _fileName, const int _number)
ExtQuotes *item = new ExtQuotes(static_cast<QWidget *>(parent()), _fileName, ExtQuotes *item = new ExtQuotes(static_cast<QWidget *>(parent()), _fileName,
directories()); directories());
item->setActive(isActive()); copyDefaults(item);
item->setApiVersion(apiVersion());
item->setComment(comment());
item->setInterval(interval());
item->setName(name());
item->setNumber(_number); item->setNumber(_number);
item->setTicker(ticker()); item->setTicker(ticker());
@ -150,7 +146,7 @@ QVariantHash ExtQuotes::run()
qCInfo(LOG_LIB) << "Send request"; qCInfo(LOG_LIB) << "Send request";
isRunning = true; isRunning = true;
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url()))); QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url())));
new QReplyTimeout(reply, 1000); new QReplyTimeout(reply, REQUEST_TIMEOUT);
} }
// update value // update value
@ -208,8 +204,8 @@ void ExtQuotes::writeConfiguration() const
void ExtQuotes::quotesReplyReceived(QNetworkReply *reply) void ExtQuotes::quotesReplyReceived(QNetworkReply *reply)
{ {
qCDebug(LOG_LIB) << "Return code" << reply->error(); qCDebug(LOG_LIB) << "Return code" << reply->error() << "with message"
qCDebug(LOG_LIB) << "Reply error message" << reply->errorString(); << reply->errorString();
isRunning = false; isRunning = false;
QJsonParseError error; QJsonParseError error;
@ -279,8 +275,7 @@ get quotes for the instrument. Refer to <a href=\"http://finance.yahoo.com/\">\
QString ExtQuotes::url() const QString ExtQuotes::url() const
{ {
QString apiUrl = QString(YAHOO_URL); QString apiUrl = QString(YAHOO_QUOTES_URL).arg(m_ticker);
apiUrl.replace(QString("$TICKER"), m_ticker);
qCInfo(LOG_LIB) << "API url" << apiUrl; qCInfo(LOG_LIB) << "API url" << apiUrl;
return apiUrl; return apiUrl;

View File

@ -22,10 +22,10 @@
#include "abstractextitem.h" #include "abstractextitem.h"
#define YAHOO_URL \ #define YAHOO_QUOTES_URL \
"https://query.yahooapis.com/v1/public/yql?q=select * from " \ "https://query.yahooapis.com/v1/public/yql?q=select * from " \
"yahoo.finance.quotes where " \ "yahoo.finance.quotes where " \
"symbol=\"$TICKER\"&env=store://datatables.org/" \ "symbol=\"%1\"&env=store://datatables.org/" \
"alltableswithkeys&format=json" "alltableswithkeys&format=json"

View File

@ -64,17 +64,12 @@ ExtScript::~ExtScript()
ExtScript *ExtScript::copy(const QString _fileName, const int _number) ExtScript *ExtScript::copy(const QString _fileName, const int _number)
{ {
qCDebug(LOG_LIB) << "File" << _fileName; qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
qCDebug(LOG_LIB) << "Number" << _number;
ExtScript *item = new ExtScript(static_cast<QWidget *>(parent()), _fileName, ExtScript *item = new ExtScript(static_cast<QWidget *>(parent()), _fileName,
directories()); directories());
item->setActive(isActive()); copyDefaults(item);
item->setApiVersion(apiVersion());
item->setComment(comment());
item->setExecutable(executable()); item->setExecutable(executable());
item->setInterval(interval());
item->setName(name());
item->setNumber(_number); item->setNumber(_number);
item->setPrefix(prefix()); item->setPrefix(prefix());
item->setRedirect(redirect()); item->setRedirect(redirect());
@ -188,7 +183,7 @@ QString ExtScript::applyFilters(QString _value) const
{ {
qCDebug(LOG_LIB) << "Value" << _value; qCDebug(LOG_LIB) << "Value" << _value;
foreach (QString filt, m_filters) { for (auto filt : m_filters) {
qCInfo(LOG_LIB) << "Found filter" << filt; qCInfo(LOG_LIB) << "Found filter" << filt;
QVariantMap filter = jsonFilters[filt].toMap(); QVariantMap filter = jsonFilters[filt].toMap();
if (filter.isEmpty()) { if (filter.isEmpty()) {
@ -196,7 +191,7 @@ QString ExtScript::applyFilters(QString _value) const
<< "in the json"; << "in the json";
continue; continue;
} }
foreach (QString f, filter.keys()) for (auto f : filter.keys())
_value.replace(f, filter[f].toString()); _value.replace(f, filter[f].toString());
} }
@ -206,8 +201,7 @@ QString ExtScript::applyFilters(QString _value) const
void ExtScript::updateFilter(const QString _filter, const bool _add) void ExtScript::updateFilter(const QString _filter, const bool _add)
{ {
qCDebug(LOG_LIB) << "Filter" << _filter; qCDebug(LOG_LIB) << "Should be added filters" << _add << "from" << _filter;
qCDebug(LOG_LIB) << "Should be added" << _add;
if (_add) { if (_add) {
if (m_filters.contains(_filter)) if (m_filters.contains(_filter))

View File

@ -82,7 +82,6 @@ private:
QString m_prefix = QString(""); QString m_prefix = QString("");
Redirect m_redirect = nothing; Redirect m_redirect = nothing;
// internal properties // internal properties
Q_PID childProcess = 0;
QVariantMap jsonFilters = QVariantMap(); QVariantMap jsonFilters = QVariantMap();
int times = 0; int times = 0;
QVariantHash value; QVariantHash value;

View File

@ -60,18 +60,13 @@ ExtUpgrade::~ExtUpgrade()
ExtUpgrade *ExtUpgrade::copy(const QString _fileName, const int _number) ExtUpgrade *ExtUpgrade::copy(const QString _fileName, const int _number)
{ {
qCDebug(LOG_LIB) << "File" << _fileName; qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
qCDebug(LOG_LIB) << "Number" << _number;
ExtUpgrade *item = new ExtUpgrade(static_cast<QWidget *>(parent()), ExtUpgrade *item = new ExtUpgrade(static_cast<QWidget *>(parent()),
_fileName, directories()); _fileName, directories());
item->setActive(isActive()); copyDefaults(item);
item->setApiVersion(apiVersion());
item->setComment(comment());
item->setExecutable(executable()); item->setExecutable(executable());
item->setFilter(filter()); item->setFilter(filter());
item->setInterval(interval());
item->setName(name());
item->setNumber(_number); item->setNumber(_number);
item->setNull(null()); item->setNull(null());

View File

@ -74,19 +74,14 @@ ExtWeather::~ExtWeather()
ExtWeather *ExtWeather::copy(const QString _fileName, const int _number) ExtWeather *ExtWeather::copy(const QString _fileName, const int _number)
{ {
qCDebug(LOG_LIB) << "File" << _fileName; qCDebug(LOG_LIB) << "File" << _fileName << "number" << _number;
qCDebug(LOG_LIB) << "Number" << _number;
ExtWeather *item = new ExtWeather(static_cast<QWidget *>(parent()), ExtWeather *item = new ExtWeather(static_cast<QWidget *>(parent()),
_fileName, directories()); _fileName, directories());
item->setActive(isActive()); copyDefaults(item);
item->setApiVersion(apiVersion());
item->setCity(city()); item->setCity(city());
item->setComment(comment());
item->setCountry(country()); item->setCountry(country());
item->setInterval(interval());
item->setImage(image()); item->setImage(image());
item->setName(name());
item->setNumber(_number); item->setNumber(_number);
item->setTs(ts()); item->setTs(ts());
@ -235,9 +230,8 @@ QVariantHash ExtWeather::run()
if (times == 1) { if (times == 1) {
qCInfo(LOG_LIB) << "Send request"; qCInfo(LOG_LIB) << "Send request";
isRunning = true; isRunning = true;
QNetworkReply *reply QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url())));
= manager->get(QNetworkRequest(QUrl(url(m_ts != 0)))); new QReplyTimeout(reply, REQUEST_TIMEOUT);
new QReplyTimeout(reply, 1000);
} }
// update value // update value
@ -305,8 +299,8 @@ void ExtWeather::writeConfiguration() const
void ExtWeather::weatherReplyReceived(QNetworkReply *reply) void ExtWeather::weatherReplyReceived(QNetworkReply *reply)
{ {
qCDebug(LOG_LIB) << "Return code" << reply->error(); qCDebug(LOG_LIB) << "Return code" << reply->error() << "with message"
qCDebug(LOG_LIB) << "Reply error message" << reply->errorString(); << reply->errorString();
isRunning = false; isRunning = false;
QJsonParseError error; QJsonParseError error;
@ -319,51 +313,52 @@ void ExtWeather::weatherReplyReceived(QNetworkReply *reply)
} }
// convert to map // convert to map
QVariantMap json = jsonDoc.toVariant().toMap(); QVariantMap json = jsonDoc.toVariant().toMap()[QString("query")].toMap();
if (json[QString("cod")].toInt() != 200) { if (json[QString("count")].toInt() != 1) {
qCWarning(LOG_LIB) << "Invalid OpenWeatherMap return code" qCWarning(LOG_LIB) << "Found data count"
<< json[QString("cod")].toInt(); << json[QString("count")].toInt() << "is not 1";
return; return;
} }
QVariantMap results
= json[QString("results")].toMap()[QString("channel")].toMap();
QVariantMap item = results[QString("item")].toMap();
QVariantHash data;
if (m_ts == 0) { 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<int>(results[QString("atmosphere")]
.toMap()[QString("pressure")]
.toFloat());
} else { } else {
QVariantList list = json[QString("list")].toList(); // forecast weather
data = parseSingleJson(list.count() <= m_ts ? list.at(m_ts - 1).toMap() QVariantList weatherList = item[QString("forecast")].toList();
: list.last().toMap()); 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 +376,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); QString apiUrl = QString(YAHOO_WEATHER_URL).arg(m_city).arg(m_country);
apiUrl.replace(QString("$CITY"), m_city);
apiUrl.replace(QString("$COUNTRY"), m_country);
qCInfo(LOG_LIB) << "API url" << apiUrl; qCInfo(LOG_LIB) << "API url" << apiUrl;
return apiUrl; return apiUrl;

View File

@ -22,12 +22,10 @@
#include "abstractextitem.h" #include "abstractextitem.h"
#define OWM_URL \ #define YAHOO_WEATHER_URL \
"http://api.openweathermap.org/data/2.5/" \ "https://query.yahooapis.com/v1/public/yql?format=json&env=store://" \
"weather?q=$CITY,$COUNTRY&units=metric" "datatables.org/alltableswithkeys&q=select * from weather.forecast where " \
#define OWM_FORECAST_URL \ "u='c' and woeid in (select woeid from geo.places(1) where text='%1, %2')"
"http://api.openweathermap.org/data/2.5/" \
"forecast?q=$CITY,$COUNTRY&units=metric"
namespace Ui namespace Ui
@ -76,9 +74,8 @@ private:
QNetworkAccessManager *manager; QNetworkAccessManager *manager;
bool isRunning = false; bool isRunning = false;
Ui::ExtWeather *ui; Ui::ExtWeather *ui;
QVariantHash parseSingleJson(const QVariantMap json) const;
void translate(); void translate();
QString url(const bool isForecast = false) const; QString url() const;
// properties // properties
QString m_city = QString("London"); QString m_city = QString("London");
QString m_country = QString("uk"); QString m_country = QString("uk");

View File

@ -23,14 +23,13 @@
#include <QBuffer> #include <QBuffer>
#include <QColorDialog> #include <QColorDialog>
#include <QDir> #include <QDir>
#include <QGraphicsEllipseItem> #include <QFileDialog>
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QGraphicsView> #include <QGraphicsView>
#include <QSettings> #include <QSettings>
#include <math.h>
#include "awdebug.h" #include "awdebug.h"
#include "graphicalitemhelper.h"
#include "version.h" #include "version.h"
@ -47,10 +46,22 @@ GraphicalItem::GraphicalItem(QWidget *parent, const QString desktopName,
initScene(); initScene();
connect(ui->checkBox_custom, SIGNAL(stateChanged(int)), this,
SLOT(changeValue(int)));
connect(ui->checkBox_activeCheck, SIGNAL(stateChanged(int)), this,
SLOT(changeColorState(int)));
connect(ui->checkBox_inactiveCheck, SIGNAL(stateChanged(int)), this,
SLOT(changeColorState(int)));
connect(ui->comboBox_type, SIGNAL(currentIndexChanged(int)), this,
SLOT(changeCountState(int)));
connect(ui->pushButton_activeColor, SIGNAL(clicked()), this, connect(ui->pushButton_activeColor, SIGNAL(clicked()), this,
SLOT(changeColor())); SLOT(changeColor()));
connect(ui->pushButton_inactiveColor, SIGNAL(clicked()), this, connect(ui->pushButton_inactiveColor, SIGNAL(clicked()), this,
SLOT(changeColor())); SLOT(changeColor()));
connect(ui->pushButton_activeImage, SIGNAL(clicked()), this,
SLOT(changeImage()));
connect(ui->pushButton_inactiveImage, SIGNAL(clicked()), this,
SLOT(changeImage()));
} }
@ -60,62 +71,62 @@ GraphicalItem::~GraphicalItem()
delete m_scene; delete m_scene;
delete ui; delete ui;
delete m_helper;
} }
GraphicalItem *GraphicalItem::copy(const QString _fileName, const int _number) GraphicalItem *GraphicalItem::copy(const QString _fileName, const int _number)
{ {
qCDebug(LOG_LIB) << "File" << _fileName; qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
qCDebug(LOG_LIB) << "Number" << _number;
GraphicalItem *item = new GraphicalItem(static_cast<QWidget *>(parent()), GraphicalItem *item = new GraphicalItem(static_cast<QWidget *>(parent()),
_fileName, directories()); _fileName, directories());
item->setActive(isActive()); copyDefaults(item);
item->setActiveColor(activeColor()); item->setActiveColor(m_activeColor);
item->setApiVersion(apiVersion()); item->setBar(m_bar);
item->setBar(bar()); item->setCount(m_count);
item->setComment(comment()); item->setCustom(m_custom);
item->setDirection(direction()); item->setDirection(m_direction);
item->setHeight(height()); item->setHeight(m_height);
item->setInactiveColor(inactiveColor()); item->setInactiveColor(m_inactiveColor);
item->setInterval(interval()); item->setMaxValue(m_maxValue);
item->setName(QString("bar%1").arg(_number)); item->setMinValue(m_minValue);
item->setNumber(_number); item->setNumber(_number);
item->setType(type()); item->setType(m_type);
item->setWidth(width()); item->setWidth(m_width);
return item; return item;
} }
QString GraphicalItem::image(const QVariant value) QString GraphicalItem::image(const QVariant &value)
{ {
qCDebug(LOG_LIB) << "Value" << value; qCDebug(LOG_LIB) << "Value" << value;
if (m_bar == QString("none"))
return QString("");
m_scene->clear(); m_scene->clear();
int scale[2] = {1, 1}; int scale[2] = {1, 1};
float converted
= m_helper->getPercents(value.toFloat(), m_minValue, m_maxValue);
// paint // paint
switch (m_type) { switch (m_type) {
case Vertical: case Vertical:
paintVertical(value.toFloat()); m_helper->paintVertical(converted);
// scale // scale
scale[1] = -2 * static_cast<int>(m_direction) + 1; scale[1] = -2 * static_cast<int>(m_direction) + 1;
break; break;
case Circle: case Circle:
paintCircle(value.toFloat()); m_helper->paintCircle(converted);
// scale // scale
scale[0] = -2 * static_cast<int>(m_direction) + 1; scale[0] = -2 * static_cast<int>(m_direction) + 1;
break; break;
case Graph: case Graph:
paintGraph(value.value<QList<float>>()); m_helper->paintGraph(converted);
// direction option is not recognized by this GI type // direction option is not recognized by this GI type
break; break;
case Horizontal: case Horizontal:
default: default:
paintHorizontal(value.toFloat()); m_helper->paintHorizontal(converted);
// scale // scale
scale[0] = -2 * static_cast<int>(m_direction) + 1; scale[0] = -2 * static_cast<int>(m_direction) + 1;
break; break;
@ -152,9 +163,27 @@ QString GraphicalItem::inactiveColor() const
} }
QString GraphicalItem::tag() const int GraphicalItem::count() const
{ {
return QString("bar%1%2").arg(number()).arg(m_bar); return m_count;
}
bool GraphicalItem::isCustom() const
{
return m_custom;
}
float GraphicalItem::maxValue() const
{
return m_maxValue;
}
float GraphicalItem::minValue() const
{
return m_minValue;
} }
@ -216,6 +245,12 @@ int GraphicalItem::height() const
} }
QStringList GraphicalItem::usedKeys() const
{
return m_usedKeys;
}
int GraphicalItem::width() const int GraphicalItem::width() const
{ {
return m_width; return m_width;
@ -232,13 +267,7 @@ void GraphicalItem::setBar(const QString _bar)
{ {
qCDebug(LOG_LIB) << "Bar" << _bar; qCDebug(LOG_LIB) << "Bar" << _bar;
if (!_bar.contains(QRegExp(
QString("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)")))) {
qCWarning(LOG_LIB) << "Unsupported bar type" << _bar;
m_bar = QString("none");
} else {
m_bar = _bar; m_bar = _bar;
}
} }
@ -250,6 +279,24 @@ void GraphicalItem::setActiveColor(const QString _color)
} }
void GraphicalItem::setCount(const int _count)
{
qCDebug(LOG_LIB) << "Count" << _count;
if (_count <= 1)
return;
m_count = _count;
}
void GraphicalItem::setCustom(const bool _custom)
{
qCDebug(LOG_LIB) << "Use custom tag" << _custom;
m_custom = _custom;
}
void GraphicalItem::setInactiveColor(const QString _color) void GraphicalItem::setInactiveColor(const QString _color)
{ {
qCDebug(LOG_LIB) << "Color" << _color; qCDebug(LOG_LIB) << "Color" << _color;
@ -258,6 +305,22 @@ void GraphicalItem::setInactiveColor(const QString _color)
} }
void GraphicalItem::setMaxValue(const float _value)
{
qCDebug(LOG_LIB) << "Max value" << _value;
m_maxValue = _value;
}
void GraphicalItem::setMinValue(const float _value)
{
qCDebug(LOG_LIB) << "Min value" << _value;
m_minValue = _value;
}
void GraphicalItem::setType(const Type _type) void GraphicalItem::setType(const Type _type)
{ {
qCDebug(LOG_LIB) << "Type" << _type; qCDebug(LOG_LIB) << "Type" << _type;
@ -310,6 +373,15 @@ void GraphicalItem::setHeight(const int _height)
} }
void GraphicalItem::setUsedKeys(const QStringList _usedKeys)
{
qCDebug(LOG_LIB) << "Used keys" << _usedKeys;
// remove dubs
m_usedKeys = QSet<QString>::fromList(_usedKeys).toList();
}
void GraphicalItem::setWidth(const int _width) void GraphicalItem::setWidth(const int _width)
{ {
qCDebug(LOG_LIB) << "Width" << _width; qCDebug(LOG_LIB) << "Width" << _width;
@ -334,7 +406,11 @@ void GraphicalItem::readConfiguration()
QSettings::IniFormat); QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry")); settings.beginGroup(QString("Desktop Entry"));
setCount(settings.value(QString("X-AW-Count"), m_count).toInt());
setCustom(settings.value(QString("X-AW-Custom"), m_custom).toBool());
setBar(settings.value(QString("X-AW-Value"), m_bar).toString()); setBar(settings.value(QString("X-AW-Value"), m_bar).toString());
setMaxValue(settings.value(QString("X-AW-Max"), m_maxValue).toFloat());
setMinValue(settings.value(QString("X-AW-Min"), m_minValue).toFloat());
setActiveColor( setActiveColor(
settings.value(QString("X-AW-ActiveColor"), m_activeColor) settings.value(QString("X-AW-ActiveColor"), m_activeColor)
.toString()); .toString());
@ -363,23 +439,24 @@ void GraphicalItem::readConfiguration()
} }
QVariantHash GraphicalItem::run()
{
// required by abstract class
return QVariantHash();
}
int GraphicalItem::showConfiguration(const QVariant args) int GraphicalItem::showConfiguration(const QVariant args)
{ {
qCDebug(LOG_LIB) << "Combobox arguments" << args; qCDebug(LOG_LIB) << "Combobox arguments" << args;
QStringList tags = args.toStringList(); QStringList tags = args.toStringList();
ui->label_nameValue->setText(name()); ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment()); ui->lineEdit_comment->setText(comment());
ui->checkBox_custom->setChecked(m_custom);
ui->comboBox_value->addItems(tags); ui->comboBox_value->addItems(tags);
if (m_custom) {
ui->lineEdit_customValue->setText(m_bar);
} else {
ui->comboBox_value->addItem(m_bar); ui->comboBox_value->addItem(m_bar);
ui->comboBox_value->setCurrentIndex(ui->comboBox_value->count() - 1); ui->comboBox_value->setCurrentIndex(ui->comboBox_value->count() - 1);
}
ui->doubleSpinBox_max->setValue(m_maxValue);
ui->doubleSpinBox_min->setValue(m_minValue);
ui->spinBox_count->setValue(m_count);
ui->pushButton_activeColor->setText(m_activeColor); ui->pushButton_activeColor->setText(m_activeColor);
ui->pushButton_inactiveColor->setText(m_inactiveColor); ui->pushButton_inactiveColor->setText(m_inactiveColor);
ui->comboBox_type->setCurrentIndex(static_cast<int>(m_type)); ui->comboBox_type->setCurrentIndex(static_cast<int>(m_type));
@ -387,13 +464,22 @@ int GraphicalItem::showConfiguration(const QVariant args)
ui->spinBox_height->setValue(m_height); ui->spinBox_height->setValue(m_height);
ui->spinBox_width->setValue(m_width); ui->spinBox_width->setValue(m_width);
// update UI
changeCountState(ui->comboBox_type->currentIndex());
changeValue(ui->checkBox_custom->checkState());
int ret = exec(); int ret = exec();
if (ret != 1) if (ret != 1)
return ret; return ret;
setName(ui->label_nameValue->text()); setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text()); setComment(ui->lineEdit_comment->text());
setApiVersion(AWGIAPI); setApiVersion(AWGIAPI);
setBar(ui->comboBox_value->currentText()); setCount(ui->spinBox_count->value());
setCustom(ui->checkBox_custom->isChecked());
setBar(m_custom ? ui->lineEdit_customValue->text()
: ui->comboBox_value->currentText());
setMaxValue(ui->doubleSpinBox_max->value());
setMinValue(ui->doubleSpinBox_min->value());
setActiveColor(ui->pushButton_activeColor->text().remove(QChar('&'))); setActiveColor(ui->pushButton_activeColor->text().remove(QChar('&')));
setInactiveColor(ui->pushButton_inactiveColor->text().remove(QChar('&'))); setInactiveColor(ui->pushButton_inactiveColor->text().remove(QChar('&')));
setStrType(ui->comboBox_type->currentText()); setStrType(ui->comboBox_type->currentText());
@ -417,6 +503,10 @@ void GraphicalItem::writeConfiguration() const
settings.beginGroup(QString("Desktop Entry")); settings.beginGroup(QString("Desktop Entry"));
settings.setValue(QString("X-AW-Value"), m_bar); settings.setValue(QString("X-AW-Value"), m_bar);
settings.setValue(QString("X-AW-Count"), m_count);
settings.setValue(QString("X-AW-Custom"), m_custom);
settings.setValue(QString("X-AW-Max"), m_maxValue);
settings.setValue(QString("X-AW-Min"), m_minValue);
settings.setValue(QString("X-AW-ActiveColor"), m_activeColor); settings.setValue(QString("X-AW-ActiveColor"), m_activeColor);
settings.setValue(QString("X-AW-InactiveColor"), m_inactiveColor); settings.setValue(QString("X-AW-InactiveColor"), m_inactiveColor);
settings.setValue(QString("X-AW-Type"), strType()); settings.setValue(QString("X-AW-Type"), strType());
@ -431,8 +521,8 @@ void GraphicalItem::writeConfiguration() const
void GraphicalItem::changeColor() void GraphicalItem::changeColor()
{ {
QColor color QColor color = m_helper->stringToColor(
= stringToColor((static_cast<QPushButton *>(sender()))->text()); (static_cast<QPushButton *>(sender()))->text());
QColor newColor = QColorDialog::getColor(color, this, tr("Select color"), QColor newColor = QColorDialog::getColor(color, this, tr("Select color"),
QColorDialog::ShowAlphaChannel); QColorDialog::ShowAlphaChannel);
if (!newColor.isValid()) if (!newColor.isValid())
@ -450,13 +540,58 @@ void GraphicalItem::changeColor()
} }
void GraphicalItem::changeColorState(const int state)
{
qCDebug(LOG_LIB) << "Current color state is" << state;
if (sender() == ui->checkBox_activeCheck) {
qCInfo(LOG_LIB) << "Change active color state";
ui->widget_activeColor->setHidden(state == Qt::Unchecked);
ui->widget_activeImage->setHidden(state != Qt::Unchecked);
} else if (sender() == ui->checkBox_inactiveCheck) {
qCInfo(LOG_LIB) << "Change inactive color state";
ui->widget_inactiveColor->setHidden(state == Qt::Unchecked);
ui->widget_inactiveImage->setHidden(state != Qt::Unchecked);
}
}
void GraphicalItem::changeCountState(const int state)
{
qCDebug(LOG_LIB) << "Current state is" << state;
// 3 is magic number. Actually 3 is Graph mode
ui->widget_count->setHidden(state != 3);
}
void GraphicalItem::changeImage()
{
QString path = static_cast<QPushButton *>(sender())->text();
QString directory = QFileInfo(path).absolutePath();
QString newPath = QFileDialog::getOpenFileName(
this, tr("Select path"), directory,
tr("Images (*.png *.bpm *.jpg);;All files (*.*)"));
qCInfo(LOG_LIB) << "Selected path" << newPath;
return static_cast<QPushButton *>(sender())->setText(newPath);
}
void GraphicalItem::changeValue(const int state)
{
qCDebug(LOG_LIB) << "Current state is" << state;
ui->widget_value->setHidden(state != Qt::Unchecked);
ui->widget_customValue->setHidden(state == Qt::Unchecked);
}
void GraphicalItem::initScene() void GraphicalItem::initScene()
{ {
// init scene // init scene
m_scene = new QGraphicsScene(); m_scene = new QGraphicsScene();
if (m_type == Graph)
m_scene->setBackgroundBrush(stringToColor(m_inactiveColor));
else
m_scene->setBackgroundBrush(QBrush(Qt::NoBrush)); m_scene->setBackgroundBrush(QBrush(Qt::NoBrush));
// init view // init view
m_view = new QGraphicsView(m_scene); m_view = new QGraphicsView(m_scene);
@ -465,104 +600,12 @@ void GraphicalItem::initScene()
m_view->setFrameShape(QFrame::NoFrame); m_view->setFrameShape(QFrame::NoFrame);
m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->resize(m_width + 5.0, m_height + 5.0); m_view->resize(m_width + 5, m_height + 5);
}
// init helper
void GraphicalItem::paintCircle(const float value) m_helper = new GraphicalItemHelper(this, m_scene);
{ m_helper->setParameters(m_activeColor, m_inactiveColor, m_width, m_height,
QPen pen; m_count);
pen.setWidth(1.0);
float percent = value / 100.0;
QGraphicsEllipseItem *circle;
QColor inactive = stringToColor(m_inactiveColor);
QColor active = stringToColor(m_activeColor);
// inactive
pen.setColor(inactive);
circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, pen,
QBrush(inactive, Qt::SolidPattern));
circle->setSpanAngle(-(1.0 - percent) * 360.0 * 16.0);
circle->setStartAngle(90.0 * 16.0 - percent * 360.0 * 16.0);
// active
pen.setColor(active);
circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, pen,
QBrush(active, Qt::SolidPattern));
circle->setSpanAngle(-percent * 360.0 * 16.0);
circle->setStartAngle(90.0 * 16.0);
}
void GraphicalItem::paintGraph(const QList<float> value)
{
QPen pen;
pen.setColor(stringToColor(m_activeColor));
// default norms
float normX
= static_cast<float>(m_width) / static_cast<float>(value.count());
float normY = static_cast<float>(m_height) / (1.5 * 100.0);
// paint graph
for (int i = 0; i < value.count() - 1; i++) {
// some magic here
float x1 = i * normX;
float y1 = -fabs(value.at(i)) * normY + 5.0;
float x2 = (i + 1) * normX;
float y2 = -fabs(value.at(i + 1)) * normY + 5.0;
m_scene->addLine(x1, y1, x2, y2, pen);
}
}
void GraphicalItem::paintHorizontal(const float value)
{
QPen pen;
float percent = value / 100.0;
pen.setWidth(m_height);
// inactive
pen.setColor(stringToColor(m_inactiveColor));
m_scene->addLine(percent * m_width + 0.5 * m_height, 0.5 * m_height,
m_width + 0.5 * m_height, 0.5 * m_height, pen);
// active
pen.setColor(stringToColor(m_activeColor));
m_scene->addLine(-0.5 * m_height, 0.5 * m_height,
percent * m_width - 0.5 * m_height, 0.5 * m_height, pen);
}
void GraphicalItem::paintVertical(const float value)
{
QPen pen;
float percent = value / 100.0;
pen.setWidth(m_width);
// inactive
pen.setColor(stringToColor(m_inactiveColor));
m_scene->addLine(0.5 * m_width, -0.5 * m_width, 0.5 * m_width,
(1.0 - percent) * m_height - 0.5 * m_width, pen);
// active
pen.setColor(stringToColor(m_activeColor));
m_scene->addLine(0.5 * m_width, (1.0 - percent) * m_height + 0.5 * m_width,
0.5 * m_width, m_height + 0.5 * m_width, pen);
}
QColor GraphicalItem::stringToColor(const QString _color) const
{
qCDebug(LOG_LIB) << "Color" << _color;
QColor qcolor;
QStringList listColor = _color.split(QChar(','));
while (listColor.count() < 4)
listColor.append(QString("0"));
qcolor.setRed(listColor.at(0).toInt());
qcolor.setGreen(listColor.at(1).toInt());
qcolor.setBlue(listColor.at(2).toInt());
qcolor.setAlpha(listColor.at(3).toInt());
return qcolor;
} }
@ -570,9 +613,18 @@ void GraphicalItem::translate()
{ {
ui->label_name->setText(i18n("Name")); ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment")); ui->label_comment->setText(i18n("Comment"));
ui->label_count->setText(i18n("Points count"));
ui->checkBox_custom->setText(i18n("Use custom formula"));
ui->label_value->setText(i18n("Value")); ui->label_value->setText(i18n("Value"));
ui->label_customValue->setText(i18n("Value"));
ui->label_max->setText(i18n("Max value"));
ui->label_min->setText(i18n("Min value"));
ui->checkBox_activeCheck->setText(i18n("Use image for active"));
ui->label_activeColor->setText(i18n("Active color")); ui->label_activeColor->setText(i18n("Active color"));
ui->label_activeImage->setText(i18n("Active image"));
ui->checkBox_inactiveCheck->setText(i18n("Use image for inactive"));
ui->label_inactiveColor->setText(i18n("Inactive color")); ui->label_inactiveColor->setText(i18n("Inactive color"));
ui->label_inactiveImage->setText(i18n("Inactive image"));
ui->label_type->setText(i18n("Type")); ui->label_type->setText(i18n("Type"));
ui->label_direction->setText(i18n("Direction")); ui->label_direction->setText(i18n("Direction"));
ui->label_height->setText(i18n("Height")); ui->label_height->setText(i18n("Height"));

View File

@ -23,6 +23,7 @@
#include "abstractextitem.h" #include "abstractextitem.h"
class GraphicalItemHelper;
class QGraphicsScene; class QGraphicsScene;
class QGraphicsView; class QGraphicsView;
@ -36,10 +37,15 @@ class GraphicalItem : public AbstractExtItem
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString bar READ bar WRITE setBar) Q_PROPERTY(QString bar READ bar WRITE setBar)
Q_PROPERTY(QString activeColor READ activeColor WRITE setActiveColor) Q_PROPERTY(QString activeColor READ activeColor WRITE setActiveColor)
Q_PROPERTY(int count READ count WRITE setCount)
Q_PROPERTY(bool custom READ isCustom WRITE setCustom)
Q_PROPERTY(QString inactiveColor READ inactiveColor WRITE setInactiveColor) Q_PROPERTY(QString inactiveColor READ inactiveColor WRITE setInactiveColor)
Q_PROPERTY(Type type READ type WRITE setType) Q_PROPERTY(Type type READ type WRITE setType)
Q_PROPERTY(Direction direction READ direction WRITE setDirection) Q_PROPERTY(Direction direction READ direction WRITE setDirection)
Q_PROPERTY(int height READ height WRITE setHeight) Q_PROPERTY(int height READ height WRITE setHeight)
Q_PROPERTY(float maxValue READ maxValue WRITE setMaxValue)
Q_PROPERTY(float minValue READ minValue WRITE setMinValue)
Q_PROPERTY(QStringList usedKeys READ usedKeys WRITE setUsedKeys)
Q_PROPERTY(int width READ width WRITE setWidth) Q_PROPERTY(int width READ width WRITE setWidth)
public: public:
@ -51,61 +57,71 @@ public:
const QStringList directories = QStringList()); const QStringList directories = QStringList());
virtual ~GraphicalItem(); virtual ~GraphicalItem();
GraphicalItem *copy(const QString _fileName, const int _number); GraphicalItem *copy(const QString _fileName, const int _number);
QString image(const QVariant value); QString image(const QVariant &value);
// get methods // get methods
QString bar() const; QString bar() const;
QString activeColor() const; QString activeColor() const;
QString inactiveColor() const; QString inactiveColor() const;
QString tag() const; int count() const;
bool isCustom() const;
float minValue() const;
float maxValue() const;
Type type() const; Type type() const;
QString strType() const; QString strType() const;
Direction direction() const; Direction direction() const;
QString strDirection() const; QString strDirection() const;
int height() const; int height() const;
QStringList usedKeys() const;
int width() const; int width() const;
QString uniq() const; QString uniq() const;
// set methods // set methods
void setBar(const QString _bar = QString("cpu")); void setBar(const QString _bar = QString("cpu"));
void setActiveColor(const QString _color = QString("0,0,0,130")); void setActiveColor(const QString _color = QString("0,0,0,130"));
void setCount(const int _count = 100);
void setCustom(const bool _custom = false);
void setInactiveColor(const QString _color = QString("255,255,255,130")); void setInactiveColor(const QString _color = QString("255,255,255,130"));
void setMinValue(const float _value = 0.0);
void setMaxValue(const float _value = 100.0);
void setType(const Type _type = Horizontal); void setType(const Type _type = Horizontal);
void setStrType(const QString _type = QString("Horizontal")); void setStrType(const QString _type = QString("Horizontal"));
void setDirection(const Direction _direction = LeftToRight); void setDirection(const Direction _direction = LeftToRight);
void setStrDirection(const QString _direction = QString("LeftToRight")); void setStrDirection(const QString _direction = QString("LeftToRight"));
void setHeight(const int _height = 100); void setHeight(const int _height = 100);
void setUsedKeys(const QStringList _usedKeys = QStringList());
void setWidth(const int _width = 100); void setWidth(const int _width = 100);
public slots: public slots:
void readConfiguration(); void readConfiguration();
QVariantHash run(); QVariantHash run() { return QVariantHash(); };
int showConfiguration(const QVariant args = QVariant()); int showConfiguration(const QVariant args = QVariant());
void writeConfiguration() const; void writeConfiguration() const;
private slots: private slots:
void changeColor(); void changeColor();
void changeColorState(const int state);
void changeCountState(const int state);
void changeImage();
void changeValue(const int state);
private: private:
QString m_fileName; GraphicalItemHelper *m_helper = nullptr;
QStringList m_dirs;
QGraphicsScene *m_scene = nullptr; QGraphicsScene *m_scene = nullptr;
QGraphicsView *m_view = nullptr; QGraphicsView *m_view = nullptr;
Ui::GraphicalItem *ui; Ui::GraphicalItem *ui;
void initScene(); void initScene();
// paint methods
void paintCircle(const float value);
void paintGraph(const QList<float> value);
void paintHorizontal(const float value);
void paintVertical(const float value);
// additional method
QColor stringToColor(const QString _color) const;
void translate(); void translate();
// properties // properties
QString m_bar = QString("cpu"); QString m_bar = QString("cpu");
QString m_activeColor = QString("0,0,0,130"); int m_count = 100;
QString m_inactiveColor = QString("255,255,255,130"); bool m_custom = false;
QString m_activeColor;
QString m_inactiveColor;
float m_minValue = 0.0f;
float m_maxValue = 100.0f;
Type m_type = Horizontal; Type m_type = Horizontal;
Direction m_direction = LeftToRight; Direction m_direction = LeftToRight;
int m_height = 100; int m_height = 100;
QStringList m_usedKeys;
int m_width = 100; int m_width = 100;
}; };

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>416</width> <width>416</width>
<height>325</height> <height>606</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -18,8 +18,14 @@
<layout class="QHBoxLayout" name="layout_name"> <layout class="QHBoxLayout" name="layout_name">
<item> <item>
<widget class="QLabel" name="label_name"> <widget class="QLabel" name="label_name">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>Name</string> <string>&amp;Name</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -27,11 +33,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_nameValue"> <widget class="QLineEdit" name="lineEdit_name"/>
<property name="text">
<string/>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -46,7 +48,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>Comment</string> <string>&amp;Comment</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -59,11 +61,61 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layout_custom">
<item>
<spacer name="spacer_custom">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_custom">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Use custom formula</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget_value" native="true">
<layout class="QHBoxLayout" name="layout_value"> <layout class="QHBoxLayout" name="layout_value">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QLabel" name="label_value"> <widget class="QLabel" name="label_value">
<property name="text"> <property name="text">
<string>Value</string> <string>&amp;Value</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -78,13 +130,181 @@
</widget> </widget>
</item> </item>
</layout> </layout>
</widget>
</item> </item>
<item> <item>
<widget class="QWidget" name="widget_customValue" native="true">
<layout class="QHBoxLayout" name="layout_customValue">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_customValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Va&amp;lue</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_customValue"/>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layout_max">
<item>
<widget class="QLabel" name="label_max">
<property name="text">
<string>&amp;Max value</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBox_max">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_min">
<item>
<widget class="QLabel" name="label_min">
<property name="text">
<string>Min val&amp;ue</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="doubleSpinBox_min">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget_count" native="true">
<layout class="QHBoxLayout" name="layout_count">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_count">
<property name="text">
<string>&amp;Points count</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_count">
<property name="maximum">
<number>2000</number>
</property>
<property name="singleStep">
<number>25</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layout_activeCheck">
<item>
<spacer name="spacer_activeCheck">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_activeCheck">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Use image for active</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget_activeColor" native="true">
<layout class="QHBoxLayout" name="layout_activeColor"> <layout class="QHBoxLayout" name="layout_activeColor">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QLabel" name="label_activeColor"> <widget class="QLabel" name="label_activeColor">
<property name="text"> <property name="text">
<string>Active color</string> <string>Activ&amp;e color</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -99,13 +319,92 @@
</widget> </widget>
</item> </item>
</layout> </layout>
</widget>
</item> </item>
<item> <item>
<widget class="QWidget" name="widget_activeImage" native="true">
<layout class="QHBoxLayout" name="layout_activeImage">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_activeImage">
<property name="text">
<string>&amp;Active image</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_activeImage">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layout_inactiveCheck">
<item>
<spacer name="spacer_inactiveCheck">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_inactiveCheck">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Use image for inactive</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget_inactiveColor" native="true">
<layout class="QHBoxLayout" name="layout_inactiveColor"> <layout class="QHBoxLayout" name="layout_inactiveColor">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QLabel" name="label_inactiveColor"> <widget class="QLabel" name="label_inactiveColor">
<property name="text"> <property name="text">
<string>Inactive color</string> <string>&amp;Inactive color</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -120,13 +419,49 @@
</widget> </widget>
</item> </item>
</layout> </layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_inactiveImage" native="true">
<layout class="QHBoxLayout" name="layout_inactiveImage">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_inactiveImage">
<property name="text">
<string>Inactive image</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_inactiveImage">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="layout_type"> <layout class="QHBoxLayout" name="layout_type">
<item> <item>
<widget class="QLabel" name="label_type"> <widget class="QLabel" name="label_type">
<property name="text"> <property name="text">
<string>Type</string> <string>&amp;Type</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -164,7 +499,7 @@
<item> <item>
<widget class="QLabel" name="label_direction"> <widget class="QLabel" name="label_direction">
<property name="text"> <property name="text">
<string>Direction</string> <string>&amp;Direction</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -192,7 +527,7 @@
<item> <item>
<widget class="QLabel" name="label_height"> <widget class="QLabel" name="label_height">
<property name="text"> <property name="text">
<string>Height</string> <string>&amp;Height</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -216,7 +551,7 @@
<item> <item>
<widget class="QLabel" name="label_width"> <widget class="QLabel" name="label_width">
<property name="text"> <property name="text">
<string>Width</string> <string>&amp;Width</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>

View File

@ -0,0 +1,201 @@
/***************************************************************************
* 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 "graphicalitemhelper.h"
#include <QColor>
#include <QGraphicsEllipseItem>
#include <QGraphicsScene>
#include <cmath>
#include "awdebug.h"
GraphicalItemHelper::GraphicalItemHelper(QObject *parent, QGraphicsScene *scene)
: QObject(parent)
, m_scene(scene)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
}
GraphicalItemHelper::~GraphicalItemHelper()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
}
void GraphicalItemHelper::setParameters(const QString active,
const QString inactive, const int width,
const int height, const int count)
{
qCDebug(LOG_LIB) << "Use active color" << active << ", inactive" << inactive
<< ", width" << width << ", height" << height << ", count"
<< count;
// put images to pens if any otherwise set pen colors
// Images resize to content here as well
if (active.startsWith(QString("/"))) {
qCInfo(LOG_LIB) << "Found path, trying to load Pixmap from" << active;
QPixmap pixmap = QPixmap(active);
if (pixmap.isNull()) {
qCInfo(LOG_LIB) << "Invalid pixmap found" << active;
m_activePen.setColor(QColor(0, 0, 0, 130));
} else {
m_activePen.setBrush(QBrush(pixmap.scaled(width, height)));
}
} else {
m_activePen.setColor(stringToColor(active));
}
if (inactive.startsWith(QString("/"))) {
qCInfo(LOG_LIB) << "Found path, trying to load Pixmap from" << inactive;
QPixmap pixmap = QPixmap(inactive);
if (pixmap.isNull()) {
qCInfo(LOG_LIB) << "Invalid pixmap found" << inactive;
m_inactivePen.setColor(QColor(255, 255, 255, 130));
} else {
m_inactivePen.setBrush(QBrush(pixmap.scaled(width, height)));
}
} else {
m_inactivePen.setColor(stringToColor(inactive));
}
m_width = width;
m_height = height;
m_count = count;
}
void GraphicalItemHelper::paintCircle(const float &percent)
{
qCDebug(LOG_LIB) << "Paint with percent" << percent;
m_activePen.setWidth(1);
m_inactivePen.setWidth(1);
QGraphicsEllipseItem *circle;
// 16 is because of qt. From Qt documentation:
// Returns the start angle for an ellipse segment in 16ths of a degree
// inactive
circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, m_inactivePen,
m_inactivePen.brush());
circle->setSpanAngle(-(1.0f - percent) * 360.0f * 16.0f);
circle->setStartAngle(90.0f * 16.0f - percent * 360.0f * 16.0f);
// active
circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, m_activePen,
m_activePen.brush());
circle->setSpanAngle(-percent * 360.0f * 16.0f);
circle->setStartAngle(90 * 16);
}
void GraphicalItemHelper::paintGraph(const float &value)
{
qCDebug(LOG_LIB) << "Paint with value" << value;
// refresh background image
m_scene->setBackgroundBrush(m_inactivePen.brush());
storeValue(value);
// default norms
float normX
= static_cast<float>(m_width) / static_cast<float>(m_values.count());
float normY = static_cast<float>(m_height - 1);
// paint graph
for (int i = 0; i < m_values.count() - 1; i++) {
// some magic here
float x1 = i * normX;
float y1 = -fabs(m_values.at(i)) * normY + 0.5f;
float x2 = (i + 1) * normX;
float y2 = -fabs(m_values.at(i + 1)) * normY + 0.5f;
m_scene->addLine(x1, y1, x2, y2, m_activePen);
}
}
void GraphicalItemHelper::paintHorizontal(const float &percent)
{
qCDebug(LOG_LIB) << "Paint with percent" << percent;
m_activePen.setWidth(m_height);
m_inactivePen.setWidth(m_height);
// inactive
m_scene->addLine(percent * m_width + 0.5 * m_height, 0.5 * m_height,
m_width + 0.5 * m_height, 0.5 * m_height, m_inactivePen);
// active
m_scene->addLine(-0.5 * m_height, 0.5 * m_height,
percent * m_width - 0.5 * m_height, 0.5 * m_height,
m_activePen);
}
void GraphicalItemHelper::paintVertical(const float &percent)
{
qCDebug(LOG_LIB) << "Paint with percent" << percent;
m_activePen.setWidth(m_height);
m_inactivePen.setWidth(m_height);
// inactive
m_scene->addLine(0.5 * m_width, -0.5 * m_width, 0.5 * m_width,
(1.0 - percent) * m_height - 0.5 * m_width, m_inactivePen);
// active
m_scene->addLine(0.5 * m_width, (1.0 - percent) * m_height + 0.5 * m_width,
0.5 * m_width, m_height + 0.5 * m_width, m_activePen);
}
float GraphicalItemHelper::getPercents(const float &value, const float &min,
const float &max)
{
qCDebug(LOG_LIB) << "Get percent value from" << value;
// newest Qt crashes here if value is nan
if (isnan(value))
return 0.0;
return (value - min) / (max - min);
}
QColor GraphicalItemHelper::stringToColor(const QString &color)
{
qCDebug(LOG_LIB) << "Color" << color;
QColor qColor;
QStringList listColor = color.split(QChar(','));
while (listColor.count() < 4)
listColor.append(QString("0"));
qColor.setRed(listColor.at(0).toInt());
qColor.setGreen(listColor.at(1).toInt());
qColor.setBlue(listColor.at(2).toInt());
qColor.setAlpha(listColor.at(3).toInt());
return qColor;
}
void GraphicalItemHelper::storeValue(const float &value)
{
qCDebug(LOG_LIB) << "Save value to array" << value;
if (m_values.count() == 0)
m_values.append(1.0);
else if (m_values.count() > m_count)
m_values.removeFirst();
m_values.append(value);
}

View File

@ -0,0 +1,59 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef GRAPHICALITEMHELPER_H
#define GRAPHICALITEMHELPER_H
#include <QColor>
#include <QObject>
#include <QPen>
class QGraphicsScene;
class GraphicalItemHelper : public QObject
{
public:
explicit GraphicalItemHelper(QObject *parent = nullptr,
QGraphicsScene *scene = nullptr);
virtual ~GraphicalItemHelper();
// parameters
void setParameters(const QString active, const QString inactive,
const int width, const int height, const int count);
// paint methods
void paintCircle(const float &percent);
void paintGraph(const float &value);
void paintHorizontal(const float &percent);
void paintVertical(const float &percent);
// additional conversion methods
float getPercents(const float &value, const float &min, const float &max);
QColor stringToColor(const QString &color);
private:
void storeValue(const float &value);
QGraphicsScene *m_scene = nullptr;
int m_count = 100;
QPen m_activePen;
QPen m_inactivePen;
int m_width = 100;
int m_height = 100;
// list of values which will be used to store data for graph type only
QList<float> m_values;
};
#endif /* GRAPHICALITEMHELPER_H */

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Some files were not shown because too many files have changed in this diff Show More