Compare commits

...

120 Commits

Author SHA1 Message Date
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
202 changed files with 16174 additions and 12638 deletions

47
.gitignore vendored
View File

@ -1,7 +1,48 @@
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
# clion settings
.idea

3
.gitmodules vendored
View File

@ -1,6 +1,3 @@
[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

11
.travis.yml.bckp Normal file
View File

@ -0,0 +1,11 @@
install:
- sudo apt-get update -qq
- sudo apt-get install -y cmake extra-cmake-modules g++ git libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev
- git submobule update --init
- rm -rf build
- mkdir build
script:
- cd build
- cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DKDE_INSTALL_USE_QT_SYS_PATHS=ON ../sources
- make

View File

@ -1,3 +1,70 @@
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)

View File

@ -1,3 +1,70 @@
Вер.3.0.1:
+ добавлены патчи для старых версий Qt
- убрана проверка на nullptr
* диалоги перемещены в QML
Вер.3.0.0:
+ добавлены теги upunits, downunits, upkb, downkb
+ добавлены теги dalbum, dartist, dtitle, salbum, sartist, stitle
+ добавлена поддержка лямбда функций
+ добавлен голландский перевод (спасибо Heimen Stoffels)
+ добавлена опциональная проверка обновлений на старте
+ добавлена возможность отключить перевод строковых тегов
+ добавлена фильтрация в ExtUpgrade (ApiVer == 3)
+ добавлена возможность смены иконки погоды (ApiVer == 2)
+ показ сообщений, если не найдено обновлений, при прямом запросе
+ добавлено перенаправление swap в ExtScript (ApiVer == 4)
+ добавлена возможность переноса слов
+ добавлена поддержка графиков в GraphicalItems (ApiVer == 3)
+ добавлена возможность показать превью из настроек
+ добавлены импорт и экспорт конфигурации
- исправлен ворнинг для пустых тултипов
- исправлен баг, приводящий к увеличению виджета
- исправлен баг с отсутствием сохранения настроек DE
- исправлен баг с большим размером на старте
- исправлен баг с невозможностью использования более, чем 10 расширений
- убраны уведомления о свободном месте на диске
- убран ключ X-AW-Output в ExtScript (ApiVer == 4)
- исправлен возможное падение при вызове деструктора web-источников
* более удобный интерфейс настройки
* улучшено логирование, применен стиль логирования Qt5
* переключено на конкурентное обновление (-DBUILD_FUTURE=ON)
* немного оптимизаций
* лучшее определение активного сетевого устройства
* значение котировок типа double (ApiVer == 3)
* лучший показ котировок
* больше комментариев в коде
* большее следование стилю кода Qt
* настройки интервала перемещены в другую группу
* работа с DataEngine была перемещена в плагин
* изменен формат данных внутри DataEngine (ломает совместимость)
Вер.2.4.0:
+ добавлена поддержка погоды
+ добавлена поддержка LA (теги la1, la5, la15)
+ добавлена кнопка "Сбросить кеш"
+ добавлена поддержка сборки с clang
+ добавлен ExtItem агрегатор
+ добавлено время в дебаг вывод
+ добавлена возможность отключить монитор плеера
- исправлен баг с неправильным расчетам скорости сети
- исправлен баг с неправильной инициализацией диалога шрифтов
- исправлен баг с отсутствием удаления объектов (#60)
* переписаны ExtItems для использования собственного абстрактного класса
* улучшена работа с обновлениями виджета (#57)
* рисование интерфейса переписано на модель сигнал-слот
* плагин опять стал приватным
* исправлен каст плагина с синглтона (#57)
* изменена логика показа данных в DataEngine
* изменена сборка пакета и прекращена поддержка отдельного пакета с DataEngine
* замена QMap на QHash, если возможно
* замена циклов на итераторы, если возможно
* список рабочий столов сейчас представлен, как QStringList
* рефакторинг
Вер.2.3.3:
* изменен рендеринг с Qt на нативный
Вер.2.3.2:
+ добавлено изменение скорости интернета с KB/s на MB/s, если величина более 1000 KB/s
- пофикшен баг с отсутствием действия при активации ссылки (спасибо infans)

234
CONTRIBUTING.md Normal file
View File

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

View File

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

View File

@ -35,7 +35,7 @@ Optional dependencies
* proprietary video driver
* hddtemp
* smartmontools
* music player (mpd or supported MPRIS)
* music player (mpd or MPRIS supported)
Make dependencies
-----------------
@ -53,7 +53,7 @@ Installation
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr ../
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
======================

View File

@ -1,27 +1,18 @@
#!/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')
MAJOR=$(grep -m1 PROJECT_VERSION_MAJOR sources/CMakeLists.txt | awk '{print $2}' | sed 's/^.\(.*\)..$/\1/')
MINOR=$(grep -m1 PROJECT_VERSION_MINOR sources/CMakeLists.txt | awk '{print $2}' | sed 's/^.\(.*\)..$/\1/')
PATCH=$(grep -m1 PROJECT_VERSION_PATCH sources/CMakeLists.txt | awk '{print $2}' | sed 's/^.\(.*\)..$/\1/')
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}"
# build widget
ARCHIVE="awesome-widgets"
FILES="AUTHORS CHANGELOG CHANGELOG-RU COPYING"
IGNORELIST="build usr .kdev4 *.kdev4"
IGNORELIST="build usr .kdev4 *.kdev4 .idea"
# create archive
[[ -e ${ARCHIVE}-${VERSION}-src.tar.xz ]] && rm -f "${ARCHIVE}-${VERSION}-src.tar.xz"
[[ -d ${ARCHIVE} ]] && rm -rf "${ARCHIVE}"
@ -29,13 +20,13 @@ 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
ln -sf "../${ARCHIVE}-${VERSION}-src.tar.xz" packages
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
sed -i "/md5sums=('[0-9A-Fa-f]*/s/[^'][^)]*/md5sums=('${MD5SUMS}'/" packages/PKGBUILD
sed -i "s/pkgver=[0-9.]*/pkgver=${VERSION}/" packages/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 {} \;
find packages -type l -xtype l -exec rm -rf {} \;

View File

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

View File

@ -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')

View File

@ -0,0 +1,11 @@
cmake
extra-cmake-modules
g++
git
libkf5i18n-dev
libkf5notifications-dev
libkf5service-dev
libkf5windowsystem-dev
plasma-framework-dev
qtbase5-dev
qtdeclarative5-dev

View File

View File

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

View File

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

View File

@ -0,0 +1,29 @@
diff --git a/sources/awesome-widget/plugin/awkeysaggregator.h b/sources/awesome-widget/plugin/awkeysaggregator.h
index f808d03..a056b3f 100644
--- a/sources/awesome-widget/plugin/awkeysaggregator.h
+++ b/sources/awesome-widget/plugin/awkeysaggregator.h
@@ -21,6 +21,7 @@
#include <QHash>
#include <QObject>
+#include <QStringList>
#include "version.h"
diff --git a/sources/awdebug.h b/sources/awdebug.h
index 48dc580..530c0d6 100644
--- a/sources/awdebug.h
+++ b/sources/awdebug.h
@@ -23,9 +23,9 @@
#ifndef LOG_FORMAT
#define LOG_FORMAT \
- "[%{time process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%{if-" \
- "warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{" \
- "category}][%{function}] %{message}"
+ "[%{time process}][%{if-debug}DD%{endif}%{if-warning}WW%{endif}%{if-" \
+ "critical}CC%{endif}%{if-fatal}FF%{endif}][%{category}][%{function}] " \
+ "%{message}"
#endif /* LOG_FORMAT */
// redefine info because it doesn't log properly

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

66
sources/.clang-format Normal file
View File

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

View File

@ -8,7 +8,7 @@ ProjectRootRelative=./
[CMake][CMake Build Directory 0]
Build Directory Path=file:///home/arcanis/Documents/github/awesome-widgets/build
Build Type=Release
Build Type=Optimization
CMake Binary=file:///usr/bin/cmake
Environment Profile=
Extra Arguments=
@ -19,5 +19,8 @@ Name=GCC
Path=gcc
Type=GCC
[Launch]
Launch Configurations=
[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>

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()
{
QNetworkReply *reply = static_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();
};

View File

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

84
sources/awdebug.cpp Normal file
View File

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

46
sources/awdebug.h Normal file
View File

@ -0,0 +1,46 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWDEBUG_H
#define AWDEBUG_H
#include <QLoggingCategory>
#ifndef LOG_FORMAT
#define LOG_FORMAT \
"[%{time process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%{if-" \
"warning}WW%{endif}%{if-critical}CC%{endif}%{if-fatal}FF%{endif}][%{" \
"category}][%{function}] %{message}"
#endif /* LOG_FORMAT */
// redefine info because it doesn't log properly
#ifdef qCInfo
#undef qCInfo
#endif /* qCInfo */
#define qCInfo qCDebug
Q_DECLARE_LOGGING_CATEGORY(LOG_AW)
Q_DECLARE_LOGGING_CATEGORY(LOG_DP)
Q_DECLARE_LOGGING_CATEGORY(LOG_ESM)
Q_DECLARE_LOGGING_CATEGORY(LOG_LIB)
const QStringList getBuildData();
#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)
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

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

View File

@ -19,17 +19,21 @@ 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
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 {
@ -39,32 +43,33 @@ Item {
height: parent.height
width: parent.width
QtControls.Tab {
anchors.margins: 10.0
title: i18n("About")
QtLayouts.ColumnLayout {
QtControls.Label {
QtLayouts.Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
text: AWActions.getAboutText("header")
text: awActions.getAboutText("header")
}
QtControls.Label {
QtLayouts.Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
text: AWActions.getAboutText("version")
text: awActions.getAboutText("version")
}
QtControls.Label {
QtLayouts.Layout.fillWidth: true
horizontalAlignment: Text.AlignJustify
text: AWActions.getAboutText("description")
text: awActions.getAboutText("description")
}
QtControls.Label {
QtLayouts.Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft
textFormat: Text.RichText
text: AWActions.getAboutText("links")
text: awActions.getAboutText("links")
onLinkActivated: Qt.openUrlExternally(link);
}
@ -75,12 +80,13 @@ Item {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
textFormat: Text.RichText
text: AWActions.getAboutText("copy")
text: awActions.getAboutText("copy")
}
}
}
QtControls.Tab {
anchors.margins: 10.0
title: i18n("Acknowledgment")
QtLayouts.ColumnLayout {
@ -88,16 +94,17 @@ Item {
QtLayouts.Layout.fillWidth: true
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignJustify
text: AWActions.getAboutText("translators")
text: awActions.getAboutText("translators")
}
QtControls.Label {
QtLayouts.Layout.fillHeight: true
QtLayouts.Layout.fillWidth: true
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignJustify
verticalAlignment: Text.AlignTop
textFormat: Text.RichText
text: AWActions.getAboutText("3rdparty")
text: awActions.getAboutText("3rdparty")
onLinkActivated: Qt.openUrlExternally(link);
}
}
@ -105,7 +112,8 @@ Item {
}
}
Component.onCompleted: {
if (debug) console.log("[about::onCompleted]")
if (debug) console.debug()
}
}

View File

@ -17,27 +17,41 @@
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import QtQuick.Dialogs 1.2 as QtDialogs
import org.kde.plasma.awesomewidget 1.0
import org.kde.plasma.private.awesomewidget 1.0
Item {
id: advancedPage
// backend
AWActions {
id: awActions
}
AWConfigHelper {
id: awConfig
}
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_height: widgetHeight.value
property alias cfg_width: widgetWidth.value
property alias cfg_notify: notify.checked
property alias cfg_wrapNewLines: wrapNewLines.checked
property alias cfg_background: background.checked
property alias cfg_interval: update.value
property alias cfg_queueLimit: queueLimit.value
property string cfg_tempUnits: tempUnits.currentText
property alias cfg_customTime: customTime.text
property alias cfg_customUptime: customUptime.text
property string cfg_tempUnits: tempUnits.currentText
property alias cfg_acOnline: acOnline.text
property alias cfg_acOffline: acOffline.text
@ -45,6 +59,90 @@ Item {
Column {
id: pageColumn
anchors.fill: parent
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: background
width: parent.width * 3 / 5
text: i18n("Enable background")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: translate
width: parent.width * 3 / 5
text: i18n("Translate strings")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: wrapNewLines
width: parent.width * 3 / 5
text: i18n("Wrap new lines")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: wordWrap
width: parent.width * 3 / 5
text: i18n("Enable word wrap")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: notify
width: parent.width * 3 / 5
text: i18n("Enable notifications")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: updates
width: parent.width * 3 / 5
text: i18n("Check updates on startup")
}
}
Row {
height: implicitHeight
width: parent.width
@ -89,41 +187,19 @@ Item {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Time interval")
}
QtControls.CheckBox {
id: notify
QtControls.SpinBox {
id: update
width: parent.width * 3 / 5
text: i18n("Enable notifications")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: wrapNewLines
width: parent.width * 3 / 5
text: i18n("Wrap new lines")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.heigth
width: parent.width * 2 / 5
}
QtControls.CheckBox {
id: background
width: parent.width * 3 / 5
text: i18n("Enable background")
minimumValue: 1000
maximumValue: 10000
stepSize: 500
value: plasmoid.configuration.interval
}
}
@ -135,29 +211,15 @@ Item {
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom time format")
text: i18n("Messages queue limit")
}
QtControls.TextField {
id: customTime
QtControls.SpinBox {
id: queueLimit
width: parent.width * 3 / 5
text: plasmoid.configuration.customTime
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom uptime format")
}
QtControls.TextField {
id: customUptime
width: parent.width * 3 / 5
text: plasmoid.configuration.customUptime
minimumValue: 0
maximumValue: 99
stepSize: 1
value: plasmoid.configuration.queueLimit
}
}
@ -207,8 +269,10 @@ Item {
]
onCurrentIndexChanged: cfg_tempUnits = model[currentIndex]["name"]
Component.onCompleted: {
if (debug) console.debug()
for (var i = 0; i < model.length; i++) {
if (model[i]["name"] == plasmoid.configuration.tempUnits) {
if (debug) console.info("Found", model[i]["name"], "on", i)
tempUnits.currentIndex = i;
}
}
@ -216,6 +280,40 @@ Item {
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom time format")
}
QtControls.TextField {
id: customTime
width: parent.width * 3 / 5
text: plasmoid.configuration.customTime
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom uptime format")
}
QtControls.TextField {
id: customUptime
width: parent.width * 3 / 5
text: plasmoid.configuration.customUptime
}
}
Row {
height: implicitHeight
width: parent.width
@ -249,9 +347,113 @@ Item {
text: plasmoid.configuration.acOffline
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Drop key cache")
onClicked: awActions.dropCache()
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Export configuration")
onClicked: saveConfigAs.open()
}
QtDialogs.FileDialog {
id: saveConfigAs
selectExisting: false
title: i18n("Export")
onAccepted: {
var status = awConfig.exportConfiguration(
plasmoid.configuration,
saveConfigAs.fileUrl.toString().replace("file://", ""))
if (status) {
messageDialog.title = i18n("Success")
messageDialog.text = i18n("Please note that binary files were not copied")
} else {
messageDialog.title = i18n("Ooops...")
messageDialog.text = i18n("Could not save configuration file")
}
messageDialog.open()
}
}
QtDialogs.MessageDialog {
id: messageDialog
standardButtons: QtDialogs.StandardButton.Ok
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Import configuration")
onClicked: openConfig.open()
}
QtDialogs.FileDialog {
id: openConfig
title: i18n("Import")
onAccepted: importSelection.open()
}
QtDialogs.Dialog {
id: importSelection
Column {
QtControls.CheckBox {
id: importPlasmoid
text: i18n("Import plasmoid settings")
}
QtControls.CheckBox {
id: importExtensions
text: i18n("Import extensions")
}
QtControls.CheckBox {
id: importAdds
text: i18n("Import additional files")
}
}
onAccepted: {
if (debug) console.debug()
var importConfig = awConfig.importConfiguration(
openConfig.fileUrl.toString().replace("file://", ""),
importPlasmoid.checked, importExtensions.checked,
importAdds.checked)
for (var key in importConfig)
plasmoid.configuration[key] = importConfig[key]
}
}
}
}
Component.onCompleted: {
if (debug) console.log("[advanced::onCompleted]")
if (debug) console.debug()
}
}

View File

@ -20,17 +20,22 @@ 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: 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,7 +44,6 @@ Item {
87: 5
}
property alias cfg_interval: update.value
property alias cfg_fontFamily: selectFont.text
property alias cfg_fontSize: fontSize.value
property string cfg_fontWeight: fontWeight.currentText
@ -50,26 +54,6 @@ Item {
Column {
id: pageColumn
anchors.fill: parent
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width / 3
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Time interval")
}
QtControls.SpinBox {
id: update
width: parent.width * 2 / 3
minimumValue: 1000
maximumValue: 10000
stepSize: 500
value: plasmoid.configuration.interval
}
}
Row {
height: implicitHeight
width: parent.width
@ -84,7 +68,11 @@ Item {
id: selectFont
width: parent.width * 2 / 3
text: plasmoid.configuration.fontFamily
onClicked: fontDialog.visible = true
onClicked: {
if (debug) console.debug()
fontDialog.setFont()
fontDialog.visible = true
}
}
}
@ -146,8 +134,10 @@ Item {
]
onCurrentIndexChanged: cfg_fontWeight = model[currentIndex]["name"]
Component.onCompleted: {
if (debug) console.debug()
for (var i = 0; i < model.length; i++) {
if (model[i]["name"] == plasmoid.configuration.fontWeight) {
if (debug) console.info("Found", model[i]["name"], "on", i)
fontWeight.currentIndex = i;
}
}
@ -181,8 +171,10 @@ Item {
]
onCurrentIndexChanged: cfg_fontStyle = model[currentIndex]["name"]
Component.onCompleted: {
if (debug) console.debug()
for (var i = 0; i < model.length; i++) {
if (model[i]["name"] == plasmoid.configuration.fontStyle) {
if (debug) console.info("Found", model[i]["name"], "on", i)
fontStyle.currentIndex = i;
}
}
@ -224,16 +216,28 @@ Item {
QtDialogs.FontDialog {
id: fontDialog
title: i18n("Select a font")
font: Qt.font({ family: selectFont.text, pointSize: fontSize.value, weight: Font.Normal })
signal setFont
onAccepted: {
if (debug) console.debug()
selectFont.text = fontDialog.font.family
fontSize.value = fontDialog.font.pointSize
fontStyle.currentIndex = fontDialog.font.italic ? 1 : 0
fontWeight.currentIndex = weight[fontDialog.font.weight]
}
onSetFont: {
if (debug) console.debug()
fontDialog.font = Qt.font({
family: selectFont.text,
pointSize: fontSize.value > 0 ? fontSize.value : 12,
italic: fontStyle.currentIndex == 1,
weight: Font.Normal,
})
}
}
Component.onCompleted: {
if (debug) console.log("[appearance::onCompleted]")
if (debug) console.debug()
}
}

View File

@ -16,273 +16,347 @@
***************************************************************************/
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
text: i18n("ACPI path")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["ACPIPATH"]
title: i18n("ACPI")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("ACPI path")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["ACPIPATH"]
onEditingFinished: cfg_dataengine["ACPIPATH"] = text
}
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom scripts")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit scripts")
onClicked: AWKeys.editItem("extscript")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("GPU device")
}
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;
title: i18n("GPU")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("GPU device")
}
QtControls.ComboBox {
id: gpuDev
width: parent.width * 3 / 5
model: ["auto", "disable", "ati", "nvidia"]
Component.onCompleted: {
if (debug) console.debug()
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["GPUDEV"]) {
if (debug) console.info("Found", model[i], "on", i)
currentIndex = i;
}
}
}
}
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("HDD")
}
QtControls.ComboBox {
id: hdd
width: parent.width * 3 / 5
model: AWKeys.getHddDevices(true)
Component.onCompleted: {
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["HDDDEV"]) {
hdd.currentIndex = i;
}
title: i18n("HDD temperature")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("HDD")
}
QtControls.ComboBox {
id: hdd
width: parent.width * 3 / 5
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("hddtemp cmd")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["HDDTEMPCMD"]
onEditingFinished: cfg_dataengine["HDDTEMPCMD"] = text
}
}
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("hddtemp cmd")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["HDDTEMPCMD"]
}
}
title: i18n("Player")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Player data symbols")
}
QtControls.SpinBox {
width: parent.width * 3 / 5
minimumValue: 1
maximumValue: 100
stepSize: 1
value: cfg_dataengine["PLAYERSYMBOLS"]
onEditingFinished: cfg_dataengine["PLAYERSYMBOLS"] = value
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPD address")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["MPDADDRESS"]
}
}
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;
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Music player")
}
QtControls.ComboBox {
id: player
width: parent.width * 3 / 5
model: ["disable", "mpris", "mpd"]
Component.onCompleted: {
if (debug) console.debug()
for (var i=0; i<model.length; i++) {
if (model[i] == cfg_dataengine["PLAYER"]) {
if (debug) console.info("Found", model[i], "on", i)
player.currentIndex = i;
}
}
}
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPRIS player name")
}
QtControls.ComboBox {
id: mpris
width: parent.width * 3 / 5
editable: true
model: ["auto", "amarok", "audacious", "clementine", "deadbeef",
"vlc", "qmmp", "xmms2", cfg_dataengine["MPRIS"]]
currentIndex: model.length - 1
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPD address")
}
QtControls.TextField {
width: parent.width * 3 / 5
text: cfg_dataengine["MPDADDRESS"]
onEditingFinished: cfg_dataengine["MPDADDRESS"] = text
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("MPD port")
}
QtControls.SpinBox {
width: parent.width * 3 / 5
minimumValue: 1000
maximumValue: 65535
stepSize: 1
value: cfg_dataengine["MPDPORT"]
onEditingFinished: cfg_dataengine["MPDPORT"] = value
}
}
}
}
Row {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Quotes monitor")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit tickers")
onClicked: AWKeys.editItem("extquotes")
}
}
title: i18n("Extensions")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Custom scripts")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit scripts")
onClicked: awKeys.editItem("extscript")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Package manager")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit command")
onClicked: AWKeys.editItem("extupgrade")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Quotes monitor")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit tickers")
onClicked: awKeys.editItem("extquotes")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Package manager")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit command")
onClicked: awKeys.editItem("extupgrade")
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Weather")
}
QtControls.Button {
width: parent.width * 3 / 5
text: i18n("Edit weather")
onClicked: awKeys.editItem("extweather")
}
}
}
}
}
Component.onCompleted: {
if (debug) console.log("[dataengine::onCompleted]")
if (debug) console.debug()
// init submodule
AWKeys.initKeys(plasmoid.configuration.text)
awKeys.updateCache()
// update hdd model
hdd.model = awKeys.getHddDevices()
for (var i=0; i<hdd.model.length; i++) {
if (hdd.model[i] == cfg_dataengine["HDDDEV"]) {
if (debug) console.info("Found", hdd.model[i], "on", i)
hdd.currentIndex = i;
}
}
}
Component.onDestruction: {
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)
awConfig.writeDataEngineConfiguration(cfg_dataengine)
}
}

