Compare commits

...

109 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
ac089dee9c Release 3.0.1
drop nullptr checking
2015-10-23 00:20:30 +03:00
2d9ca281a9 update patch...again 2015-10-22 05:25:00 +03:00
99e38118a4 drop unused declarations, update qt5.5 patch 2015-10-22 05:22:02 +03:00
68dd2432cd drop qcinfo support (it will be moved to additional patch) 2015-10-22 05:01:38 +03:00
919a10fff6 add patch to avoid errors with Qt5.3 2015-10-22 03:39:07 +03:00
d0ba320e1b add patch to revert the last commit =) 2015-10-22 02:57:06 +03:00
8545192ef8 move dialog part to qml files 2015-10-22 02:52:06 +03:00
f77cf7c1aa update contributing.md
fix #69 by adding special patches
2015-10-21 13:29:06 +03:00
dd262c3d84 small update of support files 2015-10-21 07:02:09 +03:00
df87850f65 Release 3.0.0
* turn back concurrent text update
* update screenshots
2015-10-21 06:53:34 +03:00
c2db8740b8 translation update 2015-10-20 01:23:12 +03:00
75ab84e993 * logging changes
* add configuration export status message
* prepare to release
2015-10-20 00:34:29 +03:00
c161004640 drop clion settings at all 2015-10-19 01:28:51 +03:00
c1a8c17ecb * drop workspace.xml from source tree (it is changed too offen)
* fix export and import configurations for json files
2015-10-19 00:57:27 +03:00
17a8a1734b * create cppcheck and clangformat targets
* apply code style (#67)
* send values by reference
* fix warnings on plugin destruction by disconnecting dataengines first
* fix invalid hddtemp group definition
2015-10-18 00:05:42 +03:00
8645260f99 * end work on #68
* create special class for configuration
* update clion settings
2015-10-17 00:06:32 +03:00
0e1b101703 * initial implementation of configuration export and import feature (#68)
* drop mediators in data transition
2015-10-16 07:22:03 +03:00
2db2de4c27 * try to drop text update to main thread instead of concurrent run
* update contributing.md
2015-10-15 16:54:13 +03:00
af0dd25b86 * add clang-format configuration and script
* add cppcheck script proto (TODO include directories according ot cmake
    output)
TODO do it while build time and/or commit
2015-10-14 01:01:25 +03:00
3be733a775 drop code oriented on the stream lock in parallel updates
This fact caused by the qt signal-slot implementation. Even if slots
code is going into parallel they will be called in the main app thread.
And also it is used inside KF5 dataengine implementation, so I'm affraid
that it could not be optimized w\o backend rewriting
2015-10-13 01:49:12 +03:00
d3ab0a7228 * add mutex to avoid crash on qhash data update (#62)
* update gitignore
* update contributing.md
2015-10-11 18:28:21 +03:00
440d180c20 some code style improvements (#67) 2015-10-10 00:51:24 +03:00
827275da3f fix crash which has been caused by the fact that we've called concurrent
data update and don't copy object (#66)
* more correct concurrent run
* move data split to awdataengineaggregator
2015-10-09 07:22:54 +03:00
6f86e8ec5e fix formating 2015-10-08 01:14:30 +03:00
f1e6f74c7d * add CONTRIBUTING.md
* add drop source ability for extsysmon
2015-10-08 01:08:59 +03:00
f7e24f680a * add Optimization build type which uses -O3
* create QTimer object in AWDataEngineAggregator class, emit signal to
  this timer because timers could not be started in the separate thread
* increase limit x2 with leaving the thread pool size as was
2015-10-07 01:39:10 +03:00
69c1f0ed5a * small build changes
* drop cast (they were added to try to avoid possible crash)
2015-10-06 06:49:24 +03:00
c4612d84ed move dataengine control to plugin part (ref to #66) 2015-10-05 00:00:38 +03:00
228d6500d3 update Spain translation 2015-10-01 00:18:58 +03:00
befdf0519f add loadsource for testing needs 2015-09-30 00:16:57 +03:00
79d2b07d57 update uk translation
fix typo in ru translation
2015-09-29 00:13:19 +03:00
84f6f1a820 * add commit SHA information
* allow to open link in quotes editor
* fix bug with no data updates in configuration ui
2015-09-28 19:27:55 +03:00
92ce241742 return back stream lock which will be disabled from qml by the timer. In
other case there is possibe plasma crash
2015-09-26 03:23:10 +03:00
ab2a444c84 auxiliary commit
* drop unnecessary includes
* bump API versions inside version.h
2015-09-24 00:05:09 +03:00
0fa274ad75 * fix bug in ui
* drop QUEUE_LIMIT build option (moved to runtime cfg)
* apply concurrent updates for slots
2015-09-23 03:53:42 +03:00
82e2bc23a1 * more intuitive configuration UI
* add queueLimit runtime configuration
2015-09-22 00:31:30 +03:00
4cc44c1d59 bump quotes api version to 3. Change data type from float to double to
avoid rounding problems
2015-09-21 06:17:43 +03:00
d20db1b888 rewrite several methods in GI, add support of graphs 2015-09-20 13:19:28 +03:00
120e201c5b * move update interval to another tab
* some changes inside concurrent run
* update COPYING to vanila format
2015-09-19 10:25:26 +03:00
24eb548bb3 * limit messages queue to ideal thread count
* move from QtScript to QJSEngine (first is deprecated since 5.6)
* drop unneeded includes in headers
* some changes inside queue managing
2015-09-17 01:10:55 +03:00
646e897058 * fix extsysmon multi keys sources
* change quotes values types to double
2015-09-16 00:01:07 +03:00
95b6b2d9e9 * add preview function
* more comments inside
* variables renaming
* unite several lists to one hash
* add build_future definition checking to source code
2015-09-15 00:02:59 +03:00
dddc3962a5 * better extensions update
* prepare dataaggregator to graph data
* add ability to wrap text
* move tag selection dialog to ui
2015-09-14 05:01:34 +03:00
f08600db61 change quotes output format
integrate aggregators to the plugin
2015-09-13 00:13:49 +03:00
0ba74b3130 add ability to wrap lines
rename AWToolTip to AWDataAggregator object
drop hasOutput property from ExtScript
fix some bugs in AWKeysAggregator
2015-09-12 02:32:31 +03:00
0298a8c088 create awkeysaggregator
change netwrok device definition (fix #64)
2015-09-11 00:43:35 +03:00
bf5c500938 fix bugs caused by integration 2015-09-10 04:59:35 +03:00
9e45b02c8e move extsysmon and plugin to the new source model 2015-09-09 01:48:09 +03:00
ab0ab0d40f some optimizations 2015-09-08 00:07:47 +03:00
f5e40d084d show message on no updates 2015-09-07 01:47:50 +03:00
d00ab81fe9 better look and feel for tooltip configuration ui 2015-09-06 01:43:45 +03:00
09275731aa try to implement concurent data update 2015-09-05 03:02:02 +03:00
228 changed files with 12904 additions and 6014 deletions

48
.gitignore vendored
View File

@ -1,7 +1,49 @@
sources/build
sources/usr
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# cmake
CMakeCache.txt
CMakeFiles
CMakeScripts
Makefile
cmake_install.cmake
install_manifest.txt
# build directory
build
# archives
*src.tar.[gx]z
*pkg.tar.[gx]z
build
src
pkg
*.deb
# clion settings
.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"]
path = sources/3rdparty/fontdialog
url = https://github.com/arcan1s/qtadds-fontdialog.git

View File

@ -1,7 +1,16 @@
install:
- sudo apt-get update -qq
- sudo apt-get install -y cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev
- git submobule update --init
sudo: required
dist: trusty
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
- mkdir build

View File

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

View File

@ -1,5 +1,64 @@
+ add tags upunits, downunits
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:
+ add patches for old Qt versions
- drop `nullptr` checking
* move dialogs to QML part
Ver.3.0.0:
+ add tags upunits, downunits, upkb, downkb
+ add tags dalbum, dartist, dtitle, salbum, sartist, stitle
+ add support of lambda functions
+ add Dutch translation (thanks to Heimen Stoffels)
+ add check for update function on startup (optional)
+ add ability to disable string tags translations
+ add filtering to ExtUpgrade (ApiVer == 3)
+ add ability to change weather icons (ApiVer == 2)
+ show message if no updates found on direct request
+ add swap redirect type to ExtScript (ApiVer == 4)
+ add ability to wrap words
+ add support of graphs to GraphicalItems (ApiVer == 3)
+ add ability to show preview from configuration
+ add configuration export and import functions
- fix warning for empty tooltip image
- fix bug with widget auto resizing
- fix bug with no settings saving in DE
- fix bug with large start size
- fix bug with no possibility use more than 10 ext tags
- drop HDD free space notifications
- drop X-AW-Output key for ExtScript (ApiVer == 4)
- fix possible crash on web sources destruction
* more pretty configuration ui
* improve logging, change format to Qt5 style
* switch to concurrent data update
* some more optimization
* better network device definition
* quotes values now have double type (ApiVer == 3)
* better quotes output
* more comments inside code
* more Qt code style
* move update interval to another group
* move DataEnignes operations to plugin
* change DataEngine data format (breaking changes)
Ver.2.4.0:
+ add support of weather items

View File

@ -1,3 +1,65 @@
Вер.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:
+ добавлены патчи для старых версий Qt
- убрана проверка на nullptr
* диалоги перемещены в QML
Вер.3.0.0:
+ добавлены теги upunits, downunits, upkb, downkb
+ добавлены теги dalbum, dartist, dtitle, salbum, sartist, stitle
+ добавлена поддержка лямбда функций
+ добавлен голландский перевод (спасибо Heimen Stoffels)
+ добавлена опциональная проверка обновлений на старте
+ добавлена возможность отключить перевод строковых тегов
+ добавлена фильтрация в ExtUpgrade (ApiVer == 3)
+ добавлена возможность смены иконки погоды (ApiVer == 2)
+ показ сообщений, если не найдено обновлений, при прямом запросе
+ добавлено перенаправление swap в ExtScript (ApiVer == 4)
+ добавлена возможность переноса слов
+ добавлена поддержка графиков в GraphicalItems (ApiVer == 3)
+ добавлена возможность показать превью из настроек
+ добавлены импорт и экспорт конфигурации
- исправлен ворнинг для пустых тултипов
- исправлен баг, приводящий к увеличению виджета
- исправлен баг с отсутствием сохранения настроек DE
- исправлен баг с большим размером на старте
- исправлен баг с невозможностью использования более, чем 10 расширений
- убраны уведомления о свободном месте на диске
- убран ключ X-AW-Output в ExtScript (ApiVer == 4)
- исправлен возможное падение при вызове деструктора web-источников
* более удобный интерфейс настройки
* улучшено логирование, применен стиль логирования Qt5
* переключено на конкурентное обновление (-DBUILD_FUTURE=ON)
* немного оптимизаций
* лучшее определение активного сетевого устройства
* значение котировок типа double (ApiVer == 3)
* лучший показ котировок
* больше комментариев в коде
* большее следование стилю кода Qt
* настройки интервала перемещены в другую группу
* работа с DataEngine была перемещена в плагин
* изменен формат данных внутри DataEngine (ломает совместимость)
Вер.2.4.0:
+ добавлена поддержка погоды
+ добавлена поддержка LA (теги la1, la5, la15)

234
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,234 @@
Code style
----------
The recommended code style is Qt one. See [this document](https://wiki.qt.io/Qt_Coding_Style)
for more details. To avoid manual labor there is automatic cmake target named
`clangformat` (see below). Some additional detail see below.
* Indent is only spaces. 4 spaces.
* It is highly recommended to name private variables with `m_` prefix (`m_foo`).
There is no exceptions for properties.
* Avoid to create a large methods. Exception: if method contains lambda functions.
* If some method is called only once, it is recommended to use lambda functions.
Exception is `Q_INVOKABLE` methods.
* STL containers are not recommended, use Qt ones instead.
* In other hand Qt specific variables types (`qint`, `qfloat`, etc) are not
recommended.
* Do not repeat yourself ([DRY](https://en.wikipedia.org/wiki/Don't_repeat_yourself)).
* Headers declaration:
* Include only those headers which are strictly necessary inside headers. Use
forward class declaration instead. Exception is base class header declaration.
* In a`*.cpp` file header declaration should have the following order separated
by a new line in the alphabet order:
1. Class header.
2. KDE specific headers.
3. Qt specific headers.
4. Third party headers.
5. Project headers.
* Any header should have [include guard](https://en.wikipedia.org/wiki/Include_guard)
named as `CLASSNAMECAPS_H`
* If any `#if` directive is used condition should be mentioned in `#endif`:
```
#if (FOO)
someCodeInside();
#endif /* FOO */
```
* `Q_PROPERTY` macro is allowed and recommended for QObject based classes.
* Qt macros (e.g. `signals`, `slots`, `Q_OBJECT`, etc) are allowed. In other hand
`Q_FOREACH` (`foreach`) is not allowed use `for (auto foo : bar)` instead.
* Current project standard is **C++11**.
* Do not use C-like code:
* C-like style iteration if possible. Use `for (auto foo : bar)` and
`std::for_each` instead if possible. It is also recommended to use iterators.
* C-like casts, use `const_cast`, `static_cast`, `dymanic_Cast` instead. Using
of `reinterpret_cast` is not recommended. It is highly recommended to use
`dynamic_cast` with the exception catching. It is also possible to use
`qvariant_cast` if required. Exception is class constructors, e.g.:
```
char c = 'c';
std::string s = "string";
qDebug() << QString("some string") << QChar(c) << QString(s);
```
* C-like `NULL`, use `nullptr` instead.
* It is highly recommended to avoid implicit casts.
* Abstract classes (which have at least one pure virtual method) are allowed.
* Templates are allowed and recommended. Templates usually should be described
inside header not source code file.
* Hardcode is not recommended. But it is possible to use cmake variables to
configure some items during build time.
* Build should not require any additional system variable declaration/changing.
* Any line should not end with space.
* Do not hesitate move public methods to private one if possible.
* Do not hesitate use `const` modifier. In other hand `volatile` modifier is not
recommended.
* New lines rules:
* One line after license header.
* One line between header group declaration (see above).
* Two lines after header declaration and before declaration at the end of a
file.
* One line after class and types forward declarations in headers.
* One line before each method modifiers (`public`, `public slots`, etc).
* Two lines between methods inside source code (`*.cpp`).
* One line after `qCDebug()` information (see below).
* One line inside a method to improve code reading.
* Each destructor should be virtual.
* Class constructor should have default arguments. Use `QObject *parent` property
for QObject based classes.
* QObject based classes constructors should have explicit modifier.
* Create one file (source and header) per class.
* `else if` construction is allowed and recommended.
* 'true ? foo : bar' construction is allowed and recommended for one-line assignment.
* Any global pointer should be assign to `nullptr` after deletion and before
initialization. Exception: if object is deleted into class destructor.
Comments
--------
Please do not hesitate to use comments inside source code (especially in non-obvious
blocks). Comments also may use the following keywords:
* **TODO** - indicates that some new code should be implemented here later. Please
note that usually these methods should be implemented before the next release.
* **FIXME** - some dirty hacks and/or methods which should be done better.
* **HACK** - hacks inside code which requires to avoid some restrictions and/or
which adds additional non-obvious optimizations.
Do not use dots at the end of the comment line.
Development
-----------
* Officially the latest libraries versions should be used. In addition it is
possible to add workarounds for all versions (usually by using preprocessor
directives); in this case patches should be placed to `packages` directory.
* Build should not contain any warning.
* Try to minimize message in Release build with logging disabled. It is highly
recommended to fix KDE/Qt specific warning if possible
* Do not use dependency to KDE libraries if there are no any strictly necessary.
Exceptions are KNotification and KI18n libraries.
* It is highly recommended to use submodules for third party libraries if possible.
* The main branch is **development**. Changes in this branch may be merged to the
master one only if it is a 'stable' build.
* For experimental features development new branch `feature-foo` creation is allowed
and recommended.
* Experimental features should be added inside `BUILD_FUTURE` definition:
```
#ifdef BUILD_FUTURE
someTestFunctionInside();
#endif /* BUILD_FUTURE */
```
* Any project specific build variable should be mentioned inside `version.h` as
well.
* Recommended compiler is `clang`.
HIG
---
The recommended HIG is [KDE one](https://techbase.kde.org/Projects/Usability/HIG).
Avoid to paint interfaces inside plugin because QML and C++ parts may have different
theming.
Licensing
---------
All files should be licensed under GPLv3, the owner of the license should be the
project (i.e. **awesome-widgets**). See **Tools** section for more details.
Logging
-------
For logging please use [QLoggingCategory](http://doc.qt.io/qt-5/qloggingcategory.html).
Available categories should be declared in `awdebug.*` files. The following log
levels should be used:
* **debug** (`qCDebug()`) - method arguments information. Please note that it
is recommended to logging all arguments in the one line.
* **info** (`qCInfo()`) - additional information inside methods.
* **warning** (`qCWarning()`) - not critical information, which may be caused by
mistakes in configuration for example.
* **critical** (`qCCritical()`) - a critical error. After this error program may
be terminated.
The empty log string (e.g. `qCDebug();`) is not allowed because the method names
will be stripped by compiler with `Release` build type. To log class constructor
and destructor use `__PRETTY_FUNCTION__` macro.
Testing
-------
* Any changes should be tested by using `plasmawindowed` and `plasmashell` applications.
(It is also possible to use `plasmaengineexplorer` and `plasmoidviewer` in addition.)
* Any test should be performed on real (not Virtual Machine) system.
* Test builds should be:
1. `-DCMAKE_BUILD_TYPE=Debug`.
2. `-DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON`.
3. `-DCMAKE_BUILD_TYPE=Release`.
* It is recommended to create addition test if possible.
* Addition test functions should be declated and used only inside `BUILD_TESTING`
definition.
Tools
-----
* For QString concatenation use `QString::arg` method.
* Any source file should have license header:
```
/***************************************************************************
* 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/ *
***************************************************************************/
```
* Recommended class constructor for QObject based classes:
```
FooClass::FooClass(QObject *parent, const QVariant var)
: QObject(parent)
, m_var(var)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
// some code below if any
}
```
* Property usage:
```
Q_PROPERTY(bool prop READ prop WRITE setProp);
public:
bool prop() const
{
return m_prop;
};
void setProp(const bool _prop)
{
// error checking if required
m_prop = _prop
}
private:
// declare with default value
bool m_prop = false;
```
* Use `cppcheck` to avoid common errors in the code. To start application just
run `make cppcheck`.
* Use `clang-format` to apply valid code format. To start application just run
`make clangformat`.

View File

@ -1,4 +1,4 @@
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
awesome-widgets
Copyright (C) 2013-2014 Evgeniy Alekseev
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
awesome-widgets Copyright (C) 2013 Evgeniy Alekseev
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

View File

@ -66,9 +66,9 @@ See [milestones](https://github.com/arcan1s/awesome-widgets/milestones) for more
Links
-----
* [Homepage](http://arcanis.name/projects/awesome-widgets/)
* [Migration to 2.*](http://arcanis.name/en/2014/09/04/migration-to-v2/)
* [Scripts and bars](http://arcanis.name/en/2014/12/19/aw-v21-bells-and-whistles/)
* [Homepage](https://arcanis.me/projects/awesome-widgets/)
* [Migration to 2.*](https://arcanis.me/en/2014/09/04/migration-to-v2/)
* [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)
* 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

View File

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

View File

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

View File

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

@ -0,0 +1,45 @@
diff --git a/sources/awdebug.cpp b/sources/awdebug.cpp
index eee61e1..9da8dad 100644
--- a/sources/awdebug.cpp
+++ b/sources/awdebug.cpp
@@ -20,13 +20,10 @@
#include "version.h"
-Q_LOGGING_CATEGORY(LOG_AW, "org.kde.plasma.awesomewidget",
- QtMsgType::QtWarningMsg)
-Q_LOGGING_CATEGORY(LOG_DP, "org.kde.plasma.desktoppanel",
- QtMsgType::QtWarningMsg)
-Q_LOGGING_CATEGORY(LOG_ESM, "org.kde.plasma.extsysmon", QtMsgType::QtWarningMsg)
-Q_LOGGING_CATEGORY(LOG_LIB, "org.kde.plasma.awesomewidgets",
- QtMsgType::QtWarningMsg)
+Q_LOGGING_CATEGORY(LOG_AW, "org.kde.plasma.awesomewidget")
+Q_LOGGING_CATEGORY(LOG_DP, "org.kde.plasma.desktoppanel")
+Q_LOGGING_CATEGORY(LOG_ESM, "org.kde.plasma.extsysmon")
+Q_LOGGING_CATEGORY(LOG_LIB, "org.kde.plasma.awesomewidgets")
const QStringList getBuildData()
diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/plugin/awkeys.cpp
index e5b9861..eb73073 100644
--- a/sources/awesome-widget/plugin/awkeys.cpp
+++ b/sources/awesome-widget/plugin/awkeys.cpp
@@ -439,4 +439,4 @@ void AWKeys::dataUpdated(const QString &sourceName,
// run concurrent data update
- QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, sourceName,
+ QtConcurrent::run(this, &AWKeys::setDataBySource, sourceName,
data);
diff --git a/sources/libraries.cmake b/sources/libraries.cmake
index 33192f7..46e2b1e 100644
--- a/sources/libraries.cmake
+++ b/sources/libraries.cmake
@@ -2,7 +2,7 @@
find_package(Gettext REQUIRED)
# main qt libraries
-find_package(Qt5 5.4.0 REQUIRED COMPONENTS Core DBus Network Qml Widgets)
+find_package(Qt5 5.3.0 REQUIRED COMPONENTS Core DBus Network Qml Widgets)
add_definitions(
${Qt5Core_DEFINITIONS} ${Qt5DBus_DEFINITIONS} ${Qt5Network_DEFINITIONS}
${Qt5Qml_DEFINITIONS} ${Qt5Widgets_DEFINITIONS}

View File

@ -0,0 +1,354 @@
diff --git a/sources/awesome-widget/package/contents/ui/advanced.qml b/sources/awesome-widget/package/contents/ui/advanced.qml
index 01bcd58..1ec7ba6 100644
--- a/sources/awesome-widget/package/contents/ui/advanced.qml
+++ b/sources/awesome-widget/package/contents/ui/advanced.qml
@@ -17,7 +17,6 @@
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
-import QtQuick.Dialogs 1.2 as QtDialogs
import org.kde.plasma.private.awesomewidget 1.0
@@ -372,32 +371,7 @@ Item {
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Export configuration")
- onClicked: saveConfigAs.open()
- }
-
- QtDialogs.FileDialog {
- id: saveConfigAs
- selectExisting: false
- title: i18n("Export")
- folder: awConfig.configurationDirectory()
- onAccepted: {
- var status = awConfig.exportConfiguration(
- plasmoid.configuration,
- saveConfigAs.fileUrl.toString().replace("file://", ""))
- if (status) {
- messageDialog.title = i18n("Success")
- messageDialog.text = i18n("Please note that binary files were not copied")
- } else {
- messageDialog.title = i18n("Ooops...")
- messageDialog.text = i18n("Could not save configuration file")
- }
- messageDialog.open()
- }
- }
-
- QtDialogs.MessageDialog {
- id: messageDialog
- standardButtons: QtDialogs.StandardButton.Ok
+ onClicked: awConfig.exportConfiguration(plasmoid.configuration)
}
}
@@ -410,42 +385,9 @@ Item {
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Import configuration")
- onClicked: openConfig.open()
- }
-
- QtDialogs.FileDialog {
- id: openConfig
- title: i18n("Import")
- folder: awConfig.configurationDirectory()
- onAccepted: importSelection.open()
- }
-
- QtDialogs.Dialog {
- id: importSelection
-
- Column {
- QtControls.CheckBox {
- id: importPlasmoid
- text: i18n("Import plasmoid settings")
- }
-
- QtControls.CheckBox {
- id: importExtensions
- text: i18n("Import extensions")
- }
-
- QtControls.CheckBox {
- id: importAdds
- text: i18n("Import additional files")
- }
- }
-
- onAccepted: {
+ onClicked: {
if (debug) console.debug()
- var importConfig = awConfig.importConfiguration(
- openConfig.fileUrl.toString().replace("file://", ""),
- importPlasmoid.checked, importExtensions.checked,
- importAdds.checked)
+ var importConfig = awConfig.importConfiguration()
for (var key in importConfig)
plasmoid.configuration[key] = importConfig[key]
}
diff --git a/sources/awesome-widget/package/contents/ui/main.qml b/sources/awesome-widget/package/contents/ui/main.qml
index 23e9690..ec83b91 100644
--- a/sources/awesome-widget/package/contents/ui/main.qml
+++ b/sources/awesome-widget/package/contents/ui/main.qml
@@ -17,7 +17,6 @@
import QtQuick 2.4
import QtQuick.Controls 1.3 as QtControls
-import QtQuick.Dialogs 1.2 as QtDialogs
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
@@ -110,27 +109,6 @@ Item {
}
}
- QtDialogs.Dialog {
- id: tagSelector
- title: i18n("Select tag")
-
- QtControls.ComboBox {
- id: tagSelectorBox
- width: parent.width
- editable: true
- }
-
- onAccepted: {
- var tag = tagSelectorBox.editText
- var message = i18n("Tag: %1", tag)
- message += "<br>"
- message += i18n("Value: %1", awKeys.valueByKey(tag))
- message += "<br>"
- message += i18n("Info: %1", awKeys.infoByKey(tag))
- awActions.sendNotification("tag", message)
- }
- }
-
Component.onCompleted: {
if (debug) console.debug()
@@ -216,7 +194,12 @@ Item {
function action_requestKey() {
if (debug) console.debug()
- tagSelectorBox.model = awKeys.dictKeys(true)
- return tagSelector.open()
+ var tag = awKeys.graphicalKey()
+ var message = i18n("Tag: %1", tag)
+ message += "<br>"
+ message += i18n("Value: %1", awKeys.valueByKey(tag))
+ message += "<br>"
+ message += i18n("Info: %1", awKeys.infoByKey(tag))
+ awActions.sendNotification("tag", message)
}
}
diff --git a/sources/awesome-widget/plugin/awconfighelper.cpp b/sources/awesome-widget/plugin/awconfighelper.cpp
index 6263b30..5f61d2a 100644
--- a/sources/awesome-widget/plugin/awconfighelper.cpp
+++ b/sources/awesome-widget/plugin/awconfighelper.cpp
@@ -19,10 +19,15 @@
#include <KI18n/KLocalizedString>
+#include <QCheckBox>
+#include <QDialogButtonBox>
#include <QDir>
+#include <QFileDialog>
+#include <QMessageBox>
#include <QQmlPropertyMap>
#include <QSettings>
#include <QTextCodec>
+#include <QVBoxLayout>
#include "awdebug.h"
@@ -50,11 +55,13 @@ bool AWConfigHelper::dropCache() const
}
-bool AWConfigHelper::exportConfiguration(QObject *nativeConfig,
- const QString fileName) const
+void AWConfigHelper::exportConfiguration(QObject *nativeConfig) const
{
- qCDebug(LOG_AW) << "Selected filename" << fileName;
-
+ // get file path and init settings object
+ QString fileName = QFileDialog::getSaveFileName(nullptr, i18n("Export"));
+ if (fileName.isEmpty())
+ return;
+ qCInfo(LOG_AW) << "Selected filename" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
// plasmoid configuration
@@ -96,22 +103,33 @@ bool AWConfigHelper::exportConfiguration(QObject *nativeConfig,
// sync settings
settings.sync();
// show additional message
- return settings.status() == QSettings::NoError;
+ switch (settings.status()) {
+ case QSettings::NoError:
+ QMessageBox::information(
+ nullptr, i18n("Success"),
+ i18n("Please note that binary files were not copied"));
+ break;
+ default:
+ QMessageBox::critical(nullptr, i18n("Ooops..."),
+ i18n("Could not save configuration file"));
+ break;
+ }
}
-QVariantMap AWConfigHelper::importConfiguration(const QString fileName,
- const bool importPlasmoid,
- const bool importExtensions,
- const bool importAdds) const
+QVariantMap AWConfigHelper::importConfiguration() const
{
- qCDebug(LOG_AW) << "Selected filename" << fileName;
-
QVariantMap configuration;
+ // get file path and init settings object
+ QString fileName = QFileDialog::getOpenFileName(nullptr, i18n("Import"));
+ if (fileName.isEmpty())
+ return configuration;
+ qCInfo(LOG_AW) << "Selected filename" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
+ QHash<QString, bool> selection = selectImport();
// extensions
- if (importExtensions) {
+ if (selection[QString("extensions")]) {
for (auto item : m_dirs) {
settings.beginGroup(item);
for (auto it : settings.childGroups())
@@ -121,7 +139,7 @@ QVariantMap AWConfigHelper::importConfiguration(const QString fileName,
}
// additional files
- if (importAdds) {
+ if (selection[QString("adds")]) {
settings.beginGroup(QString("json"));
// script filters
writeFile(settings, QString("filters"),
@@ -135,7 +153,7 @@ QVariantMap AWConfigHelper::importConfiguration(const QString fileName,
}
// plasmoid configuration
- if (importPlasmoid) {
+ if (selection[QString("plasmoid")]) {
settings.beginGroup(QString("plasmoid"));
for (auto key : settings.childKeys())
configuration[key] = settings.value(key);
@@ -261,6 +279,50 @@ void AWConfigHelper::readFile(QSettings &settings, const QString key,
}
+QHash<QString, bool> AWConfigHelper::selectImport() const
+{
+ QDialog *dialog = new QDialog(nullptr);
+ QCheckBox *importPlasmoidSettings
+ = new QCheckBox(i18n("Import plasmoid settings"), dialog);
+ importPlasmoidSettings->setChecked(true);
+ QCheckBox *importExtensionsSettings
+ = new QCheckBox(i18n("Import extensions"), dialog);
+ importExtensionsSettings->setChecked(true);
+ QCheckBox *importAddsSettings
+ = new QCheckBox(i18n("Import additional files"), dialog);
+ importAddsSettings->setChecked(true);
+ QDialogButtonBox *dialogButtons
+ = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
+ Qt::Horizontal, dialog);
+ QVBoxLayout *layout = new QVBoxLayout(dialog);
+ layout->addWidget(importPlasmoidSettings);
+ layout->addWidget(importExtensionsSettings);
+ layout->addWidget(importAddsSettings);
+ layout->addWidget(dialogButtons);
+ connect(dialogButtons, SIGNAL(accepted()), dialog, SLOT(accept()));
+ connect(dialogButtons, SIGNAL(rejected()), dialog, SLOT(reject()));
+
+ // get parameters
+ QHash<QString, bool> import;
+ import[QString("plasmoid")] = false;
+ import[QString("extensions")] = false;
+ import[QString("adds")] = false;
+ switch (dialog->exec()) {
+ case QDialog::Accepted:
+ import[QString("plasmoid")] = importPlasmoidSettings->isChecked();
+ import[QString("extensions")] = importExtensionsSettings->isChecked();
+ import[QString("adds")] = importAddsSettings->isChecked();
+ break;
+ case QDialog::Rejected:
+ default:
+ break;
+ }
+ dialog->deleteLater();
+
+ return import;
+}
+
+
void AWConfigHelper::writeFile(QSettings &settings, const QString key,
const QString fileName) const
{
diff --git a/sources/awesome-widget/plugin/awconfighelper.h b/sources/awesome-widget/plugin/awconfighelper.h
index 912ac3d..dc51dfb 100644
--- a/sources/awesome-widget/plugin/awconfighelper.h
+++ b/sources/awesome-widget/plugin/awconfighelper.h
@@ -33,13 +33,9 @@ public:
explicit AWConfigHelper(QObject *parent = nullptr);
virtual ~AWConfigHelper();
Q_INVOKABLE QString configurationDirectory() const;
Q_INVOKABLE bool dropCache() const;
- Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig,
- const QString fileName) const;
- Q_INVOKABLE QVariantMap importConfiguration(const QString fileName,
- const bool importPlasmoid,
- const bool importExtensions,
- const bool importAdds) const;
+ Q_INVOKABLE void exportConfiguration(QObject *nativeConfig) const;
+ Q_INVOKABLE QVariantMap importConfiguration() const;
// dataengine
Q_INVOKABLE QVariantMap readDataEngineConfiguration() const;
Q_INVOKABLE void
@@ -51,6 +47,7 @@ private:
void copySettings(QSettings &from, QSettings &to) const;
void readFile(QSettings &settings, const QString key,
const QString fileName) const;
+ QHash<QString, bool> selectImport() const;
void writeFile(QSettings &settings, const QString key,
const QString fileName) const;
// properties
diff --git a/sources/awesome-widget/plugin/awkeys.cpp b/sources/awesome-widget/plugin/awkeys.cpp
index e5b9861..039d24e 100644
--- a/sources/awesome-widget/plugin/awkeys.cpp
+++ b/sources/awesome-widget/plugin/awkeys.cpp
@@ -324,6 +324,14 @@ QStringList AWKeys::getHddDevices() const
}
+#include <QInputDialog>
+QString AWKeys::graphicalKey() const
+{
+ return QInputDialog::getItem(nullptr, i18n("Select tag"), QString(),
+ dictKeys(true), 0, true);
+}
+
+
QString AWKeys::infoByKey(QString key) const
{
qCDebug(LOG_AW) << "Requested info for key" << key;
diff --git a/sources/awesome-widget/plugin/awkeys.h b/sources/awesome-widget/plugin/awkeys.h
index a8300f1..8edc3bd 100644
--- a/sources/awesome-widget/plugin/awkeys.h
+++ b/sources/awesome-widget/plugin/awkeys.h
@@ -55,6 +55,7 @@ public:
Q_INVOKABLE QStringList dictKeys(const bool sorted = false,
const QString regexp = QString()) const;
Q_INVOKABLE QStringList getHddDevices() const;
+ Q_INVOKABLE QString graphicalKey() const;
// values
Q_INVOKABLE QString infoByKey(QString key) const;
Q_INVOKABLE QString valueByKey(QString key) const;

View File

@ -0,0 +1,31 @@
diff --git a/sources/awesome-widget/plugin/awkeysaggregator.h b/sources/awesome-widget/plugin/awkeysaggregator.h
index f808d03..a056b3f 100644
--- a/sources/awesome-widget/plugin/awkeysaggregator.h
+++ b/sources/awesome-widget/plugin/awkeysaggregator.h
@@ -21,6 +21,7 @@
#include <QHash>
#include <QObject>
+#include <QStringList>
#include "version.h"
diff --git a/sources/awdebug.h b/sources/awdebug.h
index 43944ce..c679281 100644
--- a/sources/awdebug.h
+++ b/sources/awdebug.h
@@ -21,9 +21,13 @@
#include <QLoggingCategory>
+#ifndef qCInfo
+#define qCInfo qCDebug
+#endif
+
#ifndef LOG_FORMAT
#define LOG_FORMAT \
- "[%{time process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%{if-" \
+ "[%{time process}][%{if-debug}DD%{endif}%{if-" \
"warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{" \
"category}][%{function}] %{message}"
#endif /* LOG_FORMAT */

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;
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

66
sources/.clang-format Normal file
View File

@ -0,0 +1,66 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: true
AlignConsecutiveAssignments: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Linux
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

View File

@ -8,7 +8,7 @@ ProjectRootRelative=./
[CMake][CMake Build Directory 0]
Build Directory Path=file:///home/arcanis/Documents/github/awesome-widgets/build
Build Type=Release
Build Type=Optimization
CMake Binary=file:///usr/bin/cmake
Environment Profile=
Extra Arguments=

View File

@ -1,218 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>About</class>
<widget class="QWidget" name="About">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>359</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_About">
<attribute name="title">
<string>About</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QScrollArea" name="scrollArea_about">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_about">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>418</width>
<height>284</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_name">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_version">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_description">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_links">
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
</widget>
</item>
<item>
<spacer name="spacer_about">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_ackn">
<attribute name="title">
<string>Acknowledgement</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QScrollArea" name="scrollArea_ackn">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_ackn">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>418</width>
<height>284</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_translators">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_trdparty">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
</widget>
</item>
<item>
<spacer name="spacer_ackn">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>229</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QLabel" name="label_license">
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

Submodule sources/3rdparty/task deleted from d2798204a1

Submodule sources/3rdparty/tasks deleted from 230bdecd2c

View File

@ -7,16 +7,19 @@ cmake_policy(SET CMP0011 NEW)
cmake_policy(SET CMP0015 NEW)
if (POLICY CMP0063)
cmake_policy(SET CMP0063 OLD)
endif()
endif ()
project(awesomewidgets)
set(PROJECT_AUTHOR "Evgeniy Alekseev")
set(PROJECT_CONTACT "esalexeev@gmail.com")
set(PROJECT_LICENSE "GPL3")
set(PROJECT_VERSION_MAJOR "2")
set(PROJECT_VERSION_MINOR "4")
set(PROJECT_VERSION_MAJOR "3")
set(PROJECT_VERSION_MINOR "1")
set(PROJECT_VERSION_PATCH "0")
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
# append git version if any
set(PROJECT_COMMIT_SHA "Commit hash" CACHE INTERNAL "")
include(checkgit.cmake)
string(TIMESTAMP CURRENT_DATE "%Y-%m-%d %H:%M" UTC)
string(TIMESTAMP CURRENT_YEAR "%Y")
@ -25,43 +28,59 @@ message(STATUS "Project: ${PROJECT_NAME}")
message(STATUS "Version: ${PROJECT_VERSION}")
message(STATUS "Build date: ${CURRENT_DATE}")
# components
option(BUILD_PLASMOIDS "Build plasmoids" ON)
option(BUILD_DEB_PACKAGE "Build deb package" OFF)
option(BUILD_RPM_PACKAGE "Build rpm package" OFF)
# build details
option(BUILD_FUTURE "Build with the features which will be marked as stable later" OFF)
option(BUILD_TESTING "Build with additional test abilities" OFF)
# some additional targets
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")
# generate changelog
set(PROJECT_CHANGELOG "Changelog" CACHE INTERNAL "")
include(changelog.cmake)
# flags
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-Wall -Wno-cpp -std=c++11")
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-Wall -Wno-cpp -std=c++14")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG")
# avoid newer gcc warnings
add_definitions(-D_DEFAULT_SOURCE)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -stdlib=libc++")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "-Wall -std=c++14 -stdlib=libc++")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG")
# linker flags
set(CMAKE_EXE_LINKER_FLAGS "-lc++abi")
set(CMAKE_MODULE_LINKER_FLAGS "-lc++abi")
set(CMAKE_SHARED_LINKER_FLAGS "-lc++abi")
else()
else ()
message(FATAL_ERROR "Unknown compiler")
endif()
if(CMAKE_BUILD_TYPE MATCHES Debug)
endif ()
if (CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_VERBOSE_MAKEFILE ON)
endif()
endif ()
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
set(PROJECT_TRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty)
set(PROJECT_LIBRARY awesomewidgets)
include(libraries.cmake)
include(clang-format.cmake)
include(cppcheck.cmake)
get_directory_property(CMAKE_DEFINITIONS COMPILE_DEFINITIONS)
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
add_subdirectory(awesomewidgets)
add_subdirectory(extsysmon)
if(BUILD_PLASMOIDS)
if (BUILD_PLASMOIDS)
add_subdirectory(awesome-widget)
add_subdirectory(desktop-panel)
add_subdirectory(translations)
endif()
endif ()
include(packages-recipe.cmake)

View File

@ -17,9 +17,68 @@
#include "awdebug.h"
#include "version.h"
Q_LOGGING_CATEGORY(LOG_AW, "org.kde.plasma.awesomewidget", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_DP, "org.kde.plasma.desktoppanel", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_AW, "org.kde.plasma.awesomewidget",
QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_DP, "org.kde.plasma.desktoppanel",
QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_ESM, "org.kde.plasma.extsysmon", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_LIB, "org.kde.plasma.awesomewidgets", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_LIB, "org.kde.plasma.awesomewidgets",
QtMsgType::QtWarningMsg)
const QStringList getBuildData()
{
QStringList metadata;
metadata.append(QString("=== Awesome Widgets configuration details ==="));
// build information
metadata.append(QString("Build details:"));
metadata.append(QString(" VERSION: %1").arg(VERSION));
metadata.append(QString(" COMMIT_SHA: %1").arg(COMMIT_SHA));
metadata.append(QString(" BUILD_DATE: %1").arg(BUILD_DATE));
// configuration
metadata.append(QString("API details:"));
metadata.append(QString(" AWGIAPI: %1").arg(AWGIAPI));
metadata.append(QString(" AWEQAPI: %1").arg(AWEQAPI));
metadata.append(QString(" AWESAPI: %1").arg(AWESAPI));
metadata.append(QString(" AWEUAPI: %1").arg(AWEUAPI));
metadata.append(QString(" AWEWAPI: %1").arg(AWEWAPI));
metadata.append(QString(" TIME_KEYS: %1").arg(TIME_KEYS));
// cmake properties
metadata.append(QString("cmake properties:"));
metadata.append(QString(" CMAKE_BUILD_TYPE: %1").arg(CMAKE_BUILD_TYPE));
metadata.append(
QString(" CMAKE_CXX_COMPILER: %1").arg(CMAKE_CXX_COMPILER));
metadata.append(QString(" CMAKE_CXX_FLAGS: %1").arg(CMAKE_CXX_FLAGS));
metadata.append(
QString(" CMAKE_CXX_FLAGS_DEBUG: %1").arg(CMAKE_CXX_FLAGS_DEBUG));
metadata.append(QString(" CMAKE_CXX_FLAGS_RELEASE: %1")
.arg(CMAKE_CXX_FLAGS_RELEASE));
metadata.append(QString(" CMAKE_CXX_FLAGS_OPTIMIZATION: %1")
.arg(CMAKE_CXX_FLAGS_OPTIMIZATION));
metadata.append(
QString(" CMAKE_DEFINITIONS: %1").arg(CMAKE_DEFINITIONS));
metadata.append(
QString(" CMAKE_INSTALL_PREFIX: %1").arg(CMAKE_INSTALL_PREFIX));
metadata.append(QString(" CMAKE_MODULE_LINKER_FLAGS: %1")
.arg(CMAKE_MODULE_LINKER_FLAGS));
metadata.append(QString(" CMAKE_SHARED_LINKER_FLAGS: %1")
.arg(CMAKE_SHARED_LINKER_FLAGS));
// components
metadata.append(QString("Components data:"));
metadata.append(QString(" BUILD_PLASMOIDS: %1").arg(BUILD_PLASMOIDS));
metadata.append(
QString(" BUILD_DEB_PACKAGE: %1").arg(BUILD_DEB_PACKAGE));
metadata.append(
QString(" BUILD_RPM_PACKAGE: %1").arg(BUILD_RPM_PACKAGE));
metadata.append(
QString(" CLANGFORMAT_EXECUTABLE: %1").arg(CLANGFORMAT_EXECUTABLE));
metadata.append(
QString(" CPPCHECK_EXECUTABLE: %1").arg(CPPCHECK_EXECUTABLE));
metadata.append(QString(" PROP_FUTURE: %1").arg(PROP_FUTURE));
metadata.append(QString(" PROP_TEST: %1").arg(PROP_TEST));
return metadata;
}

View File

@ -22,24 +22,19 @@
#include <QLoggingCategory>
#ifndef LOG_FORMAT
#define LOG_FORMAT "[%{time yyyy-MM-ddTHH:mm:ss.zzz}][%{if-debug}DD%{endif}%{if-info}II%{endif}%{if-warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{category}][%{function}] %{message}"
#define LOG_FORMAT \
"[%{time process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%{if-" \
"warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{" \
"category}][%{function}] %{message}"
#endif /* LOG_FORMAT */
// define info log level
// #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
// #ifndef qCInfo
// redefine info because it doesn't log properly
#ifdef qCInfo
#undef qCInfo
#endif /* qCInfo */
#define qCInfo qCDebug
// #endif /* QT_VERSION */
Q_DECLARE_LOGGING_CATEGORY(LOG_AW)
Q_DECLARE_LOGGING_CATEGORY(LOG_DP)
Q_DECLARE_LOGGING_CATEGORY(LOG_ESM)
Q_DECLARE_LOGGING_CATEGORY(LOG_LIB)
const QStringList getBuildData();
#endif /* AWDEBUG_H */

View File

@ -21,7 +21,7 @@ X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis
X-KDE-PluginInfo-Email=esalexeev@gmail.com
X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget
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-Depends=
X-KDE-PluginInfo-License=GPLv3

View File

@ -3,132 +3,141 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name=""/>
<kcfgfile name=""/>
<group name="Widget">
<!-- widget -->
<entry name="text" type="string">
<default>[cpu: $cpu%] [mem: $mem%] [swap: $swap%] [$netdev: $down/$upKB/s]</default>
</entry>
</group>
<group name="Widget">
<!-- widget -->
<entry name="text" type="string">
<default>[cpu: $cpu%] [mem: $mem%] [swap: $swap%] [$netdev: $down/$upKB/s]</default>
</entry>
</group>
<group name="Advanced">
<!-- advanced -->
<entry name="height" type="int">
<default>0</default>
</entry>
<entry name="width" type="int">
<default>0</default>
</entry>
<entry name="notify" type="bool">
<default>true</default>
</entry>
<entry name="wrapNewLines" type="bool">
<default>false</default>
</entry>
<entry name="background" type="bool">
<default>true</default>
</entry>
<entry name="customTime" type="string">
<default>$hh:$mm</default>
</entry>
<entry name="customUptime" type="string">
<default>$dd,$hh,$mm</default>
</entry>
<entry name="tempUnits" type="string">
<default>Celsius</default>
</entry>
<entry name="acOnline" type="string">
<default>(*)</default>
</entry>
<entry name="acOffline" type="string">
<default>( )</default>
</entry>
<entry name="checkUpdates" type="bool">
<default>true</default>
</entry>
<entry name="translateStrings" type="bool">
<default>true</default>
</entry>
</group>
<group name="Advanced">
<!-- advanced -->
<entry name="background" type="bool">
<default>true</default>
</entry>
<entry name="translateStrings" type="bool">
<default>true</default>
</entry>
<entry name="wrapNewLines" type="bool">
<default>false</default>
</entry>
<entry name="wrapText" type="bool">
<default>false</default>
</entry>
<entry name="notify" type="bool">
<default>true</default>
</entry>
<entry name="checkUpdates" type="bool">
<default>true</default>
</entry>
<entry name="optimize" type="bool">
<default>true</default>
</entry>
<entry name="height" type="int">
<default>0</default>
</entry>
<entry name="width" type="int">
<default>0</default>
</entry>
<entry name="interval" type="int">
<default>1000</default>
</entry>
<entry name="queueLimit" type="int">
<default>0</default>
</entry>
<entry name="tempUnits" type="string">
<default>Celsius</default>
</entry>
<entry name="customTime" type="string">
<default>$hh:$mm</default>
</entry>
<entry name="customUptime" type="string">
<default>$dd,$hh,$mm</default>
</entry>
<entry name="acOnline" type="string">
<default>(*)</default>
</entry>
<entry name="acOffline" type="string">
<default>( )</default>
</entry>
</group>
<group name="Tooltip">
<entry name="tooltipNumber" type="int">
<default>100</default>
</entry>
<entry name="useTooltipBackground" type="bool">
<default>true</default>
</entry>
<entry name="tooltipBackground" type="string">
<default>#ffffff</default>
</entry>
<entry name="cpuTooltip" type="bool">
<default>true</default>
</entry>
<entry name="cpuTooltipColor" type="string">
<default>#ff0000</default>
</entry>
<entry name="cpuclTooltip" type="bool">
<default>true</default>
</entry>
<entry name="cpuclTooltipColor" type="string">
<default>#00ff00</default>
</entry>
<entry name="memTooltip" type="bool">
<default>true</default>
</entry>
<entry name="memTooltipColor" type="string">
<default>#0000ff</default>
</entry>
<entry name="swapTooltip" type="bool">
<default>true</default>
</entry>
<entry name="swapTooltipColor" type="string">
<default>#ffff00</default>
</entry>
<entry name="downTooltip" type="bool">
<default>true</default>
</entry>
<entry name="downTooltipColor" type="string">
<default>#00ffff</default>
</entry>
<entry name="upTooltipColor" type="string">
<default>#ff00ff</default>
</entry>
<entry name="batTooltip" type="bool">
<default>true</default>
</entry>
<entry name="batTooltipColor" type="string">
<default>#008800</default>
</entry>
<entry name="batInTooltipColor" type="string">
<default>#880000</default>
</entry>
</group>
<group name="Tooltip">
<entry name="tooltipNumber" type="int">
<default>100</default>
</entry>
<entry name="useTooltipBackground" type="bool">
<default>true</default>
</entry>
<entry name="tooltipBackground" type="string">
<default>#ffffff</default>
</entry>
<entry name="cpuTooltip" type="bool">
<default>true</default>
</entry>
<entry name="cpuTooltipColor" type="string">
<default>#ff0000</default>
</entry>
<entry name="cpuclTooltip" type="bool">
<default>true</default>
</entry>
<entry name="cpuclTooltipColor" type="string">
<default>#00ff00</default>
</entry>
<entry name="memTooltip" type="bool">
<default>true</default>
</entry>
<entry name="memTooltipColor" type="string">
<default>#0000ff</default>
</entry>
<entry name="swapTooltip" type="bool">
<default>true</default>
</entry>
<entry name="swapTooltipColor" type="string">
<default>#ffff00</default>
</entry>
<entry name="downkbTooltip" type="bool">
<default>true</default>
</entry>
<entry name="downkbTooltipColor" type="string">
<default>#00ffff</default>
</entry>
<entry name="upkbTooltipColor" type="string">
<default>#ff00ff</default>
</entry>
<entry name="batTooltip" type="bool">
<default>true</default>
</entry>
<entry name="batTooltipColor" type="string">
<default>#008800</default>
</entry>
<entry name="batInTooltipColor" type="string">
<default>#880000</default>
</entry>
</group>
<group name="Appearance">
<!-- appearance -->
<entry name="interval" type="int">
<default>1000</default>
</entry>
<entry name="textAlign" type="string">
<default>center</default>
</entry>
<entry name="fontFamily" type="string">
<default>Terminus</default>
</entry>
<entry name="fontSize" type="int">
<default>12</default>
</entry>
<entry name="fontColor" type="string">
<default>#000000</default>
</entry>
<entry name="fontWeight" type="string">
<default>normal</default>
</entry>
<entry name="fontStyle" type="string">
<default>normal</default>
</entry>
</group>
<group name="Appearance">
<!-- appearance -->
<entry name="textAlign" type="string">
<default>center</default>
</entry>
<entry name="fontFamily" type="string">
<default>Terminus</default>
</entry>
<entry name="fontSize" type="int">
<default>12</default>
</entry>
<entry name="fontColor" type="string">
<default>#000000</default>
</entry>
<entry name="fontWeight" type="string">
<default>normal</default>
</entry>
<entry name="fontStyle" type="string">
<default>normal</default>
</entry>
</group>
</kcfg>

View File

@ -25,7 +25,7 @@ import org.kde.plasma.private.awesomewidget 1.0
Item {
id: aboutPage
AWActions {
id: awActions;
id: awActions
}
width: childrenRect.width
@ -43,6 +43,7 @@ Item {
height: parent.height
width: parent.width
QtControls.Tab {
anchors.margins: 10.0
title: i18n("About")
QtLayouts.ColumnLayout {
@ -85,6 +86,7 @@ Item {
}
QtControls.Tab {
anchors.margins: 10.0
title: i18n("Acknowledgment")
QtLayouts.ColumnLayout {
@ -95,13 +97,23 @@ Item {
text: awActions.getAboutText("translators")
}
QtControls.Label {
QtLayouts.Layout.fillWidth: true
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignJustify
textFormat: Text.RichText
text: awActions.getAboutText("3rdparty")
onLinkActivated: Qt.openUrlExternally(link);
}
QtControls.Label {
QtLayouts.Layout.fillHeight: true
QtLayouts.Layout.fillWidth: true
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignJustify
verticalAlignment: Text.AlignTop
textFormat: Text.RichText
text: awActions.getAboutText("3rdparty")
text: awActions.getAboutText("thanks")
onLinkActivated: Qt.openUrlExternally(link);
}
}
@ -109,6 +121,7 @@ Item {
}
}
Component.onCompleted: {
if (debug) console.debug()
}

View File

@ -17,6 +17,7 @@
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import QtQuick.Dialogs 1.2 as QtDialogs
import org.kde.plasma.private.awesomewidget 1.0
@ -25,7 +26,10 @@ Item {
id: advancedPage
// backend
AWActions {
id: awActions;
id: awActions
}
AWConfigHelper {
id: awConfig
}
width: childrenRect.width
@ -35,23 +39,125 @@ Item {
property bool debug: awActions.isDebugEnabled()
property alias cfg_background: background.checked
property alias cfg_translateStrings: translate.checked
property alias cfg_wrapNewLines: wrapNewLines.checked
property alias cfg_wrapText: wordWrap.checked
property alias cfg_notify: notify.checked
property alias cfg_checkUpdates: updates.checked
property alias cfg_optimize: optimize.checked
property alias cfg_height: widgetHeight.value
property alias cfg_width: widgetWidth.value
property alias cfg_notify: notify.checked
property alias cfg_wrapNewLines: wrapNewLines.checked
property alias cfg_background: background.checked
property alias cfg_interval: update.value
property alias cfg_queueLimit: queueLimit.value
property string cfg_tempUnits: tempUnits.currentText
property alias cfg_customTime: customTime.text
property alias cfg_customUptime: customUptime.text
property string cfg_tempUnits: tempUnits.currentText
property alias cfg_acOnline: acOnline.text
property alias cfg_acOffline: acOffline.text
property alias cfg_checkUpdates: updates.checked
property alias cfg_translateStrings: translate.checked
Column {
id: pageColumn
anchors.fill: parent
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: background
width: parent.width * 3 / 5
text: i18n("Enable background")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: translate
width: parent.width * 3 / 5
text: i18n("Translate strings")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: wrapNewLines
width: parent.width * 3 / 5
text: i18n("Wrap new lines")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: wordWrap
width: parent.width * 3 / 5
text: i18n("Enable word wrap")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: notify
width: parent.width * 3 / 5
text: i18n("Enable notifications")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: updates
width: parent.width * 3 / 5
text: i18n("Check updates on startup")
}
}
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 {
height: implicitHeight
width: parent.width
@ -96,41 +202,19 @@ Item {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Time interval")
}
QtControls.CheckBox {
id: notify
QtControls.SpinBox {
id: update
width: parent.width * 3 / 5
text: i18n("Enable notifications")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: wrapNewLines
width: parent.width * 3 / 5
text: i18n("Wrap new lines")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: background
width: parent.width * 3 / 5
text: i18n("Enable background")
minimumValue: 1000
maximumValue: 10000
stepSize: 500
value: plasmoid.configuration.interval
}
}
@ -142,29 +226,15 @@ Item {
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom time format")
text: i18n("Messages queue limit")
}
QtControls.TextField {
id: customTime
QtControls.SpinBox {
id: queueLimit
width: parent.width * 3 / 5
text: plasmoid.configuration.customTime
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom uptime format")
}
QtControls.TextField {
id: customUptime
width: parent.width * 3 / 5
text: plasmoid.configuration.customUptime
minimumValue: 0
maximumValue: 99
stepSize: 1
value: plasmoid.configuration.queueLimit
}
}
@ -225,6 +295,40 @@ Item {
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom time format")
}
QtControls.TextField {
id: customTime
width: parent.width * 3 / 5
text: plasmoid.configuration.customTime
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom uptime format")
}
QtControls.TextField {
id: customUptime
width: parent.width * 3 / 5
text: plasmoid.configuration.customUptime
}
}
Row {
height: implicitHeight
width: parent.width
@ -263,27 +367,13 @@ Item {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
height: parent.height
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: updates
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Check updates on startup")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: translate
width: parent.width * 3 / 5
text: i18n("Translate strings")
text: i18n("Drop key cache")
onClicked: awActions.dropCache()
}
}
@ -295,14 +385,91 @@ Item {
width: parent.width * 2 / 5
}
QtControls.Button {
id: selectFont
width: parent.width * 3 / 5
text: i18n("Drop key cache")
onClicked: awActions.dropCache()
text: i18n("Export configuration")
onClicked: saveConfigAs.open()
}
QtDialogs.FileDialog {
id: saveConfigAs
selectExisting: false
title: i18n("Export")
folder: awConfig.configurationDirectory()
onAccepted: {
var status = awConfig.exportConfiguration(
plasmoid.configuration,
saveConfigAs.fileUrl.toString().replace("file://", ""))
if (status) {
messageDialog.title = i18n("Success")
messageDialog.text = i18n("Please note that binary files were not copied")
} else {
messageDialog.title = i18n("Ooops...")
messageDialog.text = i18n("Could not save configuration file")
}
messageDialog.open()
}
}
QtDialogs.MessageDialog {
id: messageDialog
standardButtons: QtDialogs.StandardButton.Ok
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Import configuration")
onClicked: openConfig.open()
}
QtDialogs.FileDialog {
id: openConfig
title: i18n("Import")
folder: awConfig.configurationDirectory()
onAccepted: importSelection.open()
}
QtDialogs.Dialog {
id: importSelection
Column {
QtControls.CheckBox {
id: importPlasmoid
text: i18n("Import plasmoid settings")
}
QtControls.CheckBox {
id: importExtensions
text: i18n("Import extensions")
}
QtControls.CheckBox {
id: importAdds
text: i18n("Import additional files")
}
}
onAccepted: {
if (debug) console.debug()
var importConfig = awConfig.importConfiguration(
openConfig.fileUrl.toString().replace("file://", ""),
importPlasmoid.checked, importExtensions.checked,
importAdds.checked)
for (var key in importConfig)
plasmoid.configuration[key] = importConfig[key]
}
}
}
}
Component.onCompleted: {
if (debug) console.debug()
}

View File

@ -27,7 +27,7 @@ Item {
id: appearancePage
// backend
AWActions {
id: awActions;
id: awActions
}
width: childrenRect.width
@ -44,7 +44,6 @@ Item {
87: 5
}
property alias cfg_interval: update.value
property alias cfg_fontFamily: selectFont.text
property alias cfg_fontSize: fontSize.value
property string cfg_fontWeight: fontWeight.currentText
@ -55,26 +54,6 @@ Item {
Column {
id: pageColumn
anchors.fill: parent
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width / 3
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Time interval")
}
QtControls.SpinBox {
id: update
width: parent.width * 2 / 3
minimumValue: 1000
maximumValue: 10000
stepSize: 500
value: plasmoid.configuration.interval
}
}
Row {
height: implicitHeight
width: parent.width
@ -257,6 +236,7 @@ Item {
}
}
Component.onCompleted: {
if (debug) console.debug()
}

View File

@ -16,10 +16,8 @@
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0 as QtControls
import QtQuick.Controls 1.3 as QtControls
import QtQuick.Dialogs 1.1 as QtDialogs
import QtQuick.Layouts 1.0 as QtLayouts
import QtQuick.Controls.Styles 1.3 as QtStyles
import org.kde.plasma.private.awesomewidget 1.0
@ -28,10 +26,13 @@ Item {
id: dataenginePage
// backend
AWKeys {
id: awKeys;
id: awKeys
}
AWActions {
id: awActions;
id: awActions
}
AWConfigHelper {
id: awConfig
}
width: childrenRect.width
@ -41,274 +42,312 @@ Item {
property bool debug: awActions.isDebugEnabled()
property variant cfg_dataengine: awActions.readDataEngineConfiguration()
property variant cfg_dataengine: awConfig.readDataEngineConfiguration()
Column {
id: pageColumn
anchors.fill: parent
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("ACPI path")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["ACPIPATH"]
onEditingFinished: cfg_dataengine["ACPIPATH"] = text
title: i18n("ACPI")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("ACPI path")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["ACPIPATH"]
onEditingFinished: cfg_dataengine["ACPIPATH"] = text
}
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("GPU device")
}
QtControls.ComboBox {
id: gpuDev
width: parent.width * 3 / 5
model: ["auto", "disable", "ati", "nvidia"]
Component.onCompleted: {
if (debug) console.debug()
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["GPUDEV"]) {
if (debug) console.info("Found", model[i], "on", i)
currentIndex = i;
title: i18n("GPU")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("GPU device")
}
QtControls.ComboBox {
id: gpuDev
width: parent.width * 3 / 5
model: ["auto", "disable", "ati", "nvidia"]
Component.onCompleted: {
if (debug) console.debug()
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["GPUDEV"]) {
if (debug) console.info("Found", model[i], "on", i)
currentIndex = i;
}
}
}
}
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("HDD")
}
QtControls.ComboBox {
id: hdd
width: parent.width * 3 / 5
model: awKeys.getHddDevices(true)
Component.onCompleted: {
if (debug) console.debug()
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["HDDDEV"]) {
if (debug) console.info("Found", model[i], "on", i)
hdd.currentIndex = i;
}
title: i18n("HDD temperature")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("HDD")
}
QtControls.ComboBox {
id: hdd
width: parent.width * 3 / 5
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("hddtemp cmd")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["HDDTEMPCMD"]
onEditingFinished: cfg_dataengine["HDDTEMPCMD"] = text
}
}
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("hddtemp cmd")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["HDDTEMPCMD"]
onEditingFinished: cfg_dataengine["HDDTEMPCMD"] = text
}
}
title: i18n("Player")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Player data symbols")
}
QtControls.SpinBox {
width: parent.width * 3 / 5
minimumValue: 1
maximumValue: 100
stepSize: 1
value: cfg_dataengine["PLAYERSYMBOLS"]
onEditingFinished: cfg_dataengine["PLAYERSYMBOLS"] = value
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPD address")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["MPDADDRESS"]
onEditingFinished: cfg_dataengine["MPDADDRESS"] = text
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPD port")
}
QtControls.SpinBox {
width: parent.width * 3 / 5
minimumValue: 1000
maximumValue: 65535
stepSize: 1
value: cfg_dataengine["MPDPORT"]
onEditingFinished: cfg_dataengine["MPDPORT"] = value
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPRIS player name")
}
QtControls.ComboBox {
id: mpris
width: parent.width * 3 / 5
editable: true
model: ["auto", "amarok", "audacious", "clementine", "deadbeef",
"vlc", "qmmp", "xmms2", cfg_dataengine["MPRIS"]]
currentIndex: model.length - 1
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Music player")
}
QtControls.ComboBox {
id: player
width: parent.width * 3 / 5
model: ["disable", "mpris", "mpd"]
Component.onCompleted: {
if (debug) console.debug()
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["PLAYER"]) {
if (debug) console.info("Found", model[i], "on", i)
player.currentIndex = i;
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Music player")
}
QtControls.ComboBox {
id: player
width: parent.width * 3 / 5
model: ["disable", "mpris", "mpd"]
Component.onCompleted: {
if (debug) console.debug()
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["PLAYER"]) {
if (debug) console.info("Found", model[i], "on", i)
player.currentIndex = i;
}
}
}
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPRIS player name")
}
QtControls.ComboBox {
id: mpris
width: parent.width * 3 / 5
editable: true
model: ["auto", "amarok", "audacious", "clementine", "deadbeef",
"vlc", "qmmp", "xmms2", cfg_dataengine["MPRIS"]]
currentIndex: model.length - 1
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPD address")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["MPDADDRESS"]
onEditingFinished: cfg_dataengine["MPDADDRESS"] = text
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPD port")
}
QtControls.SpinBox {
width: parent.width * 3 / 5
minimumValue: 1000
maximumValue: 65535
stepSize: 1
value: cfg_dataengine["MPDPORT"]
onEditingFinished: cfg_dataengine["MPDPORT"] = value
}
}
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Player data symbols")
}
QtControls.SpinBox {
width: parent.width * 3 / 5
minimumValue: 1
maximumValue: 100
stepSize: 1
value: cfg_dataengine["PLAYERSYMBOLS"]
onEditingFinished: cfg_dataengine["PLAYERSYMBOLS"] = value
}
}
title: i18n("Extensions")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom scripts")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit scripts")
onClicked: awKeys.editItem("extscript")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom scripts")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit scripts")
onClicked: awKeys.editItem("extscript")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Quotes monitor")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit tickers")
onClicked: awKeys.editItem("extquotes")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Quotes monitor")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit tickers")
onClicked: awKeys.editItem("extquotes")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Package manager")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit command")
onClicked: awKeys.editItem("extupgrade")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Package manager")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit command")
onClicked: awKeys.editItem("extupgrade")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Weather")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit weather")
onClicked: awKeys.editItem("extweather")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Weather")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit weather")
onClicked: awKeys.editItem("extweather")
}
}
}
}
}
Component.onCompleted: {
if (debug) console.debug()
// init submodule
awKeys.initKeys(plasmoid.configuration.text)
awKeys.updateCache()
// update hdd model
hdd.model = awKeys.getHddDevices()
for (var i=0; i<hdd.model.length; i++) {
if (hdd.model[i] == cfg_dataengine["HDDDEV"]) {
if (debug) console.info("Found", hdd.model[i], "on", i)
hdd.currentIndex = i;
}
}
}
Component.onDestruction: {
@ -318,6 +357,6 @@ Item {
cfg_dataengine["HDDDEV"] = hdd.currentText
cfg_dataengine["PLAYER"] = player.currentText
cfg_dataengine["MPRIS"] = mpris.currentText
awActions.writeDataEngineConfiguration(cfg_dataengine)
awConfig.writeDataEngineConfiguration(cfg_dataengine)
}
}

View File

@ -17,6 +17,7 @@
import QtQuick 2.4
import QtQuick.Controls 1.3 as QtControls
import QtQuick.Dialogs 1.2 as QtDialogs
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
@ -30,20 +31,13 @@ Item {
id: main
// backend
AWKeys {
id: awKeys;
id: awKeys
}
AWActions {
id: awActions;
id: awActions
}
property bool debug: awActions.isDebugEnabled()
property variant settings: {
"customTime": plasmoid.configuration.customTime,
"customUptime": plasmoid.configuration.customUptime,
"tempUnits": plasmoid.configuration.tempUnits,
"acOnline": plasmoid.configuration.acOnline,
"acOffline": plasmoid.configuration.acOffline
}
property variant tooltipSettings: {
"tooltipNumber": plasmoid.configuration.tooltipNumber,
"useTooltipBackground": plasmoid.configuration.useTooltipBackground,
@ -52,22 +46,23 @@ Item {
"cpuclTooltip": plasmoid.configuration.cpuclTooltip,
"memTooltip": plasmoid.configuration.memTooltip,
"swapTooltip": plasmoid.configuration.swapTooltip,
"downTooltip": plasmoid.configuration.downTooltip,
"upTooltip": plasmoid.configuration.downTooltip,
"downkbTooltip": plasmoid.configuration.downkbTooltip,
"upkbTooltip": plasmoid.configuration.downkbTooltip,
"batTooltip": plasmoid.configuration.batTooltip,
"cpuTooltipColor": plasmoid.configuration.cpuTooltipColor,
"cpuclTooltipColor": plasmoid.configuration.cpuclTooltipColor,
"memTooltipColor": plasmoid.configuration.memTooltipColor,
"swapTooltipColor": plasmoid.configuration.swapTooltipColor,
"downTooltipColor": plasmoid.configuration.downTooltipColor,
"upTooltipColor": plasmoid.configuration.upTooltipColor,
"downkbTooltipColor": plasmoid.configuration.downkbTooltipColor,
"upkbTooltipColor": plasmoid.configuration.upkbTooltipColor,
"batTooltipColor": plasmoid.configuration.batTooltipColor,
"batInTooltipColor": plasmoid.configuration.batInTooltipColor,
// additinal field to parse AC status
"acOnline": plasmoid.configuration.acOnline
// additional field to parse AC status
"acOnline": plasmoid.configuration.acOnline,
// additional field to send notifications
"notify": plasmoid.configuration.notify
}
signal dropSource(string sourceName)
signal needTextUpdate(string newText)
signal needToolTipUpdate(string newText)
signal sizeUpdate
@ -85,53 +80,6 @@ Item {
Plasmoid.backgroundHints: plasmoid.configuration.background ? "DefaultBackground" : "NoBackground"
Plasmoid.associatedApplication: "ksysguard"
PlasmaCore.DataSource {
id: systemmonitorDE
engine: "systemmonitor"
connectedSources: systemmonitorDE.sources
interval: plasmoid.configuration.interval
onNewData: {
if (debug) console.debug("Update source", sourceName)
systemmonitorDE.interval = plasmoid.configuration.interval
awKeys.setDataBySource(sourceName, data, settings)
}
onSourceAdded: {
if (debug) console.debug("Source", source)
awKeys.addDevice(source)
}
}
PlasmaCore.DataSource {
id: extsysmonDE
engine: "extsysmon"
connectedSources: extsysmonDE.sources
interval: plasmoid.configuration.interval
onNewData: {
if (debug) console.debug("Update source", sourceName)
extsysmonDE.interval = plasmoid.configuration.interval
awKeys.setDataBySource(sourceName, data, settings)
}
}
PlasmaCore.DataSource {
id: timeDE
engine: "time"
connectedSources: ["Local"]
interval: 1000
onNewData: {
if (debug) console.debug("Update source", sourceName)
awKeys.setDataBySource(sourceName, data, settings)
}
}
// ui
Text {
@ -139,7 +87,7 @@ Item {
anchors.fill: parent
renderType: Text.NativeRendering
textFormat: Text.RichText
wrapMode: Text.NoWrap
wrapMode: plasmoid.configuration.wrapText ? Text.WordWrap : Text.NoWrap
horizontalAlignment: general.align[plasmoid.configuration.textAlign]
verticalAlignment: Text.AlignVCenter
@ -162,29 +110,44 @@ Item {
}
}
QtDialogs.Dialog {
id: tagSelector
title: i18n("Select tag")
QtControls.ComboBox {
id: tagSelectorBox
width: parent.width
editable: true
}
onAccepted: {
var tag = tagSelectorBox.editText
var message = i18n("Tag: %1", tag)
message += "<br>"
message += i18n("Value: %1", awKeys.valueByKey(tag))
message += "<br>"
message += i18n("Info: %1", awKeys.infoByKey(tag))
awActions.sendNotification("tag", message)
}
}
Component.onCompleted: {
if (debug) console.debug()
// actions
plasmoid.setAction("requestKey", i18n("Request key"), "utilities-system-monitor")
// 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("showReadme", i18n("Show README"), "text-x-readme")
plasmoid.setAction("checkUpdates", i18n("Check updates"), "system-software-update")
// plasmoid.setAction("report", i18n("Mail to developers"), "email")
// init submodule
Plasmoid.userConfiguringChanged(false)
// connect data
awKeys.dropSourceFromDataengine.connect(dropSource)
awKeys.needTextToBeUpdated.connect(needTextUpdate)
awKeys.needToolTipToBeUpdated.connect(needToolTipUpdate)
// check updates if required
if (plasmoid.configuration.checkUpdates) return action_checkUpdates()
}
onDropSource: {
if (debug) console.debug()
if (debug) console.debug("Source", sourceName)
systemmonitorDE.disconnectSource(sourceName)
if (plasmoid.configuration.checkUpdates) return awActions.checkUpdates(false)
}
onNeedTextUpdate: {
@ -226,17 +189,24 @@ Item {
if (debug) console.debug()
// init submodule
awKeys.initKeys(plasmoid.configuration.text)
awKeys.initTooltip(tooltipSettings)
awKeys.setPopupEnabled(plasmoid.configuration.notify)
awKeys.setTranslateStrings(plasmoid.configuration.translateStrings)
awKeys.initDataAggregator(tooltipSettings)
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit, plasmoid.configuration.optimize)
awKeys.setWrapNewLines(plasmoid.configuration.wrapNewLines)
// configure aggregator
awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline)
awKeys.setAggregatorProperty("acOnline", plasmoid.configuration.acOnline)
awKeys.setAggregatorProperty("customTime", plasmoid.configuration.customTime)
awKeys.setAggregatorProperty("customUptime", plasmoid.configuration.customUptime)
awKeys.setAggregatorProperty("tempUnits", plasmoid.configuration.tempUnits)
awKeys.setAggregatorProperty("translate", plasmoid.configuration.translateStrings)
}
function action_checkUpdates() {
if (debug) console.debug()
return awActions.checkUpdates()
return awActions.checkUpdates(true)
}
function action_showReadme() {
@ -245,15 +215,10 @@ Item {
return awActions.showReadme()
}
function action_report() {
if (debug) console.debug()
return awActions.sendEmail()
}
function action_requestKey() {
if (debug) console.debug()
return awKeys.graphicalValueByKey()
tagSelectorBox.model = awKeys.dictKeys(true)
return tagSelector.open()
}
}

View File

@ -27,7 +27,7 @@ Item {
id: tooltipPage
// backend
AWActions {
id: awActions;
id: awActions
}
width: childrenRect.width
@ -48,9 +48,9 @@ Item {
property alias cfg_memTooltipColor: memTooltipColor.text
property alias cfg_swapTooltip: swapTooltip.checked
property alias cfg_swapTooltipColor: swapTooltipColor.text
property alias cfg_downTooltip: downTooltip.checked
property alias cfg_downTooltipColor: downTooltipColor.text
property alias cfg_upTooltipColor: upTooltipColor.text
property alias cfg_downkbTooltip: downkbTooltip.checked
property alias cfg_downkbTooltipColor: downkbTooltipColor.text
property alias cfg_upkbTooltipColor: upkbTooltipColor.text
property alias cfg_batTooltip: batTooltip.checked
property alias cfg_batTooltipColor: batTooltipColor.text
property alias cfg_batInTooltipColor: batInTooltipColor.text
@ -64,7 +64,7 @@ Item {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
text: i18n("CPU, CPU clock, memory, swap and network labels support graphical tooltip. To enable them just make needed checkbox fully checked.")
text: i18n("CPU, CPU clock, memory, swap and network labels support graphical tooltip. To enable them just make needed checkbox checked.")
}
Row {
@ -87,431 +87,333 @@ Item {
}
}
Row {
QtControls.GroupBox {
id: useTooltipBackground
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - useTooltipBackground.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Background")
}
QtControls.CheckBox {
id: useTooltipBackground
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("Background")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Background color")
}
QtControls.Button {
id: tooltipBackground
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.tooltipBackground
}
}
text: plasmoid.configuration.tooltipBackground
onClicked: tooltipBackgroundDialog.visible = true
}
}
QtControls.Button {
id: tooltipBackground
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.tooltipBackground
}
}
text: plasmoid.configuration.tooltipBackground
onClicked: tooltipBackgroundDialog.visible = true
}
QtDialogs.ColorDialog {
id: tooltipBackgroundDialog
title: i18n("Select a color")
color: tooltipBackground.text
onAccepted: tooltipBackground.text = tooltipBackgroundDialog.color
QtDialogs.ColorDialog {
id: tooltipBackgroundDialog
title: i18n("Select a color")
color: tooltipBackground.text
onAccepted: tooltipBackground.text = tooltipBackgroundDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: cpuTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - cpuTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("CPU color")
}
QtControls.CheckBox {
id: cpuTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("CPU")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("CPU color")
}
QtControls.Button {
id: cpuTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.cpuTooltipColor
}
}
text: plasmoid.configuration.cpuTooltipColor
onClicked: cpuTooltipColorDialog.visible = true
}
}
QtControls.Button {
id: cpuTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.cpuTooltipColor
}
}
text: plasmoid.configuration.cpuTooltipColor
onClicked: cpuTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: cpuTooltipColorDialog
title: i18n("Select a color")
color: cpuTooltipColor.text
onAccepted: cpuTooltipColor.text = cpuTooltipColorDialog.color
QtDialogs.ColorDialog {
id: cpuTooltipColorDialog
title: i18n("Select a color")
color: cpuTooltipColor.text
onAccepted: cpuTooltipColor.text = cpuTooltipColorDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: cpuclTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - cpuclTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("CPU clock color")
}
QtControls.CheckBox {
id: cpuclTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("CPU clock")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("CPU clock color")
}
QtControls.Button {
id: cpuclTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.cpuclTooltipColor
}
}
text: plasmoid.configuration.cpuclTooltipColor
onClicked: cpuclTooltipColorDialog.visible = true
}
}
QtControls.Button {
id: cpuclTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.cpuclTooltipColor
}
}
text: plasmoid.configuration.cpuclTooltipColor
onClicked: cpuclTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: cpuclTooltipColorDialog
title: i18n("Select a color")
color: cpuclTooltipColor.text
onAccepted: cpuclTooltipColor.text = cpuclTooltipColorDialog.color
QtDialogs.ColorDialog {
id: cpuclTooltipColorDialog
title: i18n("Select a color")
color: cpuclTooltipColor.text
onAccepted: cpuclTooltipColor.text = cpuclTooltipColorDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: memTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - memTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Memory color")
}
QtControls.CheckBox {
id: memTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("Memory")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Memory color")
}
QtControls.Button {
id: memTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.memTooltipColor
}
}
text: plasmoid.configuration.memTooltipColor
onClicked: memTooltipColorDialog.visible = true
}
}
QtControls.Button {
id: memTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.memTooltipColor
}
}
text: plasmoid.configuration.memTooltipColor
onClicked: memTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: memTooltipColorDialog
title: i18n("Select a color")
color: memTooltipColor.text
onAccepted: memTooltipColor.text = memTooltipColorDialog.color
QtDialogs.ColorDialog {
id: memTooltipColorDialog
title: i18n("Select a color")
color: memTooltipColor.text
onAccepted: memTooltipColor.text = memTooltipColorDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: swapTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - swapTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Swap color")
}
QtControls.CheckBox {
id: swapTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("Swap")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Swap color")
}
QtControls.Button {
id: swapTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.swapTooltipColor
}
}
text: plasmoid.configuration.swapTooltipColor
onClicked: swapTooltipColorDialog.visible = true
}
}
QtControls.Button {
id: swapTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.swapTooltipColor
}
}
text: plasmoid.configuration.swapTooltipColor
onClicked: swapTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: swapTooltipColorDialog
title: i18n("Select a color")
color: swapTooltipColor.text
onAccepted: swapTooltipColor.text = swapTooltipColorDialog.color
QtDialogs.ColorDialog {
id: swapTooltipColorDialog
title: i18n("Select a color")
color: swapTooltipColor.text
onAccepted: swapTooltipColor.text = swapTooltipColorDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: downkbTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - downTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Download speed color")
}
QtControls.CheckBox {
id: downTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("Network")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Download speed color")
}
QtControls.Button {
id: downkbTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.downkbTooltipColor
}
}
text: plasmoid.configuration.downkbTooltipColor
onClicked: downkbTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: downkbTooltipColorDialog
title: i18n("Select a color")
color: downkbTooltipColor.text
onAccepted: downkbTooltipColor.text = downkbTooltipColorDialog.color
}
}
}
QtControls.Button {
id: downTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.downTooltipColor
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Upload speed color")
}
}
text: plasmoid.configuration.downTooltipColor
onClicked: downTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: downTooltipColorDialog
title: i18n("Select a color")
color: downTooltipColor.text
onAccepted: downTooltipColor.text = downTooltipColorDialog.color
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Upload speed color")
}
QtControls.Button {
id: upTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.upTooltipColor
}
}
text: plasmoid.configuration.upTooltipColor
onClicked: upTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: upTooltipColorDialog
title: i18n("Select a color")
color: upTooltipColor.text
onAccepted: upTooltipColor.text = upTooltipColorDialog.color
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - batTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Battery active color")
}
QtControls.CheckBox {
id: batTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
QtControls.Button {
id: upkbTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.upkbTooltipColor
}
}
text: plasmoid.configuration.upkbTooltipColor
onClicked: upkbTooltipColorDialog.visible = true
}
}
}
QtControls.Button {
id: batTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.batTooltipColor
}
}
text: plasmoid.configuration.batTooltipColor
onClicked: batTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: batTooltipColorDialog
title: i18n("Select a color")
color: batTooltipColor.text
onAccepted: batTooltipColor.text = batTooltipColorDialog.color
QtDialogs.ColorDialog {
id: upkbTooltipColorDialog
title: i18n("Select a color")
color: upkbTooltipColor.text
onAccepted: upkbTooltipColor.text = upkbTooltipColorDialog.color
}
}
}
}
Row {
QtControls.GroupBox {
id: batTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Battery inactive color")
}
QtControls.Button {
id: batInTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.batInTooltipColor
checkable: true
title: i18n("Battery")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Battery active color")
}
QtControls.Button {
id: batTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.batTooltipColor
}
}
text: plasmoid.configuration.batTooltipColor
onClicked: batTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: batTooltipColorDialog
title: i18n("Select a color")
color: batTooltipColor.text
onAccepted: batTooltipColor.text = batTooltipColorDialog.color
}
}
text: plasmoid.configuration.batInTooltipColor
onClicked: batInTooltipColorDialog.visible = true
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Battery inactive color")
}
QtControls.Button {
id: batInTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.batInTooltipColor
}
}
text: plasmoid.configuration.batInTooltipColor
onClicked: batInTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: batInTooltipColorDialog
title: i18n("Select a color")
color: batInTooltipColor.text
onAccepted: batInTooltipColor.text = batInTooltipColorDialog.color
QtDialogs.ColorDialog {
id: batInTooltipColorDialog
title: i18n("Select a color")
color: batInTooltipColor.text
onAccepted: batInTooltipColor.text = batInTooltipColorDialog.color
}
}
}
}
}
Component.onCompleted: {
if (debug) console.debug()
}

