Compare commits

..

67 Commits

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

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

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

(for example deadbeef was affected). Suggested patch should fix this
issue and seems to be working with at least deadbeef and qmmp mpris
engines.
2017-05-17 17:43:18 +03:00
253 changed files with 7888 additions and 6475 deletions

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

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

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

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

1
.gitignore vendored
View File

@ -47,3 +47,4 @@ pkg
# clion settings # clion settings
.idea .idea
cmake-build*

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "sources/3rdparty/fontdialog"]
path = sources/3rdparty/fontdialog
url = https://github.com/arcan1s/qtadds-fontdialog.git

View File

@ -1,28 +0,0 @@
sudo: required
arch:
packages:
- plasma-framework
# build deps
- cmake
- extra-cmake-modules
- python
# test
- xorg-server-xvfb
# additional targets
- clang
- cppcheck
script:
- export DISPLAY=:99.0
- git clone https://github.com/arcan1s/awesome-widgets/
- cd awesome-widgets; git submodule update --init --recursive
- mkdir awesome-widgets/build
- cd awesome-widgets/build; cmake -DKDE_INSTALL_USE_QT_SYS_PATHS=ON -DCMAKE_BUILD_TYPE=Optimization -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_FUTURE=ON -DBUILD_TESTING=ON ../sources
- cd awesome-widgets/build; make
- cd awesome-widgets/build; make cppcheck
- cd awesome-widgets/build; make clangformat && ( [ `git status -s | wc -l` -eq 0 ] || exit 1 )
- cd awesome-widgets/build; xvfb-run make test
- sleep 3
script:
- "curl -s https://raw.githubusercontent.com/mikkeloscar/arch-travis/master/arch-travis.sh | bash"

View File

@ -1,20 +0,0 @@
sudo: required
dist: trusty
language: cpp
os:
- linux
before_script:
- sudo apt-add-repository -y ppa:kubuntu-ppa/backports
- sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list
- sudo sed -i 's/trusty/wily/g' /etc/apt/sources.list.d/kubuntu-ppa-backports-trusty.list
- sudo apt-get -qq update
- sudo apt-get -y -qq -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew install libkf5i18n-dev libkf5notifications-dev libkf5service-dev libkf5windowsystem-dev plasma-framework-dev qtbase5-dev qtdeclarative5-dev extra-cmake-modules cmake g++
- rm -rf build
- mkdir build
script:
- cd build
- cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DKDE_INSTALL_USE_QT_SYS_PATHS=ON ../sources
- make

View File

@ -11,3 +11,5 @@ Ernesto Avilés Vzqz (Spanish)
Виктор Слободян (Ukrainian) Виктор Слободян (Ukrainian)
Steve Lemuel (Chinese) Steve Lemuel (Chinese)
Mariusz Kocoń (Polish) Mariusz Kocoń (Polish)
Ibnu Daru Aji (Indonesian)
Antonio Vivace (Italian)

View File