View File

@ -17,26 +17,27 @@
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
}
property bool debug: awActions.isDebugEnabled()
property variant tooltipSettings: {
"tooltipNumber": plasmoid.configuration.tooltipNumber,
"useTooltipBackground": plasmoid.configuration.useTooltipBackground,
@ -55,11 +56,15 @@ Item {
"downTooltipColor": plasmoid.configuration.downTooltipColor,
"upTooltipColor": plasmoid.configuration.upTooltipColor,
"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 dropSource(string sourceName)
signal needUpdate
signal needTextUpdate(string newText)
signal needToolTipUpdate(string newText)
signal sizeUpdate
@ -75,62 +80,14 @@ 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
AWKeys.setDataBySource(sourceName, data, settings)
}
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
AWKeys.setDataBySource(sourceName, data, settings)
}
}
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]
verticalAlignment: Text.AlignVCenter
@ -141,8 +98,6 @@ Item {
font.pointSize: plasmoid.configuration.fontSize
font.weight: general.fontWeight[plasmoid.configuration.fontWeight]
text: plasmoid.configuration.text
PlasmaCore.ToolTipArea {
height: tooltip.height
width: tooltip.width
@ -155,49 +110,71 @@ Item {
}
}
QtDialogs.Dialog {
id: tagSelector
title: i18n("Select tag")
QtControls.ComboBox {
id: tagSelectorBox
width: parent.width
editable: true
}
onAccepted: {
var tag = tagSelectorBox.editText
var message = i18n("Tag: %1", tag)
message += "<br>"
message += i18n("Value: %1", awKeys.valueByKey(tag))
message += "<br>"
message += i18n("Info: %1", awKeys.infoByKey(tag))
awActions.sendNotification("tag", message)
}
}
Component.onCompleted: {
if (debug) console.log("[main::onCompleted]")
if (debug) console.debug()
// 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)
// connect data
AWKeys.dropSourceFromDataengine.connect(dropSource)
AWKeys.needToBeUpdated.connect(needUpdate)
awKeys.needTextToBeUpdated.connect(needTextUpdate)
awKeys.needToolTipToBeUpdated.connect(needToolTipUpdate)
// check updates if required
if (plasmoid.configuration.checkUpdates) return awActions.checkUpdates(false)
}
onDropSource: {
if (debug) console.log("[main::onDropSource]")
if (debug) console.log("[main::onDropSource] : Source " + sourceName)
systemmonitorDE.disconnectSource(sourceName)
}
onNeedUpdate: {
if (debug) console.log("[main::onNeedUpdate]")
text.text = AWKeys.parsePattern()
tooltip.text = AWKeys.toolTipImage()
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
@ -207,38 +184,39 @@ Item {
Plasmoid.onUserConfiguringChanged: {
if (plasmoid.userConfiguring) return
if (debug) console.log("[main::onUserConfiguringChanged]")
if (debug) console.debug()
// init submodule
AWKeys.initKeys(plasmoid.configuration.text)
AWKeys.initTooltip(tooltipSettings)
AWKeys.setPopupEnabled(plasmoid.configuration.notify)
AWKeys.setWrapNewLines(plasmoid.configuration.wrapNewLines)
needUpdate()
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit)
awKeys.initDataAggregator(tooltipSettings)
awKeys.setWrapNewLines(plasmoid.configuration.wrapNewLines)
// configure aggregator
awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline)
awKeys.setAggregatorProperty("acOnline", plasmoid.configuration.acOnline)
awKeys.setAggregatorProperty("customTime", plasmoid.configuration.customTime)
awKeys.setAggregatorProperty("customUptime", plasmoid.configuration.customUptime)
awKeys.setAggregatorProperty("tempUnits", plasmoid.configuration.tempUnits)
awKeys.setAggregatorProperty("translate", plasmoid.configuration.translateStrings)
}
function action_checkUpdates() {
if (debug) console.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()
}
function action_report() {
if (debug) console.log("[main::action_report]")
AWActions.sendEmail()
return awActions.showReadme()
}
function action_requestKey() {
if (debug) console.log("[main::action_requestKey]")
if (debug) console.debug()
AWKeys.graphicalValueByKey()
tagSelectorBox.model = awKeys.dictKeys(true)
return tagSelector.open()
}
}

View File

@ -1 +1 @@
singleton general general.qml
singleton general 1.0 general.qml

View File

@ -20,17 +20,22 @@ 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
@ -59,7 +64,7 @@ Item {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
text: i18n("CPU, CPU clock, memory, swap and network labels support graphical tooltip. To enable them just make needed checkbox fully checked.")
text: i18n("CPU, CPU clock, memory, swap and network labels support graphical tooltip. To enable them just make needed checkbox checked.")
}
Row {
@ -82,432 +87,334 @@ Item {
}
}
Row {
QtControls.GroupBox {
id: useTooltipBackground
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - useTooltipBackground.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Background")
}
QtControls.CheckBox {
id: useTooltipBackground
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("Background")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Background color")
}
QtControls.Button {
id: tooltipBackground
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.tooltipBackground
}
}
text: plasmoid.configuration.tooltipBackground
onClicked: tooltipBackgroundDialog.visible = true
}
}
QtControls.Button {
id: tooltipBackground
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.tooltipBackground
}
}
text: plasmoid.configuration.tooltipBackground
onClicked: tooltipBackgroundDialog.visible = true
}
QtDialogs.ColorDialog {
id: tooltipBackgroundDialog
title: i18n("Select a color")
color: tooltipBackground.text
onAccepted: tooltipBackground.text = tooltipBackgroundDialog.color
QtDialogs.ColorDialog {
id: tooltipBackgroundDialog
title: i18n("Select a color")
color: tooltipBackground.text
onAccepted: tooltipBackground.text = tooltipBackgroundDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: cpuTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - cpuTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("CPU color")
}
QtControls.CheckBox {
id: cpuTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("CPU")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("CPU color")
}
QtControls.Button {
id: cpuTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.cpuTooltipColor
}
}
text: plasmoid.configuration.cpuTooltipColor
onClicked: cpuTooltipColorDialog.visible = true
}
}
QtControls.Button {
id: cpuTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.cpuTooltipColor
}
}
text: plasmoid.configuration.cpuTooltipColor
onClicked: cpuTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: cpuTooltipColorDialog
title: i18n("Select a color")
color: cpuTooltipColor.text
onAccepted: cpuTooltipColor.text = cpuTooltipColorDialog.color
QtDialogs.ColorDialog {
id: cpuTooltipColorDialog
title: i18n("Select a color")
color: cpuTooltipColor.text
onAccepted: cpuTooltipColor.text = cpuTooltipColorDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: cpuclTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - cpuclTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("CPU clock color")
}
QtControls.CheckBox {
id: cpuclTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("CPU clock")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("CPU clock color")
}
QtControls.Button {
id: cpuclTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.cpuclTooltipColor
}
}
text: plasmoid.configuration.cpuclTooltipColor
onClicked: cpuclTooltipColorDialog.visible = true
}
}
QtControls.Button {
id: cpuclTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.cpuclTooltipColor
}
}
text: plasmoid.configuration.cpuclTooltipColor
onClicked: cpuclTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: cpuclTooltipColorDialog
title: i18n("Select a color")
color: cpuclTooltipColor.text
onAccepted: cpuclTooltipColor.text = cpuclTooltipColorDialog.color
QtDialogs.ColorDialog {
id: cpuclTooltipColorDialog
title: i18n("Select a color")
color: cpuclTooltipColor.text
onAccepted: cpuclTooltipColor.text = cpuclTooltipColorDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: memTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - memTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Memory color")
}
QtControls.CheckBox {
id: memTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("Memory")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Memory color")
}
QtControls.Button {
id: memTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.memTooltipColor
}
}
text: plasmoid.configuration.memTooltipColor
onClicked: memTooltipColorDialog.visible = true
}
}
QtControls.Button {
id: memTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.memTooltipColor
}
}
text: plasmoid.configuration.memTooltipColor
onClicked: memTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: memTooltipColorDialog
title: i18n("Select a color")
color: memTooltipColor.text
onAccepted: memTooltipColor.text = memTooltipColorDialog.color
QtDialogs.ColorDialog {
id: memTooltipColorDialog
title: i18n("Select a color")
color: memTooltipColor.text
onAccepted: memTooltipColor.text = memTooltipColorDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: swapTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - swapTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Swap color")
}
QtControls.CheckBox {
id: swapTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("Swap")
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Swap color")
}
QtControls.Button {
id: swapTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.swapTooltipColor
}
}
text: plasmoid.configuration.swapTooltipColor
onClicked: swapTooltipColorDialog.visible = true
}
}
QtControls.Button {
id: swapTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.swapTooltipColor
}
}
text: plasmoid.configuration.swapTooltipColor
onClicked: swapTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: swapTooltipColorDialog
title: i18n("Select a color")
color: swapTooltipColor.text
onAccepted: swapTooltipColor.text = swapTooltipColorDialog.color
QtDialogs.ColorDialog {
id: swapTooltipColorDialog
title: i18n("Select a color")
color: swapTooltipColor.text
onAccepted: swapTooltipColor.text = swapTooltipColorDialog.color
}
}
}
Row {
QtControls.GroupBox {
id: downTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - downTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Download speed color")
}
QtControls.CheckBox {
id: downTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
checkable: true
title: i18n("Network")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Download speed color")
}
QtControls.Button {
id: downTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.downTooltipColor
}
}
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
}
}
}
QtControls.Button {
id: downTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.downTooltipColor
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Upload speed color")
}
}
text: plasmoid.configuration.downTooltipColor
onClicked: downTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: downTooltipColorDialog
title: i18n("Select a color")
color: downTooltipColor.text
onAccepted: downTooltipColor.text = downTooltipColorDialog.color
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Upload speed color")
}
QtControls.Button {
id: upTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.upTooltipColor
}
}
text: plasmoid.configuration.upTooltipColor
onClicked: upTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: upTooltipColorDialog
title: i18n("Select a color")
color: upTooltipColor.text
onAccepted: upTooltipColor.text = upTooltipColorDialog.color
}
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5 - batTooltip.width
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Battery active color")
}
QtControls.CheckBox {
id: batTooltip
height: parent.height
width: implicitWidth
style: QtStyles.CheckBoxStyle {
indicator: Rectangle {
implicitWidth: 16
implicitHeight: 16
radius: 3
border.width: 1
border.color: control.activeFocus ? "darkblue" : "gray"
Rectangle {
visible: control.checked
radius: 1
anchors.fill: parent
anchors.margins: 4
color: "#555555"
border.color: "#333333"
QtControls.Button {
id: upTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.upTooltipColor
}
}
text: plasmoid.configuration.upTooltipColor
onClicked: upTooltipColorDialog.visible = true
}
}
}
QtControls.Button {
id: batTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.batTooltipColor
}
}
text: plasmoid.configuration.batTooltipColor
onClicked: batTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: batTooltipColorDialog
title: i18n("Select a color")
color: batTooltipColor.text
onAccepted: batTooltipColor.text = batTooltipColorDialog.color
QtDialogs.ColorDialog {
id: upTooltipColorDialog
title: i18n("Select a color")
color: upTooltipColor.text
onAccepted: upTooltipColor.text = upTooltipColorDialog.color
}
}
}
}
Row {
QtControls.GroupBox {
id: batTooltip
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Battery inactive color")
}
QtControls.Button {
id: batInTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.batInTooltipColor
checkable: true
title: i18n("Battery")
Column {
height: implicitHeight
width: parent.width
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Battery active color")
}
QtControls.Button {
id: batTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.batTooltipColor
}
}
text: plasmoid.configuration.batTooltipColor
onClicked: batTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: batTooltipColorDialog
title: i18n("Select a color")
color: batTooltipColor.text
onAccepted: batTooltipColor.text = batTooltipColorDialog.color
}
}
text: plasmoid.configuration.batInTooltipColor
onClicked: batInTooltipColorDialog.visible = true
}
Row {
height: implicitHeight
width: parent.width
QtControls.Label {
height: parent.height
width: parent.width * 2 / 5
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: i18n("Battery inactive color")
}
QtControls.Button {
id: batInTooltipColor
width: parent.width * 3 / 5
style: QtStyles.ButtonStyle {
background: Rectangle {
color: plasmoid.configuration.batInTooltipColor
}
}
text: plasmoid.configuration.batInTooltipColor
onClicked: batInTooltipColorDialog.visible = true
}
QtDialogs.ColorDialog {
id: batInTooltipColorDialog
title: i18n("Select a color")
color: batInTooltipColor.text
onAccepted: batInTooltipColor.text = batInTooltipColorDialog.color
QtDialogs.ColorDialog {
id: batInTooltipColorDialog
title: i18n("Select a color")
color: batInTooltipColor.text
onAccepted: batInTooltipColor.text = batInTooltipColorDialog.color
}
}
}
}
}
Component.onCompleted: {
if (debug) console.log("[tooltip::onCompleted]")
if (debug) console.debug()
}
}

View File