View File

@ -17,7 +17,7 @@
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import org.kde.plasma.core 2.0 as PlasmaCore
import QtQuick.Dialogs 1.2 as QtDialogs
import org.kde.plasma.private.awesomewidget 1.0
@ -26,10 +26,10 @@ Item {
id: widgetPage
// backend
AWKeys {
id: awKeys;
id: awKeys
}
AWActions {
id: awActions;
id: awActions
}
width: childrenRect.width
@ -38,35 +38,11 @@ Item {
implicitHeight: pageColumn.implicitHeight
property bool debug: awActions.isDebugEnabled()
property variant settings: {
"customTime": plasmoid.configuration.customTime,
"customUptime": plasmoid.configuration.customUptime,
"tempUnits": plasmoid.configuration.tempUnits,
"acOnline": plasmoid.configuration.acOnline,
"acOffline": plasmoid.configuration.acOffline
}
property variant tooltipSettings: {
"tooltipNumber": plasmoid.configuration.tooltipNumber,
"useTooltipBackground": plasmoid.configuration.useTooltipBackground,
"tooltipBackgroung": plasmoid.configuration.tooltipBackgroung,
"cpuTooltip": plasmoid.configuration.cpuTooltip,
"cpuclTooltip": plasmoid.configuration.cpuclTooltip,
"memTooltip": plasmoid.configuration.memTooltip,
"swapTooltip": plasmoid.configuration.swapTooltip,
"downTooltip": plasmoid.configuration.downTooltip,
"upTooltip": plasmoid.configuration.downTooltip,
"batTooltip": plasmoid.configuration.batTooltip,
"cpuTooltipColor": plasmoid.configuration.cpuTooltipColor,
"cpuclTooltipColor": plasmoid.configuration.cpuclTooltipColor,
"memTooltipColor": plasmoid.configuration.memTooltipColor,
"swapTooltipColor": plasmoid.configuration.swapTooltipColor,
"downTooltipColor": plasmoid.configuration.downTooltipColor,
"upTooltipColor": plasmoid.configuration.upTooltipColor,
"batTooltipColor": plasmoid.configuration.batTooltipColor,
"batInTooltipColor": plasmoid.configuration.batInTooltipColor
}
property alias cfg_text: textPattern.text
property bool lock: true
signal needTextUpdate(string newText)
Column {
@ -77,7 +53,7 @@ Item {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
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);
}
@ -222,7 +198,7 @@ Item {
height: implicitHeight
width: parent.width
QtControls.ComboBox {
width: (parent.width - addTagButton.width - showValueButton.width - addLambdaButton.width) / 2
width: parent.width * 2 / 5
textRole: "label"
model: [
{
@ -276,21 +252,30 @@ Item {
{
'label': i18n("Weathers"),
'regexp': "^(weather(Id)?|humidity|pressure|temperature|timestamp)"
},
{
'label': i18n("Functions"),
'regexp': "functions"
}
]
onCurrentIndexChanged: {
if (debug) console.debug()
tags.model = awKeys.dictKeys(true, model[currentIndex]["regexp"])
if (model[currentIndex]["regexp"] == "functions")
tags.model = ["{{\n\n}}", "template{{\n\n}}",
"aw_all<>{{}}", "aw_count<>{{}}", "aw_keys<>{{}}",
"aw_names<>{{}}"]
else
tags.model = awKeys.dictKeys(true, model[currentIndex]["regexp"])
if (debug) console.info("Init model", tags.model, "for", model[currentIndex]["label"])
tags.currentIndex = -1
}
}
QtControls.ComboBox {
id: tags
width: (parent.width - addTagButton.width - showValueButton.width - addLambdaButton.width) / 2
width: parent.width * 1 / 5
}
QtControls.Button {
id: addTagButton
width: parent.width * 1 / 5
text: i18n("Add")
onClicked: {
@ -303,7 +288,7 @@ Item {
}
}
QtControls.Button {
id: showValueButton
width: parent.width * 1 / 5
text: i18n("Show value")
onClicked: {
@ -317,28 +302,26 @@ Item {
awActions.sendNotification("tag", message)
}
}
QtControls.Button {
id: addLambdaButton
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 {
height: implicitHeight
width: parent.width
QtControls.Button {
width: parent.width
width: parent.width * 3 / 5
text: i18n("Edit bars")
onClicked: awKeys.editItem("graphicalitem")
}
QtControls.Button {
width: parent.width * 2 / 5
text: i18n("Preview")
onClicked: {
lock = false
awKeys.initKeys(textPattern.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit, false)
awKeys.needToBeUpdated()
}
}
}
QtControls.TextArea {
@ -350,48 +333,34 @@ Item {
}
}
// we need to initializate DataEngines here too
// because we need to get keys and values
PlasmaCore.DataSource {
id: systemmonitorDE
engine: "systemmonitor"
connectedSources: systemmonitorDE.sources
interval: 5000
onNewData: {
if (debug) console.debug("Update source", sourceName)
awKeys.setDataBySource(sourceName, data, settings)
}
QtDialogs.MessageDialog {
id: compiledText
modality: Qt.NonModal
title: i18n("Preview")
}
PlasmaCore.DataSource {
id: extsysmonDE
engine: "extsysmon"
connectedSources: extsysmonDE.sources
interval: 5000
onNewData: {
if (debug) console.debug("Update source", sourceName)
awKeys.setDataBySource(sourceName, data, settings)
}
}
PlasmaCore.DataSource {
id: timeDE
engine: "time"
connectedSources: ["Local"]
interval: 5000
onNewData: {
if (debug) console.debug("Update source", sourceName)
awKeys.setDataBySource(sourceName, data, settings)
}
}
Component.onCompleted: {
if (debug) console.debug()
awKeys.needTextToBeUpdated.connect(needTextUpdate)
// init submodule
awKeys.initKeys(plasmoid.configuration.text)
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit, false)
awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline)
awKeys.setAggregatorProperty("acOnline", plasmoid.configuration.acOnline)
awKeys.setAggregatorProperty("customTime", plasmoid.configuration.customTime)
awKeys.setAggregatorProperty("customUptime", plasmoid.configuration.customUptime)
awKeys.setAggregatorProperty("tempUnits", plasmoid.configuration.tempUnits)
awKeys.setAggregatorProperty("translate", plasmoid.configuration.translateStrings)
}
onNeedTextUpdate: {
if (lock) return
if (debug) console.debug()
compiledText.text = newText.replace(/&nbsp;/g, " ")
compiledText.open()
lock = true;
}
}

View File

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

View File

@ -2,22 +2,18 @@ set(PLUGIN_NAME awplugin)
add_definitions(-DTRANSLATION_DOMAIN=\"plasma_applet_org.kde.plasma.awesomewidget\")
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/../
${CMAKE_CURRENT_SOURCE_DIR}/../../${PROJECT_LIBRARY}/
${PROJECT_TRDPARTY_DIR}
${Qt_INCLUDE}
${Kf5_INCLUDE}
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../${PROJECT_LIBRARY}/
${PROJECT_TRDPARTY_DIR}
${Qt_INCLUDE}
${Kf5_INCLUDE}
)
file(GLOB SUBPROJECT_SOURCE *.cpp ${PROJECT_TRDPARTY_DIR}/fontdialog/*.cpp ${CMAKE_SOURCE_DIR}/*.cpp)
file(GLOB SUBPROJECT_UI *.ui)
file(GLOB SUBPROJECT_NOTIFY *.notifyrc)
qt5_wrap_ui(SUBPROJECT_UI_HEADER ${SUBPROJECT_UI})
add_library(${PLUGIN_NAME} SHARED ${SUBPROJECT_SOURCE} ${SUBPROJECT_UI_HEADER})
add_library(${PLUGIN_NAME} SHARED ${SUBPROJECT_SOURCE})
target_link_libraries(${PLUGIN_NAME} ${PROJECT_LIBRARY} ${Qt_LIBRARIES} ${Kf5_LIBRARIES})
install(TARGETS ${PLUGIN_NAME} DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/private/awesomewidget)

View File

@ -21,126 +21,128 @@
#include <KNotifications/KNotification>
#include <QDesktopServices>
#include <QDir>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QProcess>
#include <QProcessEnvironment>
#include <QSettings>
#include <QStandardPaths>
#include <QUrl>
#include <fontdialog/fontdialog.h>
#include "awdebug.h"
#include "awupdatehelper.h"
#include "version.h"
AWActions::AWActions(QObject *parent)
: QObject(parent)
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_updateHelper = new AWUpdateHelper(this);
}
AWActions::~AWActions()
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
delete m_updateHelper;
}
void AWActions::checkUpdates()
void AWActions::checkUpdates(const bool showAnyway)
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << "Show anyway" << showAnyway;
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(versionReplyRecieved(QNetworkReply *)));
manager->get(QNetworkRequest(QUrl(VERSION_API)));
}
bool AWActions::dropCache() const
{
qCDebug(LOG_AW);
QString fileName = QString("%1/awesomewidgets.ndx")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
return QFile(fileName).remove();
if (!m_updateHelper->checkVersion())
m_updateHelper->checkUpdates(showAnyway);
}
// HACK: since QML could not use QLoggingCategory I need this hack
bool AWActions::isDebugEnabled() const
{
qCDebug(LOG_AW);
return LOG_AW().isDebugEnabled();
}
void AWActions::runCmd(const QString cmd) const
bool AWActions::runCmd(const QString cmd) const
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << "Cmd" << cmd;
QProcess command;
sendNotification(QString("Info"), i18n("Run %1", cmd));
command.startDetached(cmd);
}
void AWActions::sendEmail() const
{
qCDebug(LOG_AW);
return QProcess::startDetached(cmd);
}
// HACK: this method uses variable from version.h
void AWActions::showReadme() const
{
qCDebug(LOG_AW);
QDesktopServices::openUrl(QString(HOMEPAGE));
QDesktopServices::openUrl(QUrl(HOMEPAGE));
}
// HACK: this method uses variables from version.h
QString AWActions::getAboutText(const QString type) const
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << "Type" << type;
QString text;
if (type == QString("header"))
if (type == QString("header")) {
text = QString(NAME);
else if (type == QString("version"))
text = i18n("Version %1 (build date %2)", QString(VERSION), QString(BUILD_DATE));
else if (type == QString("description"))
} else if (type == QString("version")) {
text = i18n("Version %1 (build date %2)", QString(VERSION),
QString(BUILD_DATE));
if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(QString(COMMIT_SHA));
} else if (type == QString("description")) {
text = i18n("A set of minimalistic plasmoid widgets");
else if (type == QString("links"))
text = i18n("Links:") + QString("<br>") +
QString("<a href=\"%1\">%2</a><br>").arg(QString(HOMEPAGE)).arg(i18n("Homepage")) +
QString("<a href=\"%1\">%2</a><br>").arg(QString(REPOSITORY)).arg(i18n("Repository")) +
QString("<a href=\"%1\">%2</a><br>").arg(QString(BUGTRACKER)).arg(i18n("Bugtracker")) +
QString("<a href=\"%1\">%2</a><br>").arg(QString(TRANSLATION)).arg(i18n("Translation issue")) +
QString("<a href=\"%1\">%2</a><br>").arg(QString(AUR_PACKAGES)).arg(i18n("AUR packages")) +
QString("<a href=\"%1\">%2</a>").arg(QString(OPENSUSE_PACKAGES)).arg(i18n("openSUSE packages"));
else if (type == QString("copy"))
text = QString("<small>&copy; %1 <a href=\"mailto:%2\">%3</a><br>").arg(QString(DATE)).arg(QString(EMAIL)).arg(QString(AUTHOR)) +
i18n("This software is licensed under %1", QString(LICENSE)) + QString("</small>");
else if (type == QString("translators"))
} else if (type == QString("links")) {
text = i18n("Links:") + QString("<br>")
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(HOMEPAGE))
.arg(i18n("Homepage"))
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(REPOSITORY))
.arg(i18n("Repository"))
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(BUGTRACKER))
.arg(i18n("Bugtracker"))
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(TRANSLATION))
.arg(i18n("Translation issue"))
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(AUR_PACKAGES))
.arg(i18n("AUR packages"))
+ QString("<a href=\"%1\">%2</a>")
.arg(QString(OPENSUSE_PACKAGES))
.arg(i18n("openSUSE packages"));
} else if (type == QString("copy")) {
text = QString("<small>&copy; %1 <a href=\"mailto:%2\">%3</a><br>")
.arg(QString(DATE))
.arg(QString(EMAIL))
.arg(QString(AUTHOR))
+ i18n("This software is licensed under %1", QString(LICENSE))
+ QString("</small>");
} else if (type == QString("translators")) {
text = i18n("Translators: %1", QString(TRANSLATORS));
else if (type == QString("3rdparty")) {
QStringList trdPartyList = QString(TRDPARTY_LICENSE).split(QChar(';'), QString::SkipEmptyParts);
for (int i=0; i<trdPartyList.count(); i++)
} else if (type == QString("3rdparty")) {
QStringList trdPartyList
= QString(TRDPARTY_LICENSE)
.split(QChar(';'), QString::SkipEmptyParts);
for (int i = 0; i < trdPartyList.count(); i++)
trdPartyList[i] = QString("<a href=\"%3\">%1</a> (%2 license)")
.arg(trdPartyList.at(i).split(QChar(','))[0])
.arg(trdPartyList.at(i).split(QChar(','))[1])
.arg(trdPartyList.at(i).split(QChar(','))[2]);
.arg(trdPartyList.at(i).split(QChar(','))[0])
.arg(trdPartyList.at(i).split(QChar(','))[1])
.arg(trdPartyList.at(i).split(QChar(','))[2]);
text = i18n("This software uses: %1", trdPartyList.join(QString(", ")));
} else if (type == QString("thanks")) {
QStringList thanks = QString(SPECIAL_THANKS)
.split(QChar(';'), QString::SkipEmptyParts);
for (int i = 0; i < thanks.count(); i++)
thanks[i] = QString("<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;
@ -149,15 +151,14 @@ QString AWActions::getAboutText(const QString type) const
QVariantMap AWActions::getFont(const QVariantMap defaultFont) const
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << "Default font is" << defaultFont;
QVariantMap fontMap;
CFont defaultCFont = CFont(defaultFont[QString("family")].toString(),
defaultFont[QString("size")].toInt(),
400, false, defaultFont[QString("color")].toString());
CFont font = CFontDialog::getFont(i18n("Select font"), defaultCFont,
false, false);
defaultFont[QString("size")].toInt(), 400, false,
defaultFont[QString("color")].toString());
CFont font
= CFontDialog::getFont(i18n("Select font"), defaultCFont, false, false);
fontMap[QString("color")] = font.color().name();
fontMap[QString("family")] = font.family();
fontMap[QString("size")] = font.pointSize();
@ -166,116 +167,13 @@ QVariantMap AWActions::getFont(const QVariantMap defaultFont) const
}
QVariantMap AWActions::readDataEngineConfiguration() const
// to avoid additional object definition this method is static
void AWActions::sendNotification(const QString eventId, const QString message)
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << "Event" << eventId << "with message" << message;
QString fileName = QStandardPaths::locate(QStandardPaths::ConfigLocation, QString("plasma-dataengine-extsysmon.conf"));
qCInfo(LOG_AW) << "Configuration file" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
QVariantMap configuration;
settings.beginGroup(QString("Configuration"));
configuration[QString("ACPIPATH")] = settings.value(QString("ACPIPATH"), QString("/sys/class/power_supply/"));
configuration[QString("GPUDEV")] = settings.value(QString("GPUDEV"), QString("auto"));
configuration[QString("HDDDEV")] = settings.value(QString("HDDDEV"), QString("all"));
configuration[QString("HDDTEMPCMD")] = settings.value(QString("HDDTEMPCMD"), QString("sudo smartctl -a"));
configuration[QString("MPDADDRESS")] = settings.value(QString("MPDADDRESS"), QString("localhost"));
configuration[QString("MPDPORT")] = settings.value(QString("MPDPORT"), QString("6600"));
configuration[QString("MPRIS")] = settings.value(QString("MPRIS"), QString("auto"));
configuration[QString("PLAYER")] = settings.value(QString("PLAYER"), QString("mpris"));
configuration[QString("PLAYERSYMBOLS")] = settings.value(QString("PLAYERSYMBOLS"), QString("10"));
settings.endGroup();
return configuration;
}
void AWActions::writeDataEngineConfiguration(const QVariantMap configuration) const
{
qCDebug(LOG_AW);
QString fileName = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QString("/plasma-dataengine-extsysmon.conf");
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Configuration"));
settings.setValue(QString("ACPIPATH"), configuration[QString("ACPIPATH")]);
settings.setValue(QString("GPUDEV"), configuration[QString("GPUDEV")]);
settings.setValue(QString("HDDDEV"), configuration[QString("HDDDEV")]);
settings.setValue(QString("HDDTEMPCMD"), configuration[QString("HDDTEMPCMD")]);
settings.setValue(QString("MPDADDRESS"), configuration[QString("MPDADDRESS")]);
settings.setValue(QString("MPDPORT"), configuration[QString("MPDPORT")]);
settings.setValue(QString("MPRIS"), configuration[QString("MPRIS")]);
settings.setValue(QString("PLAYER"), configuration[QString("PLAYER")]);
settings.setValue(QString("PLAYERSYMBOLS"), configuration[QString("PLAYERSYMBOLS")]);
settings.endGroup();
settings.sync();
}
void AWActions::sendNotification(const QString eventId, const QString message,
const bool enablePopup)
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << "Event" << eventId;
qCDebug(LOG_AW) << "Message" << message;
if ((eventId == QString("event")) && (!enablePopup)) return;
KNotification *notification = KNotification::event(eventId, QString("Awesome Widget ::: %1").arg(eventId), message);
notification->setComponentName(QString("plasma-applet-org.kde.plasma.awesome-widget"));
}
void AWActions::showUpdates(QString version) const
{
qCDebug(LOG_AW);
QString text;
text += i18n("Current version : %1", QString(VERSION)) + QString("\n");
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;
}
}
void AWActions::versionReplyRecieved(QNetworkReply *reply) const
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << "Return code" << reply->error();
qCDebug(LOG_AW) << "Reply error message" << reply->errorString();
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;
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);
KNotification *notification = KNotification::event(
eventId, QString("Awesome Widget ::: %1").arg(eventId), message);
notification->setComponentName(
QString("plasma-applet-org.kde.plasma.awesome-widget"));
}

View File

@ -20,10 +20,9 @@
#define AWACTIONS_H
#include <QObject>
#include <QVariant>
class QNetworkReply;
class AWUpdateHelper;
class AWActions : public QObject
{
@ -32,29 +31,21 @@ class AWActions : public QObject
public:
explicit AWActions(QObject *parent = nullptr);
virtual ~AWActions();
Q_INVOKABLE void checkUpdates();
Q_INVOKABLE bool dropCache() const;
Q_INVOKABLE void checkUpdates(const bool showAnyway = false);
Q_INVOKABLE bool isDebugEnabled() const;
Q_INVOKABLE void runCmd(const QString cmd = QString("/usr/bin/true")) const;
Q_INVOKABLE void sendEmail() const;
Q_INVOKABLE bool runCmd(const QString cmd = QString("/usr/bin/true")) const;
Q_INVOKABLE void showReadme() const;
// configuration slots
Q_INVOKABLE QString getAboutText(const QString type = QString("header")) const;
Q_INVOKABLE QString getAboutText(const QString type
= QString("header")) const;
Q_INVOKABLE QVariantMap getFont(const QVariantMap defaultFont) const;
// dataengine
Q_INVOKABLE QVariantMap readDataEngineConfiguration() const;
Q_INVOKABLE void writeDataEngineConfiguration(const QVariantMap configuration) const;
public slots:
Q_INVOKABLE static void sendNotification(const QString eventId, const QString message,
const bool enablePopup = false);
private slots:
void showUpdates(QString version) const;
void versionReplyRecieved(QNetworkReply *reply) const;
Q_INVOKABLE static void sendNotification(const QString eventId,
const QString message);
private:
AWUpdateHelper *m_updateHelper = nullptr;
};

View File

@ -0,0 +1,321 @@
/***************************************************************************
* 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 "awconfighelper.h"
#include <KI18n/KLocalizedString>
#include <QDir>
#include <QQmlPropertyMap>
#include <QSettings>
#include <QTextCodec>
#include "awdebug.h"
AWConfigHelper::AWConfigHelper(QObject *parent)
: QObject(parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWConfigHelper::~AWConfigHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
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
{
QString fileName = QString("%1/awesomewidgets.ndx")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericCacheLocation));
return QFile(fileName).remove();
}
bool AWConfigHelper::exportConfiguration(QObject *nativeConfig,
const QString fileName) const
{
qCDebug(LOG_AW) << "Selected filename" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
// plasmoid configuration
QQmlPropertyMap *configuration
= static_cast<QQmlPropertyMap *>(nativeConfig);
settings.beginGroup(QString("plasmoid"));
for (auto key : configuration->keys()) {
QVariant value = configuration->value(key);
if (!value.isValid())
continue;
settings.setValue(key, value);
}
settings.endGroup();
// extensions
for (auto item : m_dirs) {
QStringList items
= QDir(QString("%1/%2").arg(m_baseDir).arg(item))
.entryList(QStringList() << QString("*.desktop"),
QDir::Files);
settings.beginGroup(item);
for (auto it : items)
copyExtensions(it, item, settings, false);
settings.endGroup();
}
// additional files
settings.beginGroup(QString("json"));
// script filters
readFile(settings, QString("filters"),
QString("%1/scripts/awesomewidgets-extscripts-filters.json")
.arg(m_baseDir));
// weather icon settings
readFile(settings, QString("weathers"),
QString("%1/weather/awesomewidgets-extweather-ids.json")
.arg(m_baseDir));
settings.endGroup();
// sync settings
settings.sync();
// show additional message
return settings.status() == QSettings::NoError;
}
QVariantMap AWConfigHelper::importConfiguration(const QString fileName,
const bool importPlasmoid,
const bool importExtensions,
const bool importAdds) const
{
qCDebug(LOG_AW) << "Selected filename" << fileName;
QVariantMap configuration;
QSettings settings(fileName, QSettings::IniFormat);
// extensions
if (importExtensions) {
for (auto item : m_dirs) {
settings.beginGroup(item);
for (auto it : settings.childGroups())
copyExtensions(it, item, settings, true);
settings.endGroup();
}
}
// additional files
if (importAdds) {
settings.beginGroup(QString("json"));
// script filters
writeFile(settings, QString("filters"),
QString("%1/scripts/awesomewidgets-extscripts-filters.json")
.arg(m_baseDir));
// weather icon settings
writeFile(settings, QString("weathers"),
QString("%1/weather/awesomewidgets-extweather-ids.json")
.arg(m_baseDir));
settings.endGroup();
}
// plasmoid configuration
if (importPlasmoid) {
settings.beginGroup(QString("plasmoid"));
for (auto key : settings.childKeys())
configuration[key] = settings.value(key);
settings.endGroup();
}
return configuration;
}
QVariantMap AWConfigHelper::readDataEngineConfiguration() const
{
QString fileName
= QStandardPaths::locate(QStandardPaths::ConfigLocation,
QString("plasma-dataengine-extsysmon.conf"));
qCInfo(LOG_AW) << "Configuration file" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
QVariantMap configuration;
settings.beginGroup(QString("Configuration"));
configuration[QString("ACPIPATH")] = settings.value(
QString("ACPIPATH"), QString("/sys/class/power_supply/"));
configuration[QString("GPUDEV")]
= settings.value(QString("GPUDEV"), QString("auto"));
configuration[QString("HDDDEV")]
= settings.value(QString("HDDDEV"), QString("all"));
configuration[QString("HDDTEMPCMD")]
= settings.value(QString("HDDTEMPCMD"), QString("sudo smartctl -a"));
configuration[QString("MPDADDRESS")]
= settings.value(QString("MPDADDRESS"), QString("localhost"));
configuration[QString("MPDPORT")]
= settings.value(QString("MPDPORT"), QString("6600"));
configuration[QString("MPRIS")]
= settings.value(QString("MPRIS"), QString("auto"));
configuration[QString("PLAYER")]
= settings.value(QString("PLAYER"), QString("mpris"));
configuration[QString("PLAYERSYMBOLS")]
= settings.value(QString("PLAYERSYMBOLS"), QString("10"));
settings.endGroup();
qCInfo(LOG_AW) << "Configuration" << configuration;
return configuration;
}
void AWConfigHelper::writeDataEngineConfiguration(
const QVariantMap configuration) const
{
qCDebug(LOG_AW) << "Configuration" << configuration;
QString fileName
= QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)
+ QString("/plasma-dataengine-extsysmon.conf");
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Configuration"));
settings.setValue(QString("ACPIPATH"), configuration[QString("ACPIPATH")]);
settings.setValue(QString("GPUDEV"), configuration[QString("GPUDEV")]);
settings.setValue(QString("HDDDEV"), configuration[QString("HDDDEV")]);
settings.setValue(QString("HDDTEMPCMD"),
configuration[QString("HDDTEMPCMD")]);
settings.setValue(QString("MPDADDRESS"),
configuration[QString("MPDADDRESS")]);
settings.setValue(QString("MPDPORT"), configuration[QString("MPDPORT")]);
settings.setValue(QString("MPRIS"), configuration[QString("MPRIS")]);
settings.setValue(QString("PLAYER"), configuration[QString("PLAYER")]);
settings.setValue(QString("PLAYERSYMBOLS"),
configuration[QString("PLAYERSYMBOLS")]);
settings.endGroup();
settings.sync();
}
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,
QSettings &settings,
const bool inverse) const
{
qCDebug(LOG_AW) << "Extension" << item << "has type" << type
<< "inverse copying" << inverse;
settings.beginGroup(item);
QSettings itemSettings(
QString("%1/%2/%3").arg(m_baseDir).arg(type).arg(item),
QSettings::IniFormat);
itemSettings.beginGroup(QString("Desktop Entry"));
if (inverse)
copySettings(settings, itemSettings);
else
copySettings(itemSettings, settings);
itemSettings.endGroup();
settings.endGroup();
if (inverse)
itemSettings.sync();
}
void AWConfigHelper::copySettings(QSettings &from, QSettings &to) const
{
for (auto key : from.childKeys())
to.setValue(key, from.value(key));
}
void AWConfigHelper::readFile(QSettings &settings, const QString key,
const QString fileName) const
{
qCDebug(LOG_AW) << "Key" << key << "from file" << fileName;
QFile file(fileName);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QString text = QString::fromUtf8(file.readAll());
file.close();
settings.setValue(key, text);
} else {
qCWarning(LOG_LIB) << "Could not open" << file.fileName();
}
}
void AWConfigHelper::writeFile(QSettings &settings, const QString key,
const QString fileName) const
{
qCDebug(LOG_AW) << "Key" << key << "to file" << fileName;
if (!settings.contains(key))
return;
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
out.setCodec("UTF-8");
out << settings.value(key).toString().toUtf8();
out.flush();
file.close();
} else {
qCWarning(LOG_LIB) << "Could not open" << file.fileName();
}
}

View File

@ -0,0 +1,69 @@
/***************************************************************************
* 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 AWCONFIGHELPER_H
#define AWCONFIGHELPER_H
#include <QObject>
#include <QStandardPaths>
class QSettings;
class AWConfigHelper : public QObject
{
Q_OBJECT
public:
explicit AWConfigHelper(QObject *parent = nullptr);
virtual ~AWConfigHelper();
Q_INVOKABLE QString configurationDirectory() const;
Q_INVOKABLE bool dropCache() const;
Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig,
const QString fileName) const;
Q_INVOKABLE QVariantMap importConfiguration(const QString fileName,
const bool importPlasmoid,
const bool importExtensions,
const bool importAdds) const;
// dataengine
Q_INVOKABLE QVariantMap readDataEngineConfiguration() const;
Q_INVOKABLE void
writeDataEngineConfiguration(const QVariantMap configuration) const;
private:
// methods
void copyConfigs(const QString localDir) const;
void copyExtensions(const QString item, const QString type,
QSettings &settings, const bool inverse) const;
void copySettings(QSettings &from, QSettings &to) const;
void readFile(QSettings &settings, const QString key,
const QString fileName) const;
void writeFile(QSettings &settings, const QString key,
const QString fileName) const;
// properties
QString m_baseDir = QString("%1/awesomewidgets")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation));
QStringList m_dirs = QStringList()
<< QString("desktops") << QString("quotes")
<< QString("scripts") << QString("upgrade")
<< QString("weather");
};
#endif /* AWCONFIGHELPER_H */

View File

@ -0,0 +1,322 @@
/***************************************************************************
* 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 "awdataaggregator.h"
#include <KI18n/KLocalizedString>
#include <QtConcurrent/QtConcurrent>
#include <QBuffer>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPixmap>
#include <cmath>
#include "awactions.h"
#include "awdebug.h"
AWDataAggregator::AWDataAggregator(QObject *parent)
: QObject(parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
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();
connect(this, SIGNAL(updateData(const QVariantHash &)), this,
SLOT(dataUpdate(const QVariantHash &)));
}
AWDataAggregator::~AWDataAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
delete toolTipScene;
}
QList<float> AWDataAggregator::getData(const QString key) const
{
qCDebug(LOG_AW) << "Key" << key;
return data[QString("%1Tooltip").arg(key)];
}
QString AWDataAggregator::htmlImage(const QPixmap &source) const
{
QByteArray byteArray;
QBuffer buffer(&byteArray);
source.save(&buffer, "PNG");
return byteArray.isEmpty()
? QString()
: QString("<img src=\"data:image/png;base64,%1\"/>")
.arg(QString(byteArray.toBase64()));
}
void AWDataAggregator::setParameters(QVariantMap settings)
{
qCDebug(LOG_AW) << "Settings" << settings;
// cast from QVariantMap to QVariantHash without data lost
configuration = qvariant_cast<QVariantHash>(settings);
m_enablePopup = configuration[QString("notify")].toBool();
counts = 0;
counts += configuration[QString("cpuTooltip")].toInt();
counts += configuration[QString("cpuclTooltip")].toInt();
counts += configuration[QString("memTooltip")].toInt();
counts += configuration[QString("swapTooltip")].toInt();
counts += configuration[QString("downkbTooltip")].toInt();
counts += configuration[QString("batTooltip")].toInt();
// resize tooltip image
toolTipView->resize(100 * counts, 105);
requiredKeys.clear();
if (configuration[QString("cpuTooltip")].toBool())
requiredKeys.append(QString("cpuTooltip"));
if (configuration[QString("cpuclTooltip")].toBool())
requiredKeys.append(QString("cpuclTooltip"));
if (configuration[QString("memTooltip")].toBool())
requiredKeys.append(QString("memTooltip"));
if (configuration[QString("swapTooltip")].toBool())
requiredKeys.append(QString("swapTooltip"));
if (configuration[QString("downkbTooltip")].toBool())
requiredKeys.append(QString("downkbTooltip"));
if (configuration[QString("upkbTooltip")].toBool())
requiredKeys.append(QString("upkbTooltip"));
if (configuration[QString("batTooltip")].toBool())
requiredKeys.append(QString("batTooltip"));
// background
toolTipScene->setBackgroundBrush(
configuration[QString("useTooltipBackground")].toBool()
? QBrush(QColor(
configuration[QString("tooltipBackground")].toString()))
: QBrush(Qt::NoBrush));
}
QPixmap AWDataAggregator::tooltipImage()
{
// create image
toolTipScene->clear();
QPen pen;
bool down = false;
for (auto key : requiredKeys) {
// create frame
float normX = 100.0f / static_cast<float>(data[key].count());
float normY = 100.0f / (1.5f * boundaries[key]);
float shift = requiredKeys.indexOf(key) * 100.0f;
if (down)
shift -= 100.0;
// apply pen color
if (key != QString("batTooltip"))
pen.setColor(
QColor(configuration[QString("%1Color").arg(key)].toString()));
// paint data inside frame
for (int j = 0; j < data[key].count() - 1; j++) {
// some magic here
float x1 = j * normX + shift;
float y1 = -fabs(data[key].at(j)) * normY + 5.0f;
float x2 = (j + 1) * normX + shift;
float y2 = -fabs(data[key].at(j + 1)) * normY + 5.0f;
if (key == QString("batTooltip")) {
if (data[key].at(j + 1) > 0)
pen.setColor(QColor(
configuration[QString("batTooltipColor")].toString()));
else
pen.setColor(
QColor(configuration[QString("batInTooltipColor")]
.toString()));
}
toolTipScene->addLine(x1, y1, x2, y2, pen);
}
if (key == QString("downkbTooltip"))
down = true;
}
return toolTipView->grab();
}
void AWDataAggregator::dataUpdate(const QVariantHash &values)
{
// do not log these arguments
setData(values);
emit(toolTipPainted(htmlImage(tooltipImage())));
}
void AWDataAggregator::checkValue(const QString source, const float value,
const float extremum) const
{
qCDebug(LOG_AW) << "Notification source" << source << "with value" << value
<< "called with extremum" << extremum;
if (value >= 0.0) {
if ((m_enablePopup) && (value > extremum)
&& (data[source].last() < extremum))
return AWActions::sendNotification(QString("event"),
notificationText(source, value));
} else {
if ((m_enablePopup) && (value < extremum)
&& (data[source].last() > extremum))
return AWActions::sendNotification(QString("event"),
notificationText(source, value));
}
}
void AWDataAggregator::checkValue(const QString source, const QString current,
const QString received) const
{
qCDebug(LOG_AW) << "Notification source" << source << "with current value"
<< current << "and received one" << received;
if ((m_enablePopup) && (current != received) && (!received.isEmpty()))
return AWActions::sendNotification(QString("event"),
notificationText(source, received));
}
void AWDataAggregator::initScene()
{
toolTipScene = new QGraphicsScene(nullptr);
toolTipView = new QGraphicsView(toolTipScene);
toolTipView->setStyleSheet(QString("background: transparent"));
toolTipView->setContentsMargins(0, 0, 0, 0);
toolTipView->setFrameShape(QFrame::NoFrame);
toolTipView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
toolTipView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
QString AWDataAggregator::notificationText(const QString source,
const float value) const
{
qCDebug(LOG_AW) << "Notification source" << source << "with value" << value;
QString output;
if (source == QString("batTooltip"))
output = value > 0.0 ? i18n("AC online") : i18n("AC offline");
else if (source == QString("cpuTooltip"))
output = i18n("High CPU load");
else if (source == QString("memTooltip"))
output = i18n("High memory usage");
else if (source == QString("swapTooltip"))
output = i18n("Swap is used");
else if (source == QString("gpu"))
output = i18n("High GPU load");
return output;
}
QString AWDataAggregator::notificationText(const QString source,
const QString value) const
{
qCDebug(LOG_AW) << "Notification source" << source << "with value" << value;
QString output;
if (source == QString("netdev"))
output = i18n("Network device has been changed to %1", value);
return output;
}
void AWDataAggregator::setData(const QVariantHash &values)
{
// do not log these arguments
// battery update requires info is AC online or not
setData(values[QString("ac")].toString()
== configuration[QString("acOnline")],
QString("batTooltip"), values[QString("bat")].toFloat());
// usual case
setData(QString("cpuTooltip"), values[QString("cpu")].toFloat(), 90.0);
setData(QString("cpuclTooltip"), values[QString("cpucl")].toFloat());
setData(QString("memTooltip"), values[QString("mem")].toFloat(), 80.0);
setData(QString("swapTooltip"), values[QString("swap")].toFloat(), 0.0);
setData(QString("downkbTooltip"), values[QString("downkb")].toFloat());
setData(QString("upkbTooltip"), values[QString("upkb")].toFloat());
// additional check for network device
[this](const QString value) {
checkValue(QString("netdev"), currentNetworkDevice, value);
currentNetworkDevice = value;
}(values[QString("netdev")].toString());
// additional check for GPU load
[this](const float value) {
checkValue(QString("gpu"), value, 90.0);
currentGPULoad = value;
}(values[QString("gpu")].toFloat());
}
void AWDataAggregator::setData(const QString &source, float value,
const float extremum)
{
qCDebug(LOG_AW) << "Source" << source << "to value" << value
<< "with extremum" << extremum;
if (data[source].count() == 0)
data[source].append(0.0);
else if (data[source].count()
> configuration[QString("tooltipNumber")].toInt())
data[source].removeFirst();
if (isnan(value))
value = 0.0;
// notifications
checkValue(source, value, extremum);
data[source].append(value);
if (source == QString("downkbTooltip")) {
QList<float> netValues
= data[QString("downkbTooltip")] + data[QString("upkbTooltip")];
// to avoid inf value of normY
netValues << 1.0;
boundaries[QString("downkbTooltip")]
= 1.2f * *std::max_element(netValues.cbegin(), netValues.cend());
boundaries[QString("upkbTooltip")]
= boundaries[QString("downkbTooltip")];
}
}
void AWDataAggregator::setData(const bool dontInvert, const QString &source,
float value)
{
qCDebug(LOG_AW) << "Do not invert" << dontInvert << "value" << value
<< "for source" << source;
// invert values for different battery colours
value = dontInvert ? value : -value;
return setData(source, value, 0.0);
}

View File

@ -0,0 +1,79 @@
/***************************************************************************
* 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 AWTOOLTIP_H
#define AWTOOLTIP_H
#include <QObject>
#include <QVariant>
class QGraphicsScene;
class QGraphicsView;
class QPixmap;
class QThreadPool;
class AWDataAggregator : public QObject
{
Q_OBJECT
public:
explicit AWDataAggregator(QObject *parent = nullptr);
virtual ~AWDataAggregator();
QList<float> getData(const QString key) const;
QString htmlImage(const QPixmap &source) const;
void setParameters(QVariantMap settings);
QPixmap tooltipImage();
signals:
void updateData(const QVariantHash &values);
void toolTipPainted(const QString image) const;
private slots:
void dataUpdate(const QVariantHash &values);
private:
// ui
QGraphicsScene *toolTipScene = nullptr;
QGraphicsView *toolTipView = nullptr;
void checkValue(const QString source, const float value,
const float extremum) const;
void checkValue(const QString source, const QString current,
const QString received) const;
void initScene();
QString notificationText(const QString source, const float value) const;
QString notificationText(const QString source, const QString value) const;
// main method
void setData(const QVariantHash &values);
void setData(const QString &source, float value,
const float extremum = -1.0f);
// different signature for battery device
void setData(const bool dontInvert, const QString &source, float value);
// variables
int counts = 0;
QVariantHash configuration;
float currentGPULoad = 0.0;
QString currentNetworkDevice = QString("lo");
QHash<QString, float> boundaries;
QHash<QString, QList<float>> data;
bool m_enablePopup = false;
QStringList requiredKeys;
};
#endif /* AWTOOLTIP_H */

View File

@ -0,0 +1,102 @@
/***************************************************************************
* 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 "awdataengineaggregator.h"
#include "awdebug.h"
#include "awkeys.h"
AWDataEngineAggregator::AWDataEngineAggregator(QObject *parent)
: QObject(parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWDataEngineAggregator::~AWDataEngineAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
clear();
}
void AWDataEngineAggregator::clear()
{
// disconnect sources first
disconnectSources();
m_dataEngines.clear();
delete m_consumer;
m_consumer = nullptr;
}
void AWDataEngineAggregator::disconnectSources()
{
for (auto dataengine : m_dataEngines.values())
for (auto source : dataengine->sources())
dataengine->disconnectSource(source, parent());
}
void AWDataEngineAggregator::initDataEngines(const int interval)
{
qCDebug(LOG_AW) << "Init dataengines with 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);
}
void AWDataEngineAggregator::dropSource(const QString source)
{
qCDebug(LOG_AW) << "Source" << source;
// FIXME there is no possibility to check to which dataengine source
// connected we will try to disconnect it from systemmonitor and extsysmon
m_dataEngines[QString("systemmonitor")]->disconnectSource(source, parent());
m_dataEngines[QString("extsysmon")]->disconnectSource(source, parent());
m_dataEngines[QString("time")]->disconnectSource(source, parent());
}
void AWDataEngineAggregator::reconnectSources(const int interval)
{
qCDebug(LOG_AW) << "Reconnect sources with interval" << interval;
m_dataEngines[QString("systemmonitor")]->connectAllSources(parent(),
interval);
m_dataEngines[QString("extsysmon")]->connectAllSources(parent(), interval);
m_dataEngines[QString("time")]->connectSource(QString("Local"), parent(),
1000);
}

View File

@ -0,0 +1,52 @@
/***************************************************************************
* 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 AWDATAENGINEAGGREGATOR_H
#define AWDATAENGINEAGGREGATOR_H
#include <Plasma/DataEngine>
#include <Plasma/DataEngineConsumer>
#include <QObject>
class AWDataEngineAggregator : public QObject
{
Q_OBJECT
public:
explicit AWDataEngineAggregator(QObject *parent = nullptr);
virtual ~AWDataEngineAggregator();
void clear();
void disconnectSources();
void initDataEngines(const int interval);
signals:
void deviceAdded(const QString &source);
public slots:
void dropSource(const QString source);
void reconnectSources(const int interval);
private:
Plasma::DataEngineConsumer *m_consumer = nullptr;
QHash<QString, Plasma::DataEngine *> m_dataEngines;
};
#endif /* AWDATAENGINEAGGREGATOR_H */

View File

@ -20,6 +20,8 @@
#include <QtQml>
#include "awactions.h"
#include "awconfighelper.h"
#include "awdataengineaggregator.h"
#include "awkeys.h"
@ -28,5 +30,6 @@ void AWPlugin::registerTypes(const char *uri)
Q_ASSERT(uri == QLatin1String("org.kde.plasma.private.awesomewidget"));
qmlRegisterType<AWActions>(uri, 1, 0, "AWActions");
qmlRegisterType<AWConfigHelper>(uri, 1, 0, "AWConfigHelper");
qmlRegisterType<AWKeys>(uri, 1, 0, "AWKeys");
}

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 */

File diff suppressed because it is too large Load Diff

View File

@ -19,21 +19,17 @@
#ifndef AWKEYS_H
#define AWKEYS_H
#include <QHash>
#include <Plasma/DataEngine>
#include <QMutex>
#include <QObject>
#include <QStringList>
#include <QVariant>
#include "extitemaggregator.h"
#include "version.h"
class AWToolTip;
class ExtQuotes;
class ExtScript;
class ExtUpgrade;
class ExtWeather;
class GraphicalItem;
class AWDataAggregator;
class AWDataEngineAggregator;
class AWKeyOperations;
class AWKeysAggregator;
class QThreadPool;
class AWKeys : public QObject
{
@ -42,27 +38,31 @@ class AWKeys : public QObject
public:
explicit AWKeys(QObject *parent = nullptr);
virtual ~AWKeys();
Q_INVOKABLE void initKeys(const QString currentPattern);
Q_INVOKABLE void initTooltip(const QVariantMap tooltipParams);
Q_INVOKABLE void setPopupEnabled(const bool popup = false);
Q_INVOKABLE void setTranslateStrings(const bool translate = false);
Q_INVOKABLE void initDataAggregator(const QVariantMap tooltipParams);
Q_INVOKABLE void initKeys(const QString currentPattern, const int interval,
const int limit, const bool optimize);
Q_INVOKABLE void setAggregatorProperty(const QString key,
const QVariant value);
Q_INVOKABLE void setWrapNewLines(const bool wrap = false);
Q_INVOKABLE QSize toolTipSize() const;
// additional method to force load keys from Qml UI. Used in some
// configuration pages
Q_INVOKABLE void updateCache();
// keys
Q_INVOKABLE void addDevice(const QString source);
Q_INVOKABLE QStringList dictKeys(const bool sorted = false,
const QString regexp = QString()) const;
Q_INVOKABLE QStringList getHddDevices() const;
Q_INVOKABLE void setDataBySource(const QString sourceName, const QVariantMap data,
const QVariantMap params);
// values
Q_INVOKABLE void graphicalValueByKey() const;
Q_INVOKABLE QString infoByKey(QString key) const;
Q_INVOKABLE QString valueByKey(QString key) const;
// configuration
Q_INVOKABLE void editItem(const QString type);
public slots:
void dataUpdated(const QString &sourceName,
const Plasma::DataEngine::Data &data);
// dummy method required by DataEngine connections
void modelChanged(QString, QAbstractItemModel *){};
signals:
void dropSourceFromDataengine(const QString source);
void needTextToBeUpdated(const QString newText) const;
@ -70,31 +70,28 @@ signals:
void needToBeUpdated();
private slots:
void dataUpdate();
void loadKeysFromCache();
void reinitKeys();
void reinitKeys(const QStringList currentKeys);
void updateTextData();
private:
// methods
void addKeyToCache(const QString type, const QString key = QString(""));
void calculateLambdas();
QString parsePattern() const;
float temperature(const float temp, const QString units) const;
// get methods
AWToolTip *toolTip = nullptr;
bool enablePopup = false;
bool translateStrings = false;
bool wrapNewLines = false;
ExtItemAggregator<GraphicalItem> *graphicalItems;
ExtItemAggregator<ExtQuotes> *extQuotes;
ExtItemAggregator<ExtScript> *extScripts;
ExtItemAggregator<ExtUpgrade> *extUpgrade;
ExtItemAggregator<ExtWeather> *extWeather;
QString pattern;
QStringList foundBars, foundKeys, foundLambdas;
QStringList timeKeys = QString(TIME_KEYS).split(QChar(','));
QHash<QString, QString> values;
QStringList diskDevices, hddDevices, mountDevices, networkDevices, tempDevices;
void calculateValues();
QString parsePattern(QString pattern) const;
void setDataBySource(const QString &sourceName, const QVariantMap &data);
// objects
AWDataAggregator *dataAggregator = nullptr;
AWDataEngineAggregator *dataEngineAggregator = nullptr;
AWKeysAggregator *aggregator = nullptr;
AWKeyOperations *keyOperator = nullptr;
// variables
QVariantMap m_tooltipParams;
QStringList m_foundBars, m_foundKeys, m_foundLambdas, m_requiredKeys;
QVariantHash values;
bool m_optimize = false;
bool m_wrapNewLines = false;
// multithread features
QThreadPool *m_threadPool = nullptr;
QMutex m_mutex;
};

View File

@ -0,0 +1,579 @@
/***************************************************************************
* 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 "awkeysaggregator.h"
#include <KI18n/KLocalizedString>
#include <QDateTime>
#include <QLocale>
#include <QRegExp>
#include "awdebug.h"
AWKeysAggregator::AWKeysAggregator(QObject *parent)
: QObject(parent)
{
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;
}
AWKeysAggregator::~AWKeysAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QString AWKeysAggregator::formater(const QVariant &data,
const QString &key) const
{
qCDebug(LOG_AW) << "Data" << data << "for key" << key;
QString output;
QLocale loc = m_translate ? QLocale::system() : QLocale::c();
// case block
switch (m_formater[key]) {
case Float:
output = QString("%1").arg(data.toFloat(), 5, 'f', 1);
break;
case FloatTwoSymbols:
output = QString("%1").arg(data.toFloat(), 5, 'f', 2);
break;
case Integer:
output = QString("%1").arg(data.toFloat(), 4, 'f', 0);
break;
case IntegerFive:
output = QString("%1").arg(data.toFloat(), 5, 'f', 0);
break;
case IntegerThree:
output = QString("%1").arg(data.toFloat(), 3, 'f', 0);
break;
case List:
output = data.toStringList().join(QChar(','));
break;
case ACFormat:
output = data.toBool() ? m_acOnline : m_acOffline;
break;
case MemGBFormat:
output
= QString("%1").arg(data.toFloat() / (1024.0 * 1024.0), 5, 'f', 1);
break;
case MemMBFormat:
output = QString("%1").arg(data.toFloat() / 1024.0, 5, 'f', 0);
break;
case NetSmartFormat:
output = [](const float value) {
if (value > 1024.0)
return QString("%1").arg(value / 1024.0, 4, 'f', 1);
else
return QString("%1").arg(value, 4, 'f', 0);
}(data.toFloat());
break;
case NetSmartUnits:
if (data.toFloat() > 1024.0)
output = m_translate ? i18n("MB/s") : QString("MB/s");
else
output = m_translate ? i18n("KB/s") : QString("KB/s");
break;
case Quotes:
// first cast
output = QString("%1").arg(data.toDouble(), 0, 'f');
output = output.rightJustified(8, QLatin1Char(' '), true);
break;
case Temperature:
output = QString("%1").arg(temperature(data.toFloat()), 5, 'f', 1);
break;
case Time:
output = data.toDateTime().toString();
break;
case TimeCustom:
output = m_customTime;
[&output, loc, this](const QDateTime dt) {
for (auto key : timeKeys)
output.replace(QString("$%1").arg(key), loc.toString(dt, key));
}(data.toDateTime());
break;
case TimeISO:
output = data.toDateTime().toString(Qt::ISODate);
break;
case TimeLong:
output = loc.toString(data.toDateTime(), QLocale::LongFormat);
break;
case TimeShort:
output = loc.toString(data.toDateTime(), QLocale::ShortFormat);
break;
case Uptime:
case UptimeCustom:
output =
[](QString source, const int uptime) {
int seconds = uptime - uptime % 60;
int minutes = seconds / 60 % 60;
int hours = ((seconds / 60) - minutes) / 60 % 24;
int days = (((seconds / 60) - minutes) / 60 - hours) / 24;
source.replace(QString("$dd"),
QString("%1").arg(days, 3, 10, QChar('0')));
source.replace(QString("$d"), QString("%1").arg(days));
source.replace(QString("$hh"),
QString("%1").arg(hours, 2, 10, QChar('0')));
source.replace(QString("$h"), QString("%1").arg(hours));
source.replace(QString("$mm"),
QString("%1").arg(minutes, 2, 10, QChar('0')));
source.replace(QString("$m"), QString("%1").arg(minutes));
return source;
}(m_formater[key] == Uptime ? QString("$ddd$hhh$mmm")
: m_customUptime,
static_cast<int>(data.toFloat()));
break;
case NoFormat:
output = data.toString();
break;
default:
output = QString();
break;
}
return output;
}
QStringList AWKeysAggregator::keysFromSource(const QString &source) const
{
qCDebug(LOG_AW) << "Search for source" << source;
return m_map.values(source);
}
void AWKeysAggregator::setAcOffline(const QString inactive)
{
qCDebug(LOG_AW) << "Inactive AC string" << inactive;
m_acOffline = inactive;
}
void AWKeysAggregator::setAcOnline(const QString active)
{
qCDebug(LOG_AW) << "Active AC string" << active;
m_acOnline = active;
}
void AWKeysAggregator::setCustomTime(const QString customTime)
{
qCDebug(LOG_AW) << "Format" << customTime;
m_customTime = customTime;
}
void AWKeysAggregator::setCustomUptime(const QString customUptime)
{
qCDebug(LOG_AW) << "Format" << customUptime;
m_customUptime = customUptime;
}
void AWKeysAggregator::setDevices(const QHash<QString, QStringList> devices)
{
qCDebug(LOG_AW) << "Devices" << devices;
m_devices = devices;
}
void AWKeysAggregator::setTempUnits(const QString units)
{
qCDebug(LOG_AW) << "Units" << units;
m_tempUnits = units;
}
void AWKeysAggregator::setTranslate(const bool translate)
{
qCDebug(LOG_AW) << "Translate" << translate;
m_translate = translate;
}
// HACK units required to define should the value be calculated as temperature
// or fan data
QStringList AWKeysAggregator::registerSource(const QString &source,
const QString &units,
const QStringList &keys)
{
qCDebug(LOG_AW) << "Source" << source << "with units" << units;
// regular expressions
QRegExp cpuRegExp = QRegExp(QString("cpu/cpu.*/TotalLoad"));
QRegExp cpuclRegExp = QRegExp(QString("cpu/cpu.*/clock"));
QRegExp hddrRegExp = QRegExp(QString("disk/.*/Rate/rblk"));
QRegExp hddwRegExp = QRegExp(QString("disk/.*/Rate/wblk"));
QRegExp mountFillRegExp = QRegExp(QString("partitions/.*/filllevel"));
QRegExp mountFreeRegExp = QRegExp(QString("partitions/.*/freespace"));
QRegExp mountUsedRegExp = QRegExp(QString("partitions/.*/usedspace"));
QRegExp netRegExp = QRegExp(
QString("network/interfaces/.*/(receiver|transmitter)/data$"));
if (source == QString("battery/ac")) {
// AC
m_map[source] = QString("ac");
m_formater[QString("ac")] = ACFormat;
} else if (source.startsWith(QString("battery/"))) {
// battery stats
QString key = source;
key.remove(QString("battery/"));
m_map[source] = key;
m_formater[key] = IntegerThree;
} else if (source == QString("cpu/system/TotalLoad")) {
// cpu
m_map[source] = QString("cpu");
m_formater[QString("cpu")] = Float;
} else if (source.contains(cpuRegExp)) {
// cpus
QString key = source;
key.remove(QString("cpu/")).remove(QString("/TotalLoad"));
m_map[source] = key;
m_formater[key] = Float;
} else if (source == QString("cpu/system/AverageClock")) {
// cpucl
m_map[source] = QString("cpucl");
m_formater[QString("cpucl")] = Integer;
} else if (source.contains(cpuclRegExp)) {
// cpucls
QString key = source;
key.remove(QString("cpu/cpu")).remove(QString("/clock"));
key = QString("cpucl%1").arg(key);
m_map[source] = key;
m_formater[key] = Integer;
} else if (source.startsWith(QString("custom"))) {
// custom
QString key = source;
key.remove(QString("custom/"));
m_map[source] = key;
m_formater[key] = NoFormat;
} else if (source == QString("desktop/current/name")) {
// current desktop name
m_map[source] = QString("desktop");
m_formater[QString("desktop")] = NoFormat;
} else if (source == QString("desktop/current/number")) {
// current desktop number
m_map[source] = QString("ndesktop");
m_formater[QString("ndesktop")] = NoFormat;
} else if (source == QString("desktop/total/number")) {
// desktop count
m_map[source] = QString("tdesktops");
m_formater[QString("tdesktops")] = NoFormat;
} else if (source.contains(hddrRegExp)) {
// read speed
QString device = source;
device.remove(QString("/Rate/rblk"));
int index = m_devices[QString("disk")].indexOf(device);
if (index > -1) {
QString key = QString("hddr%1").arg(index);
m_map[source] = key;
m_formater[key] = Integer;
}
} else if (source.contains(hddwRegExp)) {
// write speed
QString device = source;
device.remove(QString("/Rate/wblk"));
int index = m_devices[QString("disk")].indexOf(device);
if (index > -1) {
QString key = QString("hddw%1").arg(index);
m_map[source] = key;
m_formater[key] = Integer;
}
} else if (source == QString("gpu/load")) {
// gpu load
m_map[source] = QString("gpu");
m_formater[QString("gpu")] = Float;
} else if (source == QString("gpu/temperature")) {
// gpu temperature
m_map[source] = QString("gputemp");
m_formater[QString("gputemp")] = Temperature;
} else if (source.contains(mountFillRegExp)) {
// fill level
QString device = source;
device.remove(QString("partitions")).remove(QString("/filllevel"));
int index = m_devices[QString("mount")].indexOf(device);
if (index > -1) {
QString key = QString("hdd%1").arg(index);
m_map[source] = key;
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)) {
// free space
QString device = source;
device.remove(QString("partitions")).remove(QString("/freespace"));
int index = m_devices[QString("mount")].indexOf(device);
if (index > -1) {
// mb
QString key = QString("hddfreemb%1").arg(index);
m_map[source] = key;
m_formater[key] = MemMBFormat;
// gb
key = QString("hddfreegb%1").arg(index);
m_map.insertMulti(source, key);
m_formater[key] = MemGBFormat;
}
} else if (source.contains(mountUsedRegExp)) {
// used
QString device = source;
device.remove(QString("partitions")).remove(QString("/usedspace"));
int index = m_devices[QString("mount")].indexOf(device);
if (index > -1) {
// mb
QString key = QString("hddmb%1").arg(index);
m_map[source] = key;
m_formater[key] = MemMBFormat;
// gb
key = QString("hddgb%1").arg(index);
m_map.insertMulti(source, key);
m_formater[key] = MemGBFormat;
}
} else if (source.startsWith(QString("hdd/temperature"))) {
// hdd temperature
QString device = source;
device.remove(QString("hdd/temperature"));
int index = m_devices[QString("hdd")].indexOf(device);
if (index > -1) {
QString key = QString("hddtemp%1").arg(index);
m_map[source] = key;
m_formater[key] = Temperature;
}
} else if (source.startsWith(QString("cpu/system/loadavg"))) {
// load average
QString time = source;
time.remove(QString("cpu/system/loadavg"));
QString key = QString("la%1").arg(time);
m_map[source] = key;
m_formater[key] = FloatTwoSymbols;
} else if (source == QString("mem/physical/application")) {
// app memory
// mb
m_map[source] = QString("memmb");
m_formater[QString("memmb")] = MemMBFormat;
// gb
m_map.insertMulti(source, QString("memgb"));
m_formater[QString("memgb")] = MemGBFormat;
} else if (source == QString("mem/physical/free")) {
// free memory
// mb
m_map[source] = QString("memfreemb");
m_formater[QString("memfreemb")] = MemMBFormat;
// gb
m_map.insertMulti(source, QString("memfreegb"));
m_formater[QString("memfreegb")] = MemGBFormat;
} else if (source == QString("mem/physical/used")) {
// used memory
// mb
m_map[source] = QString("memusedmb");
m_formater[QString("memusedmb")] = MemMBFormat;
// gb
m_map.insertMulti(source, QString("memusedgb"));
m_formater[QString("memusedgb")] = MemGBFormat;
} else if (source == QString("network/current/name")) {
// network device
m_map[source] = QString("netdev");
m_formater[QString("netdev")] = NoFormat;
} else if (source.contains(netRegExp)) {
// network speed
QString type = source.contains(QString("receiver")) ? QString("down")
: QString("up");
int index
= m_devices[QString("net")].indexOf(source.split(QChar('/'))[2]);
if (index > -1) {
// kb
QString key = QString("%1kb%2").arg(type).arg(index);
m_map[source] = key;
m_formater[key] = Integer;
// smart
key = QString("%1%2").arg(type).arg(index);
m_map.insertMulti(source, key);
m_formater[key] = NetSmartFormat;
// units
key = QString("%1units%2").arg(type).arg(index);
m_map.insertMulti(source, key);
m_formater[key] = NetSmartUnits;
}
} else if (source.startsWith(QString("upgrade"))) {
// package manager
QString key = source;
key.remove(QString("upgrade/"));
m_map[source] = key;
m_formater[key] = IntegerThree;
} else if (source.startsWith(QString("player"))) {
// player
QString key = source;
key.remove(QString("player/"));
m_map[source] = key;
m_formater[key] = NoFormat;
} else if (source == QString("ps/running/count")) {
// running processes count
m_map[source] = QString("pscount");
m_formater[QString("pscount")] = NoFormat;
} else if (source == QString("ps/running/list")) {
// list of running processes
m_map[source] = QString("ps");
m_formater[QString("ps")] = List;
} else if (source == QString("ps/total/count")) {
// total processes count
m_map[source] = QString("pstotal");
m_formater[QString("pstotal")] = NoFormat;
} else if (source.startsWith(QString("quotes"))) {
// quotes
QString key = source;
key.remove(QString("quotes/"));
m_map[source] = key;
m_formater[key] = Quotes;
} else if (source == QString("mem/swap/free")) {
// free swap
// mb
m_map[source] = QString("swapfreemb");
m_formater[QString("swapfreemb")] = MemMBFormat;
// gb
m_map.insertMulti(source, QString("swapfreegb"));
m_formater[QString("swapfreegb")] = MemGBFormat;
} else if (source == QString("mem/swap/used")) {
// used swap
// mb
m_map[source] = QString("swapmb");
m_formater[QString("swapmb")] = MemMBFormat;
// gb
m_map.insertMulti(source, QString("swapgb"));
m_formater[QString("swapgb")] = MemGBFormat;
} else if (source.startsWith(QString("lmsensors/"))) {
// temperature
int index = m_devices[QString("temp")].indexOf(source);
// FIXME on DE initialization there are no units key
if (units.isEmpty())
return QStringList() << QString("temp%1").arg(index);
if (index > -1) {
QString key = QString("temp%1").arg(index);
m_map[source] = key;
m_formater[key] = units == QString("°C") ? Temperature : Integer;
}
} else if (source == QString("Local")) {
// time
m_map[source] = QString("time");
m_formater[QString("time")] = Time;
// custom time
m_map.insertMulti(source, QString("ctime"));
m_formater[QString("ctime")] = TimeCustom;
// ISO time
m_map.insertMulti(source, QString("isotime"));
m_formater[QString("isotime")] = TimeISO;
// long time
m_map.insertMulti(source, QString("longtime"));
m_formater[QString("longtime")] = TimeLong;
// short time
m_map.insertMulti(source, QString("shorttime"));
m_formater[QString("shorttime")] = TimeShort;
} else if (source == QString("system/uptime")) {
// uptime
m_map[source] = QString("uptime");
m_formater[QString("uptime")] = Uptime;
// custom uptime
m_map.insertMulti(source, QString("cuptime"));
m_formater[QString("cuptime")] = UptimeCustom;
} else if (source.startsWith(QString("weather/temperature"))) {
// temperature
QString key = source;
key.remove(QString("weather/"));
m_map[source] = key;
m_formater[key] = Temperature;
} else if (source.startsWith(QString("weather/"))) {
// other weather
QString key = source;
key.remove(QString("weather/"));
m_map[source] = key;
m_formater[key] = NoFormat;
} else if (source.startsWith(QString("load/load"))) {
// load source
QString key = source;
key.remove(QString("load/"));
m_map[source] = key;
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);
}
float AWKeysAggregator::temperature(const float temp) const
{
qCDebug(LOG_AW) << "Temperature value" << temp;
float converted = temp;
if (m_tempUnits == QString("Celsius")) {
} else if (m_tempUnits == QString("Fahrenheit")) {
converted = temp * 9.0f / 5.0f + 32.0f;
} else if (m_tempUnits == QString("Kelvin")) {
converted = temp + 273.15f;
} else if (m_tempUnits == QString("Reaumur")) {
converted = temp * 0.8f;
} else if (m_tempUnits == QString("cm^-1")) {
converted = (temp + 273.15f) * 0.695f;
} else if (m_tempUnits == QString("kJ/mol")) {
converted = (temp + 273.15f) * 8.31f;
} else if (m_tempUnits == QString("kcal/mol")) {
converted = (temp + 273.15f) * 1.98f;
} else {
qCWarning(LOG_AW) << "Invalid units" << m_tempUnits;
}
return converted;
}

View File

@ -0,0 +1,100 @@
/***************************************************************************
* 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 AWKEYSAGGREGATOR_H
#define AWKEYSAGGREGATOR_H
#include <QHash>
#include <QObject>
#include "version.h"
class AWKeysAggregator : public QObject
{
Q_OBJECT
Q_PROPERTY(QString acOffline MEMBER m_acOffline WRITE setAcOffline);
Q_PROPERTY(QString acOnline MEMBER m_acOnline WRITE setAcOnline);
Q_PROPERTY(QString customTime MEMBER m_customTime WRITE setCustomTime);
Q_PROPERTY(
QString customUptime MEMBER m_customUptime WRITE setCustomUptime);
Q_PROPERTY(QString tempUnits MEMBER m_tempUnits WRITE setTempUnits);
Q_PROPERTY(bool translate MEMBER m_translate WRITE setTranslate);
enum FormaterType {
// general formaters
NoFormat = 0,
Float,
FloatTwoSymbols,
Integer,
IntegerFive,
IntegerThree,
List,
// unit specific formaters
ACFormat,
MemGBFormat,
MemMBFormat,
NetSmartFormat,
NetSmartUnits,
Quotes,
Temperature,
Time,
TimeCustom,
TimeISO,
TimeLong,
TimeShort,
Uptime,
UptimeCustom
};
public:
explicit AWKeysAggregator(QObject *parent = nullptr);
virtual ~AWKeysAggregator();
// get methods
QString formater(const QVariant &data, const QString &key) const;
QStringList keysFromSource(const QString &source) const;
// set methods
void setAcOffline(const QString inactive);
void setAcOnline(const QString active);
void setCustomTime(const QString customTime);
void setCustomUptime(const QString customUptime);
void setDevices(const QHash<QString, QStringList> devices);
void setTempUnits(const QString units);
void setTranslate(const bool translate);
public slots:
QStringList registerSource(const QString &source, const QString &units,
const QStringList &keys);
private:
float temperature(const float temp) const;
QStringList timeKeys = QString(TIME_KEYS).split(QChar(','));
// variables
QString m_acOffline;
QString m_acOnline;
QString m_customTime;
QString m_customUptime;
QHash<QString, QStringList> m_devices;
QHash<QString, FormaterType> m_formater;
QHash<QString, QString> m_map;
QString m_tempUnits;
bool m_translate = false;
};
#endif /* AWKEYSAGGREGATOR_H */

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

@ -1,181 +0,0 @@
/***************************************************************************
* 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 "awtooltip.h"
#include <QBuffer>
#include <math.h>
#include "awdebug.h"
AWToolTip::AWToolTip(QObject *parent, QVariantMap settings)
: QObject(parent),
configuration(qvariant_cast<QVariantHash>(settings))
{
qCDebug(LOG_AW);
toolTipScene = new QGraphicsScene(nullptr);
toolTipView = new QGraphicsView(toolTipScene);
toolTipView->setStyleSheet(QString("background: transparent"));
toolTipView->setContentsMargins(0, 0, 0, 0);
toolTipView->setFrameShape(QFrame::NoFrame);
toolTipView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
toolTipView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
counts += configuration[QString("cpuTooltip")].toInt();
counts += configuration[QString("cpuclTooltip")].toInt();
counts += configuration[QString("memTooltip")].toInt();
counts += configuration[QString("swapTooltip")].toInt();
counts += configuration[QString("downTooltip")].toInt();
counts += configuration[QString("batTooltip")].toInt();
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;
size.setHeight(105.0);
size.setWidth(100.0 * counts);
if (configuration[QString("cpuTooltip")].toBool()) requiredKeys.append(QString("cpuTooltip"));
if (configuration[QString("cpuclTooltip")].toBool()) requiredKeys.append(QString("cpuclTooltip"));
if (configuration[QString("memTooltip")].toBool()) requiredKeys.append(QString("memTooltip"));
if (configuration[QString("swapTooltip")].toBool()) requiredKeys.append(QString("swapTooltip"));
if (configuration[QString("downTooltip")].toBool()) requiredKeys.append(QString("downTooltip"));
if (configuration[QString("upTooltip")].toBool()) requiredKeys.append(QString("upTooltip"));
if (configuration[QString("batTooltip")].toBool()) requiredKeys.append(QString("batTooltip"));
connect(this, SIGNAL(updateData(QHash<QString, QString>)),
this, SLOT(dataUpdate(QHash<QString, QString>)));
}
AWToolTip::~AWToolTip()
{
qCDebug(LOG_AW);
delete toolTipScene;
}
void AWToolTip::dataUpdate(QHash<QString, QString> values)
{
qCDebug(LOG_AW);
// battery update requires info is AC online or not
setData(QString("batTooltip"), values[QString("bat")].toFloat(),
values[QString("ac")] == configuration[QString("acOnline")]);
// usual case
setData(QString("cpuTooltip"), values[QString("cpu")].toFloat());
setData(QString("cpuclTooltip"), values[QString("cpucl")].toFloat());
setData(QString("memTooltip"), values[QString("mem")].toFloat());
setData(QString("swapTooltip"), values[QString("swap")].toFloat());
setData(QString("downTooltip"), values[QString("downkb")].toFloat());
setData(QString("upTooltip"), values[QString("upkb")].toFloat());
emit(toolTipPainted(htmlImage()));
}
QSize AWToolTip::getSize() const
{
qCDebug(LOG_AW);
return size;
}
QString AWToolTip::htmlImage()
{
qCDebug(LOG_AW);
QPixmap rawImage = image();
QByteArray byteArray;
QBuffer buffer(&byteArray);
rawImage.save(&buffer, "PNG");
return byteArray.isEmpty() ? QString() :
QString("<img src=\"data:image/png;base64,%1\"/>").arg(QString(byteArray.toBase64()));
}
QPixmap AWToolTip::image()
{
qCDebug(LOG_AW);
toolTipView->resize(size);
// create image
toolTipScene->clear();
QPen pen = QPen();
// background
toolTipScene->setBackgroundBrush(configuration[QString("useTooltipBackground")].toBool() ?
QBrush(QColor(configuration[QString("tooltipBackground")].toString())) :
QBrush(Qt::NoBrush));
bool down = false;
for (int i=0; i<requiredKeys.count(); i++) {
float normX = 100.0 / static_cast<float>(data[requiredKeys.at(i)].count());
float normY = 100.0 / (1.5 * boundaries[requiredKeys.at(i)]);
if (requiredKeys.at(i) != QString("batTooltip"))
pen.setColor(QColor(configuration[QString("%1Color").arg(requiredKeys.at(i))].toString()));
float shift = i * 100.0;
if (down) shift -= 100.0;
for (int j=0; j<data[requiredKeys.at(i)].count()-1; j++) {
// some magic here
float x1 = j * normX + shift;
float y1 = - fabs(data[requiredKeys.at(i)].at(j)) * normY + 5.0;
float x2 = (j + 1) * normX + shift;
float y2 = - fabs(data[requiredKeys.at(i)].at(j+1)) * normY + 5.0;
if (requiredKeys.at(i) == QString("batTooltip")) {
if (data[requiredKeys.at(i)].at(j+1) > 0)
pen.setColor(QColor(configuration[QString("batTooltipColor")].toString()));
else
pen.setColor(QColor(configuration[QString("batInTooltipColor")].toString()));
}
toolTipScene->addLine(x1, y1, x2, y2, pen);
}
if (requiredKeys.at(i) == QString("downTooltip")) down = true;
}
return toolTipView->grab();
}
void AWToolTip::setData(const QString source, float value, const bool dontInvert)
{
qCDebug(LOG_AW);
qCDebug(LOG_AW) << "Source" << source;
qCDebug(LOG_AW) << "Value" << value;
qCDebug(LOG_AW) << "Do not invert value" << dontInvert;
if (data[source].count() == 0)
data[source].append(0.0);
else if (data[source].count() > configuration[QString("tooltipNumber")].toInt())
data[source].takeFirst();
if (isnan(value)) value = 0.0;
// invert values for different battery colours
data[source].append(dontInvert ? value : -value);
if (source == QString("downTooltip")) {
QList<float> netValues = data[QString("downTooltip")] + data[QString("upTooltip")];
boundaries[QString("downTooltip")] = 1.2 * *std::max_element(netValues.cbegin(), netValues.cend());
boundaries[QString("upTooltip")] = boundaries[QString("downTooltip")];
}
}

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

@ -16,49 +16,38 @@
***************************************************************************/
#ifndef AWTOOLTIP_H
#define AWTOOLTIP_H
#ifndef AWUPDATEHELPER_H
#define AWUPDATEHELPER_H
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QHash>
#include <QMessageBox>
#include <QObject>
#include <QPixmap>
#include <QVariant>
#include <QVersionNumber>
class AWToolTip : public QObject
class QNetworkReply;
class AWUpdateHelper : public QObject
{
Q_OBJECT
public:
explicit AWToolTip(QObject *parent = nullptr, QVariantMap settings = QVariantMap());
virtual ~AWToolTip();
QSize getSize() const;
QString htmlImage();
QPixmap image();
signals:
void updateData(QHash<QString, QString> values);
void toolTipPainted(QString image);
explicit AWUpdateHelper(QObject *parent = nullptr);
virtual ~AWUpdateHelper();
void checkUpdates(const bool showAnyway = false);
bool checkVersion();
private slots:
void dataUpdate(QHash<QString, QString> values);
void showInfo(const QVersionNumber version);
void showUpdates(const QVersionNumber version);
void userReplyOnUpdates(QAbstractButton *button);
void versionReplyRecieved(QNetworkReply *reply, const bool showAnyway);
private:
// ui
QGraphicsScene *toolTipScene = nullptr;
QGraphicsView *toolTipView = nullptr;
void setData(const QString source, float value,
const bool dontInvert = true);
// variables
int counts = 0;
QVariantHash configuration;
QHash<QString, float> boundaries;
QHash<QString, QList<float>> data;
QStringList requiredKeys;
QSize size;
QMessageBox *genMessageBox(const QString title, const QString body,
const QMessageBox::StandardButtons buttons);
QVersionNumber m_foundVersion;
QString m_genericConfig;
};
#endif /* AWTOOLTIP_H */
#endif /* AWUPDATEHELPER_H */

View File

@ -3,18 +3,18 @@ message(STATUS "Subproject ${SUBPROJECT}")
add_definitions(-DTRANSLATION_DOMAIN=\"plasma_applet_org.kde.plasma.awesomewidget\")
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/../
${PROJECT_TRDPARTY_DIR}
${Qt_INCLUDE}
${Kf5_INCLUDE}
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${PROJECT_TRDPARTY_DIR}
${Qt_INCLUDE}
${Kf5_INCLUDE}
)
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_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_QUOTES ${CMAKE_CURRENT_SOURCE_DIR}/quotes)
set(SUBPROJECT_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/scripts)
@ -26,16 +26,16 @@ file(RELATIVE_PATH SUBPROJECT_WEATHER_JSON ${CMAKE_SOURCE_DIR} ${SUBPROJECT_WEAT
# prepare
configure_file(${SUBPROJECT_WEATHER_JSON_IN} ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON})
qt5_wrap_cpp(SUBPROJECT_MOC_SOURCE ${SUBPROJECT_HEADER})
qt5_wrap_ui(SUBPROJECT_UI_HEADER ${SUBPROJECT_UI})
add_library(${SUBPROJECT} STATIC ${SUBPROJECT_SOURCE} ${SUBPROJECT_MOC_SOURCE}
${SUBPROJECT_HEADER} ${SUBPROJECT_UI_HEADER})
add_library(${SUBPROJECT} STATIC ${SUBPROJECT_SOURCE} ${SUBPROJECT_HEADER} ${SUBPROJECT_UI_HEADER})
target_link_libraries(${SUBPROJECT} ${Qt_LIBRARIES} ${Kf5_LIBRARIES})
# install
install(DIRECTORY ${SUBPROJECT_CONFIGS} 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_SCRIPTS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_UPGRADE} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_WEATHER} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(FILES ${SUBPROJECT_INI} DESTINATION ${CONFIG_INSTALL_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/weather)

View File

@ -24,17 +24,19 @@
#include "awdebug.h"
#include "version.h"
#include "abstractextitemaggregator.h"
AbstractExtItem::AbstractExtItem(QWidget *parent, const QString desktopName,
const QStringList directories)
: QDialog(parent),
m_fileName(desktopName),
m_dirs(directories)
: QDialog(parent)
, m_fileName(desktopName)
, m_dirs(directories)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Desktop name" << desktopName;
qCDebug(LOG_LIB) << "Directories" << directories;
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
qCDebug(LOG_LIB) << "Desktop name" << desktopName << "directories"
<< directories;
m_name = m_fileName;
}
@ -42,90 +44,70 @@ AbstractExtItem::AbstractExtItem(QWidget *parent, const QString desktopName,
AbstractExtItem::~AbstractExtItem()
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
}
template <class T>
T *AbstractExtItem::copy(const QString _fileName, const int _number)
void AbstractExtItem::copyDefaults(AbstractExtItem *_other) const
{
Q_UNUSED(_fileName)
Q_UNUSED(_number)
qCDebug(LOG_LIB);
// an analog of pure virtual method
return new T();
_other->setActive(m_active);
_other->setApiVersion(m_apiVersion);
_other->setComment(m_comment);
_other->setInterval(m_interval);
_other->setName(m_name);
}
int AbstractExtItem::apiVersion() const
{
qCDebug(LOG_LIB);
return m_apiVersion;
}
QString AbstractExtItem::comment() const
{
qCDebug(LOG_LIB);
return m_comment;
}
QStringList AbstractExtItem::directories() const
{
qCDebug(LOG_LIB);
return m_dirs;
}
QString AbstractExtItem::fileName() const
{
qCDebug(LOG_LIB);
return m_fileName;
}
int AbstractExtItem::interval() const
{
qCDebug(LOG_LIB);
return m_interval;
}
bool AbstractExtItem::isActive() const
{
qCDebug(LOG_LIB);
return m_active;
}
QString AbstractExtItem::name() const
{
qCDebug(LOG_LIB);
return m_name;
}
int AbstractExtItem::number() const
{
qCDebug(LOG_LIB);
return m_number;
}
QString AbstractExtItem::tag(const QString _type) const
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Tag type" << _type;
return QString("%1%2").arg(_type).arg(m_number);
@ -134,7 +116,6 @@ QString AbstractExtItem::tag(const QString _type) const
void AbstractExtItem::setApiVersion(const int _apiVersion)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Version" << _apiVersion;
m_apiVersion = _apiVersion;
@ -143,7 +124,6 @@ void AbstractExtItem::setApiVersion(const int _apiVersion)
void AbstractExtItem::setActive(const bool _state)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "State" << _state;
m_active = _state;
@ -152,7 +132,6 @@ void AbstractExtItem::setActive(const bool _state)
void AbstractExtItem::setComment(const QString _comment)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Comment" << _comment;
m_comment = _comment;
@ -161,9 +140,9 @@ void AbstractExtItem::setComment(const QString _comment)
void AbstractExtItem::setInterval(const int _interval)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Interval" << _interval;
if (_interval <= 0) return;
if (_interval <= 0)
return;
m_interval = _interval;
}
@ -171,7 +150,6 @@ void AbstractExtItem::setInterval(const int _interval)
void AbstractExtItem::setName(const QString _name)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Name" << _name;
m_name = _name;
@ -180,7 +158,6 @@ void AbstractExtItem::setName(const QString _name)
void AbstractExtItem::setNumber(int _number)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Number" << _number;
if (_number == -1)
_number = []() {
@ -197,18 +174,22 @@ void AbstractExtItem::setNumber(int _number)
void AbstractExtItem::readConfiguration()
{
qCDebug(LOG_LIB);
for (int i=m_dirs.count()-1; i>=0; i--) {
if (!QDir(m_dirs.at(i)).entryList(QDir::Files).contains(m_fileName)) continue;
QSettings settings(QString("%1/%2").arg(m_dirs.at(i)).arg(m_fileName), QSettings::IniFormat);
for (int i = m_dirs.count() - 1; i >= 0; i--) {
if (!QDir(m_dirs.at(i)).entryList(QDir::Files).contains(m_fileName))
continue;
QSettings settings(QString("%1/%2").arg(m_dirs.at(i)).arg(m_fileName),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setName(settings.value(QString("Name"), m_name).toString());
setComment(settings.value(QString("Comment"), m_comment).toString());
setApiVersion(settings.value(QString("X-AW-ApiVersion"), m_apiVersion).toInt());
setActive(settings.value(QString("X-AW-Active"), QVariant(m_active)).toString() == QString("true"));
setInterval(settings.value(QString("X-AW-Interval"), m_interval).toInt());
setApiVersion(
settings.value(QString("X-AW-ApiVersion"), m_apiVersion).toInt());
setActive(settings.value(QString("X-AW-Active"), QVariant(m_active))
.toString()
== QString("true"));
setInterval(
settings.value(QString("X-AW-Interval"), m_interval).toInt());
setNumber(settings.value(QString("X-AW-Number"), m_number).toInt());
settings.endGroup();
}
@ -217,25 +198,24 @@ void AbstractExtItem::readConfiguration()
bool AbstractExtItem::tryDelete() const
{
qCDebug(LOG_LIB);
foreach(QString dir, m_dirs) {
for (auto dir : m_dirs) {
bool status = QFile::remove(QString("%1/%2").arg(dir).arg(m_fileName));
qCInfo(LOG_LIB) << "Remove file" << QString("%1/%2").arg(dir).arg(m_fileName) << status;
qCInfo(LOG_LIB) << "Remove file"
<< QString("%1/%2").arg(dir).arg(m_fileName) << status;
}
// check if exists
foreach(QString dir, m_dirs)
if (QFile::exists(QString("%1/%2").arg(dir).arg(m_fileName))) return false;
for (auto dir : m_dirs)
if (QFile::exists(QString("%1/%2").arg(dir).arg(m_fileName)))
return false;
return true;
}
void AbstractExtItem::writeConfiguration() const
{
qCDebug(LOG_LIB);
QSettings settings(QString("%1/%2").arg(m_dirs.first()).arg(m_fileName), QSettings::IniFormat);
QSettings settings(QString("%1/%2").arg(m_dirs.first()).arg(m_fileName),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));

View File

@ -19,7 +19,6 @@
#define ABSTRACTEXTITEM_H
#include <QDialog>
#include <QInputDialog>
#include <QVariant>
@ -37,10 +36,13 @@ class AbstractExtItem : public QDialog
Q_PROPERTY(QString uniq READ uniq)
public:
explicit AbstractExtItem(QWidget *parent = nullptr, const QString desktopName = QString(),
explicit AbstractExtItem(QWidget *parent = nullptr,
const QString desktopName = QString(),
const QStringList directories = QStringList());
virtual ~AbstractExtItem();
template <class T> T *copy(const QString _fileName, const int _number);
virtual AbstractExtItem *copy(const QString _fileName, const int _number)
= 0;
void copyDefaults(AbstractExtItem *_other) const;
// get methods
int apiVersion() const;
QString comment() const;

View File

@ -29,31 +29,34 @@
AbstractExtItemAggregator::AbstractExtItemAggregator(QWidget *parent)
: QWidget(parent)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
dialog = new QDialog(this);
widgetDialog = new QListWidget(dialog);
dialogButtons = new QDialogButtonBox(QDialogButtonBox::Open | QDialogButtonBox::Close,
Qt::Vertical, dialog);
copyButton = dialogButtons->addButton(i18n("Copy"), QDialogButtonBox::ActionRole);
createButton = dialogButtons->addButton(i18n("Create"), QDialogButtonBox::ActionRole);
deleteButton = dialogButtons->addButton(i18n("Remove"), QDialogButtonBox::ActionRole);
dialogButtons = new QDialogButtonBox(
QDialogButtonBox::Open | QDialogButtonBox::Close, Qt::Vertical, dialog);
copyButton
= dialogButtons->addButton(i18n("Copy"), QDialogButtonBox::ActionRole);
createButton = dialogButtons->addButton(i18n("Create"),
QDialogButtonBox::ActionRole);
deleteButton = dialogButtons->addButton(i18n("Remove"),
QDialogButtonBox::ActionRole);
QHBoxLayout *layout = new QHBoxLayout(dialog);
layout->addWidget(widgetDialog);
layout->addWidget(dialogButtons);
dialog->setLayout(layout);
connect(dialogButtons, SIGNAL(clicked(QAbstractButton *)),
this, SLOT(editItemButtonPressed(QAbstractButton *)));
connect(dialogButtons, SIGNAL(clicked(QAbstractButton *)), this,
SLOT(editItemButtonPressed(QAbstractButton *)));
connect(dialogButtons, SIGNAL(rejected()), dialog, SLOT(reject()));
connect(widgetDialog, SIGNAL(itemActivated(QListWidgetItem *)),
this, SLOT(editItemActivated(QListWidgetItem *)));
connect(widgetDialog, SIGNAL(itemActivated(QListWidgetItem *)), this,
SLOT(editItemActivated(QListWidgetItem *)));
}
AbstractExtItemAggregator::~AbstractExtItemAggregator()
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete dialog;
}
@ -61,14 +64,14 @@ AbstractExtItemAggregator::~AbstractExtItemAggregator()
QString AbstractExtItemAggregator::getName()
{
qCDebug(LOG_LIB);
bool ok;
QString name = QInputDialog::getText(this, i18n("Enter file name"),
i18n("File name"), QLineEdit::Normal,
QString(""), &ok);
if ((!ok) || (name.isEmpty())) return QString("");
if (!name.endsWith(QString(".desktop"))) name += QString(".desktop");
if ((!ok) || (name.isEmpty()))
return QString("");
if (!name.endsWith(QString(".desktop")))
name += QString(".desktop");
return name;
}
@ -76,34 +79,26 @@ QString AbstractExtItemAggregator::getName()
QVariant AbstractExtItemAggregator::configArgs() const
{
qCDebug(LOG_LIB);
return m_configArgs;
}
void AbstractExtItemAggregator::setConfigArgs(const QVariant _configArgs)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Configuration arguments" << _configArgs;
m_configArgs = _configArgs;
}
void AbstractExtItemAggregator::editItemActivated(QListWidgetItem *item)
void AbstractExtItemAggregator::editItemActivated(QListWidgetItem *)
{
Q_UNUSED(item)
qCDebug(LOG_LIB);
return editItem();
}
void AbstractExtItemAggregator::editItemButtonPressed(QAbstractButton *button)
{
qCDebug(LOG_LIB);
if (static_cast<QPushButton *>(button) == copyButton)
return copyItem();
else if (static_cast<QPushButton *>(button) == createButton)

View File

@ -21,12 +21,11 @@
#include <QDialog>
#include <QDialogButtonBox>
#include <QListWidget>
#include <QObject>
#include <QPushButton>
#include <QWidget>
// additinal class since QObject macro does not allow class templates
// additional class since QObject macro does not allow class templates
class AbstractExtItemAggregator : public QWidget
{
Q_OBJECT
@ -49,7 +48,7 @@ public:
void setConfigArgs(const QVariant _configArgs);
private slots:
void editItemActivated(QListWidgetItem *item);
void editItemActivated(QListWidgetItem *);
void editItemButtonPressed(QAbstractButton *button);
private:

View File

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

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
Comment=Simple bat bar
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-InactiveColor="255,255,255,255"
X-AW-Type=Horizontal
X-AW-Direction=LeftToRight
X-AW-Height=25
X-AW-Width=100
X-AW-ApiVersion=2
X-AW-ApiVersion=4
X-AW-Number=3

View File

@ -3,11 +3,14 @@ Encoding=UTF-8
Name=bar0
Comment=Simple cpu bar
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-InactiveColor="255,255,255,255"
X-AW-Type=Horizontal
X-AW-Direction=LeftToRight
X-AW-Height=25
X-AW-Width=100
X-AW-ApiVersion=2
X-AW-ApiVersion=4
X-AW-Number=0

View File

@ -3,11 +3,14 @@ Encoding=UTF-8
Name=bar1
Comment=Simple mem bar
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-InactiveColor="255,255,255,255"
X-AW-Type=Horizontal
X-AW-Direction=LeftToRight
X-AW-Height=25
X-AW-Width=100
X-AW-ApiVersion=2
X-AW-ApiVersion=4
X-AW-Number=1

View File

@ -3,11 +3,14 @@ Encoding=UTF-8
Name=bar2
Comment=Simple swap bar
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-InactiveColor="255,255,255,255"
X-AW-Type=Horizontal
X-AW-Direction=LeftToRight
X-AW-Height=25
X-AW-Width=100
X-AW-ApiVersion=2
X-AW-ApiVersion=4
X-AW-Number=2

View File

@ -24,59 +24,52 @@
#include <QSettings>
#include <QStandardPaths>
#include "abstractextitemaggregator.h"
#include "awdebug.h"
#include "abstractextitemaggregator.h"
template <class T>
class ExtItemAggregator : public AbstractExtItemAggregator
template <class T> class ExtItemAggregator : public AbstractExtItemAggregator
{
public:
explicit ExtItemAggregator(QWidget *parent, const QString type)
: AbstractExtItemAggregator(parent),
m_type(type)
: AbstractExtItemAggregator(parent)
, m_type(type)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Type" << type;
qSetMessagePattern(LOG_FORMAT);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
for (auto metadata : getBuildData())
qCDebug(LOG_LIB) << metadata;
qCDebug(LOG_LIB) << "Type" << type;
initItems();
};
virtual ~ExtItemAggregator()
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
m_items.clear();
}
m_activeItems.clear();
};
QList<T *> activeItems() { return m_activeItems; };
void editItems()
{
qCDebug(LOG_LIB);
repaint();
int ret = dialog->exec();
qCInfo(LOG_LIB) << "Dialog returns" << ret;
};
void initItems()
T *itemByTag(const QString _tag, const QString _type) const
{
qCDebug(LOG_LIB);
m_items.clear();
m_items = getItems();
};
T *itemByTag(const QString _tag) const
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Tag" << _tag;
qCDebug(LOG_LIB) << "Tag" << _tag << "with used type" << _type;
T *found = nullptr;
foreach(T *item, m_items) {
if (item->tag() != _tag) continue;
for (auto item : m_items) {
if (item->tag(_type) != _tag)
continue;
found = item;
break;
}
@ -84,16 +77,16 @@ public:
qCWarning(LOG_LIB) << "Could not find item by tag" << _tag;
return found;
}
};
T *itemByTagNumber(const int _number) const
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Number" << _number;
T *found = nullptr;
foreach(T *item, m_items) {
if (item->number() != _number) continue;
for (auto item : m_items) {
if (item->number() != _number)
continue;
found = item;
break;
}
@ -101,73 +94,71 @@ public:
qCWarning(LOG_LIB) << "Could not find item by number" << _number;
return found;
}
};
T *itemFromWidget() const
{
qCDebug(LOG_LIB);
QListWidgetItem *widgetItem = widgetDialog->currentItem();
if (widgetItem == nullptr) return nullptr;
if (widgetItem == nullptr)
return nullptr;
T *found = nullptr;
foreach(T *item, m_items) {
if (item->fileName() != widgetItem->text()) continue;
for (auto item : m_items) {
if (item->fileName() != widgetItem->text())
continue;
found = item;
break;
}
if (found == nullptr)
qCWarning(LOG_LIB) << "Could not find item by name" << widgetItem->text();
qCWarning(LOG_LIB) << "Could not find item by name"
<< widgetItem->text();
return found;
};
QList<T *> items() const
{
qCDebug(LOG_LIB);
return m_items;
};
QList<T *> items() const { return m_items; };
int uniqNumber() const
{
qCDebug(LOG_LIB);
QList<int> tagList;
foreach(T *item, m_items) tagList.append(item->number());
for (auto item : m_items)
tagList.append(item->number());
int number = 0;
while (tagList.contains(number)) number++;
while (tagList.contains(number))
number++;
return number;
};
private:
QList<T *> m_items;
QList<T *> m_activeItems;
QString m_type;
// init method
QList<T *> getItems()
{
qCDebug(LOG_LIB);
// create directory at $HOME
QString localDir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation))
.arg(m_type);
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_type);
QDir localDirectory;
if (localDirectory.mkpath(localDir))
qCInfo(LOG_LIB) << "Created directory" << localDir;
QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
QString("awesomewidgets/%1").arg(m_type),
QStandardPaths::LocateDirectory);
QStringList dirs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation,
QString("awesomewidgets/%1").arg(m_type),
QStandardPaths::LocateDirectory);
QStringList names;
QList<T *> items;
foreach(QString dir, dirs) {
for (auto dir : dirs) {
QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name);
foreach(QString file, files) {
if (!file.endsWith(QString(".desktop"))) continue;
if (names.contains(file)) continue;
for (auto file : files) {
if ((!file.endsWith(QString(".desktop")))
|| (names.contains(file)))
continue;
qCInfo(LOG_LIB) << "Found file" << file << "in" << dir;
names.append(file);
items.append(new T(this, file, dirs));
@ -175,19 +166,31 @@ private:
}
// sort items
std::sort(items.begin(), items.end(), [](const T *lhs, const T *rhs){
std::sort(items.begin(), items.end(), [](const T *lhs, const T *rhs) {
return lhs->number() < rhs->number();
});
return items;
};
void initItems()
{
m_items.clear();
m_activeItems.clear();
m_items = getItems();
for (auto item : m_items) {
if (!item->isActive())
continue;
m_activeItems.append(item);
}
};
void repaint()
{
qCDebug(LOG_LIB);
widgetDialog->clear();
foreach(T *_item, m_items) {
QListWidgetItem *item = new QListWidgetItem(_item->fileName(), widgetDialog);
for (auto _item : m_items) {
QListWidgetItem *item
= new QListWidgetItem(_item->fileName(), widgetDialog);
QStringList tooltip;
tooltip.append(i18n("Name: %1", _item->name()));
tooltip.append(i18n("Comment: %1", _item->comment()));
@ -200,8 +203,6 @@ private:
// methods
void copyItem()
{
qCDebug(LOG_LIB);
T *source = itemFromWidget();
QString fileName = getName();
int number = uniqNumber();
@ -210,7 +211,7 @@ private:
return;
}
T *newItem = source->copy(fileName, number);
T *newItem = static_cast<T *>(source->copy(fileName, number));
if (newItem->showConfiguration(configArgs()) == 1) {
initItems();
repaint();
@ -219,13 +220,12 @@ private:
void createItem()
{
qCDebug(LOG_LIB);
QString fileName = getName();
int number = uniqNumber();
QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
QString("awesomewidgets/%1").arg(m_type),
QStandardPaths::LocateDirectory);
QStringList dirs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation,
QString("awesomewidgets/%1").arg(m_type),
QStandardPaths::LocateDirectory);
if (fileName.isEmpty()) {
qCWarning(LOG_LIB) << "Nothing to create";
return;
@ -241,8 +241,6 @@ private:
void deleteItem()
{
qCDebug(LOG_LIB);
T *source = itemFromWidget();
if (source == nullptr) {
qCWarning(LOG_LIB) << "Nothing to delete";
@ -257,8 +255,6 @@ private:
void editItem()
{
qCDebug(LOG_LIB);
T *source = itemFromWidget();
if (source == nullptr) {
qCWarning(LOG_LIB) << "Nothing to edit";

View File

@ -35,10 +35,10 @@
ExtQuotes::ExtQuotes(QWidget *parent, const QString quotesName,
const QStringList directories)
: AbstractExtItem(parent, quotesName, directories),
ui(new Ui::ExtQuotes)
: AbstractExtItem(parent, quotesName, directories)
, ui(new Ui::ExtQuotes)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
readConfiguration();
ui->setupUi(this);
@ -54,35 +54,34 @@ ExtQuotes::ExtQuotes(QWidget *parent, const QString quotesName,
values[tag(QString("pricechg"))] = 0.0;
values[tag(QString("percpricechg"))] = 0.0;
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(quotesReplyReceived(QNetworkReply *)));
// HACK declare as child of nullptr to avoid crash with plasmawindowed
// in the destructor
manager = new QNetworkAccessManager(nullptr);
connect(manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(quotesReplyReceived(QNetworkReply *)));
}
ExtQuotes::~ExtQuotes()
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
disconnect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(quotesReplyReceived(QNetworkReply *)));
disconnect(manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(quotesReplyReceived(QNetworkReply *)));
delete manager;
manager->deleteLater();
delete ui;
}
ExtQuotes *ExtQuotes::copy(const QString _fileName, const int _number)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "File" << _fileName;
qCDebug(LOG_LIB) << "Number" << _number;
ExtQuotes *item = new ExtQuotes(static_cast<QWidget *>(parent()), _fileName, directories());
item->setActive(isActive());
item->setApiVersion(apiVersion());
item->setComment(comment());
item->setInterval(interval());
item->setName(name());
ExtQuotes *item = new ExtQuotes(static_cast<QWidget *>(parent()), _fileName,
directories());
copyDefaults(item);
item->setNumber(_number);
item->setTicker(ticker());
@ -92,23 +91,18 @@ ExtQuotes *ExtQuotes::copy(const QString _fileName, const int _number)
QString ExtQuotes::ticker() const
{
qCDebug(LOG_LIB);
return m_ticker;
}
QString ExtQuotes::uniq() const
{
qCDebug(LOG_LIB);
return m_ticker;
}
void ExtQuotes::setTicker(const QString _ticker)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Ticker" << _ticker;
m_ticker = _ticker;
@ -117,12 +111,16 @@ void ExtQuotes::setTicker(const QString _ticker)
void ExtQuotes::readConfiguration()
{
qCDebug(LOG_LIB);
AbstractExtItem::readConfiguration();
for (int i=directories().count()-1; i>=0; i--) {
if (!QDir(directories().at(i)).entryList(QDir::Files).contains(fileName())) continue;
QSettings settings(QString("%1/%2").arg(directories().at(i)).arg(fileName()), QSettings::IniFormat);
for (int i = directories().count() - 1; i >= 0; i--) {
if (!QDir(directories().at(i))
.entryList(QDir::Files)
.contains(fileName()))
continue;
QSettings settings(
QString("%1/%2").arg(directories().at(i)).arg(fileName()),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setTicker(settings.value(QString("X-AW-Ticker"), m_ticker).toString());
@ -131,7 +129,8 @@ void ExtQuotes::readConfiguration()
// update for current API
if ((apiVersion() > 0) && (apiVersion() < AWEQAPI)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to" << AWEQAPI;
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to"
<< AWEQAPI;
setApiVersion(AWEQAPI);
writeConfiguration();
}
@ -140,18 +139,19 @@ void ExtQuotes::readConfiguration()
QVariantHash ExtQuotes::run()
{
qCDebug(LOG_LIB);
if ((!isActive()) || (isRunning)) return values;
if ((!isActive()) || (isRunning))
return values;
if (times == 1) {
qCInfo(LOG_LIB) << "Send request";
isRunning = true;
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url())));
new QReplyTimeout(reply, 1000);
new QReplyTimeout(reply, REQUEST_TIMEOUT);
}
// update value
if (times >= interval()) times = 0;
if (times >= interval())
times = 0;
times++;
return values;
@ -161,17 +161,18 @@ QVariantHash ExtQuotes::run()
int ExtQuotes::showConfiguration(const QVariant args)
{
Q_UNUSED(args)
qCDebug(LOG_LIB);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_numberValue->setText(QString("%1").arg(number()));
ui->lineEdit_ticker->setText(m_ticker);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked : Qt::Unchecked);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked
: Qt::Unchecked);
ui->spinBox_interval->setValue(interval());
int ret = exec();
if (ret != 1) return ret;
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setNumber(ui->label_numberValue->text().toInt());
@ -187,10 +188,11 @@ int ExtQuotes::showConfiguration(const QVariant args)
void ExtQuotes::writeConfiguration() const
{
qCDebug(LOG_LIB);
AbstractExtItem::writeConfiguration();
QSettings settings(QString("%1/%2").arg(directories().first()).arg(fileName()), QSettings::IniFormat);
QSettings settings(
QString("%1/%2").arg(directories().first()).arg(fileName()),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
@ -202,54 +204,69 @@ void ExtQuotes::writeConfiguration() const
void ExtQuotes::quotesReplyReceived(QNetworkReply *reply)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Return code" << reply->error();
qCDebug(LOG_LIB) << "Reply error message" << reply->errorString();
qCDebug(LOG_LIB) << "Return code" << reply->error() << "with message"
<< reply->errorString();
isRunning = false;
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
reply->deleteLater();
if ((reply->error() != QNetworkReply::NoError) ||
(error.error != QJsonParseError::NoError)) {
if ((reply->error() != QNetworkReply::NoError)
|| (error.error != QJsonParseError::NoError)) {
qCWarning(LOG_LIB) << "Parse error" << error.errorString();
return;
}
QVariantMap jsonQuotes = jsonDoc.toVariant().toMap()[QString("query")].toMap();
jsonQuotes = jsonQuotes[QString("results")].toMap()[QString("quote")].toMap();
float value;
QVariantMap jsonQuotes
= jsonDoc.toVariant().toMap()[QString("query")].toMap();
jsonQuotes
= jsonQuotes[QString("results")].toMap()[QString("quote")].toMap();
double value;
// ask
value = jsonQuotes[QString("Ask")].toString().toFloat();
values[tag(QString("askchg"))] = values[QString("ask")].toFloat() == 0.0 ? 0.0 :
value - values[QString("ask")].toFloat();
values[tag(QString("percaskchg"))] = 100.0 * values[QString("askchg")].toFloat() / values[QString("ask")].toFloat();
value = jsonQuotes[QString("Ask")].toString().toDouble();
values[tag(QString("askchg"))]
= values[QString("ask")].toDouble() == 0.0
? 0.0
: value - values[QString("ask")].toDouble();
values[tag(QString("percaskchg"))] = 100.0
* values[QString("askchg")].toDouble()
/ values[QString("ask")].toDouble();
values[tag(QString("ask"))] = value;
// bid
value = jsonQuotes[QString("Bid")].toString().toFloat();
values[tag(QString("bidchg"))] = values[QString("bid")].toFloat() == 0.0 ? 0.0 :
value - values[QString("bid")].toFloat();
values[tag(QString("percbidchg"))] = 100.0 * values[QString("bidchg")].toFloat() / values[QString("bid")].toFloat();
value = jsonQuotes[QString("Bid")].toString().toDouble();
values[tag(QString("bidchg"))]
= values[QString("bid")].toDouble() == 0.0
? 0.0
: value - values[QString("bid")].toDouble();
values[tag(QString("percbidchg"))] = 100.0
* values[QString("bidchg")].toDouble()
/ values[QString("bid")].toDouble();
values[tag(QString("bid"))] = value;
// last trade
value = jsonQuotes[QString("LastTradePriceOnly")].toString().toFloat();
values[tag(QString("pricechg"))] = values[QString("price")].toFloat() == 0.0 ? 0.0 :
value - values[QString("price")].toFloat();
values[tag(QString("percpricechg"))] = 100.0 * values[QString("pricechg")].toFloat() / values[QString("price")].toFloat();
value = jsonQuotes[QString("LastTradePriceOnly")].toString().toDouble();
values[tag(QString("pricechg"))]
= values[QString("price")].toDouble() == 0.0
? 0.0
: value - values[QString("price")].toDouble();
values[tag(QString("percpricechg"))]
= 100.0 * values[QString("pricechg")].toDouble()
/ values[QString("price")].toDouble();
values[tag(QString("price"))] = value;
}
void ExtQuotes::translate()
{
qCDebug(LOG_LIB);
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_number->setText(i18n("Tag"));
ui->label->setText(i18n("<html><head/><body><p>Use YAHOO! finance ticker to get quotes for the instrument. Refer to <a href=\"http://finance.yahoo.com/\"><span style=\" text-decoration: underline; color:#0057ae;\">http://finance.yahoo.com/</span></a></p></body></html>"));
ui->label->setText(
i18n("<html><head/><body><p>Use YAHOO! finance ticker to \
get quotes for the instrument. Refer to <a href=\"http://finance.yahoo.com/\">\
<span style=\" text-decoration: underline; color:#0057ae;\">http://finance.yahoo.com/\
</span></a></p></body></html>"));
ui->label_ticker->setText(i18n("Ticker"));
ui->checkBox_active->setText(i18n("Active"));
ui->label_interval->setText(i18n("Interval"));
@ -258,10 +275,7 @@ void ExtQuotes::translate()
QString ExtQuotes::url() const
{
qCDebug(LOG_LIB);
QString apiUrl = QString(YAHOO_URL);
apiUrl.replace(QString("$TICKER"), m_ticker);
QString apiUrl = QString(YAHOO_QUOTES_URL).arg(m_ticker);
qCInfo(LOG_LIB) << "API url" << apiUrl;
return apiUrl;

View File

@ -18,16 +18,20 @@
#ifndef EXTQUOTES_H
#define EXTQUOTES_H
#include <QMap>
#include <QNetworkReply>
#include "abstractextitem.h"
#define YAHOO_URL "https://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.quotes where symbol=\"$TICKER\"&env=store://datatables.org/alltableswithkeys&format=json"
#define YAHOO_QUOTES_URL \
"https://query.yahooapis.com/v1/public/yql?q=select * from " \
"yahoo.finance.quotes where " \
"symbol=\"%1\"&env=store://datatables.org/" \
"alltableswithkeys&format=json"
namespace Ui {
class ExtQuotes;
namespace Ui
{
class ExtQuotes;
}
class ExtQuotes : public AbstractExtItem
@ -36,7 +40,8 @@ class ExtQuotes : public AbstractExtItem
Q_PROPERTY(QString ticker READ ticker WRITE setTicker)
public:
explicit ExtQuotes(QWidget *parent = nullptr, const QString quotesName = QString(),
explicit ExtQuotes(QWidget *parent = nullptr,
const QString quotesName = QString(),
const QStringList directories = QStringList());
virtual ~ExtQuotes();
ExtQuotes *copy(const QString _fileName, const int _number);

View File

@ -92,6 +92,9 @@
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>

View File

@ -33,10 +33,10 @@
ExtScript::ExtScript(QWidget *parent, const QString scriptName,
const QStringList directories)
: AbstractExtItem(parent, scriptName, directories),
ui(new Ui::ExtScript)
: AbstractExtItem(parent, scriptName, directories)
, ui(new Ui::ExtScript)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
readConfiguration();
readJsonFilters();
@ -45,36 +45,31 @@ ExtScript::ExtScript(QWidget *parent, const QString scriptName,
value[tag(QString("custom"))] = QString("");
process = new QProcess(this);
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(updateValue()));
process = new QProcess(nullptr);
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this,
SLOT(updateValue()));
process->waitForFinished(0);
}
ExtScript::~ExtScript()
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
process->kill();
delete process;
process->deleteLater();
delete ui;
}
ExtScript *ExtScript::copy(const QString _fileName, const int _number)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "File" << _fileName;
qCDebug(LOG_LIB) << "Number" << _number;
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
ExtScript *item = new ExtScript(static_cast<QWidget *>(parent()), _fileName, directories());
item->setActive(isActive());
item->setApiVersion(apiVersion());
item->setComment(comment());
ExtScript *item = new ExtScript(static_cast<QWidget *>(parent()), _fileName,
directories());
copyDefaults(item);
item->setExecutable(executable());
item->setHasOutput(hasOutput());
item->setInterval(interval());
item->setName(name());
item->setNumber(_number);
item->setPrefix(prefix());
item->setRedirect(redirect());
@ -85,56 +80,36 @@ ExtScript *ExtScript::copy(const QString _fileName, const int _number)
QString ExtScript::executable() const
{
qCDebug(LOG_LIB);
return m_executable;
}
QStringList ExtScript::filters() const
{
qCDebug(LOG_LIB);
return m_filters;
}
bool ExtScript::hasOutput() const
{
qCDebug(LOG_LIB);
return m_output;
}
QString ExtScript::prefix() const
{
qCDebug(LOG_LIB);
return m_prefix;
}
ExtScript::Redirect ExtScript::redirect() const
{
qCDebug(LOG_LIB);
return m_redirect;
}
QString ExtScript::uniq() const
{
qCDebug(LOG_LIB);
return m_executable;
}
QString ExtScript::strRedirect() const
{
qCDebug(LOG_LIB);
QString value;
switch (m_redirect) {
case stdout2stderr:
@ -143,6 +118,9 @@ QString ExtScript::strRedirect() const
case stderr2stdout:
value = QString("stderr2stdout");
break;
case swap:
value = QString("swap");
break;
case nothing:
default:
value = QString("nothing");
@ -155,7 +133,6 @@ QString ExtScript::strRedirect() const
void ExtScript::setExecutable(const QString _executable)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Executable" << _executable;
m_executable = _executable;
@ -164,28 +141,15 @@ void ExtScript::setExecutable(const QString _executable)
void ExtScript::setFilters(const QStringList _filters)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Filters" << _filters;
std::for_each(_filters.cbegin(), _filters.cend(),
[this](QString filter) { return updateFilter(filter); });
// foreach(QString filter, _filters)
// updateFilter(filter);
}
void ExtScript::setHasOutput(const bool _state)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "State" << _state;
m_output = _state;
}
void ExtScript::setPrefix(const QString _prefix)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Prefix" << _prefix;
m_prefix = _prefix;
@ -194,7 +158,6 @@ void ExtScript::setPrefix(const QString _prefix)
void ExtScript::setRedirect(const Redirect _redirect)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Redirect" << _redirect;
m_redirect = _redirect;
@ -203,13 +166,14 @@ void ExtScript::setRedirect(const Redirect _redirect)
void ExtScript::setStrRedirect(const QString _redirect)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Redirect" << _redirect;
if (_redirect == QString("stdout2sdterr"))
m_redirect = stdout2stderr;
else if (_redirect == QString("stderr2sdtout"))
m_redirect = stderr2stdout;
else if (_redirect == QString("swap"))
m_redirect = swap;
else
m_redirect = nothing;
}
@ -217,17 +181,17 @@ void ExtScript::setStrRedirect(const QString _redirect)
QString ExtScript::applyFilters(QString _value) const
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Value" << _value;
foreach(QString filt, m_filters) {
for (auto filt : m_filters) {
qCInfo(LOG_LIB) << "Found filter" << filt;
QVariantMap filter = jsonFilters[filt].toMap();
if (filter.isEmpty()) {
qCWarning(LOG_LIB) << "Could not find filter" << _value << "in the json";
qCWarning(LOG_LIB) << "Could not find filter" << _value
<< "in the json";
continue;
}
foreach(QString f, filter.keys())
for (auto f : filter.keys())
_value.replace(f, filter[f].toString());
}
@ -237,12 +201,11 @@ QString ExtScript::applyFilters(QString _value) const
void ExtScript::updateFilter(const QString _filter, const bool _add)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Filter" << _filter;
qCDebug(LOG_LIB) << "Should be added" << _add;
qCDebug(LOG_LIB) << "Should be added filters" << _add << "from" << _filter;
if (_add) {
if (m_filters.contains(_filter)) return;
if (m_filters.contains(_filter))
return;
m_filters.append(_filter);
} else {
m_filters.removeOne(_filter);
@ -252,30 +215,33 @@ void ExtScript::updateFilter(const QString _filter, const bool _add)
void ExtScript::readConfiguration()
{
qCDebug(LOG_LIB);
AbstractExtItem::readConfiguration();
for (int i=directories().count()-1; i>=0; i--) {
if (!QDir(directories().at(i)).entryList(QDir::Files).contains(fileName())) continue;
QSettings settings(QString("%1/%2").arg(directories().at(i)).arg(fileName()), QSettings::IniFormat);
for (int i = directories().count() - 1; i >= 0; i--) {
if (!QDir(directories().at(i))
.entryList(QDir::Files)
.contains(fileName()))
continue;
QSettings settings(
QString("%1/%2").arg(directories().at(i)).arg(fileName()),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setExecutable(settings.value(QString("Exec"), m_executable).toString());
setPrefix(settings.value(QString("X-AW-Prefix"), m_prefix).toString());
setHasOutput(settings.value(QString("X-AW-Output"), QVariant(m_output)).toString() == QString("true"));
setStrRedirect(settings.value(QString("X-AW-Redirect"), strRedirect()).toString());
setStrRedirect(
settings.value(QString("X-AW-Redirect"), strRedirect()).toString());
// api == 3
setFilters(settings.value(QString("X-AW-Filters"), m_filters).toString()
.split(QChar(','), QString::SkipEmptyParts));
setFilters(settings.value(QString("X-AW-Filters"), m_filters)
.toString()
.split(QChar(','), QString::SkipEmptyParts));
settings.endGroup();
}
if (!m_output)
setRedirect(stdout2stderr);
// update for current API
if ((apiVersion() > 0) && (apiVersion() < AWESAPI)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to" << AWESAPI;
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to"
<< AWESAPI;
setApiVersion(AWESAPI);
writeConfiguration();
}
@ -284,10 +250,10 @@ void ExtScript::readConfiguration()
void ExtScript::readJsonFilters()
{
qCDebug(LOG_LIB);
QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
QString("awesomewidgets/scripts/awesomewidgets-extscripts-filters.json"));
QString fileName = QStandardPaths::locate(
QStandardPaths::GenericDataLocation,
QString(
"awesomewidgets/scripts/awesomewidgets-extscripts-filters.json"));
qCInfo(LOG_LIB) << "Filters file" << fileName;
QFile jsonFile(fileName);
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
@ -311,17 +277,19 @@ void ExtScript::readJsonFilters()
QVariantHash ExtScript::run()
{
qCDebug(LOG_LIB);
if (!isActive()) return value;
if (!isActive())
return value;
if ((times == 1) && (process->state() == QProcess::NotRunning)) {
QStringList cmdList;
if (!m_prefix.isEmpty()) cmdList.append(m_prefix);
if (!m_prefix.isEmpty())
cmdList.append(m_prefix);
cmdList.append(m_executable);
qCInfo(LOG_LIB) << "Run cmd" << cmdList.join(QChar(' '));
process->start(cmdList.join(QChar(' ')));
} else if (times >= interval())
} else if (times >= interval()) {
times = 0;
}
times++;
return value;
@ -331,24 +299,27 @@ QVariantHash ExtScript::run()
int ExtScript::showConfiguration(const QVariant args)
{
Q_UNUSED(args)
qCDebug(LOG_LIB);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_numberValue->setText(QString("%1").arg(number()));
ui->lineEdit_command->setText(m_executable);
ui->lineEdit_prefix->setText(m_prefix);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked : Qt::Unchecked);
ui->checkBox_output->setCheckState(m_output ? Qt::Checked : Qt::Unchecked);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked
: Qt::Unchecked);
ui->comboBox_redirect->setCurrentIndex(static_cast<int>(m_redirect));
ui->spinBox_interval->setValue(interval());
// filters
ui->checkBox_colorFilter->setCheckState(m_filters.contains(QString("color")) ? Qt::Checked : Qt::Unchecked);
ui->checkBox_linesFilter->setCheckState(m_filters.contains(QString("newline")) ? Qt::Checked : Qt::Unchecked);
ui->checkBox_spaceFilter->setCheckState(m_filters.contains(QString("space")) ? Qt::Checked : Qt::Unchecked);
ui->checkBox_colorFilter->setCheckState(
m_filters.contains(QString("color")) ? Qt::Checked : Qt::Unchecked);
ui->checkBox_linesFilter->setCheckState(
m_filters.contains(QString("newline")) ? Qt::Checked : Qt::Unchecked);
ui->checkBox_spaceFilter->setCheckState(
m_filters.contains(QString("space")) ? Qt::Checked : Qt::Unchecked);
int ret = exec();
if (ret != 1) return ret;
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setNumber(ui->label_numberValue->text().toInt());
@ -356,13 +327,15 @@ int ExtScript::showConfiguration(const QVariant args)
setExecutable(ui->lineEdit_command->text());
setPrefix(ui->lineEdit_prefix->text());
setActive(ui->checkBox_active->checkState() == Qt::Checked);
setHasOutput(ui->checkBox_output->checkState() == Qt::Checked);
setStrRedirect(ui->comboBox_redirect->currentText());
setInterval(ui->spinBox_interval->value());
// filters
updateFilter(QString("color"), ui->checkBox_colorFilter->checkState() == Qt::Checked);
updateFilter(QString("newline"), ui->checkBox_linesFilter->checkState() == Qt::Checked);
updateFilter(QString("space"), ui->checkBox_spaceFilter->checkState() == Qt::Checked);
updateFilter(QString("color"),
ui->checkBox_colorFilter->checkState() == Qt::Checked);
updateFilter(QString("newline"),
ui->checkBox_linesFilter->checkState() == Qt::Checked);
updateFilter(QString("space"),
ui->checkBox_spaceFilter->checkState() == Qt::Checked);
writeConfiguration();
return ret;
@ -371,16 +344,16 @@ int ExtScript::showConfiguration(const QVariant args)
void ExtScript::writeConfiguration() const
{
qCDebug(LOG_LIB);
AbstractExtItem::writeConfiguration();
QSettings settings(QString("%1/%2").arg(directories().first()).arg(fileName()), QSettings::IniFormat);
QSettings settings(
QString("%1/%2").arg(directories().first()).arg(fileName()),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
settings.setValue(QString("Exec"), m_executable);
settings.setValue(QString("X-AW-Prefix"), m_prefix);
settings.setValue(QString("X-AW-Output"), QVariant(m_output).toString());
settings.setValue(QString("X-AW-Redirect"), strRedirect());
settings.setValue(QString("X-AW-Filters"), m_filters.join(QChar(',')));
settings.endGroup();
@ -391,13 +364,15 @@ void ExtScript::writeConfiguration() const
void ExtScript::updateValue()
{
qCDebug(LOG_LIB);
qCInfo(LOG_LIB) << "Cmd returns" << process->exitCode();
QString qdebug = QTextCodec::codecForMib(106)->toUnicode(process->readAllStandardError()).trimmed();
QString qdebug = QTextCodec::codecForMib(106)
->toUnicode(process->readAllStandardError())
.trimmed();
qCInfo(LOG_LIB) << "Error" << qdebug;
QString qoutput = QTextCodec::codecForMib(106)->toUnicode(process->readAllStandardOutput()).trimmed();
qCInfo(LOG_LIB) << "Error" << qoutput;
QString qoutput = QTextCodec::codecForMib(106)
->toUnicode(process->readAllStandardOutput())
.trimmed();
qCInfo(LOG_LIB) << "Output" << qoutput;
QString strValue;
switch (m_redirect) {
@ -406,6 +381,9 @@ void ExtScript::updateValue()
case stderr2stdout:
strValue = QString("%1\n%2").arg(qdebug).arg(qoutput);
break;
case swap:
strValue = qdebug;
break;
case nothing:
default:
strValue = qoutput;
@ -419,15 +397,12 @@ void ExtScript::updateValue()
void ExtScript::translate()
{
qCDebug(LOG_LIB);
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_number->setText(i18n("Tag"));
ui->label_command->setText(i18n("Command"));
ui->label_prefix->setText(i18n("Prefix"));
ui->checkBox_active->setText(i18n("Active"));
ui->checkBox_output->setText(i18n("Has output"));
ui->label_redirect->setText(i18n("Redirect"));
ui->label_interval->setText(i18n("Interval"));
ui->groupBox_filters->setTitle(i18n("Additional filters"));

View File

@ -18,14 +18,14 @@
#ifndef EXTSCRIPT_H
#define EXTSCRIPT_H
#include <QMap>
#include <QProcess>
#include "abstractextitem.h"
namespace Ui {
class ExtScript;
namespace Ui
{
class ExtScript;
}
class ExtScript : public AbstractExtItem
@ -33,25 +33,20 @@ class ExtScript : public AbstractExtItem
Q_OBJECT
Q_PROPERTY(QString executable READ executable WRITE setExecutable)
Q_PROPERTY(QStringList filters READ filters WRITE setFilters)
Q_PROPERTY(bool output READ hasOutput WRITE setHasOutput)
Q_PROPERTY(QString prefix READ prefix WRITE setPrefix)
Q_PROPERTY(Redirect redirect READ redirect WRITE setRedirect)
public:
enum Redirect {
stdout2stderr = 0,
nothing,
stderr2stdout
};
enum Redirect { stdout2stderr = 0, nothing, stderr2stdout, swap };
explicit ExtScript(QWidget *parent = nullptr, const QString scriptName = QString(),
explicit ExtScript(QWidget *parent = nullptr,
const QString scriptName = QString(),
const QStringList directories = QStringList());
virtual ~ExtScript();
ExtScript *copy(const QString _fileName, const int _number);
// get methods
QString executable() const;
QStringList filters() const;
bool hasOutput() const;
QString prefix() const;
Redirect redirect() const;
QString uniq() const;
@ -60,7 +55,6 @@ public:
// set methods
void setExecutable(const QString _executable = QString("/usr/bin/true"));
void setFilters(const QStringList _filters = QStringList());
void setHasOutput(const bool _state = true);
void setPrefix(const QString _prefix = QString(""));
void setRedirect(const Redirect _redirect = nothing);
void setStrRedirect(const QString _redirect = QString("nothing"));
@ -85,11 +79,9 @@ private:
// properties
QString m_executable = QString("/usr/bin/true");
QStringList m_filters = QStringList();
bool m_output = true;
QString m_prefix = QString("");
Redirect m_redirect = nothing;
// internal properties
Q_PID childProcess = 0;
QVariantMap jsonFilters = QVariantMap();
int times = 0;
QVariantHash value;

View File

@ -157,36 +157,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_output">
<item>
<spacer name="spacer_output">
<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_output">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Has output</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_redirect">
<item>
@ -216,6 +186,11 @@
<string notr="true">stderr2stdout</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">swap</string>
</property>
</item>
</widget>
</item>
</layout>

View File

@ -31,10 +31,10 @@
ExtUpgrade::ExtUpgrade(QWidget *parent, const QString upgradeName,
const QStringList directories)
: AbstractExtItem(parent, upgradeName, directories),
ui(new Ui::ExtUpgrade)
: AbstractExtItem(parent, upgradeName, directories)
, ui(new Ui::ExtUpgrade)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
readConfiguration();
ui->setupUi(this);
@ -42,7 +42,7 @@ ExtUpgrade::ExtUpgrade(QWidget *parent, const QString upgradeName,
value[tag(QString("pkgcount"))] = 0;
process = new QProcess(this);
process = new QProcess(nullptr);
connect(process, SIGNAL(finished(int)), this, SLOT(updateValue()));
process->waitForFinished(0);
}
@ -50,28 +50,23 @@ ExtUpgrade::ExtUpgrade(QWidget *parent, const QString upgradeName,
ExtUpgrade::~ExtUpgrade()
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
process->kill();
delete process;
process->deleteLater();
delete ui;
}
ExtUpgrade *ExtUpgrade::copy(const QString _fileName, const int _number)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "File" << _fileName;
qCDebug(LOG_LIB) << "Number" << _number;
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
ExtUpgrade *item = new ExtUpgrade(static_cast<QWidget *>(parent()), _fileName, directories());
item->setActive(isActive());
item->setApiVersion(apiVersion());
item->setComment(comment());
ExtUpgrade *item = new ExtUpgrade(static_cast<QWidget *>(parent()),
_fileName, directories());
copyDefaults(item);
item->setExecutable(executable());
item->setFilter(filter());
item->setInterval(interval());
item->setName(name());
item->setNumber(_number);
item->setNull(null());
@ -81,39 +76,30 @@ ExtUpgrade *ExtUpgrade::copy(const QString _fileName, const int _number)
QString ExtUpgrade::executable() const
{
qCDebug(LOG_LIB);
return m_executable;
}
QString ExtUpgrade::filter() const
{
qCDebug(LOG_LIB);
return m_filter;
}
int ExtUpgrade::null() const
{
qCDebug(LOG_LIB);
return m_null;
}
QString ExtUpgrade::uniq() const
{
qCDebug(LOG_LIB);
return m_executable;
}
void ExtUpgrade::setExecutable(const QString _executable)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Executable" << _executable;
m_executable = _executable;
@ -122,7 +108,6 @@ void ExtUpgrade::setExecutable(const QString _executable)
void ExtUpgrade::setFilter(const QString _filter)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Filter" << _filter;
m_filter = _filter;
@ -131,9 +116,9 @@ void ExtUpgrade::setFilter(const QString _filter)
void ExtUpgrade::setNull(const int _null)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Null lines" << _null;
if (_null < 0) return;
if (_null < 0)
return;
m_null = _null;
}
@ -141,12 +126,16 @@ void ExtUpgrade::setNull(const int _null)
void ExtUpgrade::readConfiguration()
{
qCDebug(LOG_LIB);
AbstractExtItem::readConfiguration();
for (int i=directories().count()-1; i>=0; i--) {
if (!QDir(directories().at(i)).entryList(QDir::Files).contains(fileName())) continue;
QSettings settings(QString("%1/%2").arg(directories().at(i)).arg(fileName()), QSettings::IniFormat);
for (int i = directories().count() - 1; i >= 0; i--) {
if (!QDir(directories().at(i))
.entryList(QDir::Files)
.contains(fileName()))
continue;
QSettings settings(
QString("%1/%2").arg(directories().at(i)).arg(fileName()),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setExecutable(settings.value(QString("Exec"), m_executable).toString());
@ -158,7 +147,8 @@ void ExtUpgrade::readConfiguration()
// update for current API
if ((apiVersion() > 0) && (apiVersion() < AWEUAPI)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to" << AWEUAPI;
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to"
<< AWEUAPI;
setApiVersion(AWEUAPI);
writeConfiguration();
}
@ -167,15 +157,16 @@ void ExtUpgrade::readConfiguration()
QVariantHash ExtUpgrade::run()
{
qCDebug(LOG_LIB);
if (!isActive()) return value;
if (!isActive())
return value;
if ((times == 1) && (process->state() == QProcess::NotRunning)) {
QString cmd = QString("sh -c \"%1\"").arg(m_executable);
qCInfo(LOG_LIB) << "Run cmd" << cmd;
process->start(cmd);
} else if (times >= interval())
} else if (times >= interval()) {
times = 0;
}
times++;
return value;
@ -185,19 +176,20 @@ QVariantHash ExtUpgrade::run()
int ExtUpgrade::showConfiguration(const QVariant args)
{
Q_UNUSED(args)
qCDebug(LOG_LIB);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_numberValue->setText(QString("%1").arg(number()));
ui->lineEdit_command->setText(m_executable);
ui->lineEdit_filter->setText(m_filter);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked : Qt::Unchecked);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked
: Qt::Unchecked);
ui->spinBox_null->setValue(m_null);
ui->spinBox_interval->setValue(interval());
int ret = exec();
if (ret != 1) return ret;
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setNumber(ui->label_numberValue->text().toInt());
@ -215,10 +207,11 @@ int ExtUpgrade::showConfiguration(const QVariant args)
void ExtUpgrade::writeConfiguration() const
{
qCDebug(LOG_LIB);
AbstractExtItem::writeConfiguration();
QSettings settings(QString("%1/%2").arg(directories().first()).arg(fileName()), QSettings::IniFormat);
QSettings settings(
QString("%1/%2").arg(directories().first()).arg(fileName()),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
@ -233,24 +226,25 @@ void ExtUpgrade::writeConfiguration() const
void ExtUpgrade::updateValue()
{
qCDebug(LOG_LIB);
qCInfo(LOG_LIB) << "Cmd returns" << process->exitCode();
qCInfo(LOG_LIB) << "Error" << process->readAllStandardError();
QString qoutput = QTextCodec::codecForMib(106)->toUnicode(process->readAllStandardOutput()).trimmed();
QString qoutput = QTextCodec::codecForMib(106)
->toUnicode(process->readAllStandardOutput())
.trimmed();
value[tag(QString("pkgcount"))] = [this](QString output) {
return m_filter.isEmpty() ?
output.split(QChar('\n'), QString::SkipEmptyParts).count() - m_null :
output.split(QChar('\n'), QString::SkipEmptyParts).filter(QRegExp(m_filter)).count();
return m_filter.isEmpty()
? output.split(QChar('\n'), QString::SkipEmptyParts).count()
- m_null
: output.split(QChar('\n'), QString::SkipEmptyParts)
.filter(QRegExp(m_filter))
.count();
}(qoutput);
}
void ExtUpgrade::translate()
{
qCDebug(LOG_LIB);
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_number->setText(i18n("Tag"));

View File

@ -23,8 +23,9 @@
#include "abstractextitem.h"
namespace Ui {
class ExtUpgrade;
namespace Ui
{
class ExtUpgrade;
}
class ExtUpgrade : public AbstractExtItem
@ -35,7 +36,8 @@ class ExtUpgrade : public AbstractExtItem
Q_PROPERTY(int null READ null WRITE setNull)
public:
explicit ExtUpgrade(QWidget *parent = nullptr, const QString upgradeName = QString(),
explicit ExtUpgrade(QWidget *parent = nullptr,
const QString upgradeName = QString(),
const QStringList directories = QStringList());
virtual ~ExtUpgrade();
ExtUpgrade *copy(const QString _fileName, const int _number);

View File

@ -36,10 +36,10 @@
ExtWeather::ExtWeather(QWidget *parent, const QString weatherName,
const QStringList directories)
: AbstractExtItem(parent, weatherName, directories),
ui(new Ui::ExtWeather)
: AbstractExtItem(parent, weatherName, directories)
, ui(new Ui::ExtWeather)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
readConfiguration();
readJsonMap();
@ -52,39 +52,36 @@ ExtWeather::ExtWeather(QWidget *parent, const QString weatherName,
values[tag(QString("pressure"))] = 0.0;
values[tag(QString("temperature"))] = 0.0;
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(weatherReplyReceived(QNetworkReply *)));
// HACK declare as child of nullptr to avoid crash with plasmawindowed
// in the destructor
manager = new QNetworkAccessManager(nullptr);
connect(manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(weatherReplyReceived(QNetworkReply *)));
}
ExtWeather::~ExtWeather()
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
disconnect(manager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(weatherReplyReceived(QNetworkReply *)));
disconnect(manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(weatherReplyReceived(QNetworkReply *)));
delete manager;
manager->deleteLater();
delete ui;
}
ExtWeather *ExtWeather::copy(const QString _fileName, const int _number)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "File" << _fileName;
qCDebug(LOG_LIB) << "Number" << _number;
qCDebug(LOG_LIB) << "File" << _fileName << "number" << _number;
ExtWeather *item = new ExtWeather(static_cast<QWidget *>(parent()), _fileName, directories());
item->setActive(isActive());
item->setApiVersion(apiVersion());
ExtWeather *item = new ExtWeather(static_cast<QWidget *>(parent()),
_fileName, directories());
copyDefaults(item);
item->setCity(city());
item->setComment(comment());
item->setCountry(country());
item->setInterval(interval());
item->setImage(image());
item->setName(name());
item->setNumber(_number);
item->setTs(ts());
@ -94,57 +91,46 @@ ExtWeather *ExtWeather::copy(const QString _fileName, const int _number)
QString ExtWeather::weatherFromInt(const int _id) const
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Weather ID" << _id;
QVariantMap map = jsonMap[m_image ? QString("image") : QString("text")].toMap();
QVariantMap map
= jsonMap[m_image ? QString("image") : QString("text")].toMap();
return map.value(QString::number(_id), map[QString("default")]).toString();
}
QString ExtWeather::city() const
{
qCDebug(LOG_LIB);
return m_city;
}
QString ExtWeather::country() const
{
qCDebug(LOG_LIB);
return m_country;
}
bool ExtWeather::image() const
{
qCDebug(LOG_LIB);
return m_image;
}
int ExtWeather::ts() const
{
qCDebug(LOG_LIB);
return m_ts;
}
QString ExtWeather::uniq() const
{
qCDebug(LOG_LIB);
return QString("%1 (%2) at %3").arg(m_city).arg(m_country).arg(m_ts);
}
void ExtWeather::setCity(const QString _city)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "City" << _city;
m_city = _city;
@ -153,7 +139,6 @@ void ExtWeather::setCity(const QString _city)
void ExtWeather::setCountry(const QString _country)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Country" << _country;
m_country = _country;
@ -162,7 +147,6 @@ void ExtWeather::setCountry(const QString _country)
void ExtWeather::setImage(const bool _image)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Use image" << _image;
m_image = _image;
@ -171,7 +155,6 @@ void ExtWeather::setImage(const bool _image)
void ExtWeather::setTs(const int _ts)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Timestamp" << _ts;
m_ts = _ts;
@ -180,25 +163,33 @@ void ExtWeather::setTs(const int _ts)
void ExtWeather::readConfiguration()
{
qCDebug(LOG_LIB);
AbstractExtItem::readConfiguration();
for (int i=directories().count()-1; i>=0; i--) {
if (!QDir(directories().at(i)).entryList(QDir::Files).contains(fileName())) continue;
QSettings settings(QString("%1/%2").arg(directories().at(i)).arg(fileName()), QSettings::IniFormat);
for (int i = directories().count() - 1; i >= 0; i--) {
if (!QDir(directories().at(i))
.entryList(QDir::Files)
.contains(fileName()))
continue;
QSettings settings(
QString("%1/%2").arg(directories().at(i)).arg(fileName()),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setCity(settings.value(QString("X-AW-City"), m_city).toString());
setCountry(settings.value(QString("X-AW-Country"), m_country).toString());
setCountry(
settings.value(QString("X-AW-Country"), m_country).toString());
setTs(settings.value(QString("X-AW-TS"), m_ts).toInt());
// api == 2
setImage(settings.value(QString("X-AW-Image"), QVariant(m_image)).toString() == QString("true"));
setImage(
settings.value(QString("X-AW-Image"), QVariant(m_image)).toString()
== QString("true"));
settings.endGroup();
}
// update for current API
if ((apiVersion() > 0) && (apiVersion() < AWEWAPI)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to" << AWEWAPI;
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to"
<< AWEWAPI;
setApiVersion(AWEWAPI);
writeConfiguration();
}
@ -207,10 +198,9 @@ void ExtWeather::readConfiguration()
void ExtWeather::readJsonMap()
{
qCDebug(LOG_LIB);
QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
QString("awesomewidgets/weather/awesomewidgets-extweather-ids.json"));
QString fileName = QStandardPaths::locate(
QStandardPaths::GenericDataLocation,
QString("awesomewidgets/weather/awesomewidgets-extweather-ids.json"));
qCInfo(LOG_LIB) << "Map file" << fileName;
QFile jsonFile(fileName);
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
@ -234,18 +224,19 @@ void ExtWeather::readJsonMap()
QVariantHash ExtWeather::run()
{
qCDebug(LOG_LIB);
if ((!isActive()) || (isRunning)) return values;
if ((!isActive()) || (isRunning))
return values;
if (times == 1) {
qCInfo(LOG_LIB) << "Send request";
isRunning = true;
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url(m_ts != 0))));
new QReplyTimeout(reply, 1000);
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url())));
new QReplyTimeout(reply, REQUEST_TIMEOUT);
}
// update value
if (times >= interval()) times = 0;
if (times >= interval())
times = 0;
times++;
return values;
@ -255,7 +246,6 @@ QVariantHash ExtWeather::run()
int ExtWeather::showConfiguration(const QVariant args)
{
Q_UNUSED(args)
qCDebug(LOG_LIB);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
@ -264,11 +254,13 @@ int ExtWeather::showConfiguration(const QVariant args)
ui->lineEdit_country->setText(m_country);
ui->spinBox_timestamp->setValue(m_ts);
ui->checkBox_image->setCheckState(m_image ? Qt::Checked : Qt::Unchecked);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked : Qt::Unchecked);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked
: Qt::Unchecked);
ui->spinBox_interval->setValue(interval());
int ret = exec();
if (ret != 1) return ret;
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setNumber(ui->label_numberValue->text().toInt());
@ -287,10 +279,11 @@ int ExtWeather::showConfiguration(const QVariant args)
void ExtWeather::writeConfiguration() const
{
qCDebug(LOG_LIB);
AbstractExtItem::writeConfiguration();
QSettings settings(QString("%1/%2").arg(directories().first()).arg(fileName()), QSettings::IniFormat);
QSettings settings(
QString("%1/%2").arg(directories().first()).arg(fileName()),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
@ -306,69 +299,71 @@ void ExtWeather::writeConfiguration() const
void ExtWeather::weatherReplyReceived(QNetworkReply *reply)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Return code" << reply->error();
qCDebug(LOG_LIB) << "Reply error message" << reply->errorString();
qCDebug(LOG_LIB) << "Return code" << reply->error() << "with message"
<< reply->errorString();
isRunning = false;
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
reply->deleteLater();
if ((reply->error() != QNetworkReply::NoError) ||
(error.error != QJsonParseError::NoError)) {
if ((reply->error() != QNetworkReply::NoError)
|| (error.error != QJsonParseError::NoError)) {
qCWarning(LOG_LIB) << "Parse error" << error.errorString();
return;
}
// convert to map
QVariantMap json = jsonDoc.toVariant().toMap();
if (json[QString("cod")].toInt() != 200) {
qCWarning(LOG_LIB) << "Invalid return code";
QVariantMap json = jsonDoc.toVariant().toMap()[QString("query")].toMap();
if (json[QString("count")].toInt() != 1) {
qCWarning(LOG_LIB) << "Found data count"
<< json[QString("count")].toInt() << "is not 1";
return;
}
QVariantMap results
= json[QString("results")].toMap()[QString("channel")].toMap();
QVariantMap item = results[QString("item")].toMap();
QVariantHash data;
if (m_ts == 0)
data = parseSingleJson(json);
else {
QVariantList list = json[QString("list")].toList();
data = parseSingleJson(list.count() <= m_ts ? list.at(m_ts-1).toMap() : list.last().toMap());
if (m_ts == 0) {
// 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 {
// forecast weather
QVariantList weatherList = item[QString("forecast")].toList();
QVariantMap weatherMap = weatherList.count() < m_ts
? weatherList.last().toMap()
: weatherList.at(m_ts).toMap();
int id = weatherMap[QString("code")].toInt();
values[tag(QString("weatherId"))] = id;
values[tag(QString("weather"))] = weatherFromInt(id);
values[tag(QString("timestamp"))]
= weatherMap[QString("date")].toString();
// yahoo provides high and low temperatures. Lets calculate average one
values[tag(QString("temperature"))]
= (weatherMap[QString("high")].toFloat()
+ weatherMap[QString("low")].toFloat())
/ 2.0;
// ... and no forecast data for humidity and pressure
values[tag(QString("humidity"))] = 0;
values[tag(QString("pressure"))] = 0.0;
}
foreach(QString key, data.keys()) values[tag(key)] = data[key];
}
QVariantHash ExtWeather::parseSingleJson(const QVariantMap json) const
{
qCDebug(LOG_LIB);
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;
}
void ExtWeather::translate()
{
qCDebug(LOG_LIB);
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_number->setText(i18n("Tag"));
@ -381,14 +376,10 @@ void ExtWeather::translate()
}
QString ExtWeather::url(const bool isForecast) const
QString ExtWeather::url() const
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Is forecast" << isForecast;
QString apiUrl = isForecast ? QString(OWM_FORECAST_URL) : QString(OWM_URL);
apiUrl.replace(QString("$CITY"), m_city);
apiUrl.replace(QString("$COUNTRY"), m_country);
QString apiUrl = QString(YAHOO_WEATHER_URL).arg(m_city).arg(m_country);
qCInfo(LOG_LIB) << "API url" << apiUrl;
return apiUrl;

View File

@ -18,17 +18,19 @@
#ifndef EXTWEATHER_H
#define EXTWEATHER_H
#include <QMap>
#include <QNetworkReply>
#include "abstractextitem.h"
#define OWM_URL "http://api.openweathermap.org/data/2.5/weather?q=$CITY,$COUNTRY&units=metric"
#define OWM_FORECAST_URL "http://api.openweathermap.org/data/2.5/forecast?q=$CITY,$COUNTRY&units=metric"
#define YAHOO_WEATHER_URL \
"https://query.yahooapis.com/v1/public/yql?format=json&env=store://" \
"datatables.org/alltableswithkeys&q=select * from weather.forecast where " \
"u='c' and woeid in (select woeid from geo.places(1) where text='%1, %2')"
namespace Ui {
class ExtWeather;
namespace Ui
{
class ExtWeather;
}
class ExtWeather : public AbstractExtItem
@ -40,7 +42,8 @@ class ExtWeather : public AbstractExtItem
Q_PROPERTY(int ts READ ts WRITE setTs)
public:
explicit ExtWeather(QWidget *parent = nullptr, const QString weatherName = QString(),
explicit ExtWeather(QWidget *parent = nullptr,
const QString weatherName = QString(),
const QStringList directories = QStringList());
virtual ~ExtWeather();
ExtWeather *copy(const QString _fileName, const int _number);
@ -71,9 +74,8 @@ private:
QNetworkAccessManager *manager;
bool isRunning = false;
Ui::ExtWeather *ui;
QVariantHash parseSingleJson(const QVariantMap json) const;
void translate();
QString url(const bool isForecast = false) const;
QString url() const;
// properties
QString m_city = QString("London");
QString m_country = QString("uk");

View File

@ -23,139 +23,123 @@
#include <QBuffer>
#include <QColorDialog>
#include <QDir>
#include <QGraphicsEllipseItem>
#include <QFileDialog>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QSettings>
#include "awdebug.h"
#include "graphicalitemhelper.h"
#include "version.h"
GraphicalItem::GraphicalItem(QWidget *parent, const QString desktopName,
const QStringList directories)
: AbstractExtItem(parent, desktopName, directories),
ui(new Ui::GraphicalItem)
: AbstractExtItem(parent, desktopName, directories)
, ui(new Ui::GraphicalItem)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
readConfiguration();
ui->setupUi(this);
translate();
connect(ui->pushButton_activeColor, SIGNAL(clicked()), this, SLOT(changeColor()));
connect(ui->pushButton_inactiveColor, SIGNAL(clicked()), this, SLOT(changeColor()));
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,
SLOT(changeColor()));
connect(ui->pushButton_inactiveColor, SIGNAL(clicked()), this,
SLOT(changeColor()));
connect(ui->pushButton_activeImage, SIGNAL(clicked()), this,
SLOT(changeImage()));
connect(ui->pushButton_inactiveImage, SIGNAL(clicked()), this,
SLOT(changeImage()));
}
GraphicalItem::~GraphicalItem()
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete m_scene;
delete ui;
delete m_helper;
}
GraphicalItem *GraphicalItem::copy(const QString _fileName, const int _number)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "File" << _fileName;
qCDebug(LOG_LIB) << "Number" << _number;
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
GraphicalItem *item = new GraphicalItem(static_cast<QWidget *>(parent()), _fileName, directories());
item->setActive(isActive());
item->setActiveColor(activeColor());
item->setApiVersion(apiVersion());
item->setBar(bar());
item->setComment(comment());
item->setDirection(direction());
item->setHeight(height());
item->setInactiveColor(inactiveColor());
item->setInterval(interval());
item->setName(QString("bar%1").arg(_number));
GraphicalItem *item = new GraphicalItem(static_cast<QWidget *>(parent()),
_fileName, directories());
copyDefaults(item);
item->setActiveColor(m_activeColor);
item->setBar(m_bar);
item->setCount(m_count);
item->setCustom(m_custom);
item->setDirection(m_direction);
item->setHeight(m_height);
item->setInactiveColor(m_inactiveColor);
item->setMaxValue(m_maxValue);
item->setMinValue(m_minValue);
item->setNumber(_number);
item->setType(type());
item->setWidth(width());
item->setType(m_type);
item->setWidth(m_width);
return item;
}
QString GraphicalItem::image(const float value) const
QString GraphicalItem::image(const QVariant &value)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Value" << value;
if (m_bar == QString("none")) return QString("");
QColor active = stringToColor(m_activeColor);
QColor inactive = stringToColor(m_inactiveColor);
float percent = value / 100.0;
int scale[2] = { 1, 1 };
QPen pen = QPen();
QGraphicsScene *scene = new QGraphicsScene();
scene->setBackgroundBrush(QBrush(Qt::NoBrush));
QGraphicsView *view = new QGraphicsView(scene);
view->setStyleSheet(QString("background: transparent"));
view->setContentsMargins(0, 0, 0, 0);
view->setFrameShape(QFrame::NoFrame);
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->resize(m_width + 5.0, m_height + 5.0);
m_scene->clear();
int scale[2] = {1, 1};
float converted
= m_helper->getPercents(value.toFloat(), m_minValue, m_maxValue);
// paint
switch (m_type) {
case Vertical:
pen.setWidth(m_width);
// inactive
pen.setColor(inactive);
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(active);
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);
m_helper->paintVertical(converted);
// scale
scale[1] = -2 * static_cast<int>(m_direction) + 1;
break;
case Circle:
QGraphicsEllipseItem *circle;
pen.setWidth(1.0);
// inactive
pen.setColor(inactive);
circle = 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 = 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);
m_helper->paintCircle(converted);
// scale
scale[0] = -2 * static_cast<int>(m_direction) + 1;
break;
case Graph:
m_helper->paintGraph(converted);
// direction option is not recognized by this GI type
break;
case Horizontal:
default:
pen.setWidth(m_height);
// inactive
pen.setColor(inactive);
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(active);
scene->addLine(-0.5 * m_height, 0.5 * m_height,
percent * m_width - 0.5 * m_height, 0.5 * m_height, pen);
m_helper->paintHorizontal(converted);
// scale
scale[0] = -2 * static_cast<int>(m_direction) + 1;
break;
}
// convert
QPixmap pixmap = view->grab().transformed(QTransform().scale(scale[0], scale[1]));
QPixmap pixmap
= m_view->grab().transformed(QTransform().scale(scale[0], scale[1]));
QByteArray byteArray;
QBuffer buffer(&byteArray);
pixmap.save(&buffer, "PNG");
QString url = QString("<img src=\"data:image/png;base64,%1\"/>").arg(QString(byteArray.toBase64()));
delete view;
delete scene;
QString url = QString("<img src=\"data:image/png;base64,%1\"/>")
.arg(QString(byteArray.toBase64()));
return url;
}
@ -163,48 +147,54 @@ QString GraphicalItem::image(const float value) const
QString GraphicalItem::bar() const
{
qCDebug(LOG_LIB);
return m_bar;
}
QString GraphicalItem::activeColor() const
{
qCDebug(LOG_LIB);
return m_activeColor;
}
QString GraphicalItem::inactiveColor() const
{
qCDebug(LOG_LIB);
return m_inactiveColor;
}
QString GraphicalItem::tag() const
int GraphicalItem::count() const
{
qCDebug(LOG_LIB);
return m_count;
}
return name() + m_bar;
bool GraphicalItem::isCustom() const
{
return m_custom;
}
float GraphicalItem::maxValue() const
{
return m_maxValue;
}
float GraphicalItem::minValue() const
{
return m_minValue;
}
GraphicalItem::Type GraphicalItem::type() const
{
qCDebug(LOG_LIB);
return m_type;
}
QString GraphicalItem::strType() const
{
qCDebug(LOG_LIB);
QString value;
switch (m_type) {
case Vertical:
@ -213,10 +203,14 @@ QString GraphicalItem::strType() const
case Circle:
value = QString("Circle");
break;
case Graph:
value = QString("Graph");
break;
case Horizontal:
default:
value = QString("Horizontal");
break;
}\
}
return value;
}
@ -224,21 +218,18 @@ QString GraphicalItem::strType() const
GraphicalItem::Direction GraphicalItem::direction() const
{
qCDebug(LOG_LIB);
return m_direction;
}
QString GraphicalItem::strDirection() const
{
qCDebug(LOG_LIB);
QString value;
switch (m_direction) {
case RightToLeft:
value = QString("RightToLeft");
break;
case LeftToRight:
default:
value = QString("LeftToRight");
break;
@ -250,62 +241,88 @@ QString GraphicalItem::strDirection() const
int GraphicalItem::height() const
{
qCDebug(LOG_LIB);
return m_height;
}
QStringList GraphicalItem::usedKeys() const
{
return m_usedKeys;
}
int GraphicalItem::width() const
{
qCDebug(LOG_LIB);
return m_width;
}
QString GraphicalItem::uniq() const
{
qCDebug(LOG_LIB);
return m_bar;
}
void GraphicalItem::setBar(const QString _bar)
{
qCDebug(LOG_LIB);
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;
}
void GraphicalItem::setActiveColor(const QString _color)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Color" << _color;
m_activeColor = _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)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Color" << _color;
m_inactiveColor = _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)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Type" << _type;
m_type = _type;
@ -314,13 +331,14 @@ void GraphicalItem::setType(const Type _type)
void GraphicalItem::setStrType(const QString _type)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Type" << _type;
if (_type == QString("Vertical"))
setType(Vertical);
else if (_type == QString("Circle"))
setType(Circle);
else if (_type == QString("Graph"))
setType(Graph);
else
setType(Horizontal);
}
@ -328,7 +346,6 @@ void GraphicalItem::setStrType(const QString _type)
void GraphicalItem::setDirection(const Direction _direction)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Direction" << _direction;
m_direction = _direction;
@ -337,7 +354,6 @@ void GraphicalItem::setDirection(const Direction _direction)
void GraphicalItem::setStrDirection(const QString _direction)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Direction" << _direction;
if (_direction == QString("RightToLeft"))
@ -349,19 +365,28 @@ void GraphicalItem::setStrDirection(const QString _direction)
void GraphicalItem::setHeight(const int _height)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Height" << _height;
if (_height <= 0) return;
if (_height <= 0)
return;
m_height = _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)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Width" << _width;
if (_width <= 0) return;
if (_width <= 0)
return;
m_width = _width;
}
@ -369,55 +394,69 @@ void GraphicalItem::setWidth(const int _width)
void GraphicalItem::readConfiguration()
{
qCDebug(LOG_LIB);
AbstractExtItem::readConfiguration();
for (int i=directories().count()-1; i>=0; i--) {
if (!QDir(directories().at(i)).entryList(QDir::Files).contains(fileName())) continue;
QSettings settings(QString("%1/%2").arg(directories().at(i)).arg(fileName()), QSettings::IniFormat);
for (int i = directories().count() - 1; i >= 0; i--) {
if (!QDir(directories().at(i))
.entryList(QDir::Files)
.contains(fileName()))
continue;
QSettings settings(
QString("%1/%2").arg(directories().at(i)).arg(fileName()),
QSettings::IniFormat);
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());
setActiveColor(settings.value(QString("X-AW-ActiveColor"), m_activeColor).toString());
setInactiveColor(settings.value(QString("X-AW-InactiveColor"), m_inactiveColor).toString());
setMaxValue(settings.value(QString("X-AW-Max"), m_maxValue).toFloat());
setMinValue(settings.value(QString("X-AW-Min"), m_minValue).toFloat());
setActiveColor(
settings.value(QString("X-AW-ActiveColor"), m_activeColor)
.toString());
setInactiveColor(
settings.value(QString("X-AW-InactiveColor"), m_inactiveColor)
.toString());
setStrType(settings.value(QString("X-AW-Type"), strType()).toString());
setStrDirection(settings.value(QString("X-AW-Direction"), strDirection()).toString());
setStrDirection(
settings.value(QString("X-AW-Direction"), strDirection())
.toString());
setHeight(settings.value(QString("X-AW-Height"), m_height).toInt());
setWidth(settings.value(QString("X-AW-Width"), m_width).toInt());
// api == 2
if (apiVersion() < 2) setNumber(bar().remove(QString("bar")).toInt());
if (apiVersion() < 2)
setNumber(bar().remove(QString("bar")).toInt());
settings.endGroup();
}
// update for current API
if ((apiVersion() > 0) && (apiVersion() < AWGIAPI)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to" << AWGIAPI;
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to"
<< AWGIAPI;
setApiVersion(AWGIAPI);
writeConfiguration();
}
}
QVariantHash GraphicalItem::run()
{
qCDebug(LOG_LIB);
// required by abstract class
return QVariantHash();
}
int GraphicalItem::showConfiguration(const QVariant args)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Combobox arguments" << args;
QStringList tags = args.toStringList();
ui->label_nameValue->setText(name());
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->checkBox_custom->setChecked(m_custom);
ui->comboBox_value->addItems(tags);
ui->comboBox_value->addItem(m_bar);
ui->comboBox_value->setCurrentIndex(ui->comboBox_value->count() - 1);
if (m_custom) {
ui->lineEdit_customValue->setText(m_bar);
} else {
ui->comboBox_value->addItem(m_bar);
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_inactiveColor->setText(m_inactiveColor);
ui->comboBox_type->setCurrentIndex(static_cast<int>(m_type));
@ -425,13 +464,22 @@ int GraphicalItem::showConfiguration(const QVariant args)
ui->spinBox_height->setValue(m_height);
ui->spinBox_width->setValue(m_width);
int ret = exec();
if (ret != 1) return ret;
// update UI
changeCountState(ui->comboBox_type->currentIndex());
changeValue(ui->checkBox_custom->checkState());
setName(ui->label_nameValue->text());
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
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('&')));
setInactiveColor(ui->pushButton_inactiveColor->text().remove(QChar('&')));
setStrType(ui->comboBox_type->currentText());
@ -446,14 +494,19 @@ int GraphicalItem::showConfiguration(const QVariant args)
void GraphicalItem::writeConfiguration() const
{
qCDebug(LOG_LIB);
AbstractExtItem::writeConfiguration();
QSettings settings(QString("%1/%2").arg(directories().first()).arg(fileName()), QSettings::IniFormat);
QSettings settings(
QString("%1/%2").arg(directories().first()).arg(fileName()),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
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-InactiveColor"), m_inactiveColor);
settings.setValue(QString("X-AW-Type"), strType());
@ -468,12 +521,12 @@ void GraphicalItem::writeConfiguration() const
void GraphicalItem::changeColor()
{
qCDebug(LOG_LIB);
QColor color = stringToColor((static_cast<QPushButton *>(sender()))->text());
QColor color = m_helper->stringToColor(
(static_cast<QPushButton *>(sender()))->text());
QColor newColor = QColorDialog::getColor(color, this, tr("Select color"),
QColorDialog::ShowAlphaChannel);
if (!newColor.isValid()) return;
if (!newColor.isValid())
return;
qCInfo(LOG_LIB) << "Selected color" << newColor;
QStringList colorText;
@ -482,37 +535,96 @@ void GraphicalItem::changeColor()
colorText.append(QString("%1").arg(newColor.blue()));
colorText.append(QString("%1").arg(newColor.alpha()));
return static_cast<QPushButton *>(sender())->setText(colorText.join(QChar(',')));
return static_cast<QPushButton *>(sender())
->setText(colorText.join(QChar(',')));
}
QColor GraphicalItem::stringToColor(const QString _color) const
void GraphicalItem::changeColorState(const int state)
{
qCDebug(LOG_LIB);
qCDebug(LOG_LIB) << "Color" << _color;
qCDebug(LOG_LIB) << "Current color state is" << state;
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());
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);
}
}
return qcolor;
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()
{
// init scene
m_scene = new QGraphicsScene();
m_scene->setBackgroundBrush(QBrush(Qt::NoBrush));
// init view
m_view = new QGraphicsView(m_scene);
m_view->setStyleSheet(QString("background: transparent"));
m_view->setContentsMargins(0, 0, 0, 0);
m_view->setFrameShape(QFrame::NoFrame);
m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->resize(m_width + 5, m_height + 5);
// init helper
m_helper = new GraphicalItemHelper(this, m_scene);
m_helper->setParameters(m_activeColor, m_inactiveColor, m_width, m_height,
m_count);
}
void GraphicalItem::translate()
{
qCDebug(LOG_LIB);
ui->label_name->setText(i18n("Name"));
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_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_activeImage->setText(i18n("Active image"));
ui->checkBox_inactiveCheck->setText(i18n("Use image for inactive"));
ui->label_inactiveColor->setText(i18n("Inactive color"));
ui->label_inactiveImage->setText(i18n("Inactive image"));
ui->label_type->setText(i18n("Type"));
ui->label_direction->setText(i18n("Direction"));
ui->label_height->setText(i18n("Height"));

View File

@ -23,8 +23,13 @@
#include "abstractextitem.h"
namespace Ui {
class GraphicalItem;
class GraphicalItemHelper;
class QGraphicsScene;
class QGraphicsView;
namespace Ui
{
class GraphicalItem;
}
class GraphicalItem : public AbstractExtItem
@ -32,73 +37,91 @@ class GraphicalItem : public AbstractExtItem
Q_OBJECT
Q_PROPERTY(QString bar READ bar WRITE setBar)
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(Type type READ type WRITE setType)
Q_PROPERTY(Direction direction READ direction WRITE setDirection)
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)
public:
enum Direction {
LeftToRight = 0,
RightToLeft
};
enum Type {
Horizontal = 0,
Vertical,
Circle
};
enum Direction { LeftToRight = 0, RightToLeft };
enum Type { Horizontal = 0, Vertical, Circle, Graph };
explicit GraphicalItem(QWidget *parent = nullptr, const QString desktopName = QString(),
explicit GraphicalItem(QWidget *parent = nullptr,
const QString desktopName = QString(),
const QStringList directories = QStringList());
virtual ~GraphicalItem();
GraphicalItem *copy(const QString _fileName, const int _number);
QString image(const float value) const;
QString image(const QVariant &value);
// get methods
QString bar() const;
QString activeColor() const;
QString inactiveColor() const;
QString tag() const;
int count() const;
bool isCustom() const;
float minValue() const;
float maxValue() const;
Type type() const;
QString strType() const;
Direction direction() const;
QString strDirection() const;
int height() const;
QStringList usedKeys() const;
int width() const;
QString uniq() const;
// set methods
void setBar(const QString _bar = QString("cpu"));
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 setMinValue(const float _value = 0.0);
void setMaxValue(const float _value = 100.0);
void setType(const Type _type = Horizontal);
void setStrType(const QString _type = QString("Horizontal"));
void setDirection(const Direction _direction = LeftToRight);
void setStrDirection(const QString _direction = QString("LeftToRight"));
void setHeight(const int _height = 100);
void setUsedKeys(const QStringList _usedKeys = QStringList());
void setWidth(const int _width = 100);
public slots:
void readConfiguration();
QVariantHash run();
QVariantHash run() { return QVariantHash(); };
int showConfiguration(const QVariant args = QVariant());
void writeConfiguration() const;
private slots:
void changeColor();
void changeColorState(const int state);
void changeCountState(const int state);
void changeImage();
void changeValue(const int state);
private:
QString m_fileName;
QStringList m_dirs;
GraphicalItemHelper *m_helper = nullptr;
QGraphicsScene *m_scene = nullptr;
QGraphicsView *m_view = nullptr;
Ui::GraphicalItem *ui;
QColor stringToColor(const QString _color) const;
void initScene();
void translate();
// properties
QString m_bar = QString("cpu");
QString m_activeColor = QString("0,0,0,130");
QString m_inactiveColor = QString("255,255,255,130");
int m_count = 100;
bool m_custom = false;
QString m_activeColor;
QString m_inactiveColor;
float m_minValue = 0.0f;
float m_maxValue = 100.0f;
Type m_type = Horizontal;
Direction m_direction = LeftToRight;
int m_height = 100;
QStringList m_usedKeys;
int m_width = 100;
};

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>416</width>
<height>325</height>
<height>606</height>
</rect>
</property>
<property name="windowTitle">
@ -18,8 +18,14 @@
<layout class="QHBoxLayout" name="layout_name">
<item>
<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">
<string>Name</string>
<string>&amp;Name</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -27,11 +33,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_nameValue">
<property name="text">
<string/>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_name"/>
</item>
</layout>
</item>
@ -46,7 +48,7 @@
</sizepolicy>
</property>
<property name="text">
<string>Comment</string>
<string>&amp;Comment</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -59,32 +61,120 @@
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_value">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layout_custom">
<item>
<widget class="QLabel" name="label_value">
<property name="text">
<string>Value</string>
<spacer name="spacer_custom">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</widget>
</spacer>
</item>
<item>
<widget class="QComboBox" name="comboBox_value">
<property name="editable">
<bool>false</bool>
<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>
<layout class="QHBoxLayout" name="layout_activeColor">
<widget class="QWidget" name="widget_value" native="true">
<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>
<widget class="QLabel" name="label_value">
<property name="text">
<string>&amp;Value</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_value">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</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_activeColor">
<widget class="QLabel" name="label_max">
<property name="text">
<string>Active color</string>
<string>&amp;Max value</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -92,20 +182,20 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_activeColor">
<property name="text">
<string notr="true"/>
<widget class="QDoubleSpinBox" name="doubleSpinBox_max">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_inactiveColor">
<layout class="QHBoxLayout" name="layout_min">
<item>
<widget class="QLabel" name="label_inactiveColor">
<widget class="QLabel" name="label_min">
<property name="text">
<string>Inactive color</string>
<string>Min val&amp;ue</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -113,20 +203,265 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_inactiveColor">
<property name="text">
<string notr="true"/>
<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">
<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_activeColor">
<property name="text">
<string>Activ&amp;e color</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_activeColor">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
</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">
<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_inactiveColor">
<property name="text">
<string>&amp;Inactive color</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_inactiveColor">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</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>
<layout class="QHBoxLayout" name="layout_type">
<item>
<widget class="QLabel" name="label_type">
<property name="text">
<string>Type</string>
<string>&amp;Type</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -150,6 +485,11 @@
<string notr="true">Circle</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Graph</string>
</property>
</item>
</widget>
</item>
</layout>
@ -159,7 +499,7 @@
<item>
<widget class="QLabel" name="label_direction">
<property name="text">
<string>Direction</string>
<string>&amp;Direction</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -187,7 +527,7 @@
<item>
<widget class="QLabel" name="label_height">
<property name="text">
<string>Height</string>
<string>&amp;Height</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -211,7 +551,7 @@
<item>
<widget class="QLabel" name="label_width">
<property name="text">
<string>Width</string>
<string>&amp;Width</string>
</property>
<property name="alignment">
<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 */

View File

@ -4,6 +4,6 @@ Name=AAPL.NASDAQ
Comment=Apple Inc
X-AW-Ticker="AAPL"
X-AW-Active=false
X-AW-ApiVersion=2
X-AW-ApiVersion=3
X-AW-Interval=60
X-AW-Number=0

View File

@ -4,6 +4,6 @@ Name=EUR/RUB
Comment=EUR/RUB
X-AW-Ticker="EURRUB=X"
X-AW-Active=false
X-AW-ApiVersion=2
X-AW-ApiVersion=3
X-AW-Interval=60
X-AW-Number=1

View File

@ -4,6 +4,6 @@ Name=EUR/USD
Comment=EUR/USD
X-AW-Ticker="EURUSD=X"
X-AW-Active=false
X-AW-ApiVersion=2
X-AW-ApiVersion=3
X-AW-Interval=60
X-AW-Number=2

View File

@ -4,6 +4,6 @@ Name=GOOG.NASDAQ
Comment=Google Inc
X-AW-Ticker="GOOG"
X-AW-Active=false
X-AW-ApiVersion=2
X-AW-ApiVersion=3
X-AW-Interval=60
X-AW-Number=3

View File

@ -4,6 +4,6 @@ Name=MSFT.NASDAQ
Comment=Microsoft Corp
X-AW-Ticker="MSFT"
X-AW-Active=false
X-AW-ApiVersion=2
X-AW-ApiVersion=3
X-AW-Interval=60
X-AW-Number=4

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