@ -1,3 +1,30 @@
Ver.3.5.0:
+ wayland support
* update code to latest standards
- drop support of windows preview
Ver.3.4.2:
+ Italian translation (#136, thanks to @avivace)
+ stooq quotes support (default) (#131)
+ Indonesian translation (#132, thanks to @ibnuda)
+ new keys - $batleftN, $batnowN, $batrateN, $battotalN, $brightness, $volume
* fix compiler warnings
* update to new qt api
- fix non printable spaces (#142, #143)
Ver.3.3.3:
+ add custom keys support (#101)
* DBus interface improvements
* rename tags (up|down|ps)total.* to (up|down|ps)tot.*
- fix issue with invalid (up|down)total($|kb) calculation (#127)
- fix issue with wrong applet identation (#125)
Ver.3.3.2:
- fix bug with invalid DP colour configuration
- fix bug with invalid HTML tags operation
* update to newest Qt and plasma
Ver.3.3.1: Ver.3.3.1:
+ add ability to direct issue report (#104) + add ability to direct issue report (#104)
+ add key completion (#105) + add key completion (#105)

View File

@ -38,7 +38,7 @@ for more details. To avoid manual labor there is automatic cmake target named
* `Q_PROPERTY` macro is allowed and recommended for QObject based classes. * `Q_PROPERTY` macro is allowed and recommended for QObject based classes.
* Qt macros (e.g. `signals`, `slots`, `Q_OBJECT`, etc) are allowed. In other hand * Qt macros (e.g. `signals`, `slots`, `Q_OBJECT`, etc) are allowed. In other hand
`Q_FOREACH` (`foreach`) is not allowed use `for (auto &foo : bar)` instead. `Q_FOREACH` (`foreach`) is not allowed use `for (auto &foo : bar)` instead.
* Current project standard is **C++11**. * Current project standard is **C++17**.
* Do not use C-like code: * Do not use C-like code:
* C-like style iteration if possible. Use `for (auto &foo : bar)` and * C-like style iteration if possible. Use `for (auto &foo : bar)` and
`std::for_each` instead if possible. It is also recommended to use iterators. `std::for_each` instead if possible. It is also recommended to use iterators.

View File

@ -1,7 +1,7 @@
awesome-widgets (ex-pytextmonitor) awesome-widgets (ex-pytextmonitor)
================================== ==================================
[![Build Status](https://travis-ci.org/arcan1s/awesome-widgets.svg?branch=development)](https://travis-ci.org/arcan1s/awesome-widgets) [![build & tests](https://github.com/arcan1s/awesome-widgets/actions/workflows/build.yml/badge.svg)](https://github.com/arcan1s/awesome-widgets/actions/workflows/build.yml)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/8254/badge.svg)](https://scan.coverity.com/projects/awesome-widgets) [![Coverity Scan Build Status](https://scan.coverity.com/projects/8254/badge.svg)](https://scan.coverity.com/projects/awesome-widgets)
Information Information
@ -31,6 +31,7 @@ Dependencies
------------ ------------
* plasma-framework * plasma-framework
* ksysguard (since plasma 5.22)
Optional dependencies Optional dependencies
--------------------- ---------------------
@ -39,6 +40,7 @@ Optional dependencies
* hddtemp * hddtemp
* smartmontools * smartmontools
* music player (mpd or MPRIS supported) * music player (mpd or MPRIS supported)
* wireless_tools
Make dependencies Make dependencies
----------------- -----------------
@ -46,6 +48,8 @@ Make dependencies
* cmake * cmake
* extra-cmake-modules * extra-cmake-modules
In addition some distros might require to install some -dev packages, e.g. the list of required packages for deb-based distros can be found [here](https://github.com/arcan1s/awesome-widgets/blob/development/.docker/Dockerfile-ubuntu-amd64#L7).
Installation Installation
------------ ------------
@ -53,7 +57,7 @@ Installation
* install * install
mkdir build && cd build mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr ../ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr ../sources
make && sudo make install make && sudo make install
**NOTE** on Plasma 5 it very likely requires `-DKDE_INSTALL_USE_QT_SYS_PATHS=ON` flag **NOTE** on Plasma 5 it very likely requires `-DKDE_INSTALL_USE_QT_SYS_PATHS=ON` flag

View File

@ -1,32 +1,20 @@
#!/bin/bash #!/bin/bash
SRCDIR="sources" SRCDIR="sources"
MAJOR=$(grep -m1 PROJECT_VERSION_MAJOR sources/CMakeLists.txt | awk '{print $2}' | sed 's/^.\(.*\)..$/\1/') VERSION="$(git describe --tags --abbrev=0)"
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 widget # build widget
ARCHIVE="awesome-widgets" ARCHIVE="awesome-widgets"
FILES="AUTHORS CHANGELOG COPYING packages patches" FILES="AUTHORS CHANGELOG COPYING packages patches sources"
IGNORELIST="build usr .kdev4 *.kdev4 .idea packages/*src.tar.xz" IGNORELIST="build usr .kdev4 *.kdev4 .idea packages/*src.tar.xz"
# create archive # create archive
[[ -e ${ARCHIVE}-${VERSION}-src.tar.xz ]] && rm -f "${ARCHIVE}-${VERSION}-src.tar.xz" [[ -e ${ARCHIVE}-${VERSION}-src.tar.xz ]] && rm -f "${ARCHIVE}-${VERSION}-src.tar.xz"
[[ -d ${ARCHIVE} ]] && rm -rf "${ARCHIVE}" [[ -d ${ARCHIVE} ]] && rm -rf "${ARCHIVE}"
cp -r "${SRCDIR}" "${ARCHIVE}" cp -r "${SRCDIR}" "${ARCHIVE}"
for FILE in ${FILES[*]}; do cp -r "$FILE" "${ARCHIVE}"; done for FILE in ${FILES[*]}; do cp -r "$FILE" "${ARCHIVE}"; done
for FILE in ${IGNORELIST[*]}; do rm -rf "${ARCHIVE}/${FILE}"; 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" packages
rm -rf "${ARCHIVE}"
# update md5sum tar cJf "${ARCHIVE}-${VERSION}-src.tar.xz" "${ARCHIVE}"
MD5SUMS=$(md5sum ${ARCHIVE}-${VERSION}-src.tar.xz | awk '{print $1}')
sed -i "/md5sums=('[0-9A-Fa-f]*/s/[^'][^)]*/md5sums=('${MD5SUMS}'/" packages/PKGBUILD rm -rf "${ARCHIVE}"
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 packages -type l -xtype l -exec rm -rf {} \;

View File

@ -2,13 +2,13 @@
pkgname=plasma5-applet-awesome-widgets pkgname=plasma5-applet-awesome-widgets
_pkgname=awesome-widgets _pkgname=awesome-widgets
pkgver=3.3.1 pkgver=3.4.3
pkgrel=1 pkgrel=1
pkgdesc="Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor)" pkgdesc="Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor)"
arch=('i686' 'x86_64') arch=('i686' 'x86_64')
url="https://arcanis.me/projects/awesome-widgets" url="https://arcanis.me/projects/awesome-widgets"
license=('GPL3') license=('GPL3')
depends=('plasma-framework') depends=('ksysguard' 'plasma-framework')
optdepends=("catalyst: for GPU monitor" optdepends=("catalyst: for GPU monitor"
"hddtemp: for HDD temperature monitor" "hddtemp: for HDD temperature monitor"
"smartmontools: for HDD temperature monitor" "smartmontools: for HDD temperature monitor"
@ -17,7 +17,7 @@ optdepends=("catalyst: for GPU monitor"
makedepends=('cmake' 'extra-cmake-modules' 'python') makedepends=('cmake' 'extra-cmake-modules' 'python')
source=(https://github.com/arcan1s/awesome-widgets/releases/download/V.${pkgver}/${_pkgname}-${pkgver}-src.tar.xz) source=(https://github.com/arcan1s/awesome-widgets/releases/download/V.${pkgver}/${_pkgname}-${pkgver}-src.tar.xz)
install=${pkgname}.install install=${pkgname}.install
md5sums=('306027b017f940c9c5eaffb65ff82a7f') md5sums=('5953ba518191bb6fff83cdb8633c735c')
backup=('etc/xdg/plasma-dataengine-extsysmon.conf') backup=('etc/xdg/plasma-dataengine-extsysmon.conf')
prepare() { prepare() {

View File

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

View File

@ -1,32 +0,0 @@
diff --git a/sources/awdebug.h b/sources/awdebug.h
index 8447c65..9f8e298 100644
--- a/sources/awdebug.h
+++ b/sources/awdebug.h
@@ -23,10 +23,14 @@
#include "version.h"
+#ifndef qCInfo
+#define qCInfo qCDebug
+#endif
+
namespace AWDebug
{
const char LOG_FORMAT[] = "[%{time "
- "process}][%{if-debug}DD%{endif}%{if-info}II%{endif}%"
+ "process}][%{if-debug}DD%{endif}%"
"{if-warning}WW%{endif}%{if-critical}CC%{endif}%{if-"
"fatal}FF%{endif}][%{category}][%{function}] "
"%{message}";
diff --git a/sources/awesome-widget/plugin/awkeysaggregator.h b/sources/awesome-widget/plugin/awkeysaggregator.h
index d29672e..f15a729 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"

View File

@ -1,139 +0,0 @@
diff --git a/sources/awesome-widget/plugin/awupdatehelper.cpp b/sources/awesome-widget/plugin/awupdatehelper.cpp
index f6b5338..b5a3163 100644
--- a/sources/awesome-widget/plugin/awupdatehelper.cpp
+++ b/sources/awesome-widget/plugin/awupdatehelper.cpp
@@ -35,7 +35,7 @@ AWUpdateHelper::AWUpdateHelper(QObject *_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
- m_foundVersion = QVersionNumber::fromString(VERSION);
+ m_foundVersion = VERSION;
m_genericConfig = QString("%1/awesomewidgets/general.ini")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation));
@@ -67,8 +67,7 @@ void AWUpdateHelper::checkUpdates(const bool _showAnyway)
bool AWUpdateHelper::checkVersion()
{
QSettings settings(m_genericConfig, QSettings::IniFormat);
- QVersionNumber version = QVersionNumber::fromString(
- settings.value("Version", QString(VERSION)).toString());
+ QString version = settings.value("Version", VERSION).toString();
// update version
settings.setValue("Version", QString(VERSION));
settings.sync();
@@ -91,12 +90,11 @@ bool AWUpdateHelper::checkVersion()
}
-void AWUpdateHelper::showInfo(const QVersionNumber &_version)
+void AWUpdateHelper::showInfo(const QString &_version)
{
qCDebug(LOG_AW) << "Version" << _version;
- QString text
- = i18n("You are using the actual version %1", _version.toString());
+ QString text = i18n("You are using the actual version %1", _version);
if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(QString(COMMIT_SHA));
return genMessageBox(i18n("No new version found"), text, QMessageBox::Ok)
@@ -104,7 +102,7 @@ void AWUpdateHelper::showInfo(const QVersionNumber &_version)
}
-void AWUpdateHelper::showUpdates(const QVersionNumber &_version)
+void AWUpdateHelper::showUpdates(const QString &_version)
{
qCDebug(LOG_AW) << "Version" << _version;
@@ -113,7 +111,7 @@ void AWUpdateHelper::showUpdates(const QVersionNumber &_version)
text += QString(COMMIT_SHA).isEmpty()
? "\n"
: QString(" (%1)\n").arg(QString(COMMIT_SHA));
- text += i18n("New version : %1", _version.toString()) + "\n\n";
+ text += i18n("New version : %1", _version) + "\n\n";
text += i18n("Click \"Ok\" to download");
genMessageBox(i18n("There are updates"), text,
@@ -130,8 +128,7 @@ void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *_button)
switch (ret) {
case QMessageBox::AcceptRole:
- QDesktopServices::openUrl(QString(RELEASES)
- + m_foundVersion.toString());
+ QDesktopServices::openUrl(QString(RELEASES) + m_foundVersion);
break;
case QMessageBox::RejectRole:
default:
@@ -162,14 +159,23 @@ void AWUpdateHelper::versionReplyRecieved(QNetworkReply *_reply,
QVariantMap firstRelease = jsonDoc.toVariant().toList().first().toMap();
QString version = firstRelease["tag_name"].toString();
version.remove("V.");
- m_foundVersion = QVersionNumber::fromString(version);
+ m_foundVersion = version;
qCInfo(LOG_AW) << "Update found version to" << m_foundVersion;
- QVersionNumber oldVersion = QVersionNumber::fromString(VERSION);
- if (oldVersion < m_foundVersion)
- return showUpdates(m_foundVersion);
+ // FIXME: possible there is a better way to check versions
+ int old_major = QString(VERSION).split(QChar('.')).at(0).toInt();
+ int old_minor = QString(VERSION).split(QChar('.')).at(1).toInt();
+ int old_patch = QString(VERSION).split(QChar('.')).at(2).toInt();
+ int new_major = version.split(QChar('.')).at(0).toInt();
+ int new_minor = version.split(QChar('.')).at(1).toInt();
+ int new_patch = version.split(QChar('.')).at(2).toInt();
+ if ((old_major < new_major)
+ || ((old_major == new_major) && (old_minor < new_minor))
+ || ((old_major == new_major) && (old_minor == new_minor)
+ && (old_patch < new_patch)))
+ return showUpdates(version);
else if (_showAnyway)
- return showInfo(m_foundVersion);
+ return showInfo(version);
}
diff --git a/sources/awesome-widget/plugin/awupdatehelper.h b/sources/awesome-widget/plugin/awupdatehelper.h
index cfd26e7..b311be2 100644
--- a/sources/awesome-widget/plugin/awupdatehelper.h
+++ b/sources/awesome-widget/plugin/awupdatehelper.h
@@ -21,7 +21,6 @@
#include <QMessageBox>
#include <QObject>
-#include <QVersionNumber>
class QNetworkReply;
@@ -37,15 +36,15 @@ public:
bool checkVersion();
private slots:
- void showInfo(const QVersionNumber &_version);
- void showUpdates(const QVersionNumber &_version);
+ void showInfo(const QString &_version);
+ void showUpdates(const QString &_version);
void userReplyOnUpdates(QAbstractButton *_button);
void versionReplyRecieved(QNetworkReply *_reply, const bool _showAnyway);
private:
QMessageBox *genMessageBox(const QString &_title, const QString &_body,
const QMessageBox::StandardButtons _buttons);
- QVersionNumber m_foundVersion;
+ QString m_foundVersion;
QString m_genericConfig;
};
diff --git a/sources/libraries.cmake b/sources/libraries.cmake
index 6f171a6..004b39f 100644
--- a/sources/libraries.cmake
+++ b/sources/libraries.cmake
@@ -2,7 +2,7 @@
find_package(Gettext REQUIRED)
# main qt libraries
-find_package(Qt5 5.6.0 REQUIRED COMPONENTS Core DBus Network Qml Test Widgets)
+find_package(Qt5 5.5.0 REQUIRED COMPONENTS Core DBus Network Qml Test Widgets)
add_definitions(
${Qt5Core_DEFINITIONS} ${Qt5DBus_DEFINITIONS} ${Qt5Network_DEFINITIONS}
${Qt5Qml_DEFINITIONS} ${Qt5Widgets_DEFINITIONS}

View File

@ -1,27 +1,26 @@
--- ---
Language: Cpp Language: Cpp
AccessModifierOffset: -4 AccessModifierOffset: -4
AlignAfterOpenBracket: true AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false AlignConsecutiveAssignments: None
AlignEscapedNewlinesLeft: false
AlignOperands: true AlignOperands: true
AlignTrailingComments: true AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: false AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false AlwaysBreakTemplateDeclarations: No
BinPackArguments: true BinPackArguments: true
BinPackParameters: true BinPackParameters: true
BreakBeforeBinaryOperators: All BreakBeforeBinaryOperators: All
BreakBeforeBraces: Linux BreakBeforeBraces: Linux
BreakBeforeTernaryOperators: true BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true BreakConstructorInitializersBeforeComma: true
ColumnLimit: 80 ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:' CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4 ConstructorInitializerIndentWidth: 4
@ -59,7 +58,7 @@ SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false SpacesInCStyleCastParentheses: false
SpacesInParentheses: false SpacesInParentheses: false
SpacesInSquareBrackets: false SpacesInSquareBrackets: false
Standard: Cpp11 Standard: Latest
TabWidth: 8 TabWidth: 8
UseTab: Never UseTab: Never
... ...

View File

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

View File

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

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

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

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

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

View File

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

View File

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

View File

@ -12,7 +12,7 @@ QReplyTimeout::QReplyTimeout(QNetworkReply *reply, const int timeout)
void QReplyTimeout::timeout() void QReplyTimeout::timeout()
{ {
QNetworkReply *reply = static_cast<QNetworkReply *>(parent()); auto *reply = dynamic_cast<QNetworkReply *>(parent());
if (reply->isRunning()) if (reply->isRunning())
reply->close(); reply->close();
} }

View File

@ -1,12 +1,13 @@
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.16.0)
# some fucking magic # some fucking magic
cmake_policy(SET CMP0003 OLD)
cmake_policy(SET CMP0002 OLD)
cmake_policy(SET CMP0011 NEW) cmake_policy(SET CMP0011 NEW)
cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0015 NEW)
if (POLICY CMP0063) if (POLICY CMP0063)
cmake_policy(SET CMP0063 OLD) cmake_policy(SET CMP0063 NEW)
endif ()
if (POLICY CMP0071)
cmake_policy(SET CMP0071 NEW)
endif () endif ()
project(awesomewidgets) project(awesomewidgets)
@ -14,8 +15,8 @@ set(PROJECT_AUTHOR "Evgeniy Alekseev")
set(PROJECT_CONTACT "esalexeev@gmail.com") set(PROJECT_CONTACT "esalexeev@gmail.com")
set(PROJECT_LICENSE "GPL3") set(PROJECT_LICENSE "GPL3")
set(PROJECT_VERSION_MAJOR "3") set(PROJECT_VERSION_MAJOR "3")
set(PROJECT_VERSION_MINOR "3") set(PROJECT_VERSION_MINOR "5")
set(PROJECT_VERSION_PATCH "1") set(PROJECT_VERSION_PATCH "0")
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
# append git version if any # append git version if any
set(PROJECT_COMMIT_SHA "Commit hash" CACHE INTERNAL "") set(PROJECT_COMMIT_SHA "Commit hash" CACHE INTERNAL "")
@ -41,40 +42,23 @@ option(BUILD_TESTING "Build with additional test abilities" OFF)
set(PROJECT_CHANGELOG "Changelog" CACHE INTERNAL "") set(PROJECT_CHANGELOG "Changelog" CACHE INTERNAL "")
include(changelog.cmake) include(changelog.cmake)
# flags # directories
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")
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")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_OPTIMIZATION "-Ofast -DNDEBUG")
# linker flags
else ()
message(FATAL_ERROR "Unknown compiler")
endif ()
if (CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_VERBOSE_MAKEFILE ON)
endif ()
# required by successfully coverity and cppcheck build
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(PROJECT_TRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty) set(PROJECT_TRDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty)
set(PROJECT_LIBRARY awesomewidgets) set(PROJECT_LIBRARY awesomewidgets)
set(PROJECT_MONITORSOURCES extsysmonsources) set(PROJECT_MONITORSOURCES extsysmonsources)
# modules
include(compiler.cmake)
include(libraries.cmake) include(libraries.cmake)
include(clang-format.cmake) include(clang-format.cmake)
include(cppcheck.cmake) include(cppcheck.cmake)
include(coverity.cmake) include(coverity.cmake)
# pre-configure
get_directory_property(CMAKE_DEFINITIONS COMPILE_DEFINITIONS) get_directory_property(CMAKE_DEFINITIONS COMPILE_DEFINITIONS)
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h) configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
# build components
add_subdirectory(awesomewidgets) add_subdirectory(awesomewidgets)
add_subdirectory(extsysmonsources) add_subdirectory(extsysmonsources)
add_subdirectory(extsysmon) add_subdirectory(extsysmon)
@ -90,4 +74,3 @@ if (BUILD_TESTING)
endif () endif ()
include(packages-recipe.cmake) include(packages-recipe.cmake)

View File

@ -21,16 +21,12 @@
#include "awdebug.h" #include "awdebug.h"
Q_LOGGING_CATEGORY(LOG_AW, "org.kde.plasma.awesomewidget", Q_LOGGING_CATEGORY(LOG_AW, "org.kde.plasma.awesomewidget", QtMsgType::QtWarningMsg)
QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_DBUS, "org.kde.plasma.awdbus", QtMsgType::QtWarningMsg) Q_LOGGING_CATEGORY(LOG_DBUS, "org.kde.plasma.awdbus", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_DP, "org.kde.plasma.desktoppanel", Q_LOGGING_CATEGORY(LOG_DP, "org.kde.plasma.desktoppanel", QtMsgType::QtWarningMsg)
QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_ESM, "org.kde.plasma.extsysmon", QtMsgType::QtWarningMsg) Q_LOGGING_CATEGORY(LOG_ESM, "org.kde.plasma.extsysmon", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_ESS, "org.kde.plasma.extsysmonsources", Q_LOGGING_CATEGORY(LOG_ESS, "org.kde.plasma.extsysmonsources", QtMsgType::QtWarningMsg)
QtMsgType::QtWarningMsg) Q_LOGGING_CATEGORY(LOG_LIB, "org.kde.plasma.awesomewidgets", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_LIB, "org.kde.plasma.awesomewidgets",
QtMsgType::QtWarningMsg)
QString AWDebug::getAboutText(const QString &_type) QString AWDebug::getAboutText(const QString &_type)
@ -45,53 +41,31 @@ QString AWDebug::getAboutText(const QString &_type)
} else if (_type == "description") { } else if (_type == "description") {
text = i18n("A set of minimalistic plasmoid widgets"); text = i18n("A set of minimalistic plasmoid widgets");
} else if (_type == "links") { } else if (_type == "links") {
text = i18n("Links:") + "<ul>" text = i18n("Links:") + "<ul>" + QString("<li><a href=\"%1\">%2</a></li>").arg(HOMEPAGE).arg(i18n("Homepage"))
+ QString("<li><a href=\"%1\">%2</a></li>") + QString("<li><a href=\"%1\">%2</a></li>").arg(REPOSITORY).arg(i18n("Repository"))
.arg(HOMEPAGE) + QString("<li><a href=\"%1\">%2</a></li>").arg(BUGTRACKER).arg(i18n("Bugtracker"))
.arg(i18n("Homepage")) + QString("<li><a href=\"%1\">%2</a></li>").arg(TRANSLATION).arg(i18n("Translation issue"))
+ QString("<li><a href=\"%1\">%2</a></li>") + QString("<li><a href=\"%1\">%2</a></li>").arg(AUR_PACKAGES).arg(i18n("AUR packages"))
.arg(REPOSITORY) + QString("<li><a href=\"%1\">%2</a></li>").arg(OPENSUSE_PACKAGES).arg(i18n("openSUSE packages"))
.arg(i18n("Repository"))
+ QString("<li><a href=\"%1\">%2</a></li>")
.arg(BUGTRACKER)
.arg(i18n("Bugtracker"))
+ QString("<li><a href=\"%1\">%2</a></li>")
.arg(TRANSLATION)
.arg(i18n("Translation issue"))
+ QString("<li><a href=\"%1\">%2</a></li>")
.arg(AUR_PACKAGES)
.arg(i18n("AUR packages"))
+ QString("<li><a href=\"%1\">%2</a></li>")
.arg(OPENSUSE_PACKAGES)
.arg(i18n("openSUSE packages"))
+ "</ul>"; + "</ul>";
} else if (_type == "copy") { } else if (_type == "copy") {
text = QString("<small>&copy; %1 <a href=\"mailto:%2\">%3</a><br>") text = QString("<small>&copy; %1 <a href=\"mailto:%2\">%3</a><br>").arg(DATE).arg(EMAIL).arg(AUTHOR)
.arg(DATE) + i18nc("This software is licensed under %1", LICENSE) + "</small>";
.arg(EMAIL)
.arg(AUTHOR)
+ i18n("This software is licensed under %1", LICENSE)
+ "</small>";
} else if (_type == "translators") { } else if (_type == "translators") {
QStringList translatorList = QString(TRANSLATORS).split(','); QStringList translatorList = QString(TRANSLATORS).split(',');
for (auto &translator : translatorList) for (auto &translator : translatorList)
translator = QString("<li>%1</li>").arg(translator); translator = QString("<li>%1</li>").arg(translator);
text text = i18n("Translators:") + "<ul>" + translatorList.join("") + "</ul>";
= i18n("Translators:") + "<ul>" + translatorList.join("") + "</ul>";
} else if (_type == "3rdparty") { } else if (_type == "3rdparty") {
QStringList trdPartyList QStringList trdPartyList = QString(TRDPARTY_LICENSE).split(';', Qt::SkipEmptyParts);
= QString(TRDPARTY_LICENSE).split(';', QString::SkipEmptyParts);
for (int i = 0; i < trdPartyList.count(); i++) for (int i = 0; i < trdPartyList.count(); i++)
trdPartyList[i] trdPartyList[i] = QString("<li><a href=\"%3\">%1</a> (%2 license)</li>")
= QString("<li><a href=\"%3\">%1</a> (%2 license)</li>") .arg(trdPartyList.at(i).split(',')[0])
.arg(trdPartyList.at(i).split(',')[0]) .arg(trdPartyList.at(i).split(',')[1])
.arg(trdPartyList.at(i).split(',')[1]) .arg(trdPartyList.at(i).split(',')[2]);
.arg(trdPartyList.at(i).split(',')[2]); text = i18n("This software uses:") + "<ul>" + trdPartyList.join("") + "</ul>";
text = i18n("This software uses:") + "<ul>" + trdPartyList.join("")
+ "</ul>";
} else if (_type == "thanks") { } else if (_type == "thanks") {
QStringList thanks QStringList thanks = QString(SPECIAL_THANKS).split(';', Qt::SkipEmptyParts);
= QString(SPECIAL_THANKS).split(';', QString::SkipEmptyParts);
for (int i = 0; i < thanks.count(); i++) for (int i = 0; i < thanks.count(); i++)
thanks[i] = QString("<li><a href=\"%2\">%1</a></li>") thanks[i] = QString("<li><a href=\"%2\">%1</a></li>")
.arg(thanks.at(i).split(',')[0]) .arg(thanks.at(i).split(',')[0])
@ -117,10 +91,8 @@ QStringList AWDebug::getBuildData()
metadata.append(QString(" AW_GRAPHITEM_API: %1").arg(AW_GRAPHITEM_API)); metadata.append(QString(" AW_GRAPHITEM_API: %1").arg(AW_GRAPHITEM_API));
metadata.append(QString(" AW_EXTQUOTES_API: %1").arg(AW_EXTQUOTES_API)); metadata.append(QString(" AW_EXTQUOTES_API: %1").arg(AW_EXTQUOTES_API));
metadata.append(QString(" AW_EXTSCRIPT_API: %1").arg(AW_EXTSCRIPT_API)); metadata.append(QString(" AW_EXTSCRIPT_API: %1").arg(AW_EXTSCRIPT_API));
metadata.append( metadata.append(QString(" AW_EXTUPGRADE_API: %1").arg(AW_EXTUPGRADE_API));
QString(" AW_EXTUPGRADE_API: %1").arg(AW_EXTUPGRADE_API)); metadata.append(QString(" AW_EXTWEATHER_API: %1").arg(AW_EXTWEATHER_API));
metadata.append(
QString(" AW_EXTWEATHER_API: %1").arg(AW_EXTWEATHER_API));
metadata.append(QString(" AW_FORMATTER_API: %1").arg(AW_FORMATTER_API)); metadata.append(QString(" AW_FORMATTER_API: %1").arg(AW_FORMATTER_API));
metadata.append(QString(" REQUEST_TIMEOUT: %1").arg(REQUEST_TIMEOUT)); metadata.append(QString(" REQUEST_TIMEOUT: %1").arg(REQUEST_TIMEOUT));
metadata.append(QString(" TIME_KEYS: %1").arg(TIME_KEYS)); metadata.append(QString(" TIME_KEYS: %1").arg(TIME_KEYS));
@ -128,41 +100,27 @@ QStringList AWDebug::getBuildData()
// cmake properties // cmake properties
metadata.append("cmake properties:"); metadata.append("cmake properties:");
metadata.append(QString(" CMAKE_BUILD_TYPE: %1").arg(CMAKE_BUILD_TYPE)); metadata.append(QString(" CMAKE_BUILD_TYPE: %1").arg(CMAKE_BUILD_TYPE));
metadata.append( metadata.append(QString(" CMAKE_CXX_COMPILER: %1").arg(CMAKE_CXX_COMPILER));
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: %1").arg(CMAKE_CXX_FLAGS));
metadata.append( metadata.append(QString(" CMAKE_CXX_FLAGS_DEBUG: %1").arg(CMAKE_CXX_FLAGS_DEBUG));
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_RELEASE: %1") metadata.append(QString(" CMAKE_CXX_FLAGS_OPTIMIZATION: %1").arg(CMAKE_CXX_FLAGS_OPTIMIZATION));
.arg(CMAKE_CXX_FLAGS_RELEASE)); metadata.append(QString(" CMAKE_DEFINITIONS: %1").arg(CMAKE_DEFINITIONS));
metadata.append(QString(" CMAKE_CXX_FLAGS_OPTIMIZATION: %1") metadata.append(QString(" CMAKE_INSTALL_PREFIX: %1").arg(CMAKE_INSTALL_PREFIX));
.arg(CMAKE_CXX_FLAGS_OPTIMIZATION)); metadata.append(QString(" CMAKE_MODULE_LINKER_FLAGS: %1").arg(CMAKE_MODULE_LINKER_FLAGS));
metadata.append( metadata.append(QString(" CMAKE_SHARED_LINKER_FLAGS: %1").arg(CMAKE_SHARED_LINKER_FLAGS));
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 // components
metadata.append("Components data:"); metadata.append("Components data:");
metadata.append(QString(" BUILD_PLASMOIDS: %1").arg(BUILD_PLASMOIDS)); metadata.append(QString(" BUILD_PLASMOIDS: %1").arg(BUILD_PLASMOIDS));
metadata.append( metadata.append(QString(" BUILD_DEB_PACKAGE: %1").arg(BUILD_DEB_PACKAGE));
QString(" BUILD_DEB_PACKAGE: %1").arg(BUILD_DEB_PACKAGE)); metadata.append(QString(" BUILD_RPM_PACKAGE: %1").arg(BUILD_RPM_PACKAGE));
metadata.append( metadata.append(QString(" CLANGFORMAT_EXECUTABLE: %1").arg(CLANGFORMAT_EXECUTABLE));
QString(" BUILD_RPM_PACKAGE: %1").arg(BUILD_RPM_PACKAGE));
metadata.append(
QString(" CLANGFORMAT_EXECUTABLE: %1").arg(CLANGFORMAT_EXECUTABLE));
metadata.append(QString(" COVERITY_COMMENT: %1").arg(COVERITY_COMMENT)); metadata.append(QString(" COVERITY_COMMENT: %1").arg(COVERITY_COMMENT));
metadata.append( metadata.append(QString(" COVERITY_DIRECTORY: %1").arg(COVERITY_DIRECTORY));
QString(" COVERITY_DIRECTORY: %1").arg(COVERITY_DIRECTORY));
metadata.append(QString(" COVERITY_EMAIL: %1").arg(COVERITY_EMAIL)); metadata.append(QString(" COVERITY_EMAIL: %1").arg(COVERITY_EMAIL));
metadata.append( metadata.append(QString(" COVERITY_EXECUTABLE: %1").arg(COVERITY_EXECUTABLE));
QString(" COVERITY_EXECUTABLE: %1").arg(COVERITY_EXECUTABLE));
metadata.append(QString(" COVERITY_URL: %1").arg(COVERITY_URL)); metadata.append(QString(" COVERITY_URL: %1").arg(COVERITY_URL));
metadata.append( metadata.append(QString(" CPPCHECK_EXECUTABLE: %1").arg(CPPCHECK_EXECUTABLE));
QString(" CPPCHECK_EXECUTABLE: %1").arg(CPPCHECK_EXECUTABLE));
// additional functions // additional functions
metadata.append(QString(" PROP_FUTURE: %1").arg(PROP_FUTURE)); metadata.append(QString(" PROP_FUTURE: %1").arg(PROP_FUTURE));
metadata.append(QString(" PROP_LOAD: %1").arg(PROP_LOAD)); metadata.append(QString(" PROP_LOAD: %1").arg(PROP_LOAD));

View File

@ -33,7 +33,7 @@ const char LOG_FORMAT[] = "[%{time "
QString getAboutText(const QString &_type); QString getAboutText(const QString &_type);
QStringList getBuildData(); QStringList getBuildData();
} } // namespace AWDebug
Q_DECLARE_LOGGING_CATEGORY(LOG_AW) Q_DECLARE_LOGGING_CATEGORY(LOG_AW)

View File

@ -15,7 +15,6 @@ Icon=utilities-system-monitor
X-KDE-ServiceTypes=Plasma/Applet X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml X-Plasma-MainScript=ui/main.qml
X-Plasma-RemoteLocation=
X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis
X-KDE-PluginInfo-Email=esalexeev@gmail.com X-KDE-PluginInfo-Email=esalexeev@gmail.com
@ -23,6 +22,5 @@ X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget
X-KDE-PluginInfo-Version=@PROJECT_VERSION@ X-KDE-PluginInfo-Version=@PROJECT_VERSION@
X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/ X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/
X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Category=System Information
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPLv3 X-KDE-PluginInfo-License=GPLv3
X-KDE-PluginInfo-EnabledByDefault=true X-KDE-PluginInfo-EnabledByDefault=true

View File

@ -30,6 +30,8 @@ Item {
width: childrenRect.width width: childrenRect.width
height: childrenRect.height height: childrenRect.height
property bool debug: awActions.isDebugEnabled()
AboutTab { AboutTab {
textProvider: awActions textProvider: awActions
} }

View File

@ -72,7 +72,7 @@ Item {
ComboBoxSelector { ComboBoxSelector {
id: fontWeight id: fontWeight
model: general.fontWeightModel model: General.fontWeightModel
text: i18n("Font weight") text: i18n("Font weight")
value: plasmoid.configuration.fontWeight value: plasmoid.configuration.fontWeight
onValueEdited: cfg_fontWeight = newValue onValueEdited: cfg_fontWeight = newValue
@ -80,7 +80,7 @@ Item {
ComboBoxSelector { ComboBoxSelector {
id: fontStyle id: fontStyle
model: general.fontStyleModel model: General.fontStyleModel
text: i18n("Font style") text: i18n("Font style")
value: plasmoid.configuration.fontStyle value: plasmoid.configuration.fontStyle
onValueEdited: cfg_fontStyle = newValue onValueEdited: cfg_fontStyle = newValue
@ -94,7 +94,7 @@ Item {
ComboBoxSelector { ComboBoxSelector {
id: textStyle id: textStyle
model: general.textStyleModel model: General.textStyleModel
text: i18n("Style") text: i18n("Style")
value: plasmoid.configuration.textStyle value: plasmoid.configuration.textStyle
onValueEdited: cfg_textStyle = newValue onValueEdited: cfg_textStyle = newValue

View File

@ -167,8 +167,8 @@ Item {
'name': 'clementine' 'name': 'clementine'
}, },
{ {
'label': 'deadbeef', 'label': 'DeaDBeeF',
'name': 'deadbeef' 'name': 'DeaDBeeF'
}, },
{ {
'label': 'vlc', 'label': 'vlc',

View File

@ -95,16 +95,16 @@ Item {
textFormat: Text.RichText textFormat: Text.RichText
wrapMode: plasmoid.configuration.wrapText ? Text.WordWrap : Text.NoWrap wrapMode: plasmoid.configuration.wrapText ? Text.WordWrap : Text.NoWrap
horizontalAlignment: general.align[plasmoid.configuration.textAlign] horizontalAlignment: General.align[plasmoid.configuration.textAlign]
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
color: plasmoid.configuration.fontColor color: plasmoid.configuration.fontColor
font.family: plasmoid.configuration.fontFamily font.family: plasmoid.configuration.fontFamily
font.italic: plasmoid.configuration.fontStyle == "italic" ? true : false font.italic: plasmoid.configuration.fontStyle == "italic" ? true : false
font.pointSize: plasmoid.configuration.fontSize font.pointSize: plasmoid.configuration.fontSize
font.weight: general.fontWeight[plasmoid.configuration.fontWeight] font.weight: General.fontWeight[plasmoid.configuration.fontWeight]
style: general.textStyle[plasmoid.configuration.textStyle] style: General.textStyle[plasmoid.configuration.textStyle]
styleColor: plasmoid.configuration.textStyleColor styleColor: plasmoid.configuration.textStyleColor
PlasmaCore.ToolTipArea { PlasmaCore.ToolTipArea {

View File

@ -3,7 +3,7 @@
# common QML constants # common QML constants
singleton general 1.0 file:///usr/share/awesomewidgets/qml/general.qml singleton General 1.0 file:///usr/share/awesomewidgets/qml/General.qml
# custom QML UI classes # custom QML UI classes
AboutTab file:///usr/share/awesomewidgets/qml/AboutTab.qml AboutTab file:///usr/share/awesomewidgets/qml/AboutTab.qml

View File

@ -58,7 +58,7 @@ Item {
backend: awKeys backend: awKeys
notifyBackend: awActions notifyBackend: awActions
textArea: textPattern textArea: textPattern
groups: general.awTagRegexp groups: General.awTagRegexp
} }
AWExtensions { AWExtensions {

View File

@ -15,14 +15,12 @@ Icon=utilities-system-monitor
X-KDE-ServiceTypes=Plasma/Applet X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml X-Plasma-MainScript=ui/main.qml
X-Plasma-RemoteLocation=
X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis
X-KDE-PluginInfo-Email=esalexeev@gmail.com X-KDE-PluginInfo-Email=esalexeev@gmail.com
X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget
X-KDE-PluginInfo-Version=3.3.1 X-KDE-PluginInfo-Version=3.5.0
X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/ X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/
X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Category=System Information
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPLv3 X-KDE-PluginInfo-License=GPLv3
X-KDE-PluginInfo-EnabledByDefault=true X-KDE-PluginInfo-EnabledByDefault=true

View File

@ -0,0 +1,181 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awabstractpairconfig.h"
#include "ui_awabstractpairconfig.h"
#include <KI18n/KLocalizedString>
#include <QPushButton>
#include <utility>
#include "awabstractselector.h"
#include "awdebug.h"
AWAbstractPairConfig::AWAbstractPairConfig(QWidget *_parent, const bool _hasEdit, QStringList _keys)
: QDialog(_parent)
, ui(new Ui::AWAbstractPairConfig)
, m_hasEdit(_hasEdit)
, m_keys(std::move(_keys))
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
ui->setupUi(this);
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
// edit feature
if (m_hasEdit) {
m_editButton = ui->buttonBox->addButton(i18n("Edit"), QDialogButtonBox::ActionRole);
connect(m_editButton, SIGNAL(clicked(bool)), this, SLOT(edit()));
}
}
AWAbstractPairConfig::~AWAbstractPairConfig()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
clearSelectors();
delete ui;
}
void AWAbstractPairConfig::showDialog()
{
// update dialog
updateDialog();
// exec dialog
return execDialog();
}
void AWAbstractPairConfig::setEditable(const bool _first, const bool _second)
{
qCDebug(LOG_AW) << "Set editable" << _first << _second;
m_editable = {_first, _second};
}
void AWAbstractPairConfig::edit()
{
m_helper->editPairs();
updateDialog();
}
void AWAbstractPairConfig::updateUi()
{
QPair<QString, QString> current = dynamic_cast<AWAbstractSelector *>(sender())->current();
int index = m_selectors.indexOf(dynamic_cast<AWAbstractSelector *>(sender()));
if ((current.first.isEmpty()) && (current.second.isEmpty())) {
// remove current selector if it is empty and does not last
if (sender() == m_selectors.last())
return;
AWAbstractSelector *selector = m_selectors.takeAt(index);
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
} else {
// add new selector if something changed
if (sender() != m_selectors.last())
return;
auto keys = initKeys();
addSelector(keys.first, keys.second, QPair<QString, QString>());
}
}
void AWAbstractPairConfig::addSelector(const QStringList &_keys, const QStringList &_values,
const QPair<QString, QString> &_current)
{
qCDebug(LOG_AW) << "Add selector with keys" << _keys << "values" << _values << "and current ones" << _current;
auto *selector = new AWAbstractSelector(ui->scrollAreaWidgetContents, m_editable);
selector->init(_keys, _values, _current);
ui->verticalLayout->insertWidget(ui->verticalLayout->count() - 1, selector);
connect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
m_selectors.append(selector);
}
void AWAbstractPairConfig::clearSelectors()
{
for (auto &selector : m_selectors) {
disconnect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
}
m_selectors.clear();
}
void AWAbstractPairConfig::execDialog()
{
int ret = exec();
QHash<QString, QString> data;
for (auto &selector : m_selectors) {
QPair<QString, QString> select = selector->current();
if (select.first.isEmpty())
continue;
data[select.first] = select.second;
}
// save configuration if required
auto status = true;
switch (ret) {
case 0:
break;
case 1:
default:
status &= m_helper->writeItems(data);
status &= m_helper->removeUnusedKeys(data.keys());
break;
}
qCDebug(LOG_AW) << "Configuration save status" << status;
}
QPair<QStringList, QStringList> AWAbstractPairConfig::initKeys() const
{
// we are adding empty string at the start
QStringList left = {""};
left.append(m_helper->leftKeys().isEmpty() ? m_keys : m_helper->leftKeys());
left.sort();
QStringList right = {""};
right.append(m_helper->rightKeys().isEmpty() ? m_keys : m_helper->rightKeys());
right.sort();
return QPair<QStringList, QStringList>(left, right);
}
void AWAbstractPairConfig::updateDialog()
{
clearSelectors();
auto pairs = m_helper->pairs();
auto keys = initKeys();
for (auto &key : m_helper->keys())
addSelector(keys.first, keys.second, QPair<QString, QString>(key, m_helper->pairs()[key]));
// empty one
addSelector(keys.first, keys.second, QPair<QString, QString>());
}

View File

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

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>AWFormatterConfig</class> <class>AWAbstractPairConfig</class>
<widget class="QDialog" name="AWFormatterConfig"> <widget class="QDialog" name="AWAbstractPairConfig">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -60,7 +60,7 @@
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>accepted()</signal> <signal>accepted()</signal>
<receiver>AWFormatterConfig</receiver> <receiver>AWAbstractPairConfig</receiver>
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
@ -76,7 +76,7 @@
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>rejected()</signal> <signal>rejected()</signal>
<receiver>AWFormatterConfig</receiver> <receiver>AWAbstractPairConfig</receiver>
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">

View File

@ -0,0 +1,135 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awabstractpairhelper.h"
#include <QSettings>
#include <QStandardPaths>
#include <utility>
#include "awdebug.h"
AWAbstractPairHelper::AWAbstractPairHelper(QString _filePath, QString _section)
: m_filePath(std::move(_filePath))
, m_section(std::move(_section))
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
AWAbstractPairHelper::initItems();
}
AWAbstractPairHelper::~AWAbstractPairHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QStringList AWAbstractPairHelper::keys() const
{
return m_pairs.keys();
}
QHash<QString, QString> AWAbstractPairHelper::pairs() const
{
return m_pairs;
}
QStringList AWAbstractPairHelper::values() const
{
return m_pairs.values();
}
QSet<QString> AWAbstractPairHelper::valuesSet() const
{
auto values = m_pairs.values();
return {values.cbegin(), values.cend()};
}
void AWAbstractPairHelper::initItems()
{
m_pairs.clear();
QStringList configs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, m_filePath);
for (auto &fileName : configs) {
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup(m_section);
QStringList keys = settings.childKeys();
for (auto &key : keys) {
QString value = settings.value(key).toString();
qCInfo(LOG_AW) << "Found key" << key << "for value" << value << "in" << settings.fileName();
if (value.isEmpty()) {
qCInfo(LOG_AW) << "Skip empty value for" << key;
continue;
}
m_pairs[key] = value;
}
settings.endGroup();
}
}
bool AWAbstractPairHelper::writeItems(const QHash<QString, QString> &_configuration) const
{
qCDebug(LOG_AW) << "Write configuration" << _configuration;
QString fileName
= QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup(m_section);
for (auto &key : _configuration.keys())
settings.setValue(key, _configuration[key]);
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}
bool AWAbstractPairHelper::removeUnusedKeys(const QStringList &_keys) const
{
qCDebug(LOG_AW) << "Remove keys" << _keys;
QString fileName
= QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup(m_section);
QStringList foundKeys = settings.childKeys();
for (auto &key : foundKeys) {
if (_keys.contains(key))
continue;
settings.remove(key);
}
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}

View File

@ -0,0 +1,51 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWABSTRACTPAIRHELPER_H
#define AWABSTRACTPAIRHELPER_H
#include <QHash>
class AWAbstractPairHelper
{
public:
explicit AWAbstractPairHelper(QString _filePath = "", QString _section = "");
virtual ~AWAbstractPairHelper();
[[nodiscard]] QStringList keys() const;
[[nodiscard]] QHash<QString, QString> pairs() const;
[[nodiscard]] QStringList values() const;
[[nodiscard]] QSet<QString> valuesSet() const;
// read-write methods
virtual void initItems();
[[nodiscard]] virtual bool writeItems(const QHash<QString, QString> &_configuration) const;
[[nodiscard]] virtual bool removeUnusedKeys(const QStringList &_keys) const;
// configuration related
virtual void editPairs() = 0;
virtual QStringList leftKeys() = 0;
virtual QStringList rightKeys() = 0;
private:
// properties
QHash<QString, QString> m_pairs;
QString m_filePath;
QString m_section;
};
#endif /* AWABSTRACTPAIRHELPER_H */

View File

@ -21,8 +21,7 @@
#include "awdebug.h" #include "awdebug.h"
AWAbstractSelector::AWAbstractSelector(QWidget *_parent, AWAbstractSelector::AWAbstractSelector(QWidget *_parent, const QPair<bool, bool> &_editable)
const QPair<bool, bool> &_editable)
: QWidget(_parent) : QWidget(_parent)
, ui(new Ui::AWAbstractSelector) , ui(new Ui::AWAbstractSelector)
{ {
@ -32,10 +31,8 @@ AWAbstractSelector::AWAbstractSelector(QWidget *_parent,
ui->comboBox_key->setEditable(_editable.first); ui->comboBox_key->setEditable(_editable.first);
ui->comboBox_value->setEditable(_editable.second); ui->comboBox_value->setEditable(_editable.second);
connect(ui->comboBox_key, SIGNAL(currentIndexChanged(int)), this, connect(ui->comboBox_key, SIGNAL(currentIndexChanged(int)), this, SIGNAL(selectionChanged()));
SIGNAL(selectionChanged())); connect(ui->comboBox_value, SIGNAL(currentIndexChanged(int)), this, SIGNAL(selectionChanged()));
connect(ui->comboBox_value, SIGNAL(currentIndexChanged(int)), this,
SIGNAL(selectionChanged()));
} }
@ -56,18 +53,15 @@ QPair<QString, QString> AWAbstractSelector::current() const
} }
void AWAbstractSelector::init(const QStringList &_keys, void AWAbstractSelector::init(const QStringList &_keys, const QStringList &_values,
const QStringList &_values,
const QPair<QString, QString> &_current) const QPair<QString, QString> &_current)
{ {
if ((!_keys.contains(_current.first)) if ((!_keys.contains(_current.first)) || (!_values.contains(_current.second))) {
|| (!_values.contains(_current.second))) { qCWarning(LOG_AW) << "Invalid current value" << _current << "not found in default ones";
qCWarning(LOG_AW) << "Invalid current value" << _current
<< "not found in default ones";
return; return;
} }
qCDebug(LOG_AW) << "Init selector with keys" << _keys << "and values" qCDebug(LOG_AW) << "Init selector with keys" << _keys << "and values" << _values << "and current ones are"
<< _values << "and current ones are" << _current; << _current;
// set data // set data
ui->comboBox_key->clear(); ui->comboBox_key->clear();

View File

@ -32,13 +32,10 @@ class AWAbstractSelector : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit AWAbstractSelector(QWidget *_parent = nullptr, explicit AWAbstractSelector(QWidget *_parent = nullptr, const QPair<bool, bool> &_editable = {false, false});
const QPair<bool, bool> &_editable ~AWAbstractSelector() override;
= {false, false}); [[nodiscard]] QPair<QString, QString> current() const;
virtual ~AWAbstractSelector(); void init(const QStringList &_keys, const QStringList &_values, const QPair<QString, QString> &_current);
QPair<QString, QString> current() const;
void init(const QStringList &_keys, const QStringList &_values,
const QPair<QString, QString> &_current);
signals: signals:
void selectionChanged(); void selectionChanged();

View File

@ -43,8 +43,6 @@ AWActions::AWActions(QObject *_parent)
AWActions::~AWActions() AWActions::~AWActions()
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
delete m_updateHelper;
} }
@ -57,14 +55,13 @@ void AWActions::checkUpdates(const bool _showAnyway)
} }
QString AWActions::getFileContent(const QString &_path) const QString AWActions::getFileContent(const QString &_path)
{ {
qCDebug(LOG_AW) << "Get content from file" << _path; qCDebug(LOG_AW) << "Get content from file" << _path;
QFile inputFile(_path); QFile inputFile(_path);
if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(LOG_AW) << "Could not open file as text" qCWarning(LOG_AW) << "Could not open file as text" << inputFile.fileName();
<< inputFile.fileName();
return ""; return "";
} }
@ -75,37 +72,36 @@ QString AWActions::getFileContent(const QString &_path) const
// HACK: since QML could not use QLoggingCategory I need this hack // HACK: since QML could not use QLoggingCategory I need this hack
bool AWActions::isDebugEnabled() const bool AWActions::isDebugEnabled()
{ {
return LOG_AW().isDebugEnabled(); return LOG_AW().isDebugEnabled();
} }
bool AWActions::runCmd(const QString &_cmd) const bool AWActions::runCmd(const QString &_cmd, const QStringList &_args)
{ {
qCDebug(LOG_AW) << "Cmd" << _cmd; qCDebug(LOG_AW) << "Cmd" << _cmd << "args" << _args;
sendNotification(QString("Info"), i18n("Run %1", _cmd)); sendNotification(QString("Info"), i18n("Run %1", _cmd));
return QProcess::startDetached(_cmd); return QProcess::startDetached(_cmd, _args);
} }
// HACK: this method uses variable from version.h // HACK: this method uses variable from version.h
void AWActions::showReadme() const void AWActions::showReadme()
{ {
QDesktopServices::openUrl(QUrl(HOMEPAGE)); QDesktopServices::openUrl(QUrl(HOMEPAGE));
} }
void AWActions::showLegacyInfo() const void AWActions::showLegacyInfo()
{ {
QMessageBox *msgBox = new QMessageBox(nullptr); auto *msgBox = new QMessageBox(nullptr);
msgBox->setAttribute(Qt::WA_DeleteOnClose); msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setModal(false); msgBox->setModal(false);
msgBox->setWindowTitle(i18n("Not supported")); msgBox->setWindowTitle(i18n("Not supported"));
msgBox->setText( msgBox->setText(i18n("You are using mammoth's Qt version, try to update it first"));
i18n("You are using mammoth's Qt version, try to update it first"));
msgBox->setStandardButtons(QMessageBox::Ok); msgBox->setStandardButtons(QMessageBox::Ok);
msgBox->setIcon(QMessageBox::Information); msgBox->setIcon(QMessageBox::Information);
@ -114,7 +110,7 @@ void AWActions::showLegacyInfo() const
// HACK: this method uses variables from version.h // HACK: this method uses variables from version.h
QString AWActions::getAboutText(const QString &_type) const QString AWActions::getAboutText(const QString &_type)
{ {
qCDebug(LOG_AW) << "Type" << _type; qCDebug(LOG_AW) << "Type" << _type;
@ -122,17 +118,15 @@ QString AWActions::getAboutText(const QString &_type) const
} }
QVariantMap AWActions::getFont(const QVariantMap &_defaultFont) const QVariantMap AWActions::getFont(const QVariantMap &_defaultFont)
{ {
qCDebug(LOG_AW) << "Default font is" << _defaultFont; qCDebug(LOG_AW) << "Default font is" << _defaultFont;
QVariantMap fontMap; QVariantMap fontMap;
int ret = 0; int ret = 0;
CFont defaultCFont CFont defaultCFont = CFont(_defaultFont["family"].toString(), _defaultFont["size"].toInt(), 400, false,
= CFont(_defaultFont["family"].toString(), _defaultFont["size"].toInt(), _defaultFont["color"].toString());
400, false, _defaultFont["color"].toString()); CFont font = CFontDialog::getFont(i18n("Select font"), defaultCFont, false, false, &ret);
CFont font = CFontDialog::getFont(i18n("Select font"), defaultCFont, false,
false, &ret);
fontMap["applied"] = ret; fontMap["applied"] = ret;
fontMap["color"] = font.color().name(); fontMap["color"] = font.color().name();
@ -144,13 +138,11 @@ QVariantMap AWActions::getFont(const QVariantMap &_defaultFont) const
// to avoid additional object definition this method is static // to avoid additional object definition this method is static
void AWActions::sendNotification(const QString &_eventId, void AWActions::sendNotification(const QString &_eventId, const QString &_message)
const QString &_message)
{ {
qCDebug(LOG_AW) << "Event" << _eventId << "with message" << _message; qCDebug(LOG_AW) << "Event" << _eventId << "with message" << _message;
KNotification *notification = KNotification::event( KNotification *notification
_eventId, QString("Awesome Widget ::: %1").arg(_eventId), _message); = KNotification::event(_eventId, QString("Awesome Widget ::: %1").arg(_eventId), _message);
notification->setComponentName( notification->setComponentName("plasma-applet-org.kde.plasma.awesome-widget");
"plasma-applet-org.kde.plasma.awesome-widget");
} }

View File

@ -31,20 +31,19 @@ class AWActions : public QObject
public: public:
explicit AWActions(QObject *_parent = nullptr); explicit AWActions(QObject *_parent = nullptr);
virtual ~AWActions(); ~AWActions() override;
Q_INVOKABLE void checkUpdates(const bool _showAnyway = false); Q_INVOKABLE void checkUpdates(bool _showAnyway = false);
Q_INVOKABLE QString getFileContent(const QString &_path) const; Q_INVOKABLE static QString getFileContent(const QString &_path);
Q_INVOKABLE bool isDebugEnabled() const; Q_INVOKABLE static bool isDebugEnabled();
Q_INVOKABLE bool runCmd(const QString &_cmd) const; Q_INVOKABLE static bool runCmd(const QString &_cmd, const QStringList &_args);
Q_INVOKABLE void showLegacyInfo() const; Q_INVOKABLE static void showLegacyInfo();
Q_INVOKABLE void showReadme() const; Q_INVOKABLE static void showReadme();
// configuration slots // configuration slots
Q_INVOKABLE QString getAboutText(const QString &_type) const; Q_INVOKABLE static QString getAboutText(const QString &_type);
Q_INVOKABLE QVariantMap getFont(const QVariantMap &_defaultFont) const; Q_INVOKABLE static QVariantMap getFont(const QVariantMap &_defaultFont);
public slots: public slots:
Q_INVOKABLE static void sendNotification(const QString &_eventId, Q_INVOKABLE static void sendNotification(const QString &_eventId, const QString &_message);
const QString &_message);
private: private:
AWUpdateHelper *m_updateHelper = nullptr; AWUpdateHelper *m_updateHelper = nullptr;

View File

@ -21,11 +21,9 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonParseError>
#include <QMessageBox> #include <QMessageBox>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QNetworkRequest>
#include "awdebug.h" #include "awdebug.h"
@ -46,27 +44,22 @@ AWBugReporter::~AWBugReporter()
void AWBugReporter::doConnect() void AWBugReporter::doConnect()
{ {
// additional method for testing needs // additional method for testing needs
connect(this, SIGNAL(replyReceived(const int, const QString &)), this, connect(this, SIGNAL(replyReceived(const int, const QString &)), this, SLOT(showInformation(int, const QString &)));
SLOT(showInformation(const int, const QString &)));
} }
QString AWBugReporter::generateText(const QString &_description, QString AWBugReporter::generateText(const QString &_description, const QString &_reproduce, const QString &_expected,
const QString &_reproduce, const QString &_logs)
const QString &_expected,
const QString &_logs) const
{ {
// do not log _logs here, it may have quite large size // do not log _logs here, it may have quite large size
qCDebug(LOG_AW) << "Generate text with description" << _description qCDebug(LOG_AW) << "Generate text with description" << _description << "steps" << _reproduce
<< "steps" << _reproduce << "and expected result" << "and expected result" << _expected;
<< _expected;
QString output; QString output;
output += QString("**Description**\n\n%1\n\n").arg(_description); output += QString("**Description**\n\n%1\n\n").arg(_description);
output += QString("**Step to _reproduce**\n\n%1\n\n").arg(_reproduce); output += QString("**Step to _reproduce**\n\n%1\n\n").arg(_reproduce);
output += QString("**Expected result**\n\n%1\n\n").arg(_expected); output += QString("**Expected result**\n\n%1\n\n").arg(_expected);
output += QString("**Version**\n\n%1\n\n") output += QString("**Version**\n\n%1\n\n").arg(AWDebug::getBuildData().join(QString("\n")));
.arg(AWDebug::getBuildData().join(QString("\n")));
// append _logs // append _logs
output += QString("**Logs**\n\n%1").arg(_logs); output += QString("**Logs**\n\n%1").arg(_logs);
@ -76,12 +69,10 @@ QString AWBugReporter::generateText(const QString &_description,
void AWBugReporter::sendBugReport(const QString &_title, const QString &_body) void AWBugReporter::sendBugReport(const QString &_title, const QString &_body)
{ {
qCDebug(LOG_AW) << "Send bug report with title" << _title << "and body" qCDebug(LOG_AW) << "Send bug report with title" << _title << "and body" << _body;
<< _body;
QNetworkAccessManager *manager = new QNetworkAccessManager(nullptr); auto *manager = new QNetworkAccessManager(nullptr);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(issueReplyRecieved(QNetworkReply *)));
SLOT(issueReplyRecieved(QNetworkReply *)));
QNetworkRequest request = QNetworkRequest(QUrl(BUGTRACKER_API)); QNetworkRequest request = QNetworkRequest(QUrl(BUGTRACKER_API));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
@ -92,10 +83,8 @@ void AWBugReporter::sendBugReport(const QString &_title, const QString &_body)
payload["body"] = _body; payload["body"] = _body;
payload["labels"] = QStringList() << "from application"; payload["labels"] = QStringList() << "from application";
// convert to QByteArray to send request // convert to QByteArray to send request
QByteArray data QByteArray data = QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact);
= QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact); qCInfo(LOG_AW) << "Send request with _body" << data.data() << "and size" << data.size();
qCInfo(LOG_AW) << "Send request with _body" << data.data() << "and size"
<< data.size();
manager->post(request, data); manager->post(request, data);
} }
@ -104,12 +93,11 @@ void AWBugReporter::sendBugReport(const QString &_title, const QString &_body)
void AWBugReporter::issueReplyRecieved(QNetworkReply *_reply) void AWBugReporter::issueReplyRecieved(QNetworkReply *_reply)
{ {
if (_reply->error() != QNetworkReply::NoError) { if (_reply->error() != QNetworkReply::NoError) {
qCWarning(LOG_AW) << "An error occurs" << _reply->error() qCWarning(LOG_AW) << "An error occurs" << _reply->error() << "with message" << _reply->errorString();
<< "with message" << _reply->errorString();
return emit(replyReceived(0, "")); return emit(replyReceived(0, ""));
} }
QJsonParseError error; QJsonParseError error{};
QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error); QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) { if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_AW) << "Parse error" << error.errorString(); qCWarning(LOG_AW) << "Parse error" << error.errorString();
@ -128,13 +116,12 @@ void AWBugReporter::issueReplyRecieved(QNetworkReply *_reply)
void AWBugReporter::showInformation(const int _number, const QString &_url) void AWBugReporter::showInformation(const int _number, const QString &_url)
{ {
qCDebug(LOG_AW) << "Created issue with number" << _number << "and url" qCDebug(LOG_AW) << "Created issue with number" << _number << "and url" << _url;
<< _url;
// cache url first // cache url first
m_lastBugUrl = _url; m_lastBugUrl = _url;
QMessageBox *msgBox = new QMessageBox(nullptr); auto *msgBox = new QMessageBox(nullptr);
msgBox->setAttribute(Qt::WA_DeleteOnClose); msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setModal(false); msgBox->setModal(false);
msgBox->setWindowTitle(i18n("Issue created")); msgBox->setWindowTitle(i18n("Issue created"));
@ -148,8 +135,7 @@ void AWBugReporter::showInformation(const int _number, const QString &_url)
void AWBugReporter::userReplyOnBugReport(QAbstractButton *_button) void AWBugReporter::userReplyOnBugReport(QAbstractButton *_button)
{ {
QMessageBox::ButtonRole ret QMessageBox::ButtonRole ret = dynamic_cast<QMessageBox *>(sender())->buttonRole(_button);
= static_cast<QMessageBox *>(sender())->buttonRole(_button);
qCInfo(LOG_AW) << "User select" << ret; qCInfo(LOG_AW) << "User select" << ret;
switch (ret) { switch (ret) {

View File

@ -31,20 +31,18 @@ class AWBugReporter : public QObject
public: public:
explicit AWBugReporter(QObject *_parent = nullptr); explicit AWBugReporter(QObject *_parent = nullptr);
virtual ~AWBugReporter(); ~AWBugReporter() override;
Q_INVOKABLE void doConnect(); Q_INVOKABLE void doConnect();
Q_INVOKABLE QString generateText(const QString &_description, Q_INVOKABLE static QString generateText(const QString &_description, const QString &_reproduce,
const QString &_reproduce, const QString &_expected, const QString &_logs);
const QString &_expected,
const QString &_logs) const;
Q_INVOKABLE void sendBugReport(const QString &_title, const QString &_body); Q_INVOKABLE void sendBugReport(const QString &_title, const QString &_body);
signals: signals:
void replyReceived(const int _number, const QString &_url); void replyReceived(int _number, const QString &_url);
private slots: private slots:
void issueReplyRecieved(QNetworkReply *_reply); void issueReplyRecieved(QNetworkReply *_reply);
void showInformation(const int _number, const QString &_url); void showInformation(int _number, const QString &_url);
void userReplyOnBugReport(QAbstractButton *_button); void userReplyOnBugReport(QAbstractButton *_button);
private: private:

View File

@ -17,11 +17,10 @@
#include "awconfighelper.h" #include "awconfighelper.h"
#include <KI18n/KLocalizedString>
#include <QDir> #include <QDir>
#include <QQmlPropertyMap> #include <QQmlPropertyMap>
#include <QSettings> #include <QSettings>
#include <QStandardPaths>
#include <QTextCodec> #include <QTextCodec>
#include "awdebug.h" #include "awdebug.h"
@ -31,6 +30,8 @@ AWConfigHelper::AWConfigHelper(QObject *_parent)
: QObject(_parent) : QObject(_parent)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_baseDir = QString("%1/awesomewidgets").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
} }
@ -40,17 +41,15 @@ AWConfigHelper::~AWConfigHelper()
} }
QString AWConfigHelper::configurationDirectory() const QString AWConfigHelper::configurationDirectory()
{ {
// get readable directory // get readable directory
QString localDir = QString("%1/awesomewidgets/configs") QString localDir = QString("%1/awesomewidgets/configs")
.arg(QStandardPaths::writableLocation( .arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
QStandardPaths::GenericDataLocation));
// create directory and copy files from default settings // create directory and copy files from default settings
QDir localDirectory; QDir localDirectory;
if ((!localDirectory.exists(localDir)) if ((!localDirectory.exists(localDir)) && (localDirectory.mkpath(localDir))) {
&& (localDirectory.mkpath(localDir))) {
qCInfo(LOG_AW) << "Created directory" << localDir; qCInfo(LOG_AW) << "Created directory" << localDir;
copyConfigs(localDir); copyConfigs(localDir);
} }
@ -59,25 +58,22 @@ QString AWConfigHelper::configurationDirectory() const
} }
bool AWConfigHelper::dropCache() const bool AWConfigHelper::dropCache()
{ {
QString fileName = QString("%1/awesomewidgets.ndx") QString fileName
.arg(QStandardPaths::writableLocation( = QString("%1/awesomewidgets.ndx").arg(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
QStandardPaths::GenericCacheLocation));
return QFile(fileName).remove(); return QFile(fileName).remove();
} }
bool AWConfigHelper::exportConfiguration(QObject *_nativeConfig, bool AWConfigHelper::exportConfiguration(QObject *_nativeConfig, const QString &_fileName) const
const QString &_fileName) const
{ {
qCDebug(LOG_AW) << "Selected filename" << _fileName; qCDebug(LOG_AW) << "Selected filename" << _fileName;
QSettings settings(_fileName, QSettings::IniFormat); QSettings settings(_fileName, QSettings::IniFormat);
// plasmoid configuration // plasmoid configuration
const QQmlPropertyMap *configuration const auto *configuration = dynamic_cast<const QQmlPropertyMap *>(_nativeConfig);
= static_cast<const QQmlPropertyMap *>(_nativeConfig);
settings.beginGroup("plasmoid"); settings.beginGroup("plasmoid");
for (auto &key : configuration->keys()) { for (auto &key : configuration->keys()) {
QVariant value = configuration->value(key); QVariant value = configuration->value(key);
@ -90,8 +86,7 @@ bool AWConfigHelper::exportConfiguration(QObject *_nativeConfig,
// extensions // extensions
for (auto &item : m_dirs) { for (auto &item : m_dirs) {
QStringList items QStringList items
= QDir(QString("%1/%2").arg(m_baseDir).arg(item)) = QDir(QString("%1/%2").arg(m_baseDir).arg(item)).entryList(QStringList() << "*.desktop", QDir::Files);
.entryList(QStringList() << "*.desktop", QDir::Files);
settings.beginGroup(item); settings.beginGroup(item);
for (auto &it : items) for (auto &it : items)
copyExtensions(it, item, settings, false); copyExtensions(it, item, settings, false);
@ -101,16 +96,16 @@ bool AWConfigHelper::exportConfiguration(QObject *_nativeConfig,
// additional files // additional files
settings.beginGroup("json"); settings.beginGroup("json");
// script filters // script filters
readFile(settings, "filters", readFile(settings, "filters", QString("%1/scripts/awesomewidgets-extscripts-filters.json").arg(m_baseDir));
QString("%1/scripts/awesomewidgets-extscripts-filters.json")
.arg(m_baseDir));
// weather icon settings // weather icon settings
readFile(settings, "weathers", readFile(settings, "weathers", QString("%1/weather/awesomewidgets-extweather-ids.json").arg(m_baseDir));
QString("%1/weather/awesomewidgets-extweather-ids.json") settings.endGroup();
.arg(m_baseDir));
settings.beginGroup("ini");
// formatter settings // formatter settings
readFile(settings, "formatters", readFile(settings, "formatters", QString("%1/formatters/formatters.ini").arg(m_baseDir));
QString("%1/formatters/formatters.ini").arg(m_baseDir)); // custom keys settings
readFile(settings, "custom", QString("%1/custom.ini").arg(m_baseDir));
settings.endGroup(); settings.endGroup();
// sync settings // sync settings
@ -120,10 +115,8 @@ bool AWConfigHelper::exportConfiguration(QObject *_nativeConfig,
} }
QVariantMap AWConfigHelper::importConfiguration(const QString &_fileName, QVariantMap AWConfigHelper::importConfiguration(const QString &_fileName, const bool _importPlasmoid,
const bool _importPlasmoid, const bool _importExtensions, const bool _importAdds) const
const bool _importExtensions,
const bool _importAdds) const
{ {
qCDebug(LOG_AW) << "Selected filename" << _fileName; qCDebug(LOG_AW) << "Selected filename" << _fileName;
@ -144,16 +137,16 @@ QVariantMap AWConfigHelper::importConfiguration(const QString &_fileName,
if (_importAdds) { if (_importAdds) {
settings.beginGroup("json"); settings.beginGroup("json");
// script filters // script filters
writeFile(settings, "filters", writeFile(settings, "filters", QString("%1/scripts/awesomewidgets-extscripts-filters.json").arg(m_baseDir));
QString("%1/scripts/awesomewidgets-extscripts-filters.json")
.arg(m_baseDir));
// weather icon settings // weather icon settings
writeFile(settings, "weathers", writeFile(settings, "weathers", QString("%1/weather/awesomewidgets-extweather-ids.json").arg(m_baseDir));
QString("%1/weather/awesomewidgets-extweather-ids.json") settings.endGroup();
.arg(m_baseDir));
settings.beginGroup("ini");
// formatter settings // formatter settings
writeFile(settings, "formatters", writeFile(settings, "formatters", QString("%1/formatters/formatters.ini").arg(m_baseDir));
QString("%1/formatters/formatters.ini").arg(m_baseDir)); // custom keys settings
writeFile(settings, "custom", QString("%1/custom.ini").arg(m_baseDir));
settings.endGroup(); settings.endGroup();
} }
@ -169,21 +162,18 @@ QVariantMap AWConfigHelper::importConfiguration(const QString &_fileName,
} }
QVariantMap AWConfigHelper::readDataEngineConfiguration() const QVariantMap AWConfigHelper::readDataEngineConfiguration()
{ {
QString fileName = QStandardPaths::locate( QString fileName = QStandardPaths::locate(QStandardPaths::ConfigLocation, "plasma-dataengine-extsysmon.conf");
QStandardPaths::ConfigLocation, "plasma-dataengine-extsysmon.conf");
qCInfo(LOG_AW) << "Configuration file" << fileName; qCInfo(LOG_AW) << "Configuration file" << fileName;
QSettings settings(fileName, QSettings::IniFormat); QSettings settings(fileName, QSettings::IniFormat);
QVariantMap configuration; QVariantMap configuration;
settings.beginGroup("Configuration"); settings.beginGroup("Configuration");
configuration["ACPIPATH"] configuration["ACPIPATH"] = settings.value("ACPIPATH", "/sys/class/power_supply/");
= settings.value("ACPIPATH", "/sys/class/power_supply/");
configuration["GPUDEV"] = settings.value("GPUDEV", "auto"); configuration["GPUDEV"] = settings.value("GPUDEV", "auto");
configuration["HDDDEV"] = settings.value("HDDDEV", "all"); configuration["HDDDEV"] = settings.value("HDDDEV", "all");
configuration["HDDTEMPCMD"] configuration["HDDTEMPCMD"] = settings.value("HDDTEMPCMD", "sudo smartctl -a");
= settings.value("HDDTEMPCMD", "sudo smartctl -a");
configuration["MPDADDRESS"] = settings.value("MPDADDRESS", "localhost"); configuration["MPDADDRESS"] = settings.value("MPDADDRESS", "localhost");
configuration["MPDPORT"] = settings.value("MPDPORT", "6600"); configuration["MPDPORT"] = settings.value("MPDPORT", "6600");
configuration["MPRIS"] = settings.value("MPRIS", "auto"); configuration["MPRIS"] = settings.value("MPRIS", "auto");
@ -197,14 +187,12 @@ QVariantMap AWConfigHelper::readDataEngineConfiguration() const
} }
bool AWConfigHelper::writeDataEngineConfiguration( bool AWConfigHelper::writeDataEngineConfiguration(const QVariantMap &_configuration)
const QVariantMap &_configuration) const
{ {
qCDebug(LOG_AW) << "Configuration" << _configuration; qCDebug(LOG_AW) << "Configuration" << _configuration;
QString fileName = QString("%1/plasma-dataengine-extsysmon.conf") QString fileName = QString("%1/plasma-dataengine-extsysmon.conf")
.arg(QStandardPaths::writableLocation( .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
QStandardPaths::ConfigLocation));
QSettings settings(fileName, QSettings::IniFormat); QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName(); qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
@ -226,39 +214,32 @@ bool AWConfigHelper::writeDataEngineConfiguration(
} }
void AWConfigHelper::copyConfigs(const QString &_localDir) const void AWConfigHelper::copyConfigs(const QString &_localDir)
{ {
qCDebug(LOG_AW) << "Local directory" << _localDir; qCDebug(LOG_AW) << "Local directory" << _localDir;
QStringList dirs = QStandardPaths::locateAll( QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "awesomewidgets/configs",
QStandardPaths::GenericDataLocation, "awesomewidgets/configs", QStandardPaths::LocateDirectory);
QStandardPaths::LocateDirectory);
for (auto &dir : dirs) { for (auto &dir : dirs) {
if (dir == _localDir) if (dir == _localDir)
continue; continue;
QStringList files = QDir(dir).entryList(QDir::Files); QStringList files = QDir(dir).entryList(QDir::Files);
for (auto &source : files) { for (auto &source : files) {
QString destination = QString("%1/%2").arg(_localDir).arg(source); QString destination = QString("%1/%2").arg(_localDir).arg(source);
bool status = QFile::copy(QString("%1/%2").arg(dir).arg(source), bool status = QFile::copy(QString("%1/%2").arg(dir).arg(source), destination);
destination); qCInfo(LOG_AW) << "File" << source << "has been copied to" << destination << "with status" << status;
qCInfo(LOG_AW) << "File" << source << "has been copied to"
<< destination << "with status" << status;
} }
} }
} }
void AWConfigHelper::copyExtensions(const QString &_item, const QString &_type, void AWConfigHelper::copyExtensions(const QString &_item, const QString &_type, QSettings &_settings,
QSettings &_settings,
const bool _inverse) const const bool _inverse) const
{ {
qCDebug(LOG_AW) << "Extension" << _item << "has type" << _type qCDebug(LOG_AW) << "Extension" << _item << "has type" << _type << "inverse copying" << _inverse;
<< "inverse copying" << _inverse;
_settings.beginGroup(_item); _settings.beginGroup(_item);
QSettings itemSettings( QSettings itemSettings(QString("%1/%2/%3").arg(m_baseDir).arg(_type).arg(_item), QSettings::IniFormat);
QString("%1/%2/%3").arg(m_baseDir).arg(_type).arg(_item),
QSettings::IniFormat);
itemSettings.beginGroup("Desktop Entry"); itemSettings.beginGroup("Desktop Entry");
if (_inverse) if (_inverse)
copySettings(_settings, itemSettings); copySettings(_settings, itemSettings);
@ -272,15 +253,14 @@ void AWConfigHelper::copyExtensions(const QString &_item, const QString &_type,
} }
void AWConfigHelper::copySettings(QSettings &_from, QSettings &_to) const void AWConfigHelper::copySettings(QSettings &_from, QSettings &_to)
{ {
for (auto &key : _from.childKeys()) for (auto &key : _from.childKeys())
_to.setValue(key, _from.value(key)); _to.setValue(key, _from.value(key));
} }
void AWConfigHelper::readFile(QSettings &_settings, const QString &_key, void AWConfigHelper::readFile(QSettings &_settings, const QString &_key, const QString &_fileName)
const QString &_fileName) const
{ {
qCDebug(LOG_AW) << "Key" << _key << "from file" << _fileName; qCDebug(LOG_AW) << "Key" << _key << "from file" << _fileName;
@ -290,13 +270,12 @@ void AWConfigHelper::readFile(QSettings &_settings, const QString &_key,
file.close(); file.close();
_settings.setValue(_key, text); _settings.setValue(_key, text);
} else { } else {
qCWarning(LOG_AW) << "Could not open" << file.fileName(); qCWarning(LOG_AW) << "Could not open to read" << file.fileName();
} }
} }
void AWConfigHelper::writeFile(QSettings &_settings, const QString &_key, void AWConfigHelper::writeFile(QSettings &_settings, const QString &_key, const QString &_fileName)
const QString &_fileName) const
{ {
qCDebug(LOG_AW) << "Key" << _key << "to file" << _fileName; qCDebug(LOG_AW) << "Key" << _key << "to file" << _fileName;
@ -311,6 +290,6 @@ void AWConfigHelper::writeFile(QSettings &_settings, const QString &_key,
out.flush(); out.flush();
file.close(); file.close();
} else { } else {
qCWarning(LOG_AW) << "Could not open" << file.fileName(); qCWarning(LOG_AW) << "Could not open to write" << file.fileName();
} }
} }

View File

@ -20,7 +20,6 @@
#define AWCONFIGHELPER_H #define AWCONFIGHELPER_H
#include <QObject> #include <QObject>
#include <QStandardPaths>
#include <QVariant> #include <QVariant>
@ -32,40 +31,26 @@ class AWConfigHelper : public QObject
public: public:
explicit AWConfigHelper(QObject *_parent = nullptr); explicit AWConfigHelper(QObject *_parent = nullptr);
virtual ~AWConfigHelper(); ~AWConfigHelper() override;
Q_INVOKABLE QString configurationDirectory() const; Q_INVOKABLE [[nodiscard]] static QString configurationDirectory();
Q_INVOKABLE bool dropCache() const; Q_INVOKABLE static bool dropCache();
Q_INVOKABLE bool exportConfiguration(QObject *_nativeConfig, Q_INVOKABLE bool exportConfiguration(QObject *_nativeConfig, const QString &_fileName) const;
const QString &_fileName) const; Q_INVOKABLE [[nodiscard]] QVariantMap importConfiguration(const QString &_fileName, bool _importPlasmoid,
Q_INVOKABLE QVariantMap importConfiguration(const QString &_fileName, bool _importExtensions, bool _importAdds) const;
const bool _importPlasmoid,
const bool _importExtensions,
const bool _importAdds) const;
// dataengine // dataengine
Q_INVOKABLE QVariantMap readDataEngineConfiguration() const; Q_INVOKABLE static QVariantMap readDataEngineConfiguration();
Q_INVOKABLE bool Q_INVOKABLE static bool writeDataEngineConfiguration(const QVariantMap &_configuration);
writeDataEngineConfiguration(const QVariantMap &_configuration) const;
private: private:
// methods // methods
void copyConfigs(const QString &_localDir) const; static void copyConfigs(const QString &_localDir);
void copyExtensions(const QString &_item, const QString &_type, void copyExtensions(const QString &_item, const QString &_type, QSettings &_settings, bool _inverse) const;
QSettings &_settings, const bool _inverse) const; static void copySettings(QSettings &_from, QSettings &_to);
void copySettings(QSettings &_from, QSettings &_to) const; static void readFile(QSettings &_settings, const QString &_key, const QString &_fileName);
void readFile(QSettings &_settings, const QString &_key, static void writeFile(QSettings &_settings, const QString &_key, const QString &_fileName);
const QString &_fileName) const;
void writeFile(QSettings &_settings, const QString &_key,
const QString &_fileName) const;
// properties // properties
QString m_baseDir = QString("%1/awesomewidgets") QString m_baseDir;
.arg(QStandardPaths::writableLocation( QStringList m_dirs = {"desktops", "quotes", "scripts", "upgrade", "weather", "formatters"};
QStandardPaths::GenericDataLocation));
QStringList m_dirs = QStringList() << "desktops"
<< "quotes"
<< "scripts"
<< "upgrade"
<< "weather"
<< "formatters";
}; };

View File

@ -15,28 +15,23 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/ ***************************************************************************/
#include "awformatterconfigfactory.h" #include "awcustomkeysconfig.h"
#include "awcustomkeyshelper.h"
#include "awdebug.h" #include "awdebug.h"
#include "awformatterconfig.h"
AWFormatterConfigFactory::AWFormatterConfigFactory(QObject *_parent) AWCustomKeysConfig::AWCustomKeysConfig(QWidget *_parent, const QStringList &_keys)
: QObject(_parent) : AWAbstractPairConfig(_parent, false, _keys)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
setEditable(true, false);
initHelper<AWCustomKeysHelper>();
}
AWCustomKeysConfig::~AWCustomKeysConfig()
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
} }
AWFormatterConfigFactory::~AWFormatterConfigFactory()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWFormatterConfigFactory::showDialog(const QStringList &_keys)
{
AWFormatterConfig *config = new AWFormatterConfig(nullptr, _keys);
config->showDialog();
config->deleteLater();
}

View File

@ -16,23 +16,20 @@
***************************************************************************/ ***************************************************************************/
#ifndef AWFORMATTERCONFIGFACTORY_H #ifndef AWCUSTOMKEYSCONFIG_H
#define AWFORMATTERCONFIGFACTORY_H #define AWCUSTOMKEYSCONFIG_H
#include <QObject> #include "awabstractpairconfig.h"
class AWFormatterConfigFactory : public QObject class AWCustomKeysConfig : public AWAbstractPairConfig
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit AWFormatterConfigFactory(QObject *_parent = nullptr); explicit AWCustomKeysConfig(QWidget *_parent = nullptr, const QStringList &_keys = QStringList());
virtual ~AWFormatterConfigFactory(); ~AWCustomKeysConfig() override;
Q_INVOKABLE void showDialog(const QStringList &_keys);
private:
}; };
#endif /* AWFORMATTERCONFIGFACTORY_H */ #endif /* AWCUSTOMKEYSCONFIG_H */

View File

@ -0,0 +1,78 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awcustomkeyshelper.h"
#include <QSet>
#include "awdebug.h"
AWCustomKeysHelper::AWCustomKeysHelper(QObject *_parent)
: QObject(_parent)
, AWAbstractPairHelper("awesomewidgets/custom.ini", "Custom")
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWCustomKeysHelper::~AWCustomKeysHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QString AWCustomKeysHelper::source(const QString &_key) const
{
qCDebug(LOG_AW) << "Get source by key" << _key;
return pairs()[_key];
}
QStringList AWCustomKeysHelper::sources() const
{
return valuesSet().values();
}
QStringList AWCustomKeysHelper::refinedSources() const
{
auto allSources = valuesSet();
QSet<QString> output;
while (output != allSources) {
output.clear();
for (auto &src : allSources)
output.insert(pairs().contains(src) ? source(src) : src);
allSources = output;
}
return output.values();
}
QStringList AWCustomKeysHelper::leftKeys()
{
return keys();
}
QStringList AWCustomKeysHelper::rightKeys()
{
return {};
}

View File

@ -0,0 +1,47 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWCUSTOMKEYSHELPER_H
#define AWCUSTOMKEYSHELPER_H
#include <QObject>
#include "awabstractpairhelper.h"
class AWCustomKeysHelper : public QObject, public AWAbstractPairHelper
{
Q_OBJECT
public:
explicit AWCustomKeysHelper(QObject *_parent = nullptr);
~AWCustomKeysHelper() override;
// get
[[nodiscard]] QString source(const QString &_key) const;
[[nodiscard]] QStringList sources() const;
[[nodiscard]] QStringList refinedSources() const;
// configuration related
void editPairs() override{};
QStringList leftKeys() override;
QStringList rightKeys() override;
private:
};
#endif /* AWCUSTOMKEYSHELPER_H */

View File

@ -22,7 +22,6 @@
#include <QBuffer> #include <QBuffer>
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QGraphicsView> #include <QGraphicsView>
#include <QPixmap>
#include <cmath> #include <cmath>
@ -44,8 +43,6 @@ AWDataAggregator::AWDataAggregator(QObject *_parent)
m_boundaries["batTooltip"] = 100.0; m_boundaries["batTooltip"] = 100.0;
initScene(); initScene();
connect(this, SIGNAL(updateData(const QVariantHash &)), this,
SLOT(dataUpdate(const QVariantHash &)));
} }
@ -57,24 +54,14 @@ AWDataAggregator::~AWDataAggregator()
} }
QList<float> AWDataAggregator::getData(const QString &_key) const QString AWDataAggregator::htmlImage(const QPixmap &_source)
{
qCDebug(LOG_AW) << "Key" << _key;
return m_values[QString("%1Tooltip").arg(_key)];
}
QString AWDataAggregator::htmlImage(const QPixmap &_source) const
{ {
QByteArray byteArray; QByteArray byteArray;
QBuffer buffer(&byteArray); QBuffer buffer(&byteArray);
_source.save(&buffer, "PNG"); _source.save(&buffer, "PNG");
return byteArray.isEmpty() return byteArray.isEmpty() ? ""
? "" : QString("<img src=\"data:image/png;base64,%1\"/>").arg(QString(byteArray.toBase64()));
: QString("<img src=\"data:image/png;base64,%1\"/>")
.arg(QString(byteArray.toBase64()));
} }
@ -114,10 +101,9 @@ void AWDataAggregator::setParameters(const QVariantMap &_settings)
requiredKeys.append("batTooltip"); requiredKeys.append("batTooltip");
// background // background
m_toolTipScene->setBackgroundBrush( m_toolTipScene->setBackgroundBrush(m_configuration["useTooltipBackground"].toBool()
m_configuration["useTooltipBackground"].toBool() ? QBrush(QColor(m_configuration["tooltipBackground"].toString()))
? QBrush(QColor(m_configuration["tooltipBackground"].toString())) : QBrush(Qt::NoBrush));
: QBrush(Qt::NoBrush));
} }
@ -131,13 +117,12 @@ QPixmap AWDataAggregator::tooltipImage()
// create frame // create frame
float normX = 100.0f / static_cast<float>(m_values[key].count()); float normX = 100.0f / static_cast<float>(m_values[key].count());
float normY = 100.0f / (1.5f * m_boundaries[key]); float normY = 100.0f / (1.5f * m_boundaries[key]);
float shift = requiredKeys.indexOf(key) * 100.0f; float shift = static_cast<float>(requiredKeys.indexOf(key)) * 100.0f;
if (down) if (down)
shift -= 100.0; shift -= 100.0;
// apply pen color // apply pen color
if (key != "batTooltip") if (key != "batTooltip")
pen.setColor(QColor( pen.setColor(QColor(m_configuration[QString("%1Color").arg(key)].toString()));
m_configuration[QString("%1Color").arg(key)].toString()));
// paint data inside frame // paint data inside frame
for (int j = 0; j < m_values[key].count() - 1; j++) { for (int j = 0; j < m_values[key].count() - 1; j++) {
// some magic here // some magic here
@ -147,11 +132,9 @@ QPixmap AWDataAggregator::tooltipImage()
float y2 = -std::fabs(m_values[key].at(j + 1)) * normY + 5.0f; float y2 = -std::fabs(m_values[key].at(j + 1)) * normY + 5.0f;
if (key == "batTooltip") { if (key == "batTooltip") {
if (m_values[key].at(j + 1) > 0) if (m_values[key].at(j + 1) > 0)
pen.setColor( pen.setColor(QColor(m_configuration["batTooltipColor"].toString()));
QColor(m_configuration["batTooltipColor"].toString()));
else else
pen.setColor(QColor( pen.setColor(QColor(m_configuration["batInTooltipColor"].toString()));
m_configuration["batInTooltipColor"].toString()));
} }
m_toolTipScene->addLine(x1, y1, x2, y2, pen); m_toolTipScene->addLine(x1, y1, x2, y2, pen);
} }
@ -171,36 +154,28 @@ void AWDataAggregator::dataUpdate(const QVariantHash &_values)
} }
void AWDataAggregator::checkValue(const QString &_source, const float _value, void AWDataAggregator::checkValue(const QString &_source, const float _value, const float _extremum) const
const float _extremum) const
{ {
qCDebug(LOG_AW) << "Notification source" << _source << "with value" qCDebug(LOG_AW) << "Notification source" << _source << "with value" << _value << "called with extremum"
<< _value << "called with extremum" << _extremum; << _extremum;
if (_value >= 0.0) { if (_value >= 0.0) {
if ((m_enablePopup) && (_value > _extremum) if ((m_enablePopup) && (_value > _extremum) && (m_values[_source].last() < _extremum))
&& (m_values[_source].last() < _extremum)) return AWActions::sendNotification("event", notificationText(_source, _value));
return AWActions::sendNotification(
"event", notificationText(_source, _value));
} else { } else {
if ((m_enablePopup) && (_value < _extremum) if ((m_enablePopup) && (_value < _extremum) && (m_values[_source].last() > _extremum))
&& (m_values[_source].last() > _extremum)) return AWActions::sendNotification("event", notificationText(_source, _value));
return AWActions::sendNotification(
"event", notificationText(_source, _value));
} }
} }
void AWDataAggregator::checkValue(const QString &_source, void AWDataAggregator::checkValue(const QString &_source, const QString &_current, const QString &_received) const
const QString &_current,
const QString &_received) const
{ {
qCDebug(LOG_AW) << "Notification source" << _source << "with current value" qCDebug(LOG_AW) << "Notification source" << _source << "with current value" << _current << "and received one"
<< _current << "and received one" << _received; << _received;
if ((m_enablePopup) && (_current != _received) && (!_received.isEmpty())) if ((m_enablePopup) && (_current != _received) && (!_received.isEmpty()))
return AWActions::sendNotification( return AWActions::sendNotification("event", notificationText(_source, _received));
"event", notificationText(_source, _received));
} }
@ -216,11 +191,9 @@ void AWDataAggregator::initScene()
} }
QString AWDataAggregator::notificationText(const QString &_source, QString AWDataAggregator::notificationText(const QString &_source, const float _value)
const float _value) const
{ {
qCDebug(LOG_AW) << "Notification source" << _source << "with value" qCDebug(LOG_AW) << "Notification source" << _source << "with value" << _value;
<< _value;
QString output; QString output;
if (_source == "batTooltip") if (_source == "batTooltip")
@ -238,11 +211,9 @@ QString AWDataAggregator::notificationText(const QString &_source,
} }
QString AWDataAggregator::notificationText(const QString &_source, QString AWDataAggregator::notificationText(const QString &_source, const QString &_value)
const QString &_value) const
{ {
qCDebug(LOG_AW) << "Notification source" << _source << "with value" qCDebug(LOG_AW) << "Notification source" << _source << "with value" << _value;
<< _value;
QString output; QString output;
if (_source == "netdev") if (_source == "netdev")
@ -256,8 +227,7 @@ void AWDataAggregator::setData(const QVariantHash &_values)
{ {
// do not log these arguments // do not log these arguments
// battery update requires info is AC online or not // battery update requires info is AC online or not
setData(_values["ac"].toString() == m_configuration["acOnline"], setData(_values["ac"].toString() == m_configuration["acOnline"], "batTooltip", _values["bat"].toFloat());
"batTooltip", _values["bat"].toFloat());
// usual case // usual case
setData("cpuTooltip", _values["cpu"].toFloat(), 90.0); setData("cpuTooltip", _values["cpu"].toFloat(), 90.0);
setData("cpuclTooltip", _values["cpucl"].toFloat()); setData("cpuclTooltip", _values["cpucl"].toFloat());
@ -271,23 +241,17 @@ void AWDataAggregator::setData(const QVariantHash &_values)
m_currentNetworkDevice = value; m_currentNetworkDevice = value;
}(_values["netdev"].toString()); }(_values["netdev"].toString());
// additional check for GPU load // additional check for GPU load
[this](const float value) { [this](const float value) { checkValue("gpu", value, 90.0); }(_values["gpu"].toFloat());
checkValue("gpu", value, 90.0);
m_currentGPULoad = value;
}(_values["gpu"].toFloat());
} }
void AWDataAggregator::setData(const QString &_source, float _value, void AWDataAggregator::setData(const QString &_source, float _value, const float _extremum)
const float _extremum)
{ {
qCDebug(LOG_AW) << "Source" << _source << "to value" << _value qCDebug(LOG_AW) << "Source" << _source << "to value" << _value << "with extremum" << _extremum;
<< "with extremum" << _extremum;
if (m_values[_source].count() == 0) if (m_values[_source].count() == 0)
m_values[_source].append(0.0); m_values[_source].append(0.0);
else if (m_values[_source].count() else if (m_values[_source].count() > m_configuration["tooltipNumber"].toInt())
> m_configuration["tooltipNumber"].toInt())
m_values[_source].removeFirst(); m_values[_source].removeFirst();
if (std::isnan(_value)) if (std::isnan(_value))
_value = 0.0; _value = 0.0;
@ -297,22 +261,18 @@ void AWDataAggregator::setData(const QString &_source, float _value,
m_values[_source].append(_value); m_values[_source].append(_value);
if (_source == "downkbTooltip") { if (_source == "downkbTooltip") {
QList<float> netValues QList<float> netValues = m_values["downkbTooltip"] + m_values["upkbTooltip"];
= m_values["downkbTooltip"] + m_values["upkbTooltip"];
// to avoid inf value of normY // to avoid inf value of normY
netValues << 1.0; netValues << 1.0;
m_boundaries["downkbTooltip"] m_boundaries["downkbTooltip"] = 1.2f * *std::max_element(netValues.cbegin(), netValues.cend());
= 1.2f * *std::max_element(netValues.cbegin(), netValues.cend());
m_boundaries["upkbTooltip"] = m_boundaries["downkbTooltip"]; m_boundaries["upkbTooltip"] = m_boundaries["downkbTooltip"];
} }
} }
void AWDataAggregator::setData(const bool _dontInvert, const QString &_source, void AWDataAggregator::setData(const bool _dontInvert, const QString &_source, float _value)
float _value)
{ {
qCDebug(LOG_AW) << "Do not invert" << _dontInvert << "value" << _value qCDebug(LOG_AW) << "Do not invert" << _dontInvert << "value" << _value << "for source" << _source;
<< "for source" << _source;
// invert values for different battery colours // invert values for different battery colours
_value = _dontInvert ? _value : -_value; _value = _dontInvert ? _value : -_value;

View File

@ -34,41 +34,34 @@ class AWDataAggregator : public QObject
public: public:
explicit AWDataAggregator(QObject *_parent = nullptr); explicit AWDataAggregator(QObject *_parent = nullptr);
virtual ~AWDataAggregator(); ~AWDataAggregator() override;
QList<float> getData(const QString &_key) const; static QString htmlImage(const QPixmap &_source);
QString htmlImage(const QPixmap &_source) const;
void setParameters(const QVariantMap &_settings); void setParameters(const QVariantMap &_settings);
QPixmap tooltipImage(); QPixmap tooltipImage();
signals: public slots:
void updateData(const QVariantHash &_values);
void toolTipPainted(const QString &_image) const;
private slots:
void dataUpdate(const QVariantHash &_values); void dataUpdate(const QVariantHash &_values);
signals:
void toolTipPainted(const QString &_image) const;
private: private:
// ui // ui
QGraphicsScene *m_toolTipScene = nullptr; QGraphicsScene *m_toolTipScene = nullptr;
QGraphicsView *m_toolTipView = nullptr; QGraphicsView *m_toolTipView = nullptr;
void checkValue(const QString &_source, const float _value, void checkValue(const QString &_source, float _value, float _extremum) const;
const float _extremum) const; void checkValue(const QString &_source, const QString &_current, const QString &_received) const;
void checkValue(const QString &_source, const QString &_current,
const QString &_received) const;
void initScene(); void initScene();
QString notificationText(const QString &_source, const float _value) const; static QString notificationText(const QString &_source, float _value);
QString notificationText(const QString &_source, static QString notificationText(const QString &_source, const QString &_value);
const QString &_value) const;
// main method // main method
void setData(const QVariantHash &_values); void setData(const QVariantHash &_values);
void setData(const QString &_source, float _value, void setData(const QString &_source, float _value, float _extremum = -1.0f);
const float _extremum = -1.0f);
// different signature for battery device // different signature for battery device
void setData(const bool _dontInvert, const QString &_source, float _value); void setData(bool _dontInvert, const QString &_source, float _value);
// variables // variables
int m_counts = 0; int m_counts = 0;
QVariantHash m_configuration; QVariantHash m_configuration;
float m_currentGPULoad = 0.0f;
QString m_currentNetworkDevice = "lo"; QString m_currentNetworkDevice = "lo";
QHash<QString, float> m_boundaries; QHash<QString, float> m_boundaries;
QHash<QString, QList<float>> m_values; QHash<QString, QList<float>> m_values;

View File

@ -20,7 +20,6 @@
#include <Plasma/DataContainer> #include <Plasma/DataContainer>
#include "awdebug.h" #include "awdebug.h"
#include "awkeys.h"
AWDataEngineAggregator::AWDataEngineAggregator(QObject *_parent) AWDataEngineAggregator::AWDataEngineAggregator(QObject *_parent)
@ -28,6 +27,18 @@ AWDataEngineAggregator::AWDataEngineAggregator(QObject *_parent)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_consumer = new Plasma::DataEngineConsumer();
m_dataEngines["systemmonitor"] = m_consumer->dataEngine("systemmonitor");
m_dataEngines["extsysmon"] = m_consumer->dataEngine("extsysmon");
m_dataEngines["time"] = m_consumer->dataEngine("time");
// additional method required by systemmonitor structure
m_newSourceConnection
= connect(m_dataEngines["systemmonitor"], &Plasma::DataEngine::sourceAdded, [this](const QString &source) {
emit(deviceAdded(source));
m_dataEngines["systemmonitor"]->connectSource(source, parent(), 1000);
});
// required to define Qt::QueuedConnection for signal-slot connection // required to define Qt::QueuedConnection for signal-slot connection
qRegisterMetaType<Plasma::DataEngine::Data>("Plasma::DataEngine::Data"); qRegisterMetaType<Plasma::DataEngine::Data>("Plasma::DataEngine::Data");
} }
@ -37,45 +48,38 @@ AWDataEngineAggregator::~AWDataEngineAggregator()
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
clear();
}
void AWDataEngineAggregator::clear()
{
// disconnect sources first
disconnectSources(); disconnectSources();
m_dataEngines.clear();
delete m_consumer;
} }
void AWDataEngineAggregator::disconnectSources() void AWDataEngineAggregator::disconnectSources()
{ {
for (auto dataengine : m_dataEngines.values()) for (auto dataEngine : m_dataEngines.values())
for (auto &source : dataengine->sources()) for (auto &source : dataEngine->sources())
dataengine->disconnectSource(source, parent()); dataEngine->disconnectSource(source, parent());
disconnect(m_newSourceConnection);
} }
void AWDataEngineAggregator::initDataEngines(const int _interval) void AWDataEngineAggregator::reconnectSources(const int _interval)
{ {
qCDebug(LOG_AW) << "Init dataengines with interval" << _interval; qCDebug(LOG_AW) << "Reconnect sources with interval" << _interval;
m_consumer = new Plasma::DataEngineConsumer(); disconnectSources();
m_dataEngines["systemmonitor"] = m_consumer->dataEngine("systemmonitor");
m_dataEngines["extsysmon"] = m_consumer->dataEngine("extsysmon");
m_dataEngines["time"] = m_consumer->dataEngine("time");
// additional method required by systemmonitor structure m_dataEngines["systemmonitor"]->connectAllSources(parent(), (uint)_interval);
connect(m_dataEngines["systemmonitor"], &Plasma::DataEngine::sourceAdded, m_dataEngines["extsysmon"]->connectAllSources(parent(), (uint)_interval);
[this, _interval](const QString source) { m_dataEngines["time"]->connectSource("Local", parent(), 1000);
emit(deviceAdded(source));
m_dataEngines["systemmonitor"]->connectSource(source, parent(),
_interval);
});
return reconnectSources(_interval); m_newSourceConnection = connect(
m_dataEngines["systemmonitor"], &Plasma::DataEngine::sourceAdded, [this, _interval](const QString &source) {
emit(deviceAdded(source));
m_dataEngines["systemmonitor"]->connectSource(source, parent(), (uint)_interval);
});
#ifdef BUILD_FUTURE
createQueuedConnection();
#endif /* BUILD_FUTURE */
} }
@ -84,23 +88,9 @@ void AWDataEngineAggregator::dropSource(const QString &_source)
qCDebug(LOG_AW) << "Source" << _source; qCDebug(LOG_AW) << "Source" << _source;
// HACK there is no possibility to check to which dataengine source // HACK there is no possibility to check to which dataengine source
// connected we will try to disconnect it from systemmonitor and extsysmon // connected we will try to disconnect it from all engines
for (auto dataengine : m_dataEngines.values()) for (auto dataEngine : m_dataEngines.values())
dataengine->disconnectSource(_source, parent()); dataEngine->disconnectSource(_source, parent());
}
void AWDataEngineAggregator::reconnectSources(const int _interval)
{
qCDebug(LOG_AW) << "Reconnect sources with interval" << _interval;
m_dataEngines["systemmonitor"]->connectAllSources(parent(), _interval);
m_dataEngines["extsysmon"]->connectAllSources(parent(), _interval);
m_dataEngines["time"]->connectSource("Local", parent(), 1000);
#ifdef BUILD_FUTURE
createQueuedConnection();
#endif /* BUILD_FUTURE */
} }
@ -110,24 +100,16 @@ void AWDataEngineAggregator::createQueuedConnection()
// for more details refer to plasma-framework source code // for more details refer to plasma-framework source code
for (auto &dataEngine : m_dataEngines.keys()) { for (auto &dataEngine : m_dataEngines.keys()) {
// different source set for different engines // different source set for different engines
QStringList sources = dataEngine == "time" QStringList sources = dataEngine == "time" ? QStringList() << "Local" : m_dataEngines[dataEngine]->sources();
? QStringList() << "Local"
: m_dataEngines[dataEngine]->sources();
// reconnect sources // reconnect sources
for (auto &source : sources) { for (auto &source : sources) {
Plasma::DataContainer *container Plasma::DataContainer *container = m_dataEngines[dataEngine]->containerForSource(source);
= m_dataEngines[dataEngine]->containerForSource(source);
// disconnect old connections first // disconnect old connections first
disconnect(container, disconnect(container, SIGNAL(dataUpdated(QString, Plasma::DataEngine::Data)), parent(),
SIGNAL(dataUpdated(QString, Plasma::DataEngine::Data)),
parent(),
SLOT(dataUpdated(QString, Plasma::DataEngine::Data))); SLOT(dataUpdated(QString, Plasma::DataEngine::Data)));
// and now reconnect with Qt::QueuedConnection type // and now reconnect with Qt::QueuedConnection type
connect(container, connect(container, SIGNAL(dataUpdated(QString, Plasma::DataEngine::Data)), parent(),
SIGNAL(dataUpdated(QString, Plasma::DataEngine::Data)), SLOT(dataUpdated(QString, Plasma::DataEngine::Data)), Qt::QueuedConnection);
parent(),
SLOT(dataUpdated(QString, Plasma::DataEngine::Data)),
Qt::QueuedConnection);
} }
} }
} }

View File

@ -31,22 +31,21 @@ class AWDataEngineAggregator : public QObject
public: public:
explicit AWDataEngineAggregator(QObject *_parent = nullptr); explicit AWDataEngineAggregator(QObject *_parent = nullptr);
virtual ~AWDataEngineAggregator(); ~AWDataEngineAggregator() override;
void clear();
void disconnectSources(); void disconnectSources();
void initDataEngines(const int _interval); void reconnectSources(int _interval);
signals: signals:
void deviceAdded(const QString &_source); void deviceAdded(const QString &_source);
public slots: public slots:
void dropSource(const QString &_source); void dropSource(const QString &_source);
void reconnectSources(const int _interval);
private: private:
void createQueuedConnection(); void createQueuedConnection();
Plasma::DataEngineConsumer *m_consumer = nullptr; Plasma::DataEngineConsumer *m_consumer = nullptr;
QHash<QString, Plasma::DataEngine *> m_dataEngines; QHash<QString, Plasma::DataEngine *> m_dataEngines;
QMetaObject::Connection m_newSourceConnection;
}; };

View File

@ -0,0 +1,445 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awdataenginemapper.h"
#include <QRegExp>
#include "awdebug.h"
#include "awformatterhelper.h"
AWDataEngineMapper::AWDataEngineMapper(QObject *_parent, AWFormatterHelper *_custom)
: QObject(_parent)
, m_customFormatters(_custom)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
// default formatters
// memory
m_formatter["mem"] = AWKeysAggregator::FormatterType::Float;
m_formatter["memtotmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter["memtotgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
// network
m_formatter["down"] = AWKeysAggregator::FormatterType::NetSmartFormat;
m_formatter["downkb"] = AWKeysAggregator::FormatterType::Integer;
m_formatter["downtot"] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter["downtotkb"] = AWKeysAggregator::FormatterType::Integer;
m_formatter["downunits"] = AWKeysAggregator::FormatterType::NetSmartUnits;
m_formatter["up"] = AWKeysAggregator::FormatterType::NetSmartFormat;
m_formatter["upkb"] = AWKeysAggregator::FormatterType::Integer;
m_formatter["uptot"] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter["uptotkb"] = AWKeysAggregator::FormatterType::Integer;
m_formatter["upunits"] = AWKeysAggregator::FormatterType::NetSmartUnits;
// swap
m_formatter["swap"] = AWKeysAggregator::FormatterType::Float;
m_formatter["swaptotmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter["swaptotgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
}
AWDataEngineMapper::~AWDataEngineMapper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWKeysAggregator::FormatterType AWDataEngineMapper::formatter(const QString &_key) const
{
qCDebug(LOG_AW) << "Get formatter for key" << _key;
return m_formatter.value(_key, AWKeysAggregator::FormatterType::NoFormat);
}
QStringList AWDataEngineMapper::keysFromSource(const QString &_source) const
{
qCDebug(LOG_AW) << "Search for source" << _source;
return m_map.values(_source);
}
// HACK units required to define should the value be calculated as temperature
// or fan data
QStringList AWDataEngineMapper::registerSource(const QString &_source, const QString &_units, const QStringList &_keys)
{
qCDebug(LOG_AW) << "Source" << _source << "with units" << _units;
// regular expressions
QRegExp cpuRegExp = QRegExp("cpu/cpu.*/TotalLoad");
QRegExp cpuclRegExp = QRegExp("cpu/cpu.*/clock");
QRegExp hddrRegExp = QRegExp("disk/.*/Rate/rblk");
QRegExp hddwRegExp = QRegExp("disk/.*/Rate/wblk");
QRegExp mountFillRegExp = QRegExp("partitions/.*/filllevel");
QRegExp mountFreeRegExp = QRegExp("partitions/.*/freespace");
QRegExp mountUsedRegExp = QRegExp("partitions/.*/usedspace");
QRegExp netRegExp = QRegExp("network/interfaces/.*/(receiver|transmitter)/data$");
QRegExp netTotalRegExp = QRegExp("network/interfaces/.*/(receiver|transmitter)/dataTotal$");
if (_source == "battery/ac") {
// AC
m_map.insert(_source, "ac");
m_formatter["ac"] = AWKeysAggregator::FormatterType::ACFormat;
} else if (_source.startsWith("battery/")) {
// battery stats
QString key = _source;
key.remove("battery/");
m_map.insert(_source, key);
m_formatter[key] = _source.contains("rate") ? AWKeysAggregator::FormatterType::Float
: AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source == "cpu/system/TotalLoad") {
// cpu
m_map.insert(_source, "cpu");
m_formatter["cpu"] = AWKeysAggregator::FormatterType::Float;
} else if (_source.contains(cpuRegExp)) {
// cpus
QString key = _source;
key.remove("cpu/").remove("/TotalLoad");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Float;
} else if (_source == "cpu/system/AverageClock") {
// cpucl
m_map.insert(_source, "cpucl");
m_formatter["cpucl"] = AWKeysAggregator::FormatterType::Integer;
} else if (_source.contains(cpuclRegExp)) {
// cpucls
QString key = _source;
key.remove("cpu/cpu").remove("/clock");
key = QString("cpucl%1").arg(key);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
} else if (_source.startsWith("custom")) {
// custom
QString key = _source;
key.remove("custom/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "desktop/current/name") {
// current desktop name
m_map.insert(_source, "desktop");
m_formatter["desktop"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "desktop/current/number") {
// current desktop number
m_map.insert(_source, "ndesktop");
m_formatter["ndesktop"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "desktop/total/number") {
// desktop count
m_map.insert(_source, "tdesktops");
m_formatter["tdesktops"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.contains(hddrRegExp)) {
// read speed
QString device = _source;
device.remove("/Rate/rblk");
int index = m_devices["disk"].indexOf(device);
if (index > -1) {
QString key = QString("hddr%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
}
} else if (_source.contains(hddwRegExp)) {
// write speed
QString device = _source;
device.remove("/Rate/wblk");
int index = m_devices["disk"].indexOf(device);
if (index > -1) {
QString key = QString("hddw%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
}
} else if (_source == "gpu/load") {
// gpu load
m_map.insert(_source, "gpu");
m_formatter["gpu"] = AWKeysAggregator::FormatterType::Float;
} else if (_source == "gpu/temperature") {
// gpu temperature
m_map.insert(_source, "gputemp");
m_formatter["gputemp"] = AWKeysAggregator::FormatterType::Temperature;
} else if (_source.contains(mountFillRegExp)) {
// fill level
QString device = _source;
device.remove("partitions").remove("/filllevel");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
QString key = QString("hdd%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Float;
// additional keys
m_formatter[QString("hddtotmb%1").arg(index)] = AWKeysAggregator::FormatterType::MemMBFormat;
m_formatter[QString("hddtotgb%1").arg(index)] = AWKeysAggregator::FormatterType::MemGBFormat;
}
} else if (_source.contains(mountFreeRegExp)) {
// free space
QString device = _source;
device.remove("partitions").remove("/freespace");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
// mb
QString key = QString("hddfreemb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
key = QString("hddfreegb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemGBFormat;
}
} else if (_source.contains(mountUsedRegExp)) {
// used
QString device = _source;
device.remove("partitions").remove("/usedspace");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
// mb
QString key = QString("hddmb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
key = QString("hddgb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemGBFormat;
}
} else if (_source.startsWith("hdd/temperature")) {
// hdd temperature
QString device = _source;
device.remove("hdd/temperature");
int index = m_devices["hdd"].indexOf(device);
if (index > -1) {
QString key = QString("hddtemp%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Temperature;
}
} else if (_source.startsWith("cpu/system/loadavg")) {
// load average
QString time = _source;
time.remove("cpu/system/loadavg");
QString key = QString("la%1").arg(time);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::FloatTwoSymbols;
} else if (_source == "mem/physical/application") {
// app memory
// mb
m_map.insert(_source, "memmb");
m_formatter["memmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "memgb");
m_formatter["memgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "mem/physical/free") {
// free memory
// mb
m_map.insert(_source, "memfreemb");
m_formatter["memfreemb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "memfreegb");
m_formatter["memfreegb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "mem/physical/used") {
// used memory
// mb
m_map.insert(_source, "memusedmb");
m_formatter["memusedmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "memusedgb");
m_formatter["memusedgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "network/current/name") {
// network device
m_map.insert(_source, "netdev");
m_formatter["netdev"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "network/current/ssid") {
// current ssid
m_map.insert(_source, "ssid");
m_formatter["ssid"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.startsWith("network/response")) {
// network response
QString key = _source;
key.remove("network/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.contains(netRegExp)) {
// network speed
QString type = _source.contains("receiver") ? "down" : "up";
int index = m_devices["net"].indexOf(_source.split('/')[2]);
if (index > -1) {
// kb
QString key = QString("%1kb%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
// smart
key = QString("%1%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NetSmartFormat;
// units
key = QString("%1units%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NetSmartUnits;
}
} else if (_source.contains(netTotalRegExp)) {
// network data total
QString type = _source.contains("receiver") ? "down" : "up";
int index = m_devices["net"].indexOf(_source.split('/')[2]);
if (index > -1) {
// kb
QString key = QString("%1totkb%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
// mb
key = QString("%1tot%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemMBFormat;
}
} else if (_source.startsWith("upgrade")) {
// package manager
QString key = _source;
key.remove("upgrade/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source.startsWith("player")) {
// player
QString key = _source;
key.remove("player/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "ps/running/count") {
// running processes count
m_map.insert(_source, "pscount");
m_formatter["pscount"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "ps/running/list") {
// list of running processes
m_map.insert(_source, "ps");
m_formatter["ps"] = AWKeysAggregator::FormatterType::List;
} else if (_source == "ps/total/count") {
// total processes count
m_map.insert(_source, "pstot");
m_formatter["pstot"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.startsWith("quotes")) {
// quotes
QString key = _source;
key.remove("quotes/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Quotes;
} else if (_source == "mem/swap/free") {
// free swap
// mb
m_map.insert(_source, "swapfreemb");
m_formatter["swapfreemb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "swapfreegb");
m_formatter["swapfreegb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "mem/swap/used") {
// used swap
// mb
m_map.insert(_source, "swapmb");
m_formatter["swapmb"] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
m_map.insert(_source, "swapgb");
m_formatter["swapgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source.startsWith("lmsensors/")) {
// temperature
int index = m_devices["temp"].indexOf(_source);
// HACK on DE initialization there are no units key
if (_units.isEmpty())
return QStringList({QString("temp%1").arg(index)});
if (index > -1) {
QString key = QString("temp%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = _units == "°C" ? AWKeysAggregator::FormatterType::Temperature
: AWKeysAggregator::FormatterType::Integer;
}
} else if (_source == "Local") {
// time
m_map.insert(_source, "time");
m_formatter["time"] = AWKeysAggregator::FormatterType::Time;
// custom time
m_map.insert(_source, "ctime");
m_formatter["ctime"] = AWKeysAggregator::FormatterType::TimeCustom;
// ISO time
m_map.insert(_source, "isotime");
m_formatter["isotime"] = AWKeysAggregator::FormatterType::TimeISO;
// long time
m_map.insert(_source, "longtime");
m_formatter["longtime"] = AWKeysAggregator::FormatterType::TimeLong;
// short time
m_map.insert(_source, "shorttime");
m_formatter["shorttime"] = AWKeysAggregator::FormatterType::TimeShort;
// timestamp
m_map.insert(_source, "tstime");
m_formatter["tstime"] = AWKeysAggregator::FormatterType::Timestamp;
} else if (_source == "system/brightness") {
m_map.insert(_source, "brightness");
m_formatter["brightness"] = AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source == "system/volume") {
m_map.insert(_source, "volume");
m_formatter["volume"] = AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source == "system/uptime") {
// uptime
m_map.insert(_source, "uptime");
m_formatter["uptime"] = AWKeysAggregator::FormatterType::Uptime;
// custom uptime
m_map.insert(_source, "cuptime");
m_formatter["cuptime"] = AWKeysAggregator::FormatterType::UptimeCustom;
} else if (_source.startsWith("weather/temperature")) {
// temperature
QString key = _source;
key.remove("weather/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Temperature;
} else if (_source.startsWith("weather/")) {
// other weather
QString key = _source;
key.remove("weather/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.startsWith("load/load")) {
// load source
QString key = _source;
key.remove("load/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Temperature;
}
QStringList foundKeys = keysFromSource(_source);
// rewrite formatters for custom ones
QStringList customFormattersKeys;
if (m_customFormatters)
customFormattersKeys = m_customFormatters->definedFormatters();
qCInfo(LOG_AW) << "Looking for formatters" << foundKeys << "in" << customFormattersKeys;
for (auto &key : foundKeys) {
if (!customFormattersKeys.contains(key))
continue;
m_formatter[key] = AWKeysAggregator::FormatterType::Custom;
}
// drop key from dictionary if no one user requested key required it
qCInfo(LOG_AW) << "Looking for keys" << foundKeys << "in" << _keys;
bool required = _keys.isEmpty() || std::any_of(foundKeys.cbegin(), foundKeys.cend(), [&_keys](const QString &key) {
return _keys.contains(key);
});
if (!required) {
m_map.remove(_source);
for (auto &key : foundKeys)
m_formatter.remove(key);
}
return keysFromSource(_source);
}
void AWDataEngineMapper::setDevices(const QHash<QString, QStringList> &_devices)
{
qCDebug(LOG_AW) << "Devices" << _devices;
m_devices = _devices;
}

View File

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

View File

@ -17,6 +17,9 @@
#include "awdbusadaptor.h" #include "awdbusadaptor.h"
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include "awdebug.h" #include "awdebug.h"
#include "awkeys.h" #include "awkeys.h"
@ -35,6 +38,24 @@ AWDBusAdaptor::~AWDBusAdaptor()
} }
QStringList AWDBusAdaptor::ActiveServices()
{
QDBusMessage listServices = QDBusConnection::sessionBus().interface()->call(QDBus::BlockWithGui, "ListNames");
if (listServices.arguments().isEmpty()) {
qCWarning(LOG_DBUS) << "Could not find any DBus service";
return {};
}
QStringList arguments = listServices.arguments().first().toStringList();
return std::accumulate(arguments.cbegin(), arguments.cend(), QStringList(),
[](QStringList source, const QString &service) {
if (service.startsWith(AWDBUS_SERVICE))
source.append(service);
return source;
});
}
QString AWDBusAdaptor::Info(const QString &key) const QString AWDBusAdaptor::Info(const QString &key) const
{ {
return m_plugin->infoByKey(key); return m_plugin->infoByKey(key);
@ -64,8 +85,7 @@ void AWDBusAdaptor::SetLogLevel(const QString &what, const int level)
qCDebug(LOG_DBUS) << "Set log level" << level << "for" << what; qCDebug(LOG_DBUS) << "Set log level" << level << "for" << what;
if (level >= m_logLevels.count()) { if (level >= m_logLevels.count()) {
qCDebug(LOG_DBUS) << "Invalid logging level" << level qCDebug(LOG_DBUS) << "Invalid logging level" << level << "should be less than" << m_logLevels.count();
<< "should be less than" << m_logLevels.count();
return; return;
} }
@ -74,19 +94,15 @@ void AWDBusAdaptor::SetLogLevel(const QString &what, const int level)
} }
void AWDBusAdaptor::SetLogLevel(const QString &what, const QString &level, void AWDBusAdaptor::SetLogLevel(const QString &what, const QString &level, const bool enabled)
const bool enabled)
{ {
qCDebug(LOG_DBUS) << "Set log level" << level << "enabled" << enabled qCDebug(LOG_DBUS) << "Set log level" << level << "enabled" << enabled << "for" << what;
<< "for" << what;
if (!m_logLevels.contains(level)) { if (!m_logLevels.contains(level)) {
qCDebug(LOG_DBUS) << "Invalid logging level" << level << "should be in" qCDebug(LOG_DBUS) << "Invalid logging level" << level << "should be in" << m_logLevels;
<< m_logLevels;
return; return;
} }
QString state = enabled ? "true" : "false"; QString state = enabled ? "true" : "false";
QLoggingCategory::setFilterRules( QLoggingCategory::setFilterRules(QString("%1.%2=%3").arg(what).arg(level).arg(state));
QString("%1.%2=%3").arg(what).arg(level).arg(state));
} }

View File

@ -33,25 +33,22 @@ class AWDBusAdaptor : public QDBusAbstractAdaptor
public: public:
explicit AWDBusAdaptor(AWKeys *_parent = nullptr); explicit AWDBusAdaptor(AWKeys *_parent = nullptr);
virtual ~AWDBusAdaptor(); ~AWDBusAdaptor() override;
public slots: public slots:
// get methods // get methods
QString Info(const QString &key) const; [[nodiscard]] static QStringList ActiveServices();
QStringList Keys(const QString &regexp) const; [[nodiscard]] QString Info(const QString &key) const;
QString Value(const QString &key) const; [[nodiscard]] QStringList Keys(const QString &regexp) const;
qlonglong WhoAmI() const; [[nodiscard]] QString Value(const QString &key) const;
[[nodiscard]] qlonglong WhoAmI() const;
// set methods // set methods
void SetLogLevel(const QString &what, const int level); void SetLogLevel(const QString &what, int level);
void SetLogLevel(const QString &what, const QString &level, void SetLogLevel(const QString &what, const QString &level, bool enabled);
const bool enabled);
private: private:
AWKeys *m_plugin = nullptr; AWKeys *m_plugin = nullptr;
QStringList m_logLevels = QStringList() << "debug" QStringList m_logLevels = {"debug", "info", "warning", "critical"};
<< "info"
<< "warning"
<< "critical";
}; };

View File

@ -22,8 +22,8 @@
#include "awactions.h" #include "awactions.h"
#include "awbugreporter.h" #include "awbugreporter.h"
#include "awconfighelper.h" #include "awconfighelper.h"
#include "awformatterconfigfactory.h"
#include "awkeys.h" #include "awkeys.h"
#include "awpairconfigfactory.h"
#include "awtelemetryhandler.h" #include "awtelemetryhandler.h"
@ -34,8 +34,7 @@ void AWPlugin::registerTypes(const char *uri)
qmlRegisterType<AWActions>(uri, 1, 0, "AWActions"); qmlRegisterType<AWActions>(uri, 1, 0, "AWActions");
qmlRegisterType<AWBugReporter>(uri, 1, 0, "AWBugReporter"); qmlRegisterType<AWBugReporter>(uri, 1, 0, "AWBugReporter");
qmlRegisterType<AWConfigHelper>(uri, 1, 0, "AWConfigHelper"); qmlRegisterType<AWConfigHelper>(uri, 1, 0, "AWConfigHelper");
qmlRegisterType<AWFormatterConfigFactory>(uri, 1, 0, qmlRegisterType<AWPairConfigFactory>(uri, 1, 0, "AWPairConfigFactory");
"AWFormatterConfigFactory");
qmlRegisterType<AWKeys>(uri, 1, 0, "AWKeys"); qmlRegisterType<AWKeys>(uri, 1, 0, "AWKeys");
qmlRegisterType<AWTelemetryHandler>(uri, 1, 0, "AWTelemetryHandler"); qmlRegisterType<AWTelemetryHandler>(uri, 1, 0, "AWTelemetryHandler");
} }

View File

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

View File

@ -16,168 +16,22 @@
***************************************************************************/ ***************************************************************************/
#include "awformatterconfig.h" #include "awformatterconfig.h"
#include "ui_awformatterconfig.h"
#include <KI18n/KLocalizedString>
#include <QPushButton>
#include "awabstractselector.h"
#include "awdebug.h" #include "awdebug.h"
#include "awformatterhelper.h" #include "awformatterhelper.h"
AWFormatterConfig::AWFormatterConfig(QWidget *_parent, const QStringList &_keys) AWFormatterConfig::AWFormatterConfig(QWidget *_parent, const QStringList &_keys)
: QDialog(_parent) : AWAbstractPairConfig(_parent, true, _keys)
, ui(new Ui::AWFormatterConfig)
, m_keys(_keys)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
ui->setupUi(this); setEditable(false, false);
m_editButton initHelper<AWFormatterHelper>();
= ui->buttonBox->addButton(i18n("Edit"), QDialogButtonBox::ActionRole);
init();
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(m_editButton, SIGNAL(clicked(bool)), this, SLOT(editFormatters()));
} }
AWFormatterConfig::~AWFormatterConfig() AWFormatterConfig::~AWFormatterConfig()
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
clearSelectors();
delete m_helper;
delete ui;
}
void AWFormatterConfig::showDialog()
{
// update dialog
updateDialog();
// exec dialog
return execDialog();
}
void AWFormatterConfig::editFormatters()
{
m_helper->editItems();
updateDialog();
}
void AWFormatterConfig::updateUi()
{
QPair<QString, QString> current
= static_cast<AWAbstractSelector *>(sender())->current();
int index
= m_selectors.indexOf(static_cast<AWAbstractSelector *>(sender()));
if ((current.first.isEmpty()) && (current.second.isEmpty())) {
// remove current selector if it is empty and does not last
if (sender() == m_selectors.last())
return;
AWAbstractSelector *selector = m_selectors.takeAt(index);
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
} else {
// add new selector if something changed
if (sender() != m_selectors.last())
return;
auto keys = initKeys();
addSelector(keys.first, keys.second, QPair<QString, QString>());
}
}
void AWFormatterConfig::addSelector(const QStringList &_keys,
const QStringList &_values,
const QPair<QString, QString> &_current)
{
qCDebug(LOG_AW) << "Add selector with keys" << _keys << "values" << _values
<< "and current ones" << _current;
AWAbstractSelector *selector
= new AWAbstractSelector(ui->scrollAreaWidgetContents);
selector->init(_keys, _values, _current);
ui->verticalLayout->insertWidget(ui->verticalLayout->count() - 1, selector);
connect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
m_selectors.append(selector);
}
void AWFormatterConfig::clearSelectors()
{
for (auto &selector : m_selectors) {
disconnect(selector, SIGNAL(selectionChanged()), this,
SLOT(updateUi()));
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
}
m_selectors.clear();
}
void AWFormatterConfig::execDialog()
{
int ret = exec();
QHash<QString, QString> data;
for (auto &selector : m_selectors) {
QPair<QString, QString> select = selector->current();
if (select.first.isEmpty())
continue;
data[select.first] = select.second;
}
// save configuration if required
switch (ret) {
case 0:
break;
case 1:
default:
m_helper->writeFormatters(data);
m_helper->removeUnusedFormatters(data.keys());
break;
}
}
void AWFormatterConfig::init()
{
delete m_helper;
m_helper = new AWFormatterHelper(this);
}
QPair<QStringList, QStringList> AWFormatterConfig::initKeys() const
{
// we are adding empty string at the start
QStringList keys = QStringList() << "";
keys.append(m_keys);
keys.sort();
QStringList knownFormatters = QStringList() << "";
knownFormatters.append(m_helper->knownFormatters());
knownFormatters.sort();
return QPair<QStringList, QStringList>(keys, knownFormatters);
}
void AWFormatterConfig::updateDialog()
{
clearSelectors();
QHash<QString, QString> appliedFormatters = m_helper->getFormatters();
auto keys = initKeys();
for (auto &key : appliedFormatters.keys())
addSelector(keys.first, keys.second,
QPair<QString, QString>(key, appliedFormatters[key]));
// empty one
addSelector(keys.first, keys.second, QPair<QString, QString>());
} }

View File

@ -19,45 +19,16 @@
#ifndef AWFORMATTERCONFIG_H #ifndef AWFORMATTERCONFIG_H
#define AWFORMATTERCONFIG_H #define AWFORMATTERCONFIG_H
#include <QDialog> #include "awabstractpairconfig.h"
class AWAbstractSelector; class AWFormatterConfig : public AWAbstractPairConfig
class AWFormatterHelper;
namespace Ui
{
class AWFormatterConfig;
}
class AWFormatterConfig : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit AWFormatterConfig(QWidget *_parent = nullptr, explicit AWFormatterConfig(QWidget *_parent = nullptr, const QStringList &_keys = QStringList());
const QStringList &_keys = QStringList()); ~AWFormatterConfig() override;
virtual ~AWFormatterConfig();
Q_INVOKABLE void showDialog();
private slots:
void editFormatters();
void updateUi();
private:
QPushButton *m_editButton = nullptr;
Ui::AWFormatterConfig *ui = nullptr;
AWFormatterHelper *m_helper = nullptr;
QList<AWAbstractSelector *> m_selectors;
// properties
QStringList m_keys;
// methods
void addSelector(const QStringList &_keys, const QStringList &_values,
const QPair<QString, QString> &_current);
void clearSelectors();
void execDialog();
void init();
QPair<QStringList, QStringList> initKeys() const;
void updateDialog();
}; };

View File

@ -35,11 +35,11 @@
AWFormatterHelper::AWFormatterHelper(QWidget *_parent) AWFormatterHelper::AWFormatterHelper(QWidget *_parent)
: AbstractExtItemAggregator(_parent, "formatters") : AbstractExtItemAggregator(_parent, "formatters")
, AWAbstractPairHelper("awesomewidgets/formatters/formatters.ini", "Formatters")
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_filePath = "awesomewidgets/formatters/formatters.ini"; AWFormatterHelper::initItems();
initItems();
} }
@ -52,13 +52,29 @@ AWFormatterHelper::~AWFormatterHelper()
} }
QString AWFormatterHelper::convert(const QVariant &_value, void AWFormatterHelper::initItems()
const QString &_name) const {
initFormatters();
// assign internal storage
m_formatters.clear();
for (auto &key : pairs().keys()) {
auto name = pairs()[key];
if (!m_formattersClasses.contains(name)) {
qCWarning(LOG_AW) << "Invalid formatter" << name << "found in" << key;
continue;
}
m_formatters[key] = m_formattersClasses[name];
}
}
QString AWFormatterHelper::convert(const QVariant &_value, const QString &_name) const
{ {
qCDebug(LOG_AW) << "Convert value" << _value << "for" << _name; qCDebug(LOG_AW) << "Convert value" << _value << "for" << _name;
return m_formatters.contains(_name) ? m_formatters[_name]->convert(_value) return m_formatters.contains(_name) ? m_formatters[_name]->convert(_value) : _value.toString();
: _value.toString();
} }
@ -68,16 +84,6 @@ QStringList AWFormatterHelper::definedFormatters() const
} }
QHash<QString, QString> AWFormatterHelper::getFormatters() const
{
QHash<QString, QString> map;
for (auto &tag : m_formatters.keys())
map[tag] = m_formatters[tag]->name();
return map;
}
QList<AbstractExtItem *> AWFormatterHelper::items() const QList<AbstractExtItem *> AWFormatterHelper::items() const
{ {
QList<AbstractExtItem *> converted; QList<AbstractExtItem *> converted;
@ -88,61 +94,24 @@ QList<AbstractExtItem *> AWFormatterHelper::items() const
} }
QStringList AWFormatterHelper::knownFormatters() const void AWFormatterHelper::editPairs()
{
return editItems();
}
QStringList AWFormatterHelper::leftKeys()
{
return {};
}
QStringList AWFormatterHelper::rightKeys()
{ {
return m_formattersClasses.keys(); return m_formattersClasses.keys();
} }
bool AWFormatterHelper::removeUnusedFormatters(const QStringList &_keys) const
{
qCDebug(LOG_AW) << "Remove formatters" << _keys;
QString fileName = QString("%1/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup("Formatters");
QStringList foundKeys = settings.childKeys();
for (auto &key : foundKeys) {
if (_keys.contains(key))
continue;
settings.remove(key);
}
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}
bool AWFormatterHelper::writeFormatters(
const QHash<QString, QString> &_configuration) const
{
qCDebug(LOG_AW) << "Write configuration" << _configuration;
QString fileName = QString("%1/%2")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation))
.arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
settings.beginGroup("Formatters");
for (auto &key : _configuration.keys())
settings.setValue(key, _configuration[key]);
settings.endGroup();
settings.sync();
return (settings.status() == QSettings::NoError);
}
void AWFormatterHelper::editItems() void AWFormatterHelper::editItems()
{ {
repaintList(); repaintList();
@ -151,13 +120,11 @@ void AWFormatterHelper::editItems()
} }
AWAbstractFormatter::FormatterClass AWAbstractFormatter::FormatterClass AWFormatterHelper::defineFormatterClass(const QString &_stringType)
AWFormatterHelper::defineFormatterClass(const QString &_stringType) const
{ {
qCDebug(LOG_AW) << "Define formatter class for" << _stringType; qCDebug(LOG_AW) << "Define formatter class for" << _stringType;
AWAbstractFormatter::FormatterClass formatter AWAbstractFormatter::FormatterClass formatter = AWAbstractFormatter::FormatterClass::NoFormat;
= AWAbstractFormatter::FormatterClass::NoFormat;
if (_stringType == "DateTime") if (_stringType == "DateTime")
formatter = AWAbstractFormatter::FormatterClass::DateTime; formatter = AWAbstractFormatter::FormatterClass::DateTime;
else if (_stringType == "Float") else if (_stringType == "Float")
@ -183,47 +150,43 @@ void AWFormatterHelper::initFormatters()
{ {
m_formattersClasses.clear(); m_formattersClasses.clear();
for (int i = m_directories.count() - 1; i >= 0; i--) { auto dirs = directories();
QStringList files for (auto &dir : dirs) {
= QDir(m_directories.at(i)).entryList(QDir::Files, QDir::Name); QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name);
for (auto &file : files) { for (auto &file : files) {
// check filename
if (!file.endsWith(".desktop")) if (!file.endsWith(".desktop"))
continue; continue;
qCInfo(LOG_AW) << "Found file" << file << "in" qCInfo(LOG_AW) << "Found file" << file << "in" << dir;
<< m_directories.at(i); QString filePath = QString("%1/%2").arg(dir).arg(file);
QString filePath // check if already exists
= QString("%1/%2").arg(m_directories.at(i)).arg(file); auto values = m_formattersClasses.values();
auto metadata = readMetadata(filePath); if (std::any_of(values.cbegin(), values.cend(),
QString name = metadata.first; [&filePath](const AWAbstractFormatter *item) { return (item->fileName() == filePath); }))
if (m_formattersClasses.contains(name))
continue; continue;
auto metadata = readMetadata(filePath);
switch (metadata.second) { switch (metadata.second) {
case AWAbstractFormatter::FormatterClass::DateTime: case AWAbstractFormatter::FormatterClass::DateTime:
m_formattersClasses[name] m_formattersClasses[metadata.first] = new AWDateTimeFormatter(this, filePath);
= new AWDateTimeFormatter(this, filePath);
break; break;
case AWAbstractFormatter::FormatterClass::Float: case AWAbstractFormatter::FormatterClass::Float:
m_formattersClasses[name] m_formattersClasses[metadata.first] = new AWFloatFormatter(this, filePath);
= new AWFloatFormatter(this, filePath);
break; break;
case AWAbstractFormatter::FormatterClass::List: case AWAbstractFormatter::FormatterClass::List:
m_formattersClasses[name] = new AWListFormatter(this, filePath); m_formattersClasses[metadata.first] = new AWListFormatter(this, filePath);
break; break;
case AWAbstractFormatter::FormatterClass::Script: case AWAbstractFormatter::FormatterClass::Script:
m_formattersClasses[name] m_formattersClasses[metadata.first] = new AWScriptFormatter(this, filePath);
= new AWScriptFormatter(this, filePath);
break; break;
case AWAbstractFormatter::FormatterClass::String: case AWAbstractFormatter::FormatterClass::String:
m_formattersClasses[name] m_formattersClasses[metadata.first] = new AWStringFormatter(this, filePath);
= new AWStringFormatter(this, filePath);
break; break;
case AWAbstractFormatter::FormatterClass::Json: case AWAbstractFormatter::FormatterClass::Json:
m_formattersClasses[name] = new AWJsonFormatter(this, filePath); m_formattersClasses[metadata.first] = new AWJsonFormatter(this, filePath);
break; break;
case AWAbstractFormatter::FormatterClass::NoFormat: case AWAbstractFormatter::FormatterClass::NoFormat:
m_formattersClasses[name] = new AWNoFormatter(this, filePath); m_formattersClasses[metadata.first] = new AWNoFormatter(this, filePath);
break; break;
} }
} }
@ -231,57 +194,7 @@ void AWFormatterHelper::initFormatters()
} }
void AWFormatterHelper::initKeys() QPair<QString, AWAbstractFormatter::FormatterClass> AWFormatterHelper::readMetadata(const QString &_filePath)
{
m_formatters.clear();
QStringList configs = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation, m_filePath);
for (auto &fileName : configs) {
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup("Formatters");
QStringList keys = settings.childKeys();
for (auto &key : keys) {
QString name = settings.value(key).toString();
qCInfo(LOG_AW) << "Found formatter" << name << "for key" << key
<< "in" << settings.fileName();
if (name.isEmpty()) {
qCInfo(LOG_AW) << "Skip empty formatter for" << key;
continue;
}
if (!m_formattersClasses.contains(name)) {
qCWarning(LOG_AW)
<< "Invalid formatter" << name << "found in" << key;
continue;
}
m_formatters[key] = m_formattersClasses[name];
}
settings.endGroup();
}
}
void AWFormatterHelper::installDirectories()
{
// create directory at $HOME
QString localDir = QString("%1/awesomewidgets/formatters")
.arg(QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation));
QDir localDirectory;
if (localDirectory.mkpath(localDir))
qCInfo(LOG_AW) << "Created directory" << localDir;
m_directories = QStandardPaths::locateAll(
QStandardPaths::GenericDataLocation, "awesomewidgets/formatters",
QStandardPaths::LocateDirectory);
}
QPair<QString, AWAbstractFormatter::FormatterClass>
AWFormatterHelper::readMetadata(const QString &_filePath) const
{ {
qCDebug(LOG_AW) << "Read initial parameters from" << _filePath; qCDebug(LOG_AW) << "Read initial parameters from" << _filePath;
@ -298,24 +211,16 @@ AWFormatterHelper::readMetadata(const QString &_filePath) const
void AWFormatterHelper::doCreateItem() void AWFormatterHelper::doCreateItem()
{ {
QStringList selection = QStringList() << "NoFormat" QStringList selection = {"NoFormat", "DateTime", "Float", "List", "Script", "String", "Json"};
<< "DateTime"
<< "Float"
<< "List"
<< "Script"
<< "String"
<< "Json";
bool ok; bool ok;
QString select = QInputDialog::getItem( QString select = QInputDialog::getItem(this, i18n("Select type"), i18n("Type:"), selection, 0, false, &ok);
this, i18n("Select type"), i18n("Type:"), selection, 0, false, &ok);
if (!ok) { if (!ok) {
qCWarning(LOG_AW) << "No type selected"; qCWarning(LOG_AW) << "No type selected";
return; return;
} }
qCInfo(LOG_AW) << "Selected type" << select; qCInfo(LOG_AW) << "Selected type" << select;
AWAbstractFormatter::FormatterClass formatter AWAbstractFormatter::FormatterClass formatter = defineFormatterClass(select);
= defineFormatterClass(select);
switch (formatter) { switch (formatter) {
case AWAbstractFormatter::FormatterClass::DateTime: case AWAbstractFormatter::FormatterClass::DateTime:
return createItem<AWDateTimeFormatter>(); return createItem<AWDateTimeFormatter>();
@ -333,11 +238,3 @@ void AWFormatterHelper::doCreateItem()
return createItem<AWNoFormatter>(); return createItem<AWNoFormatter>();
} }
} }
void AWFormatterHelper::initItems()
{
installDirectories();
initFormatters();
initKeys();
}

View File

@ -20,45 +20,39 @@
#define AWFORMATTERHELPER_H #define AWFORMATTERHELPER_H
#include "abstractextitemaggregator.h" #include "abstractextitemaggregator.h"
#include "awabstractformatter.h" #include "awabstractformatter.h"
#include "awabstractpairhelper.h"
class AWAbstractFormatter; class AWFormatterHelper : public AbstractExtItemAggregator, public AWAbstractPairHelper
class AWFormatterHelper : public AbstractExtItemAggregator
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit AWFormatterHelper(QWidget *_parent = nullptr); explicit AWFormatterHelper(QWidget *_parent = nullptr);
virtual ~AWFormatterHelper(); ~AWFormatterHelper() override;
QString convert(const QVariant &_value, const QString &_name) const; // read-write methods
QStringList definedFormatters() const; void initItems() override;
QHash<QString, QString> getFormatters() const; // methods
QList<AbstractExtItem *> items() const; [[nodiscard]] QString convert(const QVariant &_value, const QString &_name) const;
QStringList knownFormatters() const; [[nodiscard]] QStringList definedFormatters() const;
bool removeUnusedFormatters(const QStringList &_keys) const; [[nodiscard]] QList<AbstractExtItem *> items() const override;
bool writeFormatters(const QHash<QString, QString> &_configuration) const; // configuration related
void editPairs() override;
QStringList leftKeys() override;
QStringList rightKeys() override;
public slots: public slots:
void editItems(); void editItems();
private: private:
// methods // methods
AWAbstractFormatter::FormatterClass static AWAbstractFormatter::FormatterClass defineFormatterClass(const QString &_stringType);
defineFormatterClass(const QString &_stringType) const;
void initFormatters(); void initFormatters();
void initKeys(); [[nodiscard]] static QPair<QString, AWAbstractFormatter::FormatterClass> readMetadata(const QString &_filePath);
void installDirectories();
QPair<QString, AWAbstractFormatter::FormatterClass>
readMetadata(const QString &_filePath) const;
// parent methods // parent methods
void doCreateItem(); void doCreateItem() override;
void initItems();
// properties // properties
QStringList m_directories;
QString m_filePath;
QHash<QString, AWAbstractFormatter *> m_formatters; QHash<QString, AWAbstractFormatter *> m_formatters;
QHash<QString, AWAbstractFormatter *> m_formattersClasses; QHash<QString, AWAbstractFormatter *> m_formattersClasses;
}; };

View File

@ -15,11 +15,11 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/ ***************************************************************************/
#include "awkeycache.h" #include "awkeycache.h"
#include <QDir> #include <QDir>
#include <QNetworkInterface> #include <QNetworkInterface>
#include <QRegExp>
#include <QSettings> #include <QSettings>
#include <QStandardPaths> #include <QStandardPaths>
@ -30,9 +30,8 @@ bool AWKeyCache::addKeyToCache(const QString &_type, const QString &_key)
{ {
qCDebug(LOG_AW) << "Key" << _key << "with type" << _type; qCDebug(LOG_AW) << "Key" << _key << "with type" << _type;
QString fileName = QString("%1/awesomewidgets.ndx") QString fileName
.arg(QStandardPaths::writableLocation( = QString("%1/awesomewidgets.ndx").arg(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
QStandardPaths::GenericCacheLocation));
qCInfo(LOG_AW) << "Cache file" << fileName; qCInfo(LOG_AW) << "Cache file" << fileName;
QSettings cache(fileName, QSettings::IniFormat); QSettings cache(fileName, QSettings::IniFormat);
@ -42,8 +41,7 @@ bool AWKeyCache::addKeyToCache(const QString &_type, const QString &_key)
cachedValues.append(cache.value(number).toString()); cachedValues.append(cache.value(number).toString());
if (_type == "hdd") { if (_type == "hdd") {
QStringList allDevices QStringList allDevices = QDir("/dev").entryList(QDir::System, QDir::Name);
= QDir("/dev").entryList(QDir::System, QDir::Name);
QStringList devices = allDevices.filter(QRegExp("^[hms]d[a-z]$")); QStringList devices = allDevices.filter(QRegExp("^[hms]d[a-z]$"));
for (auto &dev : devices) { for (auto &dev : devices) {
QString device = QString("/dev/%1").arg(dev); QString device = QString("/dev/%1").arg(dev);
@ -51,30 +49,23 @@ bool AWKeyCache::addKeyToCache(const QString &_type, const QString &_key)
continue; continue;
qCInfo(LOG_AW) << "Found new key" << device << "for type" << _type; qCInfo(LOG_AW) << "Found new key" << device << "for type" << _type;
cachedValues.append(device); cachedValues.append(device);
cache.setValue( cache.setValue(QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), device);
QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')),
device);
} }
} else if (_type == "net") { } else if (_type == "net") {
QList<QNetworkInterface> rawInterfaceList QList<QNetworkInterface> rawInterfaceList = QNetworkInterface::allInterfaces();
= QNetworkInterface::allInterfaces();
for (auto &interface : rawInterfaceList) { for (auto &interface : rawInterfaceList) {
QString device = interface.name(); QString device = interface.name();
if (cachedValues.contains(device)) if (cachedValues.contains(device))
continue; continue;
qCInfo(LOG_AW) << "Found new key" << device << "for type" << _type; qCInfo(LOG_AW) << "Found new key" << device << "for type" << _type;
cachedValues.append(device); cachedValues.append(device);
cache.setValue( cache.setValue(QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), device);
QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')),
device);
} }
} else { } else {
if (cachedValues.contains(_key)) if (cachedValues.contains(_key))
return false; return false;
qCInfo(LOG_AW) << "Found new key" << _key << "for type" << _type; qCInfo(LOG_AW) << "Found new key" << _key << "for type" << _type;
cache.setValue( cache.setValue(QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), _key);
QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')),
_key);
} }
cache.endGroup(); cache.endGroup();
@ -83,17 +74,15 @@ bool AWKeyCache::addKeyToCache(const QString &_type, const QString &_key)
} }
QStringList AWKeyCache::getRequiredKeys(const QStringList &_keys, QStringList AWKeyCache::getRequiredKeys(const QStringList &_keys, const QStringList &_bars, const QVariantMap &_tooltip,
const QStringList &_bars, const QStringList &_userKeys, const QStringList &_allKeys)
const QVariantMap &_tooltip,
const QStringList &_allKeys)
{ {
qCDebug(LOG_AW) << "Looking for required keys in" << _keys << _bars qCDebug(LOG_AW) << "Looking for required keys in" << _keys << _bars << "using tooltip settings" << _tooltip;
<< "using tooltip settings" << _tooltip;
// initial copy // initial copy
QSet<QString> used = QSet<QString>::fromList(_keys); QSet<QString> used(_keys.cbegin(), _keys.cend());
used.unite(QSet<QString>::fromList(_bars)); used.unite(QSet(_bars.cbegin(), _bars.cend()));
used.unite(QSet(_userKeys.cbegin(), _userKeys.cend()));
// insert keys from tooltip // insert keys from tooltip
for (auto &key : _tooltip.keys()) { for (auto &key : _tooltip.keys()) {
if ((key.endsWith("Tooltip")) && (_tooltip[key].toBool())) { if ((key.endsWith("Tooltip")) && (_tooltip[key].toBool())) {
@ -109,8 +98,7 @@ QStringList AWKeyCache::getRequiredKeys(const QStringList &_keys,
continue; continue;
key.remove("hddtotmb"); key.remove("hddtotmb");
int index = key.toInt(); int index = key.toInt();
used << QString("hddfreemb%1").arg(index) used << QString("hddfreemb%1").arg(index) << QString("hddmb%1").arg(index);
<< QString("hddmb%1").arg(index);
} }
// hddtotgb* // hddtotgb*
for (auto &key : _allKeys.filter(QRegExp("^hddtotgb"))) { for (auto &key : _allKeys.filter(QRegExp("^hddtotgb"))) {
@ -118,8 +106,7 @@ QStringList AWKeyCache::getRequiredKeys(const QStringList &_keys,
continue; continue;
key.remove("hddtotgb"); key.remove("hddtotgb");
int index = key.toInt(); int index = key.toInt();
used << QString("hddfreegb%1").arg(index) used << QString("hddfreegb%1").arg(index) << QString("hddgb%1").arg(index);
<< QString("hddgb%1").arg(index);
} }
// mem // mem
if (used.contains("mem")) if (used.contains("mem"))
@ -146,20 +133,17 @@ QStringList AWKeyCache::getRequiredKeys(const QStringList &_keys,
used << "swapgb" used << "swapgb"
<< "swapfreegb"; << "swapfreegb";
// network keys // network keys
QStringList netKeys({"up", "upkb", "uptotal", "uptotalkb", "upunits", QStringList netKeys(
"down", "downkb", "downtotal", "downtotalkb", {"up", "upkb", "uptot", "uptotkb", "upunits", "down", "downkb", "downtot", "downtotkb", "downunits"});
"downunits"});
for (auto &key : netKeys) { for (auto &key : netKeys) {
if (!used.contains(key)) if (!used.contains(key))
continue; continue;
QStringList filt QStringList filt = _allKeys.filter(QRegExp(QString("^%1[0-9]{1,}").arg(key)));
= _allKeys.filter(QRegExp(QString("^%1[0-9]{1,}").arg(key)));
for (auto &filtered : filt) for (auto &filtered : filt)
used << filtered; used << filtered;
} }
// netdev key // netdev key
if (std::any_of(netKeys.cbegin(), netKeys.cend(), if (std::any_of(netKeys.cbegin(), netKeys.cend(), [&used](const QString &key) { return used.contains(key); }))
[&used](const QString &key) { return used.contains(key); }))
used << "netdev"; used << "netdev";
// HACK append dummy if there are no other keys. This hack is required // HACK append dummy if there are no other keys. This hack is required
@ -167,15 +151,14 @@ QStringList AWKeyCache::getRequiredKeys(const QStringList &_keys,
if (used.isEmpty()) if (used.isEmpty())
used << "dummy"; used << "dummy";
return used.toList(); return used.values();
} }
QHash<QString, QStringList> AWKeyCache::loadKeysFromCache() QHash<QString, QStringList> AWKeyCache::loadKeysFromCache()
{ {
QString fileName = QString("%1/awesomewidgets.ndx") QString fileName
.arg(QStandardPaths::writableLocation( = QString("%1/awesomewidgets.ndx").arg(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
QStandardPaths::GenericCacheLocation));
qCInfo(LOG_AW) << "Cache file" << fileName; qCInfo(LOG_AW) << "Cache file" << fileName;
QSettings cache(fileName, QSettings::IniFormat); QSettings cache(fileName, QSettings::IniFormat);

View File

@ -27,11 +27,10 @@
namespace AWKeyCache namespace AWKeyCache
{ {
bool addKeyToCache(const QString &_type, const QString &_key = ""); bool addKeyToCache(const QString &_type, const QString &_key = "");
QStringList getRequiredKeys(const QStringList &_keys, const QStringList &_bars, QStringList getRequiredKeys(const QStringList &_keys, const QStringList &_bars, const QVariantMap &_tooltip,
const QVariantMap &_tooltip, const QStringList &_userKeys, const QStringList &_allKeys);
const QStringList &_allKeys);
QHash<QString, QStringList> loadKeysFromCache(); QHash<QString, QStringList> loadKeysFromCache();
}; } // namespace AWKeyCache
#endif /* AWKEYCACHE_H */ #endif /* AWKEYCACHE_H */

View File

@ -18,10 +18,10 @@
#include "awkeyoperations.h" #include "awkeyoperations.h"
#include <QDir> #include <QDir>
#include <QJSEngine>
#include <QRegExp> #include <QRegExp>
#include <QThread> #include <QThread>
#include "awcustomkeyshelper.h"
#include "awdebug.h" #include "awdebug.h"
#include "awkeycache.h" #include "awkeycache.h"
#include "awpatternfunctions.h" #include "awpatternfunctions.h"
@ -38,20 +38,20 @@ AWKeyOperations::AWKeyOperations(QObject *_parent)
: QObject(_parent) : QObject(_parent)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_customKeys = new AWCustomKeysHelper(this);
m_graphicalItems = new ExtItemAggregator<GraphicalItem>(nullptr, "desktops");
m_extNetRequest = new ExtItemAggregator<ExtNetworkRequest>(nullptr, "requests");
m_extQuotes = new ExtItemAggregator<ExtQuotes>(nullptr, "quotes");
m_extScripts = new ExtItemAggregator<ExtScript>(nullptr, "scripts");
m_extUpgrade = new ExtItemAggregator<ExtUpgrade>(nullptr, "upgrade");
m_extWeather = new ExtItemAggregator<ExtWeather>(nullptr, "weather");
} }
AWKeyOperations::~AWKeyOperations() AWKeyOperations::~AWKeyOperations()
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
// extensions
delete m_graphicalItems;
delete m_extNetRequest;
delete m_extQuotes;
delete m_extScripts;
delete m_extUpgrade;
delete m_extWeather;
} }
@ -119,36 +119,37 @@ QStringList AWKeyOperations::dictKeys() const
for (int i = 0; i < m_devices["net"].count(); i++) { for (int i = 0; i < m_devices["net"].count(); i++) {
allKeys.append(QString("downunits%1").arg(i)); allKeys.append(QString("downunits%1").arg(i));
allKeys.append(QString("upunits%1").arg(i)); allKeys.append(QString("upunits%1").arg(i));
allKeys.append(QString("downtotalkb%1").arg(i)); allKeys.append(QString("downtotkb%1").arg(i));
allKeys.append(QString("downtotal%1").arg(i)); allKeys.append(QString("downtot%1").arg(i));
allKeys.append(QString("downkb%1").arg(i)); allKeys.append(QString("downkb%1").arg(i));
allKeys.append(QString("down%1").arg(i)); allKeys.append(QString("down%1").arg(i));
allKeys.append(QString("uptotalkb%1").arg(i)); allKeys.append(QString("uptotkb%1").arg(i));
allKeys.append(QString("uptotal%1").arg(i)); allKeys.append(QString("uptot%1").arg(i));
allKeys.append(QString("upkb%1").arg(i)); allKeys.append(QString("upkb%1").arg(i));
allKeys.append(QString("up%1").arg(i)); allKeys.append(QString("up%1").arg(i));
} }
// battery // battery
QStringList allBatteryDevices QStringList allBatteryDevices
= QDir("/sys/class/power_supply") = QDir("/sys/class/power_supply")
.entryList(QStringList({"BAT*"}), .entryList(QStringList({"BAT*"}), QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); for (int i = 0; i < allBatteryDevices.count(); i++) {
for (int i = 0; i < allBatteryDevices.count(); i++)
allKeys.append(QString("bat%1").arg(i)); allKeys.append(QString("bat%1").arg(i));
allKeys.append(QString("batleft%1").arg(i));
allKeys.append(QString("batnow%1").arg(i));
allKeys.append(QString("batrate%1").arg(i));
allKeys.append(QString("battotal%1").arg(i));
}
// package manager // package manager
for (auto &item : m_extUpgrade->activeItems()) for (auto &item : m_extUpgrade->activeItems())
allKeys.append(item->tag("pkgcount")); allKeys.append(item->tag("pkgcount"));
// quotes // quotes
for (auto &item : m_extQuotes->activeItems()) { for (auto &item : m_extQuotes->activeItems()) {
allKeys.append(item->tag("ask"));
allKeys.append(item->tag("askchg"));
allKeys.append(item->tag("percaskchg"));
allKeys.append(item->tag("bid"));
allKeys.append(item->tag("bidchg"));
allKeys.append(item->tag("percbidchg"));
allKeys.append(item->tag("price")); allKeys.append(item->tag("price"));
allKeys.append(item->tag("pricechg")); allKeys.append(item->tag("pricechg"));
allKeys.append(item->tag("percpricechg")); allKeys.append(item->tag("percpricechg"));
allKeys.append(item->tag("volume"));
allKeys.append(item->tag("volumechg"));
allKeys.append(item->tag("percvolumechg"));
} }
// custom // custom
for (auto &item : m_extScripts->activeItems()) for (auto &item : m_extScripts->activeItems())
@ -159,6 +160,8 @@ QStringList AWKeyOperations::dictKeys() const
// bars // bars
for (auto &item : m_graphicalItems->activeItems()) for (auto &item : m_graphicalItems->activeItems())
allKeys.append(item->tag("bar")); allKeys.append(item->tag("bar"));
// user defined keys
allKeys.append(m_customKeys->keys());
// static keys // static keys
allKeys.append(QString(STATIC_KEYS).split(',')); allKeys.append(QString(STATIC_KEYS).split(','));
@ -180,6 +183,24 @@ GraphicalItem *AWKeyOperations::giByKey(const QString &_key) const
} }
QStringList AWKeyOperations::requiredUserKeys() const
{
return m_customKeys->refinedSources();
}
QStringList AWKeyOperations::userKeys() const
{
return m_customKeys->keys();
}
QString AWKeyOperations::userKeySource(const QString &_key) const
{
return m_customKeys->source(_key);
}
QString AWKeyOperations::infoByKey(const QString &_key) const QString AWKeyOperations::infoByKey(const QString &_key) const
{ {
qCDebug(LOG_AW) << "Requested key" << _key; qCDebug(LOG_AW) << "Requested key" << _key;
@ -200,8 +221,7 @@ QString AWKeyOperations::infoByKey(const QString &_key) const
QString index = _key; QString index = _key;
index.remove(QRegExp("hdd[rw]")); index.remove(QRegExp("hdd[rw]"));
output = m_devices["disk"][index.toInt()]; output = m_devices["disk"][index.toInt()];
} else if (_key.contains( } else if (_key.contains(QRegExp("^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)"))) {
QRegExp("^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)"))) {
QString index = _key; QString index = _key;
index.remove(QRegExp("^hdd(|mb|gb|freemb|freegb|totmb|totgb)")); index.remove(QRegExp("^hdd(|mb|gb|freemb|freegb|totmb|totgb)"));
output = m_devices["mount"][index.toInt()]; output = m_devices["mount"][index.toInt()];
@ -221,8 +241,7 @@ QString AWKeyOperations::infoByKey(const QString &_key) const
AbstractExtItem *item = m_extQuotes->itemByTag(_key, stripped); AbstractExtItem *item = m_extQuotes->itemByTag(_key, stripped);
if (item) if (item)
output = item->uniq(); output = item->uniq();
} else if (_key.contains(QRegExp( } else if (_key.contains(QRegExp("(weather|weatherId|humidity|pressure|temperature)"))) {
"(weather|weatherId|humidity|pressure|temperature)"))) {
AbstractExtItem *item = m_extWeather->itemByTag(_key, stripped); AbstractExtItem *item = m_extWeather->itemByTag(_key, stripped);
if (item) if (item)
output = item->uniq(); output = item->uniq();
@ -261,8 +280,7 @@ void AWKeyOperations::editItem(const QString &_type)
qCDebug(LOG_AW) << "Item type" << _type; qCDebug(LOG_AW) << "Item type" << _type;
if (_type == "graphicalitem") { if (_type == "graphicalitem") {
QStringList keys = dictKeys().filter( QStringList keys = dictKeys().filter(QRegExp("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)"));
QRegExp("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)"));
keys.sort(); keys.sort();
m_graphicalItems->setConfigArgs(keys); m_graphicalItems->setConfigArgs(keys);
return m_graphicalItems->editItems(); return m_graphicalItems->editItems();
@ -314,29 +332,13 @@ void AWKeyOperations::addKeyToCache(const QString &_type, const QString &_key)
void AWKeyOperations::reinitKeys() void AWKeyOperations::reinitKeys()
{ {
// renew extensions m_customKeys->initItems();
// delete them if any m_graphicalItems->initItems();
delete m_graphicalItems; m_extNetRequest->initItems();
m_graphicalItems = nullptr; m_extQuotes->initItems();
delete m_extNetRequest; m_extScripts->initItems();
m_extNetRequest = nullptr; m_extUpgrade->initItems();
delete m_extQuotes; m_extWeather->initItems();
m_extQuotes = nullptr;
delete m_extScripts;
m_extScripts = nullptr;
delete m_extUpgrade;
m_extUpgrade = nullptr;
delete m_extWeather;
m_extWeather = nullptr;
// create
m_graphicalItems
= new ExtItemAggregator<GraphicalItem>(nullptr, "desktops");
m_extNetRequest
= new ExtItemAggregator<ExtNetworkRequest>(nullptr, "requests");
m_extQuotes = new ExtItemAggregator<ExtQuotes>(nullptr, "quotes");
m_extScripts = new ExtItemAggregator<ExtScript>(nullptr, "scripts");
m_extUpgrade = new ExtItemAggregator<ExtUpgrade>(nullptr, "upgrade");
m_extWeather = new ExtItemAggregator<ExtWeather>(nullptr, "weather");
// init // init
QStringList allKeys = dictKeys(); QStringList allKeys = dictKeys();

View File

@ -19,24 +19,18 @@
#ifndef AWKEYOPERATIONS_H #ifndef AWKEYOPERATIONS_H
#define AWKEYOPERATIONS_H #define AWKEYOPERATIONS_H
#include <Plasma/DataEngine>
#include <QMutex>
#include <QObject> #include <QObject>
#include "extitemaggregator.h" #include "extitemaggregator.h"
class AWDataAggregator; class AWCustomKeysHelper;
class AWDataEngineAggregator;
class AWKeysAggregator;
class ExtNetworkRequest; class ExtNetworkRequest;
class ExtQuotes; class ExtQuotes;
class ExtScript; class ExtScript;
class ExtUpgrade; class ExtUpgrade;
class ExtWeather; class ExtWeather;
class GraphicalItem; class GraphicalItem;
class QThreadPool;
class AWKeyOperations : public QObject class AWKeyOperations : public QObject
{ {
@ -45,16 +39,19 @@ class AWKeyOperations : public QObject
public: public:
explicit AWKeyOperations(QObject *_parent = nullptr); explicit AWKeyOperations(QObject *_parent = nullptr);
virtual ~AWKeyOperations(); ~AWKeyOperations() override;
QStringList devices(const QString &_type) const; [[nodiscard]] QStringList devices(const QString &_type) const;
QHash<QString, QStringList> devices() const; [[nodiscard]] QHash<QString, QStringList> devices() const;
void updateCache(); void updateCache();
// keys // keys
QStringList dictKeys() const; [[nodiscard]] QStringList dictKeys() const;
GraphicalItem *giByKey(const QString &_key) const; [[nodiscard]] GraphicalItem *giByKey(const QString &_key) const;
[[nodiscard]] QStringList requiredUserKeys() const;
[[nodiscard]] QStringList userKeys() const;
[[nodiscard]] QString userKeySource(const QString &_key) const;
// values // values
QString infoByKey(const QString &_key) const; [[nodiscard]] QString infoByKey(const QString &_key) const;
QString pattern() const; [[nodiscard]] QString pattern() const;
void setPattern(const QString &_currentPattern); void setPattern(const QString &_currentPattern);
// configuration // configuration
void editItem(const QString &_type); void editItem(const QString &_type);
@ -70,6 +67,7 @@ private:
void addKeyToCache(const QString &_type, const QString &_key = ""); void addKeyToCache(const QString &_type, const QString &_key = "");
void reinitKeys(); void reinitKeys();
// objects // objects
AWCustomKeysHelper *m_customKeys = nullptr;
ExtItemAggregator<GraphicalItem> *m_graphicalItems = nullptr; ExtItemAggregator<GraphicalItem> *m_graphicalItems = nullptr;
ExtItemAggregator<ExtNetworkRequest> *m_extNetRequest = nullptr; ExtItemAggregator<ExtNetworkRequest> *m_extNetRequest = nullptr;
ExtItemAggregator<ExtQuotes> *m_extQuotes = nullptr; ExtItemAggregator<ExtQuotes> *m_extQuotes = nullptr;

View File

@ -19,7 +19,6 @@
#include <QDBusConnection> #include <QDBusConnection>
#include <QDBusError> #include <QDBusError>
#include <QRegExp>
#include <QThread> #include <QThread>
#include <QTimer> #include <QTimer>
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
@ -57,17 +56,16 @@ AWKeys::AWKeys(QObject *_parent)
createDBusInterface(); createDBusInterface();
// update key data if required // update key data if required
connect(m_keyOperator, SIGNAL(updateKeys(const QStringList &)), this, connect(m_keyOperator, SIGNAL(updateKeys(const QStringList &)), this, SLOT(reinitKeys(const QStringList &)));
SLOT(reinitKeys(const QStringList &)));
connect(m_timer, SIGNAL(timeout()), this, SLOT(updateTextData())); connect(m_timer, SIGNAL(timeout()), this, SLOT(updateTextData()));
// transfer signal from AWDataAggregator object to QML ui // transfer signal from AWDataAggregator object to QML ui
connect(m_dataAggregator, SIGNAL(toolTipPainted(const QString &)), this, connect(m_dataAggregator, SIGNAL(toolTipPainted(const QString &)), this,
SIGNAL(needToolTipToBeUpdated(const QString &))); SIGNAL(needToolTipToBeUpdated(const QString &)));
connect(this, SIGNAL(dropSourceFromDataengine(const QString &)), connect(this, SIGNAL(dropSourceFromDataengine(const QString &)), m_dataEngineAggregator,
m_dataEngineAggregator, SLOT(dropSource(const QString &))); SLOT(dropSource(const QString &)));
// transfer signal from dataengine to update source list // transfer signal from dataengine to update source list
connect(m_dataEngineAggregator, SIGNAL(deviceAdded(const QString &)), connect(m_dataEngineAggregator, SIGNAL(deviceAdded(const QString &)), m_keyOperator,
m_keyOperator, SLOT(addDevice(const QString &))); SLOT(addDevice(const QString &)));
} }
@ -76,24 +74,9 @@ AWKeys::~AWKeys()
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_timer->stop(); m_timer->stop();
delete m_timer;
// delete dbus session // delete dbus session
qlonglong id = reinterpret_cast<qlonglong>(this); auto id = reinterpret_cast<qlonglong>(this);
QDBusConnection::sessionBus().unregisterObject(QString("/%1").arg(id)); QDBusConnection::sessionBus().unregisterObject(QString("/%1").arg(id));
// core
delete m_dataEngineAggregator;
delete m_threadPool;
delete m_aggregator;
delete m_dataAggregator;
delete m_keyOperator;
}
bool AWKeys::isDBusActive() const
{
return m_dbusActive;
} }
@ -107,23 +90,19 @@ void AWKeys::initDataAggregator(const QVariantMap &_tooltipParams)
} }
void AWKeys::initKeys(const QString &_currentPattern, const int _interval, void AWKeys::initKeys(const QString &_currentPattern, const int _interval, const int _limit, const bool _optimize)
const int _limit, const bool _optimize)
{ {
qCDebug(LOG_AW) << "Pattern" << _currentPattern << "with interval" qCDebug(LOG_AW) << "Pattern" << _currentPattern << "with interval" << _interval << "and queue limit" << _limit
<< _interval << "and queue limit" << _limit
<< "with optimization" << _optimize; << "with optimization" << _optimize;
// init // init
m_optimize = _optimize; m_optimize = _optimize;
m_threadPool->setMaxThreadCount(_limit == 0 ? QThread::idealThreadCount() m_threadPool->setMaxThreadCount(_limit == 0 ? QThread::idealThreadCount() : _limit);
: _limit);
// child objects // child objects
m_aggregator->initFormatters(); m_aggregator->initFormatters();
m_keyOperator->setPattern(_currentPattern); m_keyOperator->setPattern(_currentPattern);
m_keyOperator->updateCache(); m_keyOperator->updateCache();
m_dataEngineAggregator->clear(); m_dataEngineAggregator->reconnectSources(_interval);
m_dataEngineAggregator->initDataEngines(_interval);
// timer // timer
m_timer->setInterval(_interval); m_timer->setInterval(_interval);
@ -155,12 +134,14 @@ void AWKeys::updateCache()
QStringList AWKeys::dictKeys(const bool _sorted, const QString &_regexp) const QStringList AWKeys::dictKeys(const bool _sorted, const QString &_regexp) const
{ {
qCDebug(LOG_AW) << "Should be sorted" << _sorted << "and filter applied" qCDebug(LOG_AW) << "Should be sorted" << _sorted << "and filter applied" << _regexp;
<< _regexp;
// check if functions asked // check if functions asked
if (_regexp == "functions") if (_regexp == "functions")
return QString(STATIC_FUNCTIONS).split(','); return QString(STATIC_FUNCTIONS).split(',');
// check if user defined keys asked
if (_regexp == "userdefined")
return m_keyOperator->userKeys();
QStringList allKeys = m_keyOperator->dictKeys(); QStringList allKeys = m_keyOperator->dictKeys();
// sort if required // sort if required
@ -204,10 +185,9 @@ QString AWKeys::valueByKey(const QString &_key) const
{ {
qCDebug(LOG_AW) << "Requested value for key" << _key; qCDebug(LOG_AW) << "Requested value for key" << _key;
QString trueKey QString trueKey = _key.startsWith("bar") ? m_keyOperator->infoByKey(_key) : _key;
= _key.startsWith("bar") ? m_keyOperator->infoByKey(_key) : _key;
return m_aggregator->formatter(m_values[trueKey], trueKey); return m_aggregator->formatter(m_values[trueKey], trueKey, true);
} }
@ -219,12 +199,10 @@ void AWKeys::editItem(const QString &_type)
} }
void AWKeys::dataUpdated(const QString &_sourceName, void AWKeys::dataUpdated(const QString &_sourceName, const Plasma::DataEngine::Data &_data)
const Plasma::DataEngine::Data &_data)
{ {
// run concurrent data update // run concurrent data update
QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, _sourceName, QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, _sourceName, _data);
_data);
} }
@ -233,27 +211,23 @@ void AWKeys::reinitKeys(const QStringList &_currentKeys)
qCDebug(LOG_AW) << "Update found keys by using list" << _currentKeys; qCDebug(LOG_AW) << "Update found keys by using list" << _currentKeys;
// append lists // append lists
m_foundBars = AWPatternFunctions::findKeys(m_keyOperator->pattern(), m_foundBars = AWPatternFunctions::findKeys(m_keyOperator->pattern(), _currentKeys, true);
_currentKeys, true); m_foundKeys = AWPatternFunctions::findKeys(m_keyOperator->pattern(), _currentKeys, false);
m_foundKeys = AWPatternFunctions::findKeys(m_keyOperator->pattern(),
_currentKeys, false);
m_foundLambdas = AWPatternFunctions::findLambdas(m_keyOperator->pattern()); m_foundLambdas = AWPatternFunctions::findLambdas(m_keyOperator->pattern());
// generate list of required keys for bars // generate list of required keys for bars
QStringList barKeys; QStringList barKeys;
for (auto &bar : m_foundBars) { for (auto &bar : m_foundBars) {
GraphicalItem *item = m_keyOperator->giByKey(bar); GraphicalItem *item = m_keyOperator->giByKey(bar);
if (item->isCustom()) if (item->isCustom())
item->setUsedKeys( item->setUsedKeys(AWPatternFunctions::findKeys(item->bar(), _currentKeys, false));
AWPatternFunctions::findKeys(item->bar(), _currentKeys, false));
else else
item->setUsedKeys(QStringList() << item->bar()); item->setUsedKeys(QStringList() << item->bar());
barKeys.append(item->usedKeys()); barKeys.append(item->usedKeys());
} }
// get required keys // get required keys
m_requiredKeys m_requiredKeys = m_optimize ? AWKeyCache::getRequiredKeys(m_foundKeys, barKeys, m_tooltipParams,
= m_optimize ? AWKeyCache::getRequiredKeys( m_keyOperator->requiredUserKeys(), _currentKeys)
m_foundKeys, barKeys, m_tooltipParams, _currentKeys) : QStringList();
: QStringList();
// set key data to m_aggregator // set key data to m_aggregator
m_aggregator->setDevices(m_keyOperator->devices()); m_aggregator->setDevices(m_keyOperator->devices());
@ -266,10 +240,11 @@ void AWKeys::updateTextData()
m_mutex.lock(); m_mutex.lock();
calculateValues(); calculateValues();
QString text = parsePattern(m_keyOperator->pattern()); QString text = parsePattern(m_keyOperator->pattern());
// update tooltip values under lock
m_dataAggregator->dataUpdate(m_values);
m_mutex.unlock(); m_mutex.unlock();
emit(needTextToBeUpdated(text)); emit(needTextToBeUpdated(text));
emit(m_dataAggregator->updateData(m_values));
} }
@ -282,70 +257,66 @@ void AWKeys::calculateValues()
for (auto &device : mountDevices) { for (auto &device : mountDevices) {
int index = mountDevices.indexOf(device); int index = mountDevices.indexOf(device);
m_values[QString("hddtotmb%1").arg(index)] m_values[QString("hddtotmb%1").arg(index)]
= m_values[QString("hddfreemb%1").arg(index)].toFloat() = m_values[QString("hddfreemb%1").arg(index)].toFloat() + m_values[QString("hddmb%1").arg(index)].toFloat();
+ m_values[QString("hddmb%1").arg(index)].toFloat();
m_values[QString("hddtotgb%1").arg(index)] m_values[QString("hddtotgb%1").arg(index)]
= m_values[QString("hddfreegb%1").arg(index)].toFloat() = m_values[QString("hddfreegb%1").arg(index)].toFloat() + m_values[QString("hddgb%1").arg(index)].toFloat();
+ m_values[QString("hddgb%1").arg(index)].toFloat();
} }
// memtot* // memtot*
m_values["memtotmb"] m_values["memtotmb"] = m_values["memusedmb"].toInt() + m_values["memfreemb"].toInt();
= m_values["memusedmb"].toInt() + m_values["memfreemb"].toInt(); m_values["memtotgb"] = m_values["memusedgb"].toFloat() + m_values["memfreegb"].toFloat();
m_values["memtotgb"]
= m_values["memusedgb"].toFloat() + m_values["memfreegb"].toFloat();
// mem // mem
m_values["mem"] m_values["mem"] = 100.0f * m_values["memmb"].toFloat() / m_values["memtotmb"].toFloat();
= 100.0f * m_values["memmb"].toFloat() / m_values["memtotmb"].toFloat();
// up, down, upkb, downkb, upunits, downunits // up, down, upkb, downkb, upunits, downunits
int netIndex int netIndex = m_keyOperator->devices("net").indexOf(m_values["netdev"].toString());
= m_keyOperator->devices("net").indexOf(m_values["netdev"].toString());
m_values["down"] = m_values[QString("down%1").arg(netIndex)]; m_values["down"] = m_values[QString("down%1").arg(netIndex)];
m_values["downkb"] = m_values[QString("downkb%1").arg(netIndex)]; m_values["downkb"] = m_values[QString("downkb%1").arg(netIndex)];
m_values["downtotal"] = m_values[QString("downtotal%1").arg(netIndex)]; m_values["downtot"] = m_values[QString("downtot%1").arg(netIndex)];
m_values["downtotalkb"] = m_values[QString("downtotalkb%1").arg(netIndex)]; m_values["downtotkb"] = m_values[QString("downtotkb%1").arg(netIndex)];
m_values["downunits"] = m_values[QString("downunits%1").arg(netIndex)]; m_values["downunits"] = m_values[QString("downunits%1").arg(netIndex)];
m_values["up"] = m_values[QString("up%1").arg(netIndex)]; m_values["up"] = m_values[QString("up%1").arg(netIndex)];
m_values["upkb"] = m_values[QString("upkb%1").arg(netIndex)]; m_values["upkb"] = m_values[QString("upkb%1").arg(netIndex)];
m_values["uptotal"] = m_values[QString("uptotal%1").arg(netIndex)]; m_values["uptot"] = m_values[QString("uptot%1").arg(netIndex)];
m_values["uptotalkb"] = m_values[QString("uptotalkb%1").arg(netIndex)]; m_values["uptotkb"] = m_values[QString("uptotkb%1").arg(netIndex)];
m_values["upunits"] = m_values[QString("upunits%1").arg(netIndex)]; m_values["upunits"] = m_values[QString("upunits%1").arg(netIndex)];
// swaptot* // swaptot*
m_values["swaptotmb"] m_values["swaptotmb"] = m_values["swapmb"].toInt() + m_values["swapfreemb"].toInt();
= m_values["swapmb"].toInt() + m_values["swapfreemb"].toInt(); m_values["swaptotgb"] = m_values["swapgb"].toFloat() + m_values["swapfreegb"].toFloat();
m_values["swaptotgb"]
= m_values["swapgb"].toFloat() + m_values["swapfreegb"].toFloat();
// swap // swap
m_values["swap"] = 100.0f * m_values["swapmb"].toFloat() m_values["swap"] = 100.0f * m_values["swapmb"].toFloat() / m_values["swaptotmb"].toFloat();
/ m_values["swaptotmb"].toFloat();
// user defined keys
for (auto &key : m_keyOperator->userKeys())
m_values[key] = m_values[m_keyOperator->userKeySource(key)];
// lambdas // lambdas
for (auto &key : m_foundLambdas) for (auto &key : m_foundLambdas)
m_values[key] = AWPatternFunctions::expandLambdas( m_values[key] = AWPatternFunctions::expandLambdas(key, m_aggregator, m_values, m_foundKeys);
key, m_aggregator, m_values, m_foundKeys);
} }
void AWKeys::createDBusInterface() void AWKeys::createDBusInterface()
{ {
// get this object id // get this object id
qlonglong id = reinterpret_cast<qlonglong>(this); auto id = reinterpret_cast<qlonglong>(this);
// create session // create session
QDBusConnection bus = QDBusConnection::sessionBus(); QDBusConnection instanceBus = QDBusConnection::sessionBus();
if (!bus.registerService(AWDBUS_SERVICE)) // HACK we are going to use different services because it binds to
qCWarning(LOG_AW) << "Could not register DBus service, last error" // application
<< bus.lastError().message(); if (instanceBus.registerService(QString("%1.i%2").arg(AWDBUS_SERVICE).arg(id))) {
if (!bus.registerObject(QString("/%1").arg(id), new AWDBusAdaptor(this), if (!instanceBus.registerObject(AWDBUS_PATH, new AWDBusAdaptor(this), QDBusConnection::ExportAllContents))
QDBusConnection::ExportAllContents)) { qCWarning(LOG_AW) << "Could not register DBus object, last error" << instanceBus.lastError().message();
qCWarning(LOG_AW) << "Could not register DBus object, last error"
<< bus.lastError().message();
m_dbusActive = false;
} else { } else {
m_dbusActive = true; qCWarning(LOG_AW) << "Could not register DBus service, last error" << instanceBus.lastError().message();
} }
// and same instance but for id independent service
QDBusConnection commonBus = QDBusConnection::sessionBus();
if (commonBus.registerService(AWDBUS_SERVICE))
commonBus.registerObject(AWDBUS_PATH, new AWDBusAdaptor(this), QDBusConnection::ExportAllContents);
} }
@ -360,23 +331,14 @@ QString AWKeys::parsePattern(QString _pattern) const
// main keys // main keys
for (auto &key : m_foundKeys) for (auto &key : m_foundKeys)
_pattern.replace( _pattern.replace(QString("$%1").arg(key), m_aggregator->formatter(m_values[key], key, true));
QString("$%1").arg(key),
[this](const QString &tag, const QVariant &value) {
QString strValue = m_aggregator->formatter(value, tag);
if ((!tag.startsWith("custom")) && (!tag.startsWith("weather")))
strValue.replace(" ", "&nbsp;");
return strValue;
}(key, m_values[key]));
// bars // bars
for (auto &bar : m_foundBars) { for (auto &bar : m_foundBars) {
GraphicalItem *item = m_keyOperator->giByKey(bar); GraphicalItem *item = m_keyOperator->giByKey(bar);
QString image QString image = item->isCustom() ? item->image(
= item->isCustom() AWPatternFunctions::expandLambdas(item->bar(), m_aggregator, m_values, item->usedKeys()))
? item->image(AWPatternFunctions::expandLambdas( : item->image(m_values[item->bar()]);
item->bar(), m_aggregator, m_values, item->usedKeys()))
: item->image(m_values[item->bar()]);
_pattern.replace(QString("$%1").arg(bar), image); _pattern.replace(QString("$%1").arg(bar), image);
} }
@ -389,16 +351,14 @@ QString AWKeys::parsePattern(QString _pattern) const
} }
void AWKeys::setDataBySource(const QString &_sourceName, void AWKeys::setDataBySource(const QString &_sourceName, const QVariantMap &_data)
const QVariantMap &_data)
{ {
qCDebug(LOG_AW) << "Source" << _sourceName << "with data" << _data; qCDebug(LOG_AW) << "Source" << _sourceName << "with data" << _data;
// first list init // first list init
QStringList tags = m_aggregator->keysFromSource(_sourceName); QStringList tags = m_aggregator->keysFromSource(_sourceName);
if (tags.isEmpty()) if (tags.isEmpty())
tags = m_aggregator->registerSource( tags = m_aggregator->registerSource(_sourceName, _data["units"].toString(), m_requiredKeys);
_sourceName, _data["units"].toString(), m_requiredKeys);
// update data or drop source if there are no matches and exit // update data or drop source if there are no matches and exit
if (tags.isEmpty()) { if (tags.isEmpty()) {
@ -408,10 +368,8 @@ void AWKeys::setDataBySource(const QString &_sourceName,
m_mutex.lock(); m_mutex.lock();
// HACK workaround for time values which are stored in the different path // HACK workaround for time values which are stored in the different path
std::for_each(tags.cbegin(), tags.cend(), std::for_each(tags.cbegin(), tags.cend(), [this, &_data, &_sourceName](const QString &tag) {
[this, &_data, &_sourceName](const QString &tag) { m_values[tag] = _sourceName == "Local" ? _data["DateTime"] : _data["value"];
m_values[tag] = _sourceName == "Local" ? _data["DateTime"] });
: _data["value"];
});
m_mutex.unlock(); m_mutex.unlock();
} }

View File

@ -38,33 +38,27 @@ class AWKeys : public QObject
public: public:
explicit AWKeys(QObject *_parent = nullptr); explicit AWKeys(QObject *_parent = nullptr);
virtual ~AWKeys(); ~AWKeys() override;
bool isDBusActive() const;
Q_INVOKABLE void initDataAggregator(const QVariantMap &_tooltipParams); Q_INVOKABLE void initDataAggregator(const QVariantMap &_tooltipParams);
Q_INVOKABLE void initKeys(const QString &_currentPattern, Q_INVOKABLE void initKeys(const QString &_currentPattern, int _interval, int _limit, bool _optimize);
const int _interval, const int _limit, Q_INVOKABLE void setAggregatorProperty(const QString &_key, const QVariant &_value);
const bool _optimize); Q_INVOKABLE void setWrapNewLines(bool _wrap);
Q_INVOKABLE void setAggregatorProperty(const QString &_key,
const QVariant &_value);
Q_INVOKABLE void setWrapNewLines(const bool _wrap = false);
// additional method to force load keys from Qml UI. Used in some // additional method to force load keys from Qml UI. Used in some
// configuration pages // configuration pages
Q_INVOKABLE void updateCache(); Q_INVOKABLE void updateCache();
// keys // keys
Q_INVOKABLE QStringList dictKeys(const bool _sorted = false, Q_INVOKABLE [[nodiscard]] QStringList dictKeys(bool _sorted = false, const QString &_regexp = "") const;
const QString &_regexp = "") const; Q_INVOKABLE [[nodiscard]] QVariantList getHddDevices() const;
Q_INVOKABLE QVariantList getHddDevices() const;
// values // values
Q_INVOKABLE QString infoByKey(const QString &_key) const; Q_INVOKABLE [[nodiscard]] QString infoByKey(const QString &_key) const;
Q_INVOKABLE QString valueByKey(const QString &_key) const; Q_INVOKABLE [[nodiscard]] QString valueByKey(const QString &_key) const;
// configuration // configuration
Q_INVOKABLE void editItem(const QString &_type); Q_INVOKABLE void editItem(const QString &_type);
public slots: public slots:
void dataUpdated(const QString &_sourceName, void dataUpdated(const QString &_sourceName, const Plasma::DataEngine::Data &_data);
const Plasma::DataEngine::Data &_data);
// dummy method required by DataEngine connections // dummy method required by DataEngine connections
void modelChanged(QString, QAbstractItemModel *){}; static void modelChanged(const QString &, QAbstractItemModel *){};
signals: signals:
void dropSourceFromDataengine(const QString &_source); void dropSourceFromDataengine(const QString &_source);
@ -79,7 +73,7 @@ private:
// methods // methods
void calculateValues(); void calculateValues();
void createDBusInterface(); void createDBusInterface();
QString parsePattern(QString _pattern) const; [[nodiscard]] QString parsePattern(QString _pattern) const;
void setDataBySource(const QString &_sourceName, const QVariantMap &_data); void setDataBySource(const QString &_sourceName, const QVariantMap &_data);
// objects // objects
AWDataAggregator *m_dataAggregator = nullptr; AWDataAggregator *m_dataAggregator = nullptr;
@ -88,7 +82,6 @@ private:
AWKeyOperations *m_keyOperator = nullptr; AWKeyOperations *m_keyOperator = nullptr;
QTimer *m_timer = nullptr; QTimer *m_timer = nullptr;
// variables // variables
bool m_dbusActive = false;
QVariantMap m_tooltipParams; QVariantMap m_tooltipParams;
QStringList m_foundBars, m_foundKeys, m_foundLambdas, m_requiredKeys; QStringList m_foundBars, m_foundKeys, m_foundLambdas, m_requiredKeys;
QVariantHash m_values; QVariantHash m_values;

View File

@ -21,10 +21,11 @@
#include <QDateTime> #include <QDateTime>
#include <QLocale> #include <QLocale>
#include <QRegExp>
#include "awdataenginemapper.h"
#include "awdebug.h" #include "awdebug.h"
#include "awformatterhelper.h" #include "awformatterhelper.h"
#include "version.h"
AWKeysAggregator::AWKeysAggregator(QObject *_parent) AWKeysAggregator::AWKeysAggregator(QObject *_parent)
@ -32,54 +33,36 @@ AWKeysAggregator::AWKeysAggregator(QObject *_parent)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_customFormatters = new AWFormatterHelper(nullptr);
m_mapper = new AWDataEngineMapper(this, m_customFormatters);
// sort time keys // sort time keys
m_timeKeys = QString(TIME_KEYS).split(',');
m_timeKeys.sort(); m_timeKeys.sort();
std::reverse(m_timeKeys.begin(), m_timeKeys.end()); std::reverse(m_timeKeys.begin(), m_timeKeys.end());
// default formatters
// memory
m_formatter["mem"] = FormatterType::Float;
m_formatter["memtotmb"] = FormatterType::MemMBFormat;
m_formatter["memtotgb"] = FormatterType::MemGBFormat;
// network
m_formatter["down"] = FormatterType::NetSmartFormat;
m_formatter["downkb"] = FormatterType::Integer;
m_formatter["downunits"] = FormatterType::NetSmartUnits;
m_formatter["up"] = FormatterType::NetSmartFormat;
m_formatter["upkb"] = FormatterType::Integer;
m_formatter["upunits"] = FormatterType::NetSmartUnits;
// swap
m_formatter["swap"] = FormatterType::Float;
m_formatter["swaptotmb"] = FormatterType::MemMBFormat;
m_formatter["swaptotgb"] = FormatterType::MemGBFormat;
} }
AWKeysAggregator::~AWKeysAggregator() AWKeysAggregator::~AWKeysAggregator()
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
delete m_customFormatters;
} }
void AWKeysAggregator::initFormatters() void AWKeysAggregator::initFormatters()
{ {
if (m_customFormatters) m_customFormatters->initItems();
delete m_customFormatters;
m_customFormatters = new AWFormatterHelper(nullptr);
} }
QString AWKeysAggregator::formatter(const QVariant &_data, QString AWKeysAggregator::formatter(const QVariant &_data, const QString &_key, bool replaceSpace) const
const QString &_key) const
{ {
qCDebug(LOG_AW) << "Data" << _data << "for key" << _key; qCDebug(LOG_AW) << "Data" << _data << "for key" << _key;
QString output; QString output;
QLocale loc = m_translate ? QLocale::system() : QLocale::c(); QLocale loc = m_translate ? QLocale::system() : QLocale::c();
// case block // case block
switch (m_formatter[_key]) { switch (m_mapper->formatter(_key)) {
case FormatterType::Float: case FormatterType::Float:
output = QString("%1").arg(_data.toFloat(), 5, 'f', 1); output = QString("%1").arg(_data.toFloat(), 5, 'f', 1);
break; break;
@ -102,8 +85,7 @@ QString AWKeysAggregator::formatter(const QVariant &_data,
output = _data.toBool() ? m_acOnline : m_acOffline; output = _data.toBool() ? m_acOnline : m_acOffline;
break; break;
case FormatterType::MemGBFormat: case FormatterType::MemGBFormat:
output output = QString("%1").arg(_data.toFloat() / (1024.0 * 1024.0), 5, 'f', 1);
= QString("%1").arg(_data.toFloat() / (1024.0 * 1024.0), 5, 'f', 1);
break; break;
case FormatterType::MemMBFormat: case FormatterType::MemMBFormat:
output = QString("%1").arg(_data.toFloat() / 1024.0, 5, 'f', 0); output = QString("%1").arg(_data.toFloat() / 1024.0, 5, 'f', 0);
@ -135,7 +117,7 @@ QString AWKeysAggregator::formatter(const QVariant &_data,
break; break;
case FormatterType::TimeCustom: case FormatterType::TimeCustom:
output = m_customTime; output = m_customTime;
[&output, loc, this](const QDateTime dt) { [&output, loc, this](const QDateTime &dt) {
for (auto &key : m_timeKeys) for (auto &key : m_timeKeys)
output.replace(QString("$%1").arg(key), loc.toString(dt, key)); output.replace(QString("$%1").arg(key), loc.toString(dt, key));
}(_data.toDateTime()); }(_data.toDateTime());
@ -150,8 +132,7 @@ QString AWKeysAggregator::formatter(const QVariant &_data,
output = loc.toString(_data.toDateTime(), QLocale::ShortFormat); output = loc.toString(_data.toDateTime(), QLocale::ShortFormat);
break; break;
case FormatterType::Timestamp: case FormatterType::Timestamp:
output = QString("%1").arg( output = QString("%1").arg(_data.toDateTime().toMSecsSinceEpoch() / 1000.0, 10, 'f', 0);
_data.toDateTime().toMSecsSinceEpoch() / 1000.0, 10, 'f', 0);
break; break;
case FormatterType::Uptime: case FormatterType::Uptime:
case FormatterType::UptimeCustom: case FormatterType::UptimeCustom:
@ -161,18 +142,14 @@ QString AWKeysAggregator::formatter(const QVariant &_data,
int minutes = seconds / 60 % 60; int minutes = seconds / 60 % 60;
int hours = ((seconds / 60) - minutes) / 60 % 24; int hours = ((seconds / 60) - minutes) / 60 % 24;
int days = (((seconds / 60) - minutes) / 60 - hours) / 24; int days = (((seconds / 60) - minutes) / 60 - hours) / 24;
source.replace("$dd", source.replace("$dd", QString("%1").arg(days, 3, 10, QChar('0')));
QString("%1").arg(days, 3, 10, QChar('0')));
source.replace("$d", QString("%1").arg(days)); source.replace("$d", QString("%1").arg(days));
source.replace("$hh", source.replace("$hh", QString("%1").arg(hours, 2, 10, QChar('0')));
QString("%1").arg(hours, 2, 10, QChar('0')));
source.replace("$h", QString("%1").arg(hours)); source.replace("$h", QString("%1").arg(hours));
source.replace("$mm", source.replace("$mm", QString("%1").arg(minutes, 2, 10, QChar('0')));
QString("%1").arg(minutes, 2, 10, QChar('0')));
source.replace("$m", QString("%1").arg(minutes)); source.replace("$m", QString("%1").arg(minutes));
return source; return source;
}(m_formatter[_key] == FormatterType::Uptime ? "$ddd$hhh$mmm" }(m_mapper->formatter(_key) == FormatterType::Uptime ? "$ddd$hhh$mmm" : m_customUptime,
: m_customUptime,
static_cast<int>(_data.toFloat())); static_cast<int>(_data.toFloat()));
break; break;
case FormatterType::NoFormat: case FormatterType::NoFormat:
@ -184,6 +161,11 @@ QString AWKeysAggregator::formatter(const QVariant &_data,
break; break;
} }
// replace spaces to non-breakable ones
replaceSpace &= (!_key.startsWith("custom") && (!_key.startsWith("weather")));
if (replaceSpace)
output.replace(" ", "&nbsp;");
return output; return output;
} }
@ -192,7 +174,7 @@ QStringList AWKeysAggregator::keysFromSource(const QString &_source) const
{ {
qCDebug(LOG_AW) << "Search for source" << _source; qCDebug(LOG_AW) << "Search for source" << _source;
return m_map.values(_source); return m_mapper->keysFromSource(_source);
} }
@ -232,7 +214,7 @@ void AWKeysAggregator::setDevices(const QHash<QString, QStringList> &_devices)
{ {
qCDebug(LOG_AW) << "Devices" << _devices; qCDebug(LOG_AW) << "Devices" << _devices;
m_devices = _devices; m_mapper->setDevices(_devices);
} }
@ -252,364 +234,11 @@ void AWKeysAggregator::setTranslate(const bool _translate)
} }
// HACK units required to define should the value be calculated as temperature QStringList AWKeysAggregator::registerSource(const QString &_source, const QString &_units, const QStringList &_keys)
// or fan data
QStringList AWKeysAggregator::registerSource(const QString &_source,
const QString &_units,
const QStringList &_keys)
{ {
qCDebug(LOG_AW) << "Source" << _source << "with units" << _units; qCDebug(LOG_AW) << "Source" << _source << "with units" << _units;
// regular expressions return m_mapper->registerSource(_source, _units, _keys);
QRegExp cpuRegExp = QRegExp("cpu/cpu.*/TotalLoad");
QRegExp cpuclRegExp = QRegExp("cpu/cpu.*/clock");
QRegExp hddrRegExp = QRegExp("disk/.*/Rate/rblk");
QRegExp hddwRegExp = QRegExp("disk/.*/Rate/wblk");
QRegExp mountFillRegExp = QRegExp("partitions/.*/filllevel");
QRegExp mountFreeRegExp = QRegExp("partitions/.*/freespace");
QRegExp mountUsedRegExp = QRegExp("partitions/.*/usedspace");
QRegExp netRegExp
= QRegExp("network/interfaces/.*/(receiver|transmitter)/data$");
QRegExp netTotalRegExp
= QRegExp("network/interfaces/.*/(receiver|transmitter)/dataTotal$");
if (_source == "battery/ac") {
// AC
m_map[_source] = "ac";
m_formatter["ac"] = FormatterType::ACFormat;
} else if (_source.startsWith("battery/")) {
// battery stats
QString key = _source;
key.remove("battery/");
m_map[_source] = key;
m_formatter[key] = FormatterType::IntegerThree;
} else if (_source == "cpu/system/TotalLoad") {
// cpu
m_map[_source] = "cpu";
m_formatter["cpu"] = FormatterType::Float;
} else if (_source.contains(cpuRegExp)) {
// cpus
QString key = _source;
key.remove("cpu/").remove("/TotalLoad");
m_map[_source] = key;
m_formatter[key] = FormatterType::Float;
} else if (_source == "cpu/system/AverageClock") {
// cpucl
m_map[_source] = "cpucl";
m_formatter["cpucl"] = FormatterType::Integer;
} else if (_source.contains(cpuclRegExp)) {
// cpucls
QString key = _source;
key.remove("cpu/cpu").remove("/clock");
key = QString("cpucl%1").arg(key);
m_map[_source] = key;
m_formatter[key] = FormatterType::Integer;
} else if (_source.startsWith("custom")) {
// custom
QString key = _source;
key.remove("custom/");
m_map[_source] = key;
m_formatter[key] = FormatterType::NoFormat;
} else if (_source == "desktop/current/name") {
// current desktop name
m_map[_source] = "desktop";
m_formatter["desktop"] = FormatterType::NoFormat;
} else if (_source == "desktop/current/number") {
// current desktop number
m_map[_source] = "ndesktop";
m_formatter["ndesktop"] = FormatterType::NoFormat;
} else if (_source == "desktop/total/number") {
// desktop count
m_map[_source] = "tdesktops";
m_formatter["tdesktops"] = FormatterType::NoFormat;
} else if (_source.contains(hddrRegExp)) {
// read speed
QString device = _source;
device.remove("/Rate/rblk");
int index = m_devices["disk"].indexOf(device);
if (index > -1) {
QString key = QString("hddr%1").arg(index);
m_map[_source] = key;
m_formatter[key] = FormatterType::Integer;
}
} else if (_source.contains(hddwRegExp)) {
// write speed
QString device = _source;
device.remove("/Rate/wblk");
int index = m_devices["disk"].indexOf(device);
if (index > -1) {
QString key = QString("hddw%1").arg(index);
m_map[_source] = key;
m_formatter[key] = FormatterType::Integer;
}
} else if (_source == "gpu/load") {
// gpu load
m_map[_source] = "gpu";
m_formatter["gpu"] = FormatterType::Float;
} else if (_source == "gpu/temperature") {
// gpu temperature
m_map[_source] = "gputemp";
m_formatter["gputemp"] = FormatterType::Temperature;
} else if (_source.contains(mountFillRegExp)) {
// fill level
QString device = _source;
device.remove("partitions").remove("/filllevel");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
QString key = QString("hdd%1").arg(index);
m_map[_source] = key;
m_formatter[key] = FormatterType::Float;
// additional keys
m_formatter[QString("hddtotmb%1").arg(index)]
= FormatterType::MemMBFormat;
m_formatter[QString("hddtotgb%1").arg(index)]
= FormatterType::MemGBFormat;
}
} else if (_source.contains(mountFreeRegExp)) {
// free space
QString device = _source;
device.remove("partitions").remove("/freespace");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
// mb
QString key = QString("hddfreemb%1").arg(index);
m_map[_source] = key;
m_formatter[key] = FormatterType::MemMBFormat;
// gb
key = QString("hddfreegb%1").arg(index);
m_map.insertMulti(_source, key);
m_formatter[key] = FormatterType::MemGBFormat;
}
} else if (_source.contains(mountUsedRegExp)) {
// used
QString device = _source;
device.remove("partitions").remove("/usedspace");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
// mb
QString key = QString("hddmb%1").arg(index);
m_map[_source] = key;
m_formatter[key] = FormatterType::MemMBFormat;
// gb
key = QString("hddgb%1").arg(index);
m_map.insertMulti(_source, key);
m_formatter[key] = FormatterType::MemGBFormat;
}
} else if (_source.startsWith("hdd/temperature")) {
// hdd temperature
QString device = _source;
device.remove("hdd/temperature");
int index = m_devices["hdd"].indexOf(device);
if (index > -1) {
QString key = QString("hddtemp%1").arg(index);
m_map[_source] = key;
m_formatter[key] = FormatterType::Temperature;
}
} else if (_source.startsWith("cpu/system/loadavg")) {
// load average
QString time = _source;
time.remove("cpu/system/loadavg");
QString key = QString("la%1").arg(time);
m_map[_source] = key;
m_formatter[key] = FormatterType::FloatTwoSymbols;
} else if (_source == "mem/physical/application") {
// app memory
// mb
m_map[_source] = "memmb";
m_formatter["memmb"] = FormatterType::MemMBFormat;
// gb
m_map.insertMulti(_source, "memgb");
m_formatter["memgb"] = FormatterType::MemGBFormat;
} else if (_source == "mem/physical/free") {
// free memory
// mb
m_map[_source] = "memfreemb";
m_formatter["memfreemb"] = FormatterType::MemMBFormat;
// gb
m_map.insertMulti(_source, "memfreegb");
m_formatter["memfreegb"] = FormatterType::MemGBFormat;
} else if (_source == "mem/physical/used") {
// used memory
// mb
m_map[_source] = "memusedmb";
m_formatter["memusedmb"] = FormatterType::MemMBFormat;
// gb
m_map.insertMulti(_source, "memusedgb");
m_formatter["memusedgb"] = FormatterType::MemGBFormat;
} else if (_source == "network/current/name") {
// network device
m_map[_source] = "netdev";
m_formatter["netdev"] = FormatterType::NoFormat;
} else if (_source.startsWith("network/response")) {
// network response
QString key = _source;
key.remove("network/");
m_map[_source] = key;
m_formatter[key] = FormatterType::NoFormat;
} else if (_source.contains(netRegExp)) {
// network speed
QString type = _source.contains("receiver") ? "down" : "up";
int index = m_devices["net"].indexOf(_source.split('/')[2]);
if (index > -1) {
// kb
QString key = QString("%1kb%2").arg(type).arg(index);
m_map[_source] = key;
m_formatter[key] = FormatterType::Integer;
// smart
key = QString("%1%2").arg(type).arg(index);
m_map.insertMulti(_source, key);
m_formatter[key] = FormatterType::NetSmartFormat;
// units
key = QString("%1units%2").arg(type).arg(index);
m_map.insertMulti(_source, key);
m_formatter[key] = FormatterType::NetSmartUnits;
}
} else if (_source.contains(netTotalRegExp)) {
// network data total
QString type = _source.contains("receiver") ? "down" : "up";
int index = m_devices["net"].indexOf(_source.split('/')[2]);
if (index > -1) {
// kb
QString key = QString("%1totalkb%2").arg(type).arg(index);
m_map[_source] = key;
m_formatter[key] = FormatterType::Integer;
// mb
key = QString("%1total%2").arg(type).arg(index);
m_map.insertMulti(_source, key);
m_formatter[key] = FormatterType::MemMBFormat;
}
} else if (_source.startsWith("upgrade")) {
// package manager
QString key = _source;
key.remove("upgrade/");
m_map[_source] = key;
m_formatter[key] = FormatterType::IntegerThree;
} else if (_source.startsWith("player")) {
// player
QString key = _source;
key.remove("player/");
m_map[_source] = key;
m_formatter[key] = FormatterType::NoFormat;
} else if (_source == "ps/running/count") {
// running processes count
m_map[_source] = "pscount";
m_formatter["pscount"] = FormatterType::NoFormat;
} else if (_source == "ps/running/list") {
// list of running processes
m_map[_source] = "ps";
m_formatter["ps"] = FormatterType::List;
} else if (_source == "ps/total/count") {
// total processes count
m_map[_source] = "pstotal";
m_formatter["pstotal"] = FormatterType::NoFormat;
} else if (_source.startsWith("quotes")) {
// quotes
QString key = _source;
key.remove("quotes/");
m_map[_source] = key;
m_formatter[key] = FormatterType::Quotes;
} else if (_source == "mem/swap/free") {
// free swap
// mb
m_map[_source] = "swapfreemb";
m_formatter["swapfreemb"] = FormatterType::MemMBFormat;
// gb
m_map.insertMulti(_source, "swapfreegb");
m_formatter["swapfreegb"] = FormatterType::MemGBFormat;
} else if (_source == "mem/swap/used") {
// used swap
// mb
m_map[_source] = "swapmb";
m_formatter["swapmb"] = FormatterType::MemMBFormat;
// gb
m_map.insertMulti(_source, "swapgb");
m_formatter["swapgb"] = FormatterType::MemGBFormat;
} else if (_source.startsWith("lmsensors/")) {
// temperature
int index = m_devices["temp"].indexOf(_source);
// HACK on DE initialization there are no units key
if (_units.isEmpty())
return QStringList({QString("temp%1").arg(index)});
if (index > -1) {
QString key = QString("temp%1").arg(index);
m_map[_source] = key;
m_formatter[key] = _units == "°C" ? FormatterType::Temperature
: FormatterType::Integer;
}
} else if (_source == "Local") {
// time
m_map[_source] = "time";
m_formatter["time"] = FormatterType::Time;
// custom time
m_map.insertMulti(_source, "ctime");
m_formatter["ctime"] = FormatterType::TimeCustom;
// ISO time
m_map.insertMulti(_source, "isotime");
m_formatter["isotime"] = FormatterType::TimeISO;
// long time
m_map.insertMulti(_source, "longtime");
m_formatter["longtime"] = FormatterType::TimeLong;
// short time
m_map.insertMulti(_source, "shorttime");
m_formatter["shorttime"] = FormatterType::TimeShort;
// timestamp
m_map.insertMulti(_source, "tstime");
m_formatter["tstime"] = FormatterType::Timestamp;
} else if (_source == "system/uptime") {
// uptime
m_map[_source] = "uptime";
m_formatter["uptime"] = FormatterType::Uptime;
// custom uptime
m_map.insertMulti(_source, "cuptime");
m_formatter["cuptime"] = FormatterType::UptimeCustom;
} else if (_source.startsWith("weather/temperature")) {
// temperature
QString key = _source;
key.remove("weather/");
m_map[_source] = key;
m_formatter[key] = FormatterType::Temperature;
} else if (_source.startsWith("weather/")) {
// other weather
QString key = _source;
key.remove("weather/");
m_map[_source] = key;
m_formatter[key] = FormatterType::NoFormat;
} else if (_source.startsWith("load/load")) {
// load source
QString key = _source;
key.remove("load/");
m_map[_source] = key;
m_formatter[key] = FormatterType::Temperature;
}
QStringList foundKeys = keysFromSource(_source);
// rewrite formatters for custom ones
QStringList customFormattersKeys;
if (m_customFormatters)
customFormattersKeys = m_customFormatters->definedFormatters();
qCInfo(LOG_AW) << "Looking for fprmatters" << foundKeys << "in"
<< customFormattersKeys;
for (auto &key : foundKeys) {
if (!customFormattersKeys.contains(key))
continue;
m_formatter[key] = FormatterType::Custom;
}
// drop key from dictionary if no one user requested key required it
qCInfo(LOG_AW) << "Looking for keys" << foundKeys << "in" << _keys;
bool required
= _keys.isEmpty() || std::any_of(foundKeys.cbegin(), foundKeys.cend(),
[&_keys](const QString &key) {
return _keys.contains(key);
});
if (!required) {
m_map.remove(_source);
for (auto &key : foundKeys)
m_formatter.remove(key);
}
return keysFromSource(_source);
} }

View File

@ -22,10 +22,9 @@
#include <QHash> #include <QHash>
#include <QObject> #include <QObject>
#include "version.h"
class AWFormatterHelper; class AWFormatterHelper;
class AWDataEngineMapper;
class AWKeysAggregator : public QObject class AWKeysAggregator : public QObject
{ {
@ -33,11 +32,11 @@ class AWKeysAggregator : public QObject
Q_PROPERTY(QString acOffline MEMBER m_acOffline WRITE setAcOffline); Q_PROPERTY(QString acOffline MEMBER m_acOffline WRITE setAcOffline);
Q_PROPERTY(QString acOnline MEMBER m_acOnline WRITE setAcOnline); Q_PROPERTY(QString acOnline MEMBER m_acOnline WRITE setAcOnline);
Q_PROPERTY(QString customTime MEMBER m_customTime WRITE setCustomTime); Q_PROPERTY(QString customTime MEMBER m_customTime WRITE setCustomTime);
Q_PROPERTY( Q_PROPERTY(QString customUptime MEMBER m_customUptime WRITE setCustomUptime);
QString customUptime MEMBER m_customUptime WRITE setCustomUptime);
Q_PROPERTY(QString tempUnits MEMBER m_tempUnits WRITE setTempUnits); Q_PROPERTY(QString tempUnits MEMBER m_tempUnits WRITE setTempUnits);
Q_PROPERTY(bool translate MEMBER m_translate WRITE setTranslate); Q_PROPERTY(bool translate MEMBER m_translate WRITE setTranslate);
public:
enum class FormatterType { enum class FormatterType {
// general formatters // general formatters
Custom, Custom,
@ -66,13 +65,12 @@ class AWKeysAggregator : public QObject
UptimeCustom UptimeCustom
}; };
public:
explicit AWKeysAggregator(QObject *_parent = nullptr); explicit AWKeysAggregator(QObject *_parent = nullptr);
virtual ~AWKeysAggregator(); ~AWKeysAggregator() override;
void initFormatters(); void initFormatters();
// get methods // get methods
QString formatter(const QVariant &_data, const QString &_key) const; [[nodiscard]] QString formatter(const QVariant &_data, const QString &_key, bool replaceSpace) const;
QStringList keysFromSource(const QString &_source) const; [[nodiscard]] QStringList keysFromSource(const QString &_source) const;
// set methods // set methods
void setAcOffline(const QString &_inactive); void setAcOffline(const QString &_inactive);
void setAcOnline(const QString &_active); void setAcOnline(const QString &_active);
@ -80,24 +78,21 @@ public:
void setCustomUptime(const QString &_customUptime); void setCustomUptime(const QString &_customUptime);
void setDevices(const QHash<QString, QStringList> &_devices); void setDevices(const QHash<QString, QStringList> &_devices);
void setTempUnits(const QString &_units); void setTempUnits(const QString &_units);
void setTranslate(const bool _translate); void setTranslate(bool _translate);
public slots: public slots:
QStringList registerSource(const QString &_source, const QString &_units, QStringList registerSource(const QString &_source, const QString &_units, const QStringList &_keys);
const QStringList &_keys);
private: private:
float temperature(const float temp) const; [[nodiscard]] float temperature(float temp) const;
AWFormatterHelper *m_customFormatters = nullptr; AWFormatterHelper *m_customFormatters = nullptr;
QStringList m_timeKeys = QString(TIME_KEYS).split(','); AWDataEngineMapper *m_mapper = nullptr;
QStringList m_timeKeys;
// variables // variables
QString m_acOffline; QString m_acOffline;
QString m_acOnline; QString m_acOnline;
QString m_customTime; QString m_customTime;
QString m_customUptime; QString m_customUptime;
QHash<QString, QStringList> m_devices;
QHash<QString, FormatterType> m_formatter;
QHash<QString, QString> m_map;
QString m_tempUnits; QString m_tempUnits;
bool m_translate = false; bool m_translate = false;
}; };

View File

@ -0,0 +1,51 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awpairconfigfactory.h"
#include "awcustomkeysconfig.h"
#include "awdebug.h"
#include "awformatterconfig.h"
AWPairConfigFactory::AWPairConfigFactory(QObject *_parent)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWPairConfigFactory::~AWPairConfigFactory()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWPairConfigFactory::showFormatterDialog(const QStringList &_keys)
{
auto *config = new AWFormatterConfig(nullptr, _keys);
config->showDialog();
config->deleteLater();
}
void AWPairConfigFactory::showKeysDialog(const QStringList &_keys)
{
auto *config = new AWCustomKeysConfig(nullptr, _keys);
config->showDialog();
config->deleteLater();
}

View File

@ -0,0 +1,39 @@
/***************************************************************************
* This file is part of awesome-widgets *
* *
* awesome-widgets is free software: you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* awesome-widgets is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#ifndef AWPAIRCONFIGFACTORY_H
#define AWPAIRCONFIGFACTORY_H
#include <QObject>
class AWPairConfigFactory : public QObject
{
Q_OBJECT
public:
explicit AWPairConfigFactory(QObject *_parent = nullptr);
~AWPairConfigFactory() override;
Q_INVOKABLE static void showFormatterDialog(const QStringList &_keys);
Q_INVOKABLE static void showKeysDialog(const QStringList &_keys);
private:
};
#endif /* AWPAIRCONFIGFACTORY_H */

View File

@ -24,25 +24,21 @@
#include "awkeysaggregator.h" #include "awkeysaggregator.h"
QString AWPatternFunctions::expandLambdas(QString _code, QString AWPatternFunctions::expandLambdas(QString _code, AWKeysAggregator *_aggregator, const QVariantHash &_metadata,
AWKeysAggregator *_aggregator,
const QVariantHash &_metadata,
const QStringList &_usedKeys) const QStringList &_usedKeys)
{ {
qCDebug(LOG_AW) << "Expand lamdas in" << _code; qCDebug(LOG_AW) << "Expand lambdas in" << _code;
QJSEngine engine; QJSEngine engine;
// apply $this values // apply $this values
_code.replace("$this", _metadata[_code].toString()); _code.replace("$this", _metadata[_code].toString());
// parsed values // parsed values
for (auto &lambdaKey : _usedKeys) for (auto &lambdaKey : _usedKeys)
_code.replace(QString("$%1").arg(lambdaKey), _code.replace(QString("$%1").arg(lambdaKey), _aggregator->formatter(_metadata[lambdaKey], lambdaKey, false));
_aggregator->formatter(_metadata[lambdaKey], lambdaKey));
qCInfo(LOG_AW) << "Expression" << _code; qCInfo(LOG_AW) << "Expression" << _code;
QJSValue result = engine.evaluate(_code); QJSValue result = engine.evaluate(_code);
if (result.isError()) { if (result.isError()) {
qCWarning(LOG_AW) << "Uncaught exception at line" qCWarning(LOG_AW) << "Uncaught exception at line" << result.property("lineNumber").toInt() << ":"
<< result.property("lineNumber").toInt() << ":"
<< result.toString(); << result.toString();
return ""; return "";
} else { } else {
@ -56,9 +52,8 @@ QString AWPatternFunctions::expandTemplates(QString _code)
qCDebug(LOG_AW) << "Expand templates in" << _code; qCDebug(LOG_AW) << "Expand templates in" << _code;
// match the following construction $template{{some code here}} // match the following construction $template{{some code here}}
QRegularExpression templatesRegexp("\\$template\\{\\{(?<body>.*?)\\}\\}"); QRegularExpression templatesRegexp(R"(\$template\{\{(?<body>.*?)\}\})");
templatesRegexp.setPatternOptions( templatesRegexp.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
QRegularExpression::DotMatchesEverythingOption);
QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(_code); QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(_code);
while (it.hasNext()) { while (it.hasNext()) {
@ -70,8 +65,7 @@ QString AWPatternFunctions::expandTemplates(QString _code)
QJSValue result = engine.evaluate(body); QJSValue result = engine.evaluate(body);
QString templateResult = ""; QString templateResult = "";
if (result.isError()) { if (result.isError()) {
qCWarning(LOG_AW) << "Uncaught exception at line" qCWarning(LOG_AW) << "Uncaught exception at line" << result.property("lineNumber").toInt() << ":"
<< result.property("lineNumber").toInt() << ":"
<< result.toString(); << result.toString();
} else { } else {
templateResult = result.toString(); templateResult = result.toString();
@ -85,9 +79,8 @@ QString AWPatternFunctions::expandTemplates(QString _code)
} }
QList<AWPatternFunctions::AWFunction> QList<AWPatternFunctions::AWFunction> AWPatternFunctions::findFunctionCalls(const QString &_function,
AWPatternFunctions::findFunctionCalls(const QString &_function, const QString &_code)
const QString &_code)
{ {
qCDebug(LOG_AW) << "Looking for function" << _function << "in" << _code; qCDebug(LOG_AW) << "Looking for function" << _function << "in" << _code;
@ -97,9 +90,7 @@ AWPatternFunctions::findFunctionCalls(const QString &_function,
// in this field if they are not screened by $, i.e. '$,' // in this field if they are not screened by $, i.e. '$,'
// * body depends on the function name, double brackets should be screened // * body depends on the function name, double brackets should be screened
// by using $, e.g. ${ // by using $, e.g. ${
QRegularExpression regex( QRegularExpression regex(QString(R"(\$%1\<(?<args>.*?)\>\{\{(?<body>.*?)\}\})").arg(_function));
QString("\\$%1\\<(?<args>.*?)\\>\\{\\{(?<body>.*?)\\}\\}")
.arg(_function));
regex.setPatternOptions(QRegularExpression::DotMatchesEverythingOption); regex.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
QList<AWPatternFunctions::AWFunction> foundFunctions; QList<AWPatternFunctions::AWFunction> foundFunctions;
@ -116,9 +107,7 @@ AWPatternFunctions::findFunctionCalls(const QString &_function,
// replace '$,' to 0x1d // replace '$,' to 0x1d
argsString.replace("$,", QString(0x1d)); argsString.replace("$,", QString(0x1d));
QStringList args = argsString.split(','); QStringList args = argsString.split(',');
std::for_each(args.begin(), args.end(), [](QString &arg) { std::for_each(args.begin(), args.end(), [](QString &arg) { arg.replace(QString(0x1d), ","); });
arg.replace(QString(0x1d), ",");
});
metadata.args = args; metadata.args = args;
} }
// other variables // other variables
@ -134,20 +123,15 @@ AWPatternFunctions::findFunctionCalls(const QString &_function,
} }
QString AWPatternFunctions::insertAllKeys(QString _code, QString AWPatternFunctions::insertAllKeys(QString _code, const QStringList &_keys)
const QStringList &_keys)
{ {
qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" << _keys;
<< _keys;
QList<AWPatternFunctions::AWFunction> found QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_all", _code);
= AWPatternFunctions::findFunctionCalls("aw_all", _code);
for (auto &function : found) { for (auto &function : found) {
QString separator = function.args.isEmpty() ? "," : function.args.at(0); QString separator = function.args.isEmpty() ? "," : function.args.at(0);
QStringList required = _keys.filter(QRegExp(function.body)); QStringList required = _keys.filter(QRegExp(function.body));
std::for_each(required.begin(), required.end(), [](QString &value) { std::for_each(required.begin(), required.end(), [](QString &value) { value = QString("%1: $%1").arg(value); });
value = QString("%1: $%1").arg(value);
});
_code.replace(function.what, required.join(separator)); _code.replace(function.what, required.join(separator));
} }
@ -156,14 +140,11 @@ QString AWPatternFunctions::insertAllKeys(QString _code,
} }
QString AWPatternFunctions::insertKeyCount(QString _code, QString AWPatternFunctions::insertKeyCount(QString _code, const QStringList &_keys)
const QStringList &_keys)
{ {
qCDebug(LOG_AW) << "Looking for count in code" << _code << "using list" qCDebug(LOG_AW) << "Looking for count in code" << _code << "using list" << _keys;
<< _keys;
QList<AWPatternFunctions::AWFunction> found QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_count", _code);
= AWPatternFunctions::findFunctionCalls("aw_count", _code);
for (auto &function : found) { for (auto &function : found) {
int count = _keys.filter(QRegExp(function.body)).count(); int count = _keys.filter(QRegExp(function.body)).count();
@ -174,14 +155,11 @@ QString AWPatternFunctions::insertKeyCount(QString _code,
} }
QString AWPatternFunctions::insertKeyNames(QString _code, QString AWPatternFunctions::insertKeyNames(QString _code, const QStringList &_keys)
const QStringList &_keys)
{ {
qCDebug(LOG_AW) << "Looking for key names in code" << _code << "using list" qCDebug(LOG_AW) << "Looking for key names in code" << _code << "using list" << _keys;
<< _keys;
QList<AWPatternFunctions::AWFunction> found QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_names", _code);
= AWPatternFunctions::findFunctionCalls("aw_names", _code);
for (auto &function : found) { for (auto &function : found) {
QString separator = function.args.isEmpty() ? "," : function.args.at(0); QString separator = function.args.isEmpty() ? "," : function.args.at(0);
QStringList required = _keys.filter(QRegExp(function.body)); QStringList required = _keys.filter(QRegExp(function.body));
@ -195,17 +173,13 @@ QString AWPatternFunctions::insertKeyNames(QString _code,
QString AWPatternFunctions::insertKeys(QString _code, const QStringList &_keys) QString AWPatternFunctions::insertKeys(QString _code, const QStringList &_keys)
{ {
qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" << _keys;
<< _keys;
QList<AWPatternFunctions::AWFunction> found QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_keys", _code);
= AWPatternFunctions::findFunctionCalls("aw_keys", _code);
for (auto &function : found) { for (auto &function : found) {
QString separator = function.args.isEmpty() ? "," : function.args.at(0); QString separator = function.args.isEmpty() ? "," : function.args.at(0);
QStringList required = _keys.filter(QRegExp(function.body)); QStringList required = _keys.filter(QRegExp(function.body));
std::for_each(required.begin(), required.end(), [](QString &value) { std::for_each(required.begin(), required.end(), [](QString &value) { value = QString("$%1").arg(value); });
value = QString("$%1").arg(value);
});
_code.replace(function.what, required.join(separator)); _code.replace(function.what, required.join(separator));
} }
@ -218,8 +192,7 @@ QString AWPatternFunctions::insertMacros(QString _code)
{ {
qCDebug(LOG_AW) << "Looking for macros in code" << _code; qCDebug(LOG_AW) << "Looking for macros in code" << _code;
QList<AWPatternFunctions::AWFunction> found QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_macro", _code);
= AWPatternFunctions::findFunctionCalls("aw_macro", _code);
for (auto &macro : found) { for (auto &macro : found) {
// get macro params // get macro params
if (macro.args.isEmpty()) { if (macro.args.isEmpty()) {
@ -229,23 +202,18 @@ QString AWPatternFunctions::insertMacros(QString _code)
QString name = macro.args.takeFirst(); QString name = macro.args.takeFirst();
// find macro usage // find macro usage
QList<AWPatternFunctions::AWFunction> macroUsage QList<AWPatternFunctions::AWFunction> macroUsage
= AWPatternFunctions::findFunctionCalls( = AWPatternFunctions::findFunctionCalls(QString("aw_macro_%1").arg(name), _code);
QString("aw_macro_%1").arg(name), _code);
for (auto &function : macroUsage) { for (auto &function : macroUsage) {
if (function.args.count() != macro.args.count()) { if (function.args.count() != macro.args.count()) {
qCWarning(LOG_AW) qCWarning(LOG_AW) << "Invalid args count found for call" << function.what << "with macro" << macro.what;
<< "Invalid args count found for call" << function.what
<< "with macro" << macro.what;
continue; continue;
} }
// generate body to replace // generate body to replace
QString result = macro.body; QString result = macro.body;
std::for_each(macro.args.cbegin(), macro.args.cend(), std::for_each(macro.args.cbegin(), macro.args.cend(), [&result, macro, function](const QString &arg) {
[&result, macro, function](const QString &arg) { int index = macro.args.indexOf(arg);
int index = macro.args.indexOf(arg); result.replace(QString("$%1").arg(arg), function.args.at(index));
result.replace(QString("$%1").arg(arg), });
function.args.at(index));
});
// do replace // do replace
_code.replace(function.what, result); _code.replace(function.what, result);
} }
@ -258,20 +226,15 @@ QString AWPatternFunctions::insertMacros(QString _code)
} }
QStringList AWPatternFunctions::findKeys(const QString &_code, QStringList AWPatternFunctions::findKeys(const QString &_code, const QStringList &_keys, const bool _isBars)
const QStringList &_keys,
const bool _isBars)
{ {
qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" << _keys;
<< _keys;
QStringList selectedKeys; QStringList selectedKeys;
QString replacedCode = _code; QString replacedCode = _code;
for (auto &key : _keys) for (auto &key : _keys)
if ((key.startsWith("bar") == _isBars) if ((key.startsWith("bar") == _isBars) && (replacedCode.contains(QString("$%1").arg(key)))) {
&& (replacedCode.contains(QString("$%1").arg(key)))) { qCInfo(LOG_AW) << "Found key" << key << "with bar enabled" << _isBars;
qCInfo(LOG_AW) << "Found key" << key << "with bar enabled"
<< _isBars;
selectedKeys.append(key); selectedKeys.append(key);
replacedCode.replace(QString("$%1").arg(key), ""); replacedCode.replace(QString("$%1").arg(key), "");
} }
@ -288,9 +251,8 @@ QStringList AWPatternFunctions::findLambdas(const QString &_code)
QStringList selectedKeys; QStringList selectedKeys;
// match the following construction ${{some code here}} // match the following construction ${{some code here}}
QRegularExpression lambdaRegexp("\\$\\{\\{(?<body>.*?)\\}\\}"); QRegularExpression lambdaRegexp(R"(\$\{\{(?<body>.*?)\}\})");
lambdaRegexp.setPatternOptions( lambdaRegexp.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
QRegularExpression::DotMatchesEverythingOption);
QRegularExpressionMatchIterator it = lambdaRegexp.globalMatch(_code); QRegularExpressionMatchIterator it = lambdaRegexp.globalMatch(_code);
while (it.hasNext()) { while (it.hasNext()) {

View File

@ -34,22 +34,19 @@ typedef struct {
} AWFunction; } AWFunction;
// insert methods // insert methods
QString expandLambdas(QString _code, AWKeysAggregator *_aggregator, QString expandLambdas(QString _code, AWKeysAggregator *_aggregator, const QVariantHash &_metadata,
const QVariantHash &_metadata,
const QStringList &_usedKeys); const QStringList &_usedKeys);
QString expandTemplates(QString _code); QString expandTemplates(QString _code);
QList<AWFunction> findFunctionCalls(const QString &_function, QList<AWFunction> findFunctionCalls(const QString &_function, const QString &_code);
const QString &_code);
QString insertAllKeys(QString _code, const QStringList &_keys); QString insertAllKeys(QString _code, const QStringList &_keys);
QString insertKeyCount(QString _code, const QStringList &_keys); QString insertKeyCount(QString _code, const QStringList &_keys);
QString insertKeyNames(QString _code, const QStringList &_keys); QString insertKeyNames(QString _code, const QStringList &_keys);
QString insertKeys(QString _code, const QStringList &_keys); QString insertKeys(QString _code, const QStringList &_keys);
QString insertMacros(QString _code); QString insertMacros(QString _code);
// find methods // find methods
QStringList findKeys(const QString &_code, const QStringList &_keys, QStringList findKeys(const QString &_code, const QStringList &_keys, bool _isBars);
const bool _isBars);
QStringList findLambdas(const QString &_code); QStringList findLambdas(const QString &_code);
}; } // namespace AWPatternFunctions
#endif /* AWPATTERNFUNCTIONS_H */ #endif /* AWPATTERNFUNCTIONS_H */

View File

@ -18,10 +18,8 @@
#include "awtelemetryhandler.h" #include "awtelemetryhandler.h"
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonParseError>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QNetworkRequest>
#include <QSettings> #include <QSettings>
#include <QStandardPaths> #include <QStandardPaths>
#include <QUuid> #include <QUuid>
@ -29,15 +27,13 @@
#include "awdebug.h" #include "awdebug.h"
AWTelemetryHandler::AWTelemetryHandler(QObject *_parent, AWTelemetryHandler::AWTelemetryHandler(QObject *_parent, const QString &_clientId)
const QString &_clientId)
: QObject(_parent) : QObject(_parent)
{ {
qCDebug(LOG_AW) << __PRETTY_FUNCTION__; qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_localFile = QString("%1/awesomewidgets/telemetry.ini") m_localFile = QString("%1/awesomewidgets/telemetry.ini")
.arg(QStandardPaths::writableLocation( .arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
QStandardPaths::GenericDataLocation));
// override client id if any // override client id if any
if (!_clientId.isEmpty()) if (!_clientId.isEmpty())
@ -75,11 +71,10 @@ QString AWTelemetryHandler::getLast(const QString &_group) const
} }
void AWTelemetryHandler::init(const int _count, const bool _enableRemote, void AWTelemetryHandler::init(const int _count, const bool _enableRemote, const QString &_clientId)
const QString &_clientId)
{ {
qCDebug(LOG_AW) << "Init telemetry with count" << _count << "enable remote" qCDebug(LOG_AW) << "Init telemetry with count" << _count << "enable remote" << _enableRemote << "client ID"
<< _enableRemote << "client ID" << _clientId; << _clientId;
m_storeCount = _count; m_storeCount = _count;
m_uploadEnabled = _enableRemote; m_uploadEnabled = _enableRemote;
@ -89,8 +84,7 @@ void AWTelemetryHandler::init(const int _count, const bool _enableRemote,
bool AWTelemetryHandler::put(const QString &_group, const QString &_value) const bool AWTelemetryHandler::put(const QString &_group, const QString &_value) const
{ {
qCDebug(LOG_AW) << "Store data with group" << _group << "and value" qCDebug(LOG_AW) << "Store data with group" << _group << "and value" << _value;
<< _value;
QSettings settings(m_localFile, QSettings::IniFormat); QSettings settings(m_localFile, QSettings::IniFormat);
settings.beginGroup(_group); settings.beginGroup(_group);
@ -101,8 +95,7 @@ bool AWTelemetryHandler::put(const QString &_group, const QString &_value) const
saved.append(settings.value(key).toString()); saved.append(settings.value(key).toString());
// check if this value is already saved // check if this value is already saved
if (saved.contains(_value)) { if (saved.contains(_value)) {
qCInfo(LOG_AW) << "Configuration" << _value << "for group" << _group qCInfo(LOG_AW) << "Configuration" << _value << "for group" << _group << "is already saved";
<< "is already saved";
return false; return false;
} }
saved.append(_value); saved.append(_value);
@ -125,19 +118,16 @@ bool AWTelemetryHandler::put(const QString &_group, const QString &_value) const
} }
void AWTelemetryHandler::uploadTelemetry(const QString &_group, void AWTelemetryHandler::uploadTelemetry(const QString &_group, const QString &_value)
const QString &_value)
{ {
qCDebug(LOG_AW) << "Upload data with group" << _group << "and value" qCDebug(LOG_AW) << "Upload data with group" << _group << "and value" << _value;
<< _value;
if (!m_uploadEnabled) { if (!m_uploadEnabled) {
qCInfo(LOG_AW) << "Upload disabled by configuration"; qCInfo(LOG_AW) << "Upload disabled by configuration";
return; return;
} }
QNetworkAccessManager *manager = new QNetworkAccessManager(nullptr); auto *manager = new QNetworkAccessManager(nullptr);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(telemetryReplyRecieved(QNetworkReply *)));
SLOT(telemetryReplyRecieved(QNetworkReply *)));
QUrl url(REMOTE_TELEMETRY_URL); QUrl url(REMOTE_TELEMETRY_URL);
QNetworkRequest request(url); QNetworkRequest request(url);
@ -150,10 +140,8 @@ void AWTelemetryHandler::uploadTelemetry(const QString &_group,
payload["metadata"] = _value; payload["metadata"] = _value;
payload["type"] = _group; payload["type"] = _group;
// convert to QByteArray to send request // convert to QByteArray to send request
QByteArray data QByteArray data = QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact);
= QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact); qCInfo(LOG_AW) << "Send request with body" << data.data() << "and size" << data.size();
qCInfo(LOG_AW) << "Send request with body" << data.data() << "and size"
<< data.size();
manager->post(request, data); manager->post(request, data);
} }
@ -162,12 +150,11 @@ void AWTelemetryHandler::uploadTelemetry(const QString &_group,
void AWTelemetryHandler::telemetryReplyRecieved(QNetworkReply *_reply) void AWTelemetryHandler::telemetryReplyRecieved(QNetworkReply *_reply)
{ {
if (_reply->error() != QNetworkReply::NoError) { if (_reply->error() != QNetworkReply::NoError) {
qCWarning(LOG_AW) << "An error occurs" << _reply->error() qCWarning(LOG_AW) << "An error occurs" << _reply->error() << "with message" << _reply->errorString();
<< "with message" << _reply->errorString();
return; return;
} }
QJsonParseError error; QJsonParseError error{};
QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error); QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) { if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_AW) << "Parse error" << error.errorString(); qCWarning(LOG_AW) << "Parse error" << error.errorString();
@ -184,7 +171,7 @@ void AWTelemetryHandler::telemetryReplyRecieved(QNetworkReply *_reply)
} }
QString AWTelemetryHandler::getKey(const int _count) const QString AWTelemetryHandler::getKey(const int _count)
{ {
qCDebug(LOG_AW) << "Get key for keys count" << _count; qCDebug(LOG_AW) << "Get key for keys count" << _count;

View File

@ -20,10 +20,8 @@
#define AWTELEMETRYHANDLER_H #define AWTELEMETRYHANDLER_H
#include <QObject> #include <QObject>
#include <QtCore/QVariant>
class QAbstractButton;
class QNetworkReply; class QNetworkReply;
class AWTelemetryHandler : public QObject class AWTelemetryHandler : public QObject
@ -33,16 +31,13 @@ class AWTelemetryHandler : public QObject
public: public:
const char *REMOTE_TELEMETRY_URL = "https://arcanis.me/telemetry"; const char *REMOTE_TELEMETRY_URL = "https://arcanis.me/telemetry";
explicit AWTelemetryHandler(QObject *_parent = nullptr, explicit AWTelemetryHandler(QObject *_parent = nullptr, const QString &_clientId = "");
const QString &_clientId = ""); ~AWTelemetryHandler() override;
virtual ~AWTelemetryHandler(); Q_INVOKABLE [[nodiscard]] QStringList get(const QString &_group) const;
Q_INVOKABLE QStringList get(const QString &_group) const; Q_INVOKABLE [[nodiscard]] QString getLast(const QString &_group) const;
Q_INVOKABLE QString getLast(const QString &_group) const; Q_INVOKABLE void init(int _count, bool _enableRemote, const QString &_clientId);
Q_INVOKABLE void init(const int _count, const bool _enableRemote, Q_INVOKABLE [[nodiscard]] bool put(const QString &_group, const QString &_value) const;
const QString &_clientId); Q_INVOKABLE void uploadTelemetry(const QString &_group, const QString &_value);
Q_INVOKABLE bool put(const QString &_group, const QString &_value) const;
Q_INVOKABLE void uploadTelemetry(const QString &_group,
const QString &_value);
signals: signals:
void replyReceived(const QString &_message); void replyReceived(const QString &_message);
@ -51,7 +46,7 @@ private slots:
void telemetryReplyRecieved(QNetworkReply *_reply); void telemetryReplyRecieved(QNetworkReply *_reply);
private: private:
QString getKey(const int _count) const; static QString getKey(int _count);
QString m_clientId; QString m_clientId;
QString m_localFile; QString m_localFile;
int m_storeCount = 0; int m_storeCount = 0;

View File

@ -21,10 +21,8 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonParseError>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QNetworkRequest>
#include <QSettings> #include <QSettings>
#include "awdebug.h" #include "awdebug.h"
@ -37,8 +35,7 @@ AWUpdateHelper::AWUpdateHelper(QObject *_parent)
m_foundVersion = QVersionNumber::fromString(VERSION); m_foundVersion = QVersionNumber::fromString(VERSION);
m_genericConfig = QString("%1/awesomewidgets/general.ini") m_genericConfig = QString("%1/awesomewidgets/general.ini")
.arg(QStandardPaths::writableLocation( .arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
QStandardPaths::GenericDataLocation));
} }
@ -54,11 +51,9 @@ void AWUpdateHelper::checkUpdates(const bool _showAnyway)
// showAnyway options requires to show message if no updates found on direct // showAnyway options requires to show message if no updates found on direct
// request. In case of automatic check no message will be shown // request. In case of automatic check no message will be shown
QNetworkAccessManager *manager = new QNetworkAccessManager(nullptr); auto *manager = new QNetworkAccessManager(nullptr);
connect(manager, &QNetworkAccessManager::finished, connect(manager, &QNetworkAccessManager::finished,
[_showAnyway, this](QNetworkReply *reply) { [_showAnyway, this](QNetworkReply *reply) { return versionReplyRecieved(reply, _showAnyway); });
return versionReplyRecieved(reply, _showAnyway);
});
manager->get(QNetworkRequest(QUrl(VERSION_API))); manager->get(QNetworkRequest(QUrl(VERSION_API)));
} }
@ -67,17 +62,14 @@ void AWUpdateHelper::checkUpdates(const bool _showAnyway)
bool AWUpdateHelper::checkVersion() bool AWUpdateHelper::checkVersion()
{ {
QSettings settings(m_genericConfig, QSettings::IniFormat); QSettings settings(m_genericConfig, QSettings::IniFormat);
QVersionNumber version = QVersionNumber::fromString( QVersionNumber version = QVersionNumber::fromString(settings.value("Version", QString(VERSION)).toString());
settings.value("Version", QString(VERSION)).toString());
// update version // update version
settings.setValue("Version", QString(VERSION)); settings.setValue("Version", QString(VERSION));
settings.sync(); settings.sync();
qCInfo(LOG_AW) << "Found version" << version << "actual one is" qCInfo(LOG_AW) << "Found version" << version << "actual one is" << m_foundVersion;
<< m_foundVersion;
if ((version != m_foundVersion) && (!QString(CHANGELOG).isEmpty())) { if ((version != m_foundVersion) && (!QString(CHANGELOG).isEmpty())) {
genMessageBox(i18n("Changelog of %1", VERSION), genMessageBox(i18nc("Changelog of %1", VERSION), QString(CHANGELOG).replace('@', '\n'), QMessageBox::Ok)
QString(CHANGELOG).replace('@', '\n'), QMessageBox::Ok)
->open(); ->open();
return true; return true;
} else if (version != m_foundVersion) { } else if (version != m_foundVersion) {
@ -95,12 +87,10 @@ void AWUpdateHelper::showInfo(const QVersionNumber &_version)
{ {
qCDebug(LOG_AW) << "Version" << _version; qCDebug(LOG_AW) << "Version" << _version;
QString text QString text = i18n("You are using the actual version %1", _version.toString());
= i18n("You are using the actual version %1", _version.toString());
if (!QString(COMMIT_SHA).isEmpty()) if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(QString(COMMIT_SHA)); text += QString(" (%1)").arg(QString(COMMIT_SHA));
return genMessageBox(i18n("No new version found"), text, QMessageBox::Ok) return genMessageBox(i18n("No new version found"), text, QMessageBox::Ok)->open();
->open();
} }
@ -109,29 +99,24 @@ void AWUpdateHelper::showUpdates(const QVersionNumber &_version)
qCDebug(LOG_AW) << "Version" << _version; qCDebug(LOG_AW) << "Version" << _version;
QString text; QString text;
text += i18n("Current version : %1", VERSION); text += i18nc("Current version : %1", VERSION);
text += QString(COMMIT_SHA).isEmpty() text += QString(COMMIT_SHA).isEmpty() ? "\n" : QString(" (%1)\n").arg(QString(COMMIT_SHA));
? "\n"
: QString(" (%1)\n").arg(QString(COMMIT_SHA));
text += i18n("New version : %1", _version.toString()) + "\n\n"; text += i18n("New version : %1", _version.toString()) + "\n\n";
text += i18n("Click \"Ok\" to download"); text += i18n("Click \"Ok\" to download");
genMessageBox(i18n("There are updates"), text, genMessageBox(i18n("There are updates"), text, QMessageBox::Ok | QMessageBox::Cancel)
QMessageBox::Ok | QMessageBox::Cancel)
->open(this, SLOT(userReplyOnUpdates(QAbstractButton *))); ->open(this, SLOT(userReplyOnUpdates(QAbstractButton *)));
} }
void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *_button) void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *_button)
{ {
QMessageBox::ButtonRole ret QMessageBox::ButtonRole ret = dynamic_cast<QMessageBox *>(sender())->buttonRole(_button);
= static_cast<QMessageBox *>(sender())->buttonRole(_button);
qCInfo(LOG_AW) << "User select" << ret; qCInfo(LOG_AW) << "User select" << ret;
switch (ret) { switch (ret) {
case QMessageBox::AcceptRole: case QMessageBox::AcceptRole:
QDesktopServices::openUrl(QString(RELEASES) QDesktopServices::openUrl(QString(RELEASES) + m_foundVersion.toString());
+ m_foundVersion.toString());
break; break;
case QMessageBox::RejectRole: case QMessageBox::RejectRole:
default: default:
@ -140,17 +125,15 @@ void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *_button)
} }
void AWUpdateHelper::versionReplyRecieved(QNetworkReply *_reply, void AWUpdateHelper::versionReplyRecieved(QNetworkReply *_reply, const bool _showAnyway)
const bool _showAnyway)
{ {
qCDebug(LOG_AW) << "Show message anyway" << _showAnyway; qCDebug(LOG_AW) << "Show message anyway" << _showAnyway;
if (_reply->error() != QNetworkReply::NoError) { if (_reply->error() != QNetworkReply::NoError) {
qCWarning(LOG_AW) << "An error occurs" << _reply->error() qCWarning(LOG_AW) << "An error occurs" << _reply->error() << "with message" << _reply->errorString();
<< "with message" << _reply->errorString();
return; return;
} }
QJsonParseError error; QJsonParseError error = QJsonParseError();
QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error); QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) { if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_AW) << "Parse error" << error.errorString(); qCWarning(LOG_AW) << "Parse error" << error.errorString();
@ -174,14 +157,12 @@ void AWUpdateHelper::versionReplyRecieved(QNetworkReply *_reply,
// additional method which is used to show message box which does not block UI // additional method which is used to show message box which does not block UI
QMessageBox * QMessageBox *AWUpdateHelper::genMessageBox(const QString &_title, const QString &_body,
AWUpdateHelper::genMessageBox(const QString &_title, const QString &_body, const QMessageBox::StandardButtons _buttons)
const QMessageBox::StandardButtons _buttons)
{ {
qCDebug(LOG_AW) << "Construct message box with title" << _title qCDebug(LOG_AW) << "Construct message box with title" << _title << "and body" << _body;
<< "and body" << _body;
QMessageBox *msgBox = new QMessageBox(nullptr); auto *msgBox = new QMessageBox(nullptr);
msgBox->setAttribute(Qt::WA_DeleteOnClose); msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setModal(false); msgBox->setModal(false);
msgBox->setWindowTitle(_title); msgBox->setWindowTitle(_title);

View File

@ -32,19 +32,19 @@ class AWUpdateHelper : public QObject
public: public:
explicit AWUpdateHelper(QObject *_parent = nullptr); explicit AWUpdateHelper(QObject *_parent = nullptr);
virtual ~AWUpdateHelper(); ~AWUpdateHelper() override;
void checkUpdates(const bool _showAnyway = false); void checkUpdates(bool _showAnyway = false);
bool checkVersion(); bool checkVersion();
private slots: private slots:
void showInfo(const QVersionNumber &_version); static void showInfo(const QVersionNumber &_version);
void showUpdates(const QVersionNumber &_version); void showUpdates(const QVersionNumber &_version);
void userReplyOnUpdates(QAbstractButton *_button); void userReplyOnUpdates(QAbstractButton *_button);
void versionReplyRecieved(QNetworkReply *_reply, const bool _showAnyway); void versionReplyRecieved(QNetworkReply *_reply, bool _showAnyway);
private: private:
QMessageBox *genMessageBox(const QString &_title, const QString &_body, static QMessageBox *genMessageBox(const QString &_title, const QString &_body,
const QMessageBox::StandardButtons _buttons); QMessageBox::StandardButtons _buttons);
QVersionNumber m_foundVersion; QVersionNumber m_foundVersion;
QString m_genericConfig; QString m_genericConfig;
}; };

View File

@ -19,12 +19,11 @@
#include <QDir> #include <QDir>
#include <QLocalServer> #include <QLocalServer>
#include <QRandomGenerator>
#include <QSettings> #include <QSettings>
#include <QStandardPaths> #include <QStandardPaths>
#include <QTime>
#include "abstractextitemaggregator.h" #include "abstractextitemaggregator.h"
#include "awdebug.h"
#include "qcronscheduler.h" #include "qcronscheduler.h"
@ -46,8 +45,8 @@ AbstractExtItem::~AbstractExtItem()
if (m_socket) { if (m_socket) {
m_socket->close(); m_socket->close();
m_socket->removeServer(socket()); QLocalServer::removeServer(socket());
delete m_socket; m_socket->deleteLater();
} }
} }
@ -58,8 +57,7 @@ void AbstractExtItem::bumpApi(const int _newVer)
// update for current API // update for current API
if ((apiVersion() > 0) && (apiVersion() < _newVer)) { if ((apiVersion() > 0) && (apiVersion() < _newVer)) {
qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to" qCWarning(LOG_LIB) << "Bump API version from" << apiVersion() << "to" << _newVer;
<< _newVer;
setApiVersion(_newVer); setApiVersion(_newVer);
writeConfiguration(); writeConfiguration();
} }
@ -105,8 +103,7 @@ QString AbstractExtItem::writtableConfig() const
QString dir = QFileInfo(path).fileName(); QString dir = QFileInfo(path).fileName();
return QString("%1/awesomewidgets/%2/%3") return QString("%1/awesomewidgets/%2/%3")
.arg(QStandardPaths::writableLocation( .arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation))
QStandardPaths::GenericDataLocation))
.arg(dir) .arg(dir)
.arg(name); .arg(name);
} }
@ -203,8 +200,7 @@ void AbstractExtItem::setCron(const QString &_cron)
qCDebug(LOG_LIB) << "Cron string" << _cron; qCDebug(LOG_LIB) << "Cron string" << _cron;
// deinit module first // deinit module first
if (m_scheduler) { if (m_scheduler) {
disconnect(m_scheduler, SIGNAL(activated()), this, disconnect(m_scheduler, SIGNAL(activated()), this, SIGNAL(requestDataUpdate()));
SIGNAL(requestDataUpdate()));
delete m_scheduler; delete m_scheduler;
} }
@ -215,8 +211,7 @@ void AbstractExtItem::setCron(const QString &_cron)
// init scheduler // init scheduler
m_scheduler = new QCronScheduler(this); m_scheduler = new QCronScheduler(this);
m_scheduler->parse(cron()); m_scheduler->parse(cron());
connect(m_scheduler, SIGNAL(activated()), this, connect(m_scheduler, SIGNAL(activated()), this, SIGNAL(requestDataUpdate()));
SIGNAL(requestDataUpdate()));
} }
@ -245,9 +240,7 @@ void AbstractExtItem::setNumber(int _number)
if (generateNumber) { if (generateNumber) {
_number = []() { _number = []() {
qCWarning(LOG_LIB) << "Number is empty, generate new one"; qCWarning(LOG_LIB) << "Number is empty, generate new one";
// we suppose that currentTIme().msec() is always valid time auto n = QRandomGenerator::global()->generate() % 1000;
qsrand(static_cast<uint>(QTime::currentTime().msec()));
int n = qrand() % 1000;
qCInfo(LOG_LIB) << "Generated number is" << n; qCInfo(LOG_LIB) << "Generated number is" << n;
return n; return n;
}(); }();
@ -275,10 +268,9 @@ void AbstractExtItem::deinitSocket()
return; return;
m_socket->close(); m_socket->close();
m_socket->removeServer(socket()); QLocalServer::removeServer(socket());
delete m_socket; delete m_socket;
disconnect(m_socket, SIGNAL(newConnection()), this, disconnect(m_socket, SIGNAL(newConnection()), this, SLOT(newConnectionReceived()));
SLOT(newConnectionReceived()));
} }
@ -290,8 +282,7 @@ void AbstractExtItem::initSocket()
m_socket = new QLocalServer(this); m_socket = new QLocalServer(this);
bool listening = m_socket->listen(socket()); bool listening = m_socket->listen(socket());
qCInfo(LOG_LIB) << "Server listening on" << socket() << listening; qCInfo(LOG_LIB) << "Server listening on" << socket() << listening;
connect(m_socket, SIGNAL(newConnection()), this, connect(m_socket, SIGNAL(newConnection()), this, SLOT(newConnectionReceived()));
SLOT(newConnectionReceived()));
} }

View File

@ -40,33 +40,31 @@ class AbstractExtItem : public QDialog
Q_PROPERTY(QString uniq READ uniq) Q_PROPERTY(QString uniq READ uniq)
public: public:
explicit AbstractExtItem(QWidget *_parent = nullptr, explicit AbstractExtItem(QWidget *_parent = nullptr, const QString &_filePath = "");
const QString &_filePath = ""); ~AbstractExtItem() override;
virtual ~AbstractExtItem(); virtual void bumpApi(int _newVer);
virtual void bumpApi(const int _newVer); virtual AbstractExtItem *copy(const QString &_fileName, int _number) = 0;
virtual AbstractExtItem *copy(const QString &_fileName, const int _number)
= 0;
virtual void copyDefaults(AbstractExtItem *_other) const; virtual void copyDefaults(AbstractExtItem *_other) const;
virtual void startTimer(); virtual void startTimer();
QString writtableConfig() const; [[nodiscard]] QString writtableConfig() const;
// get methods // get methods
int apiVersion() const; [[nodiscard]] int apiVersion() const;
QString comment() const; [[nodiscard]] QString comment() const;
QString cron() const; [[nodiscard]] QString cron() const;
QString fileName() const; [[nodiscard]] QString fileName() const;
int interval() const; [[nodiscard]] int interval() const;
bool isActive() const; [[nodiscard]] bool isActive() const;
QString name() const; [[nodiscard]] QString name() const;
int number() const; [[nodiscard]] int number() const;
QString socket() const; [[nodiscard]] QString socket() const;
QString tag(const QString &_type) const; [[nodiscard]] QString tag(const QString &_type) const;
virtual QString uniq() const = 0; [[nodiscard]] virtual QString uniq() const = 0;
// set methods // set methods
void setApiVersion(const int _apiVersion); void setApiVersion(int _apiVersion);
void setActive(const bool _state); void setActive(bool _state);
void setComment(const QString &_comment); void setComment(const QString &_comment);
void setCron(const QString &_cron); void setCron(const QString &_cron);
void setInterval(const int _interval); void setInterval(int _interval);
void setName(const QString &_name); void setName(const QString &_name);
void setNumber(int _number); void setNumber(int _number);
void setSocket(const QString &_socket); void setSocket(const QString &_socket);
@ -81,7 +79,7 @@ public slots:
virtual void readConfiguration(); virtual void readConfiguration();
virtual QVariantHash run() = 0; virtual QVariantHash run() = 0;
virtual int showConfiguration(const QVariant &_args) = 0; virtual int showConfiguration(const QVariant &_args) = 0;
virtual bool tryDelete() const; [[nodiscard]] virtual bool tryDelete() const;
virtual void writeConfiguration() const; virtual void writeConfiguration() const;
private slots: private slots:

View File

@ -20,32 +20,35 @@
#include <KI18n/KLocalizedString> #include <KI18n/KLocalizedString>
#include <QFileInfo> #include <QDir>
#include <QInputDialog> #include <QInputDialog>
#include <QPushButton> #include <QPushButton>
#include <utility>
AbstractExtItemAggregator::AbstractExtItemAggregator(QWidget *_parent, AbstractExtItemAggregator::AbstractExtItemAggregator(QWidget *_parent, QString _type)
const QString &_type)
: QDialog(_parent) : QDialog(_parent)
, ui(new Ui::AbstractExtItemAggregator) , ui(new Ui::AbstractExtItemAggregator)
, m_type(_type) , m_type(std::move(_type))
{ {
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
ui->setupUi(this); // create directory at $HOME
copyButton QString localDir = QString("%1/awesomewidgets/%2")
= ui->buttonBox->addButton(i18n("Copy"), QDialogButtonBox::ActionRole); .arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation))
createButton = ui->buttonBox->addButton(i18n("Create"), .arg(type());
QDialogButtonBox::ActionRole); QDir localDirectory;
deleteButton = ui->buttonBox->addButton(i18n("Remove"), if (localDirectory.mkpath(localDir))
QDialogButtonBox::ActionRole); qCInfo(LOG_LIB) << "Created directory" << localDir;
connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton *)), this, ui->setupUi(this);
SLOT(editItemButtonPressed(QAbstractButton *))); copyButton = ui->buttonBox->addButton(i18n("Copy"), QDialogButtonBox::ActionRole);
createButton = ui->buttonBox->addButton(i18n("Create"), QDialogButtonBox::ActionRole);
deleteButton = ui->buttonBox->addButton(i18n("Remove"), QDialogButtonBox::ActionRole);
connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(editItemButtonPressed(QAbstractButton *)));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(ui->listWidget, SIGNAL(itemActivated(QListWidgetItem *)), this, connect(ui->listWidget, SIGNAL(itemActivated(QListWidgetItem *)), this, SLOT(editItemActivated(QListWidgetItem *)));
SLOT(editItemActivated(QListWidgetItem *)));
} }
@ -63,8 +66,7 @@ void AbstractExtItemAggregator::copyItem()
QString fileName = getName(); QString fileName = getName();
int number = uniqNumber(); int number = uniqNumber();
QString dir = QString("%1/awesomewidgets/%2") QString dir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation( .arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation))
QStandardPaths::GenericDataLocation))
.arg(m_type); .arg(m_type);
if ((!source) || (fileName.isEmpty())) { if ((!source) || (fileName.isEmpty())) {
qCWarning(LOG_LIB) << "Nothing to copy"; qCWarning(LOG_LIB) << "Nothing to copy";
@ -86,7 +88,7 @@ void AbstractExtItemAggregator::deleteItem()
if (!source) { if (!source) {
qCWarning(LOG_LIB) << "Nothing to delete"; qCWarning(LOG_LIB) << "Nothing to delete";
return; return;
}; }
if (source->tryDelete()) { if (source->tryDelete()) {
initItems(); initItems();
@ -101,7 +103,7 @@ void AbstractExtItemAggregator::editItem()
if (!source) { if (!source) {
qCWarning(LOG_LIB) << "Nothing to edit"; qCWarning(LOG_LIB) << "Nothing to edit";
return; return;
}; }
if (source->showConfiguration(configArgs()) == 1) { if (source->showConfiguration(configArgs()) == 1) {
initItems(); initItems();
@ -113,9 +115,7 @@ void AbstractExtItemAggregator::editItem()
QString AbstractExtItemAggregator::getName() QString AbstractExtItemAggregator::getName()
{ {
bool ok; bool ok;
QString name QString name = QInputDialog::getText(this, i18n("Enter file name"), i18n("File name"), QLineEdit::Normal, "", &ok);
= QInputDialog::getText(this, i18n("Enter file name"),
i18n("File name"), QLineEdit::Normal, "", &ok);
if ((!ok) || (name.isEmpty())) if ((!ok) || (name.isEmpty()))
return ""; return "";
if (!name.endsWith(".desktop")) if (!name.endsWith(".desktop"))
@ -125,7 +125,7 @@ QString AbstractExtItemAggregator::getName()
} }
AbstractExtItem *AbstractExtItemAggregator::itemFromWidget() AbstractExtItem *AbstractExtItemAggregator::itemFromWidget() const
{ {
QListWidgetItem *widgetItem = ui->listWidget->currentItem(); QListWidgetItem *widgetItem = ui->listWidget->currentItem();
if (!widgetItem) if (!widgetItem)
@ -140,19 +140,18 @@ AbstractExtItem *AbstractExtItemAggregator::itemFromWidget()
break; break;
} }
if (!found) if (!found)
qCWarning(LOG_LIB) << "Could not find item by name" qCWarning(LOG_LIB) << "Could not find item by name" << widgetItem->text();
<< widgetItem->text();
return found; return found;
} }
void AbstractExtItemAggregator::repaintList() void AbstractExtItemAggregator::repaintList() const
{ {
ui->listWidget->clear(); ui->listWidget->clear();
for (auto &_item : items()) { for (auto &_item : items()) {
QString fileName = QFileInfo(_item->fileName()).fileName(); QString fileName = QFileInfo(_item->fileName()).fileName();
QListWidgetItem *item = new QListWidgetItem(fileName, ui->listWidget); auto *item = new QListWidgetItem(fileName, ui->listWidget);
QStringList tooltip; QStringList tooltip;
tooltip.append(i18n("Name: %1", _item->name())); tooltip.append(i18n("Name: %1", _item->name()));
tooltip.append(i18n("Comment: %1", _item->comment())); tooltip.append(i18n("Comment: %1", _item->comment()));
@ -182,6 +181,15 @@ QVariant AbstractExtItemAggregator::configArgs() const
} }
QStringList AbstractExtItemAggregator::directories() const
{
auto dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString("awesomewidgets/%1").arg(type()),
QStandardPaths::LocateDirectory);
return dirs;
}
QString AbstractExtItemAggregator::type() const QString AbstractExtItemAggregator::type() const
{ {
return m_type; return m_type;
@ -204,11 +212,11 @@ void AbstractExtItemAggregator::editItemActivated(QListWidgetItem *)
void AbstractExtItemAggregator::editItemButtonPressed(QAbstractButton *_button) void AbstractExtItemAggregator::editItemButtonPressed(QAbstractButton *_button)
{ {
if (static_cast<QPushButton *>(_button) == copyButton) if (dynamic_cast<QPushButton *>(_button) == copyButton)
return copyItem(); return copyItem();
else if (static_cast<QPushButton *>(_button) == createButton) else if (dynamic_cast<QPushButton *>(_button) == createButton)
return doCreateItem(); return doCreateItem();
else if (static_cast<QPushButton *>(_button) == deleteButton) else if (dynamic_cast<QPushButton *>(_button) == deleteButton)
return deleteItem(); return deleteItem();
else if (ui->buttonBox->buttonRole(_button) == QDialogButtonBox::AcceptRole) else if (ui->buttonBox->buttonRole(_button) == QDialogButtonBox::AcceptRole)
return editItem(); return editItem();

View File

@ -39,8 +39,8 @@ class AbstractExtItemAggregator : public QDialog
Q_PROPERTY(QVariant type READ type) Q_PROPERTY(QVariant type READ type)
public: public:
explicit AbstractExtItemAggregator(QWidget *_parent, const QString &_type); explicit AbstractExtItemAggregator(QWidget *_parent, QString _type);
virtual ~AbstractExtItemAggregator(); ~AbstractExtItemAggregator() override;
// methods // methods
void copyItem(); void copyItem();
template <class T> void createItem() template <class T> void createItem()
@ -48,13 +48,12 @@ public:
QString fileName = getName(); QString fileName = getName();
int number = uniqNumber(); int number = uniqNumber();
QString dir = QString("%1/awesomewidgets/%2") QString dir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation( .arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation))
QStandardPaths::GenericDataLocation))
.arg(m_type); .arg(m_type);
if (fileName.isEmpty()) { if (fileName.isEmpty()) {
qCWarning(LOG_LIB) << "Nothing to create"; qCWarning(LOG_LIB) << "Nothing to create";
return; return;
}; }
QString filePath = QString("%1/%2").arg(dir).arg(fileName); QString filePath = QString("%1/%2").arg(dir).arg(fileName);
T *newItem = new T(this, filePath); T *newItem = new T(this, filePath);
@ -62,18 +61,20 @@ public:
if (newItem->showConfiguration(configArgs()) == 1) { if (newItem->showConfiguration(configArgs()) == 1) {
initItems(); initItems();
repaintList(); repaintList();
}; }
}; };
void deleteItem(); void deleteItem();
void editItem(); void editItem();
QString getName(); QString getName();
AbstractExtItem *itemFromWidget(); virtual void initItems() = 0;
void repaintList(); [[nodiscard]] AbstractExtItem *itemFromWidget() const;
int uniqNumber() const; void repaintList() const;
[[nodiscard]] int uniqNumber() const;
// get methods // get methods
QVariant configArgs() const; [[nodiscard]] QVariant configArgs() const;
virtual QList<AbstractExtItem *> items() const = 0; [[nodiscard]] QStringList directories() const;
QString type() const; [[nodiscard]] virtual QList<AbstractExtItem *> items() const = 0;
[[nodiscard]] QString type() const;
// set methods // set methods
void setConfigArgs(const QVariant &_configArgs); void setConfigArgs(const QVariant &_configArgs);
@ -92,7 +93,6 @@ private:
QString m_type; QString m_type;
// ui methods // ui methods
virtual void doCreateItem() = 0; virtual void doCreateItem() = 0;
virtual void initItems() = 0;
}; };

View File

@ -0,0 +1,45 @@
/***************************************************************************
* 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 ABSTRACTQUOTESPROVIDER_H
#define ABSTRACTQUOTESPROVIDER_H
#include <QObject>
#include <QUrl>
#include "abstractextitem.h"
class AbstractQuotesProvider : public QObject
{
Q_OBJECT
public:
explicit AbstractQuotesProvider(QObject *_parent)
: QObject(_parent){};
~AbstractQuotesProvider() override = default;
virtual void initUrl(const QString &_asset) = 0;
[[nodiscard]] virtual QVariantHash parse(const QByteArray &_source, const QVariantHash &_oldValues) const = 0;
[[nodiscard]] QString tag(const QString &_type) const
{
return dynamic_cast<AbstractExtItem *>(parent())->tag(_type);
};
[[nodiscard]] virtual QUrl url() const = 0;
};
#endif /* ABSTRACTQUOTESPROVIDER_H */

View File

@ -21,26 +21,24 @@
#include <QObject> #include <QObject>
#include <QUrl> #include <QUrl>
#include "abstractextitem.h"
class AbstractWeatherProvider : public QObject class AbstractWeatherProvider : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int number READ number)
public: public:
explicit AbstractWeatherProvider(QObject *_parent, const int _number) explicit AbstractWeatherProvider(QObject *_parent)
: QObject(_parent) : QObject(_parent){};
, m_number(_number){}; ~AbstractWeatherProvider() override = default;
virtual ~AbstractWeatherProvider(){}; virtual void initUrl(const QString &_city, const QString &_country, int _ts) = 0;
virtual void initUrl(const QString &_city, const QString &_country, [[nodiscard]] virtual QVariantHash parse(const QVariantMap &_json) const = 0;
const int _ts) [[nodiscard]] QString tag(const QString &_type) const
= 0; {
virtual QVariantHash parse(const QVariantMap &_json) const = 0; return dynamic_cast<AbstractExtItem *>(parent())->tag(_type);
virtual QUrl url() const = 0; };
int number() const { return m_number; }; [[nodiscard]] virtual QUrl url() const = 0;
private:
int m_number;
}; };

View File

@ -22,8 +22,7 @@
#include "awdebug.h" #include "awdebug.h"
AWAbstractFormatter::AWAbstractFormatter(QWidget *_parent, AWAbstractFormatter::AWAbstractFormatter(QWidget *_parent, const QString &_filePath)
const QString &_filePath)
: AbstractExtItem(_parent, _filePath) : AbstractExtItem(_parent, _filePath)
{ {
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
@ -40,7 +39,7 @@ void AWAbstractFormatter::copyDefaults(AbstractExtItem *_other) const
{ {
AbstractExtItem::copyDefaults(_other); AbstractExtItem::copyDefaults(_other);
static_cast<AWAbstractFormatter *>(_other)->setType(type()); dynamic_cast<AWAbstractFormatter *>(_other)->setType(type());
} }
@ -108,8 +107,7 @@ void AWAbstractFormatter::setStrType(const QString &_type)
} }
void AWAbstractFormatter::setType( void AWAbstractFormatter::setType(const AWAbstractFormatter::FormatterClass _type)
const AWAbstractFormatter::FormatterClass _type)
{ {
qCDebug(LOG_LIB) << "Type" << static_cast<int>(_type); qCDebug(LOG_LIB) << "Type" << static_cast<int>(_type);

View File

@ -28,32 +28,23 @@ class AWAbstractFormatter : public AbstractExtItem
Q_PROPERTY(QString strType READ strType WRITE setStrType) Q_PROPERTY(QString strType READ strType WRITE setStrType)
public: public:
enum class FormatterClass { enum class FormatterClass { DateTime, Float, List, Script, String, NoFormat, Json };
DateTime,
Float,
List,
Script,
String,
NoFormat,
Json
};
explicit AWAbstractFormatter(QWidget *_parent = nullptr, explicit AWAbstractFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
const QString &_filePath = ""); ~AWAbstractFormatter() override;
virtual ~AWAbstractFormatter(); [[nodiscard]] virtual QString convert(const QVariant &_value) const = 0;
virtual QString convert(const QVariant &_value) const = 0; void copyDefaults(AbstractExtItem *_other) const override;
void copyDefaults(AbstractExtItem *_other) const; [[nodiscard]] QString uniq() const override;
QString uniq() const;
// properties // properties
QString strType() const; [[nodiscard]] QString strType() const;
FormatterClass type() const; [[nodiscard]] FormatterClass type() const;
void setStrType(const QString &_type); void setStrType(const QString &_type);
void setType(const FormatterClass _type); void setType(FormatterClass _type);
public slots: public slots:
virtual void readConfiguration(); void readConfiguration() override;
QVariantHash run() { return QVariantHash(); }; QVariantHash run() override { return {}; };
virtual void writeConfiguration() const; void writeConfiguration() const override;
private: private:
// properties // properties

View File

@ -22,23 +22,21 @@
#include <KI18n/KLocalizedString> #include <KI18n/KLocalizedString>
#include <QDateTime> #include <QDateTime>
#include <QDir>
#include <QSettings> #include <QSettings>
#include "awdebug.h" #include "awdebug.h"
AWDateTimeFormatter::AWDateTimeFormatter(QWidget *_parent, AWDateTimeFormatter::AWDateTimeFormatter(QWidget *_parent, const QString &_filePath)
const QString &_filePath)
: AWAbstractFormatter(_parent, _filePath) : AWAbstractFormatter(_parent, _filePath)
, ui(new Ui::AWDateTimeFormatter) , ui(new Ui::AWDateTimeFormatter)
{ {
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty()) if (!_filePath.isEmpty())
readConfiguration(); AWDateTimeFormatter::readConfiguration();
ui->setupUi(this); ui->setupUi(this);
translate(); AWDateTimeFormatter::translate();
} }
@ -58,13 +56,11 @@ QString AWDateTimeFormatter::convert(const QVariant &_value) const
} }
AWDateTimeFormatter *AWDateTimeFormatter::copy(const QString &_fileName, AWDateTimeFormatter *AWDateTimeFormatter::copy(const QString &_fileName, const int _number)
const int _number)
{ {
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
AWDateTimeFormatter *item auto *item = new AWDateTimeFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
= new AWDateTimeFormatter(static_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item); AWAbstractFormatter::copyDefaults(item);
item->setFormat(format()); item->setFormat(format());
item->setTranslateString(translateString()); item->setTranslateString(translateString());
@ -111,8 +107,7 @@ void AWDateTimeFormatter::readConfiguration()
settings.beginGroup("Desktop Entry"); settings.beginGroup("Desktop Entry");
setFormat(settings.value("X-AW-Format", format()).toString()); setFormat(settings.value("X-AW-Format", format()).toString());
setTranslateString( setTranslateString(settings.value("X-AW-Translate", translateString()).toBool());
settings.value("X-AW-Translate", translateString()).toBool());
settings.endGroup(); settings.endGroup();
bumpApi(AW_FORMATTER_API); bumpApi(AW_FORMATTER_API);
@ -127,8 +122,7 @@ int AWDateTimeFormatter::showConfiguration(const QVariant &_args)
ui->lineEdit_comment->setText(comment()); ui->lineEdit_comment->setText(comment());
ui->label_typeValue->setText("DateTime"); ui->label_typeValue->setText("DateTime");
ui->lineEdit_format->setText(format()); ui->lineEdit_format->setText(format());
ui->checkBox_translate->setCheckState(translateString() ? Qt::Checked ui->checkBox_translate->setCheckState(translateString() ? Qt::Checked : Qt::Unchecked);
: Qt::Unchecked);
int ret = exec(); int ret = exec();
if (ret != 1) if (ret != 1)

View File

@ -18,9 +18,10 @@
#ifndef AWDATETIMEFORMATTER_H #ifndef AWDATETIMEFORMATTER_H
#define AWDATETIMEFORMATTER_H #define AWDATETIMEFORMATTER_H
#include "awabstractformatter.h"
#include <QLocale> #include <QLocale>
#include "awabstractformatter.h"
namespace Ui namespace Ui
{ {
@ -31,30 +32,28 @@ class AWDateTimeFormatter : public AWAbstractFormatter
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString format READ format WRITE setFormat) Q_PROPERTY(QString format READ format WRITE setFormat)
Q_PROPERTY( Q_PROPERTY(bool translateString READ translateString WRITE setTranslateString)
bool translateString READ translateString WRITE setTranslateString)
public: public:
explicit AWDateTimeFormatter(QWidget *_parent = nullptr, explicit AWDateTimeFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
const QString &_filePath = ""); ~AWDateTimeFormatter() override;
virtual ~AWDateTimeFormatter(); [[nodiscard]] QString convert(const QVariant &_value) const override;
QString convert(const QVariant &_value) const; AWDateTimeFormatter *copy(const QString &_fileName, int _number) override;
AWDateTimeFormatter *copy(const QString &_fileName, const int _number);
// properties // properties
QString format() const; [[nodiscard]] QString format() const;
bool translateString() const; [[nodiscard]] bool translateString() const;
void setFormat(const QString &_format); void setFormat(const QString &_format);
void setTranslateString(const bool _translate); void setTranslateString(bool _translate);
public slots: public slots:
void readConfiguration(); void readConfiguration() override;
int showConfiguration(const QVariant &_args); int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const; void writeConfiguration() const override;
private: private:
Ui::AWDateTimeFormatter *ui = nullptr; Ui::AWDateTimeFormatter *ui = nullptr;
void initLocale(); void initLocale();
void translate(); void translate() override;
// properties // properties
QLocale m_locale; QLocale m_locale;
QString m_format = ""; QString m_format = "";

View File

@ -21,7 +21,6 @@
#include <KI18n/KLocalizedString> #include <KI18n/KLocalizedString>
#include <QDir>
#include <QSettings> #include <QSettings>
#include "awdebug.h" #include "awdebug.h"
@ -34,9 +33,9 @@ AWFloatFormatter::AWFloatFormatter(QWidget *_parent, const QString &_filePath)
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty()) if (!_filePath.isEmpty())
readConfiguration(); AWFloatFormatter::readConfiguration();
ui->setupUi(this); ui->setupUi(this);
translate(); AWFloatFormatter::translate();
} }
@ -53,8 +52,7 @@ QString AWFloatFormatter::convert(const QVariant &_value) const
qCDebug(LOG_LIB) << "Convert value" << _value; qCDebug(LOG_LIB) << "Convert value" << _value;
QString output QString output
= QString("%1").arg(_value.toDouble() * multiplier() + summand(), = QString("%1").arg(_value.toDouble() * multiplier() + summand(), count(), format(), precision(), fillChar());
count(), format(), precision(), fillChar());
if (forceWidth()) if (forceWidth())
output = output.left(count()); output = output.left(count());
@ -62,13 +60,11 @@ QString AWFloatFormatter::convert(const QVariant &_value) const
} }
AWFloatFormatter *AWFloatFormatter::copy(const QString &_fileName, AWFloatFormatter *AWFloatFormatter::copy(const QString &_fileName, const int _number)
const int _number)
{ {
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
AWFloatFormatter *item auto *item = new AWFloatFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
= new AWFloatFormatter(static_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item); AWAbstractFormatter::copyDefaults(item);
item->setCount(count()); item->setCount(count());
item->setFormat(format()); item->setFormat(format());
@ -153,8 +149,7 @@ void AWFloatFormatter::setFormat(char _format)
{ {
qCDebug(LOG_LIB) << "Set format" << _format; qCDebug(LOG_LIB) << "Set format" << _format;
// http://doc.qt.io/qt-5/qstring.html#argument-formats // http://doc.qt.io/qt-5/qstring.html#argument-formats
if ((_format != 'e') && (_format != 'E') && (_format != 'f') if ((_format != 'e') && (_format != 'E') && (_format != 'f') && (_format != 'g') && (_format != 'G')) {
&& (_format != 'g') && (_format != 'G')) {
qCWarning(LOG_LIB) << "Invalid format" << _format; qCWarning(LOG_LIB) << "Invalid format" << _format;
_format = 'f'; _format = 'f';
} }
@ -197,10 +192,7 @@ void AWFloatFormatter::readConfiguration()
setCount(settings.value("X-AW-Width", count()).toInt()); setCount(settings.value("X-AW-Width", count()).toInt());
setFillChar(settings.value("X-AW-FillChar", fillChar()).toString().at(0)); setFillChar(settings.value("X-AW-FillChar", fillChar()).toString().at(0));
setForceWidth(settings.value("X-AW-ForceWidth", forceWidth()).toBool()); setForceWidth(settings.value("X-AW-ForceWidth", forceWidth()).toBool());
setFormat(settings.value("X-AW-Format", QString(format())) setFormat(settings.value("X-AW-Format", QString(format())).toString().at(0).toLatin1());
.toString()
.at(0)
.toLatin1());
setMultiplier(settings.value("X-AW-Multiplier", multiplier()).toDouble()); setMultiplier(settings.value("X-AW-Multiplier", multiplier()).toDouble());
setPrecision(settings.value("X-AW-Precision", precision()).toInt()); setPrecision(settings.value("X-AW-Precision", precision()).toInt());
setSummand(settings.value("X-AW-Summand", summand()).toDouble()); setSummand(settings.value("X-AW-Summand", summand()).toDouble());
@ -217,13 +209,11 @@ int AWFloatFormatter::showConfiguration(const QVariant &_args)
ui->lineEdit_name->setText(name()); ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment()); ui->lineEdit_comment->setText(comment());
ui->label_typeValue->setText("Float"); ui->label_typeValue->setText("Float");
ui->comboBox_format->setCurrentIndex( ui->comboBox_format->setCurrentIndex(ui->comboBox_format->findText(QString(format())));
ui->comboBox_format->findText(QString(format())));
ui->spinBox_precision->setValue(precision()); ui->spinBox_precision->setValue(precision());
ui->spinBox_width->setValue(count()); ui->spinBox_width->setValue(count());
ui->lineEdit_fill->setText(QString(fillChar())); ui->lineEdit_fill->setText(QString(fillChar()));
ui->checkBox_forceWidth->setCheckState(forceWidth() ? Qt::Checked ui->checkBox_forceWidth->setCheckState(forceWidth() ? Qt::Checked : Qt::Unchecked);
: Qt::Unchecked);
ui->doubleSpinBox_multiplier->setValue(multiplier()); ui->doubleSpinBox_multiplier->setValue(multiplier());
ui->doubleSpinBox_summand->setValue(summand()); ui->doubleSpinBox_summand->setValue(summand());

View File

@ -38,35 +38,34 @@ class AWFloatFormatter : public AWAbstractFormatter
Q_PROPERTY(double summand READ summand WRITE setSummand) Q_PROPERTY(double summand READ summand WRITE setSummand)
public: public:
explicit AWFloatFormatter(QWidget *_parent = nullptr, explicit AWFloatFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
const QString &_filePath = ""); ~AWFloatFormatter() override;
virtual ~AWFloatFormatter(); [[nodiscard]] QString convert(const QVariant &_value) const override;
QString convert(const QVariant &_value) const; AWFloatFormatter *copy(const QString &_fileName, int _number) override;
AWFloatFormatter *copy(const QString &_fileName, const int _number);
// properties // properties
int count() const; [[nodiscard]] int count() const;
QChar fillChar() const; [[nodiscard]] QChar fillChar() const;
bool forceWidth() const; [[nodiscard]] bool forceWidth() const;
char format() const; [[nodiscard]] char format() const;
double multiplier() const; [[nodiscard]] double multiplier() const;
int precision() const; [[nodiscard]] int precision() const;
double summand() const; [[nodiscard]] double summand() const;
void setCount(const int _count); void setCount(int _count);
void setFillChar(const QChar &_fillChar); void setFillChar(const QChar &_fillChar);
void setForceWidth(const bool _forceWidth); void setForceWidth(bool _forceWidth);
void setFormat(char _format); void setFormat(char _format);
void setMultiplier(const double _multiplier); void setMultiplier(double _multiplier);
void setPrecision(const int _precision); void setPrecision(int _precision);
void setSummand(const double _summand); void setSummand(double _summand);
public slots: public slots:
void readConfiguration(); void readConfiguration() override;
int showConfiguration(const QVariant &_args); int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const; void writeConfiguration() const override;
private: private:
Ui::AWFloatFormatter *ui = nullptr; Ui::AWFloatFormatter *ui = nullptr;
void translate(); void translate() override;
// properties // properties
int m_count = 0; int m_count = 0;
QChar m_fillChar = QChar(); QChar m_fillChar = QChar();

View File

@ -34,9 +34,9 @@ AWJsonFormatter::AWJsonFormatter(QWidget *_parent, const QString &_filePath)
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty()) if (!_filePath.isEmpty())
readConfiguration(); AWJsonFormatter::readConfiguration();
ui->setupUi(this); ui->setupUi(this);
translate(); AWJsonFormatter::translate();
} }
@ -53,10 +53,8 @@ QString AWJsonFormatter::convert(const QVariant &_value) const
qCDebug(LOG_LIB) << "Convert value" << _value; qCDebug(LOG_LIB) << "Convert value" << _value;
// check if _value is string and parse first if required // check if _value is string and parse first if required
QJsonDocument json QJsonDocument json = _value.type() == QVariant::String ? QJsonDocument::fromJson(_value.toString().toUtf8())
= _value.type() == QVariant::String : QJsonDocument::fromVariant(_value);
? QJsonDocument::fromJson(_value.toString().toUtf8())
: QJsonDocument::fromVariant(_value);
QVariant converted = json.toVariant(); QVariant converted = json.toVariant();
for (auto &element : m_splittedPath) for (auto &element : m_splittedPath)
converted = getFromJson(converted, element); converted = getFromJson(converted, element);
@ -65,13 +63,11 @@ QString AWJsonFormatter::convert(const QVariant &_value) const
} }
AWJsonFormatter *AWJsonFormatter::copy(const QString &_fileName, AWJsonFormatter *AWJsonFormatter::copy(const QString &_fileName, const int _number)
const int _number)
{ {
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
AWJsonFormatter *item auto *item = new AWJsonFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
= new AWJsonFormatter(static_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item); AWAbstractFormatter::copyDefaults(item);
item->setNumber(_number); item->setNumber(_number);
item->setPath(path()); item->setPath(path());
@ -147,8 +143,7 @@ void AWJsonFormatter::writeConfiguration() const
} }
QVariant AWJsonFormatter::getFromJson(const QVariant &_value, QVariant AWJsonFormatter::getFromJson(const QVariant &_value, const QVariant &_element)
const QVariant &_element) const
{ {
qCDebug(LOG_LIB) << "Looking for element" << _element << "in" << _value; qCDebug(LOG_LIB) << "Looking for element" << _element << "in" << _value;
@ -163,8 +158,7 @@ QVariant AWJsonFormatter::getFromJson(const QVariant &_value,
} }
QVariant AWJsonFormatter::getFromList(const QVariant &_value, QVariant AWJsonFormatter::getFromList(const QVariant &_value, const int _index)
const int _index) const
{ {
qCDebug(LOG_LIB) << "Looking for index" << _index << "in" << _value; qCDebug(LOG_LIB) << "Looking for index" << _index << "in" << _value;
@ -172,8 +166,7 @@ QVariant AWJsonFormatter::getFromList(const QVariant &_value,
} }
QVariant AWJsonFormatter::getFromMap(const QVariant &_value, QVariant AWJsonFormatter::getFromMap(const QVariant &_value, const QString &_key)
const QString &_key) const
{ {
qCDebug(LOG_LIB) << "Looking for key" << _key << "in" << _value; qCDebug(LOG_LIB) << "Looking for key" << _key << "in" << _value;
@ -184,7 +177,7 @@ QVariant AWJsonFormatter::getFromMap(const QVariant &_value,
void AWJsonFormatter::initPath() void AWJsonFormatter::initPath()
{ {
m_splittedPath.clear(); m_splittedPath.clear();
QStringList splittedByDot = m_path.split('.', QString::SkipEmptyParts); QStringList splittedByDot = m_path.split('.', Qt::SkipEmptyParts);
for (auto &element : splittedByDot) { for (auto &element : splittedByDot) {
bool ok; bool ok;

View File

@ -32,28 +32,26 @@ class AWJsonFormatter : public AWAbstractFormatter
Q_PROPERTY(QString path READ path WRITE setPath) Q_PROPERTY(QString path READ path WRITE setPath)
public: public:
explicit AWJsonFormatter(QWidget *_parent = nullptr, explicit AWJsonFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
const QString &_filePath = ""); ~AWJsonFormatter() override;
virtual ~AWJsonFormatter(); [[nodiscard]] QString convert(const QVariant &_value) const override;
QString convert(const QVariant &_value) const; AWJsonFormatter *copy(const QString &_fileName, int _number) override;
AWJsonFormatter *copy(const QString &_fileName, const int _number);
// properties // properties
QString path() const; [[nodiscard]] QString path() const;
void setPath(const QString &_path); void setPath(const QString &_path);
public slots: public slots:
void readConfiguration(); void readConfiguration() override;
int showConfiguration(const QVariant &_args); int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const; void writeConfiguration() const override;
private: private:
Ui::AWJsonFormatter *ui = nullptr; Ui::AWJsonFormatter *ui = nullptr;
QVariant getFromJson(const QVariant &_value, static QVariant getFromJson(const QVariant &_value, const QVariant &_element);
const QVariant &_element) const; static QVariant getFromList(const QVariant &_value, int _index);
QVariant getFromList(const QVariant &_value, const int _index) const; static QVariant getFromMap(const QVariant &_value, const QString &_key);
QVariant getFromMap(const QVariant &_value, const QString &_key) const;
void initPath(); void initPath();
void translate(); void translate() override;
// properties // properties
QString m_path; QString m_path;
QVariantList m_splittedPath; QVariantList m_splittedPath;

View File

@ -33,9 +33,9 @@ AWListFormatter::AWListFormatter(QWidget *_parent, const QString &_filePath)
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty()) if (!_filePath.isEmpty())
readConfiguration(); AWListFormatter::readConfiguration();
ui->setupUi(this); ui->setupUi(this);
translate(); AWListFormatter::translate();
} }
@ -59,13 +59,11 @@ QString AWListFormatter::convert(const QVariant &_value) const
} }
AWListFormatter *AWListFormatter::copy(const QString &_fileName, AWListFormatter *AWListFormatter::copy(const QString &_fileName, const int _number)
const int _number)
{ {
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
AWListFormatter *item auto *item = new AWListFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
= new AWListFormatter(static_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item); AWAbstractFormatter::copyDefaults(item);
item->setFilter(filter()); item->setFilter(filter());
item->setSeparator(separator()); item->setSeparator(separator());
@ -144,8 +142,7 @@ int AWListFormatter::showConfiguration(const QVariant &_args)
ui->label_typeValue->setText("List"); ui->label_typeValue->setText("List");
ui->lineEdit_filter->setText(filter()); ui->lineEdit_filter->setText(filter());
ui->lineEdit_separator->setText(separator()); ui->lineEdit_separator->setText(separator());
ui->checkBox_sorted->setCheckState(isSorted() ? Qt::Checked ui->checkBox_sorted->setCheckState(isSorted() ? Qt::Checked : Qt::Unchecked);
: Qt::Unchecked);
int ret = exec(); int ret = exec();
if (ret != 1) if (ret != 1)

View File

@ -34,27 +34,26 @@ class AWListFormatter : public AWAbstractFormatter
Q_PROPERTY(bool sorted READ isSorted WRITE setSorted) Q_PROPERTY(bool sorted READ isSorted WRITE setSorted)
public: public:
explicit AWListFormatter(QWidget *_parent = nullptr, explicit AWListFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
const QString &_filePath = ""); ~AWListFormatter() override;
virtual ~AWListFormatter(); [[nodiscard]] QString convert(const QVariant &_value) const override;
QString convert(const QVariant &_value) const; AWListFormatter *copy(const QString &_fileName, int _number) override;
AWListFormatter *copy(const QString &_fileName, const int _number);
// properties // properties
QString filter() const; [[nodiscard]] QString filter() const;
bool isSorted() const; [[nodiscard]] bool isSorted() const;
QString separator() const; [[nodiscard]] QString separator() const;
void setFilter(const QString &_filter); void setFilter(const QString &_filter);
void setSeparator(const QString &_separator); void setSeparator(const QString &_separator);
void setSorted(const bool _sorted); void setSorted(bool _sorted);
public slots: public slots:
void readConfiguration(); void readConfiguration() override;
int showConfiguration(const QVariant &_args); int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const; void writeConfiguration() const override;
private: private:
Ui::AWListFormatter *ui = nullptr; Ui::AWListFormatter *ui = nullptr;
void translate(); void translate() override;
// properties // properties
QString m_filter = ""; QString m_filter = "";
QString m_separator = ""; QString m_separator = "";

View File

@ -31,9 +31,9 @@ AWNoFormatter::AWNoFormatter(QWidget *_parent, const QString &_filePath)
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty()) if (!_filePath.isEmpty())
readConfiguration(); AWNoFormatter::readConfiguration();
ui->setupUi(this); ui->setupUi(this);
translate(); AWNoFormatter::translate();
} }
@ -57,8 +57,7 @@ AWNoFormatter *AWNoFormatter::copy(const QString &_fileName, const int _number)
{ {
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number; qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
AWNoFormatter *item auto *item = new AWNoFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
= new AWNoFormatter(static_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item); AWAbstractFormatter::copyDefaults(item);
item->setNumber(_number); item->setNumber(_number);

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