@ -17,48 +17,32 @@
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import org.kde.plasma.core 2.0 as PlasmaCore
import QtQuick.Dialogs 1.2 as QtDialogs
import org.kde.plasma.awesomewidget 1.0
import org.kde.plasma.private.awesomewidget 1.0
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 {
@ -82,14 +66,13 @@ Item {
iconName: "font"
onClicked: {
if (debug) console.log("[widget::onClicked] : Font button")
if (debug) console.debug("Font button")
var defaultFont = {
"color": plasmoid.configuration.fontColor,
"family": plasmoid.configuration.fontFamily,
"size": plasmoid.configuration.fontSize
}
var font = AWActions.getFont(defaultFont)
var font = awActions.getFont(defaultFont)
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -104,8 +87,7 @@ Item {
iconName: "format-indent-more"
onClicked: {
if (debug) console.log("[widget::onClicked] : Indent button")
if (debug) console.debug("Indent button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -118,8 +100,7 @@ Item {
iconName: "format-text-bold"
onClicked: {
if (debug) console.log("[widget::onClicked] : Bold button")
if (debug) console.debug("Bold button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -131,8 +112,7 @@ Item {
iconName: "format-text-italic"
onClicked: {
if (debug) console.log("[widget::onClicked] : Italic button")
if (debug) console.debug("Italic button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -144,8 +124,7 @@ Item {
iconName: "format-text-underline"
onClicked: {
if (debug) console.log("[widget::onClicked] : Underline button")
if (debug) console.debug("Underline button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -157,8 +136,7 @@ Item {
iconName: "format-text-strikethrough"
onClicked: {
if (debug) console.log("[widget::onClicked] : Strike button")
if (debug) console.debug("Strike button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -171,8 +149,7 @@ Item {
iconName: "format-justify-left"
onClicked: {
if (debug) console.log("[widget::onClicked] : Left button")
if (debug) console.debug("Left button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -184,8 +161,7 @@ Item {
iconName: "format-justify-center"
onClicked: {
if (debug) console.log("[widget::onClicked] : Center button")
if (debug) console.debug("Center button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -197,8 +173,7 @@ Item {
iconName: "format-justify-right"
onClicked: {
if (debug) console.log("[widget::onClicked] : Right button")
if (debug) console.debug("Right button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -210,8 +185,7 @@ Item {
iconName: "format-justify-fill"
onClicked: {
if (debug) console.log("[widget::onClicked] : Justify button")
if (debug) console.debug("Justify button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -223,17 +197,81 @@ Item {
Row {
height: implicitHeight
width: parent.width
QtControls.ComboBox {
width: parent.width * 1 / 5
textRole: "label"
model: [
{
'label': i18n("AC"),
'regexp': "^(ac|bat).*"
},
{
'label': i18n("Bars"),
'regexp': "^bar.*"
},
{
'label': i18n("CPU"),
'regexp': "^(cpu|gpu|la|ps|temp(?!erature)).*"
},
{
'label': i18n("Desktops"),
'regexp': "^(n|t)?desktop(s)?"
},
{
'label': i18n("HDD"),
'regexp': "^hdd.*"
},
{
'label': i18n("Memory"),
'regexp': "^(mem|swap).*"
},
{
'label': i18n("Network"),
'regexp': "^(netdev|(down|up(?!time)).*)"
},
{
'label': i18n("Music player"),
'regexp': "(^|d|s)(album|artist|duration|progress|title)"
},
{
'label': i18n("Scripts"),
'regexp': "^custom.*"
},
{
'label': i18n("Time"),
'regexp': ".*time$"
},
{
'label': i18n("Quotes"),
'regexp': "^(perc)?(ask|bid|price)(chg)?.*"
},
{
'label': i18n("Upgrades"),
'regexp': "^pkgcount.*"
},
{
'label': i18n("Weathers"),
'regexp': "^(weather(Id)?|humidity|pressure|temperature|timestamp)"
}
]
onCurrentIndexChanged: {
if (debug) console.debug()
tags.model = awKeys.dictKeys(true, model[currentIndex]["regexp"])
if (debug) console.info("Init model", tags.model, "for", model[currentIndex]["label"])
tags.currentIndex = -1
}
}
QtControls.ComboBox {
id: tags
width: parent.width - addTagButton.width - showValueButton.width
width: parent.width * 1 / 5
}
QtControls.Button {
id: addTagButton
width: parent.width * 1 / 5
text: i18n("Add")
onClicked: {
if (debug) console.log("[widget::onClicked] : Add tag button")
if (!tags.currentText) return
if (debug) console.debug("Add tag button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
@ -241,18 +279,30 @@ Item {
}
}
QtControls.Button {
id: showValueButton
width: parent.width * 1 / 5
text: i18n("Show value")
onClicked: {
if (debug) console.log("[widget::onClicked] : Show tag button")
if (!tags.currentText) return
if (debug) console.debug("Show tag button")
var message = i18n("Tag: %1", tags.currentText)
message += "<br>"
message += i18n("Value: %1", AWKeys.valueByKey(tags.currentText))
message += i18n("Value: %1", awKeys.valueByKey(tags.currentText))
message += "<br>"
message += i18n("Info: %1", AWKeys.infoByKey(tags.currentText))
AWActions.sendNotification("tag", message)
message += i18n("Info: %1", awKeys.infoByKey(tags.currentText))
awActions.sendNotification("tag", message)
}
}
QtControls.Button {
width: parent.width * 1 / 5
text: i18n("Add lambda")
onClicked: {
if (debug) console.debug("Lambda button")
var pos = textPattern.cursorPosition
var selected = textPattern.selectedText
textPattern.remove(textPattern.selectionStart, textPattern.selectionEnd)
textPattern.insert(pos, selected + "${{\n\n}}")
}
}
}
@ -261,9 +311,19 @@ Item {
height: implicitHeight
width: parent.width
QtControls.Button {
width: parent.width
width: parent.width * 3 / 5
text: i18n("Edit bars")
onClicked: AWKeys.editItem("graphicalitem")
onClicked: awKeys.editItem("graphicalitem")
}
QtControls.Button {
width: parent.width * 2 / 5
text: i18n("Preview")
onClicked: {
lock = false
awKeys.initKeys(textPattern.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit)
awKeys.needToBeUpdated()
}
}
}
@ -276,52 +336,34 @@ Item {
}
}
// we need to initializate DataEngines here too
// because we need to get keys and values
PlasmaCore.DataSource {
id: systemmonitorDE
engine: "systemmonitor"
connectedSources: systemmonitorDE.sources
interval: 5000
onNewData: {
if (debug) console.log("[widget::onNewData] : Update source " + sourceName)
AWKeys.setDataBySource(sourceName, data, settings)
}
QtDialogs.MessageDialog {
id: compiledText
modality: Qt.NonModal
title: i18n("Preview")
}
PlasmaCore.DataSource {
id: extsysmonDE
engine: "extsysmon"
connectedSources: extsysmonDE.sources
interval: 5000
onNewData: {
if (debug) console.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)
tags.model = AWKeys.dictKeys(true)
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit)
awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline)
awKeys.setAggregatorProperty("acOnline", plasmoid.configuration.acOnline)
awKeys.setAggregatorProperty("customTime", plasmoid.configuration.customTime)
awKeys.setAggregatorProperty("customUptime", plasmoid.configuration.customUptime)
awKeys.setAggregatorProperty("tempUnits", plasmoid.configuration.tempUnits)
awKeys.setAggregatorProperty("translate", plasmoid.configuration.translateStrings)
}
onNeedTextUpdate: {
if (lock) return
if (debug) console.debug()
compiledText.text = newText.replace(/&nbsp;/g, " ")
compiledText.open()
lock = true;
}
}

View File

@ -20,7 +20,7 @@ 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.3.2
X-KDE-PluginInfo-Version=3.0.1
X-KDE-PluginInfo-Website=http://arcanis.name/projects/awesome-widgets/
X-KDE-PluginInfo-Category=System Information
X-KDE-PluginInfo-Depends=

View File

@ -1,38 +1,21 @@
set (PLUGIN_NAME awplugin)
set(PLUGIN_NAME awplugin)
add_definitions(-DTRANSLATION_DOMAIN=\"plasma_applet_org.kde.plasma.awesomewidget\")
add_definitions (${Qt5Core_DEFINITIONS} ${Qt5Network_DEFINITIONS})
set (Qt_INCLUDE ${Qt5Core_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Qml_INCLUDE_DIRS})
set (Qt_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Network_LIBRARIES} ${Qt5Qml_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_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)
add_library(${PLUGIN_NAME} SHARED ${SUBPROJECT_SOURCE})
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

@ -20,111 +20,129 @@
#include <KI18n/KLocalizedString>
#include <KNotifications/KNotification>
#include <QDebug>
#include <QDesktopServices>
#include <QDir>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QProcess>
#include <QProcessEnvironment>
#include <QSettings>
#include <QStandardPaths>
#include <fontdialog/fontdialog.h>
#include <pdebug/pdebug.h>
#include "extscript.h"
#include "graphicalitem.h"
#include "awdebug.h"
#include "version.h"
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__;
}
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 *)));
// showAnyway options requires to show message if no updates found on direct
// request. In case of automatic check no message will be shown
QNetworkAccessManager *manager = new QNetworkAccessManager(nullptr);
connect(manager, &QNetworkAccessManager::finished,
[showAnyway, this](QNetworkReply *reply) {
return versionReplyRecieved(reply, showAnyway);
});
manager->get(QNetworkRequest(QUrl(VERSION_API)));
}
void AWActions::runCmd(const QString cmd)
// HACK: since QML could not use QLoggingCategory I need this hack
bool AWActions::isDebugEnabled() const
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Cmd" << cmd;
return LOG_AW().isDebugEnabled();
}
bool AWActions::runCmd(const QString cmd) const
{
qCDebug(LOG_AW) << "Cmd" << cmd;
QProcess command;
sendNotification(QString("Info"), i18n("Run %1", cmd));
command.startDetached(cmd);
return QProcess::startDetached(cmd);
}
void AWActions::sendEmail()
// HACK: this method uses variable from version.h
void AWActions::showReadme() const
{
if (debug) qDebug() << PDEBUG;
}
void AWActions::showReadme()
{
if (debug) qDebug() << PDEBUG;
QDesktopServices::openUrl(QString(HOMEPAGE));
}
QString AWActions::getAboutText(const QString type)
// HACK: this method uses variables from version.h
QString AWActions::getAboutText(const QString type) const
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Type" << type;
qCDebug(LOG_AW) << "Type" << type;
QString text;
if (type == QString("header"))
if (type == QString("header")) {
text = QString(NAME);
else if (type == QString("version"))
text = i18n("Version %1 (build date %2)", QString(VERSION), QString(BUILD_DATE));
else if (type == QString("description"))
} else if (type == QString("version")) {
text = i18n("Version %1 (build date %2)", QString(VERSION),
QString(BUILD_DATE));
if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(QString(COMMIT_SHA));
} else if (type == QString("description")) {
text = i18n("A set of minimalistic plasmoid widgets");
else if (type == QString("links"))
text = i18n("Links:") + QString("<br>") +
QString("<a href=\"%1\">%2</a><br>").arg(QString(HOMEPAGE)).arg(i18n("Homepage")) +
QString("<a href=\"%1\">%2</a><br>").arg(QString(REPOSITORY)).arg(i18n("Repository")) +
QString("<a href=\"%1\">%2</a><br>").arg(QString(BUGTRACKER)).arg(i18n("Bugtracker")) +
QString("<a href=\"%1\">%2</a><br>").arg(QString(TRANSLATION)).arg(i18n("Translation issue")) +
QString("<a href=\"%1\">%2</a><br>").arg(QString(AUR_PACKAGES)).arg(i18n("AUR packages")) +
QString("<a href=\"%1\">%2</a>").arg(QString(OPENSUSE_PACKAGES)).arg(i18n("openSUSE packages"));
else if (type == QString("copy"))
text = QString("<small>&copy; %1 <a href=\"mailto:%2\">%3</a><br>").arg(QString(DATE)).arg(QString(EMAIL)).arg(QString(AUTHOR)) +
i18n("This software is licensed under %1", QString(LICENSE)) + QString("</small>");
else if (type == QString("translators"))
} else if (type == QString("links")) {
text = i18n("Links:") + QString("<br>")
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(HOMEPAGE))
.arg(i18n("Homepage"))
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(REPOSITORY))
.arg(i18n("Repository"))
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(BUGTRACKER))
.arg(i18n("Bugtracker"))
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(TRANSLATION))
.arg(i18n("Translation issue"))
+ QString("<a href=\"%1\">%2</a><br>")
.arg(QString(AUR_PACKAGES))
.arg(i18n("AUR packages"))
+ QString("<a href=\"%1\">%2</a>")
.arg(QString(OPENSUSE_PACKAGES))
.arg(i18n("openSUSE packages"));
} else if (type == QString("copy")) {
text = QString("<small>&copy; %1 <a href=\"mailto:%2\">%3</a><br>")
.arg(QString(DATE))
.arg(QString(EMAIL))
.arg(QString(AUTHOR))
+ i18n("This software is licensed under %1", QString(LICENSE))
+ QString("</small>");
} else if (type == QString("translators")) {
text = i18n("Translators: %1", QString(TRANSLATORS));
else if (type == QString("3rdparty")) {
QStringList trdPartyList = QString(TRDPARTY_LICENSE).split(QChar(';'), QString::SkipEmptyParts);
for (int i=0; i<trdPartyList.count(); i++)
} else if (type == QString("3rdparty")) {
QStringList trdPartyList
= QString(TRDPARTY_LICENSE)
.split(QChar(';'), QString::SkipEmptyParts);
for (int i = 0; i < trdPartyList.count(); i++)
trdPartyList[i] = QString("<a href=\"%3\">%1</a> (%2 license)")
.arg(trdPartyList[i].split(QChar(','))[0])
.arg(trdPartyList[i].split(QChar(','))[1])
.arg(trdPartyList[i].split(QChar(','))[2]);
.arg(trdPartyList.at(i).split(QChar(','))[0])
.arg(trdPartyList.at(i).split(QChar(','))[1])
.arg(trdPartyList.at(i).split(QChar(','))[2]);
text = i18n("This software uses: %1", trdPartyList.join(QString(", ")));
}
@ -132,16 +150,16 @@ QString AWActions::getAboutText(const QString type)
}
QVariantMap AWActions::getFont(const QVariantMap defaultFont)
QVariantMap AWActions::getFont(const QVariantMap defaultFont) const
{
if (debug) qDebug() << PDEBUG;
qCDebug(LOG_AW) << "Default font is" << defaultFont;
QVariantMap fontMap;
CFont defaultCFont = CFont(defaultFont[QString("family")].toString(),
defaultFont[QString("size")].toInt(),
400, false, defaultFont[QString("color")].toString());
CFont font = CFontDialog::getFont(i18n("Select font"), defaultCFont,
false, false);
defaultFont[QString("size")].toInt(), 400, false,
defaultFont[QString("color")].toString());
CFont font
= CFontDialog::getFont(i18n("Select font"), defaultCFont, false, false);
fontMap[QString("color")] = font.color().name();
fontMap[QString("family")] = font.family();
fontMap[QString("size")] = font.pointSize();
@ -150,104 +168,90 @@ QVariantMap AWActions::getFont(const QVariantMap defaultFont)
}
QVariantMap 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;
qCDebug(LOG_AW) << "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);
QVariantMap configuration;
settings.beginGroup(QString("Configuration"));
configuration[QString("ACPIPATH")] = settings.value(QString("ACPIPATH"), QString("/sys/class/power_supply/"));
configuration[QString("GPUDEV")] = settings.value(QString("GPUDEV"), QString("auto"));
configuration[QString("HDDDEV")] = settings.value(QString("HDDDEV"), QString("all"));
configuration[QString("HDDTEMPCMD")] = settings.value(QString("HDDTEMPCMD"), QString("sudo smartctl -a"));
configuration[QString("MPDADDRESS")] = settings.value(QString("MPDADDRESS"), QString("localhost"));
configuration[QString("MPDPORT")] = settings.value(QString("MPDPORT"), QString("6600"));
configuration[QString("MPRIS")] = settings.value(QString("MPRIS"), QString("auto"));
configuration[QString("PLAYER")] = settings.value(QString("PLAYER"), QString("mpris"));
settings.endGroup();
return configuration;
KNotification *notification = KNotification::event(
eventId, QString("Awesome Widget ::: %1").arg(eventId), message);
notification->setComponentName(
QString("plasma-applet-org.kde.plasma.awesome-widget"));
}
void AWActions::writeDataEngineConfiguration(const QVariantMap configuration)
void AWActions::showInfo(const QString version) const
{
if (debug) qDebug() << PDEBUG;
qCDebug(LOG_AW) << "Version" << version;
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();
QString text = i18n("You are using the actual version %1", version);
if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(QString(COMMIT_SHA));
QMessageBox::information(nullptr, i18n("No new version found"), text);
}
void AWActions::sendNotification(const QString eventId, const QString message, const bool enablePopup)
void AWActions::showUpdates(const QString version) const
{
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;
qCDebug(LOG_AW) << "Version" << version;
QString text;
text += i18n("Current version : %1", QString(VERSION)) + QString("\n");
text += i18n("Current version : %1", QString(VERSION));
text += QString(COMMIT_SHA).isEmpty()
? QString("\n")
: QString(" (%1)\n").arg(QString(COMMIT_SHA));
text += i18n("New version : %1", version) + QString("\n\n");
text += i18n("Click \"Ok\" to download");
int select = QMessageBox::information(0, i18n("There are updates"), text, QMessageBox::Ok | QMessageBox::Cancel);
int select
= QMessageBox::information(nullptr, i18n("There are updates"), text,
QMessageBox::Ok | QMessageBox::Cancel);
switch (select) {
case QMessageBox::Ok:
QDesktopServices::openUrl(QString(RELEASES) + version);
break;
}
}
void AWActions::versionReplyRecieved(QNetworkReply *reply)
{
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."));
case QMessageBox::Cancel:
default:
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);
}
void AWActions::versionReplyRecieved(QNetworkReply *reply,
const bool showAnyway) const
{
qCDebug(LOG_AW) << "Return code" << reply->error();
qCDebug(LOG_AW) << "Reply error message" << reply->errorString();
qCDebug(LOG_AW) << "Show anyway" << showAnyway;
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
reply->deleteLater();
if ((reply->error() != QNetworkReply::NoError)
|| (error.error != QJsonParseError::NoError)) {
qCWarning(LOG_AW) << "Parse error" << error.errorString();
return;
}
// convert to map
QVariantMap firstRelease = jsonDoc.toVariant().toList().first().toMap();
QString version = firstRelease[QString("tag_name")].toString();
version.remove(QString("V."));
qCInfo(LOG_AW) << "Found version" << version;
// FIXME: possible there is a better way to check versions
int old_major = QString(VERSION).split(QChar('.')).at(0).toInt();
int old_minor = QString(VERSION).split(QChar('.')).at(1).toInt();
int old_patch = QString(VERSION).split(QChar('.')).at(2).toInt();
int new_major = QString(version).split(QChar('.')).at(0).toInt();
int new_minor = QString(version).split(QChar('.')).at(1).toInt();
int new_patch = QString(version).split(QChar('.')).at(2).toInt();
if ((old_major < new_major)
|| ((old_major == new_major) && (old_minor < new_minor))
|| ((old_major == new_major) && (old_minor == new_minor)
&& (old_patch < new_patch)))
return showUpdates(version);
else if (showAnyway)
return showInfo(version);
}

View File

@ -19,9 +19,7 @@
#ifndef AWACTIONS_H
#define AWACTIONS_H
#include <QMap>
#include <QObject>
#include <QVariant>
class QNetworkReply;
@ -31,31 +29,26 @@ 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);
virtual ~AWActions();
Q_INVOKABLE void checkUpdates(const bool showAnyway = false);
Q_INVOKABLE bool isDebugEnabled() const;
Q_INVOKABLE bool runCmd(const QString cmd = QString("/usr/bin/true")) const;
Q_INVOKABLE void showReadme() const;
// configuration slots
Q_INVOKABLE QString getAboutText(const QString type = QString("header"));
Q_INVOKABLE QVariantMap getFont(const QVariantMap defaultFont);
// dataengine
Q_INVOKABLE QVariantMap readDataEngineConfiguration();
Q_INVOKABLE void writeDataEngineConfiguration(const QVariantMap configuration);
Q_INVOKABLE QString getAboutText(const QString type
= QString("header")) const;
Q_INVOKABLE QVariantMap getFont(const QVariantMap defaultFont) const;
public slots:
Q_INVOKABLE static void sendNotification(const QString eventId, const QString message,
const bool enablePopup = false);
Q_INVOKABLE static void sendNotification(const QString eventId,
const QString message);
private slots:
void showUpdates(QString version);
void versionReplyRecieved(QNetworkReply *reply);
private:
// variables
bool debug = false;
void showInfo(const QString version) const;
void showUpdates(const QString version) const;
void versionReplyRecieved(QNetworkReply *reply,
const bool showAnyway) const;
};

View File

@ -0,0 +1,283 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awconfighelper.h"
#include <KI18n/KLocalizedString>
#include <QDir>
#include <QQmlPropertyMap>
#include <QSettings>
#include <QTextCodec>
#include "awdebug.h"
AWConfigHelper::AWConfigHelper(QObject *parent)
: QObject(parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWConfigHelper::~AWConfigHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
bool AWConfigHelper::dropCache() const
{
QString fileName = QString("%1/awesomewidgets.ndx")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericCacheLocation));
return QFile(fileName).remove();
}
bool AWConfigHelper::exportConfiguration(QObject *nativeConfig,
const QString fileName) const
{
qCDebug(LOG_AW) << "Selected filename" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
// plasmoid configuration
QQmlPropertyMap *configuration
= static_cast<QQmlPropertyMap *>(nativeConfig);
settings.beginGroup(QString("plasmoid"));
foreach (QString key, configuration->keys()) {
QVariant value = configuration->value(key);
if (!value.isValid())
continue;
settings.setValue(key, value);
}
settings.endGroup();
// extensions
foreach (QString item, m_dirs) {
QStringList items
= QDir(QString("%1/%2").arg(m_baseDir).arg(item))
.entryList(QStringList() << QString("*.desktop"),
QDir::Files);
settings.beginGroup(item);
foreach (QString it, items)
copyExtensions(it, item, settings, false);
settings.endGroup();
}
// additional files
settings.beginGroup(QString("json"));
// script filters
readFile(settings, QString("filters"),
QString("%1/scripts/awesomewidgets-extscripts-filters.json")
.arg(m_baseDir));
// weather icon settings
readFile(settings, QString("weathers"),
QString("%1/weather/awesomewidgets-extweather-ids.json")
.arg(m_baseDir));
settings.endGroup();
// sync settings
settings.sync();
// show additional message
return settings.status() == QSettings::NoError;
}
QVariantMap AWConfigHelper::importConfiguration(const QString fileName,
const bool importPlasmoid,
const bool importExtensions,
const bool importAdds) const
{
qCDebug(LOG_AW) << "Selected filename" << fileName;
QVariantMap configuration;
QSettings settings(fileName, QSettings::IniFormat);
// extensions
if (importExtensions) {
foreach (QString item, m_dirs) {
settings.beginGroup(item);
foreach (QString it, settings.childGroups())
copyExtensions(it, item, settings, true);
settings.endGroup();
}
}
// additional files
if (importAdds) {
settings.beginGroup(QString("json"));
// script filters
writeFile(settings, QString("filters"),
QString("%1/scripts/awesomewidgets-extscripts-filters.json")
.arg(m_baseDir));
// weather icon settings
writeFile(settings, QString("weathers"),
QString("%1/weather/awesomewidgets-extweather-ids.json")
.arg(m_baseDir));
settings.endGroup();
}
// plasmoid configuration
if (importPlasmoid) {
settings.beginGroup(QString("plasmoid"));
foreach (QString key, settings.childKeys())
configuration[key] = settings.value(key);
settings.endGroup();
}
return configuration;
}
QVariantMap AWConfigHelper::readDataEngineConfiguration() const
{
QString fileName
= QStandardPaths::locate(QStandardPaths::ConfigLocation,
QString("plasma-dataengine-extsysmon.conf"));
qCInfo(LOG_AW) << "Configuration file" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
QVariantMap configuration;
settings.beginGroup(QString("Configuration"));
configuration[QString("ACPIPATH")] = settings.value(
QString("ACPIPATH"), QString("/sys/class/power_supply/"));
configuration[QString("GPUDEV")]
= settings.value(QString("GPUDEV"), QString("auto"));
configuration[QString("HDDDEV")]
= settings.value(QString("HDDDEV"), QString("all"));
configuration[QString("HDDTEMPCMD")]
= settings.value(QString("HDDTEMPCMD"), QString("sudo smartctl -a"));
configuration[QString("MPDADDRESS")]
= settings.value(QString("MPDADDRESS"), QString("localhost"));
configuration[QString("MPDPORT")]
= settings.value(QString("MPDPORT"), QString("6600"));
configuration[QString("MPRIS")]
= settings.value(QString("MPRIS"), QString("auto"));
configuration[QString("PLAYER")]
= settings.value(QString("PLAYER"), QString("mpris"));
configuration[QString("PLAYERSYMBOLS")]
= settings.value(QString("PLAYERSYMBOLS"), QString("10"));
settings.endGroup();
qCInfo(LOG_AW) << "Configuration" << configuration;
return configuration;
}
void AWConfigHelper::writeDataEngineConfiguration(
const QVariantMap configuration) const
{
qCDebug(LOG_AW) << "Configuration" << configuration;
QString fileName
= QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)
+ QString("/plasma-dataengine-extsysmon.conf");
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Configuration"));
settings.setValue(QString("ACPIPATH"), configuration[QString("ACPIPATH")]);
settings.setValue(QString("GPUDEV"), configuration[QString("GPUDEV")]);
settings.setValue(QString("HDDDEV"), configuration[QString("HDDDEV")]);
settings.setValue(QString("HDDTEMPCMD"),
configuration[QString("HDDTEMPCMD")]);
settings.setValue(QString("MPDADDRESS"),
configuration[QString("MPDADDRESS")]);
settings.setValue(QString("MPDPORT"), configuration[QString("MPDPORT")]);
settings.setValue(QString("MPRIS"), configuration[QString("MPRIS")]);
settings.setValue(QString("PLAYER"), configuration[QString("PLAYER")]);
settings.setValue(QString("PLAYERSYMBOLS"),
configuration[QString("PLAYERSYMBOLS")]);
settings.endGroup();
settings.sync();
}
void AWConfigHelper::copyExtensions(const QString item, const QString type,
QSettings &settings,
const bool inverse) const
{
qCDebug(LOG_AW) << "Extension" << item;
qCDebug(LOG_AW) << "Type" << type;
qCDebug(LOG_AW) << "Inverse" << inverse;
settings.beginGroup(item);
QSettings itemSettings(
QString("%1/%2/%3").arg(m_baseDir).arg(type).arg(item),
QSettings::IniFormat);
itemSettings.beginGroup(QString("Desktop Entry"));
if (inverse)
copySettings(settings, itemSettings);
else
copySettings(itemSettings, settings);
itemSettings.endGroup();
settings.endGroup();
if (inverse)
itemSettings.sync();
}
void AWConfigHelper::copySettings(QSettings &from, QSettings &to) const
{
foreach (QString key, from.childKeys())
to.setValue(key, from.value(key));
}
void AWConfigHelper::readFile(QSettings &settings, const QString key,
const QString fileName) const
{
qCDebug(LOG_AW) << "Key" << key;
qCDebug(LOG_AW) << "File" << fileName;
QFile file(fileName);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QString text = QString::fromUtf8(file.readAll());
file.close();
settings.setValue(key, text);
} else {
qCWarning(LOG_LIB) << "Could not open" << file.fileName();
}
}
void AWConfigHelper::writeFile(QSettings &settings, const QString key,
const QString fileName) const
{
qCDebug(LOG_AW) << "Key" << key;
qCDebug(LOG_AW) << "File" << fileName;
if (!settings.contains(key))
return;
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
out.setCodec("UTF-8");
out << settings.value(key).toString().toUtf8();
out.flush();
file.close();
} else {
qCWarning(LOG_LIB) << "Could not open" << file.fileName();
}
}

View File

@ -0,0 +1,67 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWCONFIGHELPER_H
#define AWCONFIGHELPER_H
#include <QObject>
#include <QStandardPaths>
class QSettings;
class AWConfigHelper : public QObject
{
Q_OBJECT
public:
explicit AWConfigHelper(QObject *parent = nullptr);
virtual ~AWConfigHelper();
Q_INVOKABLE bool dropCache() const;
Q_INVOKABLE bool exportConfiguration(QObject *nativeConfig,
const QString fileName) const;
Q_INVOKABLE QVariantMap importConfiguration(const QString fileName,
const bool importPlasmoid,
const bool importExtensions,
const bool importAdds) const;
// dataengine
Q_INVOKABLE QVariantMap readDataEngineConfiguration() const;
Q_INVOKABLE void
writeDataEngineConfiguration(const QVariantMap configuration) const;
private:
// methods
void copyExtensions(const QString item, const QString type,
QSettings &settings, const bool inverse) const;
void copySettings(QSettings &from, QSettings &to) const;
void readFile(QSettings &settings, const QString key,
const QString fileName) const;
void writeFile(QSettings &settings, const QString key,
const QString fileName) const;
// properties
QString m_baseDir = QString("%1/awesomewidgets")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation));
QStringList m_dirs = QStringList()
<< QString("desktops") << QString("quotes")
<< QString("scripts") << QString("upgrade")
<< QString("weather");
};
#endif /* AWCONFIGHELPER_H */

View File

@ -0,0 +1,326 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awdataaggregator.h"
#include <KI18n/KLocalizedString>
#include <QtConcurrent/QtConcurrent>
#include <QBuffer>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPixmap>
#include <math.h>
#include "awactions.h"
#include "awdebug.h"
AWDataAggregator::AWDataAggregator(QObject *parent)
: QObject(parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
// required by signals
qRegisterMetaType<QHash<QString, QString>>("QHash<QString, QString>");
initScene();
connect(this, SIGNAL(updateData(const QHash<QString, QString> &)), this,
SLOT(dataUpdate(const QHash<QString, QString> &)));
}
AWDataAggregator::~AWDataAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
delete toolTipScene;
}
QList<float> AWDataAggregator::getData(const QString key) const
{
qCDebug(LOG_AW) << "Key" << key;
return data[QString("%1Tooltip").arg(key)];
}
QString AWDataAggregator::htmlImage(const QPixmap &source) const
{
QByteArray byteArray;
QBuffer buffer(&byteArray);
source.save(&buffer, "PNG");
return byteArray.isEmpty()
? QString()
: QString("<img src=\"data:image/png;base64,%1\"/>")
.arg(QString(byteArray.toBase64()));
}
void AWDataAggregator::setParameters(QVariantMap settings)
{
qCDebug(LOG_AW) << "Settings" << settings;
// cast from QVariantMap to QVariantHash without data lost
configuration = qvariant_cast<QVariantHash>(settings);
m_enablePopup = configuration[QString("notify")].toBool();
counts = 0;
counts += configuration[QString("cpuTooltip")].toInt();
counts += configuration[QString("cpuclTooltip")].toInt();
counts += configuration[QString("memTooltip")].toInt();
counts += configuration[QString("swapTooltip")].toInt();
counts += configuration[QString("downTooltip")].toInt();
counts += configuration[QString("batTooltip")].toInt();
// resize tooltip image
toolTipView->resize(100.0 * counts, 105.0);
boundaries[QString("cpuTooltip")] = 100.0;
boundaries[QString("cpuclTooltip")] = 4000.0;
boundaries[QString("memTooltip")] = 100.0;
boundaries[QString("swapTooltip")] = 100.0;
boundaries[QString("downTooltip")] = 1.0;
boundaries[QString("upTooltip")] = 1.0;
boundaries[QString("batTooltip")] = 100.0;
requiredKeys.clear();
if (configuration[QString("cpuTooltip")].toBool())
requiredKeys.append(QString("cpuTooltip"));
if (configuration[QString("cpuclTooltip")].toBool())
requiredKeys.append(QString("cpuclTooltip"));
if (configuration[QString("memTooltip")].toBool())
requiredKeys.append(QString("memTooltip"));
if (configuration[QString("swapTooltip")].toBool())
requiredKeys.append(QString("swapTooltip"));
if (configuration[QString("downTooltip")].toBool())
requiredKeys.append(QString("downTooltip"));
if (configuration[QString("upTooltip")].toBool())
requiredKeys.append(QString("upTooltip"));
if (configuration[QString("batTooltip")].toBool())
requiredKeys.append(QString("batTooltip"));
// background
toolTipScene->setBackgroundBrush(
configuration[QString("useTooltipBackground")].toBool()
? QBrush(QColor(
configuration[QString("tooltipBackground")].toString()))
: QBrush(Qt::NoBrush));
}
QPixmap AWDataAggregator::tooltipImage()
{
// create image
toolTipScene->clear();
QPen pen;
bool down = false;
foreach (QString key, requiredKeys) {
// create frame
float normX = 100.0 / static_cast<float>(data[key].count());
float normY = 100.0 / (1.5 * boundaries[key]);
float shift = requiredKeys.indexOf(key) * 100.0;
if (down)
shift -= 100.0;
// apply pen color
if (key != QString("batTooltip"))
pen.setColor(
QColor(configuration[QString("%1Color").arg(key)].toString()));
// paint data inside frame
for (int j = 0; j < data[key].count() - 1; j++) {
// some magic here
float x1 = j * normX + shift;
float y1 = -fabs(data[key].at(j)) * normY + 5.0;
float x2 = (j + 1) * normX + shift;
float y2 = -fabs(data[key].at(j + 1)) * normY + 5.0;
if (key == QString("batTooltip")) {
if (data[key].at(j + 1) > 0)
pen.setColor(QColor(
configuration[QString("batTooltipColor")].toString()));
else
pen.setColor(
QColor(configuration[QString("batInTooltipColor")]
.toString()));
}
toolTipScene->addLine(x1, y1, x2, y2, pen);
}
if (key == QString("downTooltip"))
down = true;
}
return toolTipView->grab();
}
void AWDataAggregator::dataUpdate(const QHash<QString, QString> &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;
qCDebug(LOG_AW) << "Value" << value;
qCDebug(LOG_AW) << "Called with extremum" << extremum;
if (value >= 0.0) {
if ((m_enablePopup) && (value > extremum)
&& (data[source].last() < extremum))
return AWActions::sendNotification(QString("event"),
notificationText(source, value));
} else {
if ((m_enablePopup) && (value < extremum)
&& (data[source].last() > extremum))
return AWActions::sendNotification(QString("event"),
notificationText(source, value));
}
}
void AWDataAggregator::checkValue(const QString source, const QString current,
const QString received) const
{
qCDebug(LOG_AW) << "Notification source" << source;
qCDebug(LOG_AW) << "Current value" << current;
qCDebug(LOG_AW) << "Received value" << received;
if ((m_enablePopup) && (current != received) && (!received.isEmpty()))
return AWActions::sendNotification(QString("event"),
notificationText(source, received));
}
void AWDataAggregator::initScene()
{
toolTipScene = new QGraphicsScene(nullptr);
toolTipView = new QGraphicsView(toolTipScene);
toolTipView->setStyleSheet(QString("background: transparent"));
toolTipView->setContentsMargins(0, 0, 0, 0);
toolTipView->setFrameShape(QFrame::NoFrame);
toolTipView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
toolTipView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
QString AWDataAggregator::notificationText(const QString source,
const float value) const
{
qCDebug(LOG_AW) << "Notification source" << source;
qCDebug(LOG_AW) << "Value" << value;
QString output;
if (source == QString("batTooltip"))
output = value > 0.0 ? i18n("AC online") : i18n("AC offline");
else if (source == QString("cpuTooltip"))
output = i18n("High CPU load");
else if (source == QString("memTooltip"))
output = i18n("High memory usage");
else if (source == QString("swapTooltip"))
output = i18n("Swap is used");
else if (source == QString("gpu"))
output = i18n("High GPU load");
return output;
}
QString AWDataAggregator::notificationText(const QString source,
const QString value) const
{
qCDebug(LOG_AW) << "Notification source" << source;
qCDebug(LOG_AW) << "Value" << value;
QString output;
if (source == QString("netdev"))
output = i18n("Network device has been changed to %1", value);
return output;
}
void AWDataAggregator::setData(const QHash<QString, QString> &values)
{
// do not log these arguments
// battery update requires info is AC online or not
setData(values[QString("ac")] == configuration[QString("acOnline")],
QString("batTooltip"), values[QString("bat")].toFloat());
// usual case
setData(QString("cpuTooltip"), values[QString("cpu")].toFloat(), 90.0);
setData(QString("cpuclTooltip"), values[QString("cpucl")].toFloat());
setData(QString("memTooltip"), values[QString("mem")].toFloat(), 90.0);
setData(QString("swapTooltip"), values[QString("swap")].toFloat(), 0.0);
setData(QString("downTooltip"), values[QString("downkb")].toFloat());
setData(QString("upTooltip"), values[QString("upkb")].toFloat());
// additional check for network device
[this](const QString value) {
checkValue(QString("netdev"), currentNetworkDevice, value);
currentNetworkDevice = value;
}(values[QString("netdev")]);
// additional check for GPU load
[this](const float value) {
checkValue(QString("gpu"), value, 90.0);
currentGPULoad = value;
}(values[QString("gpu")].toFloat());
}
void AWDataAggregator::setData(const QString &source, float value,
const float extremum)
{
qCDebug(LOG_AW) << "Source" << source;
qCDebug(LOG_AW) << "Value" << value;
qCDebug(LOG_AW) << "Called with extremum" << extremum;
if (data[source].count() == 0)
data[source].append(0.0);
else if (data[source].count()
> configuration[QString("tooltipNumber")].toInt())
data[source].removeFirst();
if (isnan(value))
value = 0.0;
// notifications
checkValue(source, value, extremum);
data[source].append(value);
if (source == QString("downTooltip")) {
QList<float> netValues
= data[QString("downTooltip")] + data[QString("upTooltip")];
boundaries[QString("downTooltip")]
= 1.2 * *std::max_element(netValues.cbegin(), netValues.cend());
boundaries[QString("upTooltip")] = boundaries[QString("downTooltip")];
}
}
void AWDataAggregator::setData(const bool dontInvert, const QString &source,
float value)
{
qCDebug(LOG_AW) << "Do not invert value" << dontInvert;
qCDebug(LOG_AW) << "Source" << source;
qCDebug(LOG_AW) << "Value" << value;
// invert values for different battery colours
value = dontInvert ? value : -value;
return setData(source, value, 0.0);
}

View File

@ -0,0 +1,79 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWTOOLTIP_H
#define AWTOOLTIP_H
#include <QObject>
#include <QVariant>
class QGraphicsScene;
class QGraphicsView;
class QPixmap;
class QThreadPool;
class AWDataAggregator : public QObject
{
Q_OBJECT
public:
explicit AWDataAggregator(QObject *parent = nullptr);
virtual ~AWDataAggregator();
QList<float> getData(const QString key) const;
QString htmlImage(const QPixmap &source) const;
void setParameters(QVariantMap settings);
QPixmap tooltipImage();
signals:
void updateData(const QHash<QString, QString> &values);
void toolTipPainted(const QString image) const;
public slots:
void dataUpdate(const QHash<QString, QString> &values);
private:
// ui
QGraphicsScene *toolTipScene = nullptr;
QGraphicsView *toolTipView = nullptr;
void checkValue(const QString source, const float value,
const float extremum) const;
void checkValue(const QString source, const QString current,
const QString received) const;
void initScene();
QString notificationText(const QString source, const float value) const;
QString notificationText(const QString source, const QString value) const;
// main method
void setData(const QHash<QString, QString> &values);
void setData(const QString &source, float value,
const float extremum = -1.0);
// different signature for battery device
void setData(const bool dontInvert, const QString &source, float value);
// variables
int counts = 0;
QVariantHash configuration;
float currentGPULoad = 0.0;
QString currentNetworkDevice = QString("lo");
QHash<QString, float> boundaries;
QHash<QString, QList<float>> data;
bool m_enablePopup = false;
QStringList requiredKeys;
};
#endif /* AWTOOLTIP_H */

View File

@ -0,0 +1,101 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awdataengineaggregator.h"
#include <Plasma/DataEngineConsumer>
#include "awdebug.h"
#include "awkeys.h"
AWDataEngineAggregator::AWDataEngineAggregator(QObject *parent,
const int interval)
: QObject(parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
setInterval(interval);
initDataEngines();
}
AWDataEngineAggregator::~AWDataEngineAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
// disconnect sources first
disconnectSources();
m_dataEngines.clear();
}
void AWDataEngineAggregator::disconnectSources()
{
foreach (QString dataengine, m_dataEngines.keys())
foreach (QString source, m_dataEngines[dataengine]->sources())
m_dataEngines[dataengine]->disconnectSource(source, parent());
}
void AWDataEngineAggregator::setInterval(const int _interval)
{
qCDebug(LOG_AW) << "Interval" << _interval;
m_interval = _interval;
}
void AWDataEngineAggregator::dropSource(const QString source)
{
qCDebug(LOG_AW) << "Source" << source;
// FIXME there is no possibility to check to which dataengine source
// connected we will try to disconnect it from systemmonitor and extsysmon
m_dataEngines[QString("systemmonitor")]->disconnectSource(source, parent());
m_dataEngines[QString("extsysmon")]->disconnectSource(source, parent());
}
void AWDataEngineAggregator::reconnectSources()
{
m_dataEngines[QString("systemmonitor")]->connectAllSources(parent(),
m_interval);
m_dataEngines[QString("extsysmon")]->connectAllSources(parent(),
m_interval);
m_dataEngines[QString("time")]->connectSource(QString("Local"), parent(),
1000);
}
void AWDataEngineAggregator::initDataEngines()
{
Plasma::DataEngineConsumer *deConsumer = new Plasma::DataEngineConsumer();
m_dataEngines[QString("systemmonitor")]
= deConsumer->dataEngine(QString("systemmonitor"));
m_dataEngines[QString("extsysmon")]
= deConsumer->dataEngine(QString("extsysmon"));
m_dataEngines[QString("time")] = deConsumer->dataEngine(QString("time"));
// additional method required by systemmonitor structure
connect(m_dataEngines[QString("systemmonitor")],
&Plasma::DataEngine::sourceAdded, [this](const QString source) {
static_cast<AWKeys *>(parent())->addDevice(source);
m_dataEngines[QString("systemmonitor")]->connectSource(
source, parent(), m_interval);
});
}

