Compare commits

...

461 Commits

Author SHA1 Message Date
88f70c0ea6 Release 3.5.0 2023-05-18 02:57:31 +03:00
338828da88 add release pipeline 2023-05-18 01:41:48 +03:00
09a3c32d0c fix some found warning 2023-05-17 21:37:00 +03:00
e9beea2d7a create workflow run 2023-05-17 18:23:58 +03:00
1e69aa93f5 add support of hidden flag 2023-05-17 14:11:58 +03:00
73f1617cbf Merge pull request #156 from arcan1s/feature/wayland-support
wayland support
2023-05-17 03:48:20 +03:00
dea9d488df wayland support 2023-05-17 03:42:40 +03:00
84de9755b5 fix (some) KF deprecation warnings 2023-03-30 03:31:57 +03:00
ff40ac96d8 update dependencies list 2021-07-07 22:09:44 +03:00
de9d90df4a Release 3.4.3
compilation fixes for old ubuntu and provide patch for old qt versions
2021-01-08 15:48:20 +03:00
883659272d add patch for qt < 5.14 2021-01-08 11:17:11 +03:00
0c443e9278 do not use nodiscard for slots (#147) 2021-01-08 10:52:57 +03:00
6ec30b71d1 Release 3.4.2
changelog updated
2021-01-07 06:55:03 +03:00
4ed19a38d9 release 3.4.1
update translators list
2020-11-07 17:10:04 +03:00
e592de9555 release 3.4.0 2020-11-07 17:05:13 +03:00
1e0316c4de fix warnings 2020-11-07 16:45:36 +03:00
91abbdcd96 clang-tidy warning fixes 2020-11-03 04:23:01 +03:00
e81d765098 update to new process api 2020-11-01 14:33:17 +03:00
8eaf444a25 fix dockerfile again 2020-11-01 01:16:10 +03:00
183e7d8a20 correct image spelling 2020-11-01 00:43:00 +03:00
a4a1ae064f newest qt fixes 2020-11-01 00:38:59 +03:00
3e81cd16bb update for docker 2020-10-31 22:02:42 +03:00
55319521b2 replace all nbsp in previews (#142) 2020-04-18 16:52:02 +03:00
e525cb4742 do not replace space to nbsp in some cases (#143) 2020-04-18 03:06:06 +03:00
0f19bce80d close process in destructor 2019-12-15 11:31:49 +03:00
e0df575aa9 hanle new sources 2019-12-15 11:23:18 +03:00
276248a748 system source, some code improvements 2019-12-14 23:54:15 +03:00
c05a87a540 add notes about dependencies 2019-12-07 11:47:45 +03:00
9f46a17b98 Add italian translation (#136) 2018-10-26 03:33:46 +03:00
c2a18f8845 add git build instruction 2018-09-17 16:43:01 +03:00
308b721c87 some docker changes (3) 2017-12-17 21:39:03 +03:00
c4c37406a5 some docker changes (2) 2017-12-17 21:32:21 +03:00
ffb66586d3 some docker changes 2017-12-17 21:27:00 +03:00
935fa04757 some travis debug 2017-12-17 21:20:55 +03:00
fee70b7385 fix typo 2017-12-17 21:13:12 +03:00
ed21e3fb18 lang: generic 2017-12-17 19:29:28 +03:00
5807d4d75e use language? 2017-12-17 18:08:17 +03:00
5bd95fe41a simplify docker 2017-12-17 18:01:56 +03:00
13edbc5eb1 docker iteration v10 2017-12-17 17:53:37 +03:00
3b41239672 fix hddevices test 2017-12-17 16:57:58 +03:00
b30bd35add remove hdddevices test 2017-12-17 16:44:43 +03:00
4bba061d66 fix lambda related code 2017-12-17 06:24:41 +03:00
ce30d90a23 fix hddtemp tests 2017-12-17 05:07:50 +03:00
423eabd857 fix battery tests 2017-12-17 04:29:23 +03:00
e5a9e99438 Replace yahoo finance to stooq (#131)
Old code is dropped to separated provider
2017-12-15 02:01:34 +03:00
eb911551eb Merge pull request #132 from ibnuda/indonesian-translation
Finished ID translation.
2017-12-03 06:31:55 +03:00
5886dcc50b Finished ID translation. 2017-12-02 01:21:36 +07:00
2d7d4c55a2 use MSD for battery calculations, fix segfault 2017-08-25 06:11:18 +03:00
ea5d73d8fd add more battery retalted keys 2017-08-24 01:20:27 +03:00
081f7a3c88 release 3.3.3 2017-08-03 01:47:10 +03:00
707fa727c5 split awkeysaggregator class 2017-07-28 04:57:07 +03:00
5d0c05e856 make tests great again (iteration #2) 2017-07-27 17:20:59 +03:00
4625afa0b9 add docker files, improve dbus interface 2017-07-27 16:47:20 +03:00
5c56f813d2 make tests great again!
Also dbus adaptor has been renamed, because it does not allow to
register one service for several applications (like plasmashell and
    plasmawindowed)
2017-07-26 20:23:26 +03:00
5e08434835 fix issue with invalid (up|down)total($|kb) calculation (see #127)
also renamed *total* tags to *tot* for consistency with other tags:

  * uptotal.* -> uptot.*
  * downtotal.* -> downtot.*
  * pstotal -> pstot
2017-07-24 15:07:36 +03:00
d2e6f2fe38 some refactoring
* massive changes inside includes, drop unused definitions
* rewrite some initialization methods to avoid additional
freeing/allocation
* drop some explicit destructors calls
2017-07-14 03:34:05 +03:00
e90e1da096 Small fixes
* update translations, add target to update translations
* add custom keys support to config helper
2017-07-13 19:15:10 +03:00
9d0a1bd70c rewrite formtatter* and customkeys* to share their code 2017-07-12 03:28:03 +03:00
7ce3e8b1cf add custom keys configuration 2017-07-10 01:43:21 +03:00
7a00dce7c5 initial implementation of custom keys 2017-07-07 00:52:16 +03:00
1a7530a847 commit metadata files too 2017-06-02 17:46:37 +03:00
1702045550 update changelog 2017-06-02 17:38:27 +03:00
fe88c72498 release 3.3.2 2017-06-02 17:35:35 +03:00
737759d03f Bug fixing
* fix bug with invalid applet and configuration load with newest qt
* fix bug with invalid DP configuration
* fix bug with invalid HTML tags operations
2017-06-02 17:34:27 +03:00
934e30819c rename deadbeef defaults 2017-05-21 23:07:12 +03:00
a4d3a09f26 add patch for mpris 2017-05-17 17:47:34 +03:00
acc4df92bc fix invalid mpris parser
In some cases it causes the error like:

Error message "Интерфейс «(null)» для пути /org/mpris/MediaPlayer2 объекта не найден"

(for example deadbeef was affected). Suggested patch should fix this
issue and seems to be working with at least deadbeef and qmmp mpris
engines.
2017-05-17 17:43:18 +03:00
0a723aef82 release 3.3.1
* bump api versions
* update changelog
2017-05-15 20:15:05 +03:00
271b8d55cf release 3.3.0 2017-05-15 17:06:03 +03:00
1afc33abef qml UI fixes 2017-05-15 17:05:22 +03:00
6b8244f3c4 fix comparison 2017-05-10 15:26:25 +03:00
ff2032cca1 update patches
Since now Qt5.4 version support is officially dropped. It means that
widgets now require

ubuntu>=16.04
debian>8
opensuse>=42.1
2017-05-10 15:01:01 +03:00
05aafc43e7 translation update 2017-05-05 18:20:50 +03:00
d0c96ce829 massive refactoring 2017-05-05 17:55:52 +03:00
6e62ceaac7 massive changes inside
* use pass by ref instead of by value if possible
* use reference in interation over collections
* fix no tag inserting
2017-05-04 15:00:50 +03:00
6e99e262d4 add configuration for cron 2017-05-03 00:27:09 +03:00
1b4d1d6944 implement qcronscheduler, tests update 2017-04-28 01:47:42 +03:00
8be4cc6e82 Add tests and UI fields for #118 2017-04-20 00:21:34 +03:00
99c750fd0b fix build again 2017-04-20 03:31:00 +03:00
fca8019972 fix ci build (3) 2017-03-08 16:56:20 +03:00
8d3dd0ed96 one more fix for travis, drop build directory from search 2017-03-08 06:55:00 +03:00
4974948151 add new deps to travis -_- 2017-03-08 06:44:02 +03:00
9e50ade6a5 add cppchec and clangformat to travis build 2017-03-08 06:33:55 +03:00
801eea9a8b add flag to cmake build 2017-03-08 06:22:58 +03:00
1841fb5ed2 extquotes test improvement 2017-02-15 00:43:21 +03:00
9c8dbdcb41 fix kwin definition again 2017-02-14 05:11:00 +03:00
53afc07457 tests cleanup 2017-02-14 04:47:24 +03:00
1caecb427b fix test library building 2017-02-14 04:35:24 +03:00
ea10d526d5 fix test library building 2017-02-14 04:32:17 +03:00
b818586a23 another iteration with fix travis tests 2017-02-14 04:26:59 +03:00
a30e6ba21b fix stupid errors (2) 2017-02-14 04:01:33 +03:00
fe38d9133b fix stupid errors 2017-02-14 03:53:33 +03:00
38c5589c10 one more iteration to try to fix tests on travis 2017-02-14 03:48:11 +03:00
ce09ab753b add temporary || true to tests to get output 2017-02-13 21:12:36 +03:00
10f556e41b Try to fix test for automatic run with travis
* Additionally calculate valid pressure
2017-02-13 21:04:03 +03:00
d097e154ff try to use virtual fb x-server to run tests 2017-02-12 20:58:14 +03:00
8979ddf52b add submodule init 2017-02-12 20:26:09 +03:00
d3dd9b3390 add python to makedeps array 2017-02-12 20:22:31 +03:00
5615fd3ff9 more correct using of arch script (2) 2017-02-12 20:19:51 +03:00
cbb8415a95 more correct using of arch script 2017-02-12 20:16:03 +03:00
8dcdae9611 another iteration with travis ci 2017-02-12 20:11:11 +03:00
bfdaadfc8b add socket activation for extensions (#118)
Option `X-AW-Socket` is used. Any message received by this socket will
trigger extension update. If the option is set, `X-AW-Interval` will be
ignored
2017-02-06 12:16:16 +03:00
9543122816 cosmetic changes caused by site moving 2017-02-02 23:12:19 +03:00
6a24fc3f63 more pretty about text
Use generic text generation for all plasmoids
2016-11-06 22:12:03 +03:00
73d1b0a69f bump formatter api version 2016-11-05 00:01:50 +03:00
06f4882a2d add network request source 2016-11-04 01:12:25 +03:00
7565ea2e82 add test case for jsonformatter
Change array indexes from "[num]" to ".num." in path
2016-11-03 00:23:10 +03:00
004a97800c add json formatter 2016-11-02 23:23:30 +03:00
8dfb6b609f better tooltip class 2016-11-01 00:02:13 +03:00
f893b34e19 run clangformat 2016-10-31 08:12:15 +03:00
a189e1af38 use default widget configuration to configure telemetry 2016-10-30 09:04:08 +03:00
0332c59daf add copyright string 2016-10-29 12:21:13 +03:00
26b375254a add telemetry configuration 2016-10-28 23:21:37 +03:00
89cb4b74fd add background color to textarea 2016-10-27 00:00:18 +03:00
ea1d5fca86 drop C-like fabs function 2016-10-26 01:02:17 +03:00
c3c46ff1b1 improve tag completion
allow to select item from tooltip by mouse and insert it to text edtior
2016-10-25 10:23:05 +03:00
87406f70c4 add initial support of tag suggestion 2016-10-24 08:12:14 +03:00
d520f55afc add test for dbus connection 2016-10-23 01:32:07 +03:00
77a94aa0c1 add methods to dbus interface 2016-10-22 00:43:16 +03:00
c103986f37 add dbus session prototype 2016-10-21 08:10:29 +03:00
7568ae2a3b move textarea to own class as well 2016-10-20 09:23:18 +03:00
2ea5824fd7 add test case for new method 2016-10-19 00:01:09 +03:00
47439ef151 update desktop panel configuration to new one 2016-10-18 00:12:25 +03:00
63d19f038c move info label to own class, move dialog to own class as well 2016-10-17 23:12:03 +03:00
9d5864aa62 move extensions to own bar 2016-10-16 12:23:23 +03:00
d74cd645fd qml improvements
* move functions to plugin part
* move model to general.qml
2016-10-15 00:01:10 +03:00
80767c9dbf update qmldir to new ui element 2016-10-14 01:10:10 +03:00
57ad8a0a2b add tag selector row 2016-10-13 00:12:46 +03:00
eea636c6f1 add html bar 2016-10-12 10:23:20 +03:00
65141ff528 add comment lines to qmldir.in file 2016-10-11 00:00:07 +03:00
f882756fad update desktoppanel qml part 2016-10-10 20:43:07 +03:00
335fbb137e move general singleton to shared part, update part of desktop-panel ui 2016-10-09 21:23:27 +03:00
fcb698e7fc use shared About tab 2016-10-08 00:54:29 +03:00
f1b5208bb2 use shared qml files 2016-10-07 22:13:41 +03:00
c9f5be6a60 use model list defined in general.qml for font configuration 2016-10-03 23:54:07 +03:00
f7094ca187 add font dialog, some color dialog improvements 2016-10-02 01:43:12 +03:00
a326ebdabf replace buttons in dataengine page 2016-10-01 12:42:05 +03:00
3ee1d4c30e Add import and export dialogs 2016-09-30 10:22:10 +03:00
31c129163b Create dialogs for button and color button 2016-09-29 10:24:03 +03:00
80c994bce0 massive qml controls replacement (#114) 2016-09-28 13:50:57 +03:00
8aa6d0c626 change opensuse url 2016-09-27 12:17:13 +03:00
33623fe75e use own control for checkbox 2016-09-25 12:41:22 +03:00
ecf4be8d9c Add support of text styling for desktop panel 2016-09-24 15:24:24 +03:00
7f6a2d8100 Add ability to change text style inside general widget (see #112) 2016-09-23 01:12:34 +03:00
086870e9c2 drop custom keys engine
With current implementation it has no sense to add this support. It
requies some architectures changes inside.
2016-09-22 02:34:20 +03:00
1c52cf72be initial import of custom keys support (#101)
It will use the configuration file `$AWHOME/custom.ini`, group `[Custom]`. One
custom key per string, key is custom key, value is any of available
standard data.

Formatters will be defined by using standard way.
2016-09-21 01:02:21 +03:00
8e598bbd13 allow editable selectors 2016-09-20 02:42:10 +03:00
877f58784b small refactoring
* change `writeFormatters` method to more intuitive
`removeUnusedFormatters`
* use class property as filename
2016-09-19 23:49:11 +03:00
ee6cf60aa4 change constants from #define to const var val
Update contributing.md accordingly
2016-09-18 00:59:23 +03:00
6449465be2 add test for telemetryhandler class 2016-09-17 23:19:06 +03:00
3403d1de50 add local history suggestion to configuration window 2016-09-16 16:03:11 +03:00
f9ddf690c7 drop semicolon from qml files, update CONTRIBUTING guide accordingly 2016-09-15 07:26:00 +03:00
87652eb774 add ability to upload telemetry to a server 2016-09-14 11:32:40 +03:00
a9924a1432 fix conditional error 2016-09-08 19:36:26 +03:00
c5cb5cb359 initial import of telemetry handler 2016-09-07 10:23:05 +03:00
65c8f552de run clangformat 2016-09-05 17:04:16 +03:00
486267256c Add patch for bug reporting 2016-09-01 15:56:56 +03:00
94e87ee570 Add legacy message 2016-08-31 20:49:31 +03:00
b17aeb88e3 drop some legacy code 2016-08-29 15:02:34 +03:00
7d8036b0e1 update russian translation 2016-08-28 16:34:13 +03:00
4d1c05d737 translation update 2016-08-27 02:54:59 +03:00
95ede170d9 use more obvious way to sort keys
Some bugs in past were related to invalid keys sorting. Automatic keys
sorting should prevent such bugs in the future
2016-08-26 23:01:16 +03:00
80d926290c finally implement bug reporting (#104) 2016-08-25 13:33:08 +03:00
5b9984d950 add frontend for bug reporting (#104) 2016-08-23 12:30:11 +03:00
e5b1102abf some changes inside bug reportin backend 2016-08-22 19:10:37 +03:00
f3f9239984 more correct error checking 2016-08-21 19:24:16 +03:00
18c993c0d5 add github issue reporing backend (#104) 2016-08-20 12:14:22 +03:00
a9e3e3f087 Possible one more performance increasing
Lets try to use own QueuedConnection type instead of default
AutoConnection. To implement it we need to disconnect all default slots
and reconnect them with specified connection type
2016-08-18 20:16:05 +03:00
8f6d9e7ab5 release 3.2.1 2016-08-11 15:05:53 +03:00
22dcebe647 update uk translation 2016-08-10 14:08:48 +03:00
6e087f418f update es translation 2016-08-07 03:19:02 +03:00
b76cbb8ce3 update nl translation
fix invalid string in DateTime formatter
2016-08-04 14:29:39 +03:00
24ad32b6ca fix missing Api version for formatters 2016-08-02 20:50:16 +03:00
51b7d3aa09 fix invalid float formatter saving
fix library formatters too
2016-08-01 19:46:28 +03:00
3674fba669 bump forgotten cmakelists 2016-07-31 13:49:11 +03:00
f1116d1f83 add some default formatters 2016-07-30 17:41:33 +03:00
bcf757477b use constat string to request mpd data 2016-07-29 13:50:03 +03:00
1864dc71d5 use sockets from MPD instead of running curl 2016-07-28 15:34:52 +03:00
90c33ab24d use m_ prefix for all internal variables, update CONTRIBUTING.md
accordingly
2016-07-27 20:40:17 +03:00
052d8a034c add formatters reinit (fix #102) 2016-07-26 15:11:52 +03:00
064cd7e44f add ability do not translate strings in DateTime formatter
option X-AW-Translate, ApiVer 2
2016-07-23 19:49:34 +03:00
9e59b22c32 add formatters to configuration functions 2016-07-21 12:20:55 +03:00
89f6661fa5 update Dutch translation 2016-07-16 22:23:20 +03:00
7836fbf77f add macro to combobox 2016-07-14 13:23:49 +03:00
d90d9e2c6f bump desktop versions in the repo 2016-07-12 12:25:29 +03:00
927e93b7fc Release 3.2.0 patches update 2016-07-10 00:09:08 +03:00
fbf89f61b4 Release 3.2.0 2016-07-09 17:01:56 +03:00
4adf457ada translation update 2016-07-08 13:51:29 +03:00
0d4211b2c4 add string formatter 2016-07-07 13:36:30 +03:00
085eec7a3d some fixes inside extensions
* do not use private variables if there are special methods
* change macro call from `aw_*` to `aw_macro_*`
* add forgotten configuration reading/writting for list formatter
2016-07-06 14:23:01 +03:00
baf5085506 prerelease translation update 2016-07-04 16:24:12 +03:00
17a0c61b4a add list formatter 2016-07-03 04:10:04 +03:00
3497922928 function improvements
* use $ for args inside macros
* allow to use screened brackets inside functions
2016-07-02 04:07:43 +03:00
2f88c7ae60 add macros support
Macros should be declared as `aw_macro<name,arg1,arg2,...>{{macro body}}` and then
they may be used as `aw_name<arg1,arg2,...>{{}}`. It just puts `macro
body` to pattern and replaces arguments to provided ones according to
macro call. E.g.:
```
$aw_macro<test,phrase>{{phrase}}$aw_test<hello world>{{}}
```
will transform into
```
hello world
```
2016-07-01 02:21:48 +03:00
8e8ac2f3c7 some refactoring
* fix undefinded behaviour
* drop dbus timout, use generic timeout insead
* drop load source to own cmake key
* update contributing.md
2016-06-30 01:59:06 +03:00
5cd5272f10 add tests for awkeys 2016-06-28 11:19:33 +03:00
bee8e2f180 add more tests for confighelper 2016-06-27 16:58:45 +03:00
bf16e72e1e add configuration tests 2016-06-26 01:52:15 +03:00
faf259e339 add tests for pattern functions some simplifications 2016-06-25 03:11:21 +03:00
f6a6704fd2 add test for awupdatehelper and template for awkeycache 2016-06-23 10:56:55 +03:00
4a0da3f978 add dpplugin tests 2016-06-22 01:04:57 +03:00
71ae832bcd add last sources test for playersource 2016-06-18 05:08:14 +03:00
0f1763cb81 add one more workaround for possible freezes (#96)
First of all it seems that freezes were caused by stuck dbus calls. I've
enabled dbus call timeout (build-configured, default to 3000 msec). And
moreover I've added one more thread lock for dbus calls.
2016-06-17 15:19:00 +03:00
b20a96d32f add fix for possible race condition (#96) 2016-06-16 15:17:58 +03:00
75d101cc8b add tests for dekstop, network and processes sources 2016-06-15 15:10:41 +03:00
5d9d551afe some fixes inside sources 2016-06-13 05:15:08 +03:00
78b7a87c29 add tests for battery and gpuload sources
+ some tests refactoring
2016-06-09 12:45:21 +03:00
bc2071a493 add gputemperature tests 2016-06-08 12:33:55 +03:00
5a0541d06d Add test for hddsource, move sources to own library 2016-06-07 14:16:48 +03:00
18789f78b3 add small test for aggregators 2016-06-05 03:57:08 +03:00
ab01c9fa08 Some test improvements 2016-06-03 01:37:23 +03:00
620c4bd1e3 Return to owm weather provider
Since yahoo support already exists, so I've added new option
X-AW-Provider (apiver 3). Added tests for these cases
2016-06-02 11:09:02 +03:00
4337379177 add tests for abstract formatter 2016-06-01 10:55:51 +03:00
69c09d9ff8 more tests for formatters 2016-05-30 01:47:06 +03:00
cae9e0d2e3 add test library for random values generation 2016-05-29 03:33:41 +03:00
7b154af1b3 add test cases for float and no formatters 2016-05-29 02:45:57 +03:00
fd3ed61191 add test for abstractextitem 2016-05-28 00:30:02 +03:00
2a257de1e6 add tests for extweather 2016-05-27 15:53:12 +03:00
6f09737f0f add test for extquotes
* change url generation in extquotes
* fix bug with missing derivate values
2016-05-26 16:10:23 +03:00
b73fb19409 add tests for extupgrade 2016-05-25 12:35:34 +03:00
c57a92b687 more consistent tests for extscripts
(fix missed filters copying found by tests btw)
2016-05-24 11:53:00 +03:00
72f0d4587b more correct test class for extscripts 2016-05-23 11:04:12 +03:00
ea7c15d865 initial commit with test modules 2016-05-22 15:14:56 +03:00
2dccc92933 fix error in extscript and extupgrade with invalid updates interval if X-AW-Interval=1 2016-05-21 14:36:24 +03:00
e71da9bdfb use overloaded constructors to create tests 2016-05-19 16:28:19 +03:00
f717c984b7 add formatters configuration to ui 2016-05-18 12:46:50 +03:00
906ad56c46 Rename some properties in GI.
Actually properties height and width are QDialog ones, just rename them
to ones with `item` prefix. No configuration keys were changed.

Update translations as well.
2016-05-17 14:22:12 +03:00
301a908aed add formatter configuration to ui 2016-05-15 01:18:18 +03:00
6bd7788aa9 More consistent formatters 2016-05-14 04:08:22 +03:00
51c7299ad0 changes in Extensions ABI
* rewrite aggregator to normal qt ui
* use X-AW prefix for formatters options
* fix logging
* use nullptr in headers
2016-05-13 13:23:25 +03:00
326c65528d rewrite formatters to ext classes 2016-05-12 20:51:21 +03:00
14aab3b758 rewrite extensions to new model 2016-05-11 14:02:15 +03:00
7c37134aab rewrite formatters according to rfc #91 2016-05-10 02:16:24 +03:00
734cbe2f4c upload vertical alignment patch, fix code (#94) 2016-05-09 04:07:58 +03:00
4bcdb3a7ff release 3.1.2 2016-05-09 00:12:06 +03:00
5ad0c533f0 prerelease updates
* update Ukrainian translation
* update patches
* merge qt5.3-qtconcurrent-and-qlogging-category.patch into
  qt5.4-replace-qml-dialogs.patch
* update cmake files
* update README
2016-05-08 00:07:44 +03:00
d57e54b714 add script formatter 2016-05-07 00:10:06 +03:00
13f2d560d0 Some more changes
* new tag - $tstime
* add summand parameter to float formatter
* drop version.h includes since it has been moved to awdebug.h (e.g. to
  introduce BUILD_FUTURE guards easy in the future)
2016-05-06 01:22:59 +03:00
2220ad6bfe initial creation of custom formatters (#91) 2016-05-05 00:11:31 +03:00
97f2e78308 add transifex integration
* update Spanish translation
* rename nl to nl_NL
2016-05-04 12:40:54 +03:00
3771ce6ec2 rename forma_t_er to forma_tt_er 2016-05-03 05:04:12 +03:00
46db3fee4c add standalone configuration example (#72) 2016-05-01 16:23:37 +03:00
a339f9a743 drop needToBeUpdated call from qml since it is not required 2016-04-30 17:36:01 +03:00
4e52d16f1a prerelese translation bump 2016-04-29 13:01:17 +03:00
097b63415e drop own workaround for update functions
use qtimer instead
2016-04-28 18:18:13 +03:00
77388deab6 initial support of total sent/received data
Tags {up,down}total{,kb}[0-9]?+
2016-04-25 16:06:37 +03:00
d01d8f95e5 fix qpixmap generation 2016-04-23 05:22:54 +03:00
22586811de backport QML code changes from awesome-widgets to deskop-panel 2016-04-22 15:39:36 +03:00
82dda14260 add background configuration dialog 2016-04-21 16:44:21 +03:00
f8e9945bc4 fix configuration dialog error
even if user selects Cancel in font dialog html codes pasted
2016-04-20 15:50:45 +03:00
139554578c fix bug introduced by 5c474e822b
No conversion has been applied for total memory values
2016-04-18 09:33:35 +03:00
1827f641f9 Merge branch 'development' of github.com:arcan1s/awesome-widgets into development 2016-04-17 16:20:12 +03:00
aef1a736c8 code improvements
* drop c++14 requirements since it is not used
* move from enum to enum classes
* more intuitive graph building in GI
* allow X-AW-Direction property works with graphs and bars
2016-04-17 16:18:13 +03:00
27a80274ac add total memory fix patch 2016-04-16 18:29:11 +03:00
0e3f83f361 add bars support to gi
same as graphs but also provides solid background under lines
2016-04-16 03:23:28 +03:00
d30df9dafc fix configuration ui
In some cases text is removed, but no new text is pasted.
2016-04-15 15:02:35 +03:00
f7a6b86cae GI improvements
* add tag information to GI configuration
* change tag identification to avoid keys reorderding
2016-04-14 16:14:26 +03:00
a3e7a84b92 drop another part of pornography in gi
more intuinitve configuration interface in graphicalitem. Improve code
for the future references (in case if new color type will be added).
Change X-AW-*Color values to ones with prefixes (added autoconversion
from old-version api)
2016-04-12 14:22:19 +03:00
354fd3cd0c drop pornography with requests
Actually it has been introduced as temporary solution but I totally
forgot about it
2016-04-10 00:22:12 +03:00
15abe54290 Another fixes
* update translator list
* drop russian changelog at all
* fix changelog building
* fix invalid graphical item UI behaviour
2016-04-09 03:55:52 +03:00
60cbc40e9f implement coverity integration (see #84) 2016-04-08 16:23:59 +03:00
bfa4f9e98e Some small changes
* changelog update
* version metadata update
* bump required Qt version to 5.6 and update patch accordinly
* fix invalid cast in update dialog
2016-04-07 16:52:05 +03:00
e9146b3b6c release 3.1.1
* translation update
* fix broken build with gcc (#87). The issue was reproduced only with
  gcc build and has been resolved by just replacing C-like `isnan` to
  `std::isnan`
2016-04-06 14:42:56 +03:00
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
be26033ff7 edit log format line 2015-09-04 00:18:46 +03:00
70020d0aef Merge branch 'master' of github.com:arcan1s/awesome-widgets 2015-09-03 00:31:07 +03:00
7218defe19 add '$this' feature to lambda functions
fix large size on startup
fix invalid key parsing
2015-09-03 00:30:10 +03:00
200ecc7196 translation update 2015-09-02 00:19:28 +03:00
6689bea9a7 implement dynamic tags 2015-09-02 00:05:11 +03:00
5940ec4531 update awdebug 2015-09-01 01:45:25 +03:00
2716f77eb2 revert 2015-09-01 01:40:48 +03:00
cfdcaae036 drop script from deps 2015-09-01 01:40:15 +03:00
82c1839634 drop hidding method 2015-09-01 01:12:10 +03:00
08dae3b02b small patch to avoid notifications on nan 2015-08-31 01:43:39 +03:00
cc2b1b7b8a add images feature to extweather (apiver == 2) 2015-08-31 00:16:04 +03:00
4c27382467 more correct logging, use qt logging for qml as well 2015-08-30 16:24:00 +03:00
aacb50c946 start moving to qt5 style logging 2015-08-29 00:58:39 +03:00
466faf53fa some refactoring, prepare to moving to qt5 style logging 2015-08-28 00:15:25 +03:00
8228d1d06b Add filter feature to ExtUpgrade (ApiVer = 3) 2015-08-26 00:24:55 +03:00
37726370ee Add additional column to configuraion ui to better tag selection 2015-08-25 00:07:23 +03:00
07305d7578 no kf5 on ubuntu 12.04 2015-08-23 02:26:12 +03:00
b97c821c8f try to upgrade ubuntu first 2015-08-23 02:16:22 +03:00
b50c1d2363 add ability to do not translate strings 2015-08-23 02:14:55 +03:00
713aa611d9 drop travis since it uses ubuntu-12.04 2015-08-22 23:11:09 +03:00
319755179f #2 2015-08-22 22:30:52 +03:00
9509d87962 try to get it working 2015-08-22 22:27:27 +03:00
6d58a3f05c add repo 2015-08-22 14:59:44 +03:00
2cca290630 try add travis-ci 2015-08-22 14:55:50 +03:00
29b75e2b12 update additional files
update translations
add "Add lambda" button to ui
2015-08-22 00:40:14 +03:00
835eb00f0d add lambda support 2015-08-21 00:05:15 +03:00
a5e9b32b28 implement support of network speed units tags
fix warning for empty tooltip image
2015-08-18 01:17:51 +03:00
fbdc9112aa update archive generator 2015-08-16 15:48:43 +03:00
b3fc0501ba unify build, allow cross build 2015-08-16 03:24:44 +03:00
a74c65a2a3 fix typo 2015-08-16 02:41:26 +03:00
4858c9dbcd add rpm recipe 2015-08-16 02:38:24 +03:00
3601b4246d add build requirements for deb packages 2015-08-16 01:54:49 +03:00
241e13ffd8 add experimental debian build 2015-08-16 01:22:28 +03:00
7a5d2d5dd4 add forgoten line to CHANGELOG
drop default active script
2015-08-11 00:05:23 +03:00
24b143f43a release 2.4.0 2015-08-10 00:09:31 +03:00
df473c53b5 move plugins to iterators 2015-08-08 00:22:25 +03:00
3122c2fa8c rewrite to iterators library part 2015-08-07 07:21:55 +03:00
08cb7d9abe fix #60
some hash improvements
2015-08-06 01:23:43 +03:00
e38863ebc2 add disable key to player monitor 2015-08-05 01:14:09 +03:00
1cddf6f14d some map replacing 2015-08-04 00:15:19 +03:00
7405b2ba1d work with extendedsysmon
* fix mpris info getting
* replace qmap to qhash if possible
* some at()/[] repalcements
* add time logging
2015-08-03 00:01:14 +03:00
6fbe897b27 fix CMake policy setup 2015-08-02 14:24:49 +03:00
5f7c35a37c edit translations build
translation update
2015-08-02 00:40:23 +03:00
6173b60806 edit cmake files
edit font dialog
2015-08-01 00:10:18 +03:00
4c9e39ec9b translation update 2015-07-31 00:48:01 +03:00
429393998c update translations cmakelists as well 2015-07-30 00:01:13 +03:00
c9acb0bdcd edit build, create a separate cmake include file 2015-07-29 23:59:42 +03:00
16305a91c4 rewrite tooltip class 2015-07-29 00:03:12 +03:00
bbb9aa0747 fix library translations 2015-07-28 00:22:34 +03:00
983b808247 move aw plugin to template-based system
bump graphicalitems to ApiVer 2 (add number property)
2015-07-27 00:05:15 +03:00
c61a5ac092 create a static library for backend items
move backend items to template-based mechanism
2015-07-26 12:58:59 +03:00
3b6df44489 more correct methods naming, prepare to move to templates 2015-07-25 00:03:45 +03:00
4742617e3e * fix building
* add clang build
* more correct method types
2015-07-24 00:18:21 +03:00
880a986782 add abstactextitem class (building is broken atm) 2015-07-23 00:07:21 +03:00
b699095f38 initial support of weather 2015-07-22 00:44:39 +03:00
a065e96bc3 * move isDebugEnabled method to AWActions
* add "Drop key cache" button
2015-07-21 00:24:50 +03:00
1110929b14 improve update events 2015-07-20 00:21:39 +03:00
c7d998eb12 more correct fix for #57 2015-07-19 00:14:49 +03:00
eb63ef5e96 Merge branch 'key-filtering-feature' 2015-07-18 00:51:21 +03:00
327d5a7ff9 more correct fix for #57 2015-07-17 09:44:44 +03:00
2b9505207c Merge branch 'memory-load-fix' 2015-07-16 00:34:18 +03:00
cd36c4ed68 drop key definition on startup since it blocks several plasmoid
instances (refer to #57)
2015-07-15 19:50:12 +03:00
903a1a454d move plugin back to private 2015-07-15 19:49:54 +03:00
cf5d713d2e Revert "drop key definition on startup since it blocks several plasmoid"
This reverts commit 4e78e0e1dd.
2015-07-15 19:34:19 +03:00
467a3bf508 fix network speed calculation for $down and $up tags 2015-07-14 00:18:29 +03:00
4e78e0e1dd drop key definition on startup since it blocks several plasmoid
instances (refer to #57)
2015-07-11 15:04:53 +03:00
d01fb91e36 bump to 2.3.2 2015-07-09 00:28:47 +03:00
61ed3a444f change text rendering 2015-07-08 12:20:01 +03:00
494590475a release 2.3.2 2015-07-04 02:35:09 +03:00
27ab7d9cd7 fix cast int as float 2015-07-03 00:05:47 +03:00
1869a68122 fix bug with no actions
set network speed units as MB/s if the value more than 1k KB/s
2015-07-03 00:04:03 +03:00
aa0a4b417d improve battery support 2015-07-01 01:14:04 +03:00
41deb8ef72 fix plasma crash with extquotes
rewrite main widget to use signal-slot model
2015-06-30 07:13:58 +03:00
aa15e13713 update fr translations 2015-06-14 17:19:38 +03:00
ad63f78929 update links to opensuse packages 2015-06-12 15:05:56 +03:00
224e558a98 release 2.3.1 2015-06-11 01:49:22 +03:00
a391df2804 - fix bug with invalid values updates from configuration UI
* merge fan tags to temp ones for better handling
2015-06-10 10:31:41 +03:00
755d0b39f8 Merge pull request #56 from underr/master
Update PT-BR translations
2015-06-06 13:18:40 +03:00
fcd612880f Update PT-BR translations 2015-06-05 21:54:24 -03:00
5aff2d2e4e update Spain translations 2015-06-05 00:19:02 +03:00
5a52c056a7 update Ukrainian translation 2015-06-04 01:54:26 +03:00
42615a6fdc update translation, fix #53 2015-06-02 01:21:03 +03:00
b431d2c6cf Release 2.3.0 2015-06-01 01:40:06 +03:00
f96b3fcb07 implement \r to default json of ExtScripts
some refactoring
bump ApiVer of ExtQuotes
update changelog
2015-05-31 02:57:43 +03:00
f534a6854a try to implement timeouts support to quotes (ref to #54) 2015-05-29 18:29:13 +03:00
b51c97abbb drop qxml, port quotes from xml to json (xml has been used for qt4
branch)
2015-05-28 09:16:27 +03:00
8dc3510a30 more pretty configuration interface
implement quotes changes
2015-05-25 02:28:09 +03:00
fce098cb5c improve work with filters for custom scripts
implement new line filters for widget text
fix bug with html parsing
implement key sorting in combo boxes
2015-05-24 00:03:54 +03:00
5f4bf9ec29 edit readme.md
implement initial support of filters (dep #53)
2015-05-23 02:07:16 +03:00
457 changed files with 39187 additions and 18403 deletions

41
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,41 @@
name: build & tests
on:
push:
branches: [ development, master ]
pull_request:
branches: [ development, master ]
env:
BUILD_TYPE: Release
jobs:
run-tests:
runs-on: ubuntu-latest
container:
image: archlinux:latest
volumes:
- ${{ github.workspace }}:/repo
options: -w /repo
steps:
- uses: actions/checkout@v3
- name: create build environment
run: pacman -Sy --noconfirm base-devel cmake extra-cmake-modules python util-linux-libs xorg-server-xvfb
- name: install dependencies
run: pacman -S --noconfirm plasma-workspace ksysguard
- name: configure cmake
run: cmake -B build -DKDE_INSTALL_USE_QT_SYS_PATHS=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_FUTURE=ON -DBUILD_TESTING=ON sources
- name: build
working-directory: /repo/build
run: make
- name: test
working-directory: /repo/build
run: xvfb-run -a make test

51
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,51 @@
name: release
on:
push:
tags:
- '*'
jobs:
make-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: create changelog
id: changelog
uses: jaywcjlove/changelog-generator@main
with:
token: ${{ secrets.GITHUB_TOKEN }}
filter: 'Release \d+\.\d+\.\d+'
- name: create archive
run: bash create_archive.sh
env:
VERSION: ${{ steps.version.outputs.VERSION }}
- name: build debian package
run: |
sudo apt update && \
sudo apt install -yq cmake extra-cmake-modules g++ git gettext make && \
sudo apt install -yq libkf5i18n-dev libkf5notifications-dev libkf5service-dev \
libkf5windowsystem-dev libkf5plasma-dev qtbase5-dev qtdeclarative5-dev \
plasma-workspace-dev && \
cmake -B build-deb -DKDE_INSTALL_USE_QT_SYS_PATHS=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Optimization -DBUILD_FUTURE=ON -DBUILD_DEB_PACKAGE=ON sources && \
cd build-deb && \
make package && \
cd ..
- name: release
uses: softprops/action-gh-release@v1
with:
body: |
${{ steps.changelog.outputs.compareurl }}
${{ steps.changelog.outputs.changelog }}
files: |
awesome-widgets-*-src.tar.xz
build-deb/plasma-widget-awesome-widgets-*.deb
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

49
.gitignore vendored
View File

@ -1,7 +1,50 @@
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
cmake-build*

12
.gitmodules vendored
View File

@ -1,12 +0,0 @@
[submodule "sources/3rdparty/pdebug"]
path = sources/3rdparty/pdebug
url = https://github.com/arcan1s/qtadds-pdebug.git
[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

8
.tx/config Normal file
View File

@ -0,0 +1,8 @@
[main]
host = https://www.transifex.com
[awesome-widgets.awesome-widgetspot]
source_file = sources/translations/awesome-widgets.pot
source_lang = en
type = PO
file_filter = sources/translations/<lang>.po

16
AUTHORS
View File

@ -1,9 +1,15 @@
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)
@underr (Brazillian Portuguese translation)
Виктор Слободян (Ukrainian translation)
Steve Lemuel (Chinese translation)
@Mermouy (French)
Ernesto Avilés Vzqz (Spanish)
@underr (Brazillian Portuguese)
Виктор Слободян (Ukrainian)
Steve Lemuel (Chinese)
Mariusz Kocoń (Polish)
Ibnu Daru Aji (Indonesian)
Antonio Vivace (Italian)

210
CHANGELOG
View File

@ -1,16 +1,222 @@
Ver.3.5.0:
+ wayland support
* update code to latest standards
- drop support of windows preview
Ver.3.4.2:
+ Italian translation (#136, thanks to @avivace)
+ stooq quotes support (default) (#131)
+ Indonesian translation (#132, thanks to @ibnuda)
+ new keys - $batleftN, $batnowN, $batrateN, $battotalN, $brightness, $volume
* fix compiler warnings
* update to new qt api
- fix non printable spaces (#142, #143)
Ver.3.3.3:
+ add custom keys support (#101)
* DBus interface improvements
* rename tags (up|down|ps)total.* to (up|down|ps)tot.*
- fix issue with invalid (up|down)total($|kb) calculation (#127)
- fix issue with wrong applet identation (#125)
Ver.3.3.2:
- fix bug with invalid DP colour configuration
- fix bug with invalid HTML tags operation
* update to newest Qt and plasma
Ver.3.3.1:
+ add ability to direct issue report (#104)
+ add key completion (#105)
+ add ability to load historical configuration (#106)
+ add ability to upload configuration to remote server (#106)
+ add stylish (#112)
+ add DBus intergration (#115)
+ add cron-like extenstion triggers (`X-AW-Socket` option) (#117)
+ add ability to trigger extensions by calling socket (`X-AW-Schedule` option) (#118)
+ add source for network requests
+ add Json formatter
- drop patches provided support for Qt 5.4
* use custom signal slot connection for dataengine (`BUILD_FUTURE` flag required)
* update UI
* refactoring
Ver.3.2.1:
+ add X-AW-Translate option to DateTime formatter
+ add formatters to configuration export and import
+ add macro fuction to selector
+ add default formatters
- add translation reinit (fix #102)
- fix invalid float formatter saving
- fix missing ApiVersion for formatters
* use sockets for MPD data
* translation update
Ver.3.2.0:
+ custom formatters (#91)
+ add backend tests (#95)
+ add OWM weather provider for ExtWeather. It can be switched by using X-AW-Provider (ApiVer 3)
+ add DBus timeout for calls (#96)
+ add macros support (`$aw_macro` and `$aw_macro_*` for calls)
- fix vertical alignment (#94)
- fix bug with invalid updates on `X-AW-Interval=1` for ExtScript and ExtUpgrade
- fix bug with missing derivate vaules in ExtQuotes
- fix possible plasma crash (#96)
- fix possible undefined behaviour if no extensions was found by name
* split dataengine sources to own library
* allow to use screened double brakets inside functions
Ver.3.1.2:
+ add standalone widget configuration example
+ new tag tstime
+ new tags uptotal* and downtotal*
+ add background configuration button
+ allow X-AW-Direction property works with graphs and bars (graphical items)
+ add bars support to Graphical Items
+ add integration with transifex
+ add integration with coverity
- drop update source (breaking changes if you are using it as developer)
- fix pen generation from file image (graphical items)
- fix bug with which font html parameters will be pasted even if there cancel clicked
- fix bug with invalid total memory formating
- fix bug in configuration UI with which there is no selected text pasted
- fixes in graphical item configuration UI and behaviour
- fix changelog building
- fix invalid cast (found by coverity)
* change text update mechanism
* grahical item improvements
* code improvements
* translation update
Ver.3.1.1:
- fix broken gcc build (#87)
* translation update
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
+ add support of load average (la1, la5, la15 tags)
+ add "drop key cache" button
+ add support of clang building
+ create ExtItems aggregator
+ add time to debug information
+ add ability to disable player monitor
- fix bug with invalid network data calculation
- fix warning with fond dialog init
- fix bug with no object deletions (#60)
* rewrite ExtItems to use own abstract class
* improve work with data updating (#57)
* move to signal-slot interface painting
* move plugin part back to private
* cast plugin as type, not signleton (#57)
* change logic in data building inside DataEngine
* edit build and drop different DataEngine packaging
* rewrite QMap to QHash if possible
* rewrite to use iterators if possible
* list of desktops is now represented as QStringList
* refactoring
Ver.2.3.3:
* change text rendering from Qt to native
Ver.2.3.2:
+ change network speed units from KB/s to MB/s if value is more than 1000 KB/s (metrics are the same)
- fix bug with no actions on link activation (thanks to infans)
* improve quotes support, e.g. fix plasma crash
* rewrite main widget to signal-slot update model
* improve battery calculation for system which has several batteries
Ver.2.3.1:
- fix bug with no updates from configuration UI
- fix invalid vertical tab parsing
* translation update
* merge fan tags to temp ones, improve lmsensors tags handling
Ver.2.3.0:
+ implement fitlers support to ExtScripts (ApiVer = 3) (#53)
+ implement ability to wrap `\n` as new lines (#53)
+ implement key sorting in comboboxes
+ implement (perc)(bid|ask|price)chg tag support (ApiVer = 2)
+ implement timeouts to quotes (#54)
- fix bug with invalid html parsing
* move from XML to JSON in ExtQuotes (ApiVer = 2)
* more pretty configuration UI
* some part of refactoring
Ver.2.2.2:
+ add quotes support (#46)
+ add support of properties height and width (#47)
+ add transtaltion support to the plugins (#50)
+ add support of key caching
+ add support of X-AW-Number to ExtScript and ExtUpgrade (ApiVer=2)
+ add support of X-AW-Number to ExtScript and ExtUpgrade (ApiVer = 2)
+ add reconnection to DataEngine (in some cases some values are not updated)
+ add widgets width and height update
- fix bug with Ext* items update (#49)
- fix bug with GPUDEV, HDDDEV settings saving from UI
- fix Desktop Panel settings
- fix bug with adding paragraph settings
* drop support of KDE4 support, created a separate branch
* drop support of KDE4 support, created a separated branch
* increase intervals limits (#48)
* hddtemp was replaced to smartctl by default
* plugins were moved from private

View File

@ -1,292 +0,0 @@
Вер.2.2.2:
+ добавлена поддержка котировок (#46)
+ добавлена поддержка свойств height и width (#47)
+ добавлена поддержка перевода в плагины (#50)
+ добавлено кеширование ключей
+ добавлена поддержка X-AW-Number в ExtScript, ExtUpgrade (ApiVer=2)
+ добавлено переподключение DataEngine (в некоторых случаях отдельные значения не обновляются)
+ добавлено обновление ширины и высоты виджета
- исправлен баг при обновлении Ext* (#49)
- исправлен баг с сохранением настроек GPUDEV, HDDDEV из графического интерфейса
- исправлены настройки Desktop Panel
- исправлен баг с добавлением настроек параграфа
* дропнута поддержка KDE4 версии (отдельная ветка разработки)
* увеличены лимиты для интервалов (#48)
* hddtemp был заменен на smartctl по умолчанию
* плагины были перемещены из private
* более корректное рисование интерфейса
Вер.2.2.1:
+ добавлен ключ X-AW-Interval в ExtUpgrade (ApiVer = 1, default = 3600)
+ добавлено кеширование значений в ExtScript и ExtUpgrade
+ добавлена поддержка isActive в ExtUpgrade
* изменена проверка версий cmake
* улучшена логика работы ExtScript и ExtUpgrade
Вер.2.2.0:
* портирование на Plasma 5
+ добавлена поддержка списка окон в тултипе
+ добавлены уведомления на системные события
+ добавлена возможность показать выбранный тег
+ добавлены теги $downN, $upN
+ добавлен инструмент netdev
+ добавлена поддержка smartctl
- убрана возможность сокрытия панелей
* незначительно изменена логика работы виджета
* исправлена отрисовка превью окон
* обновление кодовой базы KDE4 под новый ABI
* оптимизация работы DataEngine
* PKGCMD были заменены на ExtUpgrade
Вер.2.1.0:
+ добавлена функция автообновления
+ добавлена поддерка кастомных скриптов
+ добавлена поддержка превью рабочего стола для DP
+ добавлена поддержка баров
- удалена поддержка кастомных команд
- фикс #34
* исправлены уведомления
* переписан UI в соответствии со стандартами KDE
* исправлены границы для графических объектов
* переписан DP и DE на использование библиотечных функций
* изменено определение свойств GPU
* изменен поиск регулярных выражений
Вер.2.0.5:
+ добавлен нижний край к тултипу (#30)
* исправлен баг с обновлением сетевого интерфейса
* исправлен баг с тултипом батареи
* отредактирована разметка DP (#31)
Вер.2.0.4:
* более корректная работа с батареями
Вер.2.0.3:
+ добавлена поддержка нескольких тегов $bat
* отредактирована разметка
Вер.2.0.2:
+ добавлены теги $fan*
+ добавлен китайский перевод (спасибо @Lemueler)
+ добавлена проверка сетевых устройств на p2p
- удалено ps stats из уведомлений
* еще один фикс тегов cpu* и cpucl
* переписан конфигурационный интерфейс DP
* исправлены нестандартные единицы температуры
Вер.2.0.1:
+ добавлена поддержка кастомных интерфейсов
* фикс затенения краев поля
* фикс тегов cpu*, cpucl*, gpu*, ps*
Вер.2.0.0:
+ добавлен виджет awesome widget
+ новые теги $hddfreemb, $hddfreegb, $memusedmb, $memusedgb, $memfreemb $memfreegb, $swapfreemb, $swapfreegb
+ новый DataEngine - battery
+ новый тултип - battery
+ новые температурные единицы см^-1, ккал/моль, кДж/моль, Реамюр
+ добавлена возможность скрывать панели по хоткею
- удален виджет pytextmonitor
- убраны отдельные поля
- удалены README
* проект переименован в Awesome Widgets
* тег $custom (время) переименован в $ctime
* тег $custom (время работы) переименован в $cuptime
* тег $time (плеер) переименован в $duration
* тег $number переименован в $ndesktop
* тег $name переименован в $desktop
* тег $total переименован в $tdesktops
* дебаг флаг теперь DEBUG
* проект полностью переписан на C++
* тултип независит теперь от самого виджета
* настройка выравнивания текста теперь осуществляется только HTML тегами
* настройки батареи и адаптора питания вынесены в DataEngine
* изменения в конфигурационном интерфейсе
Вер.1.11.0:
+ добавлена возможность отключения фона
+ добавлен desktop DataEngine
+ добавлен виджет PTM desktop panel
+ добавлено поле текущий рабочий стол (теги $name, $number, $total)
+ добавлена возможность взаимодействия с плеерами через mpris
* добавлено использование сабмодулей
* DataEngine переписан с использованием tasks
* фикс чтения температуры nvidia
Вер.1.10.2:
- фикс ошибки с tempUnits в поле hddtemp
Вер.1.10.1:
- пофикшена ошибка с форматами чисел в поле ps
- пофикшена инициализация значений в DataEngine
- пофикшена проверка qmmp
Вер.1.10.0:
+ добавлены теги $hddtotmb, $hddtotgb
+ добавлены теги $memtotmb, $memtotgb, $swaptotmb, $swaptotgb
+ добавлена возможность форсированного обновления
+ добавлена поддержка clementine
+ добавлена поддержка команды hddtemp
+ добавлены поддержка disable для HDDDEV и GPUDEV
+ добавлена многопоточность в DataEngine
+ добавлена проверка ошибок для переменных DataEngine
+ добавлена возможность отключения всплывающих сообщений
+ добавлена возможность использовать вертикальную разметку
+ добавлена возможность добавить пустое пространство
+ добавлена возможность вывода отладочной информации (установите переменную окружения 'PTM_DEBUG' в 'yes')
+ добавлен перевод Brazillian Portuguese (@underr)
+ добавлена украинская локализация (Виктор Слободян)
- удален util.py
- удалены функции createNotifyrc, поскольку они больше не нужны
* рефакторинг конфигурационного интерфейса
* настройки плеера были перенесены из виджета в DataEngine
* исправлен вызов readme под четырехсимвольное обозначение
* перенос readme с md на html
Вер.1.9.0:
+ добавлена поддержка нескольких кастомных команд ($customN)
+ добавлено поле скорости hdd ($hddrN, $hddwN)
+ добавлены действия в контекстное меню (открыть readme и запустить ksysguard)
* исправлен парсинг поля pkg
- убрано событие по двойному клику
Вер.1.8.3:
+ добавлен испанский перевод (Ernesto Avilés Vzqz)
+ добавлены файлы readme
Вер.1.8.2:
+ добавлены различные температурные единицы (Farenheit и Kelvin)
Вер.1.8.1:
* поле pkg теперь обновляется раз в час
Вер.1.8.0:
+ добавлены скроллбары в конфигурационный интерфейс
+ добавлена настройка значений AC
+ добавлены теги $hddmbN, $hddgbN
+ добавлена поддержка ps (теги $ps, $pscount, $pstotal)
+ добавлена поддержка пакетных менеджеров (теги $pkgcountN)
* рефакторинг DataEngine
Вер.1.7.4:
+ добавлена поддержка более чем 10 тэгов в полях cpu, cpuclock, hdd, hddtemp, temp
- фиксы в форматах
* изменения в кастомном формате аптайма
Вер.1.7.3:
+ добавлены тэги $memgb, $swapgb
+ добавлена директория readme
+ добавлен французский перевод (@Mermouy)
- фикс подсказки для кастомного формата аптайма
- фикс #12
* больше рефакторинга богу рефакторинга
* интервал обновления сетевого интерфейса теперь 30*interval
* тэги $swap, $swapmb и $swapgb теперь работают одновременно (тэги $mem* тоже)
* player_name теперь имеет тип str
Вер.1.7.2:
+ добавлены тэги $dd, $d, $hh, $h, $mm, $m в кастомный формат аптайма
+ добавлено масштабирование в тултипы
+ добавлена конфигурация DE из виджета
+ добавлена кастомная команда в DE
- удалена кастомная команда из виджета
- удалены тэги $ds, $hs, $ms
Вер.1.7.1:
- удалено поле с ошибкой
* пофикшен баг с нулевым значением в тултипе
Вер.1.7.0:
+ добавлена поддержка нескольких тэгов в поле температуры
+ добавлены тэги $cpuN, $cpuclN, $hddN, $tempN, $hddtempN, $up, $down
+ добавлено поле с кастомной командой
+ добавлены тултипы для полей CPU, частоты CPU, памяти, swap и сеть
- удалены тэги @@...@@, $temp, $ccpu, $ccpucl, $net
* изменения в настройках
* виджет не требует больше net-tools
* рефакторинг
Вер.1.6.1:
+ добавлена поддержка нескольких девайсов в поле hddtemp
- фикс #6
Вер.1.6.0:
+ добавлен тэг $custom в поля time и uptime (#8)
+ русский перевод
- фикс #6, #10
* лицензия изменена на GPLv3
* изменения в сборке проекта
Вер.1.5.3:
+ добавлены тэги $album, $progress и $time tags в поле плеера (#7)
- фикс бага с нулевым свопом
Вер.1.5.2:
+ добавлены тэги $isotime, $shorttime и $longtime в поле time
Вер.1.5.1:
+ добавлено поле time
Вер.1.5.0:
+ добавлено поле player
Вер.1.4.0:
+ добавлены уведомления
Вер.1.3.6:
- фикс #1, #2
Вер.1.3.5:
- фикс бага с определением сетевого устройства
Вер.1.3.4:
+ добавлено событие по двойному щелчку
+ добавлен автовыбор сетевого устройства
- фикс еще одного падения Плазмы
Вер.1.3.3:
* редактирование чтения температурного устройства
Вер.1.3.2b:
- фикс падения Плазмы
Вер.1.3.2:
+ добавлены поля GPU, GPU temp, HDD и HDD temp
+ добавлены тэги $ccpu и $ccpucl
- фикс некоторых багов
* оптимизация и рефакторинг
Вер.1.2.2:
+ добавлен тултип в строки
Вер.1.2.1:
* если батарея не существует, возвращает off
* если AC не существует, возвращает '(?)'
Вер.1.2.0:
+ добавлен тэг $ac в поле battery
+ добавлена настройка устройств батареи и AC
+ добавлена проверка ошибок
* тэг $bat теперь читается из /sys/*
Вер.1.1.4:
* изменения в парсинге acpi (поле battery)
Вер.1.1.3:
+ добавлена настройка ширины шрифта
- небольшие фиксы
* отредактирована настройка шрифта. Теперь настройки для шрифта работают нормально
Вер.1.1.2:
+ добавлено поле CPU clock
+ добавлена функция для обновления сетевого интерфейса (100*time_interval)
* изменено обновление слайдеров
Вер.1.1.1:
+ добавлены тэги $swapmb, $memmb, $netdev, @@netdev=...@@
- небольшие фиксы
* виджет теперь состоит из нескольких полей
* отредактирован конфигурационный интерфейс
Вер.1.0:
Первый релиз

228
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,228 @@
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.
* Any private variable should start with `m_` prefix (`m_foo`). The only one
exception is `Ui` object which should be named as `ui`.
* 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++17**.
* 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.
* C-like `NULL`, use `nullptr` instead.
* C-like constant definition, use `const vartype foo = bar` definition instead.
* 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.
* Do not use semicolon in qml files unless it is required.
* Any method argument including class constructors should start with `_`.
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`.
* Additional 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

@ -1,6 +1,9 @@
awesome-widgets (ex-pytextmonitor)
==================================
[![build & tests](https://github.com/arcan1s/awesome-widgets/actions/workflows/build.yml/badge.svg)](https://github.com/arcan1s/awesome-widgets/actions/workflows/build.yml)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/8254/badge.svg)](https://scan.coverity.com/projects/awesome-widgets)
Information
-----------
@ -27,8 +30,8 @@ Instruction
Dependencies
------------
* kdebase-workspace (*if KDE4 is used*) **or** plasma-framework (*if KF5 is used*)
* lm_sensors (*for definition temperature device*)
* plasma-framework
* ksysguard (since plasma 5.22)
Optional dependencies
---------------------
@ -36,13 +39,16 @@ Optional dependencies
* proprietary video driver
* hddtemp
* smartmontools
* music player (mpd or supported MPRIS)
* music player (mpd or MPRIS supported)
* wireless_tools
Make dependencies
-----------------
* cmake
* automoc4 (*if KDE4 is used*) or extra-cmake-modules (*if KF5 is used*)
* extra-cmake-modules
In addition some distros might require to install some -dev packages, e.g. the list of required packages for deb-based distros can be found [here](https://github.com/arcan1s/awesome-widgets/blob/development/.docker/Dockerfile-ubuntu-amd64#L7).
Installation
------------
@ -51,10 +57,10 @@ Installation
* install
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr ../
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr ../sources
make && sudo make install
**NOTE** on Plasma 5 it may require `-DKDE_INSTALL_USE_QT_SYS_PATHS=ON` flag
**NOTE** on Plasma 5 it very likely requires `-DKDE_INSTALL_USE_QT_SYS_PATHS=ON` flag
Additional information
======================
@ -67,9 +73,10 @@ 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/kdeplasma-applets-awesome-widgets/) package
* Archlinux [AUR](https://aur.archlinux.org/packages/plasma5-applet-awesome-widgets/) package
* [OpenSuse](http://software.opensuse.org/search?q=awesome-widgets) packages, [KF5 OpenSuse](http://software.opensuse.org/package/plasma5-awesome-widgets) package

View File

@ -1,41 +1,20 @@
#!/bin/bash
SRCDIR="sources"
MAJOR=$(grep -m1 PROJECT_VERSION_MAJOR sources/CMakeLists.txt | awk '{print $3}' | sed 's/.$//g')
MINOR=$(grep -m1 PROJECT_VERSION_MINOR sources/CMakeLists.txt | awk '{print $3}' | sed 's/.$//g')
PATCH=$(grep -m1 PROJECT_VERSION_PATCH sources/CMakeLists.txt | awk '{print $3}' | sed 's/.$//g')
VERSION="${MAJOR}.${MINOR}.${PATCH}"
# update submodules
git submodule update --init --recursive
# build dataengine
ARCHIVE="extsysmon"
# create archive
[[ -e ${ARCHIVE}-${VERSION}-src.tar.xz ]] && rm -f ${ARCHIVE}-${VERSION}-src.tar.xz
[[ -d ${ARCHIVE} ]] && rm -rf "${ARCHIVE}"
cp -r "${SRCDIR}/${ARCHIVE}" "${ARCHIVE}"
tar cJf "${ARCHIVE}-${VERSION}-src.tar.xz" "${ARCHIVE}"
rm -rf "${ARCHIVE}"
VERSION="$(git describe --tags --abbrev=0)"
# build widget
ARCHIVE="awesome-widgets"
FILES="AUTHORS CHANGELOG CHANGELOG-RU COPYING"
IGNORELIST="build usr .kdev4 *.kdev4"
FILES="AUTHORS CHANGELOG COPYING packages patches sources"
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}"
cp -r "${SRCDIR}" "${ARCHIVE}"
for FILE in ${FILES[*]}; do cp -r "$FILE" "${ARCHIVE}"; done
for FILE in ${IGNORELIST[*]}; do rm -rf "${ARCHIVE}/${FILE}"; done
tar cJf "${ARCHIVE}-${VERSION}-src.tar.xz" "${ARCHIVE}"
ln -sf "../${ARCHIVE}-${VERSION}-src.tar.xz" arch
rm -rf "${ARCHIVE}"
# update md5sum
MD5SUMS=$(md5sum ${ARCHIVE}-${VERSION}-src.tar.xz | awk '{print $1}')
sed -i "/md5sums=('[0-9A-Fa-f]*/s/[^'][^)]*/md5sums=('${MD5SUMS}'/" arch/PKGBUILD
sed -i "s/pkgver=[0-9.]*/pkgver=${VERSION}/" arch/PKGBUILD
# clear
find . -type f -name '*src.tar.xz' -not -name "*${VERSION}-src.tar.xz" -exec rm -rf {} \;
find arch -type l -xtype l -exec rm -rf {} \;
tar cJf "${ARCHIVE}-${VERSION}-src.tar.xz" "${ARCHIVE}"
rm -rf "${ARCHIVE}"

View File

@ -2,25 +2,22 @@
pkgname=plasma5-applet-awesome-widgets
_pkgname=awesome-widgets
pkgver=2.2.2
pkgver=3.4.3
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=("amarok: for music player monitor"
"clementine: for music player monitor"
"catalyst: for GPU monitor"
depends=('ksysguard' 'plasma-framework')
optdepends=("catalyst: for GPU monitor"
"hddtemp: for HDD temperature monitor"
"smartmontools: for HDD temperature monitor"
"mpd: for music player monitor"
"nvidia-utils: for GPU monitor"
"qmmp: for music player monitor")
makedepends=('cmake' 'extra-cmake-modules')
"nvidia-utils: for GPU monitor")
makedepends=('cmake' 'extra-cmake-modules' 'python')
source=(https://github.com/arcan1s/awesome-widgets/releases/download/V.${pkgver}/${_pkgname}-${pkgver}-src.tar.xz)
install=${pkgname}.install
md5sums=('73e176a124f8bfe43a0a112307624bfe')
md5sums=('5953ba518191bb6fff83cdb8633c735c')
backup=('etc/xdg/plasma-dataengine-extsysmon.conf')
prepare() {
@ -31,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"
@ -17,7 +17,7 @@ optdepends=("amarok: for music player monitor"
"mpd: for music player monitor"
"nvidia-utils: for GPU monitor"
"qmmp: for music player monitor")
makedepends=('cmake' 'extra-cmake-modules')
makedepends=('cmake' 'extra-cmake-modules' 'git')
source=(${_pkgname}::git+https://github.com/arcan1s/awesome-widgets/)
install=${pkgname}.install
md5sums=('SKIP')

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

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

65
sources/.clang-format Normal file
View File

@ -0,0 +1,65 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: None
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: No
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Linux
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 120
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: Latest
TabWidth: 8
UseTab: Never
...

View File

@ -1,23 +0,0 @@
[Buildset]
BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x1e\x00a\x00w\x00e\x00s\x00o\x00m\x00e\x00-\x00w\x00i\x00d\x00g\x00e\x00t\x00s)
[CMake]
Build Directory Count=1
Current Build Directory Index=0
ProjectRootRelative=./
[CMake][CMake Build Directory 0]
Build Directory Path=file:///home/arcanis/Documents/github/awesome-widgets/build
Build Type=Release
CMake Binary=file:///usr/bin/cmake
Environment Profile=
Extra Arguments=
Install Directory=file:///usr
[Defines And Includes][Compiler]
Name=GCC
Path=gcc
Type=GCC
[Project]
VersionControlSupport=kdevgit

View File

@ -1,23 +0,0 @@
[Buildset]
BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x1e\x00a\x00w\x00e\x00s\x00o\x00m\x00e\x00-\x00w\x00i\x00d\x00g\x00e\x00t\x00s)
[CMake]
Build Directory Count=1
Current Build Directory Index=0
ProjectRootRelative=./
[CMake][CMake Build Directory 0]
Build Directory Path=file:///home/arcanis/Documents/github/awesome-widgets/build
Build Type=Release
CMake Binary=file:///usr/bin/cmake
Environment Profile=
Extra Arguments=
Install Directory=file:///usr
[Defines And Includes][Compiler]
Name=GCC
Path=gcc
Type=GCC
[Project]
VersionControlSupport=kdevgit

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>

165
sources/3rdparty/fontdialog/COPYING vendored Normal file
View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

4
sources/3rdparty/fontdialog/README.md vendored Normal file
View File

@ -0,0 +1,4 @@
qtadds-fontdialog
=================
Font dialog which provides a font color settings

View File

@ -0,0 +1,215 @@
/***************************************************************************
* Copyright (C) 2014 Evgeniy Alekseev *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 3.0 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library. *
***************************************************************************/
#include "fontdialog.h"
#include <QGridLayout>
CFont::CFont(const QString family, int pointSize, int weight, bool italic, QColor color)
: QFont(family, pointSize, weight, italic)
{
setCurrentColor(color);
}
QColor CFont::color()
{
return currentColor;
}
void CFont::setCurrentColor(const QColor color)
{
currentColor = color;
}
int CFont::html2QFont(const int htmlWeight)
{
int weight = 16;
switch(htmlWeight) {
case 100:
weight = 16;
break;
case 200:
case 300:
weight = 25;
break;
case 400:
weight = 50;
break;
case 500:
case 600:
weight = 63;
break;
case 700:
case 800:
weight = 75;
break;
case 900:
weight = 87;
break;
default:
break;
}
return weight;
}
int CFont::qFont2html(const int weight)
{
int htmlWeight = 400;
switch(weight) {
case 16:
htmlWeight = 100;
break;
case 25:
htmlWeight = 300;
break;
case 50:
htmlWeight = 400;
break;
case 63:
htmlWeight = 600;
break;
case 75:
htmlWeight = 800;
break;
case 87:
htmlWeight = 900;
break;
default:
break;
}
return htmlWeight;
}
int CFont::htmlWeight()
{
return CFont::qFont2html(weight());
}
void CFont::setHtmlWeight(const int htmlWeight)
{
setWeight(CFont::html2QFont(htmlWeight));
}
CFont CFont::fromQFont(const QFont font, const QColor color)
{
return CFont(font.family(), font.pointSize(), font.weight(), font.italic(), color);
}
QFont CFont::toQFont()
{
return QFont(family(), pointSize(), weight(), italic());
}
CFontDialog::CFontDialog(QWidget *parent, bool needWeight, bool needItalic)
: QDialog(parent)
{
QGridLayout *mainGrid = new QGridLayout(this);
setLayout(mainGrid);
colorBox = new QComboBox(this);
connect(colorBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateColor(QString)));
QStringList colorNames = QColor::colorNames();
int index = 0;
for (int i=0; i<colorNames.count(); i++) {
QColor color(colorNames[i]);
colorBox->addItem(colorNames[i], color);
QModelIndex idx = colorBox->model()->index(index++, 0);
colorBox->model()->setData(idx, color, Qt::BackgroundRole);
}
mainGrid->addWidget(colorBox, 0, 0);
fontBox = new QFontComboBox(this);
mainGrid->addWidget(fontBox, 0, 1);
sizeBox = new QSpinBox(this);
mainGrid->addWidget(sizeBox, 0, 2);
weightBox = new QSpinBox(this);
mainGrid->addWidget(weightBox, 0, 3);
italicBox = new QComboBox(this);
italicBox->addItem(tr("normal"));
italicBox->addItem(tr("italic"));
mainGrid->addWidget(italicBox, 0, 4);
buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, this);
QObject::connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
QObject::connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
mainGrid->addWidget(buttons, 1, 0, 1, 5);
italicBox->setHidden(!needItalic);
weightBox->setHidden(!needWeight);
}
CFontDialog::~CFontDialog()
{
delete colorBox;
delete buttons;
delete fontBox;
delete italicBox;
delete sizeBox;
delete weightBox;
}
void CFontDialog::updateColor(const QString color)
{
colorBox->setStyleSheet(QString("background:%1").arg(QColor(color).name()));
}
CFont CFontDialog::getFont(const QString title, CFont defaultFont, bool needWeight, bool needItalic, int *status)
{
CFontDialog dlg(0, needWeight, needItalic);
dlg.setWindowTitle(title);
QStringList colorNames = QColor::colorNames();
for (int i=0; i<colorNames.count(); i++)
if (QColor(colorNames[i]) == defaultFont.color()) {
dlg.colorBox->setCurrentIndex(i);
break;
}
dlg.fontBox->setCurrentFont(defaultFont);
dlg.sizeBox->setValue(defaultFont.pointSize());
dlg.weightBox->setValue(defaultFont.weight());
if (defaultFont.italic())
dlg.italicBox->setCurrentIndex(1);
else
dlg.italicBox->setCurrentIndex(0);
CFont font = CFont(defaultFont);
int ret = dlg.exec();
if (ret == 1)
font = CFont(dlg.fontBox->currentFont().family(),
dlg.sizeBox->value(),
dlg.weightBox->value(),
dlg.italicBox->currentIndex() == 1,
QColor(dlg.colorBox->currentText()));
if (status != nullptr)
*status = ret;
return font;
}

View File

@ -0,0 +1,82 @@
/***************************************************************************
* Copyright (C) 2014 Evgeniy Alekseev *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 3.0 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library. *
***************************************************************************/
#ifndef FONTDIALOG_H
#define FONTDIALOG_H
#include <QComboBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QFontComboBox>
#include <QSpinBox>
class CFont : public QFont
{
public:
explicit CFont(const QString family, int pointSize = -1,
int weight = -1, bool italic = false,
QColor color = QColor(QString("#000000")));
// color properties
QColor color();
void setCurrentColor(const QColor color);
// html weight properties
static int html2QFont(const int htmlWeight);
static int qFont2html(const int weight);
int htmlWeight();
void setHtmlWeight(const int htmlWeight);
// conversion to QFont
static CFont fromQFont(const QFont font,
const QColor color = QColor(QString("#000000")));
QFont toQFont();
private:
QColor currentColor;
};
class CFontDialog : public QDialog
{
Q_OBJECT
public:
explicit CFontDialog(QWidget *parent = 0,
const bool needWeight = true,
const bool needItalic = true);
~CFontDialog();
static CFont getFont(const QString title = tr("Select font"),
CFont defaultFont = CFont(QString("Arial"),
12, 400, false,
QColor(QString("#000000"))),
const bool needWeight = true,
const bool needItalic = true,
int *status = nullptr);
private slots:
void updateColor(const QString color);
private:
QComboBox *colorBox;
QDialogButtonBox *buttons;
QFontComboBox *fontBox;
QComboBox *italicBox;
QSpinBox *sizeBox;
QSpinBox *weightBox;
};
#endif /* FONTDIALOG_H */

Submodule sources/3rdparty/pdebug deleted from 294a590bb9

View File

@ -0,0 +1,18 @@
#include "qreplytimeout.h"
#include <QTimer>
QReplyTimeout::QReplyTimeout(QNetworkReply *reply, const int timeout)
: QObject(reply)
{
QTimer::singleShot(timeout, this, SLOT(timeout()));
}
void QReplyTimeout::timeout()
{
auto *reply = dynamic_cast<QNetworkReply *>(parent());
if (reply->isRunning())
reply->close();
}

View File

@ -0,0 +1,17 @@
// from here http://codereview.stackexchange.com/questions/30031/qnetworkreply-network-reply-timeout-helper
// no license provided
#include <QNetworkReply>
#include <QObject>
class QReplyTimeout : public QObject
{
Q_OBJECT
public:
explicit QReplyTimeout(QNetworkReply *reply, const int timeout);
public slots:
void timeout();
};

Submodule sources/3rdparty/task deleted from d2798204a1

Submodule sources/3rdparty/tasks deleted from 230bdecd2c

View File

@ -1,46 +1,76 @@
cmake_minimum_required (VERSION 2.8.12)
cmake_minimum_required(VERSION 3.16.0)
cmake_policy (SET CMP0003 OLD)
cmake_policy (SET CMP0002 OLD)
cmake_policy (SET CMP0011 NEW)
cmake_policy (SET CMP0015 NEW)
project (awesomewidgets)
set (PROJECT_AUTHOR "Evgeniy Alekseev")
set (PROJECT_CONTACT "esalexeev@gmail.com")
set (PROJECT_LICENSE "GPLv3")
set (PROJECT_VERSION_MAJOR 2)
set (PROJECT_VERSION_MINOR 2)
set (PROJECT_VERSION_PATCH 2)
set (PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
string (TIMESTAMP CURRENT_DATE "%Y-%m-%d %H:%M" UTC)
string (TIMESTAMP CURRENT_YEAR "%Y")
message (STATUS "Project: ${PROJECT_NAME}")
message (STATUS "Version: ${PROJECT_VERSION}")
message (STATUS "Build date: ${CURRENT_DATE}")
# flags
if (CMAKE_COMPILER_IS_GNUCXX)
set (CMAKE_CXX_FLAGS "-Wall -Wno-cpp -std=c++11")
set (CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set (CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
# avoid newer gcc warnings
add_definitions (-D_DEFAULT_SOURCE)
else ()
message (STATUS "Unknown compiler")
# some fucking magic
cmake_policy(SET CMP0011 NEW)
cmake_policy(SET CMP0015 NEW)
if (POLICY CMP0063)
cmake_policy(SET CMP0063 NEW)
endif ()
if (CMAKE_BUILD_TYPE MATCHES Debug)
set (CMAKE_VERBOSE_MAKEFILE ON)
if (POLICY CMP0071)
cmake_policy(SET CMP0071 NEW)
endif ()
configure_file (${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
set (PROJECT_TRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty)
project(awesomewidgets)
set(PROJECT_AUTHOR "Evgeniy Alekseev")
set(PROJECT_CONTACT "esalexeev@gmail.com")
set(PROJECT_LICENSE "GPL3")
set(PROJECT_VERSION_MAJOR "3")
set(PROJECT_VERSION_MINOR "5")
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)
add_subdirectory (extsysmon)
add_subdirectory (awesome-widget)
add_subdirectory (desktop-panel)
string(TIMESTAMP CURRENT_DATE "%Y-%m-%d %H:%M" UTC)
string(TIMESTAMP CURRENT_YEAR "%Y")
# translations
add_subdirectory (translations)
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_LOAD "Build with additional load" OFF)
option(BUILD_TESTING "Build with additional test abilities" OFF)
# generate changelog
set(PROJECT_CHANGELOG "Changelog" CACHE INTERNAL "")
include(changelog.cmake)
# directories
set(PROJECT_TRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty)
set(PROJECT_LIBRARY awesomewidgets)
set(PROJECT_MONITORSOURCES extsysmonsources)
# modules
include(compiler.cmake)
include(libraries.cmake)
include(clang-format.cmake)
include(cppcheck.cmake)
include(coverity.cmake)
# pre-configure
get_directory_property(CMAKE_DEFINITIONS COMPILE_DEFINITIONS)
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
# build components
add_subdirectory(awesomewidgets)
add_subdirectory(extsysmonsources)
add_subdirectory(extsysmon)
if (BUILD_PLASMOIDS)
add_subdirectory(qml)
add_subdirectory(awesome-widget)
add_subdirectory(desktop-panel)
add_subdirectory(translations)
endif ()
if (BUILD_TESTING)
enable_testing()
add_subdirectory(test)
endif ()
include(packages-recipe.cmake)

130
sources/awdebug.cpp Normal file
View File

@ -0,0 +1,130 @@
/***************************************************************************
* 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 <KI18n/KLocalizedString>
#include "awdebug.h"
Q_LOGGING_CATEGORY(LOG_AW, "org.kde.plasma.awesomewidget", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_DBUS, "org.kde.plasma.awdbus", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_DP, "org.kde.plasma.desktoppanel", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_ESM, "org.kde.plasma.extsysmon", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_ESS, "org.kde.plasma.extsysmonsources", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_LIB, "org.kde.plasma.awesomewidgets", QtMsgType::QtWarningMsg)
QString AWDebug::getAboutText(const QString &_type)
{
QString text;
if (_type == "header") {
text = NAME;
} else if (_type == "version") {
text = i18n("Version %1 (build date %2)", VERSION, BUILD_DATE);
if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(COMMIT_SHA);
} else if (_type == "description") {
text = i18n("A set of minimalistic plasmoid widgets");
} else if (_type == "links") {
text = i18n("Links:") + "<ul>" + QString("<li><a href=\"%1\">%2</a></li>").arg(HOMEPAGE).arg(i18n("Homepage"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(REPOSITORY).arg(i18n("Repository"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(BUGTRACKER).arg(i18n("Bugtracker"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(TRANSLATION).arg(i18n("Translation issue"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(AUR_PACKAGES).arg(i18n("AUR packages"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(OPENSUSE_PACKAGES).arg(i18n("openSUSE packages"))
+ "</ul>";
} else if (_type == "copy") {
text = QString("<small>&copy; %1 <a href=\"mailto:%2\">%3</a><br>").arg(DATE).arg(EMAIL).arg(AUTHOR)
+ i18nc("This software is licensed under %1", LICENSE) + "</small>";
} else if (_type == "translators") {
QStringList translatorList = QString(TRANSLATORS).split(',');
for (auto &translator : translatorList)
translator = QString("<li>%1</li>").arg(translator);
text = i18n("Translators:") + "<ul>" + translatorList.join("") + "</ul>";
} else if (_type == "3rdparty") {
QStringList trdPartyList = QString(TRDPARTY_LICENSE).split(';', Qt::SkipEmptyParts);
for (int i = 0; i < trdPartyList.count(); i++)
trdPartyList[i] = QString("<li><a href=\"%3\">%1</a> (%2 license)</li>")
.arg(trdPartyList.at(i).split(',')[0])
.arg(trdPartyList.at(i).split(',')[1])
.arg(trdPartyList.at(i).split(',')[2]);
text = i18n("This software uses:") + "<ul>" + trdPartyList.join("") + "</ul>";
} else if (_type == "thanks") {
QStringList thanks = QString(SPECIAL_THANKS).split(';', Qt::SkipEmptyParts);
for (int i = 0; i < thanks.count(); i++)
thanks[i] = QString("<li><a href=\"%2\">%1</a></li>")
.arg(thanks.at(i).split(',')[0])
.arg(thanks.at(i).split(',')[1]);
text = i18n("Special thanks to:") + "<ul>" + thanks.join("") + "</ul>";
}
return text;
}
QStringList AWDebug::getBuildData()
{
QStringList metadata;
metadata.append("=== Awesome Widgets configuration details ===");
// build information
metadata.append("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("API details:");
metadata.append(QString(" AW_GRAPHITEM_API: %1").arg(AW_GRAPHITEM_API));
metadata.append(QString(" AW_EXTQUOTES_API: %1").arg(AW_EXTQUOTES_API));
metadata.append(QString(" AW_EXTSCRIPT_API: %1").arg(AW_EXTSCRIPT_API));
metadata.append(QString(" AW_EXTUPGRADE_API: %1").arg(AW_EXTUPGRADE_API));
metadata.append(QString(" AW_EXTWEATHER_API: %1").arg(AW_EXTWEATHER_API));
metadata.append(QString(" AW_FORMATTER_API: %1").arg(AW_FORMATTER_API));
metadata.append(QString(" REQUEST_TIMEOUT: %1").arg(REQUEST_TIMEOUT));
metadata.append(QString(" TIME_KEYS: %1").arg(TIME_KEYS));
metadata.append(QString(" STATIC_KEYS: %1").arg(STATIC_KEYS));
// cmake properties
metadata.append("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("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(" COVERITY_COMMENT: %1").arg(COVERITY_COMMENT));
metadata.append(QString(" COVERITY_DIRECTORY: %1").arg(COVERITY_DIRECTORY));
metadata.append(QString(" COVERITY_EMAIL: %1").arg(COVERITY_EMAIL));
metadata.append(QString(" COVERITY_EXECUTABLE: %1").arg(COVERITY_EXECUTABLE));
metadata.append(QString(" COVERITY_URL: %1").arg(COVERITY_URL));
metadata.append(QString(" CPPCHECK_EXECUTABLE: %1").arg(CPPCHECK_EXECUTABLE));
// additional functions
metadata.append(QString(" PROP_FUTURE: %1").arg(PROP_FUTURE));
metadata.append(QString(" PROP_LOAD: %1").arg(PROP_LOAD));
metadata.append(QString(" PROP_TEST: %1").arg(PROP_TEST));
return metadata;
}

47
sources/awdebug.h Normal file
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 AWDEBUG_H
#define AWDEBUG_H
#include <QLoggingCategory>
#include "version.h"
namespace AWDebug
{
const char LOG_FORMAT[] = "[%{time "
"process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%"
"{if-warning}WW%{endif}%{if-critical}CC%{endif}%{if-"
"fatal}FF%{endif}][%{category}][%{function}] "
"%{message}";
QString getAboutText(const QString &_type);
QStringList getBuildData();
} // namespace AWDebug
Q_DECLARE_LOGGING_CATEGORY(LOG_AW)
Q_DECLARE_LOGGING_CATEGORY(LOG_DBUS)
Q_DECLARE_LOGGING_CATEGORY(LOG_DP)
Q_DECLARE_LOGGING_CATEGORY(LOG_ESM)
Q_DECLARE_LOGGING_CATEGORY(LOG_ESS)
Q_DECLARE_LOGGING_CATEGORY(LOG_LIB)
#endif /* AWDEBUG_H */

View File

@ -1,19 +1,7 @@
# set project name
set (SUBPROJECT plasma_applet_awesome-widget)
message (STATUS "Subproject ${SUBPROJECT}")
set(SUBPROJECT plasma_applet_awesome-widget)
message(STATUS "Subproject ${SUBPROJECT}")
# prepare
configure_file (metadata.desktop ${CMAKE_CURRENT_SOURCE_DIR}/package/metadata.desktop)
configure_file(metadata.desktop ${CMAKE_CURRENT_SOURCE_DIR}/package/metadata.desktop)
find_package (ECM 0.0.12 REQUIRED NO_MODULE)
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
find_package (Qt5 REQUIRED COMPONENTS Core Network Qml Xml)
find_package (KF5 REQUIRED COMPONENTS I18n Notifications Plasma)
include (KDEInstallDirs)
include (KDECMakeSettings)
include (KDECompilerSettings)
add_subdirectory (plugin)
plasma_install_package (package org.kde.plasma.awesomewidget)
add_subdirectory(plugin)
plasma_install_package(package org.kde.plasma.awesomewidget)

View File

@ -15,14 +15,12 @@ Icon=utilities-system-monitor
X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
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=@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
X-KDE-PluginInfo-EnabledByDefault=true

View File

@ -3,126 +3,156 @@
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="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>
</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>
<entry name="telemetryCount" type="int">
<default>100</default>
</entry>
<entry name="telemetryRemote" type="bool">
<default>false</default>
</entry>
<entry name="telemetryId" 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>
<entry name="textStyle" type="string">
<default>normal</default>
</entry>
<entry name="textStyleColor" type="string">
<default>#000000</default>
</entry>
</group>
</kcfg>

View File

@ -16,84 +16,27 @@
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import QtQuick.Layouts 1.0 as QtLayouts
import org.kde.plasma.awesomewidget 1.0
import org.kde.plasma.private.awesomewidget 1.0
Item {
id: aboutPage
// backend
AWActions {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: AWKeys.isDebugEnabled()
property bool debug: awActions.isDebugEnabled()
Column {
id: pageColumn
anchors.fill: parent
QtControls.TabView {
height: parent.height
width: parent.width
QtControls.Tab {
title: i18n("About")
QtLayouts.ColumnLayout {
QtControls.Label {
QtLayouts.Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
text: AWActions.getAboutText("header")
}
QtControls.Label {
QtLayouts.Layout.fillWidth: true
horizontalAlignment: Text.AlignJustify
text: AWActions.getAboutText("description")
}
QtControls.Label {
QtLayouts.Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft
textFormat: Text.RichText
text: AWActions.getAboutText("links")
}
QtControls.Label {
QtLayouts.Layout.fillWidth: true
font.capitalization: Font.SmallCaps
horizontalAlignment: Text.AlignHCenter
textFormat: Text.RichText
text: AWActions.getAboutText("copy")
}
}
}
QtControls.Tab {
title: i18n("Acknowledgment")
QtLayouts.ColumnLayout {
QtControls.Label {
QtLayouts.Layout.fillWidth: true
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignJustify
text: AWActions.getAboutText("translators")
}
QtControls.Label {
QtLayouts.Layout.fillWidth: true
horizontalAlignment: Text.AlignJustify
textFormat: Text.RichText
text: AWActions.getAboutText("3rdparty")
}
}
}
}
AboutTab {
textProvider: awActions
}
Component.onCompleted: {
if (debug) console.log("[about::onCompleted]")
if (debug) console.debug()
}
}

View File

@ -18,225 +18,245 @@
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import org.kde.plasma.awesomewidget 1.0
import org.kde.plasma.private.awesomewidget 1.0
Item {
id: advancedPage
// backend
AWActions {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: AWKeys.isDebugEnabled()
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_background: background.checked
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_interval: update.value
property alias cfg_queueLimit: queueLimit.value
property string cfg_tempUnits: tempUnits.value
property alias cfg_customTime: customTime.value
property alias cfg_customUptime: customUptime.value
property alias cfg_acOnline: acOnline.value
property alias cfg_acOffline: acOffline.value
property alias cfg_telemetryCount: telemetryCount.value
property alias cfg_telemetryRemote: telemetryRemote.checked
property alias cfg_telemetryId: telemetryId.value
Column {
id: pageColumn
anchors.fill: parent
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Widget height, px")
}
QtControls.SpinBox {
id: widgetHeight
width: parent.width * 3 / 5
minimumValue: 0
maximumValue: 4096
stepSize: 50
value: plasmoid.configuration.height
}
CheckBoxSelector {
id: background
text: i18n("Enable 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("Widget width, px")
}
QtControls.SpinBox {
id: widgetWidth
width: parent.width * 3 / 5
minimumValue: 0
maximumValue: 4096
stepSize: 50
value: plasmoid.configuration.width
}
CheckBoxSelector {
id: translate
text: i18n("Translate strings")
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: notify
width: parent.width * 3 / 5
text: i18n("Enable notifications")
}
CheckBoxSelector {
id: wrapNewLines
text: i18n("Wrap new lines")
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: background
width: parent.width * 3 / 5
text: i18n("Enable background")
}
CheckBoxSelector {
id: wordWrap
text: i18n("Enable word wrap")
}
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
}
CheckBoxSelector {
id: notify
text: i18n("Enable notifications")
}
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
}
CheckBoxSelector {
id: updates
text: i18n("Check updates on startup")
}
Row {
CheckBoxSelector {
id: optimize
text: i18n("Optimize subscription")
}
IntegerSelector {
id: widgetHeight
maximumValue: 4096
minimumValue: 0
stepSize: 50
text: i18n("Widget height, px")
value: plasmoid.configuration.height
}
IntegerSelector {
id: widgetWidth
maximumValue: 4096
minimumValue: 0
stepSize: 50
text: i18n("Widget width, px")
value: plasmoid.configuration.width
}
IntegerSelector {
id: update
maximumValue: 10000
minimumValue: 1000
stepSize: 500
text: i18n("Time interval")
value: plasmoid.configuration.interval
}
IntegerSelector {
id: queueLimit
maximumValue: 99
minimumValue: 0
stepSize: 1
text: i18n("Messages queue limit")
value: plasmoid.configuration.queueLimit
}
ComboBoxSelector {
id: tempUnits
model: [
{
'label': i18n("Celsius"),
'name': "Celsius"
},
{
'label': i18n("Fahrenheit"),
'name': "Fahrenheit"
},
{
'label': i18n("Kelvin"),
'name': "Kelvin"
},
{
'label': i18n("Reaumur"),
'name': "Reaumur"
},
{
'label': i18n("cm^-1"),
'name': "cm^-1"
},
{
'label': i18n("kJ/mol"),
'name': "kJ/mol"
},
{
'label': i18n("kcal/mol"),
'name': "kcal/mol"
}
]
text: i18n("Temperature units")
value: plasmoid.configuration.tempUnits
onValueEdited: cfg_tempUnits = newValue
}
LineSelector {
id: customTime
text: i18n("Custom time format")
value: plasmoid.configuration.customTime
}
LineSelector {
id: customUptime
text: i18n("Custom uptime format")
value: plasmoid.configuration.customUptime
}
LineSelector {
id: acOnline
text: i18n("AC online tag")
value: plasmoid.configuration.acOnline
}
LineSelector {
id: acOffline
text: i18n("AC offline tag")
value: plasmoid.configuration.acOffline
}
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Temperature units")
}
QtControls.ComboBox {
id: tempUnits
width: parent.width * 3 / 5
textRole: "label"
model: [
{
'label': i18n("Celsius"),
'name': "Celsius"
},
{
'label': i18n("Fahrenheit"),
'name': "Fahrenheit"
},
{
'label': i18n("Kelvin"),
'name': "Kelvin"
},
{
'label': i18n("Reaumur"),
'name': "Reaumur"
},
{
'label': i18n("cm^-1"),
'name': "cm^-1"
},
{
'label': i18n("kJ/mol"),
'name': "kJ/mol"
},
{
'label': i18n("kcal/mol"),
'name': "kcal/mol"
title: i18n("Actions")
Column {
height: implicitHeight
width: parent.width
ButtonSelector {
value: i18n("Drop key cache")
onButtonActivated: awActions.dropCache()
}
ButtonSelector {
ExportDialog {
id: saveConfigAs
configuration: plasmoid.configuration
}
]
onCurrentIndexChanged: cfg_tempUnits = model[currentIndex]["name"]
Component.onCompleted: {
for (var i = 0; i < model.length; i++) {
if (model[i]["name"] == plasmoid.configuration.tempUnits) {
tempUnits.currentIndex = i;
value: i18n("Export configuration")
onButtonActivated: saveConfigAs.open()
}
ButtonSelector {
ImportDialog {
id: loadConfigFrom
onConfigurationReceived: {
for (var key in configuration)
plasmoid.configuration[key] = configuration[key]
}
}
value: i18n("Import configuration")
onButtonActivated: loadConfigFrom.open()
}
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("AC online tag")
}
QtControls.TextField {
id: acOnline
width: parent.width * 3 / 5
text: plasmoid.configuration.acOnline
}
}
title: i18n("Telemetry")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("AC offline tag")
}
QtControls.TextField {
id: acOffline
width: parent.width * 3 / 5
text: plasmoid.configuration.acOffline
Column {
height: implicitHeight
width: parent.width
CheckBoxSelector {
id: telemetryRemote
text: i18n("Enable remote telemetry")
}
IntegerSelector {
id: telemetryCount
maximumValue: 10000
minimumValue: 0
stepSize: 50
text: i18n("History count")
value: plasmoid.configuration.telemetryCount
}
LineSelector {
id: telemetryId
text: i18n("Telemetry ID")
value: plasmoid.configuration.telemetryId
}
}
}
}
Component.onCompleted: {
if (debug) console.log("[advanced::onCompleted]")
if (debug) console.debug()
}
}

View File

@ -16,21 +16,24 @@
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import QtQuick.Controls.Styles 1.3 as QtStyles
import QtQuick.Dialogs 1.1 as QtDialogs
import org.kde.plasma.awesomewidget 1.0
import org.kde.plasma.private.awesomewidget 1.0
import "."
Item {
id: appearancePage
// backend
AWActions {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: AWKeys.isDebugEnabled()
property bool debug: awActions.isDebugEnabled()
property variant weight: {
25: 0,
50: 1,
@ -39,201 +42,73 @@ Item {
87: 5
}
property alias cfg_interval: update.value
property alias cfg_fontFamily: selectFont.text
property alias cfg_fontFamily: font.value
property alias cfg_fontSize: fontSize.value
property string cfg_fontWeight: fontWeight.currentText
property string cfg_fontStyle: fontStyle.currentText
property alias cfg_fontColor: selectColor.text
property string cfg_fontWeight: fontWeight.value
property string cfg_fontStyle: fontStyle.value
property alias cfg_fontColor: selectColor.value
property alias cfg_textStyleColor: selectStyleColor.value
property string cfg_textStyle: textStyle.value
Column {
id: pageColumn
anchors.fill: parent
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width / 3
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Time interval")
}
QtControls.SpinBox {
id: update
width: parent.width * 2 / 3
minimumValue: 1000
maximumValue: 10000
stepSize: 500
value: plasmoid.configuration.interval
}
FontSelector {
id: font
text: i18n("Font")
value: plasmoid.configuration.fontFamily
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width / 3
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Font")
}
QtControls.Button {
id: selectFont
width: parent.width * 2 / 3
text: plasmoid.configuration.fontFamily
onClicked: fontDialog.visible = true
}
IntegerSelector {
id: fontSize
maximumValue: 32
minimumValue: 8
stepSize: 1
text: i18n("Font size")
value: plasmoid.configuration.fontSize
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width / 3
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Font size")
}
QtControls.SpinBox {
id: fontSize
width: parent.width * 2 / 3
minimumValue: 8
maximumValue: 32
stepSize: 1
value: plasmoid.configuration.fontSize
}
ComboBoxSelector {
id: fontWeight
model: General.fontWeightModel
text: i18n("Font weight")
value: plasmoid.configuration.fontWeight
onValueEdited: cfg_fontWeight = newValue
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width / 3
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Font weight")
}
QtControls.ComboBox {
id: fontWeight
width: parent.width * 2 / 3
textRole: "label"
model: [
{
'label': i18n("light"),
'name': "light"
},
{
'label': i18n("normal"),
'name': "normal"
},
{
'label': i18n("demi bold"),
'name': "demibold"
},
{
'label': i18n("bold"),
'name': "bold"
},
{
'label': i18n("black"),
'name': "black"
}
]
onCurrentIndexChanged: cfg_fontWeight = model[currentIndex]["name"]
Component.onCompleted: {
for (var i = 0; i < model.length; i++) {
if (model[i]["name"] == plasmoid.configuration.fontWeight) {
fontWeight.currentIndex = i;
}
}
}
}
ComboBoxSelector {
id: fontStyle
model: General.fontStyleModel
text: i18n("Font style")
value: plasmoid.configuration.fontStyle
onValueEdited: cfg_fontStyle = newValue
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width / 3
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Font style")
}
QtControls.ComboBox {
id: fontStyle
width: parent.width * 2 / 3
textRole: "label"
model: [
{
'label': i18n("normal"),
'name': "normal"
},
{
'label': i18n("italic"),
'name': "italic"
}
]
onCurrentIndexChanged: cfg_fontStyle = model[currentIndex]["name"]
Component.onCompleted: {
for (var i = 0; i < model.length; i++) {
if (model[i]["name"] == plasmoid.configuration.fontStyle) {
fontStyle.currentIndex = i;
}
}
}
}
ColorSelector {
id: selectColor
text: i18n("Font color")
value: plasmoid.configuration.fontColor
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width / 3
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Font color")
}
QtControls.Button {
id: selectColor
width: parent.width * 2 / 3
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.fontColor
}
}
text: plasmoid.configuration.fontColor
onClicked: colorDialog.visible = true
}
ComboBoxSelector {
id: textStyle
model: General.textStyleModel
text: i18n("Style")
value: plasmoid.configuration.textStyle
onValueEdited: cfg_textStyle = newValue
}
ColorSelector {
id: selectStyleColor
text: i18n("Style color")
value: plasmoid.configuration.textStyleColor
}
}
QtDialogs.ColorDialog {
id: colorDialog
title: i18n("Select a color")
color: selectColor.text
onAccepted: selectColor.text = colorDialog.color
}
QtDialogs.FontDialog {
id: fontDialog
title: i18n("Select a font")
font: Qt.font({ family: selectFont.text, pointSize: fontSize.value, weight: Font.Normal })
onAccepted: {
selectFont.text = fontDialog.font.family
fontSize.value = fontDialog.font.pointSize
fontStyle.currentIndex = fontDialog.font.italic ? 1 : 0
fontWeight.currentIndex = weight[fontDialog.font.weight]
}
}
Component.onCompleted: {
if (debug) console.log("[appearance::onCompleted]")
if (debug) console.debug()
}
}

View File

@ -16,273 +16,249 @@
***************************************************************************/
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.awesomewidget 1.0
import org.kde.plasma.private.awesomewidget 1.0
Item {
id: dataenginePage
// backend
AWKeys {
id: awKeys
}
AWActions {
id: awActions
}
AWConfigHelper {
id: awConfig
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: AWKeys.isDebugEnabled()
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 bool debug: awActions.isDebugEnabled()
property variant cfg_dataengine: awConfig.readDataEngineConfiguration()
property variant cfg_dataengine: AWActions.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
title: i18n("ACPI")
LineSelector {
text: i18n("ACPI path")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["ACPIPATH"]
value: cfg_dataengine["ACPIPATH"]
onValueEdited: cfg_dataengine["ACPIPATH"] = newValue
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom 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
title: i18n("GPU")
ComboBoxSelector {
model: [
{
'label': "auto",
'name': "auto"
},
{
'label': "disable",
'name': "disable"
},
{
'label': "ati",
'name': "ati"
},
{
'label': "nvidia",
'name': "nvidia"
}
]
text: i18n("GPU device")
value: cfg_dataengine["GPUDEV"]
onValueEdited: cfg_dataengine["GPUDEV"] = newValue
}
QtControls.ComboBox {
id: gpuDev
width: parent.width * 3 / 5
model: ["auto", "disable", "ati", "nvidia"]
Component.onCompleted: {
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["GPUDEV"]) {
currentIndex = i;
}
}
}
QtControls.GroupBox {
height: implicitHeight
width: parent.width
title: i18n("HDD temperature")
Column {
height: implicitHeight
width: parent.width
ComboBoxSelector {
id: hdd
text: i18n("HDD")
value: cfg_dataengine["HDDDEV"]
onValueEdited: cfg_dataengine["HDDDEV"] = newValue
}
LineSelector {
text: i18n("hddtemp cmd")
value: cfg_dataengine["HDDTEMPCMD"]
onValueEdited: cfg_dataengine["HDDTEMPCMD"] = newValue
}
}
}
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: {
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["HDDDEV"]) {
hdd.currentIndex = i;
title: i18n("Player")
Column {
height: implicitHeight
width: parent.width
IntegerSelector {
maximumValue: 100
minimumValue: 1
stepSize: 1
text: i18n("Player data symbols")
value: cfg_dataengine["PLAYERSYMBOLS"]
onValueEdited: cfg_dataengine["PLAYERSYMBOLS"] = newValue
}
ComboBoxSelector {
model: [
{
'label': "disable",
'name': "disable"
},
{
'label': "mpris",
'name': "mpris"
},
{
'label': "mpd",
'name': "mpd"
}
}
]
text: i18n("Music player")
value: cfg_dataengine["PLAYER"]
onValueEdited: cfg_dataengine["PLAYER"] = newValue
}
ComboBoxSelector {
id: mpris
editable: true
model: [
{
'label': 'auto',
'name': 'auto'
},
{
'label': 'amarok',
'name': 'amarok'
},
{
'label': 'audacious',
'name': 'audacious'
},
{
'label': 'clementine',
'name': 'clementine'
},
{
'label': 'DeaDBeeF',
'name': 'DeaDBeeF'
},
{
'label': 'vlc',
'name': 'vlc'
},
{
'label': 'qmmp',
'name': 'qmmp'
},
{
'label': 'xmms2',
'name': 'xmms2'
},
{
'label': cfg_dataengine["MPRIS"],
'name': cfg_dataengine["MPRIS"]
}
]
text: i18n("MPRIS player name")
currentIndex: model.length - 1
}
LineSelector {
text: i18n("MPD address")
value: cfg_dataengine["MPDADDRESS"]
onValueEdited: cfg_dataengine["MPDADDRESS"] = newValue
}
IntegerSelector {
maximumValue: 65535
minimumValue: 1000
stepSize: 1
text: i18n("MPD port")
value: cfg_dataengine["MPDPORT"]
onValueEdited: cfg_dataengine["MPDPORT"] = newValue
}
}
}
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"]
}
}
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"]
}
}
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"]
}
}
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: ["mpris", "mpd"]
Component.onCompleted: {
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["PLAYER"]) {
player.currentIndex = i;
}
}
title: i18n("Extensions")
Column {
height: implicitHeight
width: parent.width
ButtonSelector {
value: i18n("Custom scripts")
onButtonActivated: 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")
}
}
ButtonSelector {
value: i18n("Network requests")
onButtonActivated: awKeys.editItem("extnetworkrequest")
}
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")
ButtonSelector {
value: i18n("Package manager")
onButtonActivated: awKeys.editItem("extupgrade")
}
ButtonSelector {
value: i18n("Quotes monitor")
onButtonActivated: awKeys.editItem("extquotes")
}
ButtonSelector {
value: i18n("Weather")
onButtonActivated: awKeys.editItem("extweather")
}
}
}
}
Component.onCompleted: {
if (debug) console.log("[dataengine::onCompleted]")
if (debug) console.debug()
// init submodule
AWKeys.initKeys(plasmoid.configuration.text, tooltipSettings)
awKeys.updateCache()
// update hdd model
hdd.model = awKeys.getHddDevices()
hdd.onCompleted
}
Component.onDestruction: {
if (debug) console.log("[dataengine::onDestruction]")
if (debug) console.debug()
cfg_dataengine["GPUDEV"] = gpuDev.currentText
cfg_dataengine["HDDDEV"] = hdd.currentText
cfg_dataengine["PLAYER"] = player.currentText
cfg_dataengine["MPRIS"] = mpris.currentText
AWActions.writeDataEngineConfiguration(cfg_dataengine)
cfg_dataengine["MPRIS"] = mpris.editText
awConfig.writeDataEngineConfiguration(cfg_dataengine)
}
}

View File

@ -17,26 +17,33 @@
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
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.awesomewidget 1.0
import org.kde.plasma.private.awesomewidget 1.0
import "."
Item {
id: main
property bool debug: AWKeys.isDebugEnabled()
property variant settings: {
"customTime": plasmoid.configuration.customTime,
"customUptime": plasmoid.configuration.customUptime,
"tempUnits": plasmoid.configuration.tempUnits,
"acOnline": plasmoid.configuration.acOnline,
"acOffline": plasmoid.configuration.acOffline
// backend
AWKeys {
id: awKeys
}
AWActions {
id: awActions
}
AWTelemetryHandler {
id: awTelemetryHandler
}
BugReport {
id: bugReport
}
property bool debug: awActions.isDebugEnabled()
property variant tooltipSettings: {
"tooltipNumber": plasmoid.configuration.tooltipNumber,
"useTooltipBackground": plasmoid.configuration.useTooltipBackground,
@ -45,20 +52,25 @@ 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
"batInTooltipColor": plasmoid.configuration.batInTooltipColor,
// additional field to parse AC status
"acOnline": plasmoid.configuration.acOnline,
// additional field to send notifications
"notify": plasmoid.configuration.notify
}
signal needUpdate
signal needTextUpdate(string newText)
signal needToolTipUpdate(string newText)
signal sizeUpdate
@ -74,73 +86,26 @@ 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.log("[main::onNewData] : Update source " + sourceName)
// FIXME: ugly workaround to make some sources working
systemmonitorDE.interval = plasmoid.configuration.interval
if (AWKeys.setDataBySource(sourceName, data, settings)) disconnectSource(sourceName)
}
onSourceAdded: {
if (debug) console.log("[main::onSourceAdded] : Source " + source)
AWKeys.addDevice(source)
}
}
PlasmaCore.DataSource {
id: extsysmonDE
engine: "extsysmon"
connectedSources: extsysmonDE.sources
interval: plasmoid.configuration.interval
onNewData: {
if (debug) console.log("[main::onNewData] : Update source " + sourceName)
// FIXME: ugly workaround to make some sources working
extsysmonDE.interval = plasmoid.configuration.interval
if (AWKeys.setDataBySource(sourceName, data, settings)) needUpdate()
}
}
PlasmaCore.DataSource {
id: timeDE
engine: "time"
connectedSources: ["Local"]
interval: 1000
onNewData: {
if (debug) console.log("[main::onNewData] : Update source " + sourceName)
AWKeys.setDataBySource(sourceName, data, settings)
}
}
// ui
Text {
id: text
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]
horizontalAlignment: General.align[plasmoid.configuration.textAlign]
verticalAlignment: Text.AlignVCenter
color: plasmoid.configuration.fontColor
font.family: plasmoid.configuration.fontFamily
font.italic: plasmoid.configuration.fontStyle == "italic" ? true : false
font.pointSize: plasmoid.configuration.fontSize
font.weight: general.fontWeight[plasmoid.configuration.fontWeight]
font.weight: General.fontWeight[plasmoid.configuration.fontWeight]
text: plasmoid.configuration.text
style: General.textStyle[plasmoid.configuration.textStyle]
styleColor: plasmoid.configuration.textStyleColor
PlasmaCore.ToolTipArea {
height: tooltip.height
@ -154,39 +119,74 @@ Item {
}
}
Component.onCompleted: {
if (debug) console.log("[main::onCompleted]")
QtDialogs.Dialog {
id: tagSelector
title: i18n("Select tag")
// actions
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)
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)
}
}
onNeedUpdate: {
if (debug) console.log("[main::onNeedUpdate]")
text.text = AWKeys.parsePattern()
tooltip.text = AWKeys.toolTipImage()
Component.onCompleted: {
if (debug) console.debug()
// actions
// it makes no sense to use this field with optimization enable
if (!plasmoid.configuration.optimize)
plasmoid.setAction("requestKey", i18n("Request key"), "utilities-system-monitor")
plasmoid.setAction("showReadme", i18n("Show README"), "text-x-readme")
plasmoid.setAction("checkUpdates", i18n("Check updates"), "system-software-update")
plasmoid.setAction("reportBug", i18n("Report bug"), "tools-report-bug")
// init submodule
Plasmoid.userConfiguringChanged(false)
// connect data
awKeys.needTextToBeUpdated.connect(needTextUpdate)
awKeys.needToolTipToBeUpdated.connect(needToolTipUpdate)
// check updates if required
if (plasmoid.configuration.checkUpdates) return awActions.checkUpdates(false)
}
onNeedTextUpdate: {
if (debug) console.debug()
text.text = newText
sizeUpdate()
}
onNeedToolTipUpdate: {
if (debug) console.debug()
tooltip.text = newText
}
onSizeUpdate: {
if (debug) console.log("[main::onSizeUpdate]")
if (debug) console.debug()
// 16 is a magic number
// in other case plasmoid will increase own size on each update
if (plasmoid.configuration.height == 0) {
Layout.minimumHeight = text.contentHeight
Layout.minimumHeight = text.contentHeight - 16
Layout.maximumHeight = -1
} else {
Layout.minimumHeight = plasmoid.configuration.height
Layout.maximumHeight = plasmoid.configuration.height
}
if (plasmoid.configuration.width == 0) {
Layout.minimumWidth = text.contentWidth
Layout.minimumWidth = text.contentWidth - 16
Layout.maximumWidth = -1
} else {
Layout.minimumWidth = plasmoid.configuration.width
@ -196,35 +196,63 @@ Item {
Plasmoid.onUserConfiguringChanged: {
if (plasmoid.userConfiguring) return
if (debug) console.log("[main::onUserConfiguringChanged]")
if (debug) console.debug()
// init submodule
AWKeys.initKeys(plasmoid.configuration.text, tooltipSettings, plasmoid.configuration.notify)
needUpdate()
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)
// update telemetry ID
if (plasmoid.configuration.telemetryId.length == 0)
plasmoid.configuration.telemetryId = generateUuid()
// save telemetry
awTelemetryHandler.init(plasmoid.configuration.telemetryCount,
plasmoid.configuration.telemetryRemote,
plasmoid.configuration.telemetryId)
if (awTelemetryHandler.put("awwidgetconfig", plasmoid.configuration.text))
awTelemetryHandler.uploadTelemetry("awwidgetconfig", plasmoid.configuration.text)
}
function action_checkUpdates() {
if (debug) console.log("[main::action_checkUpdates]")
AWActions.checkUpdates()
function action_checkUpdates() {
if (debug) console.debug()
return awActions.checkUpdates(true)
}
function action_showReadme() {
if (debug) console.log("[main::action_showReadme]")
if (debug) console.debug()
AWActions.showReadme()
return awActions.showReadme()
}
function action_report() {
if (debug) console.log("[main::action_report]")
function action_reportBug() {
if (debug) console.debug()
AWActions.sendEmail()
bugReport.reset()
bugReport.open()
}
function action_requestKey() {
if (debug) console.log("[main::action_requestKey]")
if (debug) console.debug()
AWKeys.graphicalValueByKey()
tagSelectorBox.model = awKeys.dictKeys(true)
return tagSelector.open()
}
// code from http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
function generateUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
}

View File

@ -1 +1,27 @@
singleton general general.qml
# Do not edit qmldir directly it will be overrided during compilation,
# edit qml/qmldir.in file instead.
# common QML constants
singleton General 1.0 file:///usr/share/awesomewidgets/qml/General.qml
# custom QML UI classes
AboutTab file:///usr/share/awesomewidgets/qml/AboutTab.qml
AWExtensions file:///usr/share/awesomewidgets/qml/AWExtensions.qml
AWInfoLabel file:///usr/share/awesomewidgets/qml/AWInfoLabel.qml
AWTagSelector file:///usr/share/awesomewidgets/qml/AWTagSelector.qml
AWTextEditor file:///usr/share/awesomewidgets/qml/AWTextEditor.qml
BugReport file:///usr/share/awesomewidgets/qml/BugReport.qml
ButtonSelector file:///usr/share/awesomewidgets/qml/ButtonSelector.qml
CheckBoxSelector file:///usr/share/awesomewidgets/qml/CheckBoxSelector.qml
ColorSelector file:///usr/share/awesomewidgets/qml/ColorSelector.qml
ComboBoxSelector file:///usr/share/awesomewidgets/qml/ComboBoxSelector.qml
ExportDialog file:///usr/share/awesomewidgets/qml/ExportDialog.qml
FontSelector file:///usr/share/awesomewidgets/qml/FontSelector.qml
HtmlDefaultFunctionsBar file:///usr/share/awesomewidgets/qml/HtmlDefaultFunctionsBar.qml
HtmlEditorButton file:///usr/share/awesomewidgets/qml/HtmlEditorButton.qml
HtmlEditorColor file:///usr/share/awesomewidgets/qml/HtmlEditorColor.qml
HtmlEditorFont file:///usr/share/awesomewidgets/qml/HtmlEditorFont.qml
ImportDialog file:///usr/share/awesomewidgets/qml/ImportDialog.qml
IntegerSelector file:///usr/share/awesomewidgets/qml/IntegerSelector.qml
LineSelector file:///usr/share/awesomewidgets/qml/LineSelector.qml

View File

@ -17,38 +17,41 @@
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import QtQuick.Controls.Styles 1.3 as QtStyles
import QtQuick.Dialogs 1.1 as QtDialogs
import org.kde.plasma.awesomewidget 1.0
import org.kde.plasma.private.awesomewidget 1.0
Item {
id: tooltipPage
// backend
AWActions {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: AWKeys.isDebugEnabled()
property bool debug: awActions.isDebugEnabled()
property alias cfg_tooltipNumber: tooltipNumber.value
property alias cfg_useTooltipBackground: useTooltipBackground.checked
property alias cfg_tooltipBackground: tooltipBackground.text
property alias cfg_tooltipBackground: tooltipBackground.value
property alias cfg_cpuTooltip: cpuTooltip.checked
property alias cfg_cpuTooltipColor: cpuTooltipColor.text
property alias cfg_cpuTooltipColor: cpuTooltipColor.value
property alias cfg_cpuclTooltip: cpuclTooltip.checked
property alias cfg_cpuclTooltipColor: cpuclTooltipColor.text
property alias cfg_cpuclTooltipColor: cpuclTooltipColor.value
property alias cfg_memTooltip: memTooltip.checked
property alias cfg_memTooltipColor: memTooltipColor.text
property alias cfg_memTooltipColor: memTooltipColor.value
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_swapTooltipColor: swapTooltipColor.value
property alias cfg_downkbTooltip: downkbTooltip.checked
property alias cfg_downkbTooltipColor: downkbTooltipColor.value
property alias cfg_upkbTooltipColor: upkbTooltipColor.value
property alias cfg_batTooltip: batTooltip.checked
property alias cfg_batTooltipColor: batTooltipColor.text
property alias cfg_batInTooltipColor: batInTooltipColor.text
property alias cfg_batTooltipColor: batTooltipColor.value
property alias cfg_batInTooltipColor: batInTooltipColor.value
Column {
@ -59,455 +62,130 @@ 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 {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Number of values for tooltips")
}
QtControls.SpinBox {
id: tooltipNumber
width: parent.width * 3 / 5
minimumValue: 50
maximumValue: 1000
stepSize: 25
value: plasmoid.configuration.tooltipNumber
}
IntegerSelector {
id: tooltipNumber
maximumValue: 1000
minimumValue: 50
stepSize: 25
text: i18n("Number of values for tooltips")
value: plasmoid.configuration.tooltipNumber
}
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"
}
}
}
}
QtControls.Button {
checkable: true
title: i18n("Background")
ColorSelector {
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
text: i18n("Background color")
value: plasmoid.configuration.tooltipBackground
}
}
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"
}
}
}
}
QtControls.Button {
checkable: true
title: i18n("CPU")
ColorSelector {
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
text: i18n("CPU color")
value: plasmoid.configuration.cpuTooltipColor
}
}
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"
}
}
}
}
QtControls.Button {
checkable: true
title: i18n("CPU clock")
ColorSelector {
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
text: i18n("CPU clock color")
value: plasmoid.configuration.cpuclTooltipColor
}
}
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"
}
}
}
}
QtControls.Button {
checkable: true
title: i18n("Memory")
ColorSelector {
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
text: i18n("Memory color")
value: plasmoid.configuration.memTooltipColor
}
}
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"
}
}
}
}
QtControls.Button {
checkable: true
title: i18n("Swap")
ColorSelector {
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
text: i18n("Swap color")
value: plasmoid.configuration.swapTooltipColor
}
}
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
ColorSelector {
id: downkbTooltipColor
text: i18n("Download speed color")
value: plasmoid.configuration.downkbTooltipColor
}
}
QtControls.Button {
id: downTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.downTooltipColor
}
ColorSelector {
id: upkbTooltipColor
text: i18n("Upload speed color")
value: plasmoid.configuration.upkbTooltipColor
}
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 {
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("Upload speed color")
}
QtControls.Button {
id: upTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.upTooltipColor
}
checkable: true
title: i18n("Battery")
Column {
height: implicitHeight
width: parent.width
ColorSelector {
id: batTooltipColor
text: i18n("Battery active color")
value: plasmoid.configuration.batTooltipColor
}
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"
}
}
ColorSelector {
id: batInTooltipColor
text: i18n("Battery inactive color")
value: plasmoid.configuration.batInTooltipColor
}
}
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
}
}
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
}
}
}
Component.onCompleted: {
if (debug) console.log("[tooltip::onCompleted]")
if (debug) console.debug()
}
}

View File

@ -15,302 +15,86 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import org.kde.plasma.core 2.0 as PlasmaCore
import QtQuick 2.2
import org.kde.plasma.awesomewidget 1.0
import org.kde.plasma.private.awesomewidget 1.0
import "."
Item {
id: widgetPage
// backend
AWKeys {
id: awKeys
}
AWActions {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: AWKeys.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 bool debug: awActions.isDebugEnabled()
property alias cfg_text: textPattern.text
property bool lock: true
signal needTextUpdate(string newText)
Column {
id: pageColumn
anchors.fill: parent
QtControls.Label {
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
text: i18n("Detailed information may be found on <a href=\"http://arcanis.name/projects/awesome-widgets/\">project homepage</a>")
AWInfoLabel {}
HtmlDefaultFunctionsBar {
textArea: textPattern
}
Row {
height: implicitHeight
width: parent.width
QtControls.Button {
text: i18n("Font")
iconName: "font"
onClicked: {
if (debug) console.log("[widget::onClicked] : Font button")
var defaultFont = {
"color": plasmoid.configuration.fontColor,
"family": plasmoid.configuration.fontFamily,
"size": plasmoid.configuration.fontSize
}
var font = AWActions.getFont(defaultFont)
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, "<span style=\"color:" + font.color +
"; font-family:'" + font.family +
"'; font-size:" + font.size + "pt;\">" +
selected + "</span>")
}
}
QtControls.Button {
iconName: "format-indent-more"
onClicked: {
if (debug) console.log("[widget::onClicked] : Indent button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, selected + "<br>\n")
}
}
QtControls.Button {
iconName: "format-text-bold"
onClicked: {
if (debug) console.log("[widget::onClicked] : Bold button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, "<b>" + selected + "</b>")
}
}
QtControls.Button {
iconName: "format-text-italic"
onClicked: {
if (debug) console.log("[widget::onClicked] : Italic button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, "<i>" + selected + "</i>")
}
}
QtControls.Button {
iconName: "format-text-underline"
onClicked: {
if (debug) console.log("[widget::onClicked] : Underline button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, "<u>" + selected + "</u>")
}
}
QtControls.Button {
iconName: "format-text-strikethrough"
onClicked: {
if (debug) console.log("[widget::onClicked] : Strike button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, "<s>" + selected + "</s>")
}
}
QtControls.Button {
iconName: "format-justify-left"
onClicked: {
if (debug) console.log("[widget::onClicked] : Left button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, "<p align=\"left\">" + selected + "</p>")
}
}
QtControls.Button {
iconName: "format-justify-center"
onClicked: {
if (debug) console.log("[widget::onClicked] : Center button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, "<p align=\"center\">" + selected + "</p>")
}
}
QtControls.Button {
iconName: "format-justify-right"
onClicked: {
if (debug) console.log("[widget::onClicked] : Right button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, "<p align=\"right\">" + selected + "</p>")
}
}
QtControls.Button {
iconName: "format-justify-fill"
onClicked: {
if (debug) console.log("[widget::onClicked] : Justify button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, "<p align=\"justify\">" + selected + "</p>")
}
}
AWTagSelector {
backend: awKeys
notifyBackend: awActions
textArea: textPattern
groups: General.awTagRegexp
}
Row {
height: implicitHeight
width: parent.width
QtControls.ComboBox {
id: tags
width: parent.width - addTagButton.width - showValueButton.width
}
QtControls.Button {
id: addTagButton
text: i18n("Add")
onClicked: {
if (debug) console.log("[widget::onClicked] : Add tag button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, selected + "$" + tags.currentText)
}
}
QtControls.Button {
id: showValueButton
text: i18n("Show value")
onClicked: {
if (debug) console.log("[widget::onClicked] : Show tag button")
var message = i18n("Tag: %1", tags.currentText)
message += "<br>"
message += i18n("Value: %1", AWKeys.valueByKey(tags.currentText))
message += "<br>"
message += i18n("Info: %1", AWKeys.infoByKey(tags.currentText))
AWActions.sendNotification("tag", message)
}
}
AWExtensions {
id: extensions
backend: awKeys
textArea: textPattern
onUnlock: lock = false
}
Row {
height: implicitHeight
width: parent.width
QtControls.Button {
width: parent.width
text: i18n("Edit bars")
onClicked: AWKeys.editItem("graphicalitem")
}
}
QtControls.TextArea {
AWTextEditor {
id: textPattern
width: parent.width
height: parent.height * 4 / 5
textFormat: TextEdit.PlainText
text: plasmoid.configuration.text
backend: awKeys
}
}
// 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.log("[widget::onNewData] : Update source " + sourceName)
AWKeys.setDataBySource(sourceName, data, settings)
}
}
PlasmaCore.DataSource {
id: extsysmonDE
engine: "extsysmon"
connectedSources: extsysmonDE.sources
interval: 5000
onNewData: {
if (debug) console.log("[widget::onNewData] : Update source " + sourceName)
AWKeys.setDataBySource(sourceName, data, settings)
}
}
PlasmaCore.DataSource {
id: timeDE
engine: "time"
connectedSources: ["Local"]
interval: 5000
onNewData: {
if (debug) console.log("[widget::onNewData] : Update source " + sourceName)
AWKeys.setDataBySource(sourceName, data, settings)
}
}
Component.onCompleted: {
if (debug) console.log("[widget::onCompleted]")
if (debug) console.debug()
awKeys.needTextToBeUpdated.connect(needTextUpdate)
// init submodule
AWKeys.initKeys(plasmoid.configuration.text, tooltipSettings)
tags.model = AWKeys.dictKeys()
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()
extensions.showMessage(newText)
lock = true
}
}

View File

@ -15,14 +15,12 @@ Icon=utilities-system-monitor
X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
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.2.2
X-KDE-PluginInfo-Website=http://arcanis.name/projects/awesome-widgets/
X-KDE-PluginInfo-Version=3.5.0
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
X-KDE-PluginInfo-EnabledByDefault=true

View File

@ -1,44 +1,23 @@
set (PLUGIN_NAME awplugin)
set(PLUGIN_NAME awplugin)
add_definitions(-DTRANSLATION_DOMAIN=\"plasma_applet_org.kde.plasma.awesomewidget\")
add_definitions (${Qt5Core_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5Xml_DEFINITIONS})
set (Qt_INCLUDE ${Qt5Core_INCLUDE_DIRS}
${Qt5Network_INCLUDE_DIRS}
${Qt5Qml_INCLUDE_DIRS}
${Qt5Xml_INCLUDE_DIRS})
set (Qt_LIBRARIES ${Qt5Core_LIBRARIES}
${Qt5Network_LIBRARIES}
${Qt5Qml_LIBRARIES}
${Qt5Xml_LIBRARIES})
set (Kf5_INCLUDE ${I18n_INCLUDE_DIR}
${Notifications_INCLUDE_DIR})
set (Kf5_LIBRARIES KF5::I18n
KF5::Notifications)
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../${PROJECT_LIBRARY}/
${PROJECT_TRDPARTY_DIR}
${Qt_INCLUDE}
${Kf5_INCLUDE}
)
include_directories (${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/../
${PROJECT_TRDPARTY_DIR}
../../extsysmon
${CMAKE_CURRENT_BINARY_DIR}/../../extsysmon
${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)
# task source is required by extscripts
file (GLOB_RECURSE SUBPROJECT_SOURCE *.cpp ${PROJECT_TRDPARTY_DIR}/fontdialog/*.cpp
../../extsysmon/extquotes.cpp
../../extsysmon/extscript.cpp
../../extsysmon/extupgrade.cpp)
file (GLOB SUBPROJECT_UI *.ui)
file (GLOB SUBPROJECT_NOTIFY *.notifyrc)
set (SUBPROJECT_DESKTOP ${CMAKE_CURRENT_SOURCE_DIR}/desktops)
qt5_wrap_ui(SUBPROJECT_UI_HEADER ${SUBPROJECT_UI})
add_library(${PLUGIN_NAME} SHARED ${SUBPROJECT_SOURCE} ${SUBPROJECT_UI_HEADER})
target_link_libraries(${PLUGIN_NAME} ${PROJECT_LIBRARY} ${Qt_LIBRARIES} ${Kf5_LIBRARIES})
qt5_wrap_ui (SUBPROJECT_UI_HEADER ${SUBPROJECT_UI})
add_library (${PLUGIN_NAME} SHARED ${SUBPROJECT_SOURCE} ${SUBPROJECT_UI_HEADER})
target_link_libraries (${PLUGIN_NAME} ${Qt_LIBRARIES} ${Kf5_LIBRARIES})
install (TARGETS ${PLUGIN_NAME} DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/awesomewidget)
install (FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/awesomewidget)
install (FILES ${SUBPROJECT_NOTIFY} DESTINATION ${KNOTIFYRC_INSTALL_DIR})
install (DIRECTORY ${SUBPROJECT_DESKTOP} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(TARGETS ${PLUGIN_NAME} DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/private/awesomewidget)
install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/private/awesomewidget)
install(FILES ${SUBPROJECT_NOTIFY} DESTINATION ${KNOTIFYRC_INSTALL_DIR})

View File

@ -0,0 +1,181 @@
/***************************************************************************
* 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 "awabstractpairconfig.h"
#include "ui_awabstractpairconfig.h"
#include <KI18n/KLocalizedString>
#include <QPushButton>
#include <utility>
#include "awabstractselector.h"
#include "awdebug.h"
AWAbstractPairConfig::AWAbstractPairConfig(QWidget *_parent, const bool _hasEdit, QStringList _keys)
: QDialog(_parent)
, ui(new Ui::AWAbstractPairConfig)
, m_hasEdit(_hasEdit)
, m_keys(std::move(_keys))
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
ui->setupUi(this);
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
// edit feature
if (m_hasEdit) {
m_editButton = ui->buttonBox->addButton(i18n("Edit"), QDialogButtonBox::ActionRole);
connect(m_editButton, SIGNAL(clicked(bool)), this, SLOT(edit()));
}
}
AWAbstractPairConfig::~AWAbstractPairConfig()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
clearSelectors();
delete ui;
}
void AWAbstractPairConfig::showDialog()
{
// update dialog
updateDialog();
// exec dialog
return execDialog();
}
void AWAbstractPairConfig::setEditable(const bool _first, const bool _second)
{
qCDebug(LOG_AW) << "Set editable" << _first << _second;
m_editable = {_first, _second};
}
void AWAbstractPairConfig::edit()
{
m_helper->editPairs();
updateDialog();
}
void AWAbstractPairConfig::updateUi()
{
QPair<QString, QString> current = dynamic_cast<AWAbstractSelector *>(sender())->current();
int index = m_selectors.indexOf(dynamic_cast<AWAbstractSelector *>(sender()));
if ((current.first.isEmpty()) && (current.second.isEmpty())) {
// remove current selector if it is empty and does not last
if (sender() == m_selectors.last())
return;
AWAbstractSelector *selector = m_selectors.takeAt(index);
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
} else {
// add new selector if something changed
if (sender() != m_selectors.last())
return;
auto keys = initKeys();
addSelector(keys.first, keys.second, QPair<QString, QString>());
}
}
void AWAbstractPairConfig::addSelector(const QStringList &_keys, const QStringList &_values,
const QPair<QString, QString> &_current)
{
qCDebug(LOG_AW) << "Add selector with keys" << _keys << "values" << _values << "and current ones" << _current;
auto *selector = new AWAbstractSelector(ui->scrollAreaWidgetContents, m_editable);
selector->init(_keys, _values, _current);
ui->verticalLayout->insertWidget(ui->verticalLayout->count() - 1, selector);
connect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
m_selectors.append(selector);
}
void AWAbstractPairConfig::clearSelectors()
{
for (auto &selector : m_selectors) {
disconnect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
}
m_selectors.clear();
}
void AWAbstractPairConfig::execDialog()
{
int ret = exec();
QHash<QString, QString> data;
for (auto &selector : m_selectors) {
QPair<QString, QString> select = selector->current();
if (select.first.isEmpty())
continue;
data[select.first] = select.second;
}
// save configuration if required
auto status = true;
switch (ret) {
case 0:
break;
case 1:
default:
status &= m_helper->writeItems(data);
status &= m_helper->removeUnusedKeys(data.keys());
break;
}
qCDebug(LOG_AW) << "Configuration save status" << status;
}
QPair<QStringList, QStringList> AWAbstractPairConfig::initKeys() const
{
// we are adding empty string at the start
QStringList left = {""};
left.append(m_helper->leftKeys().isEmpty() ? m_keys : m_helper->leftKeys());
left.sort();
QStringList right = {""};
right.append(m_helper->rightKeys().isEmpty() ? m_keys : m_helper->rightKeys());
right.sort();
return QPair<QStringList, QStringList>(left, right);
}
void AWAbstractPairConfig::updateDialog()
{
clearSelectors();
auto pairs = m_helper->pairs();
auto keys = initKeys();
for (auto &key : m_helper->keys())
addSelector(keys.first, keys.second, QPair<QString, QString>(key, m_helper->pairs()[key]));
// empty one
addSelector(keys.first, keys.second, QPair<QString, QString>());
}

View File

@ -0,0 +1,72 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWABSTRACTPAIRCONFIG_H
#define AWABSTRACTPAIRCONFIG_H
#include <QDialog>
#include "awabstractpairhelper.h"
class AWAbstractSelector;
namespace Ui
{
class AWAbstractPairConfig;
}
class AWAbstractPairConfig : public QDialog
{
Q_OBJECT
public:
explicit AWAbstractPairConfig(QWidget *_parent = nullptr, bool _hasEdit = false, QStringList _keys = QStringList());
~AWAbstractPairConfig() override;
template <class T> void initHelper()
{
delete m_helper;
m_helper = new T(this);
}
void showDialog();
// properties
void setEditable(bool _first, bool _second);
private slots:
void edit();
void updateUi();
private:
QPushButton *m_editButton = nullptr;
Ui::AWAbstractPairConfig *ui = nullptr;
AWAbstractPairHelper *m_helper = nullptr;
QList<AWAbstractSelector *> m_selectors;
// properties
QPair<bool, bool> m_editable = {false, false};
bool m_hasEdit = false;
QStringList m_keys;
// methods
void addSelector(const QStringList &_keys, const QStringList &_values, const QPair<QString, QString> &_current);
void clearSelectors();
void execDialog();
[[nodiscard]] QPair<QStringList, QStringList> initKeys() const;
void updateDialog();
};
#endif /* AWABSTRACTPAIRCONFIG_H */

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AWAbstractPairConfig</class>
<widget class="QDialog" name="AWAbstractPairConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>384</width>
<height>249</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer">
<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>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AWAbstractPairConfig</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AWAbstractPairConfig</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,135 @@
/***************************************************************************
* 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 "awabstractpairhelper.h"
#include <QSettings>
#include <QStandardPaths>
#include <utility>
#include "awdebug.h"
AWAbstractPairHelper::AWAbstractPairHelper(QString _filePath, QString _section)
: m_filePath(std::move(_filePath))
, m_section(std::move(_section))
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
AWAbstractPairHelper::initItems();
}
AWAbstractPairHelper::~AWAbstractPairHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QStringList AWAbstractPairHelper::keys() const
{
return m_pairs.keys();
}
QHash<QString, QString> AWAbstractPairHelper::pairs() const
{
return m_pairs;
}
QStringList AWAbstractPairHelper::values() const
{
return m_pairs.values();
}
QSet<QString> AWAbstractPairHelper::valuesSet() const
{
auto values = m_pairs.values();
return {values.cbegin(), values.cend()};
}
void AWAbstractPairHelper::initItems()
{
m_pairs.clear();
QStringList configs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, m_filePath);
for (auto &fileName : configs) {
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup(m_section);
QStringList keys = settings.childKeys();
for (auto &key : keys) {
QString value = settings.value(key).toString();
qCInfo(LOG_AW) << "Found key" << key << "for value" << value << "in" << settings.fileName();
if (value.isEmpty()) {
qCInfo(LOG_AW) << "Skip empty value for" << key;
continue;
}
m_pairs[key] = value;
}
settings.endGroup();
}
}
bool AWAbstractPairHelper::writeItems(const QHash<QString, QString> &_configuration) const
{
qCDebug(LOG_AW) << "Write configuration" << _configuration;
QString fileName
= QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup(m_section);
for (auto &key : _configuration.keys())
settings.setValue(key, _configuration[key]);
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}
bool AWAbstractPairHelper::removeUnusedKeys(const QStringList &_keys) const
{
qCDebug(LOG_AW) << "Remove keys" << _keys;
QString fileName
= QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup(m_section);
QStringList foundKeys = settings.childKeys();
for (auto &key : foundKeys) {
if (_keys.contains(key))
continue;
settings.remove(key);
}
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}

View File

@ -0,0 +1,51 @@
/***************************************************************************
* 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 AWABSTRACTPAIRHELPER_H
#define AWABSTRACTPAIRHELPER_H
#include <QHash>
class AWAbstractPairHelper
{
public:
explicit AWAbstractPairHelper(QString _filePath = "", QString _section = "");
virtual ~AWAbstractPairHelper();
[[nodiscard]] QStringList keys() const;
[[nodiscard]] QHash<QString, QString> pairs() const;
[[nodiscard]] QStringList values() const;
[[nodiscard]] QSet<QString> valuesSet() const;
// read-write methods
virtual void initItems();
[[nodiscard]] virtual bool writeItems(const QHash<QString, QString> &_configuration) const;
[[nodiscard]] virtual bool removeUnusedKeys(const QStringList &_keys) const;
// configuration related
virtual void editPairs() = 0;
virtual QStringList leftKeys() = 0;
virtual QStringList rightKeys() = 0;
private:
// properties
QHash<QString, QString> m_pairs;
QString m_filePath;
QString m_section;
};
#endif /* AWABSTRACTPAIRHELPER_H */

View File

@ -0,0 +1,75 @@
/***************************************************************************
* 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 "awabstractselector.h"
#include "ui_awabstractselector.h"
#include "awdebug.h"
AWAbstractSelector::AWAbstractSelector(QWidget *_parent, const QPair<bool, bool> &_editable)
: QWidget(_parent)
, ui(new Ui::AWAbstractSelector)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
ui->setupUi(this);
ui->comboBox_key->setEditable(_editable.first);
ui->comboBox_value->setEditable(_editable.second);
connect(ui->comboBox_key, SIGNAL(currentIndexChanged(int)), this, SIGNAL(selectionChanged()));
connect(ui->comboBox_value, SIGNAL(currentIndexChanged(int)), this, SIGNAL(selectionChanged()));
}
AWAbstractSelector::~AWAbstractSelector()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
delete ui;
}
QPair<QString, QString> AWAbstractSelector::current() const
{
QString key = ui->comboBox_key->currentText();
QString value = ui->comboBox_value->currentText();
return QPair<QString, QString>(key, value);
}
void AWAbstractSelector::init(const QStringList &_keys, const QStringList &_values,
const QPair<QString, QString> &_current)
{
if ((!_keys.contains(_current.first)) || (!_values.contains(_current.second))) {
qCWarning(LOG_AW) << "Invalid current value" << _current << "not found in default ones";
return;
}
qCDebug(LOG_AW) << "Init selector with keys" << _keys << "and values" << _values << "and current ones are"
<< _current;
// set data
ui->comboBox_key->clear();
ui->comboBox_key->addItems(_keys);
ui->comboBox_value->clear();
ui->comboBox_value->addItems(_values);
// set current values
ui->comboBox_key->setCurrentText(_current.first);
ui->comboBox_value->setCurrentText(_current.second);
}

View File

@ -0,0 +1,48 @@
/***************************************************************************
* 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 AWABSTRACTSELECTOR_H
#define AWABSTRACTSELECTOR_H
#include <QWidget>
namespace Ui
{
class AWAbstractSelector;
}
class AWAbstractSelector : public QWidget
{
Q_OBJECT
public:
explicit AWAbstractSelector(QWidget *_parent = nullptr, const QPair<bool, bool> &_editable = {false, false});
~AWAbstractSelector() override;
[[nodiscard]] QPair<QString, QString> current() const;
void init(const QStringList &_keys, const QStringList &_values, const QPair<QString, QString> &_current);
signals:
void selectionChanged();
private:
Ui::AWAbstractSelector *ui = nullptr;
};
#endif /* AWABSTRACTSELECTOR_H */

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AWAbstractSelector</class>
<widget class="QWidget" name="AWAbstractSelector">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>25</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<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="QComboBox" name="comboBox_key"/>
</item>
<item>
<widget class="QComboBox" name="comboBox_value"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -20,232 +20,129 @@
#include <KI18n/KLocalizedString>
#include <KNotifications/KNotification>
#include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QFile>
#include <QProcess>
#include <QProcessEnvironment>
#include <QSettings>
#include <QStandardPaths>
#include <QUrl>
#include <fontdialog/fontdialog.h>
#include <pdebug/pdebug.h>
#include "extscript.h"
#include "graphicalitem.h"
#include "version.h"
#include "awdebug.h"
#include "awupdatehelper.h"
AWActions::AWActions(QObject *parent)
: QObject(parent)
AWActions::AWActions(QObject *_parent)
: QObject(_parent)
{
// debug
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
QString debugEnv = environment.value(QString("DEBUG"), QString("no"));
debug = (debugEnv == QString("yes"));
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_updateHelper = new AWUpdateHelper(this);
}
AWActions::~AWActions()
{
if (debug) qDebug() << PDEBUG;
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWActions::checkUpdates()
void AWActions::checkUpdates(const bool _showAnyway)
{
if (debug) qDebug() << PDEBUG;
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)));
if (!m_updateHelper->checkVersion())
m_updateHelper->checkUpdates(_showAnyway);
}
void AWActions::runCmd(const QString cmd)
QString AWActions::getFileContent(const QString &_path)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Cmd" << cmd;
qCDebug(LOG_AW) << "Get content from file" << _path;
QProcess command;
sendNotification(QString("Info"), i18n("Run %1", cmd));
command.startDetached(cmd);
}
void AWActions::sendEmail()
{
if (debug) qDebug() << PDEBUG;
}
void AWActions::showReadme()
{
if (debug) qDebug() << PDEBUG;
QDesktopServices::openUrl(QString(HOMEPAGE));
}
QString AWActions::getAboutText(const QString type)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Type" << type;
QString text;
if (type == QString("header"))
text = QString(NAME);
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"))
text = i18n("Translators: %1", QString(TRANSLATORS));
else if (type == QString("3rdparty")) {
QStringList trdPartyList = QString(TRDPARTY_LICENSE).split(QChar(';'), QString::SkipEmptyParts);
for (int i=0; i<trdPartyList.count(); i++)
trdPartyList[i] = QString("<a href=\"%3\">%1</a> (%2 license)")
.arg(trdPartyList[i].split(QChar(','))[0])
.arg(trdPartyList[i].split(QChar(','))[1])
.arg(trdPartyList[i].split(QChar(','))[2]);
text = i18n("This software uses: %1", trdPartyList.join(QString(", ")));
QFile inputFile(_path);
if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(LOG_AW) << "Could not open file as text" << inputFile.fileName();
return "";
}
return text;
QString output = inputFile.readAll();
inputFile.close();
return output;
}
QMap<QString, QVariant> AWActions::getFont(const QMap<QString, QVariant> defaultFont)
// HACK: since QML could not use QLoggingCategory I need this hack
bool AWActions::isDebugEnabled()
{
if (debug) qDebug() << PDEBUG;
return LOG_AW().isDebugEnabled();
}
QMap<QString, QVariant> 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);
fontMap[QString("color")] = font.color().name();
fontMap[QString("family")] = font.family();
fontMap[QString("size")] = font.pointSize();
bool AWActions::runCmd(const QString &_cmd, const QStringList &_args)
{
qCDebug(LOG_AW) << "Cmd" << _cmd << "args" << _args;
sendNotification(QString("Info"), i18n("Run %1", _cmd));
return QProcess::startDetached(_cmd, _args);
}
// HACK: this method uses variable from version.h
void AWActions::showReadme()
{
QDesktopServices::openUrl(QUrl(HOMEPAGE));
}
void AWActions::showLegacyInfo()
{
auto *msgBox = new QMessageBox(nullptr);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setModal(false);
msgBox->setWindowTitle(i18n("Not supported"));
msgBox->setText(i18n("You are using mammoth's Qt version, try to update it first"));
msgBox->setStandardButtons(QMessageBox::Ok);
msgBox->setIcon(QMessageBox::Information);
msgBox->open();
}
// HACK: this method uses variables from version.h
QString AWActions::getAboutText(const QString &_type)
{
qCDebug(LOG_AW) << "Type" << _type;
return AWDebug::getAboutText(_type);
}
QVariantMap AWActions::getFont(const QVariantMap &_defaultFont)
{
qCDebug(LOG_AW) << "Default font is" << _defaultFont;
QVariantMap fontMap;
int ret = 0;
CFont defaultCFont = CFont(_defaultFont["family"].toString(), _defaultFont["size"].toInt(), 400, false,
_defaultFont["color"].toString());
CFont font = CFontDialog::getFont(i18n("Select font"), defaultCFont, false, false, &ret);
fontMap["applied"] = ret;
fontMap["color"] = font.color().name();
fontMap["family"] = font.family();
fontMap["size"] = font.pointSize();
return fontMap;
}
QMap<QString, QVariant> AWActions::readDataEngineConfiguration()
// to avoid additional object definition this method is static
void AWActions::sendNotification(const QString &_eventId, const QString &_message)
{
if (debug) qDebug() << PDEBUG;
qCDebug(LOG_AW) << "Event" << _eventId << "with message" << _message;
QString fileName = QStandardPaths::locate(QStandardPaths::ConfigLocation, QString("plasma-dataengine-extsysmon.conf"));
if (debug) qDebug() << PDEBUG << ":" << "Configuration file" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
QMap<QString, QVariant> 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"));
settings.endGroup();
return configuration;
}
void AWActions::writeDataEngineConfiguration(const QMap<QString, QVariant> configuration)
{
if (debug) qDebug() << PDEBUG;
QString fileName = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QString("/plasma-dataengine-extsysmon.conf");
QSettings settings(fileName, QSettings::IniFormat);
if (debug) qDebug() << PDEBUG << ":" << "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.endGroup();
settings.sync();
}
void AWActions::sendNotification(const QString eventId, const QString message, const bool enablePopup)
{
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)
{
if (debug) qDebug() << PDEBUG;
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(0, 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)
{
if (debug) qDebug() << PDEBUG;
QString answer = reply->readAll();
if (!answer.contains(QString("tag_name"))) return;
QString version = QString(VERSION);
if (debug) qDebug() << PDEBUG << answer;
for (int i=0; i<answer.split(QString("tag_name")).count(); i++) {
version = answer.split(QString("tag_name"))[1].split(QChar(','))[0];
version.remove(QChar('"'));
version.remove(QChar(':'));
version.remove(QString("V."));
break;
}
int old_major = QString(VERSION).split(QChar('.'))[0].toInt();
int old_minor = QString(VERSION).split(QChar('.'))[1].toInt();
int old_patch = QString(VERSION).split(QChar('.'))[2].toInt();
int new_major = QString(version).split(QChar('.'))[0].toInt();
int new_minor = QString(version).split(QChar('.'))[1].toInt();
int new_patch = QString(version).split(QChar('.'))[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)))
showUpdates(version);
KNotification *notification
= KNotification::event(_eventId, QString("Awesome Widget ::: %1").arg(_eventId), _message);
notification->setComponentName("plasma-applet-org.kde.plasma.awesome-widget");
}

View File

@ -21,41 +21,32 @@
#include <QMap>
#include <QObject>
#include <QVariant>
class QNetworkReply;
class AWUpdateHelper;
class AWActions : public QObject
{
Q_OBJECT
public:
AWActions(QObject *parent = nullptr);
~AWActions();
Q_INVOKABLE void checkUpdates();
Q_INVOKABLE void runCmd(const QString cmd = QString("/usr/bin/true"));
Q_INVOKABLE void sendEmail();
Q_INVOKABLE void showReadme();
explicit AWActions(QObject *_parent = nullptr);
~AWActions() override;
Q_INVOKABLE void checkUpdates(bool _showAnyway = false);
Q_INVOKABLE static QString getFileContent(const QString &_path);
Q_INVOKABLE static bool isDebugEnabled();
Q_INVOKABLE static bool runCmd(const QString &_cmd, const QStringList &_args);
Q_INVOKABLE static void showLegacyInfo();
Q_INVOKABLE static void showReadme();
// configuration slots
Q_INVOKABLE QString getAboutText(const QString type = QString("header"));
Q_INVOKABLE QMap<QString, QVariant> getFont(const QMap<QString, QVariant> defaultFont);
// dataengine
Q_INVOKABLE QMap<QString, QVariant> readDataEngineConfiguration();
Q_INVOKABLE void writeDataEngineConfiguration(const QMap<QString, QVariant> configuration);
Q_INVOKABLE static QString getAboutText(const QString &_type);
Q_INVOKABLE static QVariantMap getFont(const QVariantMap &_defaultFont);
public slots:
Q_INVOKABLE static void sendNotification(const QString eventId, const QString message,
const bool enablePopup = false);
private slots:
void showUpdates(QString version);
void versionReplyRecieved(QNetworkReply *reply);
Q_INVOKABLE static void sendNotification(const QString &_eventId, const QString &_message);
private:
// variables
bool debug = false;
AWUpdateHelper *m_updateHelper = nullptr;
};

View File

@ -0,0 +1,149 @@
/***************************************************************************
* 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 "awbugreporter.h"
#include <KI18n/KLocalizedString>
#include <QDesktopServices>
#include <QJsonDocument>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include "awdebug.h"
AWBugReporter::AWBugReporter(QObject *_parent)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWBugReporter::~AWBugReporter()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWBugReporter::doConnect()
{
// additional method for testing needs
connect(this, SIGNAL(replyReceived(const int, const QString &)), this, SLOT(showInformation(int, const QString &)));
}
QString AWBugReporter::generateText(const QString &_description, const QString &_reproduce, const QString &_expected,
const QString &_logs)
{
// do not log _logs here, it may have quite large size
qCDebug(LOG_AW) << "Generate text with description" << _description << "steps" << _reproduce
<< "and expected result" << _expected;
QString output;
output += QString("**Description**\n\n%1\n\n").arg(_description);
output += QString("**Step to _reproduce**\n\n%1\n\n").arg(_reproduce);
output += QString("**Expected result**\n\n%1\n\n").arg(_expected);
output += QString("**Version**\n\n%1\n\n").arg(AWDebug::getBuildData().join(QString("\n")));
// append _logs
output += QString("**Logs**\n\n%1").arg(_logs);
return output;
}
void AWBugReporter::sendBugReport(const QString &_title, const QString &_body)
{
qCDebug(LOG_AW) << "Send bug report with title" << _title << "and body" << _body;
auto *manager = new QNetworkAccessManager(nullptr);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(issueReplyRecieved(QNetworkReply *)));
QNetworkRequest request = QNetworkRequest(QUrl(BUGTRACKER_API));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
// generate payload
QVariantMap payload;
payload["title"] = _title;
payload["body"] = _body;
payload["labels"] = QStringList() << "from application";
// convert to QByteArray to send request
QByteArray data = QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact);
qCInfo(LOG_AW) << "Send request with _body" << data.data() << "and size" << data.size();
manager->post(request, data);
}
void AWBugReporter::issueReplyRecieved(QNetworkReply *_reply)
{
if (_reply->error() != QNetworkReply::NoError) {
qCWarning(LOG_AW) << "An error occurs" << _reply->error() << "with message" << _reply->errorString();
return emit(replyReceived(0, ""));
}
QJsonParseError error{};
QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_AW) << "Parse error" << error.errorString();
return emit(replyReceived(0, ""));
}
_reply->deleteLater();
// convert to map
QVariantMap response = jsonDoc.toVariant().toMap();
QString url = response["html_url"].toString();
int number = response["number"].toInt();
return emit(replyReceived(number, url));
}
void AWBugReporter::showInformation(const int _number, const QString &_url)
{
qCDebug(LOG_AW) << "Created issue with number" << _number << "and url" << _url;
// cache url first
m_lastBugUrl = _url;
auto *msgBox = new QMessageBox(nullptr);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setModal(false);
msgBox->setWindowTitle(i18n("Issue created"));
msgBox->setText(i18n("Issue %1 has been created", _number));
msgBox->setStandardButtons(QMessageBox::Open | QMessageBox::Close);
msgBox->setIcon(QMessageBox::Information);
msgBox->open(this, SLOT(userReplyOnBugReport(QAbstractButton *)));
}
void AWBugReporter::userReplyOnBugReport(QAbstractButton *_button)
{
QMessageBox::ButtonRole ret = dynamic_cast<QMessageBox *>(sender())->buttonRole(_button);
qCInfo(LOG_AW) << "User select" << ret;
switch (ret) {
case QMessageBox::AcceptRole:
QDesktopServices::openUrl(m_lastBugUrl);
break;
case QMessageBox::RejectRole:
default:
break;
}
}

View File

@ -0,0 +1,53 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWBUGREPORTER_H
#define AWBUGREPORTER_H
#include <QObject>
class QAbstractButton;
class QNetworkReply;
class AWBugReporter : public QObject
{
Q_OBJECT
public:
explicit AWBugReporter(QObject *_parent = nullptr);
~AWBugReporter() override;
Q_INVOKABLE void doConnect();
Q_INVOKABLE static QString generateText(const QString &_description, const QString &_reproduce,
const QString &_expected, const QString &_logs);
Q_INVOKABLE void sendBugReport(const QString &_title, const QString &_body);
signals:
void replyReceived(int _number, const QString &_url);
private slots:
void issueReplyRecieved(QNetworkReply *_reply);
void showInformation(int _number, const QString &_url);
void userReplyOnBugReport(QAbstractButton *_button);
private:
QString m_lastBugUrl;
};
#endif /* AWBUGREPORTER_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 "awconfighelper.h"
#include <QDir>
#include <QQmlPropertyMap>
#include <QSettings>
#include <QStandardPaths>
#include <QTextCodec>
#include "awdebug.h"
AWConfigHelper::AWConfigHelper(QObject *_parent)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_baseDir = QString("%1/awesomewidgets").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
}
AWConfigHelper::~AWConfigHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QString AWConfigHelper::configurationDirectory()
{
// 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()
{
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
const auto *configuration = dynamic_cast<const QQmlPropertyMap *>(_nativeConfig);
settings.beginGroup("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() << "*.desktop", QDir::Files);
settings.beginGroup(item);
for (auto &it : items)
copyExtensions(it, item, settings, false);
settings.endGroup();
}
// additional files
settings.beginGroup("json");
// script filters
readFile(settings, "filters", QString("%1/scripts/awesomewidgets-extscripts-filters.json").arg(m_baseDir));
// weather icon settings
readFile(settings, "weathers", QString("%1/weather/awesomewidgets-extweather-ids.json").arg(m_baseDir));
settings.endGroup();
settings.beginGroup("ini");
// formatter settings
readFile(settings, "formatters", QString("%1/formatters/formatters.ini").arg(m_baseDir));
// custom keys settings
readFile(settings, "custom", QString("%1/custom.ini").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("json");
// script filters
writeFile(settings, "filters", QString("%1/scripts/awesomewidgets-extscripts-filters.json").arg(m_baseDir));
// weather icon settings
writeFile(settings, "weathers", QString("%1/weather/awesomewidgets-extweather-ids.json").arg(m_baseDir));
settings.endGroup();
settings.beginGroup("ini");
// formatter settings
writeFile(settings, "formatters", QString("%1/formatters/formatters.ini").arg(m_baseDir));
// custom keys settings
writeFile(settings, "custom", QString("%1/custom.ini").arg(m_baseDir));
settings.endGroup();
}
// plasmoid configuration
if (_importPlasmoid) {
settings.beginGroup("plasmoid");
for (auto &key : settings.childKeys())
configuration[key] = settings.value(key);
settings.endGroup();
}
return configuration;
}
QVariantMap AWConfigHelper::readDataEngineConfiguration()
{
QString fileName = QStandardPaths::locate(QStandardPaths::ConfigLocation, "plasma-dataengine-extsysmon.conf");
qCInfo(LOG_AW) << "Configuration file" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
QVariantMap configuration;
settings.beginGroup("Configuration");
configuration["ACPIPATH"] = settings.value("ACPIPATH", "/sys/class/power_supply/");
configuration["GPUDEV"] = settings.value("GPUDEV", "auto");
configuration["HDDDEV"] = settings.value("HDDDEV", "all");
configuration["HDDTEMPCMD"] = settings.value("HDDTEMPCMD", "sudo smartctl -a");
configuration["MPDADDRESS"] = settings.value("MPDADDRESS", "localhost");
configuration["MPDPORT"] = settings.value("MPDPORT", "6600");
configuration["MPRIS"] = settings.value("MPRIS", "auto");
configuration["PLAYER"] = settings.value("PLAYER", "mpris");
configuration["PLAYERSYMBOLS"] = settings.value("PLAYERSYMBOLS", "10");
settings.endGroup();
qCInfo(LOG_AW) << "Configuration" << configuration;
return configuration;
}
bool AWConfigHelper::writeDataEngineConfiguration(const QVariantMap &_configuration)
{
qCDebug(LOG_AW) << "Configuration" << _configuration;
QString fileName = QString("%1/plasma-dataengine-extsysmon.conf")
.arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup("Configuration");
settings.setValue("ACPIPATH", _configuration["ACPIPATH"]);
settings.setValue("GPUDEV", _configuration["GPUDEV"]);
settings.setValue("HDDDEV", _configuration["HDDDEV"]);
settings.setValue("HDDTEMPCMD", _configuration["HDDTEMPCMD"]);
settings.setValue("MPDADDRESS", _configuration["MPDADDRESS"]);
settings.setValue("MPDPORT", _configuration["MPDPORT"]);
settings.setValue("MPRIS", _configuration["MPRIS"]);
settings.setValue("PLAYER", _configuration["PLAYER"]);
settings.setValue("PLAYERSYMBOLS", _configuration["PLAYERSYMBOLS"]);
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}
void AWConfigHelper::copyConfigs(const QString &_localDir)
{
qCDebug(LOG_AW) << "Local directory" << _localDir;
QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "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("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)
{
for (auto &key : _from.childKeys())
_to.setValue(key, _from.value(key));
}
void AWConfigHelper::readFile(QSettings &_settings, const QString &_key, const QString &_fileName)
{
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_AW) << "Could not open to read" << file.fileName();
}
}
void AWConfigHelper::writeFile(QSettings &_settings, const QString &_key, const QString &_fileName)
{
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_AW) << "Could not open to write" << file.fileName();
}
}

View File

@ -0,0 +1,57 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWCONFIGHELPER_H
#define AWCONFIGHELPER_H
#include <QObject>
#include <QVariant>
class QSettings;
class AWConfigHelper : public QObject
{
Q_OBJECT
public:
explicit AWConfigHelper(QObject *_parent = nullptr);
~AWConfigHelper() override;
Q_INVOKABLE [[nodiscard]] static QString configurationDirectory();
Q_INVOKABLE static bool dropCache();
Q_INVOKABLE bool exportConfiguration(QObject *_nativeConfig, const QString &_fileName) const;
Q_INVOKABLE [[nodiscard]] QVariantMap importConfiguration(const QString &_fileName, bool _importPlasmoid,
bool _importExtensions, bool _importAdds) const;
// dataengine
Q_INVOKABLE static QVariantMap readDataEngineConfiguration();
Q_INVOKABLE static bool writeDataEngineConfiguration(const QVariantMap &_configuration);
private:
// methods
static void copyConfigs(const QString &_localDir);
void copyExtensions(const QString &_item, const QString &_type, QSettings &_settings, bool _inverse) const;
static void copySettings(QSettings &_from, QSettings &_to);
static void readFile(QSettings &_settings, const QString &_key, const QString &_fileName);
static void writeFile(QSettings &_settings, const QString &_key, const QString &_fileName);
// properties
QString m_baseDir;
QStringList m_dirs = {"desktops", "quotes", "scripts", "upgrade", "weather", "formatters"};
};
#endif /* AWCONFIGHELPER_H */

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/ *
***************************************************************************/
#include "awcustomkeysconfig.h"
#include "awcustomkeyshelper.h"
#include "awdebug.h"
AWCustomKeysConfig::AWCustomKeysConfig(QWidget *_parent, const QStringList &_keys)
: AWAbstractPairConfig(_parent, false, _keys)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
setEditable(true, false);
initHelper<AWCustomKeysHelper>();
}
AWCustomKeysConfig::~AWCustomKeysConfig()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}

View File

@ -0,0 +1,35 @@
/***************************************************************************
* 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 AWCUSTOMKEYSCONFIG_H
#define AWCUSTOMKEYSCONFIG_H
#include "awabstractpairconfig.h"
class AWCustomKeysConfig : public AWAbstractPairConfig
{
Q_OBJECT
public:
explicit AWCustomKeysConfig(QWidget *_parent = nullptr, const QStringList &_keys = QStringList());
~AWCustomKeysConfig() override;
};
#endif /* AWCUSTOMKEYSCONFIG_H */

View File

@ -0,0 +1,78 @@
/***************************************************************************
* 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 "awcustomkeyshelper.h"
#include <QSet>
#include "awdebug.h"
AWCustomKeysHelper::AWCustomKeysHelper(QObject *_parent)
: QObject(_parent)
, AWAbstractPairHelper("awesomewidgets/custom.ini", "Custom")
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWCustomKeysHelper::~AWCustomKeysHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QString AWCustomKeysHelper::source(const QString &_key) const
{
qCDebug(LOG_AW) << "Get source by key" << _key;
return pairs()[_key];
}
QStringList AWCustomKeysHelper::sources() const
{
return valuesSet().values();
}
QStringList AWCustomKeysHelper::refinedSources() const
{
auto allSources = valuesSet();
QSet<QString> output;
while (output != allSources) {
output.clear();
for (auto &src : allSources)
output.insert(pairs().contains(src) ? source(src) : src);
allSources = output;
}
return output.values();
}
QStringList AWCustomKeysHelper::leftKeys()
{
return keys();
}
QStringList AWCustomKeysHelper::rightKeys()
{
return {};
}

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 AWCUSTOMKEYSHELPER_H
#define AWCUSTOMKEYSHELPER_H
#include <QObject>
#include "awabstractpairhelper.h"
class AWCustomKeysHelper : public QObject, public AWAbstractPairHelper
{
Q_OBJECT
public:
explicit AWCustomKeysHelper(QObject *_parent = nullptr);
~AWCustomKeysHelper() override;
// get
[[nodiscard]] QString source(const QString &_key) const;
[[nodiscard]] QStringList sources() const;
[[nodiscard]] QStringList refinedSources() const;
// configuration related
void editPairs() override{};
QStringList leftKeys() override;
QStringList rightKeys() override;
private:
};
#endif /* AWCUSTOMKEYSHELPER_H */

View File

@ -0,0 +1,280 @@
/***************************************************************************
* 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 <QBuffer>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <cmath>
#include "awactions.h"
#include "awdebug.h"
AWDataAggregator::AWDataAggregator(QObject *_parent)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_boundaries["cpuTooltip"] = 100.0;
m_boundaries["cpuclTooltip"] = 4000.0;
m_boundaries["memTooltip"] = 100.0;
m_boundaries["swapTooltip"] = 100.0;
m_boundaries["downkbTooltip"] = 1.0;
m_boundaries["upkbTooltip"] = 1.0;
m_boundaries["batTooltip"] = 100.0;
initScene();
}
AWDataAggregator::~AWDataAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
delete m_toolTipScene;
}
QString AWDataAggregator::htmlImage(const QPixmap &_source)
{
QByteArray byteArray;
QBuffer buffer(&byteArray);
_source.save(&buffer, "PNG");
return byteArray.isEmpty() ? ""
: QString("<img src=\"data:image/png;base64,%1\"/>").arg(QString(byteArray.toBase64()));
}
void AWDataAggregator::setParameters(const QVariantMap &_settings)
{
qCDebug(LOG_AW) << "Settings" << _settings;
// cast from QVariantMap to QVariantHash without data lost
m_configuration = qvariant_cast<QVariantHash>(_settings);
m_enablePopup = m_configuration["notify"].toBool();
m_counts = 0;
m_counts += m_configuration["cpuTooltip"].toInt();
m_counts += m_configuration["cpuclTooltip"].toInt();
m_counts += m_configuration["memTooltip"].toInt();
m_counts += m_configuration["swapTooltip"].toInt();
m_counts += m_configuration["downkbTooltip"].toInt();
m_counts += m_configuration["batTooltip"].toInt();
// resize tooltip image
m_toolTipView->resize(100 * m_counts, 105);
requiredKeys.clear();
if (m_configuration["cpuTooltip"].toBool())
requiredKeys.append("cpuTooltip");
if (m_configuration["cpuclTooltip"].toBool())
requiredKeys.append("cpuclTooltip");
if (m_configuration["memTooltip"].toBool())
requiredKeys.append("memTooltip");
if (m_configuration["swapTooltip"].toBool())
requiredKeys.append("swapTooltip");
if (m_configuration["downkbTooltip"].toBool())
requiredKeys.append("downkbTooltip");
if (m_configuration["upkbTooltip"].toBool())
requiredKeys.append("upkbTooltip");
if (m_configuration["batTooltip"].toBool())
requiredKeys.append("batTooltip");
// background
m_toolTipScene->setBackgroundBrush(m_configuration["useTooltipBackground"].toBool()
? QBrush(QColor(m_configuration["tooltipBackground"].toString()))
: QBrush(Qt::NoBrush));
}
QPixmap AWDataAggregator::tooltipImage()
{
// create image
m_toolTipScene->clear();
QPen pen;
bool down = false;
for (auto &key : requiredKeys) {
// create frame
float normX = 100.0f / static_cast<float>(m_values[key].count());
float normY = 100.0f / (1.5f * m_boundaries[key]);
float shift = static_cast<float>(requiredKeys.indexOf(key)) * 100.0f;
if (down)
shift -= 100.0;
// apply pen color
if (key != "batTooltip")
pen.setColor(QColor(m_configuration[QString("%1Color").arg(key)].toString()));
// paint data inside frame
for (int j = 0; j < m_values[key].count() - 1; j++) {
// some magic here
float x1 = j * normX + shift;
float y1 = -std::fabs(m_values[key].at(j)) * normY + 5.0f;
float x2 = (j + 1) * normX + shift;
float y2 = -std::fabs(m_values[key].at(j + 1)) * normY + 5.0f;
if (key == "batTooltip") {
if (m_values[key].at(j + 1) > 0)
pen.setColor(QColor(m_configuration["batTooltipColor"].toString()));
else
pen.setColor(QColor(m_configuration["batInTooltipColor"].toString()));
}
m_toolTipScene->addLine(x1, y1, x2, y2, pen);
}
if (key == "downkbTooltip")
down = true;
}
return m_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) && (m_values[_source].last() < _extremum))
return AWActions::sendNotification("event", notificationText(_source, _value));
} else {
if ((m_enablePopup) && (_value < _extremum) && (m_values[_source].last() > _extremum))
return AWActions::sendNotification("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("event", notificationText(_source, _received));
}
void AWDataAggregator::initScene()
{
m_toolTipScene = new QGraphicsScene(nullptr);
m_toolTipView = new QGraphicsView(m_toolTipScene);
m_toolTipView->setStyleSheet("background: transparent");
m_toolTipView->setContentsMargins(0, 0, 0, 0);
m_toolTipView->setFrameShape(QFrame::NoFrame);
m_toolTipView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_toolTipView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
QString AWDataAggregator::notificationText(const QString &_source, const float _value)
{
qCDebug(LOG_AW) << "Notification source" << _source << "with value" << _value;
QString output;
if (_source == "batTooltip")
output = _value > 0.0 ? i18n("AC online") : i18n("AC offline");
else if (_source == "cpuTooltip")
output = i18n("High CPU load");
else if (_source == "memTooltip")
output = i18n("High memory usage");
else if (_source == "swapTooltip")
output = i18n("Swap is used");
else if (_source == "gpu")
output = i18n("High GPU load");
return output;
}
QString AWDataAggregator::notificationText(const QString &_source, const QString &_value)
{
qCDebug(LOG_AW) << "Notification source" << _source << "with value" << _value;
QString output;
if (_source == "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["ac"].toString() == m_configuration["acOnline"], "batTooltip", _values["bat"].toFloat());
// usual case
setData("cpuTooltip", _values["cpu"].toFloat(), 90.0);
setData("cpuclTooltip", _values["cpucl"].toFloat());
setData("memTooltip", _values["mem"].toFloat(), 80.0);
setData("swapTooltip", _values["swap"].toFloat(), 0.0);
setData("downkbTooltip", _values["downkb"].toFloat());
setData("upkbTooltip", _values["upkb"].toFloat());
// additional check for network device
[this](const QString &value) {
checkValue("netdev", m_currentNetworkDevice, value);
m_currentNetworkDevice = value;
}(_values["netdev"].toString());
// additional check for GPU load
[this](const float value) { checkValue("gpu", value, 90.0); }(_values["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 (m_values[_source].count() == 0)
m_values[_source].append(0.0);
else if (m_values[_source].count() > m_configuration["tooltipNumber"].toInt())
m_values[_source].removeFirst();
if (std::isnan(_value))
_value = 0.0;
// notifications
checkValue(_source, _value, _extremum);
m_values[_source].append(_value);
if (_source == "downkbTooltip") {
QList<float> netValues = m_values["downkbTooltip"] + m_values["upkbTooltip"];
// to avoid inf value of normY
netValues << 1.0;
m_boundaries["downkbTooltip"] = 1.2f * *std::max_element(netValues.cbegin(), netValues.cend());
m_boundaries["upkbTooltip"] = m_boundaries["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,73 @@
/***************************************************************************
* 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);
~AWDataAggregator() override;
static QString htmlImage(const QPixmap &_source);
void setParameters(const QVariantMap &_settings);
QPixmap tooltipImage();
public slots:
void dataUpdate(const QVariantHash &_values);
signals:
void toolTipPainted(const QString &_image) const;
private:
// ui
QGraphicsScene *m_toolTipScene = nullptr;
QGraphicsView *m_toolTipView = nullptr;
void checkValue(const QString &_source, float _value, float _extremum) const;
void checkValue(const QString &_source, const QString &_current, const QString &_received) const;
void initScene();
static QString notificationText(const QString &_source, float _value);
static QString notificationText(const QString &_source, const QString &_value);
// main method
void setData(const QVariantHash &_values);
void setData(const QString &_source, float _value, float _extremum = -1.0f);
// different signature for battery device
void setData(bool _dontInvert, const QString &_source, float _value);
// variables
int m_counts = 0;
QVariantHash m_configuration;
QString m_currentNetworkDevice = "lo";
QHash<QString, float> m_boundaries;
QHash<QString, QList<float>> m_values;
bool m_enablePopup = false;
QStringList requiredKeys;
};
#endif /* AWTOOLTIP_H */

View File

@ -0,0 +1,115 @@
/***************************************************************************
* 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 <Plasma/DataContainer>
#include "awdebug.h"
AWDataEngineAggregator::AWDataEngineAggregator(QObject *_parent)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_consumer = new Plasma::DataEngineConsumer();
m_dataEngines["systemmonitor"] = m_consumer->dataEngine("systemmonitor");
m_dataEngines["extsysmon"] = m_consumer->dataEngine("extsysmon");
m_dataEngines["time"] = m_consumer->dataEngine("time");
// additional method required by systemmonitor structure
m_newSourceConnection
= connect(m_dataEngines["systemmonitor"], &Plasma::DataEngine::sourceAdded, [this](const QString &source) {
emit(deviceAdded(source));
m_dataEngines["systemmonitor"]->connectSource(source, parent(), 1000);
});
// required to define Qt::QueuedConnection for signal-slot connection
qRegisterMetaType<Plasma::DataEngine::Data>("Plasma::DataEngine::Data");
}
AWDataEngineAggregator::~AWDataEngineAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
disconnectSources();
}
void AWDataEngineAggregator::disconnectSources()
{
for (auto dataEngine : m_dataEngines.values())
for (auto &source : dataEngine->sources())
dataEngine->disconnectSource(source, parent());
disconnect(m_newSourceConnection);
}
void AWDataEngineAggregator::reconnectSources(const int _interval)
{
qCDebug(LOG_AW) << "Reconnect sources with interval" << _interval;
disconnectSources();
m_dataEngines["systemmonitor"]->connectAllSources(parent(), (uint)_interval);
m_dataEngines["extsysmon"]->connectAllSources(parent(), (uint)_interval);
m_dataEngines["time"]->connectSource("Local", parent(), 1000);
m_newSourceConnection = connect(
m_dataEngines["systemmonitor"], &Plasma::DataEngine::sourceAdded, [this, _interval](const QString &source) {
emit(deviceAdded(source));
m_dataEngines["systemmonitor"]->connectSource(source, parent(), (uint)_interval);
});
#ifdef BUILD_FUTURE
createQueuedConnection();
#endif /* BUILD_FUTURE */
}
void AWDataEngineAggregator::dropSource(const QString &_source)
{
qCDebug(LOG_AW) << "Source" << _source;
// HACK there is no possibility to check to which dataengine source
// connected we will try to disconnect it from all engines
for (auto dataEngine : m_dataEngines.values())
dataEngine->disconnectSource(_source, parent());
}
void AWDataEngineAggregator::createQueuedConnection()
{
// HACK additional method which forces QueuedConnection instead of Auto one
// for more details refer to plasma-framework source code
for (auto &dataEngine : m_dataEngines.keys()) {
// different source set for different engines
QStringList sources = dataEngine == "time" ? QStringList() << "Local" : m_dataEngines[dataEngine]->sources();
// reconnect sources
for (auto &source : sources) {
Plasma::DataContainer *container = m_dataEngines[dataEngine]->containerForSource(source);
// disconnect old connections first
disconnect(container, SIGNAL(dataUpdated(QString, Plasma::DataEngine::Data)), parent(),
SLOT(dataUpdated(QString, Plasma::DataEngine::Data)));
// and now reconnect with Qt::QueuedConnection type
connect(container, SIGNAL(dataUpdated(QString, Plasma::DataEngine::Data)), parent(),
SLOT(dataUpdated(QString, Plasma::DataEngine::Data)), Qt::QueuedConnection);
}
}
}

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);
~AWDataEngineAggregator() override;
void disconnectSources();
void reconnectSources(int _interval);
signals:
void deviceAdded(const QString &_source);
public slots:
void dropSource(const QString &_source);
private:
void createQueuedConnection();
Plasma::DataEngineConsumer *m_consumer = nullptr;
QHash<QString, Plasma::DataEngine *> m_dataEngines;
QMetaObject::Connection m_newSourceConnection;
};
#endif /* AWDATAENGINEAGGREGATOR_H */

View File

@ -0,0 +1,445 @@
/***************************************************************************
* 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 "awdataenginemapper.h"
#include <QRegExp>
#include "awdebug.h"
#include "awformatterhelper.h"
AWDataEngineMapper::AWDataEngineMapper(QObject *_parent, AWFormatterHelper *_custom)
: QObject(_parent)
, m_customFormatters(_custom)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
// default formatters
// memory
m_formatter["mem"] = AWKeysAggregator::FormatterType::Float;
m_formatter["memtotmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter["memtotgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
// network
m_formatter["down"] = AWKeysAggregator::FormatterType::NetSmartFormat;
m_formatter["downkb"] = AWKeysAggregator::FormatterType::Integer;
m_formatter["downtot"] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter["downtotkb"] = AWKeysAggregator::FormatterType::Integer;
m_formatter["downunits"] = AWKeysAggregator::FormatterType::NetSmartUnits;
m_formatter["up"] = AWKeysAggregator::FormatterType::NetSmartFormat;
m_formatter["upkb"] = AWKeysAggregator::FormatterType::Integer;
m_formatter["uptot"] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter["uptotkb"] = AWKeysAggregator::FormatterType::Integer;
m_formatter["upunits"] = AWKeysAggregator::FormatterType::NetSmartUnits;
// swap
m_formatter["swap"] = AWKeysAggregator::FormatterType::Float;
m_formatter["swaptotmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter["swaptotgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
}
AWDataEngineMapper::~AWDataEngineMapper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWKeysAggregator::FormatterType AWDataEngineMapper::formatter(const QString &_key) const
{
qCDebug(LOG_AW) << "Get formatter for key" << _key;
return m_formatter.value(_key, AWKeysAggregator::FormatterType::NoFormat);
}
QStringList AWDataEngineMapper::keysFromSource(const QString &_source) const
{
qCDebug(LOG_AW) << "Search for source" << _source;
return m_map.values(_source);
}
// HACK units required to define should the value be calculated as temperature
// or fan data
QStringList AWDataEngineMapper::registerSource(const QString &_source, const QString &_units, const QStringList &_keys)
{
qCDebug(LOG_AW) << "Source" << _source << "with units" << _units;
// regular expressions
QRegExp cpuRegExp = QRegExp("cpu/cpu.*/TotalLoad");
QRegExp cpuclRegExp = QRegExp("cpu/cpu.*/clock");
QRegExp hddrRegExp = QRegExp("disk/.*/Rate/rblk");
QRegExp hddwRegExp = QRegExp("disk/.*/Rate/wblk");
QRegExp mountFillRegExp = QRegExp("partitions/.*/filllevel");
QRegExp mountFreeRegExp = QRegExp("partitions/.*/freespace");
QRegExp mountUsedRegExp = QRegExp("partitions/.*/usedspace");
QRegExp netRegExp = QRegExp("network/interfaces/.*/(receiver|transmitter)/data$");
QRegExp netTotalRegExp = QRegExp("network/interfaces/.*/(receiver|transmitter)/dataTotal$");
if (_source == "battery/ac") {
// AC
m_map.insert(_source, "ac");
m_formatter["ac"] = AWKeysAggregator::FormatterType::ACFormat;
} else if (_source.startsWith("battery/")) {
// battery stats
QString key = _source;
key.remove("battery/");
m_map.insert(_source, key);
m_formatter[key] = _source.contains("rate") ? AWKeysAggregator::FormatterType::Float
: AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source == "cpu/system/TotalLoad") {
// cpu
m_map.insert(_source, "cpu");
m_formatter["cpu"] = AWKeysAggregator::FormatterType::Float;
} else if (_source.contains(cpuRegExp)) {
// cpus
QString key = _source;
key.remove("cpu/").remove("/TotalLoad");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Float;
} else if (_source == "cpu/system/AverageClock") {
// cpucl
m_map.insert(_source, "cpucl");
m_formatter["cpucl"] = AWKeysAggregator::FormatterType::Integer;
} else if (_source.contains(cpuclRegExp)) {
// cpucls
QString key = _source;
key.remove("cpu/cpu").remove("/clock");
key = QString("cpucl%1").arg(key);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
} else if (_source.startsWith("custom")) {
// custom
QString key = _source;
key.remove("custom/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "desktop/current/name") {
// current desktop name
m_map.insert(_source, "desktop");
m_formatter["desktop"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "desktop/current/number") {
// current desktop number
m_map.insert(_source, "ndesktop");
m_formatter["ndesktop"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "desktop/total/number") {
// desktop count
m_map.insert(_source, "tdesktops");
m_formatter["tdesktops"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.contains(hddrRegExp)) {
// read speed
QString device = _source;
device.remove("/Rate/rblk");
int index = m_devices["disk"].indexOf(device);
if (index > -1) {
QString key = QString("hddr%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
}
} else if (_source.contains(hddwRegExp)) {
// write speed
QString device = _source;
device.remove("/Rate/wblk");
int index = m_devices["disk"].indexOf(device);
if (index > -1) {
QString key = QString("hddw%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
}
} else if (_source == "gpu/load") {
// gpu load
m_map.insert(_source, "gpu");
m_formatter["gpu"] = AWKeysAggregator::FormatterType::Float;
} else if (_source == "gpu/temperature") {
// gpu temperature
m_map.insert(_source, "gputemp");
m_formatter["gputemp"] = AWKeysAggregator::FormatterType::Temperature;
} else if (_source.contains(mountFillRegExp)) {
// fill level
QString device = _source;
device.remove("partitions").remove("/filllevel");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
QString key = QString("hdd%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Float;
// additional keys
m_formatter[QString("hddtotmb%1").arg(index)] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter[QString("hddtotgb%1").arg(index)] = AWKeysAggregator::FormatterType::MemGBFormat;
}
} else if (_source.contains(mountFreeRegExp)) {
// free space
QString device = _source;
device.remove("partitions").remove("/freespace");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
// mb
QString key = QString("hddfreemb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
key = QString("hddfreegb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemGBFormat;
}
} else if (_source.contains(mountUsedRegExp)) {
// used
QString device = _source;
device.remove("partitions").remove("/usedspace");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
// mb
QString key = QString("hddmb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
key = QString("hddgb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemGBFormat;
}
} else if (_source.startsWith("hdd/temperature")) {
// hdd temperature
QString device = _source;
device.remove("hdd/temperature");
int index = m_devices["hdd"].indexOf(device);
if (index > -1) {
QString key = QString("hddtemp%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Temperature;
}
} else if (_source.startsWith("cpu/system/loadavg")) {
// load average
QString time = _source;
time.remove("cpu/system/loadavg");
QString key = QString("la%1").arg(time);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::FloatTwoSymbols;
} else if (_source == "mem/physical/application") {
// app memory
// mb
m_map.insert(_source, "memmb");
m_formatter["memmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "memgb");
m_formatter["memgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "mem/physical/free") {
// free memory
// mb
m_map.insert(_source, "memfreemb");
m_formatter["memfreemb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "memfreegb");
m_formatter["memfreegb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "mem/physical/used") {
// used memory
// mb
m_map.insert(_source, "memusedmb");
m_formatter["memusedmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "memusedgb");
m_formatter["memusedgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "network/current/name") {
// network device
m_map.insert(_source, "netdev");
m_formatter["netdev"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "network/current/ssid") {
// current ssid
m_map.insert(_source, "ssid");
m_formatter["ssid"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.startsWith("network/response")) {
// network response
QString key = _source;
key.remove("network/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.contains(netRegExp)) {
// network speed
QString type = _source.contains("receiver") ? "down" : "up";
int index = m_devices["net"].indexOf(_source.split('/')[2]);
if (index > -1) {
// kb
QString key = QString("%1kb%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
// smart
key = QString("%1%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NetSmartFormat;
// units
key = QString("%1units%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NetSmartUnits;
}
} else if (_source.contains(netTotalRegExp)) {
// network data total
QString type = _source.contains("receiver") ? "down" : "up";
int index = m_devices["net"].indexOf(_source.split('/')[2]);
if (index > -1) {
// kb
QString key = QString("%1totkb%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
// mb
key = QString("%1tot%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemMBFormat;
}
} else if (_source.startsWith("upgrade")) {
// package manager
QString key = _source;
key.remove("upgrade/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source.startsWith("player")) {
// player
QString key = _source;
key.remove("player/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "ps/running/count") {
// running processes count
m_map.insert(_source, "pscount");
m_formatter["pscount"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "ps/running/list") {
// list of running processes
m_map.insert(_source, "ps");
m_formatter["ps"] = AWKeysAggregator::FormatterType::List;
} else if (_source == "ps/total/count") {
// total processes count
m_map.insert(_source, "pstot");
m_formatter["pstot"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.startsWith("quotes")) {
// quotes
QString key = _source;
key.remove("quotes/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Quotes;
} else if (_source == "mem/swap/free") {
// free swap
// mb
m_map.insert(_source, "swapfreemb");
m_formatter["swapfreemb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "swapfreegb");
m_formatter["swapfreegb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "mem/swap/used") {
// used swap
// mb
m_map.insert(_source, "swapmb");
m_formatter["swapmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "swapgb");
m_formatter["swapgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source.startsWith("lmsensors/")) {
// temperature
int index = m_devices["temp"].indexOf(_source);
// HACK 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.insert(_source, key);
m_formatter[key] = _units == "°C" ? AWKeysAggregator::FormatterType::Temperature
: AWKeysAggregator::FormatterType::Integer;
}
} else if (_source == "Local") {
// time
m_map.insert(_source, "time");
m_formatter["time"] = AWKeysAggregator::FormatterType::Time;
// custom time
m_map.insert(_source, "ctime");
m_formatter["ctime"] = AWKeysAggregator::FormatterType::TimeCustom;
// ISO time
m_map.insert(_source, "isotime");
m_formatter["isotime"] = AWKeysAggregator::FormatterType::TimeISO;
// long time
m_map.insert(_source, "longtime");
m_formatter["longtime"] = AWKeysAggregator::FormatterType::TimeLong;
// short time
m_map.insert(_source, "shorttime");
m_formatter["shorttime"] = AWKeysAggregator::FormatterType::TimeShort;
// timestamp
m_map.insert(_source, "tstime");
m_formatter["tstime"] = AWKeysAggregator::FormatterType::Timestamp;
} else if (_source == "system/brightness") {
m_map.insert(_source, "brightness");
m_formatter["brightness"] = AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source == "system/volume") {
m_map.insert(_source, "volume");
m_formatter["volume"] = AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source == "system/uptime") {
// uptime
m_map.insert(_source, "uptime");
m_formatter["uptime"] = AWKeysAggregator::FormatterType::Uptime;
// custom uptime
m_map.insert(_source, "cuptime");
m_formatter["cuptime"] = AWKeysAggregator::FormatterType::UptimeCustom;
} else if (_source.startsWith("weather/temperature")) {
// temperature
QString key = _source;
key.remove("weather/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Temperature;
} else if (_source.startsWith("weather/")) {
// other weather
QString key = _source;
key.remove("weather/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.startsWith("load/load")) {
// load source
QString key = _source;
key.remove("load/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Temperature;
}
QStringList foundKeys = keysFromSource(_source);
// rewrite formatters for custom ones
QStringList customFormattersKeys;
if (m_customFormatters)
customFormattersKeys = m_customFormatters->definedFormatters();
qCInfo(LOG_AW) << "Looking for formatters" << foundKeys << "in" << customFormattersKeys;
for (auto &key : foundKeys) {
if (!customFormattersKeys.contains(key))
continue;
m_formatter[key] = AWKeysAggregator::FormatterType::Custom;
}
// drop key from dictionary if no one user requested key required it
qCInfo(LOG_AW) << "Looking for keys" << foundKeys << "in" << _keys;
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);
for (auto &key : foundKeys)
m_formatter.remove(key);
}
return keysFromSource(_source);
}
void AWDataEngineMapper::setDevices(const QHash<QString, QStringList> &_devices)
{
qCDebug(LOG_AW) << "Devices" << _devices;
m_devices = _devices;
}

View File

@ -0,0 +1,53 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWDATAENGINEMAPPER_H
#define AWDATAENGINEMAPPER_H
#include <QMultiHash>
#include <QObject>
#include "awkeysaggregator.h"
class AWFormatterHelper;
class AWDataEngineMapper : public QObject
{
Q_OBJECT
public:
explicit AWDataEngineMapper(QObject *_parent = nullptr, AWFormatterHelper *_custom = nullptr);
~AWDataEngineMapper() override;
// get methods
[[nodiscard]] AWKeysAggregator::FormatterType formatter(const QString &_key) const;
[[nodiscard]] QStringList keysFromSource(const QString &_source) const;
// set methods
QStringList registerSource(const QString &_source, const QString &_units, const QStringList &_keys);
void setDevices(const QHash<QString, QStringList> &_devices);
private:
AWFormatterHelper *m_customFormatters = nullptr;
// variables
QHash<QString, QStringList> m_devices;
QHash<QString, AWKeysAggregator::FormatterType> m_formatter;
QMultiHash<QString, QString> m_map;
};
#endif /* AWDATAENGINEMAPPER_H */

View File

@ -0,0 +1,108 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awdbusadaptor.h"
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include "awdebug.h"
#include "awkeys.h"
AWDBusAdaptor::AWDBusAdaptor(AWKeys *_parent)
: QDBusAbstractAdaptor(_parent)
, m_plugin(_parent)
{
qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__;
}
AWDBusAdaptor::~AWDBusAdaptor()
{
qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__;
}
QStringList AWDBusAdaptor::ActiveServices()
{
QDBusMessage listServices = QDBusConnection::sessionBus().interface()->call(QDBus::BlockWithGui, "ListNames");
if (listServices.arguments().isEmpty()) {
qCWarning(LOG_DBUS) << "Could not find any DBus service";
return {};
}
QStringList arguments = listServices.arguments().first().toStringList();
return std::accumulate(arguments.cbegin(), arguments.cend(), QStringList(),
[](QStringList source, const QString &service) {
if (service.startsWith(AWDBUS_SERVICE))
source.append(service);
return source;
});
}
QString AWDBusAdaptor::Info(const QString &key) const
{
return m_plugin->infoByKey(key);
}
QStringList AWDBusAdaptor::Keys(const QString &regexp) const
{
return m_plugin->dictKeys(true, regexp);
}
QString AWDBusAdaptor::Value(const QString &key) const
{
return m_plugin->valueByKey(key);
}
qlonglong AWDBusAdaptor::WhoAmI() const
{
return reinterpret_cast<qlonglong>(m_plugin);
}
void AWDBusAdaptor::SetLogLevel(const QString &what, const int level)
{
qCDebug(LOG_DBUS) << "Set log level" << level << "for" << what;
if (level >= m_logLevels.count()) {
qCDebug(LOG_DBUS) << "Invalid logging level" << level << "should be less than" << m_logLevels.count();
return;
}
for (auto &lev : m_logLevels)
SetLogLevel(what, lev, m_logLevels.indexOf(lev) >= level);
}
void AWDBusAdaptor::SetLogLevel(const QString &what, const QString &level, const bool enabled)
{
qCDebug(LOG_DBUS) << "Set log level" << level << "enabled" << enabled << "for" << what;
if (!m_logLevels.contains(level)) {
qCDebug(LOG_DBUS) << "Invalid logging level" << level << "should be in" << m_logLevels;
return;
}
QString state = enabled ? "true" : "false";
QLoggingCategory::setFilterRules(QString("%1.%2=%3").arg(what).arg(level).arg(state));
}

View File

@ -0,0 +1,55 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWDBUSADAPTOR_H
#define AWDBUSADAPTOR_H
#include <QDBusAbstractAdaptor>
#include "version.h"
class AWKeys;
class AWDBusAdaptor : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", AWDBUS_SERVICE_NAME)
public:
explicit AWDBusAdaptor(AWKeys *_parent = nullptr);
~AWDBusAdaptor() override;
public slots:
// get methods
[[nodiscard]] static QStringList ActiveServices();
[[nodiscard]] QString Info(const QString &key) const;
[[nodiscard]] QStringList Keys(const QString &regexp) const;
[[nodiscard]] QString Value(const QString &key) const;
[[nodiscard]] qlonglong WhoAmI() const;
// set methods
void SetLogLevel(const QString &what, int level);
void SetLogLevel(const QString &what, const QString &level, bool enabled);
private:
AWKeys *m_plugin = nullptr;
QStringList m_logLevels = {"debug", "info", "warning", "critical"};
};
#endif /* AWDBUSADAPTOR_H */

View File

@ -20,31 +20,21 @@
#include <QtQml>
#include "awactions.h"
#include "awbugreporter.h"
#include "awconfighelper.h"
#include "awkeys.h"
static QObject *awactions_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine);
Q_UNUSED(scriptEngine);
return new AWActions();
}
static QObject *awkeys_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine);
Q_UNUSED(scriptEngine);
return new AWKeys();
}
#include "awpairconfigfactory.h"
#include "awtelemetryhandler.h"
void AWPlugin::registerTypes(const char *uri)
{
Q_ASSERT(uri == QLatin1String("org.kde.plasma.awesomewidget"));
Q_ASSERT(uri == QLatin1String("org.kde.plasma.private.awesomewidget"));
qmlRegisterSingletonType<AWActions>(uri, 1, 0, "AWActions", awactions_singletontype_provider);
qmlRegisterSingletonType<AWKeys>(uri, 1, 0, "AWKeys", awkeys_singletontype_provider);
qmlRegisterType<AWActions>(uri, 1, 0, "AWActions");
qmlRegisterType<AWBugReporter>(uri, 1, 0, "AWBugReporter");
qmlRegisterType<AWConfigHelper>(uri, 1, 0, "AWConfigHelper");
qmlRegisterType<AWPairConfigFactory>(uri, 1, 0, "AWPairConfigFactory");
qmlRegisterType<AWKeys>(uri, 1, 0, "AWKeys");
qmlRegisterType<AWTelemetryHandler>(uri, 1, 0, "AWTelemetryHandler");
}

View File

@ -28,7 +28,7 @@ class AWPlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
void registerTypes(const char *uri);
void registerTypes(const char *uri) override;
};

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/ *
***************************************************************************/
#include "awformatterconfig.h"
#include "awdebug.h"
#include "awformatterhelper.h"
AWFormatterConfig::AWFormatterConfig(QWidget *_parent, const QStringList &_keys)
: AWAbstractPairConfig(_parent, true, _keys)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
setEditable(false, false);
initHelper<AWFormatterHelper>();
}
AWFormatterConfig::~AWFormatterConfig()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}

View File

@ -0,0 +1,35 @@
/***************************************************************************
* 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 AWFORMATTERCONFIG_H
#define AWFORMATTERCONFIG_H
#include "awabstractpairconfig.h"
class AWFormatterConfig : public AWAbstractPairConfig
{
Q_OBJECT
public:
explicit AWFormatterConfig(QWidget *_parent = nullptr, const QStringList &_keys = QStringList());
~AWFormatterConfig() override;
};
#endif /* AWFORMATTERCONFIG_H */

View File

@ -0,0 +1,240 @@
/***************************************************************************
* 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 "awformatterhelper.h"
#include <KI18n/KLocalizedString>
#include <QDir>
#include <QInputDialog>
#include <QSettings>
#include "awdatetimeformatter.h"
#include "awdebug.h"
#include "awfloatformatter.h"
#include "awjsonformatter.h"
#include "awlistformatter.h"
#include "awnoformatter.h"
#include "awscriptformatter.h"
#include "awstringformatter.h"
AWFormatterHelper::AWFormatterHelper(QWidget *_parent)
: AbstractExtItemAggregator(_parent, "formatters")
, AWAbstractPairHelper("awesomewidgets/formatters/formatters.ini", "Formatters")
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
AWFormatterHelper::initItems();
}
AWFormatterHelper::~AWFormatterHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_formatters.clear();
m_formattersClasses.clear();
}
void AWFormatterHelper::initItems()
{
initFormatters();
// assign internal storage
m_formatters.clear();
for (auto &key : pairs().keys()) {
auto name = pairs()[key];
if (!m_formattersClasses.contains(name)) {
qCWarning(LOG_AW) << "Invalid formatter" << name << "found in" << key;
continue;
}
m_formatters[key] = m_formattersClasses[name];
}
}
QString AWFormatterHelper::convert(const QVariant &_value, const QString &_name) const
{
qCDebug(LOG_AW) << "Convert value" << _value << "for" << _name;
return m_formatters.contains(_name) ? m_formatters[_name]->convert(_value) : _value.toString();
}
QStringList AWFormatterHelper::definedFormatters() const
{
return m_formatters.keys();
}
QList<AbstractExtItem *> AWFormatterHelper::items() const
{
QList<AbstractExtItem *> converted;
for (auto &item : m_formattersClasses.values())
converted.append(item);
return converted;
}
void AWFormatterHelper::editPairs()
{
return editItems();
}
QStringList AWFormatterHelper::leftKeys()
{
return {};
}
QStringList AWFormatterHelper::rightKeys()
{
return m_formattersClasses.keys();
}
void AWFormatterHelper::editItems()
{
repaintList();
int ret = exec();
qCInfo(LOG_AW) << "Dialog returns" << ret;
}
AWAbstractFormatter::FormatterClass AWFormatterHelper::defineFormatterClass(const QString &_stringType)
{
qCDebug(LOG_AW) << "Define formatter class for" << _stringType;
AWAbstractFormatter::FormatterClass formatter = AWAbstractFormatter::FormatterClass::NoFormat;
if (_stringType == "DateTime")
formatter = AWAbstractFormatter::FormatterClass::DateTime;
else if (_stringType == "Float")
formatter = AWAbstractFormatter::FormatterClass::Float;
else if (_stringType == "List")
formatter = AWAbstractFormatter::FormatterClass::List;
else if (_stringType == "NoFormat")
;
else if (_stringType == "Script")
formatter = AWAbstractFormatter::FormatterClass::Script;
else if (_stringType == "String")
formatter = AWAbstractFormatter::FormatterClass::String;
else if (_stringType == "Json")
formatter = AWAbstractFormatter::FormatterClass::Json;
else
qCWarning(LOG_AW) << "Unknown formatter" << _stringType;
return formatter;
}
void AWFormatterHelper::initFormatters()
{
m_formattersClasses.clear();
auto dirs = directories();
for (auto &dir : dirs) {
QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name);
for (auto &file : files) {
// check filename
if (!file.endsWith(".desktop"))
continue;
qCInfo(LOG_AW) << "Found file" << file << "in" << dir;
QString filePath = QString("%1/%2").arg(dir).arg(file);
// check if already exists
auto values = m_formattersClasses.values();
if (std::any_of(values.cbegin(), values.cend(),
[&filePath](const AWAbstractFormatter *item) { return (item->fileName() == filePath); }))
continue;
auto metadata = readMetadata(filePath);
switch (metadata.second) {
case AWAbstractFormatter::FormatterClass::DateTime:
m_formattersClasses[metadata.first] = new AWDateTimeFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::Float:
m_formattersClasses[metadata.first] = new AWFloatFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::List:
m_formattersClasses[metadata.first] = new AWListFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::Script:
m_formattersClasses[metadata.first] = new AWScriptFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::String:
m_formattersClasses[metadata.first] = new AWStringFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::Json:
m_formattersClasses[metadata.first] = new AWJsonFormatter(this, filePath);
break;
case AWAbstractFormatter::FormatterClass::NoFormat:
m_formattersClasses[metadata.first] = new AWNoFormatter(this, filePath);
break;
}
}
}
}
QPair<QString, AWAbstractFormatter::FormatterClass> AWFormatterHelper::readMetadata(const QString &_filePath)
{
qCDebug(LOG_AW) << "Read initial parameters from" << _filePath;
QSettings settings(_filePath, QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
QString name = settings.value("Name", _filePath).toString();
QString type = settings.value("X-AW-Type", "NoFormat").toString();
AWAbstractFormatter::FormatterClass formatter = defineFormatterClass(type);
settings.endGroup();
return QPair<QString, AWAbstractFormatter::FormatterClass>(name, formatter);
}
void AWFormatterHelper::doCreateItem()
{
QStringList selection = {"NoFormat", "DateTime", "Float", "List", "Script", "String", "Json"};
bool ok;
QString select = QInputDialog::getItem(this, i18n("Select type"), i18n("Type:"), selection, 0, false, &ok);
if (!ok) {
qCWarning(LOG_AW) << "No type selected";
return;
}
qCInfo(LOG_AW) << "Selected type" << select;
AWAbstractFormatter::FormatterClass formatter = defineFormatterClass(select);
switch (formatter) {
case AWAbstractFormatter::FormatterClass::DateTime:
return createItem<AWDateTimeFormatter>();
case AWAbstractFormatter::FormatterClass::Float:
return createItem<AWFloatFormatter>();
case AWAbstractFormatter::FormatterClass::List:
return createItem<AWListFormatter>();
case AWAbstractFormatter::FormatterClass::Script:
return createItem<AWScriptFormatter>();
case AWAbstractFormatter::FormatterClass::String:
return createItem<AWStringFormatter>();
case AWAbstractFormatter::FormatterClass::Json:
return createItem<AWJsonFormatter>();
case AWAbstractFormatter::FormatterClass::NoFormat:
return createItem<AWNoFormatter>();
}
}

View File

@ -0,0 +1,61 @@
/***************************************************************************
* 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 AWFORMATTERHELPER_H
#define AWFORMATTERHELPER_H
#include "abstractextitemaggregator.h"
#include "awabstractformatter.h"
#include "awabstractpairhelper.h"
class AWFormatterHelper : public AbstractExtItemAggregator, public AWAbstractPairHelper
{
Q_OBJECT
public:
explicit AWFormatterHelper(QWidget *_parent = nullptr);
~AWFormatterHelper() override;
// read-write methods
void initItems() override;
// methods
[[nodiscard]] QString convert(const QVariant &_value, const QString &_name) const;
[[nodiscard]] QStringList definedFormatters() const;
[[nodiscard]] QList<AbstractExtItem *> items() const override;
// configuration related
void editPairs() override;
QStringList leftKeys() override;
QStringList rightKeys() override;
public slots:
void editItems();
private:
// methods
static AWAbstractFormatter::FormatterClass defineFormatterClass(const QString &_stringType);
void initFormatters();
[[nodiscard]] static QPair<QString, AWAbstractFormatter::FormatterClass> readMetadata(const QString &_filePath);
// parent methods
void doCreateItem() override;
// properties
QHash<QString, AWAbstractFormatter *> m_formatters;
QHash<QString, AWAbstractFormatter *> m_formattersClasses;
};
#endif /* AWFORMATTERHELPER_H */

View File

@ -0,0 +1,174 @@
/***************************************************************************
* 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 <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 &number : cache.allKeys())
cachedValues.append(cache.value(number).toString());
if (_type == "hdd") {
QStringList allDevices = QDir("/dev").entryList(QDir::System, QDir::Name);
QStringList devices = allDevices.filter(QRegExp("^[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;
cachedValues.append(device);
cache.setValue(QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), device);
}
} else if (_type == "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;
cachedValues.append(device);
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 &_userKeys, const QStringList &_allKeys)
{
qCDebug(LOG_AW) << "Looking for required keys in" << _keys << _bars << "using tooltip settings" << _tooltip;
// initial copy
QSet<QString> used(_keys.cbegin(), _keys.cend());
used.unite(QSet(_bars.cbegin(), _bars.cend()));
used.unite(QSet(_userKeys.cbegin(), _userKeys.cend()));
// insert keys from tooltip
for (auto &key : _tooltip.keys()) {
if ((key.endsWith("Tooltip")) && (_tooltip[key].toBool())) {
key.remove("Tooltip");
used << key;
}
}
// insert depending keys, refer to AWKeys::calculateValues()
// hddtotmb*
for (auto &key : _allKeys.filter(QRegExp("^hddtotmb"))) {
if (!used.contains(key))
continue;
key.remove("hddtotmb");
int index = key.toInt();
used << QString("hddfreemb%1").arg(index) << QString("hddmb%1").arg(index);
}
// hddtotgb*
for (auto &key : _allKeys.filter(QRegExp("^hddtotgb"))) {
if (!used.contains(key))
continue;
key.remove("hddtotgb");
int index = key.toInt();
used << QString("hddfreegb%1").arg(index) << QString("hddgb%1").arg(index);
}
// mem
if (used.contains("mem"))
used << "memmb"
<< "memtotmb";
// memtotmb
if (used.contains("memtotmb"))
used << "memusedmb"
<< "memfreemb";
// memtotgb
if (used.contains("memtotgb"))
used << "memusedgb"
<< "memfreegb";
// swap
if (used.contains("swap"))
used << "swapmb"
<< "swaptotmb";
// swaptotmb
if (used.contains("swaptotmb"))
used << "swapmb"
<< "swapfreemb";
// memtotgb
if (used.contains("swaptotgb"))
used << "swapgb"
<< "swapfreegb";
// network keys
QStringList netKeys(
{"up", "upkb", "uptot", "uptotkb", "upunits", "down", "downkb", "downtot", "downtotkb", "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 << "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 << "dummy";
return used.values();
}
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,36 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWKEYCACHE_H
#define AWKEYCACHE_H
#include <QHash>
#include <QString>
#include <QVariant>
namespace AWKeyCache
{
bool addKeyToCache(const QString &_type, const QString &_key = "");
QStringList getRequiredKeys(const QStringList &_keys, const QStringList &_bars, const QVariantMap &_tooltip,
const QStringList &_userKeys, const QStringList &_allKeys);
QHash<QString, QStringList> loadKeysFromCache();
} // namespace AWKeyCache
#endif /* AWKEYCACHE_H */

View File

@ -0,0 +1,356 @@
/***************************************************************************
* 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 <QRegExp>
#include <QThread>
#include "awcustomkeyshelper.h"
#include "awdebug.h"
#include "awkeycache.h"
#include "awpatternfunctions.h"
// extensions
#include "extnetworkrequest.h"
#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__;
m_customKeys = new AWCustomKeysHelper(this);
m_graphicalItems = new ExtItemAggregator<GraphicalItem>(nullptr, "desktops");
m_extNetRequest = new ExtItemAggregator<ExtNetworkRequest>(nullptr, "requests");
m_extQuotes = new ExtItemAggregator<ExtQuotes>(nullptr, "quotes");
m_extScripts = new ExtItemAggregator<ExtScript>(nullptr, "scripts");
m_extUpgrade = new ExtItemAggregator<ExtUpgrade>(nullptr, "upgrade");
m_extWeather = new ExtItemAggregator<ExtWeather>(nullptr, "weather");
}
AWKeyOperations::~AWKeyOperations()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
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("hdd");
addKeyToCache("net");
}
QStringList AWKeyOperations::dictKeys() const
{
QStringList allKeys;
// weather
for (auto &item : m_extWeather->activeItems()) {
allKeys.append(item->tag("weatherId"));
allKeys.append(item->tag("weather"));
allKeys.append(item->tag("humidity"));
allKeys.append(item->tag("pressure"));
allKeys.append(item->tag("temperature"));
allKeys.append(item->tag("timestamp"));
}
// cpuclock & cpu
for (int i = 0; i < QThread::idealThreadCount(); i++) {
allKeys.append(QString("cpucl%1").arg(i));
allKeys.append(QString("cpu%1").arg(i));
}
// temperature
for (int i = 0; i < m_devices["temp"].count(); i++)
allKeys.append(QString("temp%1").arg(i));
// hdd
for (int i = 0; i < m_devices["mount"].count(); 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 = 0; i < m_devices["disk"].count(); i++) {
allKeys.append(QString("hddr%1").arg(i));
allKeys.append(QString("hddw%1").arg(i));
}
// hdd temp
for (int i = 0; i < m_devices["hdd"].count(); i++)
allKeys.append(QString("hddtemp%1").arg(i));
// network
for (int i = 0; i < m_devices["net"].count(); i++) {
allKeys.append(QString("downunits%1").arg(i));
allKeys.append(QString("upunits%1").arg(i));
allKeys.append(QString("downtotkb%1").arg(i));
allKeys.append(QString("downtot%1").arg(i));
allKeys.append(QString("downkb%1").arg(i));
allKeys.append(QString("down%1").arg(i));
allKeys.append(QString("uptotkb%1").arg(i));
allKeys.append(QString("uptot%1").arg(i));
allKeys.append(QString("upkb%1").arg(i));
allKeys.append(QString("up%1").arg(i));
}
// battery
QStringList allBatteryDevices
= QDir("/sys/class/power_supply")
.entryList(QStringList({"BAT*"}), QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
for (int i = 0; i < allBatteryDevices.count(); i++) {
allKeys.append(QString("bat%1").arg(i));
allKeys.append(QString("batleft%1").arg(i));
allKeys.append(QString("batnow%1").arg(i));
allKeys.append(QString("batrate%1").arg(i));
allKeys.append(QString("battotal%1").arg(i));
}
// package manager
for (auto &item : m_extUpgrade->activeItems())
allKeys.append(item->tag("pkgcount"));
// quotes
for (auto &item : m_extQuotes->activeItems()) {
allKeys.append(item->tag("price"));
allKeys.append(item->tag("pricechg"));
allKeys.append(item->tag("percpricechg"));
allKeys.append(item->tag("volume"));
allKeys.append(item->tag("volumechg"));
allKeys.append(item->tag("percvolumechg"));
}
// custom
for (auto &item : m_extScripts->activeItems())
allKeys.append(item->tag("custom"));
// network requests
for (auto &item : m_extNetRequest->activeItems())
allKeys.append(item->tag("response"));
// bars
for (auto &item : m_graphicalItems->activeItems())
allKeys.append(item->tag("bar"));
// user defined keys
allKeys.append(m_customKeys->keys());
// static keys
allKeys.append(QString(STATIC_KEYS).split(','));
// sort in valid order
allKeys.sort();
std::reverse(allKeys.begin(), allKeys.end());
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 m_graphicalItems->itemByTag(_key, "bar");
}
QStringList AWKeyOperations::requiredUserKeys() const
{
return m_customKeys->refinedSources();
}
QStringList AWKeyOperations::userKeys() const
{
return m_customKeys->keys();
}
QString AWKeyOperations::userKeySource(const QString &_key) const
{
return m_customKeys->source(_key);
}
QString AWKeyOperations::infoByKey(const QString &_key) const
{
qCDebug(LOG_AW) << "Requested key" << _key;
QString stripped = _key;
stripped.remove(QRegExp("\\d+"));
QString output;
if (_key.startsWith("bar")) {
AbstractExtItem *item = m_graphicalItems->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.startsWith("custom")) {
AbstractExtItem *item = m_extScripts->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.contains(QRegExp("^hdd[rw]"))) {
QString index = _key;
index.remove(QRegExp("hdd[rw]"));
output = m_devices["disk"][index.toInt()];
} else if (_key.contains(QRegExp("^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)"))) {
QString index = _key;
index.remove(QRegExp("^hdd(|mb|gb|freemb|freegb|totmb|totgb)"));
output = m_devices["mount"][index.toInt()];
} else if (_key.startsWith("hddtemp")) {
QString index = _key;
index.remove("hddtemp");
output = m_devices["hdd"][index.toInt()];
} else if (_key.contains(QRegExp("^(down|up)[0-9]"))) {
QString index = _key;
index.remove(QRegExp("^(down|up)"));
output = m_devices["net"][index.toInt()];
} else if (_key.startsWith("pkgcount")) {
AbstractExtItem *item = m_extUpgrade->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.contains(QRegExp("(^|perc)(ask|bid|price)(chg|)"))) {
AbstractExtItem *item = m_extQuotes->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.contains(QRegExp("(weather|weatherId|humidity|pressure|temperature)"))) {
AbstractExtItem *item = m_extWeather->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.startsWith("temp")) {
QString index = _key;
index.remove("temp");
output = m_devices["temp"][index.toInt()];
} else if (_key.startsWith("response")) {
AbstractExtItem *item = m_extNetRequest->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else {
output = "(none)";
}
return output;
}
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 == "graphicalitem") {
QStringList keys = dictKeys().filter(QRegExp("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)"));
keys.sort();
m_graphicalItems->setConfigArgs(keys);
return m_graphicalItems->editItems();
} else if (_type == "extnetworkrequest") {
return m_extNetRequest->editItems();
} else if (_type == "extquotes") {
return m_extQuotes->editItems();
} else if (_type == "extscript") {
return m_extScripts->editItems();
} else if (_type == "extupgrade") {
return m_extUpgrade->editItems();
} else if (_type == "extweather") {
return m_extWeather->editItems();
}
}
void AWKeyOperations::addDevice(const QString &_source)
{
qCDebug(LOG_AW) << "Source" << _source;
QRegExp diskRegexp = QRegExp("disk/(?:md|sd|hd)[a-z|0-9]_.*/Rate/(?:rblk)");
QRegExp mountRegexp = QRegExp("partitions/.*/filllevel");
if (_source.contains(diskRegexp)) {
QString device = _source;
device.remove("/Rate/rblk");
addKeyToCache("disk", device);
} else if (_source.contains(mountRegexp)) {
QString device = _source;
device.remove("partitions").remove("/filllevel");
addKeyToCache("mount", device);
} else if (_source.startsWith("lmsensors")) {
addKeyToCache("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()
{
m_customKeys->initItems();
m_graphicalItems->initItems();
m_extNetRequest->initItems();
m_extQuotes->initItems();
m_extScripts->initItems();
m_extUpgrade->initItems();
m_extWeather->initItems();
// 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);
m_pattern = AWPatternFunctions::insertMacros(m_pattern);
// 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 <QObject>
#include "extitemaggregator.h"
class AWCustomKeysHelper;
class ExtNetworkRequest;
class ExtQuotes;
class ExtScript;
class ExtUpgrade;
class ExtWeather;
class GraphicalItem;
class AWKeyOperations : public QObject
{
Q_OBJECT
Q_PROPERTY(QString pattern READ pattern WRITE setPattern)
public:
explicit AWKeyOperations(QObject *_parent = nullptr);
~AWKeyOperations() override;
[[nodiscard]] QStringList devices(const QString &_type) const;
[[nodiscard]] QHash<QString, QStringList> devices() const;
void updateCache();
// keys
[[nodiscard]] QStringList dictKeys() const;
[[nodiscard]] GraphicalItem *giByKey(const QString &_key) const;
[[nodiscard]] QStringList requiredUserKeys() const;
[[nodiscard]] QStringList userKeys() const;
[[nodiscard]] QString userKeySource(const QString &_key) const;
// values
[[nodiscard]] QString infoByKey(const QString &_key) const;
[[nodiscard]] 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 = "");
void reinitKeys();
// objects
AWCustomKeysHelper *m_customKeys = nullptr;
ExtItemAggregator<GraphicalItem> *m_graphicalItems = nullptr;
ExtItemAggregator<ExtNetworkRequest> *m_extNetRequest = nullptr;
ExtItemAggregator<ExtQuotes> *m_extQuotes = nullptr;
ExtItemAggregator<ExtScript> *m_extScripts = nullptr;
ExtItemAggregator<ExtUpgrade> *m_extUpgrade = nullptr;
ExtItemAggregator<ExtWeather> *m_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,106 +19,77 @@
#ifndef AWKEYS_H
#define AWKEYS_H
#include <QDialog>
#include <QDialogButtonBox>
#include <QListWidget>
#include <QMap>
#include <Plasma/DataEngine>
#include <QMutex>
#include <QObject>
#include <QStringList>
#include <QPushButton>
#include <QVariant>
class AWToolTip;
class ExtQuotes;
class ExtScript;
class ExtUpgrade;
class GraphicalItem;
class AWDataAggregator;
class AWDataEngineAggregator;
class AWKeyOperations;
class AWKeysAggregator;
class QThreadPool;
class QTimer;
class AWKeys : public QObject
{
Q_OBJECT
enum RequestedItem {
Nothing,
RequestedGraphicalItem,
RequestedExtQuotes,
RequestedExtScript,
RequestedExtUpgrade
};
public:
AWKeys(QObject *parent = nullptr);
~AWKeys();
Q_INVOKABLE void initKeys(const QString currentPattern,
const QMap<QString, QVariant> tooltipParams,
const bool popup = false);
Q_INVOKABLE bool isDebugEnabled();
Q_INVOKABLE QString parsePattern();
Q_INVOKABLE QString toolTipImage();
Q_INVOKABLE QSize toolTipSize();
explicit AWKeys(QObject *_parent = nullptr);
~AWKeys() override;
Q_INVOKABLE void initDataAggregator(const QVariantMap &_tooltipParams);
Q_INVOKABLE void initKeys(const QString &_currentPattern, int _interval, int _limit, bool _optimize);
Q_INVOKABLE void setAggregatorProperty(const QString &_key, const QVariant &_value);
Q_INVOKABLE void setWrapNewLines(bool _wrap);
// 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();
Q_INVOKABLE QStringList getHddDevices();
Q_INVOKABLE bool setDataBySource(const QString sourceName,
const QMap<QString, QVariant> data,
const QMap<QString, QVariant> params);
Q_INVOKABLE [[nodiscard]] QStringList dictKeys(bool _sorted = false, const QString &_regexp = "") const;
Q_INVOKABLE [[nodiscard]] QVariantList getHddDevices() const;
// values
Q_INVOKABLE void graphicalValueByKey();
Q_INVOKABLE QString infoByKey(QString key);
Q_INVOKABLE QString valueByKey(QString key);
Q_INVOKABLE [[nodiscard]] QString infoByKey(const QString &_key) const;
Q_INVOKABLE [[nodiscard]] QString valueByKey(const QString &_key) const;
// configuration
Q_INVOKABLE void editItem(const QString type);
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
static void modelChanged(const QString &, QAbstractItemModel *){};
signals:
void dropSourceFromDataengine(const QString &_source);
void needTextToBeUpdated(const QString &_newText) const;
void needToolTipToBeUpdated(const QString &_newText) const;
private slots:
void loadKeysFromCache();
void reinitKeys();
// editor
void editItemButtonPressed(QAbstractButton *button);
void copyBar(const QString original);
void copyQuotes(const QString original);
void copyScript(const QString original);
void copyUpgrade(const QString original);
void reinitKeys(const QStringList &_currentKeys);
void updateTextData();
private:
// methods
void addKeyToCache(const QString type, const QString key = QString(""));
bool checkKeys(const QMap<QString, QVariant> data);
QString networkDevice();
int numberCpus();
float temperature(const float temp, const QString units);
// find methods
QStringList findGraphicalItems();
QStringList findKeys();
// get methods
QList<ExtQuotes *> getExtQuotes();
QList<ExtScript *> getExtScripts();
QList<ExtUpgrade *> getExtUpgrade();
QList<GraphicalItem *> getGraphicalItems();
GraphicalItem *getItemByTag(const QString tag);
QStringList getTimeKeys();
AWToolTip *toolTip = nullptr;
// graphical elements
QDialog *dialog = nullptr;
QListWidget *widgetDialog = nullptr;
QDialogButtonBox *dialogButtons = nullptr;
QPushButton *copyButton = nullptr;
QPushButton *createButton = nullptr;
QPushButton *deleteButton = nullptr;
RequestedItem requestedItem = Nothing;
void calculateValues();
void createDBusInterface();
[[nodiscard]] QString parsePattern(QString _pattern) const;
void setDataBySource(const QString &_sourceName, const QVariantMap &_data);
// objects
AWDataAggregator *m_dataAggregator = nullptr;
AWDataEngineAggregator *m_dataEngineAggregator = nullptr;
AWKeysAggregator *m_aggregator = nullptr;
AWKeyOperations *m_keyOperator = nullptr;
QTimer *m_timer = nullptr;
// variables
bool debug = false;
bool enablePopup = false;
QList<GraphicalItem *> graphicalItems;
QList<ExtQuotes *> extQuotes;
QList<ExtScript *> extScripts;
QList<ExtUpgrade *> extUpgrade;
QStringList foundBars, foundKeys, keys;
QString pattern;
QMap<QString, QString> values;
QStringList diskDevices, fanDevices, hddDevices, mountDevices, networkDevices, tempDevices;
QVariantMap m_tooltipParams;
QStringList m_foundBars, m_foundKeys, m_foundLambdas, m_requiredKeys;
QVariantHash m_values;
bool m_optimize = false;
bool m_wrapNewLines = false;
// multithread features
QThreadPool *m_threadPool = nullptr;
QMutex m_mutex;
};

View File

@ -0,0 +1,268 @@
/***************************************************************************
* 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 "awdataenginemapper.h"
#include "awdebug.h"
#include "awformatterhelper.h"
#include "version.h"
AWKeysAggregator::AWKeysAggregator(QObject *_parent)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_customFormatters = new AWFormatterHelper(nullptr);
m_mapper = new AWDataEngineMapper(this, m_customFormatters);
// sort time keys
m_timeKeys = QString(TIME_KEYS).split(',');
m_timeKeys.sort();
std::reverse(m_timeKeys.begin(), m_timeKeys.end());
}
AWKeysAggregator::~AWKeysAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWKeysAggregator::initFormatters()
{
m_customFormatters->initItems();
}
QString AWKeysAggregator::formatter(const QVariant &_data, const QString &_key, bool replaceSpace) const
{
qCDebug(LOG_AW) << "Data" << _data << "for key" << _key;
QString output;
QLocale loc = m_translate ? QLocale::system() : QLocale::c();
// case block
switch (m_mapper->formatter(_key)) {
case FormatterType::Float:
output = QString("%1").arg(_data.toFloat(), 5, 'f', 1);
break;
case FormatterType::FloatTwoSymbols:
output = QString("%1").arg(_data.toFloat(), 5, 'f', 2);
break;
case FormatterType::Integer:
output = QString("%1").arg(_data.toFloat(), 4, 'f', 0);
break;
case FormatterType::IntegerFive:
output = QString("%1").arg(_data.toFloat(), 5, 'f', 0);
break;
case FormatterType::IntegerThree:
output = QString("%1").arg(_data.toFloat(), 3, 'f', 0);
break;
case FormatterType::List:
output = _data.toStringList().join(',');
break;
case FormatterType::ACFormat:
output = _data.toBool() ? m_acOnline : m_acOffline;
break;
case FormatterType::MemGBFormat:
output = QString("%1").arg(_data.toFloat() / (1024.0 * 1024.0), 5, 'f', 1);
break;
case FormatterType::MemMBFormat:
output = QString("%1").arg(_data.toFloat() / 1024.0, 5, 'f', 0);
break;
case FormatterType::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 FormatterType::NetSmartUnits:
if (_data.toFloat() > 1024.0)
output = m_translate ? i18n("MB/s") : "MB/s";
else
output = m_translate ? i18n("KB/s") : "KB/s";
break;
case FormatterType::Quotes:
// first cast
output = QString("%1").arg(_data.toDouble(), 0, 'f');
output = output.rightJustified(8, QLatin1Char(' '), true);
break;
case FormatterType::Temperature:
output = QString("%1").arg(temperature(_data.toFloat()), 5, 'f', 1);
break;
case FormatterType::Time:
output = _data.toDateTime().toString();
break;
case FormatterType::TimeCustom:
output = m_customTime;
[&output, loc, this](const QDateTime &dt) {
for (auto &key : m_timeKeys)
output.replace(QString("$%1").arg(key), loc.toString(dt, key));
}(_data.toDateTime());
break;
case FormatterType::TimeISO:
output = _data.toDateTime().toString(Qt::ISODate);
break;
case FormatterType::TimeLong:
output = loc.toString(_data.toDateTime(), QLocale::LongFormat);
break;
case FormatterType::TimeShort:
output = loc.toString(_data.toDateTime(), QLocale::ShortFormat);
break;
case FormatterType::Timestamp:
output = QString("%1").arg(_data.toDateTime().toMSecsSinceEpoch() / 1000.0, 10, 'f', 0);
break;
case FormatterType::Uptime:
case FormatterType::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("$dd", QString("%1").arg(days, 3, 10, QChar('0')));
source.replace("$d", QString("%1").arg(days));
source.replace("$hh", QString("%1").arg(hours, 2, 10, QChar('0')));
source.replace("$h", QString("%1").arg(hours));
source.replace("$mm", QString("%1").arg(minutes, 2, 10, QChar('0')));
source.replace("$m", QString("%1").arg(minutes));
return source;
}(m_mapper->formatter(_key) == FormatterType::Uptime ? "$ddd$hhh$mmm" : m_customUptime,
static_cast<int>(_data.toFloat()));
break;
case FormatterType::NoFormat:
output = _data.toString();
break;
case FormatterType::Custom:
if (m_customFormatters)
output = m_customFormatters->convert(_data, _key);
break;
}
// replace spaces to non-breakable ones
replaceSpace &= (!_key.startsWith("custom") && (!_key.startsWith("weather")));
if (replaceSpace)
output.replace(" ", "&nbsp;");
return output;
}
QStringList AWKeysAggregator::keysFromSource(const QString &_source) const
{
qCDebug(LOG_AW) << "Search for source" << _source;
return m_mapper->keysFromSource(_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_mapper->setDevices(_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;
}
QStringList AWKeysAggregator::registerSource(const QString &_source, const QString &_units, const QStringList &_keys)
{
qCDebug(LOG_AW) << "Source" << _source << "with units" << _units;
return m_mapper->registerSource(_source, _units, _keys);
}
float AWKeysAggregator::temperature(const float temp) const
{
qCDebug(LOG_AW) << "Temperature value" << temp;
float converted = temp;
if (m_tempUnits == "Celsius") {
} else if (m_tempUnits == "Fahrenheit") {
converted = temp * 9.0f / 5.0f + 32.0f;
} else if (m_tempUnits == "Kelvin") {
converted = temp + 273.15f;
} else if (m_tempUnits == "Reaumur") {
converted = temp * 0.8f;
} else if (m_tempUnits == "cm^-1") {
converted = (temp + 273.15f) * 0.695f;
} else if (m_tempUnits == "kJ/mol") {
converted = (temp + 273.15f) * 8.31f;
} else if (m_tempUnits == "kcal/mol") {
converted = (temp + 273.15f) * 1.98f;
} else {
qCWarning(LOG_AW) << "Invalid units" << m_tempUnits;
}
return converted;
}

View File

@ -0,0 +1,101 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWKEYSAGGREGATOR_H
#define AWKEYSAGGREGATOR_H
#include <QHash>
#include <QObject>
class AWFormatterHelper;
class AWDataEngineMapper;
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);
public:
enum class FormatterType {
// general formatters
Custom,
NoFormat,
Float,
FloatTwoSymbols,
Integer,
IntegerFive,
IntegerThree,
List,
// unit specific formatters
ACFormat,
MemGBFormat,
MemMBFormat,
NetSmartFormat,
NetSmartUnits,
Quotes,
Temperature,
Time,
TimeCustom,
TimeISO,
TimeLong,
TimeShort,
Timestamp,
Uptime,
UptimeCustom
};
explicit AWKeysAggregator(QObject *_parent = nullptr);
~AWKeysAggregator() override;
void initFormatters();
// get methods
[[nodiscard]] QString formatter(const QVariant &_data, const QString &_key, bool replaceSpace) const;
[[nodiscard]] 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(bool _translate);
public slots:
QStringList registerSource(const QString &_source, const QString &_units, const QStringList &_keys);
private:
[[nodiscard]] float temperature(float temp) const;
AWFormatterHelper *m_customFormatters = nullptr;
AWDataEngineMapper *m_mapper = nullptr;
QStringList m_timeKeys;
// variables
QString m_acOffline;
QString m_acOnline;
QString m_customTime;
QString m_customUptime;
QString m_tempUnits;
bool m_translate = false;
};
#endif /* AWKEYSAGGREGATOR_H */

View File

@ -0,0 +1,51 @@
/***************************************************************************
* 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 "awpairconfigfactory.h"
#include "awcustomkeysconfig.h"
#include "awdebug.h"
#include "awformatterconfig.h"
AWPairConfigFactory::AWPairConfigFactory(QObject *_parent)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWPairConfigFactory::~AWPairConfigFactory()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWPairConfigFactory::showFormatterDialog(const QStringList &_keys)
{
auto *config = new AWFormatterConfig(nullptr, _keys);
config->showDialog();
config->deleteLater();
}
void AWPairConfigFactory::showKeysDialog(const QStringList &_keys)
{
auto *config = new AWCustomKeysConfig(nullptr, _keys);
config->showDialog();
config->deleteLater();
}

View File

@ -0,0 +1,39 @@
/***************************************************************************
* 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 AWPAIRCONFIGFACTORY_H
#define AWPAIRCONFIGFACTORY_H
#include <QObject>
class AWPairConfigFactory : public QObject
{
Q_OBJECT
public:
explicit AWPairConfigFactory(QObject *_parent = nullptr);
~AWPairConfigFactory() override;
Q_INVOKABLE static void showFormatterDialog(const QStringList &_keys);
Q_INVOKABLE static void showKeysDialog(const QStringList &_keys);
private:
};
#endif /* AWPAIRCONFIGFACTORY_H */

View File

@ -0,0 +1,270 @@
/***************************************************************************
* 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 lambdas in" << _code;
QJSEngine engine;
// apply $this values
_code.replace("$this", _metadata[_code].toString());
// parsed values
for (auto &lambdaKey : _usedKeys)
_code.replace(QString("$%1").arg(lambdaKey), _aggregator->formatter(_metadata[lambdaKey], lambdaKey, false));
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 "";
} 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(R"(\$template\{\{(?<body>.*?)\}\})");
templatesRegexp.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(_code);
while (it.hasNext()) {
QRegularExpressionMatch match = it.next();
QString body = match.captured("body");
QJSEngine engine;
qCInfo(LOG_AW) << "Expression" << body;
QJSValue result = engine.evaluate(body);
QString templateResult = "";
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;
}
QList<AWPatternFunctions::AWFunction> 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 should be screened
// by using $, e.g. ${
QRegularExpression regex(QString(R"(\$%1\<(?<args>.*?)\>\{\{(?<body>.*?)\}\})").arg(_function));
regex.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
QList<AWPatternFunctions::AWFunction> foundFunctions;
QRegularExpressionMatchIterator it = regex.globalMatch(_code);
while (it.hasNext()) {
QRegularExpressionMatch match = it.next();
AWPatternFunctions::AWFunction metadata;
// work with args
QString argsString = match.captured("args");
if (argsString.isEmpty()) {
metadata.args = QStringList();
} else {
// replace '$,' to 0x1d
argsString.replace("$,", QString(0x1d));
QStringList args = argsString.split(',');
std::for_each(args.begin(), args.end(), [](QString &arg) { arg.replace(QString(0x1d), ","); });
metadata.args = args;
}
// other variables
metadata.body = match.captured("body");
metadata.what = match.captured();
// replace brackets
metadata.body.replace("${", "{");
metadata.body.replace("$}", "}");
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;
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_all", _code);
for (auto &function : found) {
QString separator = function.args.isEmpty() ? "," : function.args.at(0);
QStringList required = _keys.filter(QRegExp(function.body));
std::for_each(required.begin(), required.end(), [](QString &value) { value = QString("%1: $%1").arg(value); });
_code.replace(function.what, 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;
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_count", _code);
for (auto &function : found) {
int count = _keys.filter(QRegExp(function.body)).count();
_code.replace(function.what, 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;
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_names", _code);
for (auto &function : found) {
QString separator = function.args.isEmpty() ? "," : function.args.at(0);
QStringList required = _keys.filter(QRegExp(function.body));
_code.replace(function.what, 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;
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_keys", _code);
for (auto &function : found) {
QString separator = function.args.isEmpty() ? "," : function.args.at(0);
QStringList required = _keys.filter(QRegExp(function.body));
std::for_each(required.begin(), required.end(), [](QString &value) { value = QString("$%1").arg(value); });
_code.replace(function.what, required.join(separator));
}
return _code;
}
QString AWPatternFunctions::insertMacros(QString _code)
{
qCDebug(LOG_AW) << "Looking for macros in code" << _code;
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_macro", _code);
for (auto &macro : found) {
// get macro params
if (macro.args.isEmpty()) {
qCWarning(LOG_AW) << "No macro name found for" << macro.what;
continue;
}
QString name = macro.args.takeFirst();
// find macro usage
QList<AWPatternFunctions::AWFunction> macroUsage
= AWPatternFunctions::findFunctionCalls(QString("aw_macro_%1").arg(name), _code);
for (auto &function : macroUsage) {
if (function.args.count() != macro.args.count()) {
qCWarning(LOG_AW) << "Invalid args count found for call" << function.what << "with macro" << macro.what;
continue;
}
// generate body to replace
QString result = macro.body;
std::for_each(macro.args.cbegin(), macro.args.cend(), [&result, macro, function](const QString &arg) {
int index = macro.args.indexOf(arg);
result.replace(QString("$%1").arg(arg), function.args.at(index));
});
// do replace
_code.replace(function.what, result);
}
// remove macro from source pattern
_code.remove(macro.what);
}
return _code;
}
QStringList AWPatternFunctions::findKeys(const QString &_code, const QStringList &_keys, const bool _isBars)
{
qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" << _keys;
QStringList selectedKeys;
QString replacedCode = _code;
for (auto &key : _keys)
if ((key.startsWith("bar") == _isBars) && (replacedCode.contains(QString("$%1").arg(key)))) {
qCInfo(LOG_AW) << "Found key" << key << "with bar enabled" << _isBars;
selectedKeys.append(key);
replacedCode.replace(QString("$%1").arg(key), "");
}
if (selectedKeys.isEmpty())
qCWarning(LOG_AW) << "No keys found";
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(R"(\$\{\{(?<body>.*?)\}\})");
lambdaRegexp.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
QRegularExpressionMatchIterator it = lambdaRegexp.globalMatch(_code);
while (it.hasNext()) {
QRegularExpressionMatch match = it.next();
QString lambda = match.captured("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,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 AWPATTERNFUNCTIONS_H
#define AWPATTERNFUNCTIONS_H
#include <QString>
#include <QVariant>
class AWKeysAggregator;
namespace AWPatternFunctions
{
typedef struct {
QStringList args;
QString body;
QString what;
} AWFunction;
// insert methods
QString expandLambdas(QString _code, AWKeysAggregator *_aggregator, const QVariantHash &_metadata,
const QStringList &_usedKeys);
QString expandTemplates(QString _code);
QList<AWFunction> 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);
QString insertMacros(QString _code);
// find methods
QStringList findKeys(const QString &_code, const QStringList &_keys, bool _isBars);
QStringList findLambdas(const QString &_code);
} // namespace AWPatternFunctions
#endif /* AWPATTERNFUNCTIONS_H */

View File

@ -0,0 +1,179 @@
/***************************************************************************
* 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 "awtelemetryhandler.h"
#include <QJsonDocument>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSettings>
#include <QStandardPaths>
#include <QUuid>
#include "awdebug.h"
AWTelemetryHandler::AWTelemetryHandler(QObject *_parent, const QString &_clientId)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_localFile = QString("%1/awesomewidgets/telemetry.ini")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
// override client id if any
if (!_clientId.isEmpty())
m_clientId = _clientId;
}
AWTelemetryHandler::~AWTelemetryHandler()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QStringList AWTelemetryHandler::get(const QString &_group) const
{
qCDebug(LOG_AW) << "Get stored data for group" << _group;
QStringList values;
QSettings settings(m_localFile, QSettings::IniFormat);
settings.beginGroup(_group);
for (auto &key : settings.childKeys())
values.append(settings.value(key).toString());
settings.endGroup();
return values;
}
QString AWTelemetryHandler::getLast(const QString &_group) const
{
qCDebug(LOG_AW) << "Get last stored data for group" << _group;
return get(_group).last();
}
void AWTelemetryHandler::init(const int _count, const bool _enableRemote, const QString &_clientId)
{
qCDebug(LOG_AW) << "Init telemetry with count" << _count << "enable remote" << _enableRemote << "client ID"
<< _clientId;
m_storeCount = _count;
m_uploadEnabled = _enableRemote;
m_clientId = _clientId;
}
bool AWTelemetryHandler::put(const QString &_group, const QString &_value) const
{
qCDebug(LOG_AW) << "Store data with group" << _group << "and value" << _value;
QSettings settings(m_localFile, QSettings::IniFormat);
settings.beginGroup(_group);
// values will be stored as num=value inside specified group
// load all values to memory
QStringList saved;
for (auto &key : settings.childKeys())
saved.append(settings.value(key).toString());
// check if this value is already saved
if (saved.contains(_value)) {
qCInfo(LOG_AW) << "Configuration" << _value << "for group" << _group << "is already saved";
return false;
}
saved.append(_value);
// remove old ones
while (saved.count() > m_storeCount)
saved.takeFirst();
// clear group
settings.remove("");
// and save now
for (auto &val : saved) {
QString key = getKey(settings.childKeys().count());
settings.setValue(key, val);
}
// sync settings
settings.endGroup();
settings.sync();
// return status
return (settings.status() == QSettings::NoError);
}
void AWTelemetryHandler::uploadTelemetry(const QString &_group, const QString &_value)
{
qCDebug(LOG_AW) << "Upload data with group" << _group << "and value" << _value;
if (!m_uploadEnabled) {
qCInfo(LOG_AW) << "Upload disabled by configuration";
return;
}
auto *manager = new QNetworkAccessManager(nullptr);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(telemetryReplyRecieved(QNetworkReply *)));
QUrl url(REMOTE_TELEMETRY_URL);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
// generate payload
QVariantMap payload;
payload["api"] = AW_TELEMETRY_API;
payload["client_id"] = m_clientId;
payload["metadata"] = _value;
payload["type"] = _group;
// convert to QByteArray to send request
QByteArray data = QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact);
qCInfo(LOG_AW) << "Send request with body" << data.data() << "and size" << data.size();
manager->post(request, data);
}
void AWTelemetryHandler::telemetryReplyRecieved(QNetworkReply *_reply)
{
if (_reply->error() != QNetworkReply::NoError) {
qCWarning(LOG_AW) << "An error occurs" << _reply->error() << "with message" << _reply->errorString();
return;
}
QJsonParseError error{};
QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_AW) << "Parse error" << error.errorString();
return;
}
_reply->deleteLater();
// convert to map
QVariantMap response = jsonDoc.toVariant().toMap();
QString message = response["message"].toString();
qCInfo(LOG_AW) << "Server reply on telemetry" << message;
return emit(replyReceived(message));
}
QString AWTelemetryHandler::getKey(const int _count)
{
qCDebug(LOG_AW) << "Get key for keys count" << _count;
return QString("%1").arg(_count, 3, 10, QChar('0'));
}

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