View File

@ -16,43 +16,36 @@
***************************************************************************/
#ifndef AWTOOLTIP_H
#define AWTOOLTIP_H
#ifndef AWDATAENGINEAGGREGATOR_H
#define AWDATAENGINEAGGREGATOR_H
#include <Plasma/DataEngine>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QMap>
#include <QObject>
#include <QPixmap>
#include <QVariant>
class AWToolTip : public QObject
class AWDataEngineAggregator : public QObject
{
Q_OBJECT
Q_PROPERTY(int interval MEMBER m_interval WRITE setInterval);
public:
AWToolTip(QObject *parent = nullptr, QVariantMap settings = QVariantMap());
~AWToolTip();
explicit AWDataEngineAggregator(QObject *parent = nullptr,
const int interval = 1000);
virtual ~AWDataEngineAggregator();
void disconnectSources();
// properties
void setInterval(const int _interval);
QSize getSize();
QPixmap image();
void setData(const QString source, float value,
const bool ac = true);
public slots:
void dropSource(const QString source);
void reconnectSources();
private:
// ui
QGraphicsScene *toolTipScene = nullptr;
QGraphicsView *toolTipView = nullptr;
// variables
bool debug = false;
int counts = 0;
QVariantMap configuration;
QMap<QString, float> boundaries;
QMap<QString, QList<float>> data;
QStringList requiredKeys;
QSize size;
void initDataEngines();
QHash<QString, Plasma::DataEngine *> m_dataEngines;
int m_interval;
};
#endif /* AWTOOLTIP_H */
#endif /* AWDATAENGINEAGGREGATOR_H */

View File

@ -20,31 +20,15 @@
#include <QtQml>
#include "awactions.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();
}
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<AWConfigHelper>(uri, 1, 0, "AWConfigHelper");
qmlRegisterType<AWKeys>(uri, 1, 0, "AWKeys");
}

File diff suppressed because it is too large Load Diff

View File

@ -19,111 +19,90 @@
#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>
#include "extitemaggregator.h"
class AWToolTip;
class AWDataAggregator;
class AWDataEngineAggregator;
class AWKeysAggregator;
class ExtQuotes;
class ExtScript;
class ExtUpgrade;
class ExtWeather;
class GraphicalItem;
class QThreadPool;
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);
Q_INVOKABLE void initTooltip(const QVariantMap tooltipParams);
Q_INVOKABLE void setPopupEnabled(const bool popup = false);
explicit AWKeys(QObject *parent = nullptr);
virtual ~AWKeys();
Q_INVOKABLE void initDataAggregator(const QVariantMap tooltipParams);
Q_INVOKABLE void initKeys(const QString currentPattern, const int interval,
const int limit);
Q_INVOKABLE void setAggregatorProperty(const QString key,
const QVariant value);
Q_INVOKABLE void setWrapNewLines(const bool wrap = false);
Q_INVOKABLE bool isDebugEnabled();
Q_INVOKABLE QString parsePattern();
Q_INVOKABLE QString toolTipImage();
Q_INVOKABLE QSize toolTipSize();
Q_INVOKABLE void updateCache();
// keys
Q_INVOKABLE void addDevice(const QString source);
Q_INVOKABLE QStringList dictKeys(const bool sorted = false);
Q_INVOKABLE QStringList getHddDevices();
Q_INVOKABLE void setDataBySource(const QString sourceName, const QVariantMap data,
const QVariantMap params);
Q_INVOKABLE QStringList dictKeys(const bool sorted = false,
const QString regexp = QString()) const;
Q_INVOKABLE QStringList getHddDevices() const;
// values
Q_INVOKABLE void graphicalValueByKey();
Q_INVOKABLE QString infoByKey(QString key);
Q_INVOKABLE QString valueByKey(QString key);
Q_INVOKABLE QString infoByKey(QString key) const;
Q_INVOKABLE QString valueByKey(QString key) const;
// configuration
Q_INVOKABLE void editItem(const QString type);
public slots:
void addDevice(const QString source);
void dataUpdated(const QString &sourceName,
const Plasma::DataEngine::Data &data);
// dummy method required by DataEngine connections
void modelChanged(QString, QAbstractItemModel *){};
signals:
void dropSourceFromDataengine(const QString source);
void needTextToBeUpdated(const QString newText) const;
void needToolTipToBeUpdated(const QString newText) const;
void needToBeUpdated();
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 updateTextData();
private:
// methods
void addKeyToCache(const QString type, const QString key = QString(""));
bool checkKeys(const QVariantMap data);
QString htmlValue(QString key);
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();
QString parsePattern(QString pattern) const;
void setDataBySource(const QString &sourceName, const QVariantMap &data);
// objects
AWDataAggregator *dataAggregator = nullptr;
AWDataEngineAggregator *dataEngineAggregator = nullptr;
AWKeysAggregator *aggregator = nullptr;
ExtItemAggregator<GraphicalItem> *graphicalItems = nullptr;
ExtItemAggregator<ExtQuotes> *extQuotes = nullptr;
ExtItemAggregator<ExtScript> *extScripts = nullptr;
ExtItemAggregator<ExtUpgrade> *extUpgrade = nullptr;
ExtItemAggregator<ExtWeather> *extWeather = nullptr;
// variables
bool debug = false;
bool enablePopup = false;
bool wrapNewLines = 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, hddDevices, mountDevices, networkDevices, tempDevices;
QHash<QString, QStringList> m_devices;
QStringList m_foundBars, m_foundKeys, m_foundLambdas;
QString m_pattern;
QHash<QString, QString> values;
bool m_wrapNewLines = false;
// multithread features
QThreadPool *m_threadPool = nullptr;
QMutex m_mutex;
};

View File

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

View File

@ -0,0 +1,98 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWKEYSAGGREGATOR_H
#define AWKEYSAGGREGATOR_H
#include <QHash>
#include <QObject>
#include "version.h"
class AWKeysAggregator : public QObject
{
Q_OBJECT
Q_PROPERTY(QString acOffline MEMBER m_acOffline WRITE setAcOffline);
Q_PROPERTY(QString acOnline MEMBER m_acOnline WRITE setAcOnline);
Q_PROPERTY(QString customTime MEMBER m_customTime WRITE setCustomTime);
Q_PROPERTY(
QString customUptime MEMBER m_customUptime WRITE setCustomUptime);
Q_PROPERTY(QString tempUnits MEMBER m_tempUnits WRITE setTempUnits);
Q_PROPERTY(bool translate MEMBER m_translate WRITE setTranslate);
enum FormaterType {
// general formaters
NoFormat = 0,
Float,
FloatTwoSymbols,
Integer,
IntegerThree,
List,
// unit specific formaters
ACFormat,
MemGBFormat,
MemMBFormat,
NetSmartFormat,
NetSmartUnits,
Quotes,
Temperature,
Time,
TimeCustom,
TimeISO,
TimeLong,
TimeShort,
Uptime,
UptimeCustom
};
public:
explicit AWKeysAggregator(QObject *parent = nullptr);
virtual ~AWKeysAggregator();
// get methods
QString formater(const QVariant &data, const QString &key) const;
QStringList keysFromSource(const QString &source) const;
// set methods
void setAcOffline(const QString inactive);
void setAcOnline(const QString active);
void setCustomTime(const QString customTime);
void setCustomUptime(const QString customUptime);
void setDevices(const QHash<QString, QStringList> devices);
void setTempUnits(const QString units);
void setTranslate(const bool translate);
public slots:
QStringList registerSource(const QString &source, const QString &units);
private:
float temperature(const float temp) const;
QStringList timeKeys = QString(TIME_KEYS).split(QChar(','));
// variables
QString m_acOffline;
QString m_acOnline;
QString m_customTime;
QString m_customUptime;
QHash<QString, QStringList> m_devices;
QHash<QString, FormaterType> m_formater;
QHash<QString, QString> m_map;
QString m_tempUnits;
bool m_translate = false;
};
#endif /* AWKEYSAGGREGATOR_H */

View File

@ -1,154 +0,0 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awtooltip.h"
#include <QDebug>
#include <QProcessEnvironment>
#include <math.h>
#include <pdebug/pdebug.h>
AWToolTip::AWToolTip(QObject *parent, QVariantMap settings)
: QObject(parent),
configuration(settings)
{
// debug
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
QString debugEnv = environment.value(QString("DEBUG"), QString("no"));
debug = (debugEnv == QString("yes"));
toolTipScene = new QGraphicsScene();
toolTipView = new QGraphicsView(toolTipScene);
toolTipView->setStyleSheet(QString("background: transparent"));
toolTipView->setContentsMargins(0, 0, 0, 0);
toolTipView->setFrameShape(QFrame::NoFrame);
toolTipView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
toolTipView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
counts += configuration[QString("cpuTooltip")].toInt();
counts += configuration[QString("cpuclTooltip")].toInt();
counts += configuration[QString("memTooltip")].toInt();
counts += configuration[QString("swapTooltip")].toInt();
counts += configuration[QString("downTooltip")].toInt();
counts += configuration[QString("batTooltip")].toInt();
boundaries[QString("cpuTooltip")] = 100.0;
boundaries[QString("cpuclTooltip")] = 4000.0;
boundaries[QString("memTooltip")] = 100.0;
boundaries[QString("swapTooltip")] = 100.0;
boundaries[QString("downTooltip")] = 1.0;
boundaries[QString("upTooltip")] = 1.0;
boundaries[QString("batTooltip")] = 100.0;
size.setHeight(105.0);
size.setWidth(100.0 * counts);
if (configuration[QString("cpuTooltip")].toBool()) requiredKeys.append(QString("cpuTooltip"));
if (configuration[QString("cpuclTooltip")].toBool()) requiredKeys.append(QString("cpuclTooltip"));
if (configuration[QString("memTooltip")].toBool()) requiredKeys.append(QString("memTooltip"));
if (configuration[QString("swapTooltip")].toBool()) requiredKeys.append(QString("swapTooltip"));
if (configuration[QString("downTooltip")].toBool()) requiredKeys.append(QString("downTooltip"));
if (configuration[QString("upTooltip")].toBool()) requiredKeys.append(QString("upTooltip"));
if (configuration[QString("batTooltip")].toBool()) requiredKeys.append(QString("batTooltip"));
}
AWToolTip::~AWToolTip()
{
if (debug) qDebug() << PDEBUG;
delete toolTipView;
delete toolTipScene;
}
QSize AWToolTip::getSize()
{
if (debug) qDebug() << PDEBUG;
return size;
}
QPixmap AWToolTip::image()
{
if (debug) qDebug() << PDEBUG;
toolTipView->resize(size);
// create image
toolTipScene->clear();
QPen pen = QPen();
// background
if (configuration[QString("useTooltipBackground")].toBool())
toolTipScene->setBackgroundBrush(QBrush(QColor(configuration[QString("tooltipBackground")].toString())));
else
toolTipScene->setBackgroundBrush(QBrush(Qt::NoBrush));
bool down = false;
for (int i=0; i<requiredKeys.count(); i++) {
float normX = 100.0 / static_cast<float>(data[requiredKeys[i]].count());
float normY = 100.0 / (1.5 * boundaries[requiredKeys[i]]);
if (requiredKeys[i] != QString("batTooltip"))
pen.setColor(QColor(configuration[QString("%1Color").arg(requiredKeys[i])].toString()));
float shift = i * 100.0;
if (down) shift -= 100.0;
for (int j=0; j<data[requiredKeys[i]].count()-1; j++) {
float x1 = j * normX + shift;
float y1 = - fabs(data[requiredKeys[i]][j]) * normY + 5.0;
float x2 = (j + 1) * normX + shift;
float y2 = - fabs(data[requiredKeys[i]][j+1]) * normY + 5.0;
if (requiredKeys[i] == QString("batTooltip")) {
if (data[requiredKeys[i]][j+1] > 0)
pen.setColor(QColor(configuration[QString("batTooltipColor")].toString()));
else
pen.setColor(QColor(configuration[QString("batInTooltipColor")].toString()));
}
toolTipScene->addLine(x1, y1, x2, y2, pen);
}
if (requiredKeys[i] == QString("downTooltip")) down = true;
}
return toolTipView->grab();
}
void AWToolTip::setData(const QString source, float value, const bool ac)
{
if (debug) qDebug() << PDEBUG;
if (data[source].count() == 0)
data[source].append(0.0);
else if (data[source].count() > configuration[QString("tooltipNumber")].toInt())
data[source].takeFirst();
if (isnan(value)) value = 0.0;
if (ac)
data[source].append(value);
else
data[source].append(-value);
if ((source == QString("downTooltip")) || (source == QString("upTooltip"))) {
for (int i=0; i<data[QString("downTooltip")].count(); i++)
if (boundaries[QString("downTooltip")] < data[QString("downTooltip")][i])
boundaries[QString("downTooltip")] = data[QString("downTooltip")][i];
for (int i=0; i<data[QString("upTooltip")].count(); i++)
if (boundaries[QString("downTooltip")] < data[QString("upTooltip")][i])
boundaries[QString("downTooltip")] = data[QString("upTooltip")][i];
boundaries[QString("downTooltip")] *= 1.2;
boundaries[QString("upTooltip")] = boundaries[QString("downTooltip")];
}
}

View File

@ -1,525 +0,0 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "graphicalitem.h"
#include "ui_graphicalitem.h"
#include <KI18n/KLocalizedString>
#include <QBuffer>
#include <QColorDialog>
#include <QDebug>
#include <QDir>
#include <QGraphicsEllipseItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QSettings>
#include <pdebug/pdebug.h>
#include "version.h"
GraphicalItem::GraphicalItem(QWidget *parent, const QString desktopName, const QStringList directories, const bool debugCmd)
: QDialog(parent),
m_fileName(desktopName),
m_dirs(directories),
debug(debugCmd),
ui(new Ui::GraphicalItem)
{
readConfiguration();
ui->setupUi(this);
connect(ui->pushButton_activeColor, SIGNAL(clicked()), this, SLOT(changeColor()));
connect(ui->pushButton_inactiveColor, SIGNAL(clicked()), this, SLOT(changeColor()));
}
GraphicalItem::~GraphicalItem()
{
if (debug) qDebug() << PDEBUG;
delete ui;
}
QString GraphicalItem::image(const float value)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Value" << value;
if (m_bar == QString("none")) return QString("");
QColor active = stringToColor(m_activeColor);
QColor inactive = stringToColor(m_inactiveColor);
float percent = value / 100.0;
int scale[2] = {1, 1};
QPen pen = QPen();
QGraphicsScene *scene = new QGraphicsScene();
scene->setBackgroundBrush(QBrush(Qt::NoBrush));
QGraphicsView *view = new QGraphicsView(scene);
view->setStyleSheet(QString("background: transparent"));
view->setContentsMargins(0, 0, 0, 0);
view->setFrameShape(QFrame::NoFrame);
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->resize(m_width + 5.0, m_height + 5.0);
// paint
switch (m_type) {
case Vertical:
pen.setWidth(m_width);
// inactive
pen.setColor(inactive);
scene->addLine(0.5 * m_width, -0.5 * m_width, 0.5 * m_width,
(1.0 - percent) * m_height - 0.5 * m_width, pen);
// active
pen.setColor(active);
scene->addLine(0.5 * m_width, (1.0 - percent) * m_height + 0.5 * m_width,
0.5 * m_width, m_height + 0.5 * m_width, pen);
// scale
scale[1] = -2 * static_cast<int>(m_direction) + 1;
break;
case Circle:
QGraphicsEllipseItem *circle;
pen.setWidth(1.0);
// inactive
pen.setColor(inactive);
circle = scene->addEllipse(0.0, 0.0, m_width, m_height, pen, QBrush(inactive, Qt::SolidPattern));
circle->setSpanAngle(- (1.0 - percent) * 360.0 * 16.0);
circle->setStartAngle(90.0 * 16.0 - percent * 360.0 * 16.0);
// active
pen.setColor(active);
circle = scene->addEllipse(0.0, 0.0, m_width, m_height, pen, QBrush(active, Qt::SolidPattern));
circle->setSpanAngle(- percent * 360.0 * 16.0);
circle->setStartAngle(90.0 * 16.0);
// scale
scale[0] = -2 * static_cast<int>(m_direction) + 1;
break;
default:
pen.setWidth(m_height);
// inactive
pen.setColor(inactive);
scene->addLine(percent * m_width + 0.5 * m_height, 0.5 * m_height,
m_width + 0.5 * m_height, 0.5 * m_height, pen);
// active
pen.setColor(active);
scene->addLine(-0.5 * m_height, 0.5 * m_height,
percent * m_width - 0.5 * m_height, 0.5 * m_height, pen);
// scale
scale[0] = -2 * static_cast<int>(m_direction) + 1;
break;
}
// convert
QPixmap pixmap = view->grab().transformed(QTransform().scale(scale[0], scale[1]));
QByteArray byteArray;
QBuffer buffer(&byteArray);
pixmap.save(&buffer, "PNG");
QString url = QString("<img src=\"data:image/png;base64,%1\"/>").arg(QString(byteArray.toBase64()));
delete view;
delete scene;
return url;
}
QString GraphicalItem::fileName()
{
if (debug) qDebug() << PDEBUG;
return m_fileName;
}
int GraphicalItem::apiVersion()
{
if (debug) qDebug() << PDEBUG;
return m_apiVersion;
}
QString GraphicalItem::name()
{
if (debug) qDebug() << PDEBUG;
return m_name;
}
QString GraphicalItem::comment()
{
if (debug) qDebug() << PDEBUG;
return m_comment;
}
QString GraphicalItem::bar()
{
if (debug) qDebug() << PDEBUG;
return m_bar;
}
QString GraphicalItem::activeColor()
{
if (debug) qDebug() << PDEBUG;
return m_activeColor;
}
QString GraphicalItem::inactiveColor()
{
if (debug) qDebug() << PDEBUG;
return m_inactiveColor;
}
GraphicalItem::Type GraphicalItem::type()
{
if (debug) qDebug() << PDEBUG;
return m_type;
}
QString GraphicalItem::strType()
{
if (debug) qDebug() << PDEBUG;
QString value;
switch (m_type) {
case Vertical:
value = QString("Vertical");
break;
case Circle:
value = QString("Circle");
break;
default:
value = QString("Horizontal");
break;
}\
return value;
}
GraphicalItem::Direction GraphicalItem::direction()
{
if (debug) qDebug() << PDEBUG;
return m_direction;
}
QString GraphicalItem::strDirection()
{
if (debug) qDebug() << PDEBUG;
QString value;
switch (m_direction) {
case RightToLeft:
value = QString("RightToLeft");
break;
default:
value = QString("LeftToRight");
break;
}
return value;
}
int GraphicalItem::height()
{
if (debug) qDebug() << PDEBUG;
return m_height;
}
int GraphicalItem::width()
{
if (debug) qDebug() << PDEBUG;
return m_width;
}
void GraphicalItem::setApiVersion(const int _apiVersion)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Version" << _apiVersion;
m_apiVersion = _apiVersion;
}
void GraphicalItem::setName(const QString _name)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Name" << _name;
m_name = _name;
}
void GraphicalItem::setComment(const QString _comment)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Comment" << _comment;
m_comment = _comment;
}
void GraphicalItem::setBar(const QString _bar)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Bar" << _bar;
if ((!_bar.contains(QRegExp(QString("cpu(?!cl).*")))) &&
(!_bar.contains(QRegExp(QString("gpu")))) &&
(!_bar.contains(QRegExp(QString("mem")))) &&
(!_bar.contains(QRegExp(QString("swap")))) &&
(!_bar.contains(QRegExp(QString("hdd[0-9].*")))) &&
(!_bar.contains(QRegExp(QString("bat.*")))))
m_bar = QString("none");
else
m_bar = _bar;
}
void GraphicalItem::setActiveColor(const QString _color)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Color" << _color;
m_activeColor = _color;
}
void GraphicalItem::setInactiveColor(const QString _color)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Color" << _color;
m_inactiveColor = _color;
}
void GraphicalItem::setType(const Type _type)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Type" << _type;
m_type = _type;
}
void GraphicalItem::setStrType(const QString _type)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Type" << _type;
if (_type == QString("Vertical"))
setType(Vertical);
else if (_type == QString("Circle"))
setType(Circle);
else
setType(Horizontal);
}
void GraphicalItem::setDirection(const Direction _direction)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Direction" << _direction;
m_direction = _direction;
}
void GraphicalItem::setStrDirection(const QString _direction)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Direction" << _direction;
if (_direction == QString("RightToLeft"))
setDirection(RightToLeft);
else
setDirection(LeftToRight);
}
void GraphicalItem::setHeight(const int _height)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Height" << _height;
if (_height <= 0) return;
m_height = _height;
}
void GraphicalItem::setWidth(const int _width)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Width" << _width;
if (_width <= 0) return;
m_width = _width;
}
void GraphicalItem::readConfiguration()
{
if (debug) qDebug() << PDEBUG;
for (int i=m_dirs.count()-1; i>=0; i--) {
if (!QDir(m_dirs[i]).entryList(QDir::Files).contains(m_fileName)) continue;
QSettings settings(QString("%1/%2").arg(m_dirs[i]).arg(m_fileName), QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setName(settings.value(QString("Name"), m_name).toString());
setComment(settings.value(QString("Comment"), m_comment).toString());
setApiVersion(settings.value(QString("X-AW-ApiVersion"), AWGIAPI).toInt());
setBar(settings.value(QString("X-AW-Value"), m_bar).toString());
setActiveColor(settings.value(QString("X-AW-ActiveColor"), m_activeColor).toString());
setInactiveColor(settings.value(QString("X-AW-InactiveColor"), m_inactiveColor).toString());
setStrType(settings.value(QString("X-AW-Type"), strType()).toString());
setStrDirection(settings.value(QString("X-AW-Direction"), strDirection()).toString());
setHeight(settings.value(QString("X-AW-Height"), m_height).toInt());
setWidth(settings.value(QString("X-AW-Width"), m_width).toInt());
settings.endGroup();
}
}
int GraphicalItem::showConfiguration(const QStringList tags)
{
if (debug) qDebug() << PDEBUG;
ui->label_nameValue->setText(m_name);
ui->lineEdit_comment->setText(m_comment);
ui->comboBox_value->addItems(tags);
ui->comboBox_value->addItem(m_bar);
ui->comboBox_value->setCurrentIndex(ui->comboBox_value->count() - 1);
ui->pushButton_activeColor->setText(m_activeColor);
ui->pushButton_inactiveColor->setText(m_inactiveColor);
ui->comboBox_type->setCurrentIndex(static_cast<int>(m_type));
ui->comboBox_direction->setCurrentIndex(static_cast<int>(m_direction));
ui->spinBox_height->setValue(m_height);
ui->spinBox_width->setValue(m_width);
int ret = exec();
if (ret != 1) return ret;
setName(ui->label_nameValue->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AWGIAPI);
setBar(ui->comboBox_value->currentText());
setActiveColor(ui->pushButton_activeColor->text().remove(QChar('&')));
setInactiveColor(ui->pushButton_inactiveColor->text().remove(QChar('&')));
setStrType(ui->comboBox_type->currentText());
setStrDirection(ui->comboBox_direction->currentText());
setHeight(ui->spinBox_height->value());
setWidth(ui->spinBox_width->value());
writeConfiguration();
return ret;
}
bool GraphicalItem::tryDelete()
{
if (debug) qDebug() << PDEBUG;
for (int i=0; i<m_dirs.count(); i++)
if (debug) qDebug() << PDEBUG << ":" << "Remove file" << QString("%1/%2").arg(m_dirs[i]).arg(m_fileName) <<
QFile::remove(QString("%1/%2").arg(m_dirs[i]).arg(m_fileName));
// check if exists
for (int i=0; i<m_dirs.count(); i++)
if (QFile::exists(QString("%1/%2").arg(m_dirs[i]).arg(m_fileName))) return false;
return true;
}
void GraphicalItem::writeConfiguration()
{
if (debug) qDebug() << PDEBUG;
QSettings settings(QString("%1/%2").arg(m_dirs[0]).arg(m_fileName), QSettings::IniFormat);
if (debug) qDebug() << PDEBUG << ":" << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
settings.setValue(QString("Encoding"), QString("UTF-8"));
settings.setValue(QString("Name"), m_name);
settings.setValue(QString("Comment"), m_comment);
settings.setValue(QString("X-AW-ApiVersion"), m_apiVersion);
settings.setValue(QString("X-AW-Value"), m_bar);
settings.setValue(QString("X-AW-ActiveColor"), m_activeColor);
settings.setValue(QString("X-AW-InactiveColor"), m_inactiveColor);
settings.setValue(QString("X-AW-Type"), strType());
settings.setValue(QString("X-AW-Direction"), strDirection());
settings.setValue(QString("X-AW-Height"), m_height);
settings.setValue(QString("X-AW-Width"), m_width);
settings.endGroup();
settings.sync();
}
void GraphicalItem::changeColor()
{
if (debug) qDebug() << PDEBUG;
QColor color = stringToColor((dynamic_cast<QPushButton *>(sender()))->text());
QColor newColor = QColorDialog::getColor(color, 0, i18n("Select color"),
QColorDialog::ShowAlphaChannel);
if (!newColor.isValid()) return;
QStringList colorText;
colorText.append(QString("%1").arg(newColor.red()));
colorText.append(QString("%1").arg(newColor.green()));
colorText.append(QString("%1").arg(newColor.blue()));
colorText.append(QString("%1").arg(newColor.alpha()));
dynamic_cast<QPushButton *>(sender())->setText(colorText.join(QChar(',')));
}
QColor GraphicalItem::stringToColor(const QString _color)
{
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Color" << _color;
QColor qcolor;
QStringList listColor = _color.split(QChar(','));
while (listColor.count() < 4)
listColor.append(QString("0"));
qcolor.setRed(listColor[0].toInt());
qcolor.setGreen(listColor[1].toInt());
qcolor.setBlue(listColor[2].toInt());
qcolor.setAlpha(listColor[3].toInt());
return qcolor;
}

View File

@ -1,3 +1,2 @@
module org.kde.plasma.awesomewidget
module org.kde.plasma.private.awesomewidget
plugin awplugin

View File

@ -0,0 +1,37 @@
set(SUBPROJECT ${PROJECT_LIBRARY})
message(STATUS "Subproject ${SUBPROJECT}")
add_definitions(-DTRANSLATION_DOMAIN=\"plasma_applet_org.kde.plasma.awesomewidget\")
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${PROJECT_TRDPARTY_DIR}
${Qt_INCLUDE}
${Kf5_INCLUDE}
)
file(GLOB SUBPROJECT_SOURCE *.cpp ${PROJECT_TRDPARTY_DIR}/qreplytimeout/*.cpp ${CMAKE_SOURCE_DIR}/*.cpp)
file(GLOB SUBPROJECT_HEADER *.h ${PROJECT_TRDPARTY_DIR}/qreplytimeout/*.h)
file(GLOB SUBPROJECT_UI *.ui)
set(SUBPROJECT_GRAPHITEMS ${CMAKE_CURRENT_SOURCE_DIR}/desktops)
set(SUBPROJECT_QUOTES ${CMAKE_CURRENT_SOURCE_DIR}/quotes)
set(SUBPROJECT_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/scripts)
set(SUBPROJECT_UPGRADE ${CMAKE_CURRENT_SOURCE_DIR}/upgrade)
set(SUBPROJECT_WEATHER ${CMAKE_CURRENT_SOURCE_DIR}/weather)
file(GLOB SUBPROJECT_WEATHER_JSON_IN *.json)
file(RELATIVE_PATH SUBPROJECT_WEATHER_JSON ${CMAKE_SOURCE_DIR} ${SUBPROJECT_WEATHER_JSON_IN})
# prepare
configure_file(${SUBPROJECT_WEATHER_JSON_IN} ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON})
qt5_wrap_ui(SUBPROJECT_UI_HEADER ${SUBPROJECT_UI})
add_library(${SUBPROJECT} STATIC ${SUBPROJECT_SOURCE} ${SUBPROJECT_HEADER} ${SUBPROJECT_UI_HEADER})
target_link_libraries(${SUBPROJECT} ${Qt_LIBRARIES} ${Kf5_LIBRARIES})
# install
install(DIRECTORY ${SUBPROJECT_GRAPHITEMS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_QUOTES} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_SCRIPTS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_UPGRADE} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_WEATHER} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/weather)

View File

@ -0,0 +1,227 @@
/***************************************************************************
* 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 "abstractextitem.h"
#include <QDir>
#include <QSettings>
#include <QStandardPaths>
#include <QTime>
#include "awdebug.h"
#include "version.h"
AbstractExtItem::AbstractExtItem(QWidget *parent, const QString desktopName,
const QStringList directories)
: QDialog(parent)
, m_fileName(desktopName)
, m_dirs(directories)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
qCDebug(LOG_LIB) << "Desktop name" << desktopName;
qCDebug(LOG_LIB) << "Directories" << directories;
m_name = m_fileName;
}
AbstractExtItem::~AbstractExtItem()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
}
template <class T> T *AbstractExtItem::copy(const QString, const int)
{
// an analog of pure virtual method
return new T();
}
int AbstractExtItem::apiVersion() const
{
return m_apiVersion;
}
QString AbstractExtItem::comment() const
{
return m_comment;
}
QStringList AbstractExtItem::directories() const
{
return m_dirs;
}
QString AbstractExtItem::fileName() const
{
return m_fileName;
}
int AbstractExtItem::interval() const
{
return m_interval;
}
bool AbstractExtItem::isActive() const
{
return m_active;
}
QString AbstractExtItem::name() const
{
return m_name;
}
int AbstractExtItem::number() const
{
return m_number;
}
QString AbstractExtItem::tag(const QString _type) const
{
qCDebug(LOG_LIB) << "Tag type" << _type;
return QString("%1%2").arg(_type).arg(m_number);
}
void AbstractExtItem::setApiVersion(const int _apiVersion)
{
qCDebug(LOG_LIB) << "Version" << _apiVersion;
m_apiVersion = _apiVersion;
}
void AbstractExtItem::setActive(const bool _state)
{
qCDebug(LOG_LIB) << "State" << _state;
m_active = _state;
}
void AbstractExtItem::setComment(const QString _comment)
{
qCDebug(LOG_LIB) << "Comment" << _comment;
m_comment = _comment;
}
void AbstractExtItem::setInterval(const int _interval)
{
qCDebug(LOG_LIB) << "Interval" << _interval;
if (_interval <= 0)
return;
m_interval = _interval;
}
void AbstractExtItem::setName(const QString _name)
{
qCDebug(LOG_LIB) << "Name" << _name;
m_name = _name;
}
void AbstractExtItem::setNumber(int _number)
{
qCDebug(LOG_LIB) << "Number" << _number;
if (_number == -1)
_number = []() {
qCWarning(LOG_LIB) << "Number is empty, generate new one";
qsrand(QTime::currentTime().msec());
int n = qrand() % 1000;
qCInfo(LOG_LIB) << "Generated number is" << n;
return n;
}();
m_number = _number;
}
void AbstractExtItem::readConfiguration()
{
for (int i = m_dirs.count() - 1; i >= 0; i--) {
if (!QDir(m_dirs.at(i)).entryList(QDir::Files).contains(m_fileName))
continue;
QSettings settings(QString("%1/%2").arg(m_dirs.at(i)).arg(m_fileName),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setName(settings.value(QString("Name"), m_name).toString());
setComment(settings.value(QString("Comment"), m_comment).toString());
setApiVersion(
settings.value(QString("X-AW-ApiVersion"), m_apiVersion).toInt());
setActive(settings.value(QString("X-AW-Active"), QVariant(m_active))
.toString()
== QString("true"));
setInterval(
settings.value(QString("X-AW-Interval"), m_interval).toInt());
setNumber(settings.value(QString("X-AW-Number"), m_number).toInt());
settings.endGroup();
}
}
bool AbstractExtItem::tryDelete() const
{
foreach (QString dir, m_dirs) {
bool status = QFile::remove(QString("%1/%2").arg(dir).arg(m_fileName));
qCInfo(LOG_LIB) << "Remove file"
<< QString("%1/%2").arg(dir).arg(m_fileName) << status;
}
// check if exists
foreach (QString dir, m_dirs)
if (QFile::exists(QString("%1/%2").arg(dir).arg(m_fileName)))
return false;
return true;
}
void AbstractExtItem::writeConfiguration() const
{
QSettings settings(QString("%1/%2").arg(m_dirs.first()).arg(m_fileName),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
settings.setValue(QString("Encoding"), QString("UTF-8"));
settings.setValue(QString("Name"), m_name);
settings.setValue(QString("Comment"), m_comment);
settings.setValue(QString("X-AW-ApiVersion"), m_apiVersion);
settings.setValue(QString("X-AW-Active"), QVariant(m_active).toString());
settings.setValue(QString("X-AW-Interval"), m_interval);
settings.setValue(QString("X-AW-Number"), m_number);
settings.endGroup();
settings.sync();
}

View File

@ -15,82 +15,70 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef EXTUPGRADE_H
#define EXTUPGRADE_H
#ifndef ABSTRACTEXTITEM_H
#define ABSTRACTEXTITEM_H
#include <QDialog>
#include <QProcess>
#include <QVariant>
namespace Ui {
class ExtUpgrade;
}
class ExtUpgrade : public QDialog
class AbstractExtItem : public QDialog
{
Q_OBJECT
Q_PROPERTY(int apiVersion READ apiVersion WRITE setApiVersion)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(QString comment READ comment WRITE setComment)
Q_PROPERTY(QString executable READ executable WRITE setExecutable)
Q_PROPERTY(int null READ null WRITE setNull)
Q_PROPERTY(int number READ number WRITE setNumber)
Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(int apiVersion READ apiVersion WRITE setApiVersion)
Q_PROPERTY(QString comment READ comment WRITE setComment)
Q_PROPERTY(QStringList directories READ directories)
Q_PROPERTY(QString fileName READ fileName)
Q_PROPERTY(int interval READ interval WRITE setInterval)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int number READ number WRITE setNumber)
Q_PROPERTY(QString uniq READ uniq)
public:
explicit ExtUpgrade(QWidget *parent = nullptr, const QString upgradeName = QString(),
const QStringList directories = QStringList(), const bool debugCmd = false);
~ExtUpgrade();
explicit AbstractExtItem(QWidget *parent = nullptr,
const QString desktopName = QString(),
const QStringList directories = QStringList());
virtual ~AbstractExtItem();
template <class T> T *copy(const QString, const int);
// get methods
int apiVersion();
QString comment();
QString executable();
QString fileName();
int interval();
QString name();
int null();
int number();
QString tag();
bool isActive();
int apiVersion() const;
QString comment() const;
QStringList directories() const;
QString fileName() const;
int interval() const;
bool isActive() const;
QString name() const;
int number() const;
QString tag(const QString _type) const;
virtual QString uniq() const = 0;
// set methods
void setApiVersion(const int _apiVersion = 0);
void setActive(const bool _state = true);
void setComment(const QString _comment = QString("empty"));
void setExecutable(const QString _executable = QString("/usr/bin/true"));
void setInterval(const int _interval = 1);
void setName(const QString _name = QString("none"));
void setNull(const int _null = 0);
void setNumber(int _number = -1);
void setInterval(const int _interval = 0);
public slots:
void readConfiguration();
int run();
int showConfiguration();
bool tryDelete();
void writeConfiguration();
private slots:
void updateValue();
virtual void readConfiguration();
virtual QVariantHash run() = 0;
virtual int showConfiguration(const QVariant args = QVariant()) = 0;
bool tryDelete() const;
virtual void writeConfiguration() const;
private:
QString m_fileName;
QStringList m_dirs;
bool debug;
QProcess *process = nullptr;
Ui::ExtUpgrade *ui;
virtual void translate() = 0;
// properties
int m_apiVersion = 0;
bool m_active = true;
QString m_comment = QString("empty");
QString m_executable = QString("/usr/bin/true");
int m_interval = 1;
QString m_name = QString("none");
int m_null = 0;
int m_number = -1;
int m_interval = 3600;
int times = 0;
int value = 0;
};
#endif /* EXTUPGRADE_H */
#endif /* ABSTRACTEXTITEM_H */

View File

@ -0,0 +1,112 @@
/***************************************************************************
* 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 "abstractextitemaggregator.h"
#include <KI18n/KLocalizedString>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QLineEdit>
#include "awdebug.h"
AbstractExtItemAggregator::AbstractExtItemAggregator(QWidget *parent)
: QWidget(parent)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
dialog = new QDialog(this);
widgetDialog = new QListWidget(dialog);
dialogButtons = new QDialogButtonBox(
QDialogButtonBox::Open | QDialogButtonBox::Close, Qt::Vertical, dialog);
copyButton
= dialogButtons->addButton(i18n("Copy"), QDialogButtonBox::ActionRole);
createButton = dialogButtons->addButton(i18n("Create"),
QDialogButtonBox::ActionRole);
deleteButton = dialogButtons->addButton(i18n("Remove"),
QDialogButtonBox::ActionRole);
QHBoxLayout *layout = new QHBoxLayout(dialog);
layout->addWidget(widgetDialog);
layout->addWidget(dialogButtons);
dialog->setLayout(layout);
connect(dialogButtons, SIGNAL(clicked(QAbstractButton *)), this,
SLOT(editItemButtonPressed(QAbstractButton *)));
connect(dialogButtons, SIGNAL(rejected()), dialog, SLOT(reject()));
connect(widgetDialog, SIGNAL(itemActivated(QListWidgetItem *)), this,
SLOT(editItemActivated(QListWidgetItem *)));
}
AbstractExtItemAggregator::~AbstractExtItemAggregator()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete dialog;
}
QString AbstractExtItemAggregator::getName()
{
bool ok;
QString name = QInputDialog::getText(this, i18n("Enter file name"),
i18n("File name"), QLineEdit::Normal,
QString(""), &ok);
if ((!ok) || (name.isEmpty()))
return QString("");
if (!name.endsWith(QString(".desktop")))
name += QString(".desktop");
return name;
}
QVariant AbstractExtItemAggregator::configArgs() const
{
return m_configArgs;
}
void AbstractExtItemAggregator::setConfigArgs(const QVariant _configArgs)
{
qCDebug(LOG_LIB) << "Configuration arguments" << _configArgs;
m_configArgs = _configArgs;
}
void AbstractExtItemAggregator::editItemActivated(QListWidgetItem *item)
{
Q_UNUSED(item)
return editItem();
}
void AbstractExtItemAggregator::editItemButtonPressed(QAbstractButton *button)
{
if (static_cast<QPushButton *>(button) == copyButton)
return copyItem();
else if (static_cast<QPushButton *>(button) == createButton)
return createItem();
else if (static_cast<QPushButton *>(button) == deleteButton)
return deleteItem();
else if (dialogButtons->buttonRole(button) == QDialogButtonBox::AcceptRole)
return editItem();
}

View File

@ -0,0 +1,64 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef ABSTRACTEXTITEMAGGREGATOR_H
#define ABSTRACTEXTITEMAGGREGATOR_H
#include <QDialog>
#include <QDialogButtonBox>
#include <QListWidget>
#include <QPushButton>
#include <QWidget>
// additional class since QObject macro does not allow class templates
class AbstractExtItemAggregator : public QWidget
{
Q_OBJECT
Q_PROPERTY(QVariant configArgs READ configArgs WRITE setConfigArgs)
public:
explicit AbstractExtItemAggregator(QWidget *parent = nullptr);
virtual ~AbstractExtItemAggregator();
QString getName();
// ui
QDialog *dialog = nullptr;
QListWidget *widgetDialog = nullptr;
QDialogButtonBox *dialogButtons = nullptr;
QPushButton *copyButton = nullptr;
QPushButton *createButton = nullptr;
QPushButton *deleteButton = nullptr;
// get methods
QVariant configArgs() const;
// set methods
void setConfigArgs(const QVariant _configArgs);
private slots:
void editItemActivated(QListWidgetItem *item);
void editItemButtonPressed(QAbstractButton *button);
private:
QVariant m_configArgs;
// methods
virtual void copyItem() = 0;
virtual void createItem() = 0;
virtual void deleteItem() = 0;
virtual void editItem() = 0;
};
#endif /* ABSTRACTEXTITEMAGGREGATOR_H */

View File

@ -0,0 +1,139 @@
{
"__url": "http://openweathermap.org/weather-conditions",
"image": {
"__comment": "should be described as html image with full path inside",
"default": "",
"800": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/01d.png\">",
"801": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/02d.png\">",
"802": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/03d.png\">",
"803": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/03d.png\">",
"804": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/04d.png\">",
"300": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"301": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"302": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"310": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"311": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"312": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"313": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"314": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"321": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"520": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"521": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"522": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"531": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/09d.png\">",
"500": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">",
"501": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">",
"502": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">",
"503": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">",
"504": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/10d.png\">",
"200": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"201": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"202": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"210": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"211": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"212": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"221": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"230": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"231": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"232": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/11d.png\">",
"511": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"600": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"601": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"602": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"611": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"612": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"615": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"616": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"620": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"621": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"622": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/13d.png\">",
"701": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"711": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"721": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"731": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"741": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"751": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"761": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"762": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"771": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">",
"781": "<img src=\"@CMAKE_INSTALL_PREFIX@/@DATA_INSTALL_DIR@/@PROJECT_NAME@/weather/50d.png\">"
},
"text": {
"default": "\u2604",
"800": "\u2600",
"801": "\u26C5",
"802": "\u2601",
"803": "\u2601",
"804": "\u2601",
"300": "\u2602",
"301": "\u2602",
"302": "\u2602",
"310": "\u2602",
"311": "\u2602",
"312": "\u2602",
"313": "\u2602",
"314": "\u2602",
"321": "\u2602",
"520": "\u2602",
"521": "\u2602",
"522": "\u2602",
"531": "\u2602",
"500": "\u2614",
"501": "\u2614",
"502": "\u2614",
"503": "\u2614",
"504": "\u2614",
"200": "\u2608",
"201": "\u2608",
"202": "\u2608",
"210": "\u2608",
"211": "\u2608",
"212": "\u2608",
"221": "\u2608",
"230": "\u2608",
"231": "\u2608",
"232": "\u2608",
"511": "\u2603",
"600": "\u2603",
"601": "\u2603",
"602": "\u2603",
"611": "\u2603",
"612": "\u2603",
"615": "\u2603",
"616": "\u2603",
"620": "\u2603",
"621": "\u2603",
"622": "\u2603",
"701": "\u26C5",
"711": "\u26C5",
"721": "\u26C5",
"731": "\u26C5",
"741": "\u26C5",
"751": "\u26C5",
"761": "\u26C5",
"762": "\u26C5",
"771": "\u26C5",
"781": "\u26C5"
}
}

View File

@ -9,4 +9,5 @@ X-AW-Type=Horizontal
X-AW-Direction=LeftToRight
X-AW-Height=25
X-AW-Width=100
X-AW-ApiVersion=1
X-AW-ApiVersion=3
X-AW-Number=3

View File

@ -9,4 +9,5 @@ X-AW-Type=Horizontal
X-AW-Direction=LeftToRight
X-AW-Height=25
X-AW-Width=100
X-AW-ApiVersion=1
X-AW-ApiVersion=3
X-AW-Number=0

View File

@ -9,4 +9,5 @@ X-AW-Type=Horizontal
X-AW-Direction=LeftToRight
X-AW-Height=25
X-AW-Width=100
X-AW-ApiVersion=1
X-AW-ApiVersion=3
X-AW-Number=1

View File

@ -9,4 +9,5 @@ X-AW-Type=Horizontal
X-AW-Direction=LeftToRight
X-AW-Height=25
X-AW-Width=100
X-AW-ApiVersion=1
X-AW-ApiVersion=3
X-AW-Number=2

View File

@ -0,0 +1,271 @@
/***************************************************************************
* 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 EXTITEMAGGREGATOR_H
#define EXTITEMAGGREGATOR_H
#include <KI18n/KLocalizedString>
#include <QDir>
#include <QSettings>
#include <QStandardPaths>
#include "abstractextitemaggregator.h"
#include "awdebug.h"
template <class T> class ExtItemAggregator : public AbstractExtItemAggregator
{
public:
explicit ExtItemAggregator(QWidget *parent, const QString type)
: AbstractExtItemAggregator(parent)
, m_type(type)
{
qSetMessagePattern(LOG_FORMAT);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
foreach (const QString metadata, getBuildData())
qCDebug(LOG_LIB) << metadata;
qCDebug(LOG_LIB) << "Type" << type;
initItems();
};
virtual ~ExtItemAggregator()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
m_items.clear();
m_activeItems.clear();
};
QList<T *> activeItems() { return m_activeItems; };
void editItems()
{
repaint();
int ret = dialog->exec();
qCInfo(LOG_LIB) << "Dialog returns" << ret;
};
T *itemByTag(const QString _tag) const
{
qCDebug(LOG_LIB) << "Tag" << _tag;
T *found = nullptr;
foreach (T *item, m_items) {
if (item->tag() != _tag)
continue;
found = item;
break;
}
if (found == nullptr)
qCWarning(LOG_LIB) << "Could not find item by tag" << _tag;
return found;
};
T *itemByTagNumber(const int _number) const
{
qCDebug(LOG_LIB) << "Number" << _number;
T *found = nullptr;
foreach (T *item, m_items) {
if (item->number() != _number)
continue;
found = item;
break;
}
if (found == nullptr)
qCWarning(LOG_LIB) << "Could not find item by number" << _number;
return found;
};
T *itemFromWidget() const
{
QListWidgetItem *widgetItem = widgetDialog->currentItem();
if (widgetItem == nullptr)
return nullptr;
T *found = nullptr;
foreach (T *item, m_items) {
if (item->fileName() != widgetItem->text())
continue;
found = item;
break;
}
if (found == nullptr)
qCWarning(LOG_LIB) << "Could not find item by name"
<< widgetItem->text();
return found;
};
QList<T *> items() const { return m_items; };
int uniqNumber() const
{
QList<int> tagList;
foreach (T *item, m_items)
tagList.append(item->number());
int number = 0;
while (tagList.contains(number))
number++;
return number;
};
private:
QList<T *> m_items;
QList<T *> m_activeItems;
QString m_type;
// init method
QList<T *> getItems()
{
// create directory at $HOME
QString localDir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_type);
QDir localDirectory;
if (localDirectory.mkpath(localDir))
qCInfo(LOG_LIB) << "Created directory" << localDir;
QStringList dirs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation,
QString("awesomewidgets/%1").arg(m_type),
QStandardPaths::LocateDirectory);
QStringList names;
QList<T *> items;
foreach (QString dir, dirs) {
QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name);
foreach (QString file, files) {
if ((!file.endsWith(QString(".desktop")))
|| (names.contains(file)))
continue;
qCInfo(LOG_LIB) << "Found file" << file << "in" << dir;
names.append(file);
items.append(new T(this, file, dirs));
}
}
// sort items
std::sort(items.begin(), items.end(), [](const T *lhs, const T *rhs) {
return lhs->number() < rhs->number();
});
return items;
};
void initItems()
{
m_items.clear();
m_activeItems.clear();
m_items = getItems();
foreach (T *item, m_items) {
if (!item->isActive())
continue;
m_activeItems.append(item);
}
};
void repaint()
{
widgetDialog->clear();
foreach (T *_item, m_items) {
QListWidgetItem *item
= new QListWidgetItem(_item->fileName(), widgetDialog);
QStringList tooltip;
tooltip.append(i18n("Name: %1", _item->name()));
tooltip.append(i18n("Comment: %1", _item->comment()));
tooltip.append(i18n("Identity: %1", _item->uniq()));
item->setToolTip(tooltip.join(QChar('\n')));
widgetDialog->addItem(item);
}
};
// methods
void copyItem()
{
T *source = itemFromWidget();
QString fileName = getName();
int number = uniqNumber();
if ((source == nullptr) || (fileName.isEmpty())) {
qCWarning(LOG_LIB) << "Nothing to copy";
return;
}
T *newItem = source->copy(fileName, number);
if (newItem->showConfiguration(configArgs()) == 1) {
initItems();
repaint();
}
};
void createItem()
{
QString fileName = getName();
int number = uniqNumber();
QStringList dirs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation,
QString("awesomewidgets/%1").arg(m_type),
QStandardPaths::LocateDirectory);
if (fileName.isEmpty()) {
qCWarning(LOG_LIB) << "Nothing to create";
return;
};
T *newItem = new T(this, fileName, dirs);
newItem->setNumber(number);
if (newItem->showConfiguration(configArgs()) == 1) {
initItems();
repaint();
}
};
void deleteItem()
{
T *source = itemFromWidget();
if (source == nullptr) {
qCWarning(LOG_LIB) << "Nothing to delete";
return;
};
if (source->tryDelete()) {
initItems();
repaint();
}
};
void editItem()
{
T *source = itemFromWidget();
if (source == nullptr) {
qCWarning(LOG_LIB) << "Nothing to edit";
return;
};
if (source->showConfiguration(configArgs()) == 1) {
initItems();
repaint();
}
};
};
#endif /* EXTITEMAGGREGATOR_H */

View File

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

View File

@ -0,0 +1,77 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef EXTQUOTES_H
#define EXTQUOTES_H
#include <QNetworkReply>
#include "abstractextitem.h"
#define YAHOO_URL \
"https://query.yahooapis.com/v1/public/yql?q=select * from " \
"yahoo.finance.quotes where " \
"symbol=\"$TICKER\"&env=store://datatables.org/" \
"alltableswithkeys&format=json"
namespace Ui
{
class ExtQuotes;
}
class ExtQuotes : public AbstractExtItem
{
Q_OBJECT
Q_PROPERTY(QString ticker READ ticker WRITE setTicker)
public:
explicit ExtQuotes(QWidget *parent = nullptr,
const QString quotesName = QString(),
const QStringList directories = QStringList());
virtual ~ExtQuotes();
ExtQuotes *copy(const QString _fileName, const int _number);
// get methods
QString ticker() const;
QString uniq() const;
// set methods
void setTicker(const QString _ticker = QString("EURUSD=X"));
public slots:
void readConfiguration();
QVariantHash run();
int showConfiguration(const QVariant args = QVariant());
void writeConfiguration() const;
private slots:
void quotesReplyReceived(QNetworkReply *reply);
private:
QNetworkAccessManager *manager;
bool isRunning = false;
Ui::ExtQuotes *ui;
void translate();
QString url() const;
// properties
QString m_ticker = QString("EURUSD=X");
// values
int times = 0;
QVariantHash values;
};
#endif /* EXTQUOTES_H */

View File

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

View File

@ -0,0 +1,418 @@
/***************************************************************************
* 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 "extscript.h"
#include "ui_extscript.h"
#include <KI18n/KLocalizedString>
#include <QDir>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QSettings>
#include <QStandardPaths>
#include <QTextCodec>
#include "awdebug.h"
#include "version.h"
ExtScript::ExtScript(QWidget *parent, const QString scriptName,
const QStringList directories)
: AbstractExtItem(parent, scriptName, directories)
, ui(new Ui::ExtScript)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
readConfiguration();
readJsonFilters();
ui->setupUi(this);
translate();
value[tag(QString("custom"))] = QString("");
process = new QProcess(nullptr);
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this,
SLOT(updateValue()));
process->waitForFinished(0);
}
ExtScript::~ExtScript()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
process->kill();
process->deleteLater();
delete ui;
}
ExtScript *ExtScript::copy(const QString _fileName, const int _number)
{
qCDebug(LOG_LIB) << "File" << _fileName;
qCDebug(LOG_LIB) << "Number" << _number;
ExtScript *item = new ExtScript(static_cast<QWidget *>(parent()), _fileName,
directories());
item->setActive(isActive());
item->setApiVersion(apiVersion());
item->setComment(comment());
item->setExecutable(executable());
item->setInterval(interval());
item->setName(name());
item->setNumber(_number);
item->setPrefix(prefix());
item->setRedirect(redirect());
return item;
}
QString ExtScript::executable() const
{
return m_executable;
}
QStringList ExtScript::filters() const
{
return m_filters;
}
QString ExtScript::prefix() const
{
return m_prefix;
}
ExtScript::Redirect ExtScript::redirect() const
{
return m_redirect;
}
QString ExtScript::uniq() const
{
return m_executable;
}
QString ExtScript::strRedirect() const
{
QString value;
switch (m_redirect) {
case stdout2stderr:
value = QString("stdout2stderr");
break;
case stderr2stdout:
value = QString("stderr2stdout");
break;
case swap:
value = QString("swap");
break;
case nothing:
default:
value = QString("nothing");
break;
}
return value;
}
void ExtScript::setExecutable(const QString _executable)
{
qCDebug(LOG_LIB) << "Executable" << _executable;
m_executable = _executable;
}
void ExtScript::setFilters(const QStringList _filters)
{
qCDebug(LOG_LIB) << "Filters" << _filters;
std::for_each(_filters.cbegin(), _filters.cend(),
[this](QString filter) { return updateFilter(filter); });
}
void ExtScript::setPrefix(const QString _prefix)
{
qCDebug(LOG_LIB) << "Prefix" << _prefix;
m_prefix = _prefix;
}
void ExtScript::setRedirect(const Redirect _redirect)
{
qCDebug(LOG_LIB) << "Redirect" << _redirect;
m_redirect = _redirect;
}
void ExtScript::setStrRedirect(const QString _redirect)
{
qCDebug(LOG_LIB) << "Redirect" << _redirect;
if (_redirect == QString("stdout2sdterr"))
m_redirect = stdout2stderr;
else if (_redirect == QString("stderr2sdtout"))
m_redirect = stderr2stdout;
else if (_redirect == QString("swap"))
m_redirect = swap;
else
m_redirect = nothing;
}
QString ExtScript::applyFilters(QString _value) const
{
qCDebug(LOG_LIB) << "Value" << _value;
foreach (QString filt, m_filters) {
qCInfo(LOG_LIB) << "Found filter" << filt;
QVariantMap filter = jsonFilters[filt].toMap();
if (filter.isEmpty()) {
qCWarning(LOG_LIB) << "Could not find filter" << _value
<< "in the json";
continue;
}
foreach (QString f, filter.keys())
_value.replace(f, filter[f].toString());
}
return _value;
}
void ExtScript::updateFilter(const QString _filter, const bool _add)
{
qCDebug(LOG_LIB) << "Filter" << _filter;
qCDebug(LOG_LIB) << "Should be added" << _add;
if (_add) {
if (m_filters.contains(_filter))
return;
m_filters.append(_filter);
} else {
m_filters.removeOne(_filter);
}
}
void ExtScript::readConfiguration()
{
AbstractExtItem::readConfiguration();
for (int i = directories().count() - 1; i >= 0; i--) {
if (!QDir(directories().at(i))
.entryList(QDir::Files)
.contains(fileName()))
continue;
QSettings settings(
QString("%1/%2").arg(directories().at(i)).arg(fileName()),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setExecutable(settings.value(QString("Exec"), m_executable).toString());
setPrefix(settings.value(QString("X-AW-Prefix"), m_prefix).toString());
setStrRedirect(
settings.value(QString("X-AW-Redirect"), strRedirect()).toString());
// api == 3
setFilters(settings.value(QString("X-AW-Filters"), m_filters)
.toString()
.split(QChar(','), QString::SkipEmptyParts));
settings.endGroup();
}
// update for current API
if ((apiVersion() > 0) && (apiVersion() < AWESAPI)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to"
<< AWESAPI;
setApiVersion(AWESAPI);
writeConfiguration();
}
}
void ExtScript::readJsonFilters()
{
QString fileName = QStandardPaths::locate(
QStandardPaths::GenericDataLocation,
QString(
"awesomewidgets/scripts/awesomewidgets-extscripts-filters.json"));
qCInfo(LOG_LIB) << "Filters file" << fileName;
QFile jsonFile(fileName);
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(LOG_LIB) << "Could not open" << fileName;
return;
}
QString jsonText = jsonFile.readAll();
jsonFile.close();
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonText.toUtf8(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_LIB) << "Parse error" << error.errorString();
return;
}
jsonFilters = jsonDoc.toVariant().toMap();
qCInfo(LOG_LIB) << "Filters" << jsonFilters;
}
QVariantHash ExtScript::run()
{
if (!isActive())
return value;
if ((times == 1) && (process->state() == QProcess::NotRunning)) {
QStringList cmdList;
if (!m_prefix.isEmpty())
cmdList.append(m_prefix);
cmdList.append(m_executable);
qCInfo(LOG_LIB) << "Run cmd" << cmdList.join(QChar(' '));
process->start(cmdList.join(QChar(' ')));
} else if (times >= interval()) {
times = 0;
}
times++;
return value;
}
int ExtScript::showConfiguration(const QVariant args)
{
Q_UNUSED(args)
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_numberValue->setText(QString("%1").arg(number()));
ui->lineEdit_command->setText(m_executable);
ui->lineEdit_prefix->setText(m_prefix);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked
: Qt::Unchecked);
ui->comboBox_redirect->setCurrentIndex(static_cast<int>(m_redirect));
ui->spinBox_interval->setValue(interval());
// filters
ui->checkBox_colorFilter->setCheckState(
m_filters.contains(QString("color")) ? Qt::Checked : Qt::Unchecked);
ui->checkBox_linesFilter->setCheckState(
m_filters.contains(QString("newline")) ? Qt::Checked : Qt::Unchecked);
ui->checkBox_spaceFilter->setCheckState(
m_filters.contains(QString("space")) ? Qt::Checked : Qt::Unchecked);
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setNumber(ui->label_numberValue->text().toInt());
setApiVersion(AWESAPI);
setExecutable(ui->lineEdit_command->text());
setPrefix(ui->lineEdit_prefix->text());
setActive(ui->checkBox_active->checkState() == Qt::Checked);
setStrRedirect(ui->comboBox_redirect->currentText());
setInterval(ui->spinBox_interval->value());
// filters
updateFilter(QString("color"),
ui->checkBox_colorFilter->checkState() == Qt::Checked);
updateFilter(QString("newline"),
ui->checkBox_linesFilter->checkState() == Qt::Checked);
updateFilter(QString("space"),
ui->checkBox_spaceFilter->checkState() == Qt::Checked);
writeConfiguration();
return ret;
}
void ExtScript::writeConfiguration() const
{
AbstractExtItem::writeConfiguration();
QSettings settings(
QString("%1/%2").arg(directories().first()).arg(fileName()),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
settings.setValue(QString("Exec"), m_executable);
settings.setValue(QString("X-AW-Prefix"), m_prefix);
settings.setValue(QString("X-AW-Redirect"), strRedirect());
settings.setValue(QString("X-AW-Filters"), m_filters.join(QChar(',')));
settings.endGroup();
settings.sync();
}
void ExtScript::updateValue()
{
qCInfo(LOG_LIB) << "Cmd returns" << process->exitCode();
QString qdebug = QTextCodec::codecForMib(106)
->toUnicode(process->readAllStandardError())
.trimmed();
qCInfo(LOG_LIB) << "Error" << qdebug;
QString qoutput = QTextCodec::codecForMib(106)
->toUnicode(process->readAllStandardOutput())
.trimmed();
qCInfo(LOG_LIB) << "Output" << qoutput;
QString strValue;
switch (m_redirect) {
case stdout2stderr:
break;
case stderr2stdout:
strValue = QString("%1\n%2").arg(qdebug).arg(qoutput);
break;
case swap:
strValue = qdebug;
break;
case nothing:
default:
strValue = qoutput;
break;
}
// filters
value[tag(QString("custom"))] = applyFilters(strValue);
}
void ExtScript::translate()
{
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_number->setText(i18n("Tag"));
ui->label_command->setText(i18n("Command"));
ui->label_prefix->setText(i18n("Prefix"));
ui->checkBox_active->setText(i18n("Active"));
ui->label_redirect->setText(i18n("Redirect"));
ui->label_interval->setText(i18n("Interval"));
ui->groupBox_filters->setTitle(i18n("Additional filters"));
ui->checkBox_colorFilter->setText(i18n("Wrap colors"));
ui->checkBox_linesFilter->setText(i18n("Wrap new lines"));
ui->checkBox_spaceFilter->setText(i18n("Wrap spaces"));
}

View File

@ -18,107 +18,74 @@
#ifndef EXTSCRIPT_H
#define EXTSCRIPT_H
#include <QDialog>
#include <QMap>
#include <QProcess>
#include "abstractextitem.h"
namespace Ui {
class ExtScript;
namespace Ui
{
class ExtScript;
}
class ExtScript : public QDialog
class ExtScript : public AbstractExtItem
{
Q_OBJECT
Q_PROPERTY(bool active READ isActive WRITE setActive)
Q_PROPERTY(int apiVersion READ apiVersion WRITE setApiVersion)
Q_PROPERTY(QString comment READ comment WRITE setComment)
Q_PROPERTY(QString executable READ executable WRITE setExecutable)
Q_PROPERTY(QStringList filters READ filters WRITE setFilters)
Q_PROPERTY(int interval READ interval WRITE setInterval)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int number READ number WRITE setNumber)
Q_PROPERTY(bool output READ hasOutput WRITE setHasOutput)
Q_PROPERTY(QString prefix READ prefix WRITE setPrefix)
Q_PROPERTY(Redirect redirect READ redirect WRITE setRedirect)
public:
enum Redirect {
stdout2stderr = 0,
nothing,
stderr2stdout
};
enum Redirect { stdout2stderr = 0, nothing, stderr2stdout, swap };
explicit ExtScript(QWidget *parent = nullptr, const QString scriptName = QString(),
const QStringList directories = QStringList(), const bool debugCmd = false);
~ExtScript();
explicit ExtScript(QWidget *parent = nullptr,
const QString scriptName = QString(),
const QStringList directories = QStringList());
virtual ~ExtScript();
ExtScript *copy(const QString _fileName, const int _number);
// get methods
int apiVersion();
QString comment();
QString executable();
QString fileName();
QStringList filters();
bool hasOutput();
int interval();
bool isActive();
QString name();
int number();
QString prefix();
Redirect redirect();
QString executable() const;
QStringList filters() const;
QString prefix() const;
Redirect redirect() const;
QString uniq() const;
// derivatives
QString strRedirect();
QString tag();
QString strRedirect() const;
// set methods
void setApiVersion(const int _apiVersion = 0);
void setActive(const bool _state = true);
void setComment(const QString _comment = QString("empty"));
void setExecutable(const QString _executable = QString("/usr/bin/true"));
void setFilters(const QStringList _filters = QStringList());
void setHasOutput(const bool _state = true);
void setInterval(const int _interval = 1);
void setName(const QString _name = QString("none"));
void setNumber(int _number = -1);
void setPrefix(const QString _prefix = QString(""));
void setRedirect(const Redirect _redirect = nothing);
void setStrRedirect(const QString _redirect = QString("nothing"));
// filters
QString applyFilters(QString _value);
QString applyFilters(QString _value) const;
void updateFilter(const QString _filter, const bool _add = true);
public slots:
void readConfiguration();
void readJsonFilters();
QString run();
int showConfiguration();
bool tryDelete();
void writeConfiguration();
QVariantHash run();
int showConfiguration(const QVariant args = QVariant());
void writeConfiguration() const;
private slots:
void updateValue();
private:
QString m_fileName;
QStringList m_dirs;
bool debug;
QProcess *process = nullptr;
Ui::ExtScript *ui;
void translate();
// properties
int m_apiVersion = 0;
bool m_active = true;
QString m_comment = QString("empty");
QString m_executable = QString("/usr/bin/true");
QStringList m_filters = QStringList();
int m_interval = 1;
QString m_name = QString("none");
int m_number = -1;
bool m_output = true;
QString m_prefix = QString("");
Redirect m_redirect = nothing;
// internal properties
Q_PID childProcess = 0;
QVariantMap jsonFilters = QVariantMap();
int times = 0;
QString value = QString();
QVariantHash value;
};

View File

@ -157,36 +157,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_output">
<item>
<spacer name="spacer_output">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_output">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Has output</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_redirect">
<item>
@ -216,6 +186,11 @@
<string notr="true">stderr2stdout</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">swap</string>
</property>
</item>
</widget>
</item>
</layout>

View File

@ -0,0 +1,261 @@
/***************************************************************************
* 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 "extupgrade.h"
#include "ui_extupgrade.h"
#include <KI18n/KLocalizedString>
#include <QDir>
#include <QRegExp>
#include <QSettings>
#include <QTextCodec>
#include "awdebug.h"
#include "version.h"
ExtUpgrade::ExtUpgrade(QWidget *parent, const QString upgradeName,
const QStringList directories)
: AbstractExtItem(parent, upgradeName, directories)
, ui(new Ui::ExtUpgrade)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
readConfiguration();
ui->setupUi(this);
translate();
value[tag(QString("pkgcount"))] = 0;
process = new QProcess(nullptr);
connect(process, SIGNAL(finished(int)), this, SLOT(updateValue()));
process->waitForFinished(0);
}
ExtUpgrade::~ExtUpgrade()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
process->kill();
process->deleteLater();
delete ui;
}
ExtUpgrade *ExtUpgrade::copy(const QString _fileName, const int _number)
{
qCDebug(LOG_LIB) << "File" << _fileName;
qCDebug(LOG_LIB) << "Number" << _number;
ExtUpgrade *item = new ExtUpgrade(static_cast<QWidget *>(parent()),
_fileName, directories());
item->setActive(isActive());
item->setApiVersion(apiVersion());
item->setComment(comment());
item->setExecutable(executable());
item->setFilter(filter());
item->setInterval(interval());
item->setName(name());
item->setNumber(_number);
item->setNull(null());
return item;
}
QString ExtUpgrade::executable() const
{
return m_executable;
}
QString ExtUpgrade::filter() const
{
return m_filter;
}
int ExtUpgrade::null() const
{
return m_null;
}
QString ExtUpgrade::uniq() const
{
return m_executable;
}
void ExtUpgrade::setExecutable(const QString _executable)
{
qCDebug(LOG_LIB) << "Executable" << _executable;
m_executable = _executable;
}
void ExtUpgrade::setFilter(const QString _filter)
{
qCDebug(LOG_LIB) << "Filter" << _filter;
m_filter = _filter;
}
void ExtUpgrade::setNull(const int _null)
{
qCDebug(LOG_LIB) << "Null lines" << _null;
if (_null < 0)
return;
m_null = _null;
}
void ExtUpgrade::readConfiguration()
{
AbstractExtItem::readConfiguration();
for (int i = directories().count() - 1; i >= 0; i--) {
if (!QDir(directories().at(i))
.entryList(QDir::Files)
.contains(fileName()))
continue;
QSettings settings(
QString("%1/%2").arg(directories().at(i)).arg(fileName()),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setExecutable(settings.value(QString("Exec"), m_executable).toString());
setNull(settings.value(QString("X-AW-Null"), m_null).toInt());
// api == 3
setFilter(settings.value(QString("X-AW-Filter"), m_filter).toString());
settings.endGroup();
}
// update for current API
if ((apiVersion() > 0) && (apiVersion() < AWEUAPI)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to"
<< AWEUAPI;
setApiVersion(AWEUAPI);
writeConfiguration();
}
}
QVariantHash ExtUpgrade::run()
{
if (!isActive())
return value;
if ((times == 1) && (process->state() == QProcess::NotRunning)) {
QString cmd = QString("sh -c \"%1\"").arg(m_executable);
qCInfo(LOG_LIB) << "Run cmd" << cmd;
process->start(cmd);
} else if (times >= interval()) {
times = 0;
}
times++;
return value;
}
int ExtUpgrade::showConfiguration(const QVariant args)
{
Q_UNUSED(args)
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_numberValue->setText(QString("%1").arg(number()));
ui->lineEdit_command->setText(m_executable);
ui->lineEdit_filter->setText(m_filter);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked
: Qt::Unchecked);
ui->spinBox_null->setValue(m_null);
ui->spinBox_interval->setValue(interval());
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setNumber(ui->label_numberValue->text().toInt());
setApiVersion(AWEUAPI);
setExecutable(ui->lineEdit_command->text());
setFilter(ui->lineEdit_filter->text());
setActive(ui->checkBox_active->checkState() == Qt::Checked);
setNull(ui->spinBox_null->value());
setInterval(ui->spinBox_interval->value());
writeConfiguration();
return ret;
}
void ExtUpgrade::writeConfiguration() const
{
AbstractExtItem::writeConfiguration();
QSettings settings(
QString("%1/%2").arg(directories().first()).arg(fileName()),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
settings.setValue(QString("Exec"), m_executable);
settings.setValue(QString("X-AW-Filter"), m_filter);
settings.setValue(QString("X-AW-Null"), m_null);
settings.endGroup();
settings.sync();
}
void ExtUpgrade::updateValue()
{
qCInfo(LOG_LIB) << "Cmd returns" << process->exitCode();
qCInfo(LOG_LIB) << "Error" << process->readAllStandardError();
QString qoutput = QTextCodec::codecForMib(106)
->toUnicode(process->readAllStandardOutput())
.trimmed();
value[tag(QString("pkgcount"))] = [this](QString output) {
return m_filter.isEmpty()
? output.split(QChar('\n'), QString::SkipEmptyParts).count()
- m_null
: output.split(QChar('\n'), QString::SkipEmptyParts)
.filter(QRegExp(m_filter))
.count();
}(qoutput);
}
void ExtUpgrade::translate()
{
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_number->setText(i18n("Tag"));
ui->label_command->setText(i18n("Command"));
ui->label_filter->setText(i18n("Filter"));
ui->checkBox_active->setText(i18n("Active"));
ui->label_null->setText(i18n("Null"));
ui->label_interval->setText(i18n("Interval"));
}

View File

@ -0,0 +1,77 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef EXTUPGRADE_H
#define EXTUPGRADE_H
#include <QProcess>
#include "abstractextitem.h"
namespace Ui
{
class ExtUpgrade;
}
class ExtUpgrade : public AbstractExtItem
{
Q_OBJECT
Q_PROPERTY(QString executable READ executable WRITE setExecutable)
Q_PROPERTY(QString filter READ filter WRITE setFilter)
Q_PROPERTY(int null READ null WRITE setNull)
public:
explicit ExtUpgrade(QWidget *parent = nullptr,
const QString upgradeName = QString(),
const QStringList directories = QStringList());
virtual ~ExtUpgrade();
ExtUpgrade *copy(const QString _fileName, const int _number);
// get methods
QString executable() const;
QString filter() const;
int null() const;
QString uniq() const;
// set methods
void setExecutable(const QString _executable = QString("/usr/bin/true"));
void setFilter(const QString _filter = QString());
void setNull(const int _null = 0);
public slots:
void readConfiguration();
QVariantHash run();
int showConfiguration(const QVariant args = QVariant());
void writeConfiguration() const;
private slots:
void updateValue();
private:
QProcess *process = nullptr;
Ui::ExtUpgrade *ui;
void translate();
// properties
QString m_executable = QString("/usr/bin/true");
QString m_filter = QString("");
int m_null = 0;
// internal properties
int times = 0;
QVariantHash value;
};
#endif /* EXTUPGRADE_H */

View File

@ -104,6 +104,29 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_filter">
<item>
<widget class="QLabel" name="label_filter">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Filter</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_filter"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_active">
<item>

View File

@ -0,0 +1,394 @@
/***************************************************************************
* 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 "extweather.h"
#include "ui_extweather.h"
#include <KI18n/KLocalizedString>
#include <QDir>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QSettings>
#include <QStandardPaths>
#include <qreplytimeout/qreplytimeout.h>
#include "awdebug.h"
#include "version.h"
ExtWeather::ExtWeather(QWidget *parent, const QString weatherName,
const QStringList directories)
: AbstractExtItem(parent, weatherName, directories)
, ui(new Ui::ExtWeather)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
readConfiguration();
readJsonMap();
ui->setupUi(this);
translate();
values[tag(QString("weatherId"))] = 0;
values[tag(QString("weather"))] = QString("");
values[tag(QString("humidity"))] = 0;
values[tag(QString("pressure"))] = 0.0;
values[tag(QString("temperature"))] = 0.0;
// HACK declare as child of nullptr to avoid crash with plasmawindowed
// in the destructor
manager = new QNetworkAccessManager(nullptr);
connect(manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(weatherReplyReceived(QNetworkReply *)));
}
ExtWeather::~ExtWeather()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
disconnect(manager, SIGNAL(finished(QNetworkReply *)), this,
SLOT(weatherReplyReceived(QNetworkReply *)));
manager->deleteLater();
delete ui;
}
ExtWeather *ExtWeather::copy(const QString _fileName, const int _number)
{
qCDebug(LOG_LIB) << "File" << _fileName;
qCDebug(LOG_LIB) << "Number" << _number;
ExtWeather *item = new ExtWeather(static_cast<QWidget *>(parent()),
_fileName, directories());
item->setActive(isActive());
item->setApiVersion(apiVersion());
item->setCity(city());
item->setComment(comment());
item->setCountry(country());
item->setInterval(interval());
item->setImage(image());
item->setName(name());
item->setNumber(_number);
item->setTs(ts());
return item;
}
QString ExtWeather::weatherFromInt(const int _id) const
{
qCDebug(LOG_LIB) << "Weather ID" << _id;
QVariantMap map
= jsonMap[m_image ? QString("image") : QString("text")].toMap();
return map.value(QString::number(_id), map[QString("default")]).toString();
}
QString ExtWeather::city() const
{
return m_city;
}
QString ExtWeather::country() const
{
return m_country;
}
bool ExtWeather::image() const
{
return m_image;
}
int ExtWeather::ts() const
{
return m_ts;
}
QString ExtWeather::uniq() const
{
return QString("%1 (%2) at %3").arg(m_city).arg(m_country).arg(m_ts);
}
void ExtWeather::setCity(const QString _city)
{
qCDebug(LOG_LIB) << "City" << _city;
m_city = _city;
}
void ExtWeather::setCountry(const QString _country)
{
qCDebug(LOG_LIB) << "Country" << _country;
m_country = _country;
}
void ExtWeather::setImage(const bool _image)
{
qCDebug(LOG_LIB) << "Use image" << _image;
m_image = _image;
}
void ExtWeather::setTs(const int _ts)
{
qCDebug(LOG_LIB) << "Timestamp" << _ts;
m_ts = _ts;
}
void ExtWeather::readConfiguration()
{
AbstractExtItem::readConfiguration();
for (int i = directories().count() - 1; i >= 0; i--) {
if (!QDir(directories().at(i))
.entryList(QDir::Files)
.contains(fileName()))
continue;
QSettings settings(
QString("%1/%2").arg(directories().at(i)).arg(fileName()),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setCity(settings.value(QString("X-AW-City"), m_city).toString());
setCountry(
settings.value(QString("X-AW-Country"), m_country).toString());
setTs(settings.value(QString("X-AW-TS"), m_ts).toInt());
// api == 2
setImage(
settings.value(QString("X-AW-Image"), QVariant(m_image)).toString()
== QString("true"));
settings.endGroup();
}
// update for current API
if ((apiVersion() > 0) && (apiVersion() < AWEWAPI)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to"
<< AWEWAPI;
setApiVersion(AWEWAPI);
writeConfiguration();
}
}
void ExtWeather::readJsonMap()
{
QString fileName = QStandardPaths::locate(
QStandardPaths::GenericDataLocation,
QString("awesomewidgets/weather/awesomewidgets-extweather-ids.json"));
qCInfo(LOG_LIB) << "Map file" << fileName;
QFile jsonFile(fileName);
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(LOG_LIB) << "Could not open" << fileName;
return;
}
QString jsonText = jsonFile.readAll();
jsonFile.close();
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonText.toUtf8(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_LIB) << "Parse error" << error.errorString();
return;
}
jsonMap = jsonDoc.toVariant().toMap();
qCInfo(LOG_LIB) << "Weather map" << jsonMap;
}
QVariantHash ExtWeather::run()
{
if ((!isActive()) || (isRunning))
return values;
if (times == 1) {
qCInfo(LOG_LIB) << "Send request";
isRunning = true;
QNetworkReply *reply
= manager->get(QNetworkRequest(QUrl(url(m_ts != 0))));
new QReplyTimeout(reply, 1000);
}
// update value
if (times >= interval())
times = 0;
times++;
return values;
}
int ExtWeather::showConfiguration(const QVariant args)
{
Q_UNUSED(args)
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_numberValue->setText(QString("%1").arg(number()));
ui->lineEdit_city->setText(m_city);
ui->lineEdit_country->setText(m_country);
ui->spinBox_timestamp->setValue(m_ts);
ui->checkBox_image->setCheckState(m_image ? Qt::Checked : Qt::Unchecked);
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked
: Qt::Unchecked);
ui->spinBox_interval->setValue(interval());
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setNumber(ui->label_numberValue->text().toInt());
setApiVersion(AWEWAPI);
setCity(ui->lineEdit_city->text());
setCountry(ui->lineEdit_country->text());
setTs(ui->spinBox_timestamp->value());
setImage(ui->checkBox_image->checkState() == Qt::Checked);
setActive(ui->checkBox_active->checkState() == Qt::Checked);
setInterval(ui->spinBox_interval->value());
writeConfiguration();
return ret;
}
void ExtWeather::writeConfiguration() const
{
AbstractExtItem::writeConfiguration();
QSettings settings(
QString("%1/%2").arg(directories().first()).arg(fileName()),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
settings.setValue(QString("X-AW-City"), m_city);
settings.setValue(QString("X-AW-Country"), m_country);
settings.setValue(QString("X-AW-Image"), m_image);
settings.setValue(QString("X-AW-TS"), m_ts);
settings.endGroup();
settings.sync();
}
void ExtWeather::weatherReplyReceived(QNetworkReply *reply)
{
qCDebug(LOG_LIB) << "Return code" << reply->error();
qCDebug(LOG_LIB) << "Reply error message" << reply->errorString();
isRunning = false;
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
reply->deleteLater();
if ((reply->error() != QNetworkReply::NoError)
|| (error.error != QJsonParseError::NoError)) {
qCWarning(LOG_LIB) << "Parse error" << error.errorString();
return;
}
// convert to map
QVariantMap json = jsonDoc.toVariant().toMap();
if (json[QString("cod")].toInt() != 200) {
qCWarning(LOG_LIB) << "Invalid OpenWeatherMap return code"
<< json[QString("cod")].toInt();
return;
}
QVariantHash data;
if (m_ts == 0) {
data = parseSingleJson(json);
} else {
QVariantList list = json[QString("list")].toList();
data = parseSingleJson(list.count() <= m_ts ? list.at(m_ts - 1).toMap()
: list.last().toMap());
}
foreach (QString key, data.keys())
values[tag(key)] = data[key];
}
QVariantHash ExtWeather::parseSingleJson(const QVariantMap json) const
{
qCDebug(LOG_LIB) << "Single json data" << json;
QVariantHash output;
// weather status
QVariantList weather = json[QString("weather")].toList();
if (!weather.isEmpty()) {
int _id = weather.first().toMap()[QString("id")].toInt();
output[QString("weatherId")] = _id;
output[QString("weather")] = weatherFromInt(_id);
}
// main data
QVariantMap mainWeather = json[QString("main")].toMap();
if (!weather.isEmpty()) {
output[QString("humidity")]
= mainWeather[QString("humidity")].toFloat();
output[QString("pressure")]
= mainWeather[QString("pressure")].toFloat();
output[QString("temperature")] = mainWeather[QString("temp")].toFloat();
}
return output;
}
void ExtWeather::translate()
{
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_number->setText(i18n("Tag"));
ui->label_city->setText(i18n("City"));
ui->label_country->setText(i18n("Country"));
ui->label_timestamp->setText(i18n("Timestamp"));
ui->checkBox_image->setText(i18n("Use images"));
ui->checkBox_active->setText(i18n("Active"));
ui->label_interval->setText(i18n("Interval"));
}
QString ExtWeather::url(const bool isForecast) const
{
qCDebug(LOG_LIB) << "Is forecast" << isForecast;
QString apiUrl = isForecast ? QString(OWM_FORECAST_URL) : QString(OWM_URL);
apiUrl.replace(QString("$CITY"), m_city);
apiUrl.replace(QString("$COUNTRY"), m_country);
qCInfo(LOG_LIB) << "API url" << apiUrl;
return apiUrl;
}

View File

@ -0,0 +1,94 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef EXTWEATHER_H
#define EXTWEATHER_H
#include <QNetworkReply>
#include "abstractextitem.h"
#define OWM_URL \
"http://api.openweathermap.org/data/2.5/" \
"weather?q=$CITY,$COUNTRY&units=metric"
#define OWM_FORECAST_URL \
"http://api.openweathermap.org/data/2.5/" \
"forecast?q=$CITY,$COUNTRY&units=metric"
namespace Ui
{
class ExtWeather;
}
class ExtWeather : public AbstractExtItem
{
Q_OBJECT
Q_PROPERTY(QString city READ city WRITE setCity)
Q_PROPERTY(QString country READ country WRITE setCountry)
Q_PROPERTY(bool image READ image WRITE setImage)
Q_PROPERTY(int ts READ ts WRITE setTs)
public:
explicit ExtWeather(QWidget *parent = nullptr,
const QString weatherName = QString(),
const QStringList directories = QStringList());
virtual ~ExtWeather();
ExtWeather *copy(const QString _fileName, const int _number);
QString weatherFromInt(const int _id) const;
// get methods
QString city() const;
QString country() const;
bool image() const;
int ts() const;
QString uniq() const;
// set methods
void setCity(const QString _city = QString("London"));
void setCountry(const QString _country = QString("uk"));
void setImage(const bool _image = false);
void setTs(const int _ts = 0);
public slots:
void readConfiguration();
void readJsonMap();
QVariantHash run();
int showConfiguration(const QVariant args = QVariant());
void writeConfiguration() const;
private slots:
void weatherReplyReceived(QNetworkReply *reply);
private:
QNetworkAccessManager *manager;
bool isRunning = false;
Ui::ExtWeather *ui;
QVariantHash parseSingleJson(const QVariantMap json) const;
void translate();
QString url(const bool isForecast = false) const;
// properties
QString m_city = QString("London");
QString m_country = QString("uk");
bool m_image = false;
int m_ts = 0;
QVariantMap jsonMap = QVariantMap();
// values
int times = 0;
QVariantHash values;
};
#endif /* EXTWEATHER_H */

View File

@ -0,0 +1,301 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ExtWeather</class>
<widget class="QDialog" name="ExtWeather">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>420</width>
<height>301</height>
</rect>
</property>
<property name="windowTitle">
<string>Configuration</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="layout_name">
<item>
<widget class="QLabel" name="label_name">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_name"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_comment">
<item>
<widget class="QLabel" name="label_comment">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Comment</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_comment"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_number">
<item>
<widget class="QLabel" name="label_number">
<property name="text">
<string>Tag</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_numberValue">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_city">
<item>
<widget class="QLabel" name="label_city">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>City</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_city"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_country">
<item>
<widget class="QLabel" name="label_country">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Country</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_country"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_timestamp">
<item>
<widget class="QLabel" name="label_timestamp">
<property name="text">
<string>Timestamp</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_timestamp">
<property name="maximum">
<number>40</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_image">
<item>
<spacer name="spacer_image">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_image">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Use images</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_active">
<item>
<spacer name="spacer_active">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_active">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Active</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layout_interval">
<item>
<widget class="QLabel" name="label_interval">
<property name="text">
<string>Interval</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_interval">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>60</number>
</property>
</widget>
</item>
</layout>
</item>
<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>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ExtWeather</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>ExtWeather</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,580 @@
/***************************************************************************
* 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 "graphicalitem.h"
#include "ui_graphicalitem.h"
#include <KI18n/KLocalizedString>
#include <QBuffer>
#include <QColorDialog>
#include <QDir>
#include <QGraphicsEllipseItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QSettings>
#include <math.h>
#include "awdebug.h"
#include "version.h"
GraphicalItem::GraphicalItem(QWidget *parent, const QString desktopName,
const QStringList directories)
: AbstractExtItem(parent, desktopName, directories)
, ui(new Ui::GraphicalItem)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
readConfiguration();
ui->setupUi(this);
translate();
initScene();
connect(ui->pushButton_activeColor, SIGNAL(clicked()), this,
SLOT(changeColor()));
connect(ui->pushButton_inactiveColor, SIGNAL(clicked()), this,
SLOT(changeColor()));
}
GraphicalItem::~GraphicalItem()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete m_scene;
delete ui;
}
GraphicalItem *GraphicalItem::copy(const QString _fileName, const int _number)
{
qCDebug(LOG_LIB) << "File" << _fileName;
qCDebug(LOG_LIB) << "Number" << _number;
GraphicalItem *item = new GraphicalItem(static_cast<QWidget *>(parent()),
_fileName, directories());
item->setActive(isActive());
item->setActiveColor(activeColor());
item->setApiVersion(apiVersion());
item->setBar(bar());
item->setComment(comment());
item->setDirection(direction());
item->setHeight(height());
item->setInactiveColor(inactiveColor());
item->setInterval(interval());
item->setName(QString("bar%1").arg(_number));
item->setNumber(_number);
item->setType(type());
item->setWidth(width());
return item;
}
QString GraphicalItem::image(const QVariant value)
{
qCDebug(LOG_LIB) << "Value" << value;
if (m_bar == QString("none"))
return QString("");
m_scene->clear();
int scale[2] = {1, 1};
// paint
switch (m_type) {
case Vertical:
paintVertical(value.toFloat());
// scale
scale[1] = -2 * static_cast<int>(m_direction) + 1;
break;
case Circle:
paintCircle(value.toFloat());
// scale
scale[0] = -2 * static_cast<int>(m_direction) + 1;
break;
case Graph:
paintGraph(value.value<QList<float>>());
// direction option is not recognized by this GI type
break;
case Horizontal:
default:
paintHorizontal(value.toFloat());
// scale
scale[0] = -2 * static_cast<int>(m_direction) + 1;
break;
}
// convert
QPixmap pixmap
= m_view->grab().transformed(QTransform().scale(scale[0], scale[1]));
QByteArray byteArray;
QBuffer buffer(&byteArray);
pixmap.save(&buffer, "PNG");
QString url = QString("<img src=\"data:image/png;base64,%1\"/>")
.arg(QString(byteArray.toBase64()));
return url;
}
QString GraphicalItem::bar() const
{
return m_bar;
}
QString GraphicalItem::activeColor() const
{
return m_activeColor;
}
QString GraphicalItem::inactiveColor() const
{
return m_inactiveColor;
}
QString GraphicalItem::tag() const
{
return QString("bar%1%2").arg(number()).arg(m_bar);
}
GraphicalItem::Type GraphicalItem::type() const
{
return m_type;
}
QString GraphicalItem::strType() const
{
QString value;
switch (m_type) {
case Vertical:
value = QString("Vertical");
break;
case Circle:
value = QString("Circle");
break;
case Graph:
value = QString("Graph");
break;
case Horizontal:
default:
value = QString("Horizontal");
break;
}
return value;
}
GraphicalItem::Direction GraphicalItem::direction() const
{
return m_direction;
}
QString GraphicalItem::strDirection() const
{
QString value;
switch (m_direction) {
case RightToLeft:
value = QString("RightToLeft");
break;
case LeftToRight:
default:
value = QString("LeftToRight");
break;
}
return value;
}
int GraphicalItem::height() const
{
return m_height;
}
int GraphicalItem::width() const
{
return m_width;
}
QString GraphicalItem::uniq() const
{
return m_bar;
}
void GraphicalItem::setBar(const QString _bar)
{
qCDebug(LOG_LIB) << "Bar" << _bar;
if (!_bar.contains(QRegExp(
QString("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)")))) {
qCWarning(LOG_LIB) << "Unsupported bar type" << _bar;
m_bar = QString("none");
} else {
m_bar = _bar;
}
}
void GraphicalItem::setActiveColor(const QString _color)
{
qCDebug(LOG_LIB) << "Color" << _color;
m_activeColor = _color;
}
void GraphicalItem::setInactiveColor(const QString _color)
{
qCDebug(LOG_LIB) << "Color" << _color;
m_inactiveColor = _color;
}
void GraphicalItem::setType(const Type _type)
{
qCDebug(LOG_LIB) << "Type" << _type;
m_type = _type;
}
void GraphicalItem::setStrType(const QString _type)
{
qCDebug(LOG_LIB) << "Type" << _type;
if (_type == QString("Vertical"))
setType(Vertical);
else if (_type == QString("Circle"))
setType(Circle);
else if (_type == QString("Graph"))
setType(Graph);
else
setType(Horizontal);
}
void GraphicalItem::setDirection(const Direction _direction)
{
qCDebug(LOG_LIB) << "Direction" << _direction;
m_direction = _direction;
}
void GraphicalItem::setStrDirection(const QString _direction)
{
qCDebug(LOG_LIB) << "Direction" << _direction;
if (_direction == QString("RightToLeft"))
setDirection(RightToLeft);
else
setDirection(LeftToRight);
}
void GraphicalItem::setHeight(const int _height)
{
qCDebug(LOG_LIB) << "Height" << _height;
if (_height <= 0)
return;
m_height = _height;
}
void GraphicalItem::setWidth(const int _width)
{
qCDebug(LOG_LIB) << "Width" << _width;
if (_width <= 0)
return;
m_width = _width;
}
void GraphicalItem::readConfiguration()
{
AbstractExtItem::readConfiguration();
for (int i = directories().count() - 1; i >= 0; i--) {
if (!QDir(directories().at(i))
.entryList(QDir::Files)
.contains(fileName()))
continue;
QSettings settings(
QString("%1/%2").arg(directories().at(i)).arg(fileName()),
QSettings::IniFormat);
settings.beginGroup(QString("Desktop Entry"));
setBar(settings.value(QString("X-AW-Value"), m_bar).toString());
setActiveColor(
settings.value(QString("X-AW-ActiveColor"), m_activeColor)
.toString());
setInactiveColor(
settings.value(QString("X-AW-InactiveColor"), m_inactiveColor)
.toString());
setStrType(settings.value(QString("X-AW-Type"), strType()).toString());
setStrDirection(
settings.value(QString("X-AW-Direction"), strDirection())
.toString());
setHeight(settings.value(QString("X-AW-Height"), m_height).toInt());
setWidth(settings.value(QString("X-AW-Width"), m_width).toInt());
// api == 2
if (apiVersion() < 2)
setNumber(bar().remove(QString("bar")).toInt());
settings.endGroup();
}
// update for current API
if ((apiVersion() > 0) && (apiVersion() < AWGIAPI)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to"
<< AWGIAPI;
setApiVersion(AWGIAPI);
writeConfiguration();
}
}
QVariantHash GraphicalItem::run()
{
// required by abstract class
return QVariantHash();
}
int GraphicalItem::showConfiguration(const QVariant args)
{
qCDebug(LOG_LIB) << "Combobox arguments" << args;
QStringList tags = args.toStringList();
ui->label_nameValue->setText(name());
ui->lineEdit_comment->setText(comment());
ui->comboBox_value->addItems(tags);
ui->comboBox_value->addItem(m_bar);
ui->comboBox_value->setCurrentIndex(ui->comboBox_value->count() - 1);
ui->pushButton_activeColor->setText(m_activeColor);
ui->pushButton_inactiveColor->setText(m_inactiveColor);
ui->comboBox_type->setCurrentIndex(static_cast<int>(m_type));
ui->comboBox_direction->setCurrentIndex(static_cast<int>(m_direction));
ui->spinBox_height->setValue(m_height);
ui->spinBox_width->setValue(m_width);
int ret = exec();
if (ret != 1)
return ret;
setName(ui->label_nameValue->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AWGIAPI);
setBar(ui->comboBox_value->currentText());
setActiveColor(ui->pushButton_activeColor->text().remove(QChar('&')));
setInactiveColor(ui->pushButton_inactiveColor->text().remove(QChar('&')));
setStrType(ui->comboBox_type->currentText());
setStrDirection(ui->comboBox_direction->currentText());
setHeight(ui->spinBox_height->value());
setWidth(ui->spinBox_width->value());
writeConfiguration();
return ret;
}
void GraphicalItem::writeConfiguration() const
{
AbstractExtItem::writeConfiguration();
QSettings settings(
QString("%1/%2").arg(directories().first()).arg(fileName()),
QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup(QString("Desktop Entry"));
settings.setValue(QString("X-AW-Value"), m_bar);
settings.setValue(QString("X-AW-ActiveColor"), m_activeColor);
settings.setValue(QString("X-AW-InactiveColor"), m_inactiveColor);
settings.setValue(QString("X-AW-Type"), strType());
settings.setValue(QString("X-AW-Direction"), strDirection());
settings.setValue(QString("X-AW-Height"), m_height);
settings.setValue(QString("X-AW-Width"), m_width);
settings.endGroup();
settings.sync();
}
void GraphicalItem::changeColor()
{
QColor color
= stringToColor((static_cast<QPushButton *>(sender()))->text());
QColor newColor = QColorDialog::getColor(color, this, tr("Select color"),
QColorDialog::ShowAlphaChannel);
if (!newColor.isValid())
return;
qCInfo(LOG_LIB) << "Selected color" << newColor;
QStringList colorText;
colorText.append(QString("%1").arg(newColor.red()));
colorText.append(QString("%1").arg(newColor.green()));
colorText.append(QString("%1").arg(newColor.blue()));
colorText.append(QString("%1").arg(newColor.alpha()));
return static_cast<QPushButton *>(sender())
->setText(colorText.join(QChar(',')));
}
void GraphicalItem::initScene()
{
// init scene
m_scene = new QGraphicsScene();
if (m_type == Graph)
m_scene->setBackgroundBrush(stringToColor(m_inactiveColor));
else
m_scene->setBackgroundBrush(QBrush(Qt::NoBrush));
// init view
m_view = new QGraphicsView(m_scene);
m_view->setStyleSheet(QString("background: transparent"));
m_view->setContentsMargins(0, 0, 0, 0);
m_view->setFrameShape(QFrame::NoFrame);
m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->resize(m_width + 5.0, m_height + 5.0);
}
void GraphicalItem::paintCircle(const float value)
{
QPen pen;
pen.setWidth(1.0);
float percent = value / 100.0;
QGraphicsEllipseItem *circle;
QColor inactive = stringToColor(m_inactiveColor);
QColor active = stringToColor(m_activeColor);
// inactive
pen.setColor(inactive);
circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, pen,
QBrush(inactive, Qt::SolidPattern));
circle->setSpanAngle(-(1.0 - percent) * 360.0 * 16.0);
circle->setStartAngle(90.0 * 16.0 - percent * 360.0 * 16.0);
// active
pen.setColor(active);
circle = m_scene->addEllipse(0.0, 0.0, m_width, m_height, pen,
QBrush(active, Qt::SolidPattern));
circle->setSpanAngle(-percent * 360.0 * 16.0);
circle->setStartAngle(90.0 * 16.0);
}
void GraphicalItem::paintGraph(const QList<float> value)
{
QPen pen;
pen.setColor(stringToColor(m_activeColor));
// default norms
float normX
= static_cast<float>(m_width) / static_cast<float>(value.count());
float normY = static_cast<float>(m_height) / (1.5 * 100.0);
// paint graph
for (int i = 0; i < value.count() - 1; i++) {
// some magic here
float x1 = i * normX;
float y1 = -fabs(value.at(i)) * normY + 5.0;
float x2 = (i + 1) * normX;
float y2 = -fabs(value.at(i + 1)) * normY + 5.0;
m_scene->addLine(x1, y1, x2, y2, pen);
}
}
void GraphicalItem::paintHorizontal(const float value)
{
QPen pen;
float percent = value / 100.0;
pen.setWidth(m_height);
// inactive
pen.setColor(stringToColor(m_inactiveColor));
m_scene->addLine(percent * m_width + 0.5 * m_height, 0.5 * m_height,
m_width + 0.5 * m_height, 0.5 * m_height, pen);
// active
pen.setColor(stringToColor(m_activeColor));
m_scene->addLine(-0.5 * m_height, 0.5 * m_height,
percent * m_width - 0.5 * m_height, 0.5 * m_height, pen);
}
void GraphicalItem::paintVertical(const float value)
{
QPen pen;
float percent = value / 100.0;
pen.setWidth(m_width);
// inactive
pen.setColor(stringToColor(m_inactiveColor));
m_scene->addLine(0.5 * m_width, -0.5 * m_width, 0.5 * m_width,
(1.0 - percent) * m_height - 0.5 * m_width, pen);
// active
pen.setColor(stringToColor(m_activeColor));
m_scene->addLine(0.5 * m_width, (1.0 - percent) * m_height + 0.5 * m_width,
0.5 * m_width, m_height + 0.5 * m_width, pen);
}
QColor GraphicalItem::stringToColor(const QString _color) const
{
qCDebug(LOG_LIB) << "Color" << _color;
QColor qcolor;
QStringList listColor = _color.split(QChar(','));
while (listColor.count() < 4)
listColor.append(QString("0"));
qcolor.setRed(listColor.at(0).toInt());
qcolor.setGreen(listColor.at(1).toInt());
qcolor.setBlue(listColor.at(2).toInt());
qcolor.setAlpha(listColor.at(3).toInt());
return qcolor;
}
void GraphicalItem::translate()
{
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_value->setText(i18n("Value"));
ui->label_activeColor->setText(i18n("Active color"));
ui->label_inactiveColor->setText(i18n("Inactive color"));
ui->label_type->setText(i18n("Type"));
ui->label_direction->setText(i18n("Direction"));
ui->label_height->setText(i18n("Height"));
ui->label_width->setText(i18n("Width"));
}

View File

@ -19,19 +19,21 @@
#define GRAPHICALITEM_H
#include <QColor>
#include <QDialog>
#include "abstractextitem.h"
namespace Ui {
class GraphicalItem;
class QGraphicsScene;
class QGraphicsView;
namespace Ui
{
class GraphicalItem;
}
class GraphicalItem : public QDialog
class GraphicalItem : public AbstractExtItem
{
Q_OBJECT
Q_PROPERTY(int apiVersion READ apiVersion WRITE setApiVersion)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(QString comment READ comment WRITE setComment)
Q_PROPERTY(QString bar READ bar WRITE setBar)
Q_PROPERTY(QString activeColor READ activeColor WRITE setActiveColor)
Q_PROPERTY(QString inactiveColor READ inactiveColor WRITE setInactiveColor)
@ -41,38 +43,28 @@ class GraphicalItem : public QDialog
Q_PROPERTY(int width READ width WRITE setWidth)
public:
enum Direction {
LeftToRight = 0,
RightToLeft
};
enum Type {
Horizontal = 0,
Vertical,
Circle
};
enum Direction { LeftToRight = 0, RightToLeft };
enum Type { Horizontal = 0, Vertical, Circle, Graph };
explicit GraphicalItem(QWidget *parent = nullptr, const QString desktopName = QString(),
const QStringList directories = QStringList(), const bool debugCmd = false);
~GraphicalItem();
QString fileName();
QString image(const float value);
explicit GraphicalItem(QWidget *parent = nullptr,
const QString desktopName = QString(),
const QStringList directories = QStringList());
virtual ~GraphicalItem();
GraphicalItem *copy(const QString _fileName, const int _number);
QString image(const QVariant value);
// get methods
int apiVersion();
QString name();
QString comment();
QString bar();
QString activeColor();
QString inactiveColor();
Type type();
QString strType();
Direction direction();
QString strDirection();
int height();
int width();
QString bar() const;
QString activeColor() const;
QString inactiveColor() const;
QString tag() const;
Type type() const;
QString strType() const;
Direction direction() const;
QString strDirection() const;
int height() const;
int width() const;
QString uniq() const;
// set methods
void setApiVersion(const int _apiVersion = 0);
void setName(const QString _name = QString("none"));
void setComment(const QString _comment = QString("empty"));
void setBar(const QString _bar = QString("cpu"));
void setActiveColor(const QString _color = QString("0,0,0,130"));
void setInactiveColor(const QString _color = QString("255,255,255,130"));
@ -85,23 +77,29 @@ public:
public slots:
void readConfiguration();
int showConfiguration(const QStringList tags = QStringList());
bool tryDelete();
void writeConfiguration();
QVariantHash run();
int showConfiguration(const QVariant args = QVariant());
void writeConfiguration() const;
private slots:
void changeColor();
private:
QColor stringToColor(const QString _color);
QString m_fileName;
QStringList m_dirs;
bool debug;
QGraphicsScene *m_scene = nullptr;
QGraphicsView *m_view = nullptr;
Ui::GraphicalItem *ui;
void initScene();
// paint methods
void paintCircle(const float value);
void paintGraph(const QList<float> value);
void paintHorizontal(const float value);
void paintVertical(const float value);
// additional method
QColor stringToColor(const QString _color) const;
void translate();
// properties
int m_apiVersion = 0;
QString m_name = QString("none");
QString m_comment = QString("empty");
QString m_bar = QString("cpu");
QString m_activeColor = QString("0,0,0,130");
QString m_inactiveColor = QString("255,255,255,130");

View File

@ -150,6 +150,11 @@
<string notr="true">Circle</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Graph</string>
</property>
</item>
</widget>
</item>
</layout>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,6 +4,6 @@ Name=RTS
Comment=RTS Index
X-AW-Ticker="RTS.RS"
X-AW-Active=false
X-AW-ApiVersion=2
X-AW-ApiVersion=3
X-AW-Interval=60
X-AW-Number=5

View File

@ -4,6 +4,6 @@ Name=S&P
Comment=S&P 500 Index
X-AW-Ticker="^GSPC"
X-AW-Active=false
X-AW-ApiVersion=2
X-AW-ApiVersion=3
X-AW-Interval=60
X-AW-Number=6

View File

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

View File

@ -4,6 +4,6 @@ Name=VIX
Comment=Volatility S&P 500
X-AW-Ticker="^VIX"
X-AW-Active=false
X-AW-ApiVersion=2
X-AW-ApiVersion=3
X-AW-Interval=60
X-AW-Number=7

View File

@ -4,10 +4,9 @@ Name=aw-get-external-ip
Comment=Custom command to get external IP
Exec=curl ip4.telize.com
X-AW-Prefix=
X-AW-Active=true
X-AW-Output=true
X-AW-Active=false
X-AW-Redirect=nothing
X-AW-Interval=1
X-AW-ApiVersion=3
X-AW-ApiVersion=4
X-AW-Number=0
X-AW-Filters=

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