Compare commits

..

No commits in common. "84e5b7d64eb0ec7ab3dc6a04156bf5823e1e4cc4" and "eecb128865d463a5e8faeb09f2b0b7d9d6d682f0" have entirely different histories.

288 changed files with 7828 additions and 4966 deletions

View File

@ -2,11 +2,9 @@ name: build & tests
on:
push:
branches:
- master
branches: [ development, master ]
pull_request:
branches:
- master
branches: [ development, master ]
env:
BUILD_TYPE: Release
@ -26,13 +24,13 @@ jobs:
- uses: actions/checkout@v3
- name: create build environment
run: pacman -Syu --noconfirm base-devel cmake extra-cmake-modules python util-linux-libs xorg-server-xvfb
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
run: pacman -S --noconfirm plasma-workspace ksysguard
- name: configure cmake
run: cmake -B build -S sources -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_FUTURE=ON -DBUILD_TESTING=ON
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

View File

@ -25,17 +25,17 @@ jobs:
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: 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
@ -45,7 +45,7 @@ jobs:
${{ steps.changelog.outputs.changelog }}
files: |
awesome-widgets-*-src.tar.xz
# build-deb/plasma-widget-awesome-widgets-*.deb
build-deb/plasma-widget-awesome-widgets-*.deb
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,6 +1,3 @@
Ver.4.0.0:
* migration to plasma 6
Ver.3.5.0:
+ wayland support
* update code to latest standards
@ -15,6 +12,7 @@ Ver.3.4.2:
* update to new qt api
- fix non printable spaces (#142, #143)
Ver.3.3.3:
+ add custom keys support (#101)
* DBus interface improvements

View File

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

View File

@ -14,11 +14,11 @@ A collection of minimalistic widgets which looks like Awesome Window Manager wid
Features
========
* easy and fully configurable native Plasma widget which may be used as desktop or panel widget
* additionnal widget which shows active desktop status
* clear text configuration with html tags support
* easy and fully configurable native Plasma widget which may be used as Conky widget or as Awesome-like information panel
* panel which shows active desktop status
* clear Conky-like configuration with html tags support
* custom command support (it may be simple action as well as special custom tag)
* graphical widgets support - tooltips, bars
* graphical item support - tooltips, bars
See [links](#Links) for more details.
@ -30,11 +30,15 @@ Instruction
Dependencies
------------
* plasma-workspace
* plasma-framework
* ksysguard (since plasma 5.22)
Optional dependencies
---------------------
* proprietary video driver
* hddtemp
* smartmontools
* music player (mpd or MPRIS supported)
* wireless_tools
@ -44,20 +48,19 @@ Make dependencies
* cmake
* 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).
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
------------
* download sources
* build package
* install
cmake -B build -S sources -DCMAKE_BUILD_TYPE=Release
cmake --build build
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr ../sources
make && sudo make install
* install package
cmake --install build
**NOTE** on Plasma 5 it very likely requires `-DKDE_INSTALL_USE_QT_SYS_PATHS=ON` flag
Additional information
======================

View File

@ -1,31 +1,41 @@
# Maintainer: Evgeniy Alekseev <arcanis at archlinux dot org>
pkgname=plasma6-applet-awesome-widgets
pkgname=plasma5-applet-awesome-widgets
_pkgname=awesome-widgets
pkgver=4.0.0alpha2
pkgver=3.4.3
pkgrel=1
pkgdesc="Collection of minimalistic Plasmoids which look like Awesome WM widgets (ex-PyTextMonitor)"
arch=('x86_64')
arch=('i686' 'x86_64')
url="https://arcanis.me/projects/awesome-widgets"
license=('GPL3')
depends=('plasma-workspace')
optdepends=("mpd: for music player monitor"
"wireless_tools: wifi information")
depends=('ksysguard' 'plasma-framework')
optdepends=("catalyst: for GPU monitor"
"hddtemp: for HDD temperature monitor"
"smartmontools: for HDD temperature monitor"
"mpd: for music player monitor"
"nvidia-utils: for GPU monitor")
makedepends=('cmake' 'extra-cmake-modules' 'python')
source=(https://github.com/arcan1s/awesome-widgets/releases/download/${pkgver}/${_pkgname}-${pkgver}-src.tar.xz)
install="$pkgname.install"
source=(https://github.com/arcan1s/awesome-widgets/releases/download/V.${pkgver}/${_pkgname}-${pkgver}-src.tar.xz)
install=${pkgname}.install
md5sums=('5953ba518191bb6fff83cdb8633c735c')
backup=('etc/xdg/plasma-dataengine-extsysmon.conf')
prepare() {
rm -rf "${srcdir}/build"
mkdir "${srcdir}/build"
}
build () {
cmake -B build -S "${_pkgname}" \
-DCMAKE_BUILD_TYPE=Optimization \
-DBUILD_FUTURE=ON \
-DBUILD_TESTING=OFF
cmake --build build
cd "${srcdir}/build"
cmake -DKDE_INSTALL_USE_QT_SYS_PATHS=ON \
-DCMAKE_BUILD_TYPE=Optimization \
-DCMAKE_INSTALL_PREFIX=/usr \
-DBUILD_FUTURE=ON \
"../${_pkgname}"
make
}
package() {
DESTDIR="$pkgdir" cmake --install build
cd "${srcdir}/build"
make DESTDIR="${pkgdir}" install
}
sha256sums=('b2a7b07a1df6f710f4e0d6e5898933f4ddb131818b922dc4b8e48afe3e98a664')

View File

@ -39,6 +39,81 @@ void CFont::setCurrentColor(const QColor 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);
@ -58,7 +133,7 @@ CFontDialog::CFontDialog(QWidget *parent, bool needWeight, bool needItalic)
setLayout(mainGrid);
colorBox = new QComboBox(this);
connect(colorBox, &QComboBox::currentTextChanged, this, &CFontDialog::updateColor);
connect(colorBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateColor(QString)));
QStringList colorNames = QColor::colorNames();
int index = 0;
for (int i=0; i<colorNames.count(); i++) {
@ -81,8 +156,8 @@ CFontDialog::CFontDialog(QWidget *parent, bool needWeight, bool needItalic)
buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, this);
QObject::connect(buttons, &QDialogButtonBox::accepted, this, &CFontDialog::accept);
QObject::connect(buttons, &QDialogButtonBox::rejected, this, &CFontDialog::reject);
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);

View File

@ -15,7 +15,8 @@
* License along with this library. *
***************************************************************************/
#pragma once
#ifndef FONTDIALOG_H
#define FONTDIALOG_H
#include <QComboBox>
#include <QDialog>
@ -33,6 +34,11 @@ public:
// 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")));
@ -71,3 +77,6 @@ private:
QSpinBox *sizeBox;
QSpinBox *weightBox;
};
#endif /* FONTDIALOG_H */

View File

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

View File

@ -9,17 +9,14 @@ endif ()
if (POLICY CMP0071)
cmake_policy(SET CMP0071 NEW)
endif ()
if (POLICY CMP0160)
cmake_policy(SET CMP0160 OLD)
endif ()
project(awesomewidgets)
set(PROJECT_AUTHOR "Evgeniy Alekseev")
set(PROJECT_CONTACT "esalexeev@gmail.com")
set(PROJECT_LICENSE "GPL3")
set(PROJECT_VERSION_MAJOR "4")
set(PROJECT_VERSION_MINOR "0")
set(PROJECT_VERSION_PATCH "0")
set(PROJECT_VERSION_MAJOR "3")
set(PROJECT_VERSION_MINOR "5")
set(PROJECT_VERSION_PATCH "1")
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
# append git version if any
set(PROJECT_COMMIT_SHA "Commit hash" CACHE INTERNAL "")

View File

@ -41,32 +41,35 @@ QString AWDebug::getAboutText(const QString &_type)
} else if (_type == "description") {
text = i18n("A set of minimalistic plasmoid widgets");
} else if (_type == "links") {
text = i18n("Links:") + "<ul>" + QString("<li><a href=\"%1\">%2</a></li>").arg(HOMEPAGE, i18n("Homepage"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(REPOSITORY, i18n("Repository"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(BUGTRACKER, i18n("Bugtracker"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(TRANSLATION, i18n("Translation issue"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(AUR_PACKAGES, i18n("AUR packages"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(OPENSUSE_PACKAGES, i18n("openSUSE packages")) + "</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>").arg(REPOSITORY).arg(i18n("Repository"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(BUGTRACKER).arg(i18n("Bugtracker"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(TRANSLATION).arg(i18n("Translation issue"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(AUR_PACKAGES).arg(i18n("AUR packages"))
+ QString("<li><a href=\"%1\">%2</a></li>").arg(OPENSUSE_PACKAGES).arg(i18n("openSUSE packages"))
+ "</ul>";
} else if (_type == "copy") {
text = QString("<small>&copy; %1 <a href=\"mailto:%2\">%3</a><br>").arg(DATE, EMAIL, AUTHOR)
+ i18n("This software is licensed under %1", LICENSE) + "</small>";
text = QString("<small>&copy; %1 <a href=\"mailto:%2\">%3</a><br>").arg(DATE).arg(EMAIL).arg(AUTHOR)
+ i18nc("This software is licensed under %1", LICENSE) + "</small>";
} else if (_type == "translators") {
auto translatorList = QString(TRANSLATORS).split(',');
QStringList translatorList = QString(TRANSLATORS).split(',');
for (auto &translator : translatorList)
translator = QString("<li>%1</li>").arg(translator);
text = i18n("Translators:") + "<ul>" + translatorList.join("") + "</ul>";
} else if (_type == "3rdparty") {
auto trdPartyList = QString(TRDPARTY_LICENSE).split(';', Qt::SkipEmptyParts);
for (auto i = 0; i < trdPartyList.count(); ++i)
QStringList trdPartyList = QString(TRDPARTY_LICENSE).split(';', Qt::SkipEmptyParts);
for (int i = 0; i < trdPartyList.count(); i++)
trdPartyList[i] = QString("<li><a href=\"%3\">%1</a> (%2 license)</li>")
.arg(trdPartyList.at(i).split(',')[0], trdPartyList.at(i).split(',')[1],
trdPartyList.at(i).split(',')[2]);
.arg(trdPartyList.at(i).split(',')[0])
.arg(trdPartyList.at(i).split(',')[1])
.arg(trdPartyList.at(i).split(',')[2]);
text = i18n("This software uses:") + "<ul>" + trdPartyList.join("") + "</ul>";
} else if (_type == "thanks") {
auto thanks = QString(SPECIAL_THANKS).split(';', Qt::SkipEmptyParts);
for (auto i = 0; i < thanks.count(); ++i)
thanks[i]
= QString("<li><a href=\"%2\">%1</a></li>").arg(thanks.at(i).split(',')[0], thanks.at(i).split(',')[1]);
QStringList thanks = QString(SPECIAL_THANKS).split(';', Qt::SkipEmptyParts);
for (int i = 0; i < thanks.count(); i++)
thanks[i] = QString("<li><a href=\"%2\">%1</a></li>")
.arg(thanks.at(i).split(',')[0])
.arg(thanks.at(i).split(',')[1]);
text = i18n("Special thanks to:") + "<ul>" + thanks.join("") + "</ul>";
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWDEBUG_H
#define AWDEBUG_H
#include <QLoggingCategory>
@ -40,3 +42,6 @@ Q_DECLARE_LOGGING_CATEGORY(LOG_DP)
Q_DECLARE_LOGGING_CATEGORY(LOG_ESM)
Q_DECLARE_LOGGING_CATEGORY(LOG_ESS)
Q_DECLARE_LOGGING_CATEGORY(LOG_LIB)
#endif /* AWDEBUG_H */

View File

@ -1,7 +1,7 @@
set(SUBPROJECT plasma_applet_awesome-widget)
message(STATUS "Subproject ${SUBPROJECT}")
configure_file(metadata.json ${CMAKE_CURRENT_SOURCE_DIR}/package/metadata.json)
configure_file(metadata.desktop ${CMAKE_CURRENT_SOURCE_DIR}/package/metadata.desktop)
add_subdirectory(plugin)
plasma_install_package(package org.kde.plasma.awesomewidget)

View File

@ -0,0 +1,26 @@
[Desktop Entry]
Encoding=UTF-8
Name=Awesome Widget
Comment=A minimalistic Plasmoid
Comment[en]=A minimalistic Plasmoid
Comment[es]=Un plasmoide minimalista
Comment[es]=Un script Plasmoïde minimaliste
Comment[pt_BR]=Um script Plasmoid
Comment[ru]=Минималистичный плазмоид
Comment[uk]=Мінімалістичний плазмоїд
X-KDE-ServiceTypes=Plasma/Applet
Type=Service
Icon=utilities-system-monitor
X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis
X-KDE-PluginInfo-Email=esalexeev@gmail.com
X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget
X-KDE-PluginInfo-Version=@PROJECT_VERSION@
X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/
X-KDE-PluginInfo-Category=System Information
X-KDE-PluginInfo-License=GPLv3
X-KDE-PluginInfo-EnabledByDefault=true

View File

@ -1,26 +0,0 @@
{
"KPackageStructure": "Plasma/Applet",
"KPlugin": {
"Authors": [
{
"Email": "esalexeev@gmail.com",
"Name": "Evgeniy Alekseev aka arcanis"
}
],
"Category": "System Information",
"Description": "A minimalistic Plasmoid",
"Description[en]": "A minimalistic Plasmoid",
"Description[es]": "Un script Plasmoïde minimaliste",
"Description[pt_BR]": "Um script Plasmoid",
"Description[ru]": "Минималистичный плазмоид",
"Description[uk]": "Мінімалістичний плазмоїд",
"EnabledByDefault": true,
"Icon": "utilities-system-monitor",
"Id": "org.kde.plasma.awesomewidget",
"License": "GPLv3",
"Name": "Awesome Widget",
"Version": "@PROJECT_VERSION@",
"Website": "https://arcanis.me/projects/awesome-widgets/"
},
"X-Plasma-API-Minimum-Version": "6.0"
}

View File

@ -15,7 +15,7 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
import QtQuick 2.15
import QtQuick 2.0
import org.kde.plasma.configuration 2.0
@ -51,12 +51,6 @@ ConfigModel {
source: "dataengine.qml"
}
ConfigCategory {
name: i18n("Report bug")
icon: "tools-report-bug"
source: "bug.qml"
}
ConfigCategory {
name: i18n("About")
icon: "help-about"

View File

@ -7,141 +7,150 @@
<group name="Widget">
<!-- widget -->
<entry name="text" type="String">
<entry name="text" type="string">
<default>[cpu: $cpu%] [mem: $mem%] [swap: $swap%] [$netdev: $down/$upKB/s]</default>
</entry>
</group>
<group name="Advanced">
<!-- advanced -->
<entry name="background" type="Bool">
<entry name="background" type="bool">
<default>true</default>
</entry>
<entry name="translateStrings" type="Bool">
<entry name="translateStrings" type="bool">
<default>true</default>
</entry>
<entry name="wrapNewLines" type="Bool">
<entry name="wrapNewLines" type="bool">
<default>false</default>
</entry>
<entry name="wrapText" type="Bool">
<entry name="wrapText" type="bool">
<default>false</default>
</entry>
<entry name="notify" type="Bool">
<entry name="notify" type="bool">
<default>true</default>
</entry>
<entry name="checkUpdates" type="Bool">
<entry name="checkUpdates" type="bool">
<default>true</default>
</entry>
<entry name="optimize" type="Bool">
<entry name="optimize" type="bool">
<default>true</default>
</entry>
<entry name="height" type="Int">
<entry name="height" type="int">
<default>0</default>
</entry>
<entry name="width" type="Int">
<entry name="width" type="int">
<default>0</default>
</entry>
<entry name="interval" type="Int">
<entry name="interval" type="int">
<default>1000</default>
</entry>
<entry name="tempUnits" type="String">
<entry name="queueLimit" type="int">
<default>0</default>
</entry>
<entry name="tempUnits" type="string">
<default>Celsius</default>
</entry>
<entry name="customTime" type="String">
<entry name="customTime" type="string">
<default>$hh:$mm</default>
</entry>
<entry name="customUptime" type="String">
<entry name="customUptime" type="string">
<default>$dd,$hh,$mm</default>
</entry>
<entry name="acOnline" type="String">
<entry name="acOnline" type="string">
<default>(*)</default>
</entry>
<entry name="acOffline" type="String">
<entry name="acOffline" type="string">
<default>( )</default>
</entry>
<entry name="historyCount" type="Int">
<entry name="telemetryCount" type="int">
<default>100</default>
</entry>
<entry name="telemetryRemote" type="bool">
<default>false</default>
</entry>
<entry name="telemetryId" type="string">
<default></default>
</entry>
</group>
<group name="Tooltip">
<entry name="tooltipNumber" type="Int">
<entry name="tooltipNumber" type="int">
<default>100</default>
</entry>
<entry name="useTooltipBackground" type="Bool">
<entry name="useTooltipBackground" type="bool">
<default>true</default>
</entry>
<entry name="tooltipBackground" type="String">
<entry name="tooltipBackground" type="string">
<default>#ffffff</default>
</entry>
<entry name="cpuTooltip" type="Bool">
<entry name="cpuTooltip" type="bool">
<default>true</default>
</entry>
<entry name="cpuTooltipColor" type="String">
<entry name="cpuTooltipColor" type="string">
<default>#ff0000</default>
</entry>
<entry name="cpuclTooltip" type="Bool">
<entry name="cpuclTooltip" type="bool">
<default>true</default>
</entry>
<entry name="cpuclTooltipColor" type="String">
<entry name="cpuclTooltipColor" type="string">
<default>#00ff00</default>
</entry>
<entry name="memTooltip" type="Bool">
<entry name="memTooltip" type="bool">
<default>true</default>
</entry>
<entry name="memTooltipColor" type="String">
<entry name="memTooltipColor" type="string">
<default>#0000ff</default>
</entry>
<entry name="swapTooltip" type="Bool">
<entry name="swapTooltip" type="bool">
<default>true</default>
</entry>
<entry name="swapTooltipColor" type="String">
<entry name="swapTooltipColor" type="string">
<default>#ffff00</default>
</entry>
<entry name="downkbTooltip" type="Bool">
<entry name="downkbTooltip" type="bool">
<default>true</default>
</entry>
<entry name="downkbTooltipColor" type="String">
<entry name="downkbTooltipColor" type="string">
<default>#00ffff</default>
</entry>
<entry name="upkbTooltipColor" type="String">
<entry name="upkbTooltipColor" type="string">
<default>#ff00ff</default>
</entry>
<entry name="batTooltip" type="Bool">
<entry name="batTooltip" type="bool">
<default>true</default>
</entry>
<entry name="batTooltipColor" type="String">
<entry name="batTooltipColor" type="string">
<default>#008800</default>
</entry>
<entry name="batInTooltipColor" type="String">
<entry name="batInTooltipColor" type="string">
<default>#880000</default>
</entry>
</group>
<group name="Appearance">
<!-- appearance -->
<entry name="textAlign" type="String">
<entry name="textAlign" type="string">
<default>center</default>
</entry>
<entry name="fontFamily" type="String">
<entry name="fontFamily" type="string">
<default>Terminus</default>
</entry>
<entry name="fontSize" type="Int">
<entry name="fontSize" type="int">
<default>12</default>
</entry>
<entry name="fontColor" type="String">
<entry name="fontColor" type="string">
<default>#000000</default>
</entry>
<entry name="fontWeight" type="String">
<entry name="fontWeight" type="string">
<default>normal</default>
</entry>
<entry name="fontStyle" type="String">
<entry name="fontStyle" type="string">
<default>normal</default>
</entry>
<entry name="textStyle" type="String">
<entry name="textStyle" type="string">
<default>normal</default>
</entry>
<entry name="textStyleColor" type="String">
<entry name="textStyleColor" type="string">
<default>#000000</default>
</entry>
</group>

View File

@ -15,22 +15,28 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
import QtQuick 2.15
import org.kde.kcmutils as KCM
import QtQuick 2.0
import org.kde.plasma.awesomewidgets
import org.kde.plasma.private.awesomewidget
import org.kde.plasma.private.awesomewidget 1.0
KCM.SimpleKCM {
Item {
id: aboutPage
// backend
AWActions {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
property bool debug: awActions.isDebugEnabled()
AboutTab {
textProvider: awActions
}
Component.onCompleted: {
if (debug) console.debug()
}
}

View File

@ -15,22 +15,26 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
import QtQuick 2.15
import QtQuick.Controls
import org.kde.kcmutils as KCM
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import org.kde.plasma.awesomewidgets
import org.kde.plasma.private.awesomewidget
import org.kde.plasma.private.awesomewidget 1.0
KCM.SimpleKCM {
Item {
id: advancedPage
// backend
AWConfigHelper {
id: awConfig
AWActions {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: awActions.isDebugEnabled()
property alias cfg_background: background.checked
property alias cfg_translateStrings: translate.checked
property alias cfg_wrapNewLines: wrapNewLines.checked
@ -41,14 +45,19 @@ KCM.SimpleKCM {
property alias cfg_height: widgetHeight.value
property alias cfg_width: widgetWidth.value
property alias cfg_interval: update.value
property alias cfg_queueLimit: queueLimit.value
property string cfg_tempUnits: tempUnits.value
property alias cfg_customTime: customTime.value
property alias cfg_customUptime: customUptime.value
property alias cfg_acOnline: acOnline.value
property alias cfg_acOffline: acOffline.value
property alias cfg_historyCount: historyCount.value
property alias cfg_telemetryCount: telemetryCount.value
property alias cfg_telemetryRemote: telemetryRemote.checked
property alias cfg_telemetryId: telemetryId.value
Column {
id: pageColumn
anchors.fill: parent
CheckBoxSelector {
@ -113,41 +122,50 @@ KCM.SimpleKCM {
value: plasmoid.configuration.interval
}
IntegerSelector {
id: queueLimit
maximumValue: 99
minimumValue: 0
stepSize: 1
text: i18n("Messages queue limit")
value: plasmoid.configuration.queueLimit
}
ComboBoxSelector {
id: tempUnits
model: [
{
"label": i18n("Celsius"),
"name": "Celsius"
'label': i18n("Celsius"),
'name': "Celsius"
},
{
"label": i18n("Fahrenheit"),
"name": "Fahrenheit"
'label': i18n("Fahrenheit"),
'name': "Fahrenheit"
},
{
"label": i18n("Kelvin"),
"name": "Kelvin"
'label': i18n("Kelvin"),
'name': "Kelvin"
},
{
"label": i18n("Reaumur"),
"name": "Reaumur"
'label': i18n("Reaumur"),
'name': "Reaumur"
},
{
"label": i18n("cm^-1"),
"name": "cm^-1"
'label': i18n("cm^-1"),
'name': "cm^-1"
},
{
"label": i18n("kJ/mol"),
"name": "kJ/mol"
'label': i18n("kJ/mol"),
'name': "kJ/mol"
},
{
"label": i18n("kcal/mol"),
"name": "kcal/mol"
'label': i18n("kcal/mol"),
'name': "kcal/mol"
}
]
text: i18n("Temperature units")
value: plasmoid.configuration.tempUnits
onValueEdited: newValue => cfg_tempUnits = newValue
onValueEdited: cfg_tempUnits = newValue
}
LineSelector {
@ -174,20 +192,18 @@ KCM.SimpleKCM {
value: plasmoid.configuration.acOffline
}
GroupBox {
width: parent.width
QtControls.GroupBox {
height: implicitHeight
width: parent.width
title: i18n("Actions")
Column {
height: implicitHeight
width: parent.width
ButtonSelector {
value: i18n("Drop key cache")
onButtonActivated: awConfig.dropCache()
onButtonActivated: awActions.dropCache()
}
ButtonSelector {
ExportDialog {
id: saveConfigAs
@ -196,12 +212,11 @@ KCM.SimpleKCM {
value: i18n("Export configuration")
onButtonActivated: saveConfigAs.open()
}
ButtonSelector {
ImportDialog {
id: loadConfigFrom
onConfigurationReceived: {
for (const key in configuration)
for (var key in configuration)
plasmoid.configuration[key] = configuration[key]
}
}
@ -211,24 +226,37 @@ KCM.SimpleKCM {
}
}
GroupBox {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
title: i18n("History")
title: i18n("Telemetry")
Column {
height: implicitHeight
width: parent.width
CheckBoxSelector {
id: telemetryRemote
text: i18n("Enable remote telemetry")
}
IntegerSelector {
id: historyCount
id: telemetryCount
maximumValue: 10000
minimumValue: 0
stepSize: 50
text: i18n("History count")
value: plasmoid.configuration.historyCount
value: plasmoid.configuration.telemetryCount
}
LineSelector {
id: telemetryId
text: i18n("Telemetry ID")
value: plasmoid.configuration.telemetryId
}
}
}
}
Component.onCompleted: {
if (debug) console.debug()
}
}

View File

@ -15,22 +15,31 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
import QtQuick 2.15
import org.kde.kcmutils as KCM
import QtQuick 2.0
import org.kde.plasma.awesomewidgets
import org.kde.plasma.private.awesomewidget
import org.kde.plasma.private.awesomewidget 1.0
import "."
KCM.SimpleKCM {
Item {
id: appearancePage
// backend
AWActions {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: awActions.isDebugEnabled()
property variant weight: {
25: 0,
50: 1,
63: 3,
75: 4,
87: 5,
87: 5
}
property alias cfg_fontFamily: font.value
@ -41,7 +50,9 @@ KCM.SimpleKCM {
property alias cfg_textStyleColor: selectStyleColor.value
property string cfg_textStyle: textStyle.value
Column {
id: pageColumn
anchors.fill: parent
FontSelector {
@ -64,7 +75,7 @@ KCM.SimpleKCM {
model: General.fontWeightModel
text: i18n("Font weight")
value: plasmoid.configuration.fontWeight
onValueEdited: newValue => cfg_fontWeight = newValue
onValueEdited: cfg_fontWeight = newValue
}
ComboBoxSelector {
@ -72,7 +83,7 @@ KCM.SimpleKCM {
model: General.fontStyleModel
text: i18n("Font style")
value: plasmoid.configuration.fontStyle
onValueEdited: newValue => cfg_fontStyle = newValue
onValueEdited: cfg_fontStyle = newValue
}
ColorSelector {
@ -86,7 +97,7 @@ KCM.SimpleKCM {
model: General.textStyleModel
text: i18n("Style")
value: plasmoid.configuration.textStyle
onValueEdited: newValue => cfg_textStyle = newValue
onValueEdited: cfg_textStyle = newValue
}
ColorSelector {
@ -95,4 +106,9 @@ KCM.SimpleKCM {
value: plasmoid.configuration.textStyleColor
}
}
Component.onCompleted: {
if (debug) console.debug()
}
}

View File

@ -15,46 +15,105 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
import QtQuick 2.15
import QtQuick.Controls
import org.kde.kcmutils as KCM
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import QtQuick.Dialogs 1.1 as QtDialogs
import org.kde.plasma.awesomewidgets
import org.kde.plasma.private.awesomewidget
import org.kde.plasma.private.awesomewidget 1.0
KCM.SimpleKCM {
Item {
id: dataenginePage
// backend
AWKeys {
id: awKeys
}
AWActions {
id: awActions
}
AWConfigHelper {
id: awConfig
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: awActions.isDebugEnabled()
property variant cfg_dataengine: awConfig.readDataEngineConfiguration()
Column {
anchors.fill: parent
GroupBox {
Column {
id: pageColumn
anchors.fill: parent
QtControls.GroupBox {
height: implicitHeight
width: parent.width
title: i18n("ACPI")
LineSelector {
text: i18n("ACPI path")
value: cfg_dataengine["ACPIPATH"]
onValueEdited: newValue => cfg_dataengine["ACPIPATH"] = newValue
onValueEdited: cfg_dataengine["ACPIPATH"] = newValue
}
}
GroupBox {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
title: i18n("GPU")
ComboBoxSelector {
model: [
{
'label': "auto",
'name': "auto"
},
{
'label': "disable",
'name': "disable"
},
{
'label': "ati",
'name': "ati"
},
{
'label': "nvidia",
'name': "nvidia"
}
]
text: i18n("GPU device")
value: cfg_dataengine["GPUDEV"]
onValueEdited: cfg_dataengine["GPUDEV"] = newValue
}
}
QtControls.GroupBox {
height: implicitHeight
width: parent.width
title: i18n("HDD temperature")
Column {
height: implicitHeight
width: parent.width
ComboBoxSelector {
id: hdd
text: i18n("HDD")
value: cfg_dataengine["HDDDEV"]
onValueEdited: cfg_dataengine["HDDDEV"] = newValue
}
LineSelector {
text: i18n("hddtemp cmd")
value: cfg_dataengine["HDDTEMPCMD"]
onValueEdited: cfg_dataengine["HDDTEMPCMD"] = newValue
}
}
}
QtControls.GroupBox {
height: implicitHeight
width: parent.width
title: i18n("Player")
Column {
height: implicitHeight
width: parent.width
@ -64,27 +123,27 @@ KCM.SimpleKCM {
stepSize: 1
text: i18n("Player data symbols")
value: cfg_dataengine["PLAYERSYMBOLS"]
onValueEdited: newValue => cfg_dataengine["PLAYERSYMBOLS"] = newValue
onValueEdited: cfg_dataengine["PLAYERSYMBOLS"] = newValue
}
ComboBoxSelector {
model: [
{
"label": "disable",
"name": "disable"
'label': "disable",
'name': "disable"
},
{
"label": "mpris",
"name": "mpris"
'label': "mpris",
'name': "mpris"
},
{
"label": "mpd",
"name": "mpd"
'label': "mpd",
'name': "mpd"
}
]
text: i18n("Music player")
value: cfg_dataengine["PLAYER"]
onValueEdited: newValue => cfg_dataengine["PLAYER"] = newValue
onValueEdited: cfg_dataengine["PLAYER"] = newValue
}
ComboBoxSelector {
@ -92,40 +151,40 @@ KCM.SimpleKCM {
editable: true
model: [
{
"label": "auto",
"name": "auto"
'label': 'auto',
'name': 'auto'
},
{
"label": "amarok",
"name": "amarok"
'label': 'amarok',
'name': 'amarok'
},
{
"label": "audacious",
"name": "audacious"
'label': 'audacious',
'name': 'audacious'
},
{
"label": "clementine",
"name": "clementine"
'label': 'clementine',
'name': 'clementine'
},
{
"label": "DeaDBeeF",
"name": "DeaDBeeF"
'label': 'DeaDBeeF',
'name': 'DeaDBeeF'
},
{
"label": "vlc",
"name": "vlc"
'label': 'vlc',
'name': 'vlc'
},
{
"label": "qmmp",
"name": "qmmp"
'label': 'qmmp',
'name': 'qmmp'
},
{
"label": "xmms2",
"name": "xmms2"
'label': 'xmms2',
'name': 'xmms2'
},
{
"label": cfg_dataengine["MPRIS"],
"name": cfg_dataengine["MPRIS"]
'label': cfg_dataengine["MPRIS"],
'name': cfg_dataengine["MPRIS"]
}
]
text: i18n("MPRIS player name")
@ -135,7 +194,7 @@ KCM.SimpleKCM {
LineSelector {
text: i18n("MPD address")
value: cfg_dataengine["MPDADDRESS"]
onValueEdited: newValue => cfg_dataengine["MPDADDRESS"] = newValue
onValueEdited: cfg_dataengine["MPDADDRESS"] = newValue
}
IntegerSelector {
@ -144,20 +203,18 @@ KCM.SimpleKCM {
stepSize: 1
text: i18n("MPD port")
value: cfg_dataengine["MPDPORT"]
onValueEdited: newValue => cfg_dataengine["MPDPORT"] = newValue
onValueEdited: cfg_dataengine["MPDPORT"] = newValue
}
}
}
GroupBox {
QtControls.GroupBox {
height: implicitHeight
width: parent.width
title: i18n("Extensions")
Column {
height: implicitHeight
width: parent.width
ButtonSelector {
value: i18n("Custom scripts")
onButtonActivated: awKeys.editItem("extscript")
@ -188,11 +245,19 @@ KCM.SimpleKCM {
Component.onCompleted: {
if (debug) console.debug()
// init submodule
awKeys.updateCache()
// update hdd model
hdd.model = awKeys.getHddDevices()
hdd.onCompleted
}
Component.onDestruction: {
if (debug) console.debug()
cfg_dataengine["MPRIS"] = mpris.editText
awConfig.writeDataEngineConfiguration(cfg_dataengine)
}

View File

@ -15,18 +15,20 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
import QtQuick 2.15
import QtQuick.Layouts
import org.kde.plasma.core as PlasmaCore
import QtQuick 2.4
import QtQuick.Controls 1.3 as QtControls
import QtQuick.Dialogs 1.2 as QtDialogs
import QtQuick.Layouts 1.1
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.awesomewidgets
import org.kde.plasma.private.awesomewidget
import org.kde.plasma.private.awesomewidget 1.0
import "."
PlasmoidItem {
Item {
id: main
// backend
AWKeys {
id: awKeys
@ -37,7 +39,11 @@ PlasmoidItem {
AWTelemetryHandler {
id: awTelemetryHandler
}
BugReport {
id: bugReport
}
property bool debug: awActions.isDebugEnabled()
property variant tooltipSettings: {
"tooltipNumber": plasmoid.configuration.tooltipNumber,
"useTooltipBackground": plasmoid.configuration.useTooltipBackground,
@ -67,12 +73,19 @@ PlasmoidItem {
signal needToolTipUpdate(string newText)
signal sizeUpdate
Layout.fillWidth: PlasmoidItem.formFactor !== PlasmaCore.Planar
Layout.fillHeight: PlasmoidItem.formFactor !== PlasmaCore.Planar
// init
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
Plasmoid.compactRepresentation: Plasmoid.fullRepresentation
Layout.fillWidth: plasmoid.formFactor != PlasmaCore.Planar
Layout.fillHeight: plasmoid.formFactor != PlasmaCore.Planar
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Plasmoid.icon: "utilities-system-monitor"
Plasmoid.backgroundHints: plasmoid.configuration.background ? "DefaultBackground" : "NoBackground"
Plasmoid.associatedApplication: "ksysguard"
// ui
Text {
@ -87,7 +100,7 @@ PlasmoidItem {
color: plasmoid.configuration.fontColor
font.family: plasmoid.configuration.fontFamily
font.italic: plasmoid.configuration.fontStyle === "italic"
font.italic: plasmoid.configuration.fontStyle == "italic" ? true : false
font.pointSize: plasmoid.configuration.fontSize
font.weight: General.fontWeight[plasmoid.configuration.fontWeight]
@ -106,26 +119,38 @@ PlasmoidItem {
}
}
Plasmoid.contextualActions: [
PlasmaCore.Action {
text: i18n("Run monitor")
icon.name: "utilities-system-monitor"
onTriggered: awActions.runCmd("plasma-systemmonitor", [])
},
PlasmaCore.Action {
text: i18n("Show README")
icon.name: "text-x-readme"
onTriggered: awActions.showReadme()
},
PlasmaCore.Action {
text: i18n("Check updates")
icon.name: "system-software-update"
onTriggered: awActions.checkUpdates(true)
QtDialogs.Dialog {
id: tagSelector
title: i18n("Select tag")
QtControls.ComboBox {
id: tagSelectorBox
width: parent.width
editable: true
}
]
onAccepted: {
var tag = tagSelectorBox.editText
var message = i18n("Tag: %1", tag)
message += "<br>"
message += i18n("Value: %1", awKeys.valueByKey(tag))
message += "<br>"
message += i18n("Info: %1", awKeys.infoByKey(tag))
awActions.sendNotification("tag", message)
}
}
Component.onCompleted: {
if (debug) console.debug()
// actions
// it makes no sense to use this field with optimization enable
if (!plasmoid.configuration.optimize)
plasmoid.setAction("requestKey", i18n("Request key"), "utilities-system-monitor")
plasmoid.setAction("showReadme", i18n("Show README"), "text-x-readme")
plasmoid.setAction("checkUpdates", i18n("Check updates"), "system-software-update")
plasmoid.setAction("reportBug", i18n("Report bug"), "tools-report-bug")
// init submodule
Plasmoid.userConfiguringChanged(false)
// connect data
@ -135,26 +160,32 @@ PlasmoidItem {
if (plasmoid.configuration.checkUpdates) return awActions.checkUpdates(false)
}
onNeedTextUpdate: newText => {
onNeedTextUpdate: {
if (debug) console.debug()
text.text = newText
sizeUpdate()
}
onNeedToolTipUpdate: newText => {
onNeedToolTipUpdate: {
if (debug) console.debug()
tooltip.text = newText
}
onSizeUpdate: {
if (debug) console.debug()
// 16 is a magic number
// in other case plasmoid will increase own size on each update
if (plasmoid.configuration.height === 0) {
if (plasmoid.configuration.height == 0) {
Layout.minimumHeight = text.contentHeight - 16
Layout.maximumHeight = -1
} else {
Layout.minimumHeight = plasmoid.configuration.height
Layout.maximumHeight = plasmoid.configuration.height
}
if (plasmoid.configuration.width === 0) {
if (plasmoid.configuration.width == 0) {
Layout.minimumWidth = text.contentWidth - 16
Layout.maximumWidth = -1
} else {
@ -165,10 +196,12 @@ PlasmoidItem {
Plasmoid.onUserConfiguringChanged: {
if (plasmoid.userConfiguring) return
if (debug) console.debug()
// init submodule
awKeys.initDataAggregator(tooltipSettings)
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval, plasmoid.configuration.optimize)
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval,
plasmoid.configuration.queueLimit, plasmoid.configuration.optimize)
awKeys.setWrapNewLines(plasmoid.configuration.wrapNewLines)
// configure aggregator
awKeys.setAggregatorProperty("acOffline", plasmoid.configuration.acOffline)
@ -177,8 +210,49 @@ PlasmoidItem {
awKeys.setAggregatorProperty("customUptime", plasmoid.configuration.customUptime)
awKeys.setAggregatorProperty("tempUnits", plasmoid.configuration.tempUnits)
awKeys.setAggregatorProperty("translate", plasmoid.configuration.translateStrings)
// update telemetry ID
if (plasmoid.configuration.telemetryId.length == 0)
plasmoid.configuration.telemetryId = generateUuid()
// save telemetry
awTelemetryHandler.init(plasmoid.configuration.historyCount)
awTelemetryHandler.put("awwidgetconfig", plasmoid.configuration.text)
awTelemetryHandler.init(plasmoid.configuration.telemetryCount,
plasmoid.configuration.telemetryRemote,
plasmoid.configuration.telemetryId)
if (awTelemetryHandler.put("awwidgetconfig", plasmoid.configuration.text))
awTelemetryHandler.uploadTelemetry("awwidgetconfig", plasmoid.configuration.text)
}
function action_checkUpdates() {
if (debug) console.debug()
return awActions.checkUpdates(true)
}
function action_showReadme() {
if (debug) console.debug()
return awActions.showReadme()
}
function action_reportBug() {
if (debug) console.debug()
bugReport.reset()
bugReport.open()
}
function action_requestKey() {
if (debug) console.debug()
tagSelectorBox.model = awKeys.dictKeys(true)
return tagSelector.open()
}
// code from http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
function generateUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
}

View File

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

View File

@ -15,16 +15,25 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
import QtQuick 2.15
import QtQuick.Controls
import org.kde.kcmutils as KCM
import QtQuick 2.0
import QtQuick.Controls 1.3 as QtControls
import org.kde.plasma.awesomewidgets
import org.kde.plasma.private.awesomewidget
import org.kde.plasma.private.awesomewidget 1.0
KCM.SimpleKCM {
Item {
id: tooltipPage
// backend
AWActions {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: awActions.isDebugEnabled()
property alias cfg_tooltipNumber: tooltipNumber.value
property alias cfg_useTooltipBackground: useTooltipBackground.checked
@ -37,17 +46,18 @@ KCM.SimpleKCM {
property alias cfg_memTooltipColor: memTooltipColor.value
property alias cfg_swapTooltip: swapTooltip.checked
property alias cfg_swapTooltipColor: swapTooltipColor.value
property alias cfg_downkbTooltip: networkTooltip.checked
property alias cfg_downkbTooltip: downkbTooltip.checked
property alias cfg_downkbTooltipColor: downkbTooltipColor.value
property alias cfg_upkbTooltipColor: upkbTooltipColor.value
property alias cfg_batTooltip: batTooltip.checked
property alias cfg_batTooltipColor: batTooltipColor.value
property alias cfg_batInTooltipColor: batInTooltipColor.value
Column {
anchors.fill: parent
Label {
Column {
id: pageColumn
anchors.fill: parent
QtControls.Label {
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
@ -64,116 +74,85 @@ KCM.SimpleKCM {
value: plasmoid.configuration.tooltipNumber
}
GroupBox {
QtControls.GroupBox {
id: useTooltipBackground
height: implicitHeight
width: parent.width
property alias checked: useTooltipBackgroundLabel.checked
label: CheckBox {
id: useTooltipBackgroundLabel
text: i18n("Background")
}
checkable: true
title: i18n("Background")
ColorSelector {
id: tooltipBackground
enabled: useTooltipBackgroundLabel.checked
text: i18n("Background color")
value: plasmoid.configuration.tooltipBackground
}
}
GroupBox {
QtControls.GroupBox {
id: cpuTooltip
height: implicitHeight
width: parent.width
property alias checked: cpuTooltipLabel.checked
label: CheckBox {
id: cpuTooltipLabel
text: i18n("CPU")
}
checkable: true
title: i18n("CPU")
ColorSelector {
id: cpuTooltipColor
enabled: cpuTooltipLabel.checked
text: i18n("CPU color")
value: plasmoid.configuration.cpuTooltipColor
}
}
GroupBox {
QtControls.GroupBox {
id: cpuclTooltip
height: implicitHeight
width: parent.width
property alias checked: cpuclTooltipLabel.checked
label: CheckBox {
id: cpuclTooltipLabel
text: i18n("CPU clock")
}
checkable: true
title: i18n("CPU clock")
ColorSelector {
id: cpuclTooltipColor
enabled: cpuclTooltipLabel.checked
text: i18n("CPU clock color")
value: plasmoid.configuration.cpuclTooltipColor
}
}
GroupBox {
QtControls.GroupBox {
id: memTooltip
height: implicitHeight
width: parent.width
property alias checked: memTooltipLabel.checked
label: CheckBox {
id: memTooltipLabel
text: i18n("Memory")
}
checkable: true
title: i18n("Memory")
ColorSelector {
id: memTooltipColor
enabled: memTooltipLabel.checked
text: i18n("Memory color")
value: plasmoid.configuration.memTooltipColor
}
}
GroupBox {
QtControls.GroupBox {
id: swapTooltip
height: implicitHeight
width: parent.width
property alias checked: swapTooltipLabel.checked
label: CheckBox {
id: swapTooltipLabel
text: i18n("Swap")
}
checkable: true
title: i18n("Swap")
ColorSelector {
id: swapTooltipColor
enabled: swapTooltipLabel.checked
text: i18n("Swap color")
value: plasmoid.configuration.swapTooltipColor
}
}
GroupBox {
id: networkTooltip
QtControls.GroupBox {
id: downkbTooltip
height: implicitHeight
width: parent.width
property alias checked: networkTooltipLabel.checked
label: CheckBox {
id: networkTooltipLabel
text: i18n("Network")
}
checkable: true
title: i18n("Network")
Column {
height: implicitHeight
width: parent.width
enabled: networkTooltipLabel.checked
ColorSelector {
id: downkbTooltipColor
text: i18n("Download speed color")
value: plasmoid.configuration.downkbTooltipColor
}
ColorSelector {
id: upkbTooltipColor
text: i18n("Upload speed color")
@ -182,26 +161,20 @@ KCM.SimpleKCM {
}
}
GroupBox {
QtControls.GroupBox {
id: batTooltip
height: implicitHeight
width: parent.width
property alias checked: batteryTooltipLabel.checked
label: CheckBox {
id: batteryTooltipLabel
text: i18n("Battery")
}
checkable: true
title: i18n("Battery")
Column {
height: implicitHeight
width: parent.width
enabled: batteryTooltipLabel.checked
ColorSelector {
id: batTooltipColor
text: i18n("Battery active color")
value: plasmoid.configuration.batTooltipColor
}
ColorSelector {
id: batInTooltipColor
text: i18n("Battery inactive color")
@ -210,4 +183,9 @@ KCM.SimpleKCM {
}
}
}
Component.onCompleted: {
if (debug) console.debug()
}
}

View File

@ -15,17 +15,14 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
import QtQuick 2.15
import QtQuick.Controls
import org.kde.kcmutils as KCM
import QtQuick 2.2
import org.kde.plasma.awesomewidgets
import org.kde.plasma.private.awesomewidget
import org.kde.plasma.private.awesomewidget 1.0
import "."
KCM.SimpleKCM {
Item {
id: widgetPage
// backend
AWKeys {
id: awKeys
@ -34,12 +31,21 @@ KCM.SimpleKCM {
id: awActions
}
width: childrenRect.width
height: childrenRect.height
implicitWidth: pageColumn.implicitWidth
implicitHeight: pageColumn.implicitHeight
property bool debug: awActions.isDebugEnabled()
property alias cfg_text: textPattern.text
property bool lock: true
signal needTextUpdate(string newText)
Column {
id: pageColumn
anchors.fill: parent
AWInfoLabel {}
@ -68,7 +74,10 @@ KCM.SimpleKCM {
}
}
Component.onCompleted: {
if (debug) console.debug()
awKeys.needTextToBeUpdated.connect(needTextUpdate)
// init submodule
awKeys.initKeys(plasmoid.configuration.text, plasmoid.configuration.interval,
@ -81,8 +90,9 @@ KCM.SimpleKCM {
awKeys.setAggregatorProperty("translate", plasmoid.configuration.translateStrings)
}
onNeedTextUpdate: newText => {
onNeedTextUpdate: {
if (lock) return
if (debug) console.debug()
extensions.showMessage(newText)
lock = true

View File

@ -0,0 +1,26 @@
[Desktop Entry]
Encoding=UTF-8
Name=Awesome Widget
Comment=A minimalistic Plasmoid
Comment[en]=A minimalistic Plasmoid
Comment[es]=Un plasmoide minimalista
Comment[es]=Un script Plasmoïde minimaliste
Comment[pt_BR]=Um script Plasmoid
Comment[ru]=Минималистичный плазмоид
Comment[uk]=Мінімалістичний плазмоїд
X-KDE-ServiceTypes=Plasma/Applet
Type=Service
Icon=utilities-system-monitor
X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript
X-Plasma-MainScript=ui/main.qml
X-KDE-PluginInfo-Author=Evgeniy Alekseev aka arcanis
X-KDE-PluginInfo-Email=esalexeev@gmail.com
X-KDE-PluginInfo-Name=org.kde.plasma.awesomewidget
X-KDE-PluginInfo-Version=3.5.1
X-KDE-PluginInfo-Website=https://arcanis.me/projects/awesome-widgets/
X-KDE-PluginInfo-Category=System Information
X-KDE-PluginInfo-License=GPLv3
X-KDE-PluginInfo-EnabledByDefault=true

View File

@ -1,26 +0,0 @@
{
"KPackageStructure": "Plasma/Applet",
"KPlugin": {
"Authors": [
{
"Email": "esalexeev@gmail.com",
"Name": "Evgeniy Alekseev aka arcanis"
}
],
"Category": "System Information",
"Description": "A minimalistic Plasmoid",
"Description[en]": "A minimalistic Plasmoid",
"Description[es]": "Un script Plasmoïde minimaliste",
"Description[pt_BR]": "Um script Plasmoid",
"Description[ru]": "Минималистичный плазмоид",
"Description[uk]": "Мінімалістичний плазмоїд",
"EnabledByDefault": true,
"Icon": "utilities-system-monitor",
"Id": "org.kde.plasma.awesomewidget",
"License": "GPLv3",
"Name": "Awesome Widget",
"Version": "4.0.0",
"Website": "https://arcanis.me/projects/awesome-widgets/"
},
"X-Plasma-API-Minimum-Version": "6.0"
}

View File

@ -7,17 +7,17 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../../${PROJECT_LIBRARY}/
${PROJECT_TRDPARTY_DIR}
${Qt_INCLUDE}
${Kf6_INCLUDE}
${Kf5_INCLUDE}
)
file(GLOB SUBPROJECT_SOURCE *.cpp ${PROJECT_TRDPARTY_DIR}/fontdialog/*.cpp ${CMAKE_SOURCE_DIR}/*.cpp)
file(GLOB SUBPROJECT_UI *.ui)
file(GLOB SUBPROJECT_NOTIFY *.notifyrc)
qt6_wrap_ui(SUBPROJECT_UI_HEADER ${SUBPROJECT_UI})
qt5_wrap_ui(SUBPROJECT_UI_HEADER ${SUBPROJECT_UI})
add_library(${PLUGIN_NAME} SHARED ${SUBPROJECT_SOURCE} ${SUBPROJECT_UI_HEADER})
target_link_libraries(${PLUGIN_NAME} ${PROJECT_LIBRARY} ${Qt_LIBRARIES} ${Kf6_LIBRARIES})
target_link_libraries(${PLUGIN_NAME} ${PROJECT_LIBRARY} ${Qt_LIBRARIES} ${Kf5_LIBRARIES})
install(TARGETS ${PLUGIN_NAME} DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/awesomewidget)
install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/awesomewidget)
install(FILES ${SUBPROJECT_NOTIFY} DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR})
install(TARGETS ${PLUGIN_NAME} DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/private/awesomewidget)
install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/plasma/private/awesomewidget)
install(FILES ${SUBPROJECT_NOTIFY} DESTINATION ${KNOTIFYRC_INSTALL_DIR})

View File

@ -37,13 +37,13 @@ AWAbstractPairConfig::AWAbstractPairConfig(QWidget *_parent, const bool _hasEdit
ui->setupUi(this);
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &AWAbstractPairConfig::accept);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &AWAbstractPairConfig::reject);
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, &QPushButton::clicked, [this]() { return edit(); });
connect(m_editButton, SIGNAL(clicked(bool)), this, SLOT(edit()));
}
}
@ -58,12 +58,6 @@ AWAbstractPairConfig::~AWAbstractPairConfig()
}
void AWAbstractPairConfig::setHelper(std::unique_ptr<AWAbstractPairHelper> _helper)
{
m_helper = std::move(_helper);
}
void AWAbstractPairConfig::showDialog()
{
// update dialog
@ -90,14 +84,14 @@ void AWAbstractPairConfig::edit()
void AWAbstractPairConfig::updateUi()
{
auto current = dynamic_cast<AWAbstractSelector *>(sender())->current();
auto index = m_selectors.indexOf(dynamic_cast<AWAbstractSelector *>(sender()));
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;
auto selector = m_selectors.takeAt(index);
AWAbstractSelector *selector = m_selectors.takeAt(index);
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
} else {
@ -115,18 +109,18 @@ void AWAbstractPairConfig::addSelector(const QStringList &_keys, const QStringLi
{
qCDebug(LOG_AW) << "Add selector with keys" << _keys << "values" << _values << "and current ones" << _current;
auto selector = new AWAbstractSelector(ui->scrollAreaWidgetContents, m_editable);
auto *selector = new AWAbstractSelector(ui->scrollAreaWidgetContents, m_editable);
selector->init(_keys, _values, _current);
ui->verticalLayout->insertWidget(ui->verticalLayout->count() - 1, selector);
connect(selector, &AWAbstractSelector::selectionChanged, this, &AWAbstractPairConfig::updateUi);
connect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
m_selectors.append(selector);
}
void AWAbstractPairConfig::clearSelectors()
{
for (auto selector : m_selectors) {
disconnect(selector, &AWAbstractSelector::selectionChanged, this, &AWAbstractPairConfig::updateUi);
for (auto &selector : m_selectors) {
disconnect(selector, SIGNAL(selectionChanged()), this, SLOT(updateUi()));
ui->verticalLayout->removeWidget(selector);
selector->deleteLater();
}
@ -136,10 +130,10 @@ void AWAbstractPairConfig::clearSelectors()
void AWAbstractPairConfig::execDialog()
{
auto ret = exec();
int ret = exec();
QHash<QString, QString> data;
for (auto selector : m_selectors) {
auto select = selector->current();
for (auto &selector : m_selectors) {
QPair<QString, QString> select = selector->current();
if (select.first.isEmpty())
continue;
data[select.first] = select.second;
@ -166,12 +160,11 @@ QPair<QStringList, QStringList> AWAbstractPairConfig::initKeys() const
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 {left, right};
return QPair<QStringList, QStringList>(left, right);
}
@ -182,7 +175,7 @@ void AWAbstractPairConfig::updateDialog()
auto keys = initKeys();
for (auto &key : m_helper->keys())
addSelector(keys.first, keys.second, {key, pairs[key]});
addSelector(keys.first, keys.second, QPair<QString, QString>(key, m_helper->pairs()[key]));
// empty one
addSelector(keys.first, keys.second, {});
addSelector(keys.first, keys.second, QPair<QString, QString>());
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWABSTRACTPAIRCONFIG_H
#define AWABSTRACTPAIRCONFIG_H
#include <QDialog>
@ -33,9 +35,14 @@ class AWAbstractPairConfig : public QDialog
Q_OBJECT
public:
explicit AWAbstractPairConfig(QWidget *_parent = nullptr, bool _hasEdit = false, QStringList _keys = {});
explicit AWAbstractPairConfig(QWidget *_parent = nullptr, bool _hasEdit = false, QStringList _keys = QStringList());
~AWAbstractPairConfig() override;
void setHelper(std::unique_ptr<AWAbstractPairHelper> _helper);
template <class T> void initHelper()
{
delete m_helper;
m_helper = new T(this);
}
void showDialog();
// properties
void setEditable(bool _first, bool _second);
@ -47,7 +54,7 @@ private slots:
private:
QPushButton *m_editButton = nullptr;
Ui::AWAbstractPairConfig *ui = nullptr;
std::unique_ptr<AWAbstractPairHelper> m_helper;
AWAbstractPairHelper *m_helper = nullptr;
QList<AWAbstractSelector *> m_selectors;
// properties
QPair<bool, bool> m_editable = {false, false};
@ -60,3 +67,6 @@ private:
[[nodiscard]] QPair<QStringList, QStringList> initKeys() const;
void updateDialog();
};
#endif /* AWABSTRACTPAIRCONFIG_H */

View File

@ -34,6 +34,12 @@ AWAbstractPairHelper::AWAbstractPairHelper(QString _filePath, QString _section)
}
AWAbstractPairHelper::~AWAbstractPairHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QStringList AWAbstractPairHelper::keys() const
{
return m_pairs.keys();
@ -63,16 +69,16 @@ void AWAbstractPairHelper::initItems()
{
m_pairs.clear();
auto configs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, m_filePath);
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);
auto keys = settings.childKeys();
QStringList keys = settings.childKeys();
for (auto &key : keys) {
auto value = settings.value(key).toString();
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;
@ -89,8 +95,8 @@ bool AWAbstractPairHelper::writeItems(const QHash<QString, QString> &_configurat
{
qCDebug(LOG_AW) << "Write configuration" << _configuration;
auto fileName
= QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), m_filePath);
QString fileName
= QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).arg(m_filePath);
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << fileName;
@ -101,7 +107,7 @@ bool AWAbstractPairHelper::writeItems(const QHash<QString, QString> &_configurat
settings.sync();
return settings.status() == QSettings::NoError;
return (settings.status() == QSettings::NoError);
}
@ -109,13 +115,14 @@ bool AWAbstractPairHelper::removeUnusedKeys(const QStringList &_keys) const
{
qCDebug(LOG_AW) << "Remove keys" << _keys;
auto fileName
= QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), m_filePath);
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 : settings.childKeys()) {
QStringList foundKeys = settings.childKeys();
for (auto &key : foundKeys) {
if (_keys.contains(key))
continue;
settings.remove(key);
@ -124,5 +131,5 @@ bool AWAbstractPairHelper::removeUnusedKeys(const QStringList &_keys) const
settings.sync();
return settings.status() == QSettings::NoError;
return (settings.status() == QSettings::NoError);
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWABSTRACTPAIRHELPER_H
#define AWABSTRACTPAIRHELPER_H
#include <QHash>
@ -24,7 +26,7 @@ class AWAbstractPairHelper
{
public:
explicit AWAbstractPairHelper(QString _filePath = "", QString _section = "");
virtual ~AWAbstractPairHelper() = default;
virtual ~AWAbstractPairHelper();
[[nodiscard]] QStringList keys() const;
[[nodiscard]] QHash<QString, QString> pairs() const;
[[nodiscard]] QStringList values() const;
@ -44,3 +46,6 @@ private:
QString m_filePath;
QString m_section;
};
#endif /* AWABSTRACTPAIRHELPER_H */

View File

@ -31,8 +31,8 @@ AWAbstractSelector::AWAbstractSelector(QWidget *_parent, const QPair<bool, bool>
ui->comboBox_key->setEditable(_editable.first);
ui->comboBox_value->setEditable(_editable.second);
connect(ui->comboBox_key, &QComboBox::currentIndexChanged, this, &AWAbstractSelector::selectionChanged);
connect(ui->comboBox_value, &QComboBox::currentIndexChanged, this, &AWAbstractSelector::selectionChanged);
connect(ui->comboBox_key, SIGNAL(currentIndexChanged(int)), this, SIGNAL(selectionChanged()));
connect(ui->comboBox_value, SIGNAL(currentIndexChanged(int)), this, SIGNAL(selectionChanged()));
}
@ -46,10 +46,10 @@ AWAbstractSelector::~AWAbstractSelector()
QPair<QString, QString> AWAbstractSelector::current() const
{
auto key = ui->comboBox_key->currentText();
auto value = ui->comboBox_value->currentText();
QString key = ui->comboBox_key->currentText();
QString value = ui->comboBox_value->currentText();
return {key, value};
return QPair<QString, QString>(key, value);
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWABSTRACTSELECTOR_H
#define AWABSTRACTSELECTOR_H
#include <QWidget>
@ -41,3 +43,6 @@ signals:
private:
Ui::AWAbstractSelector *ui = nullptr;
};
#endif /* AWABSTRACTSELECTOR_H */

View File

@ -40,6 +40,12 @@ AWActions::AWActions(QObject *_parent)
}
AWActions::~AWActions()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWActions::checkUpdates(const bool _showAnyway)
{
qCDebug(LOG_AW) << "Show anyway" << _showAnyway;
@ -59,17 +65,24 @@ QString AWActions::getFileContent(const QString &_path)
return "";
}
auto output = inputFile.readAll();
QString output = inputFile.readAll();
inputFile.close();
return output;
}
// HACK: since QML could not use QLoggingCategory I need this hack
bool AWActions::isDebugEnabled()
{
return LOG_AW().isDebugEnabled();
}
bool AWActions::runCmd(const QString &_cmd, const QStringList &_args)
{
qCDebug(LOG_AW) << "Cmd" << _cmd << "args" << _args;
sendNotification("system", i18n("Run %1", _cmd));
sendNotification(QString("Info"), i18n("Run %1", _cmd));
return QProcess::startDetached(_cmd, _args);
}
@ -82,6 +95,20 @@ void AWActions::showReadme()
}
void AWActions::showLegacyInfo()
{
auto *msgBox = new QMessageBox(nullptr);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setModal(false);
msgBox->setWindowTitle(i18n("Not supported"));
msgBox->setText(i18n("You are using mammoth's Qt version, try to update it first"));
msgBox->setStandardButtons(QMessageBox::Ok);
msgBox->setIcon(QMessageBox::Information);
msgBox->open();
}
// HACK: this method uses variables from version.h
QString AWActions::getAboutText(const QString &_type)
{
@ -96,10 +123,10 @@ QVariantMap AWActions::getFont(const QVariantMap &_defaultFont)
qCDebug(LOG_AW) << "Default font is" << _defaultFont;
QVariantMap fontMap;
auto ret = 0;
auto defaultCFont = CFont(_defaultFont["family"].toString(), _defaultFont["size"].toInt(), 400, false,
_defaultFont["color"].toString());
auto font = CFontDialog::getFont(i18n("Select font"), defaultCFont, false, false, &ret);
int ret = 0;
CFont defaultCFont = CFont(_defaultFont["family"].toString(), _defaultFont["size"].toInt(), 400, false,
_defaultFont["color"].toString());
CFont font = CFontDialog::getFont(i18n("Select font"), defaultCFont, false, false, &ret);
fontMap["applied"] = ret;
fontMap["color"] = font.color().name();
@ -115,6 +142,7 @@ void AWActions::sendNotification(const QString &_eventId, const QString &_messag
{
qCDebug(LOG_AW) << "Event" << _eventId << "with message" << _message;
auto event = KNotification::event(_eventId, QString("Awesome Widget ::: %1").arg(_eventId), _message);
event->setComponentName("plasma-applet-org.kde.plasma.awesome-widget");
KNotification *notification
= KNotification::event(_eventId, QString("Awesome Widget ::: %1").arg(_eventId), _message);
notification->setComponentName("plasma-applet-org.kde.plasma.awesome-widget");
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWACTIONS_H
#define AWACTIONS_H
#include <QMap>
#include <QObject>
@ -29,10 +31,12 @@ class AWActions : public QObject
public:
explicit AWActions(QObject *_parent = nullptr);
~AWActions() override = default;
~AWActions() override;
Q_INVOKABLE void checkUpdates(bool _showAnyway = false);
Q_INVOKABLE static QString getFileContent(const QString &_path);
Q_INVOKABLE static bool isDebugEnabled();
Q_INVOKABLE static bool runCmd(const QString &_cmd, const QStringList &_args);
Q_INVOKABLE static void showLegacyInfo();
Q_INVOKABLE static void showReadme();
// configuration slots
Q_INVOKABLE static QString getAboutText(const QString &_type);
@ -44,3 +48,6 @@ public slots:
private:
AWUpdateHelper *m_updateHelper = nullptr;
};
#endif /* AWACTIONS_H */

View File

@ -18,7 +18,6 @@
#include "awbugreporter.h"
#include <KI18n/KLocalizedString>
#include <KNotifications/KNotification>
#include <QDesktopServices>
#include <QJsonDocument>
@ -33,24 +32,19 @@ AWBugReporter::AWBugReporter(QObject *_parent)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_manager = new QNetworkAccessManager(nullptr);
connect(m_manager, &QNetworkAccessManager::finished, this, &AWBugReporter::issueReplyReceived);
}
AWBugReporter::~AWBugReporter()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_manager->deleteLater();
}
void AWBugReporter::doConnect() const
void AWBugReporter::doConnect()
{
// additional method for testing needs
connect(this, &AWBugReporter::replyReceived, this, &AWBugReporter::showInformation);
connect(this, SIGNAL(replyReceived(const int, const QString &)), this, SLOT(showInformation(int, const QString &)));
}
@ -77,24 +71,26 @@ void AWBugReporter::sendBugReport(const QString &_title, const QString &_body)
{
qCDebug(LOG_AW) << "Send bug report with title" << _title << "and body" << _body;
auto *manager = new QNetworkAccessManager(nullptr);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(issueReplyRecieved(QNetworkReply *)));
auto request = QNetworkRequest(QUrl(BUGTRACKER_API));
QNetworkRequest request = QNetworkRequest(QUrl(BUGTRACKER_API));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
// generate payload
QVariantMap payload;
payload["title"] = _title;
payload["body"] = _body;
payload["labels"] = QStringList({"from application"});
payload["labels"] = QStringList() << "from application";
// convert to QByteArray to send request
auto data = QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact);
QByteArray data = QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact);
qCInfo(LOG_AW) << "Send request with _body" << data.data() << "and size" << data.size();
m_manager->post(request, data);
manager->post(request, data);
}
void AWBugReporter::issueReplyReceived(QNetworkReply *_reply)
void AWBugReporter::issueReplyRecieved(QNetworkReply *_reply)
{
if (_reply->error() != QNetworkReply::NoError) {
qCWarning(LOG_AW) << "An error occurs" << _reply->error() << "with message" << _reply->errorString();
@ -102,7 +98,7 @@ void AWBugReporter::issueReplyReceived(QNetworkReply *_reply)
}
QJsonParseError error{};
auto jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_AW) << "Parse error" << error.errorString();
return emit(replyReceived(0, ""));
@ -110,20 +106,14 @@ void AWBugReporter::issueReplyReceived(QNetworkReply *_reply)
_reply->deleteLater();
// convert to map
auto response = jsonDoc.toVariant().toMap();
auto url = response["html_url"].toString();
auto number = response["number"].toInt();
QVariantMap response = jsonDoc.toVariant().toMap();
QString url = response["html_url"].toString();
int number = response["number"].toInt();
return emit(replyReceived(number, url));
}
void AWBugReporter::openBugReport()
{
QDesktopServices::openUrl(m_lastBugUrl);
}
void AWBugReporter::showInformation(const int _number, const QString &_url)
{
qCDebug(LOG_AW) << "Created issue with number" << _number << "and url" << _url;
@ -131,9 +121,29 @@ void AWBugReporter::showInformation(const int _number, const QString &_url)
// cache url first
m_lastBugUrl = _url;
auto event = KNotification::event("system", i18n("Issue created"), i18n("Issue %1 has been created", _number));
event->setComponentName("plasma-applet-org.kde.plasma.awesome-widget");
auto *msgBox = new QMessageBox(nullptr);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setModal(false);
msgBox->setWindowTitle(i18n("Issue created"));
msgBox->setText(i18n("Issue %1 has been created", _number));
msgBox->setStandardButtons(QMessageBox::Open | QMessageBox::Close);
msgBox->setIcon(QMessageBox::Information);
auto action = event->addAction(i18n("Details"));
connect(action, &KNotificationAction::activated, this, &AWBugReporter::openBugReport);
msgBox->open(this, SLOT(userReplyOnBugReport(QAbstractButton *)));
}
void AWBugReporter::userReplyOnBugReport(QAbstractButton *_button)
{
QMessageBox::ButtonRole ret = dynamic_cast<QMessageBox *>(sender())->buttonRole(_button);
qCInfo(LOG_AW) << "User select" << ret;
switch (ret) {
case QMessageBox::AcceptRole:
QDesktopServices::openUrl(m_lastBugUrl);
break;
case QMessageBox::RejectRole:
default:
break;
}
}

View File

@ -15,12 +15,14 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWBUGREPORTER_H
#define AWBUGREPORTER_H
#include <QObject>
class QNetworkAccessManager;
class QAbstractButton;
class QNetworkReply;
class AWBugReporter : public QObject
@ -30,7 +32,7 @@ class AWBugReporter : public QObject
public:
explicit AWBugReporter(QObject *_parent = nullptr);
~AWBugReporter() override;
Q_INVOKABLE void doConnect() const;
Q_INVOKABLE void doConnect();
Q_INVOKABLE static QString generateText(const QString &_description, const QString &_reproduce,
const QString &_expected, const QString &_logs);
Q_INVOKABLE void sendBugReport(const QString &_title, const QString &_body);
@ -39,11 +41,13 @@ signals:
void replyReceived(int _number, const QString &_url);
private slots:
void issueReplyReceived(QNetworkReply *_reply);
void openBugReport();
void issueReplyRecieved(QNetworkReply *_reply);
void showInformation(int _number, const QString &_url);
void userReplyOnBugReport(QAbstractButton *_button);
private:
QString m_lastBugUrl;
QNetworkAccessManager *m_manager = nullptr;
};
#endif /* AWBUGREPORTER_H */

View File

@ -21,6 +21,7 @@
#include <QQmlPropertyMap>
#include <QSettings>
#include <QStandardPaths>
#include <QTextCodec>
#include "awdebug.h"
@ -34,11 +35,17 @@ AWConfigHelper::AWConfigHelper(QObject *_parent)
}
AWConfigHelper::~AWConfigHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QString AWConfigHelper::configurationDirectory()
{
// get readable directory
auto localDir = QString("%1/awesomewidgets/configs")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
QString localDir = QString("%1/awesomewidgets/configs")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
// create directory and copy files from default settings
QDir localDirectory;
@ -53,7 +60,7 @@ QString AWConfigHelper::configurationDirectory()
bool AWConfigHelper::dropCache()
{
auto fileName
QString fileName
= QString("%1/awesomewidgets.ndx").arg(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
return QFile(fileName).remove();
@ -66,10 +73,10 @@ bool AWConfigHelper::exportConfiguration(QObject *_nativeConfig, const QString &
QSettings settings(_fileName, QSettings::IniFormat);
// plasmoid configuration
auto configuration = dynamic_cast<const QQmlPropertyMap *>(_nativeConfig);
const auto *configuration = dynamic_cast<const QQmlPropertyMap *>(_nativeConfig);
settings.beginGroup("plasmoid");
for (auto &key : configuration->keys()) {
auto value = configuration->value(key);
QVariant value = configuration->value(key);
if (!value.isValid())
continue;
settings.setValue(key, value);
@ -78,7 +85,8 @@ bool AWConfigHelper::exportConfiguration(QObject *_nativeConfig, const QString &
// extensions
for (auto &item : m_dirs) {
auto items = QDir(QString("%1/%2").arg(m_baseDir, item)).entryList({"*.desktop"}, QDir::Files);
QStringList items
= QDir(QString("%1/%2").arg(m_baseDir).arg(item)).entryList(QStringList() << "*.desktop", QDir::Files);
settings.beginGroup(item);
for (auto &it : items)
copyExtensions(it, item, settings, false);
@ -156,13 +164,16 @@ QVariantMap AWConfigHelper::importConfiguration(const QString &_fileName, const
QVariantMap AWConfigHelper::readDataEngineConfiguration()
{
auto fileName = QStandardPaths::locate(QStandardPaths::ConfigLocation, "plasma-dataengine-extsysmon.conf");
QString fileName = QStandardPaths::locate(QStandardPaths::ConfigLocation, "plasma-dataengine-extsysmon.conf");
qCInfo(LOG_AW) << "Configuration file" << fileName;
QSettings settings(fileName, QSettings::IniFormat);
QVariantMap configuration;
settings.beginGroup("Configuration");
configuration["ACPIPATH"] = settings.value("ACPIPATH", "/sys/class/power_supply/");
configuration["GPUDEV"] = settings.value("GPUDEV", "auto");
configuration["HDDDEV"] = settings.value("HDDDEV", "all");
configuration["HDDTEMPCMD"] = settings.value("HDDTEMPCMD", "sudo smartctl -a");
configuration["MPDADDRESS"] = settings.value("MPDADDRESS", "localhost");
configuration["MPDPORT"] = settings.value("MPDPORT", "6600");
configuration["MPRIS"] = settings.value("MPRIS", "auto");
@ -180,13 +191,16 @@ bool AWConfigHelper::writeDataEngineConfiguration(const QVariantMap &_configurat
{
qCDebug(LOG_AW) << "Configuration" << _configuration;
auto fileName = QString("%1/plasma-dataengine-extsysmon.conf")
.arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
QString fileName = QString("%1/plasma-dataengine-extsysmon.conf")
.arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
QSettings settings(fileName, QSettings::IniFormat);
qCInfo(LOG_AW) << "Configuration file" << settings.fileName();
settings.beginGroup("Configuration");
settings.setValue("ACPIPATH", _configuration["ACPIPATH"]);
settings.setValue("GPUDEV", _configuration["GPUDEV"]);
settings.setValue("HDDDEV", _configuration["HDDDEV"]);
settings.setValue("HDDTEMPCMD", _configuration["HDDTEMPCMD"]);
settings.setValue("MPDADDRESS", _configuration["MPDADDRESS"]);
settings.setValue("MPDPORT", _configuration["MPDPORT"]);
settings.setValue("MPRIS", _configuration["MPRIS"]);
@ -204,15 +218,15 @@ void AWConfigHelper::copyConfigs(const QString &_localDir)
{
qCDebug(LOG_AW) << "Local directory" << _localDir;
auto dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "awesomewidgets/configs",
QStandardPaths::LocateDirectory);
QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "awesomewidgets/configs",
QStandardPaths::LocateDirectory);
for (auto &dir : dirs) {
if (dir == _localDir)
continue;
auto files = QDir(dir).entryList(QDir::Files);
QStringList files = QDir(dir).entryList(QDir::Files);
for (auto &source : files) {
auto destination = QString("%1/%2").arg(_localDir, source);
auto status = QFile::copy(QString("%1/%2").arg(dir, source), destination);
QString destination = QString("%1/%2").arg(_localDir).arg(source);
bool status = QFile::copy(QString("%1/%2").arg(dir).arg(source), destination);
qCInfo(LOG_AW) << "File" << source << "has been copied to" << destination << "with status" << status;
}
}
@ -225,7 +239,7 @@ void AWConfigHelper::copyExtensions(const QString &_item, const QString &_type,
qCDebug(LOG_AW) << "Extension" << _item << "has type" << _type << "inverse copying" << _inverse;
_settings.beginGroup(_item);
QSettings itemSettings(QString("%1/%2/%3").arg(m_baseDir, _type, _item), QSettings::IniFormat);
QSettings itemSettings(QString("%1/%2/%3").arg(m_baseDir).arg(_type).arg(_item), QSettings::IniFormat);
itemSettings.beginGroup("Desktop Entry");
if (_inverse)
copySettings(_settings, itemSettings);
@ -252,7 +266,7 @@ void AWConfigHelper::readFile(QSettings &_settings, const QString &_key, const Q
QFile file(_fileName);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
auto text = QString::fromUtf8(file.readAll());
QString text = QString::fromUtf8(file.readAll());
file.close();
_settings.setValue(_key, text);
} else {
@ -271,6 +285,7 @@ void AWConfigHelper::writeFile(QSettings &_settings, const QString &_key, const
QFile file(_fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
out.setCodec("UTF-8");
out << _settings.value(_key).toString().toUtf8();
out.flush();
file.close();

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWCONFIGHELPER_H
#define AWCONFIGHELPER_H
#include <QObject>
#include <QVariant>
@ -29,7 +31,7 @@ class AWConfigHelper : public QObject
public:
explicit AWConfigHelper(QObject *_parent = nullptr);
~AWConfigHelper() override = default;
~AWConfigHelper() override;
Q_INVOKABLE [[nodiscard]] static QString configurationDirectory();
Q_INVOKABLE static bool dropCache();
Q_INVOKABLE bool exportConfiguration(QObject *_nativeConfig, const QString &_fileName) const;
@ -50,3 +52,6 @@ private:
QString m_baseDir;
QStringList m_dirs = {"desktops", "quotes", "scripts", "upgrade", "weather", "formatters"};
};
#endif /* AWCONFIGHELPER_H */

View File

@ -27,5 +27,11 @@ AWCustomKeysConfig::AWCustomKeysConfig(QWidget *_parent, const QStringList &_key
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
setEditable(true, false);
setHelper(std::make_unique<AWCustomKeysHelper>());
initHelper<AWCustomKeysHelper>();
}
AWCustomKeysConfig::~AWCustomKeysConfig()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWCUSTOMKEYSCONFIG_H
#define AWCUSTOMKEYSCONFIG_H
#include "awabstractpairconfig.h"
@ -26,5 +28,8 @@ class AWCustomKeysConfig : public AWAbstractPairConfig
public:
explicit AWCustomKeysConfig(QWidget *_parent = nullptr, const QStringList &_keys = QStringList());
~AWCustomKeysConfig() override = default;
~AWCustomKeysConfig() override;
};
#endif /* AWCUSTOMKEYSCONFIG_H */

View File

@ -30,6 +30,12 @@ AWCustomKeysHelper::AWCustomKeysHelper(QObject *_parent)
}
AWCustomKeysHelper::~AWCustomKeysHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
QString AWCustomKeysHelper::source(const QString &_key) const
{
qCDebug(LOG_AW) << "Get source by key" << _key;

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWCUSTOMKEYSHELPER_H
#define AWCUSTOMKEYSHELPER_H
#include <QObject>
@ -28,7 +30,7 @@ class AWCustomKeysHelper : public QObject, public AWAbstractPairHelper
public:
explicit AWCustomKeysHelper(QObject *_parent = nullptr);
~AWCustomKeysHelper() override = default;
~AWCustomKeysHelper() override;
// get
[[nodiscard]] QString source(const QString &_key) const;
[[nodiscard]] QStringList sources() const;
@ -37,4 +39,9 @@ public:
void editPairs() override{};
QStringList leftKeys() override;
QStringList rightKeys() override;
private:
};
#endif /* AWCUSTOMKEYSHELPER_H */

View File

@ -50,8 +50,7 @@ AWDataAggregator::~AWDataAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_toolTipView->deleteLater();
m_toolTipScene->deleteLater();
delete m_toolTipScene;
}
@ -85,26 +84,26 @@ void AWDataAggregator::setParameters(const QVariantMap &_settings)
// resize tooltip image
m_toolTipView->resize(100 * m_counts, 105);
m_requiredKeys.clear();
requiredKeys.clear();
if (m_configuration["cpuTooltip"].toBool())
m_requiredKeys.append("cpuTooltip");
requiredKeys.append("cpuTooltip");
if (m_configuration["cpuclTooltip"].toBool())
m_requiredKeys.append("cpuclTooltip");
requiredKeys.append("cpuclTooltip");
if (m_configuration["memTooltip"].toBool())
m_requiredKeys.append("memTooltip");
requiredKeys.append("memTooltip");
if (m_configuration["swapTooltip"].toBool())
m_requiredKeys.append("swapTooltip");
requiredKeys.append("swapTooltip");
if (m_configuration["downkbTooltip"].toBool())
m_requiredKeys.append("downkbTooltip");
requiredKeys.append("downkbTooltip");
if (m_configuration["upkbTooltip"].toBool())
m_requiredKeys.append("upkbTooltip");
requiredKeys.append("upkbTooltip");
if (m_configuration["batTooltip"].toBool())
m_requiredKeys.append("batTooltip");
requiredKeys.append("batTooltip");
// background
m_toolTipScene->setBackgroundBrush(m_configuration["useTooltipBackground"].toBool()
? QColor(m_configuration["tooltipBackground"].toString())
: Qt::NoBrush);
? QBrush(QColor(m_configuration["tooltipBackground"].toString()))
: QBrush(Qt::NoBrush));
}
@ -113,42 +112,34 @@ QPixmap AWDataAggregator::tooltipImage()
// create image
m_toolTipScene->clear();
QPen pen;
auto shift = 0.0;
for (auto i = 0; i < m_requiredKeys.count(); ++i) {
auto key = m_requiredKeys[i];
bool down = false;
for (auto &key : requiredKeys) {
// create frame
auto normX = 100.0 / static_cast<float>(m_values[key].count());
auto normY = 100.0 / (1.5 * m_boundaries[key]);
float normX = 100.0f / static_cast<float>(m_values[key].count());
float normY = 100.0f / (1.5f * m_boundaries[key]);
float shift = static_cast<float>(requiredKeys.indexOf(key)) * 100.0f;
if (down)
shift -= 100.0;
// apply pen color
if (key != "batTooltip")
pen.setColor(m_configuration[QString("%1Color").arg(key)].toString());
pen.setColor(QColor(m_configuration[QString("%1Color").arg(key)].toString()));
// paint data inside frame
for (int j = 0; j < m_values[key].count() - 1; j++) {
// some magic here
auto x1 = j * normX + shift;
auto y1 = -std::fabs(m_values[key].at(j)) * normY + 5.0;
auto x2 = (j + 1) * normX + shift;
auto y2 = -std::fabs(m_values[key].at(j + 1)) * normY + 5.0;
// apply color for the battery tooltip based on charge/discharge
float x1 = j * normX + shift;
float y1 = -std::fabs(m_values[key].at(j)) * normY + 5.0f;
float x2 = (j + 1) * normX + shift;
float y2 = -std::fabs(m_values[key].at(j + 1)) * normY + 5.0f;
if (key == "batTooltip") {
if (m_values[key].at(j + 1) > 0)
pen.setColor(QColor(m_configuration["batTooltipColor"].toString()));
else
pen.setColor(QColor(m_configuration["batInTooltipColor"].toString()));
}
m_toolTipScene->addLine(x1, y1, x2, y2, pen);
}
// increase frame shift if not downkbtooltip
// Additional workaround is required because there is frame (uokb and downkb) which contains two charts
// with the same shift
if (key != "downkbTooltip")
shift += 100.0;
if (key == "downkbTooltip")
down = true;
}
return m_toolTipView->grab();
@ -163,7 +154,7 @@ void AWDataAggregator::dataUpdate(const QVariantHash &_values)
}
void AWDataAggregator::checkValue(const QString &_source, const double _value, const double _extremum) const
void AWDataAggregator::checkValue(const QString &_source, const float _value, const float _extremum) const
{
qCDebug(LOG_AW) << "Notification source" << _source << "with value" << _value << "called with extremum"
<< _extremum;
@ -236,27 +227,25 @@ void AWDataAggregator::setData(const QVariantHash &_values)
{
// do not log these arguments
// battery update requires info is AC online or not
setData(_values["ac"].toString() == m_configuration["acOnline"], "batTooltip", _values["bat"].toDouble());
setData(_values["ac"].toString() == m_configuration["acOnline"], "batTooltip", _values["bat"].toFloat());
// usual case
setData("cpuTooltip", _values["cpu"].toDouble(), 90.0);
setData("cpuclTooltip", _values["cpucl"].toDouble());
setData("memTooltip", _values["mem"].toDouble(), 80.0);
setData("swapTooltip", _values["swap"].toDouble(), 0.0);
setData("downkbTooltip", _values["downkb"].toDouble());
setData("upkbTooltip", _values["upkb"].toDouble());
setData("cpuTooltip", _values["cpu"].toFloat(), 90.0);
setData("cpuclTooltip", _values["cpucl"].toFloat());
setData("memTooltip", _values["mem"].toFloat(), 80.0);
setData("swapTooltip", _values["swap"].toFloat(), 0.0);
setData("downkbTooltip", _values["downkb"].toFloat());
setData("upkbTooltip", _values["upkb"].toFloat());
// additional check for network device
auto currentNetworkDevice = _values["netdev"].toString();
checkValue("netdev", m_currentNetworkDevice, currentNetworkDevice);
m_currentNetworkDevice = currentNetworkDevice;
[this](const QString &value) {
checkValue("netdev", m_currentNetworkDevice, value);
m_currentNetworkDevice = value;
}(_values["netdev"].toString());
// additional check for GPU load
checkValue("gpu", _values["gpu"].toDouble(), 90.0);
[this](const float value) { checkValue("gpu", value, 90.0); }(_values["gpu"].toFloat());
}
void AWDataAggregator::setData(const QString &_source, double _value, const double _extremum)
void AWDataAggregator::setData(const QString &_source, float _value, const float _extremum)
{
qCDebug(LOG_AW) << "Source" << _source << "to value" << _value << "with extremum" << _extremum;
@ -272,20 +261,16 @@ void AWDataAggregator::setData(const QString &_source, double _value, const doub
m_values[_source].append(_value);
if (_source == "downkbTooltip") {
// to avoid copying of objects to another list we find max elements in each sequence and compare them
auto downMax = m_values["downkbTooltip"].empty()
? 1.0
: *std::max_element(m_values["downkbTooltip"].cbegin(), m_values["downkbTooltip"].cend());
auto upMax = m_values["upkbTooltip"].empty()
? 1.0
: *std::max_element(m_values["upkbTooltip"].cbegin(), m_values["upkbTooltip"].cend());
// assign both
m_boundaries["upkbTooltip"] = m_boundaries["downkbTooltip"] = 1.2 * std::max(downMax, upMax);
QList<float> netValues = m_values["downkbTooltip"] + m_values["upkbTooltip"];
// to avoid inf value of normY
netValues << 1.0;
m_boundaries["downkbTooltip"] = 1.2f * *std::max_element(netValues.cbegin(), netValues.cend());
m_boundaries["upkbTooltip"] = m_boundaries["downkbTooltip"];
}
}
void AWDataAggregator::setData(const bool _dontInvert, const QString &_source, double _value)
void AWDataAggregator::setData(const bool _dontInvert, const QString &_source, float _value)
{
qCDebug(LOG_AW) << "Do not invert" << _dontInvert << "value" << _value << "for source" << _source;

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWTOOLTIP_H
#define AWTOOLTIP_H
#include <QObject>
#include <QVariant>
@ -24,6 +26,7 @@
class QGraphicsScene;
class QGraphicsView;
class QPixmap;
class QThreadPool;
class AWDataAggregator : public QObject
{
@ -46,22 +49,25 @@ private:
// ui
QGraphicsScene *m_toolTipScene = nullptr;
QGraphicsView *m_toolTipView = nullptr;
void checkValue(const QString &_source, double _value, double _extremum) const;
void checkValue(const QString &_source, float _value, float _extremum) const;
void checkValue(const QString &_source, const QString &_current, const QString &_received) const;
void initScene();
static QString notificationText(const QString &_source, float _value);
static QString notificationText(const QString &_source, const QString &_value);
// main method
void setData(const QVariantHash &_values);
void setData(const QString &_source, double _value, double _extremum = -1.0);
void setData(const QString &_source, float _value, float _extremum = -1.0f);
// different signature for battery device
void setData(bool _dontInvert, const QString &_source, double _value);
void setData(bool _dontInvert, const QString &_source, float _value);
// variables
int m_counts = 0;
QVariantHash m_configuration;
QString m_currentNetworkDevice = "lo";
QHash<QString, double> m_boundaries;
QHash<QString, QList<double>> m_values;
QHash<QString, float> m_boundaries;
QHash<QString, QList<float>> m_values;
bool m_enablePopup = false;
QStringList m_requiredKeys;
QStringList requiredKeys;
};
#endif /* AWTOOLTIP_H */

View File

@ -17,35 +17,30 @@
#include "awdataengineaggregator.h"
#include <ksysguard/formatter/Unit.h>
#include <ksysguard/systemstats/DBusInterface.h>
#include <QDBusConnection>
#include <Plasma/DataContainer>
#include "awdebug.h"
AWDataEngineAggregator::AWDataEngineAggregator(QObject *_parent)
: QObject(_parent)
, m_interface(new KSysGuard::SystemStats::DBusInterface())
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
qDBusRegisterMetaType<KSysGuard::SensorData>();
qDBusRegisterMetaType<KSysGuard::SensorInfo>();
qDBusRegisterMetaType<KSysGuard::SensorDataList>();
qDBusRegisterMetaType<QHash<QString, KSysGuard::SensorInfo>>();
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");
connect(m_interface, &KSysGuard::SystemStats::DBusInterface::newSensorData, this,
&AWDataEngineAggregator::updateData);
connect(m_interface, &KSysGuard::SystemStats::DBusInterface::sensorMetaDataChanged, this,
&AWDataEngineAggregator::updateSensors);
connect(m_interface, &KSysGuard::SystemStats::DBusInterface::sensorAdded, this,
&AWDataEngineAggregator::sensorAdded);
connect(m_interface, &KSysGuard::SystemStats::DBusInterface::sensorRemoved, this,
&AWDataEngineAggregator::sensorRemoved);
// 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);
});
loadSources();
// required to define Qt::QueuedConnection for signal-slot connection
qRegisterMetaType<Plasma::DataEngine::Data>("Plasma::DataEngine::Data");
}
@ -54,102 +49,67 @@ AWDataEngineAggregator::~AWDataEngineAggregator()
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
disconnectSources();
m_interface->deleteLater();
}
void AWDataEngineAggregator::connectSources()
{
auto keys = m_sensors.keys();
auto newKeys = QSet(keys.cbegin(), keys.cend()) - m_subscribed;
m_interface->subscribe(newKeys.values()).waitForFinished();
m_subscribed.unite(newKeys);
}
void AWDataEngineAggregator::disconnectSources()
{
m_interface->unsubscribe(m_subscribed.values()).waitForFinished();
m_subscribed.clear();
for (auto dataEngine : m_dataEngines.values())
for (auto &source : dataEngine->sources())
dataEngine->disconnectSource(source, parent());
disconnect(m_newSourceConnection);
}
bool AWDataEngineAggregator::isValidSensor(const KSysGuard::SensorInfo &_sensor)
void AWDataEngineAggregator::reconnectSources(const int _interval)
{
return _sensor.unit != KSysGuard::UnitInvalid;
}
qCDebug(LOG_AW) << "Reconnect sources with interval" << _interval;
disconnectSources();
void AWDataEngineAggregator::loadSources()
{
auto response = m_interface->allSensors();
response.waitForFinished();
m_dataEngines["systemmonitor"]->connectAllSources(parent(), (uint)_interval);
m_dataEngines["extsysmon"]->connectAllSources(parent(), (uint)_interval);
m_dataEngines["time"]->connectSource("Local", parent(), 1000);
auto sensors = response.value();
updateSensors(sensors);
connectSources();
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);
});
for (auto &sensor : m_sensors.keys())
emit(deviceAdded(sensor));
#ifdef BUILD_FUTURE
createQueuedConnection();
#endif /* BUILD_FUTURE */
}
void AWDataEngineAggregator::dropSource(const QString &_source)
{
qCDebug(LOG_AW) << "Disconnect sensor" << _source;
qCDebug(LOG_AW) << "Source" << _source;
if (m_subscribed.contains(_source)) {
m_interface->unsubscribe({_source}).waitForFinished();
m_subscribed.remove(_source);
}
}
void AWDataEngineAggregator::sensorAdded(const QString &_sensor)
{
qCDebug(LOG_AW) << "New sensor added" << _sensor;
// check if sensor is actually valid
auto response = m_interface->sensors({_sensor});
response.waitForFinished();
auto info = response.value().value(_sensor);
if (!isValidSensor(info))
return;
m_sensors[_sensor] = info;
dropSource(_sensor); // force reconnect
if (!m_subscribed.contains(_sensor)) {
m_interface->subscribe({_sensor}).waitForFinished();
m_subscribed.insert(_sensor);
}
// notify about new device
emit(deviceAdded(_sensor));
}
void AWDataEngineAggregator::sensorRemoved(const QString &_sensor)
{
qCDebug(LOG_AW) << "Sensor" << _sensor << "has been removed";
m_sensors.remove(_sensor);
dropSource(_sensor);
}
void AWDataEngineAggregator::updateData(const KSysGuard::SensorDataList &_data)
{
emit(dataUpdated(m_sensors, _data));
}
void AWDataEngineAggregator::updateSensors(const QHash<QString, KSysGuard::SensorInfo> &_sensors)
{
for (auto [source, sensor] : _sensors.asKeyValueRange()) {
if (!isValidSensor(sensor))
continue;
m_sensors.insert(source, sensor);
// HACK there is no possibility to check to which dataengine source
// connected we will try to disconnect it from all engines
for (auto dataEngine : m_dataEngines.values())
dataEngine->disconnectSource(_source, parent());
}
void AWDataEngineAggregator::createQueuedConnection()
{
// HACK additional method which forces QueuedConnection instead of Auto one
// for more details refer to plasma-framework source code
for (auto &dataEngine : m_dataEngines.keys()) {
// different source set for different engines
QStringList sources = dataEngine == "time" ? QStringList() << "Local" : m_dataEngines[dataEngine]->sources();
// reconnect sources
for (auto &source : sources) {
Plasma::DataContainer *container = m_dataEngines[dataEngine]->containerForSource(source);
// disconnect old connections first
disconnect(container, SIGNAL(dataUpdated(QString, Plasma::DataEngine::Data)), parent(),
SLOT(dataUpdated(QString, Plasma::DataEngine::Data)));
// and now reconnect with Qt::QueuedConnection type
connect(container, SIGNAL(dataUpdated(QString, Plasma::DataEngine::Data)), parent(),
SLOT(dataUpdated(QString, Plasma::DataEngine::Data)), Qt::QueuedConnection);
}
}
}

View File

@ -15,20 +15,16 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#include <ksysguard/systemstats/SensorInfo.h>
#ifndef AWDATAENGINEAGGREGATOR_H
#define AWDATAENGINEAGGREGATOR_H
#include <Plasma/DataEngine>
#include <Plasma/DataEngineConsumer>
#include <QHash>
#include <QObject>
#include <QSet>
namespace KSysGuard::SystemStats
{
class DBusInterface;
}
class AWDataEngineAggregator : public QObject
{
Q_OBJECT
@ -36,24 +32,21 @@ class AWDataEngineAggregator : public QObject
public:
explicit AWDataEngineAggregator(QObject *_parent = nullptr);
~AWDataEngineAggregator() override;
void connectSources();
void disconnectSources();
[[nodiscard]] static bool isValidSensor(const KSysGuard::SensorInfo &_sensor);
void loadSources();
void reconnectSources(int _interval);
signals:
void dataUpdated(const QHash<QString, KSysGuard::SensorInfo> &_sensors, const KSysGuard::SensorDataList &_data);
void deviceAdded(const QString &_source);
public slots:
void dropSource(const QString &_source);
void sensorAdded(const QString &_sensor);
void sensorRemoved(const QString &_sensor);
void updateData(const KSysGuard::SensorDataList &_data);
void updateSensors(const QHash<QString, KSysGuard::SensorInfo> &_sensors);
private:
KSysGuard::SystemStats::DBusInterface *m_interface = nullptr;
QHash<QString, KSysGuard::SensorInfo> m_sensors;
QSet<QString> m_subscribed;
void createQueuedConnection();
Plasma::DataEngineConsumer *m_consumer = nullptr;
QHash<QString, Plasma::DataEngine *> m_dataEngines;
QMetaObject::Connection m_newSourceConnection;
};
#endif /* AWDATAENGINEAGGREGATOR_H */

View File

@ -17,7 +17,7 @@
#include "awdataenginemapper.h"
#include <QRegularExpression>
#include <QRegExp>
#include "awdebug.h"
#include "awformatterhelper.h"
@ -52,6 +52,12 @@ AWDataEngineMapper::AWDataEngineMapper(QObject *_parent, AWFormatterHelper *_cus
}
AWDataEngineMapper::~AWDataEngineMapper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
AWKeysAggregator::FormatterType AWDataEngineMapper::formatter(const QString &_key) const
{
qCDebug(LOG_AW) << "Get formatter for key" << _key;
@ -70,126 +76,106 @@ QStringList AWDataEngineMapper::keysFromSource(const QString &_source) const
// HACK units required to define should the value be calculated as temperature
// or fan data
QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSysGuard::Unit _units,
const QStringList &_keys)
QStringList AWDataEngineMapper::registerSource(const QString &_source, const QString &_units, const QStringList &_keys)
{
qCDebug(LOG_AW) << "Source" << _source << "with units" << _units;
// regular expressions
static auto cpuRegExp = QRegularExpression("^cpu/cpu.*/usage$");
static auto cpuclRegExp = QRegularExpression("^cpu/cpu.*/frequency$");
static auto cpuTempRegExp = QRegularExpression("^cpu/cpu.*/temperature$");
static auto gpuRegExp = QRegularExpression("^gpu/gpu.*/usage$");
static auto gpuTempRegExp = QRegularExpression("^gpu/gpu.*/temperature$");
static auto hddrRegExp = QRegularExpression("^disk/.*/read$");
static auto hddwRegExp = QRegularExpression("^disk/.*/write$");
static auto mountFillRegExp = QRegularExpression("^disk/.*/usedPercent$");
static auto mountFreeRegExp = QRegularExpression("^disk/.*/free$");
static auto mountUsedRegExp = QRegularExpression("^disk/.*/used$");
static auto netRegExp = QRegularExpression("^network/.*/(download|upload)$");
static auto netTotalRegExp = QRegularExpression("^network/.*/(totalDownload|totalUpload)$");
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 == "extsysmon/battery/ac") {
if (_source == "battery/ac") {
// AC
m_map.insert(_source, "ac");
m_formatter["ac"] = AWKeysAggregator::FormatterType::ACFormat;
} else if (_source.startsWith("extsysmon/battery/")) {
} else if (_source.startsWith("battery/")) {
// battery stats
auto key = _source;
key.remove("extsysmon/battery/");
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/all/usage") {
} else if (_source == "cpu/system/TotalLoad") {
// cpu
m_map.insert(_source, "cpu");
m_formatter["cpu"] = AWKeysAggregator::FormatterType::Float;
} else if (_source.contains(cpuRegExp)) {
// cpus
auto key = _source;
key.remove("cpu/").remove("/usage");
QString key = _source;
key.remove("cpu/").remove("/TotalLoad");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Float;
} else if (_source == "cpu/all/averageFrequency") {
} else if (_source == "cpu/system/AverageClock") {
// cpucl
m_map.insert(_source, "cpucl");
m_formatter["cpucl"] = AWKeysAggregator::FormatterType::Integer;
} else if (_source.contains(cpuclRegExp)) {
// cpucls
auto key = _source;
key.remove("cpu/cpu").remove("/frequency");
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("extsysmon/custom")) {
} else if (_source.startsWith("custom")) {
// custom
auto key = _source;
key.remove("extsysmon/custom/");
QString key = _source;
key.remove("custom/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "extsysmon/desktop/name") {
} else if (_source == "desktop/current/name") {
// current desktop name
m_map.insert(_source, "desktop");
m_formatter["desktop"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "extsysmon/desktop/number") {
} else if (_source == "desktop/current/number") {
// current desktop number
m_map.insert(_source, "ndesktop");
m_formatter["ndesktop"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "extsysmon/desktop/count") {
} 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
auto device = _source;
device.remove("disk/").remove("/read");
auto index = m_devices["disk"].indexOf(device);
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::MemKBFormat;
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
}
} else if (_source.contains(hddwRegExp)) {
// write speed
auto device = _source;
device.remove("disk/").remove("/write");
auto index = m_devices["disk"].indexOf(device);
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::MemKBFormat;
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
}
} else if (_source == "gpu/all/usage") {
} else if (_source == "gpu/load") {
// gpu load
m_map.insert(_source, "gpu");
m_formatter["gpu"] = AWKeysAggregator::FormatterType::Float;
} else if (_source.contains(gpuRegExp)) {
// gpus
auto device = _source;
device.remove("gpu/").remove("/usage");
auto index = m_devices["gpu"].indexOf(device);
if (index > -1) {
auto key = QString("gpu%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Float;
}
} else if (_source.contains(gpuTempRegExp)) {
// gpus temps
auto device = _source;
device.remove("gpu/").remove("/temperature");
auto index = m_devices["gpu"].indexOf(device);
if (index > -1) {
auto key = QString("gputemp%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Temperature;
}
} 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
auto device = _source;
device.remove("disk/").remove("/usedPercent");
auto index = m_devices["mount"].indexOf(device);
QString device = _source;
device.remove("partitions").remove("/filllevel");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
auto key = QString("hdd%1").arg(index);
QString key = QString("hdd%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Float;
// additional keys
@ -198,12 +184,12 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
}
} else if (_source.contains(mountFreeRegExp)) {
// free space
auto device = _source;
device.remove("disk/").remove("/free");
auto index = m_devices["mount"].indexOf(device);
QString device = _source;
device.remove("partitions").remove("/freespace");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
// mb
auto key = QString("hddfreemb%1").arg(index);
QString key = QString("hddfreemb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
@ -213,12 +199,12 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
}
} else if (_source.contains(mountUsedRegExp)) {
// used
auto device = _source;
device.remove("disk/").remove("/used");
auto index = m_devices["mount"].indexOf(device);
QString device = _source;
device.remove("partitions").remove("/usedspace");
int index = m_devices["mount"].indexOf(device);
if (index > -1) {
// mb
auto key = QString("hddmb%1").arg(index);
QString key = QString("hddmb%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemMBFormat;
// gb
@ -226,14 +212,24 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemGBFormat;
}
} else if (_source.startsWith("cpu/loadaverages/loadaverage")) {
} 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
auto time = _source;
time.remove("cpu/loadaverages/loadaverage");
auto key = QString("la%1").arg(time);
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 == "memory/physical/application") {
} else if (_source == "mem/physical/application") {
// app memory
// mb
m_map.insert(_source, "memmb");
@ -241,7 +237,7 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
// gb
m_map.insert(_source, "memgb");
m_formatter["memgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "memory/physical/free") {
} else if (_source == "mem/physical/free") {
// free memory
// mb
m_map.insert(_source, "memfreemb");
@ -249,7 +245,7 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
// gb
m_map.insert(_source, "memfreegb");
m_formatter["memfreegb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "memory/physical/used") {
} else if (_source == "mem/physical/used") {
// used memory
// mb
m_map.insert(_source, "memusedmb");
@ -257,29 +253,29 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
// gb
m_map.insert(_source, "memusedgb");
m_formatter["memusedgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "extsysmon/network/device") {
} else if (_source == "network/current/name") {
// network device
m_map.insert(_source, "netdev");
m_formatter["netdev"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "extsysmon/network/ssid") {
} else if (_source == "network/current/ssid") {
// current ssid
m_map.insert(_source, "ssid");
m_formatter["ssid"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.startsWith("extsysmon/requests/response")) {
} else if (_source.startsWith("network/response")) {
// network response
auto key = _source;
key.remove("extsysmon/requests/");
QString key = _source;
key.remove("network/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.contains(netRegExp)) {
// network speed
auto type = _source.endsWith("download") ? "down" : "up";
auto index = m_devices["net"].indexOf(_source.split('/')[1]);
QString type = _source.contains("receiver") ? "down" : "up";
int index = m_devices["net"].indexOf(_source.split('/')[2]);
if (index > -1) {
// kb
auto key = QString("%1kb%2").arg(type).arg(index);
QString key = QString("%1kb%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemKBFormat;
m_formatter[key] = AWKeysAggregator::FormatterType::Integer;
// smart
key = QString("%1%2").arg(type).arg(index);
m_map.insert(_source, key);
@ -291,49 +287,49 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
}
} else if (_source.contains(netTotalRegExp)) {
// network data total
auto type = _source.endsWith("Download") ? "down" : "up";
auto index = m_devices["net"].indexOf(_source.split('/')[1]);
QString type = _source.contains("receiver") ? "down" : "up";
int index = m_devices["net"].indexOf(_source.split('/')[2]);
if (index > -1) {
// kb
auto key = QString("%1totkb%2").arg(type).arg(index);
QString key = QString("%1totkb%2").arg(type).arg(index);
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::MemKBFormat;
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("extsysmon/upgrade")) {
} else if (_source.startsWith("upgrade")) {
// package manager
auto key = _source;
key.remove("extsysmon/upgrade/");
QString key = _source;
key.remove("upgrade/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source.startsWith("extsysmon/player")) {
} else if (_source.startsWith("player")) {
// player
auto key = _source;
key.remove("extsysmon/player/");
QString key = _source;
key.remove("player/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "extsysmon/ps/running") {
} else if (_source == "ps/running/count") {
// running processes count
m_map.insert(_source, "pscount");
m_formatter["pscount"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source == "extsysmon/ps/list") {
} else if (_source == "ps/running/list") {
// list of running processes
m_map.insert(_source, "ps");
m_formatter["ps"] = AWKeysAggregator::FormatterType::List;
} else if (_source == "extsysmon/ps/count") {
} else if (_source == "ps/total/count") {
// total processes count
m_map.insert(_source, "pstot");
m_formatter["pstot"] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.startsWith("extsysmon/quotes")) {
} else if (_source.startsWith("quotes")) {
// quotes
auto key = _source;
key.remove("extsysmon/quotes/");
QString key = _source;
key.remove("quotes/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Quotes;
} else if (_source == "memory/swap/free") {
} else if (_source == "mem/swap/free") {
// free swap
// mb
m_map.insert(_source, "swapfreemb");
@ -341,7 +337,7 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
// gb
m_map.insert(_source, "swapfreegb");
m_formatter["swapfreegb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source == "memory/swap/used") {
} else if (_source == "mem/swap/used") {
// used swap
// mb
m_map.insert(_source, "swapmb");
@ -349,20 +345,19 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
// gb
m_map.insert(_source, "swapgb");
m_formatter["swapgb"] = AWKeysAggregator::FormatterType::MemGBFormat;
} else if (_source.startsWith("lmsensors/") || _source.contains(cpuTempRegExp)
|| _source == "cpu/all/averageTemperature") {
} else if (_source.startsWith("lmsensors/")) {
// temperature
auto index = m_devices["temp"].indexOf(_source);
int index = m_devices["temp"].indexOf(_source);
// HACK on DE initialization there are no units key
if (_units == KSysGuard::UnitInvalid)
if (_units.isEmpty())
return QStringList({QString("temp%1").arg(index)});
if (index > -1) {
auto key = QString("temp%1").arg(index);
QString key = QString("temp%1").arg(index);
m_map.insert(_source, key);
m_formatter[key] = _units == KSysGuard::UnitCelsius ? AWKeysAggregator::FormatterType::Temperature
: AWKeysAggregator::FormatterType::Integer;
m_formatter[key] = _units == "°C" ? AWKeysAggregator::FormatterType::Temperature
: AWKeysAggregator::FormatterType::Integer;
}
} else if (_source == "extsysmon/time/now") {
} else if (_source == "Local") {
// time
m_map.insert(_source, "time");
m_formatter["time"] = AWKeysAggregator::FormatterType::Time;
@ -381,40 +376,40 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
// timestamp
m_map.insert(_source, "tstime");
m_formatter["tstime"] = AWKeysAggregator::FormatterType::Timestamp;
} else if (_source == "extsysmon/system/brightness") {
} else if (_source == "system/brightness") {
m_map.insert(_source, "brightness");
m_formatter["brightness"] = AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source == "extsysmon/system/volume") {
} else if (_source == "system/volume") {
m_map.insert(_source, "volume");
m_formatter["volume"] = AWKeysAggregator::FormatterType::IntegerThree;
} else if (_source == "os/system/uptime") {
} 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("extsysmon/weather/temperature")) {
} else if (_source.startsWith("weather/temperature")) {
// temperature
auto key = _source;
key.remove("extsysmon/weather/");
QString key = _source;
key.remove("weather/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Temperature;
} else if (_source.startsWith("extsysmon/weather/")) {
} else if (_source.startsWith("weather/")) {
// other weather
auto key = _source;
key.remove("extsysmon/weather/");
QString key = _source;
key.remove("weather/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::NoFormat;
} else if (_source.startsWith("extsysmon/load/load")) {
} else if (_source.startsWith("load/load")) {
// load source
auto key = _source;
key.remove("extsysmon/load/");
QString key = _source;
key.remove("load/");
m_map.insert(_source, key);
m_formatter[key] = AWKeysAggregator::FormatterType::Temperature;
}
auto foundKeys = keysFromSource(_source);
QStringList foundKeys = keysFromSource(_source);
// rewrite formatters for custom ones
QStringList customFormattersKeys;
@ -429,7 +424,7 @@ QStringList AWDataEngineMapper::registerSource(const QString &_source, const KSy
// drop key from dictionary if no one user requested key required it
qCInfo(LOG_AW) << "Looking for keys" << foundKeys << "in" << _keys;
auto required = _keys.isEmpty() || std::any_of(foundKeys.cbegin(), foundKeys.cend(), [&_keys](auto &key) {
bool required = _keys.isEmpty() || std::any_of(foundKeys.cbegin(), foundKeys.cend(), [&_keys](const QString &key) {
return _keys.contains(key);
});
if (!required) {

View File

@ -15,9 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#include <ksysguard/formatter/Unit.h>
#ifndef AWDATAENGINEMAPPER_H
#define AWDATAENGINEMAPPER_H
#include <QMultiHash>
#include <QObject>
@ -33,12 +33,12 @@ class AWDataEngineMapper : public QObject
public:
explicit AWDataEngineMapper(QObject *_parent = nullptr, AWFormatterHelper *_custom = nullptr);
~AWDataEngineMapper() override = default;
~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, KSysGuard::Unit _units, const QStringList &_keys);
QStringList registerSource(const QString &_source, const QString &_units, const QStringList &_keys);
void setDevices(const QHash<QString, QStringList> &_devices);
private:
@ -48,3 +48,6 @@ private:
QHash<QString, AWKeysAggregator::FormatterType> m_formatter;
QMultiHash<QString, QString> m_map;
};
#endif /* AWDATAENGINEMAPPER_H */

View File

@ -32,20 +32,27 @@ AWDBusAdaptor::AWDBusAdaptor(AWKeys *_parent)
}
AWDBusAdaptor::~AWDBusAdaptor()
{
qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__;
}
QStringList AWDBusAdaptor::ActiveServices()
{
auto listServices = QDBusConnection::sessionBus().interface()->call(QDBus::BlockWithGui, "ListNames");
QDBusMessage listServices = QDBusConnection::sessionBus().interface()->call(QDBus::BlockWithGui, "ListNames");
if (listServices.arguments().isEmpty()) {
qCWarning(LOG_DBUS) << "Could not find any DBus service";
return {};
}
auto arguments = listServices.arguments().first().toStringList();
QStringList arguments = listServices.arguments().first().toStringList();
return std::accumulate(arguments.cbegin(), arguments.cend(), QStringList(), [](auto source, auto &service) {
if (service.startsWith(AWDBUS_SERVICE))
source.append(service);
return source;
});
return std::accumulate(arguments.cbegin(), arguments.cend(), QStringList(),
[](QStringList source, const QString &service) {
if (service.startsWith(AWDBUS_SERVICE))
source.append(service);
return source;
});
}
@ -96,6 +103,6 @@ void AWDBusAdaptor::SetLogLevel(const QString &what, const QString &level, const
return;
}
auto state = enabled ? "true" : "false";
QLoggingCategory::setFilterRules(QString("%1.%2=%3").arg(what, level, state));
QString state = enabled ? "true" : "false";
QLoggingCategory::setFilterRules(QString("%1.%2=%3").arg(what).arg(level).arg(state));
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWDBUSADAPTOR_H
#define AWDBUSADAPTOR_H
#include <QDBusAbstractAdaptor>
@ -31,7 +33,7 @@ class AWDBusAdaptor : public QDBusAbstractAdaptor
public:
explicit AWDBusAdaptor(AWKeys *_parent = nullptr);
~AWDBusAdaptor() override = default;
~AWDBusAdaptor() override;
public slots:
// get methods
@ -48,3 +50,6 @@ private:
AWKeys *m_plugin = nullptr;
QStringList m_logLevels = {"debug", "info", "warning", "critical"};
};
#endif /* AWDBUSADAPTOR_H */

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWPLUGIN_H
#define AWPLUGIN_H
#include <QQmlExtensionPlugin>
@ -28,3 +30,6 @@ class AWPlugin : public QQmlExtensionPlugin
public:
void registerTypes(const char *uri) override;
};
#endif /* AWPLUGIN_H */

View File

@ -27,5 +27,11 @@ AWFormatterConfig::AWFormatterConfig(QWidget *_parent, const QStringList &_keys)
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
setEditable(false, false);
setHelper(std::make_unique<AWFormatterHelper>());
initHelper<AWFormatterHelper>();
}
AWFormatterConfig::~AWFormatterConfig()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWFORMATTERCONFIG_H
#define AWFORMATTERCONFIG_H
#include "awabstractpairconfig.h"
@ -26,5 +28,8 @@ class AWFormatterConfig : public AWAbstractPairConfig
public:
explicit AWFormatterConfig(QWidget *_parent = nullptr, const QStringList &_keys = QStringList());
~AWFormatterConfig() override = default;
~AWFormatterConfig() override;
};
#endif /* AWFORMATTERCONFIG_H */

View File

@ -33,7 +33,7 @@
#include "awstringformatter.h"
AWFormatterHelper::AWFormatterHelper(QObject *_parent)
AWFormatterHelper::AWFormatterHelper(QWidget *_parent)
: AbstractExtItemAggregator(_parent, "formatters")
, AWAbstractPairHelper("awesomewidgets/formatters/formatters.ini", "Formatters")
{
@ -58,7 +58,8 @@ void AWFormatterHelper::initItems()
// assign internal storage
m_formatters.clear();
for (auto [key, name] : pairs().asKeyValueRange()) {
for (auto &key : pairs().keys()) {
auto name = pairs()[key];
if (!m_formattersClasses.contains(name)) {
qCWarning(LOG_AW) << "Invalid formatter" << name << "found in" << key;
continue;
@ -86,7 +87,7 @@ QStringList AWFormatterHelper::definedFormatters() const
QList<AbstractExtItem *> AWFormatterHelper::items() const
{
QList<AbstractExtItem *> converted;
for (auto item : m_formattersClasses.values())
for (auto &item : m_formattersClasses.values())
converted.append(item);
return converted;
@ -113,7 +114,8 @@ QStringList AWFormatterHelper::rightKeys()
void AWFormatterHelper::editItems()
{
auto ret = exec();
repaintList();
int ret = exec();
qCInfo(LOG_AW) << "Dialog returns" << ret;
}
@ -122,7 +124,7 @@ AWAbstractFormatter::FormatterClass AWFormatterHelper::defineFormatterClass(cons
{
qCDebug(LOG_AW) << "Define formatter class for" << _stringType;
auto formatter = AWAbstractFormatter::FormatterClass::NoFormat;
AWAbstractFormatter::FormatterClass formatter = AWAbstractFormatter::FormatterClass::NoFormat;
if (_stringType == "DateTime")
formatter = AWAbstractFormatter::FormatterClass::DateTime;
else if (_stringType == "Float")
@ -150,17 +152,17 @@ void AWFormatterHelper::initFormatters()
auto dirs = directories();
for (auto &dir : dirs) {
auto files = QDir(dir).entryList(QDir::Files, QDir::Name);
QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name);
for (auto &file : files) {
// check filename
if (!file.endsWith(".desktop"))
continue;
qCInfo(LOG_AW) << "Found file" << file << "in" << dir;
auto filePath = QString("%1/%2").arg(dir, file);
QString filePath = QString("%1/%2").arg(dir).arg(file);
// check if already exists
auto values = m_formattersClasses.values();
if (std::any_of(values.cbegin(), values.cend(),
[&filePath](auto item) { return (item->filePath() == filePath); }))
[&filePath](const AWAbstractFormatter *item) { return (item->fileName() == filePath); }))
continue;
auto metadata = readMetadata(filePath);
@ -197,43 +199,42 @@ QPair<QString, AWAbstractFormatter::FormatterClass> AWFormatterHelper::readMetad
qCDebug(LOG_AW) << "Read initial parameters from" << _filePath;
QSettings settings(_filePath, QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
auto name = settings.value("Name", _filePath).toString();
auto type = settings.value("X-AW-Type", "NoFormat").toString();
auto formatter = defineFormatterClass(type);
QString name = settings.value("Name", _filePath).toString();
QString type = settings.value("X-AW-Type", "NoFormat").toString();
AWAbstractFormatter::FormatterClass formatter = defineFormatterClass(type);
settings.endGroup();
return {name, formatter};
return QPair<QString, AWAbstractFormatter::FormatterClass>(name, formatter);
}
void AWFormatterHelper::doCreateItem(QListWidget *_widget)
void AWFormatterHelper::doCreateItem()
{
QStringList selection = {"NoFormat", "DateTime", "Float", "List", "Script", "String", "Json"};
bool ok;
auto select = QInputDialog::getItem(nullptr, i18n("Select type"), i18n("Type:"), selection, 0, false, &ok);
QString select = QInputDialog::getItem(this, i18n("Select type"), i18n("Type:"), selection, 0, false, &ok);
if (!ok) {
qCWarning(LOG_AW) << "No type selected";
return;
}
qCInfo(LOG_AW) << "Selected type" << select;
auto formatter = defineFormatterClass(select);
AWAbstractFormatter::FormatterClass formatter = defineFormatterClass(select);
switch (formatter) {
case AWAbstractFormatter::FormatterClass::DateTime:
return createItem<AWDateTimeFormatter>(_widget);
return createItem<AWDateTimeFormatter>();
case AWAbstractFormatter::FormatterClass::Float:
return createItem<AWFloatFormatter>(_widget);
return createItem<AWFloatFormatter>();
case AWAbstractFormatter::FormatterClass::List:
return createItem<AWListFormatter>(_widget);
return createItem<AWListFormatter>();
case AWAbstractFormatter::FormatterClass::Script:
return createItem<AWScriptFormatter>(_widget);
return createItem<AWScriptFormatter>();
case AWAbstractFormatter::FormatterClass::String:
return createItem<AWStringFormatter>(_widget);
return createItem<AWStringFormatter>();
case AWAbstractFormatter::FormatterClass::Json:
return createItem<AWJsonFormatter>(_widget);
return createItem<AWJsonFormatter>();
case AWAbstractFormatter::FormatterClass::NoFormat:
return createItem<AWNoFormatter>(_widget);
return createItem<AWNoFormatter>();
}
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWFORMATTERHELPER_H
#define AWFORMATTERHELPER_H
#include "abstractextitemaggregator.h"
#include "awabstractformatter.h"
@ -27,7 +29,7 @@ class AWFormatterHelper : public AbstractExtItemAggregator, public AWAbstractPai
Q_OBJECT
public:
explicit AWFormatterHelper(QObject *_parent = nullptr);
explicit AWFormatterHelper(QWidget *_parent = nullptr);
~AWFormatterHelper() override;
// read-write methods
void initItems() override;
@ -49,8 +51,11 @@ private:
void initFormatters();
[[nodiscard]] static QPair<QString, AWAbstractFormatter::FormatterClass> readMetadata(const QString &_filePath);
// parent methods
void doCreateItem(QListWidget *_widget) override;
void doCreateItem() override;
// properties
QHash<QString, AWAbstractFormatter *> m_formatters;
QHash<QString, AWAbstractFormatter *> m_formattersClasses;
};
#endif /* AWFORMATTERHELPER_H */

View File

@ -20,7 +20,6 @@
#include <QDir>
#include <QNetworkInterface>
#include <QRegularExpression>
#include <QSettings>
#include <QStandardPaths>
@ -31,7 +30,7 @@ bool AWKeyCache::addKeyToCache(const QString &_type, const QString &_key)
{
qCDebug(LOG_AW) << "Key" << _key << "with type" << _type;
auto fileName
QString fileName
= QString("%1/awesomewidgets.ndx").arg(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
qCInfo(LOG_AW) << "Cache file" << fileName;
QSettings cache(fileName, QSettings::IniFormat);
@ -41,10 +40,21 @@ bool AWKeyCache::addKeyToCache(const QString &_type, const QString &_key)
for (auto &number : cache.allKeys())
cachedValues.append(cache.value(number).toString());
if (_type == "net") {
auto rawInterfaceList = QNetworkInterface::allInterfaces();
if (_type == "hdd") {
QStringList allDevices = QDir("/dev").entryList(QDir::System, QDir::Name);
QStringList devices = allDevices.filter(QRegExp("^[hms]d[a-z]$"));
for (auto &dev : devices) {
QString device = QString("/dev/%1").arg(dev);
if (cachedValues.contains(device))
continue;
qCInfo(LOG_AW) << "Found new key" << device << "for type" << _type;
cachedValues.append(device);
cache.setValue(QString("%1").arg(cache.allKeys().count(), 3, 10, QChar('0')), device);
}
} else if (_type == "net") {
QList<QNetworkInterface> rawInterfaceList = QNetworkInterface::allInterfaces();
for (auto &interface : rawInterfaceList) {
auto device = interface.name();
QString device = interface.name();
if (cachedValues.contains(device))
continue;
qCInfo(LOG_AW) << "Found new key" << device << "for type" << _type;
@ -74,29 +84,28 @@ QStringList AWKeyCache::getRequiredKeys(const QStringList &_keys, const QStringL
used.unite(QSet(_bars.cbegin(), _bars.cend()));
used.unite(QSet(_userKeys.cbegin(), _userKeys.cend()));
// insert keys from tooltip
for (auto [key, value] : _tooltip.asKeyValueRange()) {
if ((key.endsWith("Tooltip")) && value.toBool()) {
auto local = key;
local.remove("Tooltip");
used << local;
for (auto &key : _tooltip.keys()) {
if ((key.endsWith("Tooltip")) && (_tooltip[key].toBool())) {
key.remove("Tooltip");
used << key;
}
}
// insert depending keys, refer to AWKeys::calculateValues()
// hddtotmb*
for (auto &key : _allKeys.filter(QRegularExpression("^hddtotmb"))) {
for (auto &key : _allKeys.filter(QRegExp("^hddtotmb"))) {
if (!used.contains(key))
continue;
key.remove("hddtotmb");
auto index = key.toInt();
int index = key.toInt();
used << QString("hddfreemb%1").arg(index) << QString("hddmb%1").arg(index);
}
// hddtotgb*
for (auto &key : _allKeys.filter(QRegularExpression("^hddtotgb"))) {
for (auto &key : _allKeys.filter(QRegExp("^hddtotgb"))) {
if (!used.contains(key))
continue;
key.remove("hddtotgb");
auto index = key.toInt();
int index = key.toInt();
used << QString("hddfreegb%1").arg(index) << QString("hddgb%1").arg(index);
}
// mem
@ -129,12 +138,12 @@ QStringList AWKeyCache::getRequiredKeys(const QStringList &_keys, const QStringL
for (auto &key : netKeys) {
if (!used.contains(key))
continue;
auto filt = _allKeys.filter(QRegularExpression(QString("^%1[0-9]{1,}").arg(key)));
QStringList filt = _allKeys.filter(QRegExp(QString("^%1[0-9]{1,}").arg(key)));
for (auto &filtered : filt)
used << filtered;
}
// netdev key
if (std::any_of(netKeys.cbegin(), netKeys.cend(), [&used](auto &key) { return used.contains(key); }))
if (std::any_of(netKeys.cbegin(), netKeys.cend(), [&used](const QString &key) { return used.contains(key); }))
used << "netdev";
// HACK append dummy if there are no other keys. This hack is required
@ -148,7 +157,7 @@ QStringList AWKeyCache::getRequiredKeys(const QStringList &_keys, const QStringL
QHash<QString, QStringList> AWKeyCache::loadKeysFromCache()
{
auto fileName
QString fileName
= QString("%1/awesomewidgets.ndx").arg(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
qCInfo(LOG_AW) << "Cache file" << fileName;
QSettings cache(fileName, QSettings::IniFormat);

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWKEYCACHE_H
#define AWKEYCACHE_H
#include <QHash>
#include <QString>
@ -29,3 +31,6 @@ QStringList getRequiredKeys(const QStringList &_keys, const QStringList &_bars,
const QStringList &_userKeys, const QStringList &_allKeys);
QHash<QString, QStringList> loadKeysFromCache();
} // namespace AWKeyCache
#endif /* AWKEYCACHE_H */

View File

@ -18,7 +18,7 @@
#include "awkeyoperations.h"
#include <QDir>
#include <QRegularExpression>
#include <QRegExp>
#include <QThread>
#include "awcustomkeyshelper.h"
@ -40,12 +40,18 @@ AWKeyOperations::AWKeyOperations(QObject *_parent)
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_customKeys = new AWCustomKeysHelper(this);
m_graphicalItems = new ExtItemAggregator<GraphicalItem>(this, "desktops");
m_extNetRequest = new ExtItemAggregator<ExtNetworkRequest>(this, "requests");
m_extQuotes = new ExtItemAggregator<ExtQuotes>(this, "quotes");
m_extScripts = new ExtItemAggregator<ExtScript>(this, "scripts");
m_extUpgrade = new ExtItemAggregator<ExtUpgrade>(this, "upgrade");
m_extWeather = new ExtItemAggregator<ExtWeather>(this, "weather");
m_graphicalItems = new ExtItemAggregator<GraphicalItem>(nullptr, "desktops");
m_extNetRequest = new ExtItemAggregator<ExtNetworkRequest>(nullptr, "requests");
m_extQuotes = new ExtItemAggregator<ExtQuotes>(nullptr, "quotes");
m_extScripts = new ExtItemAggregator<ExtScript>(nullptr, "scripts");
m_extUpgrade = new ExtItemAggregator<ExtUpgrade>(nullptr, "upgrade");
m_extWeather = new ExtItemAggregator<ExtWeather>(nullptr, "weather");
}
AWKeyOperations::~AWKeyOperations()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
@ -66,6 +72,7 @@ QHash<QString, QStringList> AWKeyOperations::devices() const
void AWKeyOperations::updateCache()
{
// update network and hdd list
addKeyToCache("hdd");
addKeyToCache("net");
}
@ -74,7 +81,7 @@ QStringList AWKeyOperations::dictKeys() const
{
QStringList allKeys;
// weather
for (auto item : m_extWeather->activeItems()) {
for (auto &item : m_extWeather->activeItems()) {
allKeys.append(item->tag("weatherId"));
allKeys.append(item->tag("weather"));
allKeys.append(item->tag("humidity"));
@ -83,20 +90,15 @@ QStringList AWKeyOperations::dictKeys() const
allKeys.append(item->tag("timestamp"));
}
// cpuclock & cpu
for (auto i = 0; i < QThread::idealThreadCount(); ++i) {
for (int i = 0; i < QThread::idealThreadCount(); i++) {
allKeys.append(QString("cpucl%1").arg(i));
allKeys.append(QString("cpu%1").arg(i));
}
// temperature
for (auto i = 0; i < m_devices["temp"].count(); ++i)
for (int i = 0; i < m_devices["temp"].count(); i++)
allKeys.append(QString("temp%1").arg(i));
// gpu
for (auto i = 0; i < m_devices["gpu"].count(); ++i) {
allKeys.append(QString("gpu%1").arg(i));
allKeys.append(QString("gputemp%1").arg(i));
}
// hdd
for (auto i = 0; i < m_devices["mount"].count(); ++i) {
for (int i = 0; i < m_devices["mount"].count(); i++) {
allKeys.append(QString("hddmb%1").arg(i));
allKeys.append(QString("hddgb%1").arg(i));
allKeys.append(QString("hddfreemb%1").arg(i));
@ -106,12 +108,15 @@ QStringList AWKeyOperations::dictKeys() const
allKeys.append(QString("hdd%1").arg(i));
}
// hdd speed
for (auto i = 0; i < m_devices["disk"].count(); ++i) {
for (int i = 0; i < m_devices["disk"].count(); i++) {
allKeys.append(QString("hddr%1").arg(i));
allKeys.append(QString("hddw%1").arg(i));
}
// hdd temp
for (int i = 0; i < m_devices["hdd"].count(); i++)
allKeys.append(QString("hddtemp%1").arg(i));
// network
for (auto 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("upunits%1").arg(i));
allKeys.append(QString("downtotkb%1").arg(i));
@ -124,9 +129,10 @@ QStringList AWKeyOperations::dictKeys() const
allKeys.append(QString("up%1").arg(i));
}
// battery
auto allBatteryDevices = QDir("/sys/class/power_supply")
.entryList(QStringList({"BAT*"}), QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
for (int i = 0; i < allBatteryDevices.count(); ++i) {
QStringList allBatteryDevices
= QDir("/sys/class/power_supply")
.entryList(QStringList({"BAT*"}), QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
for (int i = 0; i < allBatteryDevices.count(); i++) {
allKeys.append(QString("bat%1").arg(i));
allKeys.append(QString("batleft%1").arg(i));
allKeys.append(QString("batnow%1").arg(i));
@ -134,10 +140,10 @@ QStringList AWKeyOperations::dictKeys() const
allKeys.append(QString("battotal%1").arg(i));
}
// package manager
for (auto item : m_extUpgrade->activeItems())
for (auto &item : m_extUpgrade->activeItems())
allKeys.append(item->tag("pkgcount"));
// quotes
for (auto item : m_extQuotes->activeItems()) {
for (auto &item : m_extQuotes->activeItems()) {
allKeys.append(item->tag("price"));
allKeys.append(item->tag("pricechg"));
allKeys.append(item->tag("percpricechg"));
@ -146,13 +152,13 @@ QStringList AWKeyOperations::dictKeys() const
allKeys.append(item->tag("percvolumechg"));
}
// custom
for (auto item : m_extScripts->activeItems())
for (auto &item : m_extScripts->activeItems())
allKeys.append(item->tag("custom"));
// network requests
for (auto item : m_extNetRequest->activeItems())
for (auto &item : m_extNetRequest->activeItems())
allKeys.append(item->tag("response"));
// bars
for (auto item : m_graphicalItems->activeItems())
for (auto &item : m_graphicalItems->activeItems())
allKeys.append(item->tag("bar"));
// user defined keys
allKeys.append(m_customKeys->keys());
@ -199,58 +205,52 @@ QString AWKeyOperations::infoByKey(const QString &_key) const
{
qCDebug(LOG_AW) << "Requested key" << _key;
static auto numberRegExp = QRegularExpression("\\d+");
auto stripped = _key;
stripped.remove(numberRegExp);
QString stripped = _key;
stripped.remove(QRegExp("\\d+"));
QString output;
static auto hddRegExp = QRegularExpression("^hdd(|mb|gb|freemb|freegb|totmb|totgb)");
static auto hddrwRegExp = QRegularExpression("^hdd[rw]");
static auto hddMatchRegExp = QRegularExpression("^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)");
static auto netRegExp = QRegularExpression("^(down|up)");
static auto netMatchRegExp = QRegularExpression("^(down|up)[0-9]");
static auto quotesRegExp = QRegularExpression("^(|perc)(ask|bid|price)(chg|)");
static auto weatherRegExp = QRegularExpression("^(weather|weatherId|humidity|pressure|temperature)");
if (_key.startsWith("bar")) {
auto item = m_graphicalItems->itemByTag(_key, stripped);
AbstractExtItem *item = m_graphicalItems->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.startsWith("custom")) {
auto item = m_extScripts->itemByTag(_key, stripped);
AbstractExtItem *item = m_extScripts->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.contains(hddrwRegExp)) {
auto index = _key;
index.remove(hddrwRegExp);
} else if (_key.contains(QRegExp("^hdd[rw]"))) {
QString index = _key;
index.remove(QRegExp("hdd[rw]"));
output = m_devices["disk"][index.toInt()];
} else if (_key.contains(hddMatchRegExp)) {
auto index = _key;
index.remove(hddRegExp);
} else if (_key.contains(QRegExp("^hdd([0-9]|mb|gb|freemb|freegb|totmb|totgb)"))) {
QString index = _key;
index.remove(QRegExp("^hdd(|mb|gb|freemb|freegb|totmb|totgb)"));
output = m_devices["mount"][index.toInt()];
} else if (_key.contains(netMatchRegExp)) {
auto index = _key;
index.remove(netRegExp);
} else if (_key.startsWith("hddtemp")) {
QString index = _key;
index.remove("hddtemp");
output = m_devices["hdd"][index.toInt()];
} else if (_key.contains(QRegExp("^(down|up)[0-9]"))) {
QString index = _key;
index.remove(QRegExp("^(down|up)"));
output = m_devices["net"][index.toInt()];
} else if (_key.startsWith("pkgcount")) {
auto item = m_extUpgrade->itemByTag(_key, stripped);
AbstractExtItem *item = m_extUpgrade->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.contains(quotesRegExp)) {
auto item = m_extQuotes->itemByTag(_key, stripped);
} else if (_key.contains(QRegExp("(^|perc)(ask|bid|price)(chg|)"))) {
AbstractExtItem *item = m_extQuotes->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.contains(weatherRegExp)) {
auto item = m_extWeather->itemByTag(_key, stripped);
} else if (_key.contains(QRegExp("(weather|weatherId|humidity|pressure|temperature)"))) {
AbstractExtItem *item = m_extWeather->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else if (_key.startsWith("temp")) {
auto index = _key;
QString index = _key;
index.remove("temp");
output = m_devices["temp"][index.toInt()];
} else if (_key.startsWith("response")) {
auto item = m_extNetRequest->itemByTag(_key, stripped);
AbstractExtItem *item = m_extNetRequest->itemByTag(_key, stripped);
if (item)
output = item->uniq();
} else {
@ -279,10 +279,8 @@ void AWKeyOperations::editItem(const QString &_type)
{
qCDebug(LOG_AW) << "Item type" << _type;
static auto supportsGraphicalRegExp = QRegularExpression("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)");
if (_type == "graphicalitem") {
auto keys = dictKeys().filter(supportsGraphicalRegExp);
QStringList keys = dictKeys().filter(QRegExp("^(cpu(?!cl).*|gpu$|mem$|swap$|hdd[0-9].*|bat.*)"));
keys.sort();
m_graphicalItems->setConfigArgs(keys);
return m_graphicalItems->editItems();
@ -304,26 +302,19 @@ void AWKeyOperations::addDevice(const QString &_source)
{
qCDebug(LOG_AW) << "Source" << _source;
static auto diskRegexp = QRegularExpression("^disk/.*/read$");
static auto mountRegexp = QRegularExpression("^disk/.*/usedPercent$");
static auto cpuTempRegExp = QRegularExpression("^cpu/cpu.*/temperature$");
static auto gpuRegExp = QRegularExpression("^gpu/gpu.*/usage$");
QRegExp diskRegexp = QRegExp("disk/(?:md|sd|hd)[a-z|0-9]_.*/Rate/(?:rblk)");
QRegExp mountRegexp = QRegExp("partitions/.*/filllevel");
if (_source.contains(diskRegexp)) {
auto device = _source;
device.remove("disk/").remove("/read");
QString device = _source;
device.remove("/Rate/rblk");
addKeyToCache("disk", device);
} else if (_source.contains(mountRegexp)) {
auto device = _source;
device.remove("disk/").remove("/usedPercent");
QString device = _source;
device.remove("partitions").remove("/filllevel");
addKeyToCache("mount", device);
} else if (_source.startsWith("lmsensors") || _source.contains(cpuTempRegExp)
|| _source == "cpu/all/averageTemperature") {
} else if (_source.startsWith("lmsensors")) {
addKeyToCache("temp", _source);
} else if (_source.contains(gpuRegExp)) {
auto device = _source;
device.remove("gpu/").remove("/usage");
addKeyToCache("gpu", device);
}
}
@ -350,7 +341,7 @@ void AWKeyOperations::reinitKeys()
m_extWeather->initItems();
// init
auto allKeys = dictKeys();
QStringList allKeys = dictKeys();
// apply aw_* functions
m_pattern = AWPatternFunctions::insertAllKeys(m_pattern, allKeys);

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWKEYOPERATIONS_H
#define AWKEYOPERATIONS_H
#include <QObject>
@ -37,7 +39,7 @@ class AWKeyOperations : public QObject
public:
explicit AWKeyOperations(QObject *_parent = nullptr);
~AWKeyOperations() override = default;
~AWKeyOperations() override;
[[nodiscard]] QStringList devices(const QString &_type) const;
[[nodiscard]] QHash<QString, QStringList> devices() const;
void updateCache();
@ -76,3 +78,6 @@ private:
QHash<QString, QStringList> m_devices;
QString m_pattern;
};
#endif /* AWKEYOPERATIONS_H */

View File

@ -19,8 +19,9 @@
#include <QDBusConnection>
#include <QDBusError>
#include <QRegularExpression>
#include <QThread>
#include <QTimer>
#include <QtConcurrent/QtConcurrent>
#include "awdataaggregator.h"
#include "awdataengineaggregator.h"
@ -41,6 +42,9 @@ AWKeys::AWKeys(QObject *_parent)
for (auto &metadata : AWDebug::getBuildData())
qCDebug(LOG_AW) << metadata;
// thread pool
m_threadPool = new QThreadPool(this);
m_aggregator = new AWKeysAggregator(this);
m_dataAggregator = new AWDataAggregator(this);
m_dataEngineAggregator = new AWDataEngineAggregator(this);
@ -52,17 +56,16 @@ AWKeys::AWKeys(QObject *_parent)
createDBusInterface();
// update key data if required
connect(m_keyOperator, &AWKeyOperations::updateKeys, this, &AWKeys::reinitKeys);
connect(m_timer, &QTimer::timeout, this, &AWKeys::updateTextData);
connect(m_keyOperator, SIGNAL(updateKeys(const QStringList &)), this, SLOT(reinitKeys(const QStringList &)));
connect(m_timer, SIGNAL(timeout()), this, SLOT(updateTextData()));
// transfer signal from AWDataAggregator object to QML ui
connect(m_dataAggregator, &AWDataAggregator::toolTipPainted,
[this](const QString &_tooltip) { emit(needToolTipToBeUpdated(_tooltip)); });
connect(this, &AWKeys::dropSourceFromDataengine, m_dataEngineAggregator, &AWDataEngineAggregator::dropSource);
connect(m_dataEngineAggregator, &AWDataEngineAggregator::dataUpdated, this, &AWKeys::dataUpdated);
connect(m_dataAggregator, SIGNAL(toolTipPainted(const QString &)), this,
SIGNAL(needToolTipToBeUpdated(const QString &)));
connect(this, SIGNAL(dropSourceFromDataengine(const QString &)), m_dataEngineAggregator,
SLOT(dropSource(const QString &)));
// transfer signal from dataengine to update source list
connect(m_dataEngineAggregator, &AWDataEngineAggregator::deviceAdded, m_keyOperator, &AWKeyOperations::addDevice);
connect(m_dataEngineAggregator, SIGNAL(deviceAdded(const QString &)), m_keyOperator,
SLOT(addDevice(const QString &)));
}
@ -87,17 +90,19 @@ void AWKeys::initDataAggregator(const QVariantMap &_tooltipParams)
}
void AWKeys::initKeys(const QString &_currentPattern, const int _interval, const bool _optimize)
void AWKeys::initKeys(const QString &_currentPattern, const int _interval, const int _limit, const bool _optimize)
{
qCDebug(LOG_AW) << "Pattern" << _currentPattern << "with interval" << _interval << "with optimization" << _optimize;
qCDebug(LOG_AW) << "Pattern" << _currentPattern << "with interval" << _interval << "and queue limit" << _limit
<< "with optimization" << _optimize;
// init
m_optimize = _optimize;
m_threadPool->setMaxThreadCount(_limit == 0 ? QThread::idealThreadCount() : _limit);
// child objects
m_aggregator->initFormatters();
m_keyOperator->setPattern(_currentPattern);
m_keyOperator->updateCache();
m_dataEngineAggregator->loadSources();
m_dataEngineAggregator->reconnectSources(_interval);
// timer
m_timer->setInterval(_interval);
@ -143,7 +148,27 @@ QStringList AWKeys::dictKeys(const bool _sorted, const QString &_regexp) const
if (_sorted)
allKeys.sort();
return allKeys.filter(QRegularExpression(_regexp));
return allKeys.filter(QRegExp(_regexp));
}
QVariantList AWKeys::getHddDevices() const
{
QStringList hddDevices = m_keyOperator->devices("hdd");
// required by selector in the UI
hddDevices.insert(0, "disable");
hddDevices.insert(0, "auto");
// build model
QVariantList devices;
for (auto &device : hddDevices) {
QVariantMap model;
model["label"] = device;
model["name"] = device;
devices.append(model);
}
return devices;
}
@ -160,9 +185,9 @@ QString AWKeys::valueByKey(const QString &_key) const
{
qCDebug(LOG_AW) << "Requested value for key" << _key;
auto realKey = _key.startsWith("bar") ? m_keyOperator->infoByKey(_key) : _key;
QString trueKey = _key.startsWith("bar") ? m_keyOperator->infoByKey(_key) : _key;
return m_aggregator->formatter(m_values[realKey], realKey, true);
return m_aggregator->formatter(m_values[trueKey], trueKey, true);
}
@ -174,16 +199,10 @@ void AWKeys::editItem(const QString &_type)
}
void AWKeys::dataUpdated(const QHash<QString, KSysGuard::SensorInfo> &_sensors, const KSysGuard::SensorDataList &_data)
void AWKeys::dataUpdated(const QString &_sourceName, const Plasma::DataEngine::Data &_data)
{
qCDebug(LOG_AW) << "Update data for" << _data.count() << "items";
for (auto &data : _data) {
if (!_sensors.contains(data.sensorProperty))
continue;
auto sensor = _sensors[data.sensorProperty];
setDataBySource(data.sensorProperty, sensor, data.payload);
}
// run concurrent data update
QtConcurrent::run(m_threadPool, this, &AWKeys::setDataBySource, _sourceName, _data);
}
@ -198,7 +217,7 @@ void AWKeys::reinitKeys(const QStringList &_currentKeys)
// generate list of required keys for bars
QStringList barKeys;
for (auto &bar : m_foundBars) {
auto item = m_keyOperator->giByKey(bar);
GraphicalItem *item = m_keyOperator->giByKey(bar);
if (item->isCustom())
item->setUsedKeys(AWPatternFunctions::findKeys(item->bar(), _currentKeys, false));
else
@ -218,10 +237,12 @@ void AWKeys::reinitKeys(const QStringList &_currentKeys)
void AWKeys::updateTextData()
{
// do not do it in parallel to avoid race condition
m_mutex.lock();
calculateValues();
auto text = parsePattern(m_keyOperator->pattern());
QString text = parsePattern(m_keyOperator->pattern());
// update tooltip values under lock
m_dataAggregator->dataUpdate(m_values);
m_mutex.unlock();
emit(needTextToBeUpdated(text));
}
@ -232,23 +253,23 @@ void AWKeys::updateTextData()
void AWKeys::calculateValues()
{
// hddtot*
auto mountDevices = m_keyOperator->devices("mount");
QStringList mountDevices = m_keyOperator->devices("mount");
for (auto &device : mountDevices) {
auto index = mountDevices.indexOf(device);
m_values[QString("hddtotmb%1").arg(index)] = m_values[QString("hddfreemb%1").arg(index)].toDouble()
+ m_values[QString("hddmb%1").arg(index)].toDouble();
m_values[QString("hddtotgb%1").arg(index)] = m_values[QString("hddfreegb%1").arg(index)].toDouble()
+ m_values[QString("hddgb%1").arg(index)].toDouble();
int index = mountDevices.indexOf(device);
m_values[QString("hddtotmb%1").arg(index)]
= m_values[QString("hddfreemb%1").arg(index)].toFloat() + m_values[QString("hddmb%1").arg(index)].toFloat();
m_values[QString("hddtotgb%1").arg(index)]
= m_values[QString("hddfreegb%1").arg(index)].toFloat() + m_values[QString("hddgb%1").arg(index)].toFloat();
}
// memtot*
m_values["memtotmb"] = m_values["memusedmb"].toLongLong() + m_values["memfreemb"].toLongLong();
m_values["memtotgb"] = m_values["memusedgb"].toDouble() + m_values["memfreegb"].toDouble();
m_values["memtotmb"] = m_values["memusedmb"].toInt() + m_values["memfreemb"].toInt();
m_values["memtotgb"] = m_values["memusedgb"].toFloat() + m_values["memfreegb"].toFloat();
// mem
m_values["mem"] = 100.0 * m_values["memmb"].toDouble() / m_values["memtotmb"].toDouble();
m_values["mem"] = 100.0f * m_values["memmb"].toFloat() / m_values["memtotmb"].toFloat();
// up, down, upkb, downkb, upunits, downunits
auto netIndex = m_keyOperator->devices("net").indexOf(m_values["netdev"].toString());
int netIndex = m_keyOperator->devices("net").indexOf(m_values["netdev"].toString());
m_values["down"] = m_values[QString("down%1").arg(netIndex)];
m_values["downkb"] = m_values[QString("downkb%1").arg(netIndex)];
m_values["downtot"] = m_values[QString("downtot%1").arg(netIndex)];
@ -261,10 +282,10 @@ void AWKeys::calculateValues()
m_values["upunits"] = m_values[QString("upunits%1").arg(netIndex)];
// swaptot*
m_values["swaptotmb"] = m_values["swapmb"].toLongLong() + m_values["swapfreemb"].toLongLong();
m_values["swaptotgb"] = m_values["swapgb"].toDouble() + m_values["swapfreegb"].toDouble();
m_values["swaptotmb"] = m_values["swapmb"].toInt() + m_values["swapfreemb"].toInt();
m_values["swaptotgb"] = m_values["swapgb"].toFloat() + m_values["swapfreegb"].toFloat();
// swap
m_values["swap"] = 100.0 * m_values["swapmb"].toDouble() / m_values["swaptotmb"].toDouble();
m_values["swap"] = 100.0f * m_values["swapmb"].toFloat() / m_values["swaptotmb"].toFloat();
// user defined keys
for (auto &key : m_keyOperator->userKeys())
@ -282,7 +303,7 @@ void AWKeys::createDBusInterface()
auto id = reinterpret_cast<qlonglong>(this);
// create session
auto instanceBus = QDBusConnection::sessionBus();
QDBusConnection instanceBus = QDBusConnection::sessionBus();
// HACK we are going to use different services because it binds to
// application
if (instanceBus.registerService(QString("%1.i%2").arg(AWDBUS_SERVICE).arg(id))) {
@ -293,7 +314,7 @@ void AWKeys::createDBusInterface()
}
// and same instance but for id independent service
auto commonBus = QDBusConnection::sessionBus();
QDBusConnection commonBus = QDBusConnection::sessionBus();
if (commonBus.registerService(AWDBUS_SERVICE))
commonBus.registerObject(AWDBUS_PATH, new AWDBusAdaptor(this), QDBusConnection::ExportAllContents);
}
@ -302,7 +323,7 @@ void AWKeys::createDBusInterface()
QString AWKeys::parsePattern(QString _pattern) const
{
// screen sign
_pattern.replace("$$", QChar(0x1d));
_pattern.replace("$$", QString(0x1d));
// lambdas
for (auto &key : m_foundLambdas)
@ -314,15 +335,15 @@ QString AWKeys::parsePattern(QString _pattern) const
// bars
for (auto &bar : m_foundBars) {
auto item = m_keyOperator->giByKey(bar);
auto image = item->isCustom() ? item->image(
AWPatternFunctions::expandLambdas(item->bar(), m_aggregator, m_values, item->usedKeys()))
: item->image(m_values[item->bar()]);
GraphicalItem *item = m_keyOperator->giByKey(bar);
QString image = item->isCustom() ? item->image(
AWPatternFunctions::expandLambdas(item->bar(), m_aggregator, m_values, item->usedKeys()))
: item->image(m_values[item->bar()]);
_pattern.replace(QString("$%1").arg(bar), image);
}
// prepare strings
_pattern.replace(QChar(0x1d), "$");
_pattern.replace(QString(0x1d), "$");
if (m_wrapNewLines)
_pattern.replace("\n", "<br>");
@ -330,20 +351,25 @@ QString AWKeys::parsePattern(QString _pattern) const
}
void AWKeys::setDataBySource(const QString &_source, const KSysGuard::SensorInfo &_sensor, const QVariant &_value)
void AWKeys::setDataBySource(const QString &_sourceName, const QVariantMap &_data)
{
qCDebug(LOG_AW) << "Source" << _source << _sensor.name << "with data" << _value;
qCDebug(LOG_AW) << "Source" << _sourceName << "with data" << _data;
// first list init
auto tags = m_aggregator->keysFromSource(_source);
QStringList tags = m_aggregator->keysFromSource(_sourceName);
if (tags.isEmpty())
tags = m_aggregator->registerSource(_source, _sensor.unit, m_requiredKeys);
tags = m_aggregator->registerSource(_sourceName, _data["units"].toString(), m_requiredKeys);
// update data or drop source if there are no matches and exit
if (tags.isEmpty()) {
qCInfo(LOG_AW) << "Sensor" << _source << "not found";
return emit(dropSourceFromDataengine(_source));
qCInfo(LOG_AW) << "Source" << _sourceName << "not found";
return emit(dropSourceFromDataengine(_sourceName));
}
std::for_each(tags.cbegin(), tags.cend(), [this, _value](const QString &tag) { m_values[tag] = _value; });
m_mutex.lock();
// HACK workaround for time values which are stored in the different path
std::for_each(tags.cbegin(), tags.cend(), [this, &_data, &_sourceName](const QString &tag) {
m_values[tag] = _sourceName == "Local" ? _data["DateTime"] : _data["value"];
});
m_mutex.unlock();
}

View File

@ -15,17 +15,21 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWKEYS_H
#define AWKEYS_H
#include <Plasma/DataEngine>
#include <QMutex>
#include <QObject>
#include <ksysguard/systemstats/SensorInfo.h>
class AWDataAggregator;
class AWDataEngineAggregator;
class AWKeyOperations;
class AWKeysAggregator;
class QThreadPool;
class QTimer;
class AWKeys : public QObject
@ -36,7 +40,7 @@ public:
explicit AWKeys(QObject *_parent = nullptr);
~AWKeys() override;
Q_INVOKABLE void initDataAggregator(const QVariantMap &_tooltipParams);
Q_INVOKABLE void initKeys(const QString &_currentPattern, int _interval, bool _optimize);
Q_INVOKABLE void initKeys(const QString &_currentPattern, int _interval, int _limit, bool _optimize);
Q_INVOKABLE void setAggregatorProperty(const QString &_key, const QVariant &_value);
Q_INVOKABLE void setWrapNewLines(bool _wrap);
// additional method to force load keys from Qml UI. Used in some
@ -44,19 +48,24 @@ public:
Q_INVOKABLE void updateCache();
// keys
Q_INVOKABLE [[nodiscard]] QStringList dictKeys(bool _sorted = false, const QString &_regexp = "") const;
Q_INVOKABLE [[nodiscard]] QVariantList getHddDevices() const;
// values
Q_INVOKABLE [[nodiscard]] QString infoByKey(const QString &_key) const;
Q_INVOKABLE [[nodiscard]] QString valueByKey(const QString &_key) const;
// configuration
Q_INVOKABLE void editItem(const QString &_type);
public slots:
void dataUpdated(const QString &_sourceName, const Plasma::DataEngine::Data &_data);
// dummy method required by DataEngine connections
static void modelChanged(const QString &, QAbstractItemModel *){};
signals:
void dropSourceFromDataengine(const QString &_source);
void needTextToBeUpdated(const QString &_newText) const;
void needToolTipToBeUpdated(const QString &_newText) const;
private slots:
void dataUpdated(const QHash<QString, KSysGuard::SensorInfo> &_sensors, const KSysGuard::SensorDataList &_data);
void reinitKeys(const QStringList &_currentKeys);
void updateTextData();
@ -65,7 +74,7 @@ private:
void calculateValues();
void createDBusInterface();
[[nodiscard]] QString parsePattern(QString _pattern) const;
void setDataBySource(const QString &_source, const KSysGuard::SensorInfo &_sensor, const QVariant &_value);
void setDataBySource(const QString &_sourceName, const QVariantMap &_data);
// objects
AWDataAggregator *m_dataAggregator = nullptr;
AWDataEngineAggregator *m_dataEngineAggregator = nullptr;
@ -78,4 +87,10 @@ private:
QVariantHash m_values;
bool m_optimize = false;
bool m_wrapNewLines = false;
// multithread features
QThreadPool *m_threadPool = nullptr;
QMutex m_mutex;
};
#endif /* AWKEYS_H */

View File

@ -33,7 +33,7 @@ AWKeysAggregator::AWKeysAggregator(QObject *_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_customFormatters = new AWFormatterHelper(this);
m_customFormatters = new AWFormatterHelper(nullptr);
m_mapper = new AWDataEngineMapper(this, m_customFormatters);
// sort time keys
@ -43,6 +43,12 @@ AWKeysAggregator::AWKeysAggregator(QObject *_parent)
}
AWKeysAggregator::~AWKeysAggregator()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWKeysAggregator::initFormatters()
{
m_customFormatters->initItems();
@ -58,19 +64,19 @@ QString AWKeysAggregator::formatter(const QVariant &_data, const QString &_key,
// case block
switch (m_mapper->formatter(_key)) {
case FormatterType::Float:
output = QString("%1").arg(_data.toDouble(), 5, 'f', 1);
output = QString("%1").arg(_data.toFloat(), 5, 'f', 1);
break;
case FormatterType::FloatTwoSymbols:
output = QString("%1").arg(_data.toDouble(), 5, 'f', 2);
output = QString("%1").arg(_data.toFloat(), 5, 'f', 2);
break;
case FormatterType::Integer:
output = QString("%1").arg(_data.toDouble(), 4, 'f', 0);
output = QString("%1").arg(_data.toFloat(), 4, 'f', 0);
break;
case FormatterType::IntegerFive:
output = QString("%1").arg(_data.toDouble(), 5, 'f', 0);
output = QString("%1").arg(_data.toFloat(), 5, 'f', 0);
break;
case FormatterType::IntegerThree:
output = QString("%1").arg(_data.toDouble(), 3, 'f', 0);
output = QString("%1").arg(_data.toFloat(), 3, 'f', 0);
break;
case FormatterType::List:
output = _data.toStringList().join(',');
@ -79,24 +85,21 @@ QString AWKeysAggregator::formatter(const QVariant &_data, const QString &_key,
output = _data.toBool() ? m_acOnline : m_acOffline;
break;
case FormatterType::MemGBFormat:
output = QString("%1").arg(_data.toDouble() / GBinBytes, 5, 'f', 1);
output = QString("%1").arg(_data.toFloat() / (1024.0 * 1024.0), 5, 'f', 1);
break;
case FormatterType::MemMBFormat:
output = QString("%1").arg(_data.toDouble() / MBinBytes, 5, 'f', 0);
break;
case FormatterType::MemKBFormat:
output = QString("%1").arg(_data.toDouble() / KBinBytes, 5, 'f', 0);
output = QString("%1").arg(_data.toFloat() / 1024.0, 5, 'f', 0);
break;
case FormatterType::NetSmartFormat:
output = [](const double value) {
if (value > MBinBytes)
return QString("%1").arg(value / MBinBytes, 4, 'f', 1);
output = [](const float value) {
if (value > 1024.0)
return QString("%1").arg(value / 1024.0, 4, 'f', 1);
else
return QString("%1").arg(value / KBinBytes, 4, 'f', 0);
}(_data.toDouble());
return QString("%1").arg(value, 4, 'f', 0);
}(_data.toFloat());
break;
case FormatterType::NetSmartUnits:
if (_data.toDouble() > MBinBytes)
if (_data.toFloat() > 1024.0)
output = m_translate ? i18n("MB/s") : "MB/s";
else
output = m_translate ? i18n("KB/s") : "KB/s";
@ -107,49 +110,47 @@ QString AWKeysAggregator::formatter(const QVariant &_data, const QString &_key,
output = output.rightJustified(8, QLatin1Char(' '), true);
break;
case FormatterType::Temperature:
output = QString("%1").arg(temperature(_data.toDouble()), 5, 'f', 1);
output = QString("%1").arg(temperature(_data.toFloat()), 5, 'f', 1);
break;
case FormatterType::Time:
output = QDateTime::fromSecsSinceEpoch(_data.toLongLong()).toString();
output = _data.toDateTime().toString();
break;
case FormatterType::TimeCustom:
output = m_customTime;
[&output, loc, this](const QDateTime &dt) {
for (auto &key : m_timeKeys)
output.replace(QString("$%1").arg(key), loc.toString(dt, key));
}(QDateTime::fromSecsSinceEpoch(_data.toLongLong()));
}(_data.toDateTime());
break;
case FormatterType::TimeISO:
output = QDateTime::fromSecsSinceEpoch(_data.toLongLong()).toString(Qt::ISODate);
output = _data.toDateTime().toString(Qt::ISODate);
break;
case FormatterType::TimeLong:
output = loc.toString(QDateTime::fromSecsSinceEpoch(_data.toLongLong()), QLocale::LongFormat);
output = loc.toString(_data.toDateTime(), QLocale::LongFormat);
break;
case FormatterType::TimeShort:
output = loc.toString(QDateTime::fromSecsSinceEpoch(_data.toLongLong()), QLocale::ShortFormat);
output = loc.toString(_data.toDateTime(), QLocale::ShortFormat);
break;
case FormatterType::Timestamp:
output = _data.toString();
output = QString("%1").arg(_data.toDateTime().toMSecsSinceEpoch() / 1000.0, 10, 'f', 0);
break;
case FormatterType::Uptime:
case FormatterType::UptimeCustom:
output =
[](auto source, auto uptime) {
auto seconds = uptime - uptime % 60;
auto minutes = seconds / 60 % 60;
auto hours = ((seconds / 60) - minutes) / 60 % 24;
auto days = (((seconds / 60) - minutes) / 60 - hours) / 24;
[](QString source, const int uptime) {
int seconds = uptime - uptime % 60;
int minutes = seconds / 60 % 60;
int hours = ((seconds / 60) - minutes) / 60 % 24;
int days = (((seconds / 60) - minutes) / 60 - hours) / 24;
source.replace("$dd", QString("%1").arg(days, 3, 10, QChar('0')));
source.replace("$d", QString("%1").arg(days));
source.replace("$hh", QString("%1").arg(hours, 2, 10, QChar('0')));
source.replace("$h", QString("%1").arg(hours));
source.replace("$mm", QString("%1").arg(minutes, 2, 10, QChar('0')));
source.replace("$m", QString("%1").arg(minutes));
return source;
}(m_mapper->formatter(_key) == FormatterType::Uptime ? "$ddd$hhh$mmm" : m_customUptime,
static_cast<int>(_data.toDouble()));
static_cast<int>(_data.toFloat()));
break;
case FormatterType::NoFormat:
output = _data.toString();
@ -233,8 +234,7 @@ void AWKeysAggregator::setTranslate(const bool _translate)
}
QStringList AWKeysAggregator::registerSource(const QString &_source, const KSysGuard::Unit _units,
const QStringList &_keys)
QStringList AWKeysAggregator::registerSource(const QString &_source, const QString &_units, const QStringList &_keys)
{
qCDebug(LOG_AW) << "Source" << _source << "with units" << _units;
@ -242,24 +242,24 @@ QStringList AWKeysAggregator::registerSource(const QString &_source, const KSysG
}
double AWKeysAggregator::temperature(const double temp) const
float AWKeysAggregator::temperature(const float temp) const
{
qCDebug(LOG_AW) << "Temperature value" << temp;
auto converted = temp;
float converted = temp;
if (m_tempUnits == "Celsius") {
} else if (m_tempUnits == "Fahrenheit") {
converted = temp * 9.0f / 5.0 + 32.0;
converted = temp * 9.0f / 5.0f + 32.0f;
} else if (m_tempUnits == "Kelvin") {
converted = temp + 273.15;
converted = temp + 273.15f;
} else if (m_tempUnits == "Reaumur") {
converted = temp * 0.8;
converted = temp * 0.8f;
} else if (m_tempUnits == "cm^-1") {
converted = (temp + 273.15) * 0.695;
converted = (temp + 273.15f) * 0.695f;
} else if (m_tempUnits == "kJ/mol") {
converted = (temp + 273.15) * 8.31;
converted = (temp + 273.15f) * 8.31f;
} else if (m_tempUnits == "kcal/mol") {
converted = (temp + 273.15) * 1.98;
converted = (temp + 273.15f) * 1.98f;
} else {
qCWarning(LOG_AW) << "Invalid units" << m_tempUnits;
}

View File

@ -15,9 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#include <ksysguard/formatter/Unit.h>
#ifndef AWKEYSAGGREGATOR_H
#define AWKEYSAGGREGATOR_H
#include <QHash>
#include <QObject>
@ -51,7 +51,6 @@ public:
ACFormat,
MemGBFormat,
MemMBFormat,
MemKBFormat,
NetSmartFormat,
NetSmartUnits,
Quotes,
@ -66,12 +65,8 @@ public:
UptimeCustom
};
static constexpr double KBinBytes = 1024.0;
static constexpr double MBinBytes = 1024.0 * KBinBytes;
static constexpr double GBinBytes = 1024.0 * MBinBytes;
explicit AWKeysAggregator(QObject *_parent = nullptr);
~AWKeysAggregator() override = default;
~AWKeysAggregator() override;
void initFormatters();
// get methods
[[nodiscard]] QString formatter(const QVariant &_data, const QString &_key, bool replaceSpace) const;
@ -86,10 +81,10 @@ public:
void setTranslate(bool _translate);
public slots:
QStringList registerSource(const QString &_source, KSysGuard::Unit _units, const QStringList &_keys);
QStringList registerSource(const QString &_source, const QString &_units, const QStringList &_keys);
private:
[[nodiscard]] double temperature(double temp) const;
[[nodiscard]] float temperature(float temp) const;
AWFormatterHelper *m_customFormatters = nullptr;
AWDataEngineMapper *m_mapper = nullptr;
QStringList m_timeKeys;
@ -101,3 +96,6 @@ private:
QString m_tempUnits;
bool m_translate = false;
};
#endif /* AWKEYSAGGREGATOR_H */

View File

@ -29,9 +29,15 @@ AWPairConfigFactory::AWPairConfigFactory(QObject *_parent)
}
AWPairConfigFactory::~AWPairConfigFactory()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWPairConfigFactory::showFormatterDialog(const QStringList &_keys)
{
auto config = new AWFormatterConfig(nullptr, _keys);
auto *config = new AWFormatterConfig(nullptr, _keys);
config->showDialog();
config->deleteLater();
}
@ -39,7 +45,7 @@ void AWPairConfigFactory::showFormatterDialog(const QStringList &_keys)
void AWPairConfigFactory::showKeysDialog(const QStringList &_keys)
{
auto config = new AWCustomKeysConfig(nullptr, _keys);
auto *config = new AWCustomKeysConfig(nullptr, _keys);
config->showDialog();
config->deleteLater();
}

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWPAIRCONFIGFACTORY_H
#define AWPAIRCONFIGFACTORY_H
#include <QObject>
@ -26,9 +28,12 @@ class AWPairConfigFactory : public QObject
public:
explicit AWPairConfigFactory(QObject *_parent = nullptr);
~AWPairConfigFactory() override = default;
~AWPairConfigFactory() override;
Q_INVOKABLE static void showFormatterDialog(const QStringList &_keys);
Q_INVOKABLE static void showKeysDialog(const QStringList &_keys);
private:
};
#endif /* AWPAIRCONFIGFACTORY_H */

View File

@ -36,7 +36,7 @@ QString AWPatternFunctions::expandLambdas(QString _code, AWKeysAggregator *_aggr
for (auto &lambdaKey : _usedKeys)
_code.replace(QString("$%1").arg(lambdaKey), _aggregator->formatter(_metadata[lambdaKey], lambdaKey, false));
qCInfo(LOG_AW) << "Expression" << _code;
auto result = engine.evaluate(_code);
QJSValue result = engine.evaluate(_code);
if (result.isError()) {
qCWarning(LOG_AW) << "Uncaught exception at line" << result.property("lineNumber").toInt() << ":"
<< result.toString();
@ -52,17 +52,17 @@ QString AWPatternFunctions::expandTemplates(QString _code)
qCDebug(LOG_AW) << "Expand templates in" << _code;
// match the following construction $template{{some code here}}
static QRegularExpression templatesRegexp(R"(\$template\{\{(?<body>.*?)\}\})");
QRegularExpression templatesRegexp(R"(\$template\{\{(?<body>.*?)\}\})");
templatesRegexp.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
auto it = templatesRegexp.globalMatch(_code);
QRegularExpressionMatchIterator it = templatesRegexp.globalMatch(_code);
while (it.hasNext()) {
auto match = it.next();
auto body = match.captured("body");
QRegularExpressionMatch match = it.next();
QString body = match.captured("body");
QJSEngine engine;
qCInfo(LOG_AW) << "Expression" << body;
auto result = engine.evaluate(body);
QJSValue result = engine.evaluate(body);
QString templateResult = "";
if (result.isError()) {
qCWarning(LOG_AW) << "Uncaught exception at line" << result.property("lineNumber").toInt() << ":"
@ -94,20 +94,20 @@ QList<AWPatternFunctions::AWFunction> AWPatternFunctions::findFunctionCalls(cons
regex.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
QList<AWPatternFunctions::AWFunction> foundFunctions;
auto it = regex.globalMatch(_code);
QRegularExpressionMatchIterator it = regex.globalMatch(_code);
while (it.hasNext()) {
auto match = it.next();
QRegularExpressionMatch match = it.next();
AWPatternFunctions::AWFunction metadata;
// work with args
auto argsString = match.captured("args");
QString argsString = match.captured("args");
if (argsString.isEmpty()) {
metadata.args = QStringList();
} else {
// replace '$,' to 0x1d
argsString.replace("$,", QChar(0x1d));
auto args = argsString.split(',');
std::for_each(args.begin(), args.end(), [](auto &arg) { arg.replace(QChar(0x1d), ","); });
argsString.replace("$,", QString(0x1d));
QStringList args = argsString.split(',');
std::for_each(args.begin(), args.end(), [](QString &arg) { arg.replace(QString(0x1d), ","); });
metadata.args = args;
}
// other variables
@ -127,11 +127,11 @@ QString AWPatternFunctions::insertAllKeys(QString _code, const QStringList &_key
{
qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" << _keys;
auto found = AWPatternFunctions::findFunctionCalls("aw_all", _code);
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_all", _code);
for (auto &function : found) {
auto separator = function.args.isEmpty() ? "," : function.args.at(0);
auto required = _keys.filter(QRegularExpression(function.body));
std::for_each(required.begin(), required.end(), [](auto &value) { value = QString("%1: $%1").arg(value); });
QString separator = function.args.isEmpty() ? "," : function.args.at(0);
QStringList required = _keys.filter(QRegExp(function.body));
std::for_each(required.begin(), required.end(), [](QString &value) { value = QString("%1: $%1").arg(value); });
_code.replace(function.what, required.join(separator));
}
@ -144,9 +144,9 @@ QString AWPatternFunctions::insertKeyCount(QString _code, const QStringList &_ke
{
qCDebug(LOG_AW) << "Looking for count in code" << _code << "using list" << _keys;
auto found = AWPatternFunctions::findFunctionCalls("aw_count", _code);
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_count", _code);
for (auto &function : found) {
auto count = _keys.filter(QRegularExpression(function.body)).count();
int count = _keys.filter(QRegExp(function.body)).count();
_code.replace(function.what, QString::number(count));
}
@ -159,10 +159,10 @@ QString AWPatternFunctions::insertKeyNames(QString _code, const QStringList &_ke
{
qCDebug(LOG_AW) << "Looking for key names in code" << _code << "using list" << _keys;
auto found = AWPatternFunctions::findFunctionCalls("aw_names", _code);
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_names", _code);
for (auto &function : found) {
auto separator = function.args.isEmpty() ? "," : function.args.at(0);
auto required = _keys.filter(QRegularExpression(function.body));
QString separator = function.args.isEmpty() ? "," : function.args.at(0);
QStringList required = _keys.filter(QRegExp(function.body));
_code.replace(function.what, required.join(separator));
}
@ -175,11 +175,11 @@ QString AWPatternFunctions::insertKeys(QString _code, const QStringList &_keys)
{
qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" << _keys;
auto found = AWPatternFunctions::findFunctionCalls("aw_keys", _code);
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_keys", _code);
for (auto &function : found) {
auto separator = function.args.isEmpty() ? "," : function.args.at(0);
auto required = _keys.filter(QRegularExpression(function.body));
std::for_each(required.begin(), required.end(), [](auto &value) { value = QString("$%1").arg(value); });
QString separator = function.args.isEmpty() ? "," : function.args.at(0);
QStringList required = _keys.filter(QRegExp(function.body));
std::for_each(required.begin(), required.end(), [](QString &value) { value = QString("$%1").arg(value); });
_code.replace(function.what, required.join(separator));
}
@ -192,25 +192,26 @@ QString AWPatternFunctions::insertMacros(QString _code)
{
qCDebug(LOG_AW) << "Looking for macros in code" << _code;
auto found = AWPatternFunctions::findFunctionCalls("aw_macro", _code);
QList<AWPatternFunctions::AWFunction> found = AWPatternFunctions::findFunctionCalls("aw_macro", _code);
for (auto &macro : found) {
// get macro params
if (macro.args.isEmpty()) {
qCWarning(LOG_AW) << "No macro name found for" << macro.what;
continue;
}
auto name = macro.args.takeFirst();
QString name = macro.args.takeFirst();
// find macro usage
auto macroUsage = AWPatternFunctions::findFunctionCalls(QString("aw_macro_%1").arg(name), _code);
QList<AWPatternFunctions::AWFunction> macroUsage
= AWPatternFunctions::findFunctionCalls(QString("aw_macro_%1").arg(name), _code);
for (auto &function : macroUsage) {
if (function.args.count() != macro.args.count()) {
qCWarning(LOG_AW) << "Invalid args count found for call" << function.what << "with macro" << macro.what;
continue;
}
// generate body to replace
auto result = macro.body;
std::for_each(macro.args.cbegin(), macro.args.cend(), [&result, macro, function](auto &arg) {
auto index = macro.args.indexOf(arg);
QString result = macro.body;
std::for_each(macro.args.cbegin(), macro.args.cend(), [&result, macro, function](const QString &arg) {
int index = macro.args.indexOf(arg);
result.replace(QString("$%1").arg(arg), function.args.at(index));
});
// do replace
@ -230,7 +231,7 @@ QStringList AWPatternFunctions::findKeys(const QString &_code, const QStringList
qCDebug(LOG_AW) << "Looking for keys in code" << _code << "using list" << _keys;
QStringList selectedKeys;
auto replacedCode = _code;
QString replacedCode = _code;
for (auto &key : _keys)
if ((key.startsWith("bar") == _isBars) && (replacedCode.contains(QString("$%1").arg(key)))) {
qCInfo(LOG_AW) << "Found key" << key << "with bar enabled" << _isBars;
@ -250,13 +251,13 @@ QStringList AWPatternFunctions::findLambdas(const QString &_code)
QStringList selectedKeys;
// match the following construction ${{some code here}}
static QRegularExpression lambdaRegexp(R"(\$\{\{(?<body>.*?)\}\})");
QRegularExpression lambdaRegexp(R"(\$\{\{(?<body>.*?)\}\})");
lambdaRegexp.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
auto it = lambdaRegexp.globalMatch(_code);
QRegularExpressionMatchIterator it = lambdaRegexp.globalMatch(_code);
while (it.hasNext()) {
auto match = it.next();
auto lambda = match.captured("body");
QRegularExpressionMatch match = it.next();
QString lambda = match.captured("body");
// append
qCInfo(LOG_AW) << "Found lambda" << lambda;

View File

@ -15,7 +15,9 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWPATTERNFUNCTIONS_H
#define AWPATTERNFUNCTIONS_H
#include <QString>
#include <QVariant>
@ -45,3 +47,6 @@ QString insertMacros(QString _code);
QStringList findKeys(const QString &_code, const QStringList &_keys, bool _isBars);
QStringList findLambdas(const QString &_code);
} // namespace AWPatternFunctions
#endif /* AWPATTERNFUNCTIONS_H */

View File

@ -18,6 +18,8 @@
#include "awtelemetryhandler.h"
#include <QJsonDocument>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSettings>
#include <QStandardPaths>
#include <QUuid>
@ -25,13 +27,23 @@
#include "awdebug.h"
AWTelemetryHandler::AWTelemetryHandler(QObject *_parent)
AWTelemetryHandler::AWTelemetryHandler(QObject *_parent, const QString &_clientId)
: QObject(_parent)
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
m_localFile = QString("%1/awesomewidgets/telemetry.ini")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
// override client id if any
if (!_clientId.isEmpty())
m_clientId = _clientId;
}
AWTelemetryHandler::~AWTelemetryHandler()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
@ -59,11 +71,14 @@ QString AWTelemetryHandler::getLast(const QString &_group) const
}
void AWTelemetryHandler::init(const int _count)
void AWTelemetryHandler::init(const int _count, const bool _enableRemote, const QString &_clientId)
{
qCDebug(LOG_AW) << "Init telemetry with count" << _count;
qCDebug(LOG_AW) << "Init telemetry with count" << _count << "enable remote" << _enableRemote << "client ID"
<< _clientId;
m_storeCount = _count;
m_uploadEnabled = _enableRemote;
m_clientId = _clientId;
}
@ -91,7 +106,7 @@ bool AWTelemetryHandler::put(const QString &_group, const QString &_value) const
settings.remove("");
// and save now
for (auto &val : saved) {
auto key = getKey(settings.childKeys().count());
QString key = getKey(settings.childKeys().count());
settings.setValue(key, val);
}
@ -103,6 +118,59 @@ bool AWTelemetryHandler::put(const QString &_group, const QString &_value) const
}
void AWTelemetryHandler::uploadTelemetry(const QString &_group, const QString &_value)
{
qCDebug(LOG_AW) << "Upload data with group" << _group << "and value" << _value;
if (!m_uploadEnabled) {
qCInfo(LOG_AW) << "Upload disabled by configuration";
return;
}
auto *manager = new QNetworkAccessManager(nullptr);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(telemetryReplyRecieved(QNetworkReply *)));
QUrl url(REMOTE_TELEMETRY_URL);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
// generate payload
QVariantMap payload;
payload["api"] = AW_TELEMETRY_API;
payload["client_id"] = m_clientId;
payload["metadata"] = _value;
payload["type"] = _group;
// convert to QByteArray to send request
QByteArray data = QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact);
qCInfo(LOG_AW) << "Send request with body" << data.data() << "and size" << data.size();
manager->post(request, data);
}
void AWTelemetryHandler::telemetryReplyRecieved(QNetworkReply *_reply)
{
if (_reply->error() != QNetworkReply::NoError) {
qCWarning(LOG_AW) << "An error occurs" << _reply->error() << "with message" << _reply->errorString();
return;
}
QJsonParseError error{};
QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_AW) << "Parse error" << error.errorString();
return;
}
_reply->deleteLater();
// convert to map
QVariantMap response = jsonDoc.toVariant().toMap();
QString message = response["message"].toString();
qCInfo(LOG_AW) << "Server reply on telemetry" << message;
return emit(replyReceived(message));
}
QString AWTelemetryHandler::getKey(const int _count)
{
qCDebug(LOG_AW) << "Get key for keys count" << _count;

View File

@ -15,25 +15,43 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWTELEMETRYHANDLER_H
#define AWTELEMETRYHANDLER_H
#include <QObject>
class QNetworkReply;
class AWTelemetryHandler : public QObject
{
Q_OBJECT
public:
explicit AWTelemetryHandler(QObject *_parent = nullptr);
~AWTelemetryHandler() override = default;
const char *REMOTE_TELEMETRY_URL = "https://arcanis.me/telemetry";
explicit AWTelemetryHandler(QObject *_parent = nullptr, const QString &_clientId = "");
~AWTelemetryHandler() override;
Q_INVOKABLE [[nodiscard]] QStringList get(const QString &_group) const;
Q_INVOKABLE [[nodiscard]] QString getLast(const QString &_group) const;
Q_INVOKABLE void init(int _count);
Q_INVOKABLE void init(int _count, bool _enableRemote, const QString &_clientId);
Q_INVOKABLE [[nodiscard]] bool put(const QString &_group, const QString &_value) const;
Q_INVOKABLE void uploadTelemetry(const QString &_group, const QString &_value);
signals:
void replyReceived(const QString &_message);
private slots:
void telemetryReplyRecieved(QNetworkReply *_reply);
private:
static QString getKey(int _count);
QString m_clientId;
QString m_localFile;
int m_storeCount = 0;
bool m_uploadEnabled = false;
};
#endif /* AWTELEMETRYHANDLER_H */

View File

@ -18,14 +18,12 @@
#include "awupdatehelper.h"
#include <KI18n/KLocalizedString>
#include <KNotifications/KNotification>
#include <QDesktopServices>
#include <QJsonDocument>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSettings>
#include <QStandardPaths>
#include "awdebug.h"
@ -41,15 +39,21 @@ AWUpdateHelper::AWUpdateHelper(QObject *_parent)
}
AWUpdateHelper::~AWUpdateHelper()
{
qCDebug(LOG_AW) << __PRETTY_FUNCTION__;
}
void AWUpdateHelper::checkUpdates(const bool _showAnyway)
{
qCDebug(LOG_AW) << "Show anyway" << _showAnyway;
// showAnyway options required 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
auto manager = new QNetworkAccessManager(nullptr);
auto *manager = new QNetworkAccessManager(nullptr);
connect(manager, &QNetworkAccessManager::finished,
[_showAnyway, this](QNetworkReply *reply) { return versionReplyReceived(reply, _showAnyway); });
[_showAnyway, this](QNetworkReply *reply) { return versionReplyRecieved(reply, _showAnyway); });
manager->get(QNetworkRequest(QUrl(VERSION_API)));
}
@ -58,14 +62,15 @@ void AWUpdateHelper::checkUpdates(const bool _showAnyway)
bool AWUpdateHelper::checkVersion()
{
QSettings settings(m_genericConfig, QSettings::IniFormat);
auto version = QVersionNumber::fromString(settings.value("Version", QString(VERSION)).toString());
QVersionNumber version = QVersionNumber::fromString(settings.value("Version", QString(VERSION)).toString());
// update version
settings.setValue("Version", QString(VERSION));
settings.sync();
qCInfo(LOG_AW) << "Found version" << version << "actual one is" << m_foundVersion;
if ((version != m_foundVersion) && (!QString(CHANGELOG).isEmpty())) {
sendNotification(i18n("Changelog of %1", VERSION), QString(CHANGELOG).replace('@', '\n'));
genMessageBox(i18nc("Changelog of %1", VERSION), QString(CHANGELOG).replace('@', '\n'), QMessageBox::Ok)
->open();
return true;
} else if (version != m_foundVersion) {
qCWarning(LOG_AW) << "No changelog information provided";
@ -78,40 +83,49 @@ bool AWUpdateHelper::checkVersion()
}
void AWUpdateHelper::openReleasesPage()
{
QDesktopServices::openUrl(QString(RELEASES) + m_foundVersion.toString());
}
void AWUpdateHelper::showInfo(const QVersionNumber &_version)
{
qCDebug(LOG_AW) << "Version" << _version;
auto text = i18n("You are using the actual version %1", _version.toString());
QString text = i18n("You are using the actual version %1", _version.toString());
if (!QString(COMMIT_SHA).isEmpty())
text += QString(" (%1)").arg(QString(COMMIT_SHA));
sendNotification(i18n("No new version found"), text);
return genMessageBox(i18n("No new version found"), text, QMessageBox::Ok)->open();
}
void AWUpdateHelper::showUpdates(const QVersionNumber &_version) const
void AWUpdateHelper::showUpdates(const QVersionNumber &_version)
{
qCDebug(LOG_AW) << "Version" << _version;
QString text;
text += i18n("Current version : %1", VERSION);
text += i18nc("Current version : %1", 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("Click \"Ok\" to download");
auto event = sendNotification(i18n("There are updates"), text);
auto action = event->addAction(i18n("Details"));
connect(action, &KNotificationAction::activated, this, &AWUpdateHelper::openReleasesPage);
genMessageBox(i18n("There are updates"), text, QMessageBox::Ok | QMessageBox::Cancel)
->open(this, SLOT(userReplyOnUpdates(QAbstractButton *)));
}
void AWUpdateHelper::versionReplyReceived(QNetworkReply *_reply, const bool _showAnyway)
void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *_button)
{
QMessageBox::ButtonRole ret = dynamic_cast<QMessageBox *>(sender())->buttonRole(_button);
qCInfo(LOG_AW) << "User select" << ret;
switch (ret) {
case QMessageBox::AcceptRole:
QDesktopServices::openUrl(QString(RELEASES) + m_foundVersion.toString());
break;
case QMessageBox::RejectRole:
default:
break;
}
}
void AWUpdateHelper::versionReplyRecieved(QNetworkReply *_reply, const bool _showAnyway)
{
qCDebug(LOG_AW) << "Show message anyway" << _showAnyway;
if (_reply->error() != QNetworkReply::NoError) {
@ -119,23 +133,22 @@ void AWUpdateHelper::versionReplyReceived(QNetworkReply *_reply, const bool _sho
return;
}
auto error = QJsonParseError();
auto jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
QJsonParseError error = QJsonParseError();
QJsonDocument jsonDoc = QJsonDocument::fromJson(_reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(LOG_AW) << "Parse error" << error.errorString();
return;
}
_reply->deleteLater();
_reply->manager()->deleteLater(); // remember to delete manager too
// convert to map
auto firstRelease = jsonDoc.toVariant().toList().first().toMap();
auto version = firstRelease["tag_name"].toString();
QVariantMap firstRelease = jsonDoc.toVariant().toList().first().toMap();
QString version = firstRelease["tag_name"].toString();
version.remove("V.");
m_foundVersion = QVersionNumber::fromString(version);
qCInfo(LOG_AW) << "Update found version to" << m_foundVersion;
auto oldVersion = QVersionNumber::fromString(VERSION);
QVersionNumber oldVersion = QVersionNumber::fromString(VERSION);
if (oldVersion < m_foundVersion)
return showUpdates(m_foundVersion);
else if (_showAnyway)
@ -144,12 +157,18 @@ void AWUpdateHelper::versionReplyReceived(QNetworkReply *_reply, const bool _sho
// additional method which is used to show message box which does not block UI
KNotification *AWUpdateHelper::sendNotification(const QString &_title, const QString &_body)
QMessageBox *AWUpdateHelper::genMessageBox(const QString &_title, const QString &_body,
const QMessageBox::StandardButtons _buttons)
{
qCDebug(LOG_AW) << "Construct message box with title" << _title << "and body" << _body;
auto event = KNotification::event("system", _title, _body);
event->setComponentName("plasma-applet-org.kde.plasma.awesome-widget");
auto *msgBox = new QMessageBox(nullptr);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setModal(false);
msgBox->setWindowTitle(_title);
msgBox->setText(_body);
msgBox->setStandardButtons(_buttons);
msgBox->setIcon(QMessageBox::Information);
return event;
return msgBox;
}

View File

@ -15,13 +15,15 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWUPDATEHELPER_H
#define AWUPDATEHELPER_H
#include <QMessageBox>
#include <QObject>
#include <QVersionNumber>
class KNotification;
class QNetworkReply;
class AWUpdateHelper : public QObject
@ -30,18 +32,22 @@ class AWUpdateHelper : public QObject
public:
explicit AWUpdateHelper(QObject *_parent = nullptr);
~AWUpdateHelper() override = default;
~AWUpdateHelper() override;
void checkUpdates(bool _showAnyway = false);
bool checkVersion();
private slots:
void openReleasesPage();
static void showInfo(const QVersionNumber &_version);
void showUpdates(const QVersionNumber &_version) const;
void versionReplyReceived(QNetworkReply *_reply, bool _showAnyway);
void showUpdates(const QVersionNumber &_version);
void userReplyOnUpdates(QAbstractButton *_button);
void versionReplyRecieved(QNetworkReply *_reply, bool _showAnyway);
private:
static KNotification *sendNotification(const QString &_title, const QString &_body);
static QMessageBox *genMessageBox(const QString &_title, const QString &_body,
QMessageBox::StandardButtons _buttons);
QVersionNumber m_foundVersion;
QString m_genericConfig;
};
#endif /* AWUPDATEHELPER_H */

View File

@ -7,7 +7,7 @@ include_directories(
${CMAKE_BINARY_DIR}
${PROJECT_TRDPARTY_DIR}
${Qt_INCLUDE}
${Kf6_INCLUDE}
${Kf5_INCLUDE}
)
file(GLOB SUBPROJECT_SOURCE *.cpp ${PROJECT_TRDPARTY_DIR}/qreplytimeout/*.cpp ${CMAKE_SOURCE_DIR}/*.cpp)
@ -28,18 +28,18 @@ file(RELATIVE_PATH SUBPROJECT_WEATHER_JSON ${CMAKE_SOURCE_DIR} ${SUBPROJECT_WEAT
# prepare
configure_file(${SUBPROJECT_WEATHER_JSON_IN} ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON})
qt6_wrap_ui(SUBPROJECT_UI_HEADER ${SUBPROJECT_UI})
qt5_wrap_ui(SUBPROJECT_UI_HEADER ${SUBPROJECT_UI})
add_library(${SUBPROJECT} STATIC ${SUBPROJECT_SOURCE} ${SUBPROJECT_HEADER} ${SUBPROJECT_UI_HEADER})
target_link_libraries(${SUBPROJECT} ${Qt_LIBRARIES} ${Kf6_LIBRARIES})
target_link_libraries(${SUBPROJECT} ${Qt_LIBRARIES} ${Kf5_LIBRARIES})
# install
install(DIRECTORY ${SUBPROJECT_CONFIGS} DESTINATION ${KDE_INSTALL_DATADIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_FORMATTERS} DESTINATION ${KDE_INSTALL_DATADIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_GRAPHITEMS} DESTINATION ${KDE_INSTALL_DATADIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_QUOTES} DESTINATION ${KDE_INSTALL_DATADIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_SCRIPTS} DESTINATION ${KDE_INSTALL_DATADIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_REQUESTS} DESTINATION ${KDE_INSTALL_DATADIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_UPGRADE} DESTINATION ${KDE_INSTALL_DATADIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_WEATHER} DESTINATION ${KDE_INSTALL_DATADIR}/${PROJECT_NAME})
install(FILES ${SUBPROJECT_INI} DESTINATION /${KDE_INSTALL_CONFDIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON} DESTINATION ${KDE_INSTALL_DATADIR}/${PROJECT_NAME}/weather)
install(DIRECTORY ${SUBPROJECT_CONFIGS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_FORMATTERS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_GRAPHITEMS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_QUOTES} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_SCRIPTS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_REQUESTS} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_UPGRADE} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(DIRECTORY ${SUBPROJECT_WEATHER} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME})
install(FILES ${SUBPROJECT_INI} DESTINATION ${CONFIG_INSTALL_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_WEATHER_JSON} DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/weather)

View File

@ -27,21 +27,15 @@
#include "qcronscheduler.h"
AbstractExtItem::AbstractExtItem(QObject *_parent, const QString &_filePath)
: QObject(_parent)
, m_filePath(_filePath)
AbstractExtItem::AbstractExtItem(QWidget *_parent, const QString &_filePath)
: QDialog(_parent)
, m_fileName(_filePath)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
qCDebug(LOG_LIB) << "Desktop name" << _filePath;
m_name = m_filePath;
m_scheduler = new QCronScheduler(this);
connect(m_scheduler, &QCronScheduler::activated, this, &AbstractExtItem::requestDataUpdate);
m_socket = new QLocalServer(this);
connect(m_socket, &QLocalServer::newConnection, this, &AbstractExtItem::requestDataUpdate);
m_name = m_fileName;
}
@ -49,11 +43,11 @@ AbstractExtItem::~AbstractExtItem()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
m_scheduler->stop();
m_scheduler->deleteLater();
m_socket->close();
m_socket->deleteLater();
if (m_socket) {
m_socket->close();
QLocalServer::removeServer(socket());
m_socket->deleteLater();
}
}
@ -101,16 +95,17 @@ void AbstractExtItem::startTimer()
}
QString AbstractExtItem::writableConfig() const
QString AbstractExtItem::writtableConfig() const
{
auto path = m_filePath;
auto name = fileName();
// extract subdirectory
path.remove(path.length() - name.length() - 1, name.length() + 1);
auto dir = QFileInfo(path).fileName();
QString path = m_fileName;
QString name = QFileInfo(path).fileName();
path.remove(path.count() - name.count() - 1, name.count() + 1);
QString dir = QFileInfo(path).fileName();
return QString("%1/awesomewidgets/%2/%3")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), dir, name);
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation))
.arg(dir)
.arg(name);
}
@ -134,13 +129,7 @@ QString AbstractExtItem::cron() const
QString AbstractExtItem::fileName() const
{
return QFileInfo(filePath()).fileName();
}
QString AbstractExtItem::filePath() const
{
return m_filePath;
return m_fileName;
}
@ -209,14 +198,20 @@ void AbstractExtItem::setComment(const QString &_comment)
void AbstractExtItem::setCron(const QString &_cron)
{
qCDebug(LOG_LIB) << "Cron string" << _cron;
// deinit module first
if (m_scheduler) {
disconnect(m_scheduler, SIGNAL(activated()), this, SIGNAL(requestDataUpdate()));
delete m_scheduler;
}
m_cron = _cron;
if (m_cron.isEmpty()) { // disable cron timer
m_scheduler->stop();
} else {
m_scheduler->parse(m_cron);
m_scheduler->start();
}
if (cron().isEmpty())
return;
// init scheduler
m_scheduler = new QCronScheduler(this);
m_scheduler->parse(cron());
connect(m_scheduler, SIGNAL(activated()), this, SIGNAL(requestDataUpdate()));
}
@ -241,11 +236,11 @@ void AbstractExtItem::setName(const QString &_name)
void AbstractExtItem::setNumber(int _number)
{
qCDebug(LOG_LIB) << "Number" << _number;
auto generateNumber = (_number == -1);
bool generateNumber = (_number == -1);
if (generateNumber) {
_number = []() {
qCWarning(LOG_LIB) << "Number is empty, generate new one";
auto n = QRandomGenerator::global()->bounded(1000);
auto n = QRandomGenerator::global()->generate() % 1000;
qCInfo(LOG_LIB) << "Generated number is" << n;
return n;
}();
@ -260,24 +255,40 @@ void AbstractExtItem::setNumber(int _number)
void AbstractExtItem::setSocket(const QString &_socket)
{
qCDebug(LOG_LIB) << "Socket" << _socket;
// remove old socket first
deinitSocket();
m_socketFile = _socket;
}
void AbstractExtItem::deinitSocket()
{
if (!m_socket)
return;
m_socket->close();
QLocalServer::removeServer(socket());
delete m_socket;
disconnect(m_socket, SIGNAL(newConnection()), this, SLOT(newConnectionReceived()));
}
void AbstractExtItem::initSocket()
{
// reload local socket
m_socket->close();
// remove old socket first
deinitSocket();
auto listening = m_socket->listen(m_socketFile);
qCInfo(LOG_LIB) << "Server listening on" << m_socketFile << listening;
m_socket = new QLocalServer(this);
bool listening = m_socket->listen(socket());
qCInfo(LOG_LIB) << "Server listening on" << socket() << listening;
connect(m_socket, SIGNAL(newConnection()), this, SLOT(newConnectionReceived()));
}
void AbstractExtItem::readConfiguration()
{
QSettings settings(m_filePath, QSettings::IniFormat);
QSettings settings(m_fileName, QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
setName(settings.value("Name", name()).toString());
@ -294,8 +305,8 @@ void AbstractExtItem::readConfiguration()
bool AbstractExtItem::tryDelete() const
{
auto status = QFile::remove(m_filePath);
qCInfo(LOG_LIB) << "Remove file" << m_filePath << status;
bool status = QFile::remove(m_fileName);
qCInfo(LOG_LIB) << "Remove file" << m_fileName << status;
return status;
}
@ -303,7 +314,7 @@ bool AbstractExtItem::tryDelete() const
void AbstractExtItem::writeConfiguration() const
{
QSettings settings(writableConfig(), QSettings::IniFormat);
QSettings settings(writtableConfig(), QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup("Desktop Entry");
@ -320,3 +331,9 @@ void AbstractExtItem::writeConfiguration() const
settings.sync();
}
void AbstractExtItem::newConnectionReceived()
{
emit(requestDataUpdate());
}

View File

@ -15,16 +15,17 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef ABSTRACTEXTITEM_H
#define ABSTRACTEXTITEM_H
#include <QDialog>
#include <QVariant>
class QCronScheduler;
class QLocalServer;
class QWidget;
class AbstractExtItem : public QObject
class AbstractExtItem : public QDialog
{
Q_OBJECT
Q_PROPERTY(bool active READ isActive WRITE setActive)
@ -32,7 +33,6 @@ class AbstractExtItem : public QObject
Q_PROPERTY(QString comment READ comment WRITE setComment)
Q_PROPERTY(QString cron READ cron WRITE setCron)
Q_PROPERTY(QString fileName READ fileName)
Q_PROPERTY(QString filePath READ filePath)
Q_PROPERTY(int interval READ interval WRITE setInterval)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int number READ number WRITE setNumber)
@ -40,19 +40,18 @@ class AbstractExtItem : public QObject
Q_PROPERTY(QString uniq READ uniq)
public:
explicit AbstractExtItem(QObject *_parent = nullptr, const QString &_filePath = "");
explicit AbstractExtItem(QWidget *_parent = nullptr, const QString &_filePath = "");
~AbstractExtItem() override;
virtual void bumpApi(int _newVer);
virtual AbstractExtItem *copy(const QString &_fileName, int _number) = 0;
virtual void copyDefaults(AbstractExtItem *_other) const;
virtual void startTimer();
[[nodiscard]] QString writableConfig() const;
[[nodiscard]] QString writtableConfig() const;
// get methods
[[nodiscard]] int apiVersion() const;
[[nodiscard]] QString comment() const;
[[nodiscard]] QString cron() const;
[[nodiscard]] QString fileName() const;
[[nodiscard]] QString filePath() const;
[[nodiscard]] int interval() const;
[[nodiscard]] bool isActive() const;
[[nodiscard]] QString name() const;
@ -75,19 +74,22 @@ signals:
void requestDataUpdate();
public slots:
virtual void deinitSocket();
virtual void initSocket();
virtual void readConfiguration();
virtual QVariantHash run() = 0;
virtual int showConfiguration(QWidget *_parent, const QVariant &_args) = 0;
virtual int showConfiguration(const QVariant &_args) = 0;
[[nodiscard]] virtual bool tryDelete() const;
virtual void writeConfiguration() const;
private slots:
void newConnectionReceived();
private:
QCronScheduler *m_scheduler = nullptr;
QString m_filePath = "";
QString m_fileName = "/dev/null";
int m_times = 0;
// FIXME find a better way to do it
virtual void translate(void *_ui) = 0;
virtual void translate() = 0;
// properties
int m_apiVersion = 0;
bool m_active = true;
@ -99,3 +101,6 @@ private:
QLocalServer *m_socket = nullptr;
QString m_socketFile = "";
};
#endif /* ABSTRACTEXTITEM_H */

View File

@ -26,44 +26,65 @@
#include <utility>
AbstractExtItemAggregator::AbstractExtItemAggregator(QObject *_parent, QString _type)
: QObject(_parent)
AbstractExtItemAggregator::AbstractExtItemAggregator(QWidget *_parent, QString _type)
: QDialog(_parent)
, ui(new Ui::AbstractExtItemAggregator)
, m_type(std::move(_type))
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
// create directory at $HOME
auto localDir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), type());
if (QDir().mkpath(localDir))
QString localDir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation))
.arg(type());
QDir localDirectory;
if (localDirectory.mkpath(localDir))
qCInfo(LOG_LIB) << "Created directory" << localDir;
ui->setupUi(this);
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->listWidget, SIGNAL(itemActivated(QListWidgetItem *)), this, SLOT(editItemActivated(QListWidgetItem *)));
}
void AbstractExtItemAggregator::copyItem(QListWidget *_widget)
AbstractExtItemAggregator::~AbstractExtItemAggregator()
{
auto source = itemFromWidget(_widget);
auto fileName = getName();
auto number = uniqNumber();
auto dir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), m_type);
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete ui;
}
void AbstractExtItemAggregator::copyItem()
{
AbstractExtItem *source = itemFromWidget();
QString fileName = getName();
int number = uniqNumber();
QString dir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation))
.arg(m_type);
if ((!source) || (fileName.isEmpty())) {
qCWarning(LOG_LIB) << "Nothing to copy";
return;
}
auto filePath = QString("%1/%2").arg(dir, fileName);
QString filePath = QString("%1/%2").arg(dir).arg(fileName);
auto newItem = source->copy(filePath, number);
if (newItem->showConfiguration(nullptr, configArgs()) == 1) {
AbstractExtItem *newItem = source->copy(filePath, number);
if (newItem->showConfiguration(configArgs()) == 1) {
initItems();
repaintList(_widget);
repaintList();
}
}
void AbstractExtItemAggregator::deleteItem(QListWidget *_widget)
void AbstractExtItemAggregator::deleteItem()
{
auto source = itemFromWidget(_widget);
AbstractExtItem *source = itemFromWidget();
if (!source) {
qCWarning(LOG_LIB) << "Nothing to delete";
return;
@ -71,58 +92,30 @@ void AbstractExtItemAggregator::deleteItem(QListWidget *_widget)
if (source->tryDelete()) {
initItems();
repaintList(_widget);
repaintList();
}
}
void AbstractExtItemAggregator::editItem(QListWidget *_widget)
void AbstractExtItemAggregator::editItem()
{
auto source = itemFromWidget(_widget);
AbstractExtItem *source = itemFromWidget();
if (!source) {
qCWarning(LOG_LIB) << "Nothing to edit";
return;
}
if (source->showConfiguration(nullptr, configArgs()) == 1) {
if (source->showConfiguration(configArgs()) == 1) {
initItems();
repaintList(_widget);
repaintList();
}
}
int AbstractExtItemAggregator::exec()
{
auto dialog = new QDialog();
auto ui = new Ui::AbstractExtItemAggregator();
ui->setupUi(dialog);
auto copyButton = ui->buttonBox->addButton(i18n("Copy"), QDialogButtonBox::ActionRole);
auto createButton = ui->buttonBox->addButton(i18n("Create"), QDialogButtonBox::ActionRole);
auto deleteButton = ui->buttonBox->addButton(i18n("Remove"), QDialogButtonBox::ActionRole);
connect(copyButton, &QPushButton::clicked, [this, ui]() { copyItem(ui->listWidget); });
connect(createButton, &QPushButton::clicked, [this, ui]() { doCreateItem(ui->listWidget); });
connect(deleteButton, &QPushButton::clicked, [this, ui]() { deleteItem(ui->listWidget); });
connect(ui->buttonBox, &QDialogButtonBox::accepted, [this, ui]() { editItem(ui->listWidget); });
connect(ui->buttonBox, &QDialogButtonBox::rejected, [dialog]() { dialog->reject(); });
connect(ui->listWidget, &QListWidget::itemActivated, [this, ui](QListWidgetItem *) { editItem(ui->listWidget); });
repaintList(ui->listWidget);
auto ret = dialog->exec();
dialog->deleteLater();
delete ui;
return ret;
}
QString AbstractExtItemAggregator::getName()
{
bool ok;
auto name = QInputDialog::getText(nullptr, i18n("Enter file name"), i18n("File name"), QLineEdit::Normal, "", &ok);
QString name = QInputDialog::getText(this, i18n("Enter file name"), i18n("File name"), QLineEdit::Normal, "", &ok);
if ((!ok) || (name.isEmpty()))
return "";
if (!name.endsWith(".desktop"))
@ -132,15 +125,15 @@ QString AbstractExtItemAggregator::getName()
}
AbstractExtItem *AbstractExtItemAggregator::itemFromWidget(QListWidget *_widget) const
AbstractExtItem *AbstractExtItemAggregator::itemFromWidget() const
{
auto widgetItem = _widget->currentItem();
QListWidgetItem *widgetItem = ui->listWidget->currentItem();
if (!widgetItem)
return nullptr;
AbstractExtItem *found = nullptr;
for (auto item : items()) {
auto fileName = item->fileName();
for (auto &item : items()) {
QString fileName = QFileInfo(item->fileName()).fileName();
if (fileName != widgetItem->text())
continue;
found = item;
@ -153,18 +146,18 @@ AbstractExtItem *AbstractExtItemAggregator::itemFromWidget(QListWidget *_widget)
}
void AbstractExtItemAggregator::repaintList(QListWidget *_widget) const
void AbstractExtItemAggregator::repaintList() const
{
_widget->clear();
for (auto _item : items()) {
QString fileName = _item->fileName();
auto item = new QListWidgetItem(fileName, _widget);
ui->listWidget->clear();
for (auto &_item : items()) {
QString fileName = QFileInfo(_item->fileName()).fileName();
auto *item = new QListWidgetItem(fileName, ui->listWidget);
QStringList tooltip;
tooltip.append(i18n("Name: %1", _item->name()));
tooltip.append(i18n("Comment: %1", _item->comment()));
tooltip.append(i18n("Identity: %1", _item->uniq()));
item->setToolTip(tooltip.join('\n'));
_widget->addItem(item);
ui->listWidget->addItem(item);
}
}
@ -172,10 +165,9 @@ void AbstractExtItemAggregator::repaintList(QListWidget *_widget) const
int AbstractExtItemAggregator::uniqNumber() const
{
QList<int> tagList;
for (auto item : items())
for (auto &item : items())
tagList.append(item->number());
auto number = 0;
int number = 0;
while (tagList.contains(number))
number++;
@ -191,8 +183,10 @@ QVariant AbstractExtItemAggregator::configArgs() const
QStringList AbstractExtItemAggregator::directories() const
{
return QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString("awesomewidgets/%1").arg(type()),
QStandardPaths::LocateDirectory);
auto dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString("awesomewidgets/%1").arg(type()),
QStandardPaths::LocateDirectory);
return dirs;
}
@ -208,3 +202,22 @@ void AbstractExtItemAggregator::setConfigArgs(const QVariant &_configArgs)
m_configArgs = _configArgs;
}
void AbstractExtItemAggregator::editItemActivated(QListWidgetItem *)
{
return editItem();
}
void AbstractExtItemAggregator::editItemButtonPressed(QAbstractButton *_button)
{
if (dynamic_cast<QPushButton *>(_button) == copyButton)
return copyItem();
else if (dynamic_cast<QPushButton *>(_button) == createButton)
return doCreateItem();
else if (dynamic_cast<QPushButton *>(_button) == deleteButton)
return deleteItem();
else if (ui->buttonBox->buttonRole(_button) == QDialogButtonBox::AcceptRole)
return editItem();
}

View File

@ -15,53 +15,60 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef ABSTRACTEXTITEMAGGREGATOR_H
#define ABSTRACTEXTITEMAGGREGATOR_H
#include <QDialog>
#include <QStandardPaths>
#include "abstractextitem.h"
#include "awdebug.h"
class QListWidget;
class QAbstractButton;
class QListWidgetItem;
namespace Ui
{
class AbstractExtItemAggregator;
}
class AbstractExtItemAggregator : public QObject
class AbstractExtItemAggregator : public QDialog
{
Q_OBJECT
Q_PROPERTY(QVariant configArgs READ configArgs WRITE setConfigArgs)
Q_PROPERTY(QVariant type READ type)
public:
explicit AbstractExtItemAggregator(QObject *_parent, QString _type);
explicit AbstractExtItemAggregator(QWidget *_parent, QString _type);
~AbstractExtItemAggregator() override;
// methods
void copyItem(QListWidget *_widget);
template <class T> void createItem(QListWidget *_widget)
void copyItem();
template <class T> void createItem()
{
auto fileName = getName();
auto number = uniqNumber();
auto dir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation), m_type);
QString fileName = getName();
int number = uniqNumber();
QString dir = QString("%1/awesomewidgets/%2")
.arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation))
.arg(m_type);
if (fileName.isEmpty()) {
qCWarning(LOG_LIB) << "Nothing to create";
return;
}
auto filePath = QString("%1/%2").arg(dir, fileName);
QString filePath = QString("%1/%2").arg(dir).arg(fileName);
auto newItem = new T(this, filePath);
T *newItem = new T(this, filePath);
newItem->setNumber(number);
if (newItem->showConfiguration(nullptr, configArgs()) == 1) {
if (newItem->showConfiguration(configArgs()) == 1) {
initItems();
repaintList(_widget);
repaintList();
}
};
void deleteItem(QListWidget *_widget);
void editItem(QListWidget *_widget);
[[nodiscard]] int exec();
[[nodiscard]] static QString getName();
void deleteItem();
void editItem();
QString getName();
virtual void initItems() = 0;
[[nodiscard]] AbstractExtItem *itemFromWidget(QListWidget *_widget) const;
void repaintList(QListWidget *_widget) const;
[[nodiscard]] AbstractExtItem *itemFromWidget() const;
void repaintList() const;
[[nodiscard]] int uniqNumber() const;
// get methods
[[nodiscard]] QVariant configArgs() const;
@ -71,10 +78,22 @@ public:
// set methods
void setConfigArgs(const QVariant &_configArgs);
private slots:
void editItemActivated(QListWidgetItem *);
void editItemButtonPressed(QAbstractButton *_button);
private:
// ui
Ui::AbstractExtItemAggregator *ui = nullptr;
QPushButton *copyButton = nullptr;
QPushButton *createButton = nullptr;
QPushButton *deleteButton = nullptr;
// properties
QVariant m_configArgs;
QString m_type;
// ui methods
virtual void doCreateItem(QListWidget *_widget) = 0;
virtual void doCreateItem() = 0;
};
#endif /* ABSTRACTEXTITEMAGGREGATOR_H */

View File

@ -15,17 +15,31 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef ABSTRACTQUOTESPROVIDER_H
#define ABSTRACTQUOTESPROVIDER_H
#include <QObject>
#include <QUrl>
#include <QVariant>
#include "abstractextitem.h"
class AbstractQuotesProvider
class AbstractQuotesProvider : public QObject
{
Q_OBJECT
public:
virtual ~AbstractQuotesProvider() = default;
explicit AbstractQuotesProvider(QObject *_parent)
: QObject(_parent){};
~AbstractQuotesProvider() override = default;
virtual void initUrl(const QString &_asset) = 0;
[[nodiscard]] virtual QVariantHash parse(const QByteArray &_source) = 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

@ -15,17 +15,31 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef ABSTRACTWEATHERPROVIDER_H
#define ABSTRACTWEATHERPROVIDER_H
#include <QObject>
#include <QUrl>
#include <QVariant>
#include "abstractextitem.h"
class AbstractWeatherProvider
class AbstractWeatherProvider : public QObject
{
Q_OBJECT
public:
virtual ~AbstractWeatherProvider() = default;
explicit AbstractWeatherProvider(QObject *_parent)
: QObject(_parent){};
~AbstractWeatherProvider() override = default;
virtual void initUrl(const QString &_city, const QString &_country, int _ts) = 0;
[[nodiscard]] virtual QVariantHash parse(const QVariantMap &_json) const = 0;
[[nodiscard]] QString tag(const QString &_type) const
{
return dynamic_cast<AbstractExtItem *>(parent())->tag(_type);
};
[[nodiscard]] virtual QUrl url() const = 0;
};
#endif /* ABSTRACTWEATHERPROVIDER_H */

View File

@ -22,13 +22,19 @@
#include "awdebug.h"
AWAbstractFormatter::AWAbstractFormatter(QObject *_parent, const QString &_filePath)
AWAbstractFormatter::AWAbstractFormatter(QWidget *_parent, const QString &_filePath)
: AbstractExtItem(_parent, _filePath)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
}
AWAbstractFormatter::~AWAbstractFormatter()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
}
void AWAbstractFormatter::copyDefaults(AbstractExtItem *_other) const
{
AbstractExtItem::copyDefaults(_other);
@ -39,7 +45,7 @@ void AWAbstractFormatter::copyDefaults(AbstractExtItem *_other) const
QString AWAbstractFormatter::uniq() const
{
return QString("%1(%2)").arg(name(), strType());
return QString("%1(%2)").arg(name()).arg(strType());
}
@ -113,7 +119,7 @@ void AWAbstractFormatter::readConfiguration()
{
AbstractExtItem::readConfiguration();
QSettings settings(filePath(), QSettings::IniFormat);
QSettings settings(fileName(), QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
setStrType(settings.value("X-AW-Type", strType()).toString());
@ -125,7 +131,7 @@ void AWAbstractFormatter::writeConfiguration() const
{
AbstractExtItem::writeConfiguration();
QSettings settings(writableConfig(), QSettings::IniFormat);
QSettings settings(writtableConfig(), QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup("Desktop Entry");

View File

@ -15,9 +15,8 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#include <QRegularExpression>
#ifndef AWABSTRACTFORMATTER_H
#define AWABSTRACTFORMATTER_H
#include "abstractextitem.h"
@ -31,8 +30,8 @@ class AWAbstractFormatter : public AbstractExtItem
public:
enum class FormatterClass { DateTime, Float, List, Script, String, NoFormat, Json };
explicit AWAbstractFormatter(QObject *_parent = nullptr, const QString &_filePath = "");
~AWAbstractFormatter() override = default;
explicit AWAbstractFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
~AWAbstractFormatter() override;
[[nodiscard]] virtual QString convert(const QVariant &_value) const = 0;
void copyDefaults(AbstractExtItem *_other) const override;
[[nodiscard]] QString uniq() const override;
@ -51,3 +50,6 @@ private:
// properties
FormatterClass m_type = FormatterClass::NoFormat;
};
#endif /* AWABSTRACTFORMATTER_H */

View File

@ -15,6 +15,7 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awdatetimeformatter.h"
#include "ui_awdatetimeformatter.h"
@ -26,13 +27,24 @@
#include "awdebug.h"
AWDateTimeFormatter::AWDateTimeFormatter(QObject *_parent, const QString &_filePath)
AWDateTimeFormatter::AWDateTimeFormatter(QWidget *_parent, const QString &_filePath)
: AWAbstractFormatter(_parent, _filePath)
, ui(new Ui::AWDateTimeFormatter)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty())
AWDateTimeFormatter::readConfiguration();
ui->setupUi(this);
AWDateTimeFormatter::translate();
}
AWDateTimeFormatter::~AWDateTimeFormatter()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete ui;
}
@ -48,9 +60,8 @@ AWDateTimeFormatter *AWDateTimeFormatter::copy(const QString &_fileName, const i
{
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
auto item = new AWDateTimeFormatter(parent(), _fileName);
auto *item = new AWDateTimeFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item);
item->setFormat(format());
item->setTranslateString(translateString());
item->setNumber(_number);
@ -92,7 +103,7 @@ void AWDateTimeFormatter::readConfiguration()
{
AWAbstractFormatter::readConfiguration();
QSettings settings(filePath(), QSettings::IniFormat);
QSettings settings(fileName(), QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
setFormat(settings.value("X-AW-Format", format()).toString());
@ -103,36 +114,27 @@ void AWDateTimeFormatter::readConfiguration()
}
int AWDateTimeFormatter::showConfiguration(QWidget *_parent, const QVariant &_args)
int AWDateTimeFormatter::showConfiguration(const QVariant &_args)
{
Q_UNUSED(_args)
auto dialog = new QDialog(_parent);
auto ui = new Ui::AWDateTimeFormatter();
ui->setupUi(dialog);
translate(ui);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_typeValue->setText("DateTime");
ui->lineEdit_format->setText(format());
ui->checkBox_translate->setCheckState(translateString() ? Qt::Checked : Qt::Unchecked);
auto ret = dialog->exec();
if (ret == 1) {
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setFormat(ui->lineEdit_format->text());
setTranslateString(ui->checkBox_translate->checkState() == Qt::Checked);
writeConfiguration();
}
dialog->deleteLater();
delete ui;
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setFormat(ui->lineEdit_format->text());
setTranslateString(ui->checkBox_translate->checkState() == Qt::Checked);
writeConfiguration();
return ret;
}
@ -141,7 +143,7 @@ void AWDateTimeFormatter::writeConfiguration() const
{
AWAbstractFormatter::writeConfiguration();
QSettings settings(writableConfig(), QSettings::IniFormat);
QSettings settings(writtableConfig(), QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup("Desktop Entry");
@ -158,10 +160,9 @@ void AWDateTimeFormatter::initLocale()
m_locale = m_translate ? QLocale::system() : QLocale::c();
}
void AWDateTimeFormatter::translate(void *_ui)
{
auto ui = reinterpret_cast<Ui::AWDateTimeFormatter *>(_ui);
void AWDateTimeFormatter::translate()
{
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_type->setText(i18n("Type"));

View File

@ -15,13 +15,19 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWDATETIMEFORMATTER_H
#define AWDATETIMEFORMATTER_H
#include <QLocale>
#include "awabstractformatter.h"
namespace Ui
{
class AWDateTimeFormatter;
}
class AWDateTimeFormatter : public AWAbstractFormatter
{
Q_OBJECT
@ -29,7 +35,8 @@ class AWDateTimeFormatter : public AWAbstractFormatter
Q_PROPERTY(bool translateString READ translateString WRITE setTranslateString)
public:
explicit AWDateTimeFormatter(QObject *_parent = nullptr, const QString &_filePath = "");
explicit AWDateTimeFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
~AWDateTimeFormatter() override;
[[nodiscard]] QString convert(const QVariant &_value) const override;
AWDateTimeFormatter *copy(const QString &_fileName, int _number) override;
// properties
@ -40,14 +47,18 @@ public:
public slots:
void readConfiguration() override;
int showConfiguration(QWidget *_parent, const QVariant &_args) override;
int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const override;
private:
Ui::AWDateTimeFormatter *ui = nullptr;
void initLocale();
void translate(void *_ui) override;
void translate() override;
// properties
QLocale m_locale;
QString m_format = "";
bool m_translate = true;
};
#endif /* AWDATETIMEFORMATTER_H */

View File

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

View File

@ -15,6 +15,7 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awfloatformatter.h"
#include "ui_awfloatformatter.h"
@ -25,13 +26,24 @@
#include "awdebug.h"
AWFloatFormatter::AWFloatFormatter(QObject *_parent, const QString &_filePath)
AWFloatFormatter::AWFloatFormatter(QWidget *_parent, const QString &_filePath)
: AWAbstractFormatter(_parent, _filePath)
, ui(new Ui::AWFloatFormatter)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty())
AWFloatFormatter::readConfiguration();
ui->setupUi(this);
AWFloatFormatter::translate();
}
AWFloatFormatter::~AWFloatFormatter()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete ui;
}
@ -39,7 +51,7 @@ QString AWFloatFormatter::convert(const QVariant &_value) const
{
qCDebug(LOG_LIB) << "Convert value" << _value;
auto output
QString output
= QString("%1").arg(_value.toDouble() * multiplier() + summand(), count(), format(), precision(), fillChar());
if (forceWidth())
output = output.left(count());
@ -52,9 +64,8 @@ AWFloatFormatter *AWFloatFormatter::copy(const QString &_fileName, const int _nu
{
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
auto item = new AWFloatFormatter(parent(), _fileName);
auto *item = new AWFloatFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item);
item->setCount(count());
item->setFormat(format());
item->setFillChar(fillChar());
@ -175,7 +186,7 @@ void AWFloatFormatter::readConfiguration()
{
AWAbstractFormatter::readConfiguration();
QSettings settings(filePath(), QSettings::IniFormat);
QSettings settings(fileName(), QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
setCount(settings.value("X-AW-Width", count()).toInt());
@ -191,15 +202,10 @@ void AWFloatFormatter::readConfiguration()
}
int AWFloatFormatter::showConfiguration(QWidget *_parent, const QVariant &_args)
int AWFloatFormatter::showConfiguration(const QVariant &_args)
{
Q_UNUSED(_args)
auto dialog = new QDialog(_parent);
auto ui = new Ui::AWFloatFormatter();
ui->setupUi(dialog);
translate(ui);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_typeValue->setText("Float");
@ -211,26 +217,22 @@ int AWFloatFormatter::showConfiguration(QWidget *_parent, const QVariant &_args)
ui->doubleSpinBox_multiplier->setValue(multiplier());
ui->doubleSpinBox_summand->setValue(summand());
auto ret = dialog->exec();
if (ret == 1) {
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setFormat(ui->comboBox_format->currentText().at(0).toLatin1());
setPrecision(ui->spinBox_precision->value());
setCount(ui->spinBox_width->value());
setFillChar(ui->lineEdit_fill->text().at(0));
setForceWidth(ui->checkBox_forceWidth->checkState() == Qt::Checked);
setMultiplier(ui->doubleSpinBox_multiplier->value());
setSummand(ui->doubleSpinBox_summand->value());
writeConfiguration();
}
dialog->deleteLater();
delete ui;
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setFormat(ui->comboBox_format->currentText().at(0).toLatin1());
setPrecision(ui->spinBox_precision->value());
setCount(ui->spinBox_width->value());
setFillChar(ui->lineEdit_fill->text().at(0));
setForceWidth(ui->checkBox_forceWidth->checkState() == Qt::Checked);
setMultiplier(ui->doubleSpinBox_multiplier->value());
setSummand(ui->doubleSpinBox_summand->value());
writeConfiguration();
return ret;
}
@ -239,7 +241,7 @@ void AWFloatFormatter::writeConfiguration() const
{
AWAbstractFormatter::writeConfiguration();
QSettings settings(writableConfig(), QSettings::IniFormat);
QSettings settings(writtableConfig(), QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup("Desktop Entry");
@ -256,10 +258,8 @@ void AWFloatFormatter::writeConfiguration() const
}
void AWFloatFormatter::translate(void *_ui)
void AWFloatFormatter::translate()
{
auto ui = reinterpret_cast<Ui::AWFloatFormatter *>(_ui);
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_type->setText(i18n("Type"));

View File

@ -15,11 +15,17 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWFLOATFORMATTER_H
#define AWFLOATFORMATTER_H
#include "awabstractformatter.h"
namespace Ui
{
class AWFloatFormatter;
}
class AWFloatFormatter : public AWAbstractFormatter
{
Q_OBJECT
@ -32,7 +38,8 @@ class AWFloatFormatter : public AWAbstractFormatter
Q_PROPERTY(double summand READ summand WRITE setSummand)
public:
explicit AWFloatFormatter(QObject *_parent = nullptr, const QString &_filePath = "");
explicit AWFloatFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
~AWFloatFormatter() override;
[[nodiscard]] QString convert(const QVariant &_value) const override;
AWFloatFormatter *copy(const QString &_fileName, int _number) override;
// properties
@ -53,11 +60,12 @@ public:
public slots:
void readConfiguration() override;
int showConfiguration(QWidget *_parent, const QVariant &_args) override;
int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const override;
private:
void translate(void *_ui) override;
Ui::AWFloatFormatter *ui = nullptr;
void translate() override;
// properties
int m_count = 0;
QChar m_fillChar = QChar();
@ -67,3 +75,6 @@ private:
int m_precision = -1;
double m_summand = 0.0;
};
#endif /* AWFLOATFORMATTER_H */

View File

@ -15,6 +15,7 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awjsonformatter.h"
#include "ui_awjsonformatter.h"
@ -26,13 +27,24 @@
#include "awdebug.h"
AWJsonFormatter::AWJsonFormatter(QObject *_parent, const QString &_filePath)
AWJsonFormatter::AWJsonFormatter(QWidget *_parent, const QString &_filePath)
: AWAbstractFormatter(_parent, _filePath)
, ui(new Ui::AWJsonFormatter)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty())
AWJsonFormatter::readConfiguration();
ui->setupUi(this);
AWJsonFormatter::translate();
}
AWJsonFormatter::~AWJsonFormatter()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete ui;
}
@ -41,10 +53,10 @@ QString AWJsonFormatter::convert(const QVariant &_value) const
qCDebug(LOG_LIB) << "Convert value" << _value;
// check if _value is string and parse first if required
auto json = _value.userType() == QMetaType::QString ? QJsonDocument::fromJson(_value.toString().toUtf8())
: QJsonDocument::fromVariant(_value);
auto converted = json.toVariant();
for (auto &element : m_path)
QJsonDocument json = _value.type() == QVariant::String ? QJsonDocument::fromJson(_value.toString().toUtf8())
: QJsonDocument::fromVariant(_value);
QVariant converted = json.toVariant();
for (auto &element : m_splittedPath)
converted = getFromJson(converted, element);
return converted.toString();
@ -55,9 +67,8 @@ AWJsonFormatter *AWJsonFormatter::copy(const QString &_fileName, const int _numb
{
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
auto item = new AWJsonFormatter(parent(), _fileName);
auto *item = new AWJsonFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item);
item->setNumber(_number);
item->setPath(path());
@ -67,8 +78,7 @@ AWJsonFormatter *AWJsonFormatter::copy(const QString &_fileName, const int _numb
QString AWJsonFormatter::path() const
{
return std::accumulate(m_path.cbegin(), m_path.cend(), QString(""),
[](auto acc, auto &value) { return QString("%1.%2").arg(acc, value.toString()); });
return m_path;
}
@ -76,14 +86,8 @@ void AWJsonFormatter::setPath(const QString &_path)
{
qCDebug(LOG_LIB) << "Path" << _path;
m_path.clear();
auto elements = _path.split('.', Qt::SkipEmptyParts);
for (auto &element : elements) {
bool ok;
auto number = element.toInt(&ok);
m_path.append(ok ? QVariant(number) : QVariant(element));
}
m_path = _path;
initPath();
}
@ -91,7 +95,7 @@ void AWJsonFormatter::readConfiguration()
{
AWAbstractFormatter::readConfiguration();
QSettings settings(filePath(), QSettings::IniFormat);
QSettings settings(fileName(), QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
setPath(settings.value("X-AW-Path", path()).toString());
@ -101,34 +105,25 @@ void AWJsonFormatter::readConfiguration()
}
int AWJsonFormatter::showConfiguration(QWidget *_parent, const QVariant &args)
int AWJsonFormatter::showConfiguration(const QVariant &args)
{
Q_UNUSED(args)
auto dialog = new QDialog(_parent);
auto ui = new Ui::AWJsonFormatter();
ui->setupUi(dialog);
translate(ui);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_typeValue->setText("Json");
ui->lineEdit_path->setText(path());
auto ret = dialog->exec();
if (ret == 1) {
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setPath(ui->lineEdit_path->text());
writeConfiguration();
}
dialog->deleteLater();
delete ui;
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setPath(ui->lineEdit_path->text());
writeConfiguration();
return ret;
}
@ -137,7 +132,7 @@ void AWJsonFormatter::writeConfiguration() const
{
AWAbstractFormatter::writeConfiguration();
QSettings settings(writableConfig(), QSettings::IniFormat);
QSettings settings(writtableConfig(), QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup("Desktop Entry");
@ -152,9 +147,9 @@ QVariant AWJsonFormatter::getFromJson(const QVariant &_value, const QVariant &_e
{
qCDebug(LOG_LIB) << "Looking for element" << _element << "in" << _value;
if (_element.userType() == QMetaType::QString) {
if (_element.type() == QVariant::String) {
return getFromMap(_value, _element.toString());
} else if (_element.userType() == QMetaType::Int) {
} else if (_element.type() == QVariant::Int) {
return getFromList(_value, _element.toInt());
} else {
qCWarning(LOG_LIB) << "Unknown type" << _element.typeName();
@ -179,10 +174,21 @@ QVariant AWJsonFormatter::getFromMap(const QVariant &_value, const QString &_key
}
void AWJsonFormatter::translate(void *_ui)
void AWJsonFormatter::initPath()
{
auto ui = reinterpret_cast<Ui::AWJsonFormatter *>(_ui);
m_splittedPath.clear();
QStringList splittedByDot = m_path.split('.', Qt::SkipEmptyParts);
for (auto &element : splittedByDot) {
bool ok;
int number = element.toInt(&ok);
m_splittedPath.append(ok ? QVariant(number) : QVariant(element));
}
}
void AWJsonFormatter::translate()
{
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_type->setText(i18n("Type"));

View File

@ -15,18 +15,25 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWJSONFORMATTER_H
#define AWJSONFORMATTER_H
#include "awabstractformatter.h"
namespace Ui
{
class AWJsonFormatter;
}
class AWJsonFormatter : public AWAbstractFormatter
{
Q_OBJECT
Q_PROPERTY(QString path READ path WRITE setPath)
public:
explicit AWJsonFormatter(QObject *_parent = nullptr, const QString &_filePath = "");
explicit AWJsonFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
~AWJsonFormatter() override;
[[nodiscard]] QString convert(const QVariant &_value) const override;
AWJsonFormatter *copy(const QString &_fileName, int _number) override;
// properties
@ -35,14 +42,20 @@ public:
public slots:
void readConfiguration() override;
int showConfiguration(QWidget *_parent, const QVariant &_args) override;
int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const override;
private:
Ui::AWJsonFormatter *ui = nullptr;
static QVariant getFromJson(const QVariant &_value, const QVariant &_element);
static QVariant getFromList(const QVariant &_value, int _index);
static QVariant getFromMap(const QVariant &_value, const QString &_key);
void translate(void *_ui) override;
void initPath();
void translate() override;
// properties
QVariantList m_path;
QString m_path;
QVariantList m_splittedPath;
};
#endif /* AWJSONFORMATTER_H */

View File

@ -15,6 +15,7 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awlistformatter.h"
#include "ui_awlistformatter.h"
@ -25,13 +26,24 @@
#include "awdebug.h"
AWListFormatter::AWListFormatter(QObject *_parent, const QString &_filePath)
AWListFormatter::AWListFormatter(QWidget *_parent, const QString &_filePath)
: AWAbstractFormatter(_parent, _filePath)
, ui(new Ui::AWListFormatter)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty())
AWListFormatter::readConfiguration();
ui->setupUi(this);
AWListFormatter::translate();
}
AWListFormatter::~AWListFormatter()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete ui;
}
@ -39,7 +51,7 @@ QString AWListFormatter::convert(const QVariant &_value) const
{
qCDebug(LOG_LIB) << "Convert value" << _value;
auto output = _value.toStringList();
QStringList output = _value.toStringList();
if (isSorted())
output.sort();
@ -51,9 +63,8 @@ AWListFormatter *AWListFormatter::copy(const QString &_fileName, const int _numb
{
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
auto item = new AWListFormatter(parent(), _fileName);
auto *item = new AWListFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item);
item->setFilter(filter());
item->setSeparator(separator());
item->setSorted(isSorted());
@ -86,13 +97,13 @@ void AWListFormatter::setFilter(const QString &_filter)
qCDebug(LOG_LIB) << "Filter" << _filter;
m_filter = _filter;
m_regex = QRegularExpression(m_filter);
m_regex = QRegExp(m_filter);
}
void AWListFormatter::setSeparator(const QString &_separator)
{
qCDebug(LOG_LIB) << "Separator" << _separator;
qCDebug(LOG_LIB) << "Separtor" << _separator;
m_separator = _separator;
}
@ -110,7 +121,7 @@ void AWListFormatter::readConfiguration()
{
AWAbstractFormatter::readConfiguration();
QSettings settings(filePath(), QSettings::IniFormat);
QSettings settings(fileName(), QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
setFilter(settings.value("X-AW-Filter", filter()).toString());
@ -122,15 +133,10 @@ void AWListFormatter::readConfiguration()
}
int AWListFormatter::showConfiguration(QWidget *_parent, const QVariant &_args)
int AWListFormatter::showConfiguration(const QVariant &_args)
{
Q_UNUSED(_args)
auto dialog = new QDialog(_parent);
auto ui = new Ui::AWListFormatter();
ui->setupUi(dialog);
translate(ui);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_typeValue->setText("List");
@ -138,22 +144,18 @@ int AWListFormatter::showConfiguration(QWidget *_parent, const QVariant &_args)
ui->lineEdit_separator->setText(separator());
ui->checkBox_sorted->setCheckState(isSorted() ? Qt::Checked : Qt::Unchecked);
auto ret = dialog->exec();
if (ret == 1) {
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setFilter(ui->lineEdit_filter->text());
setSeparator(ui->lineEdit_separator->text());
setSorted(ui->checkBox_sorted->checkState() == Qt::Checked);
writeConfiguration();
}
dialog->deleteLater();
delete ui;
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setFilter(ui->lineEdit_filter->text());
setSeparator(ui->lineEdit_separator->text());
setSorted(ui->checkBox_sorted->checkState() == Qt::Checked);
writeConfiguration();
return ret;
}
@ -162,7 +164,7 @@ void AWListFormatter::writeConfiguration() const
{
AWAbstractFormatter::writeConfiguration();
QSettings settings(writableConfig(), QSettings::IniFormat);
QSettings settings(writtableConfig(), QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup("Desktop Entry");
@ -175,10 +177,8 @@ void AWListFormatter::writeConfiguration() const
}
void AWListFormatter::translate(void *_ui)
void AWListFormatter::translate()
{
auto ui = reinterpret_cast<Ui::AWListFormatter *>(_ui);
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_type->setText(i18n("Type"));

View File

@ -15,11 +15,17 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWLISTFORMATTER_H
#define AWLISTFORMATTER_H
#include "awabstractformatter.h"
namespace Ui
{
class AWListFormatter;
}
class AWListFormatter : public AWAbstractFormatter
{
Q_OBJECT
@ -28,7 +34,8 @@ class AWListFormatter : public AWAbstractFormatter
Q_PROPERTY(bool sorted READ isSorted WRITE setSorted)
public:
explicit AWListFormatter(QObject *_parent = nullptr, const QString &_filePath = "");
explicit AWListFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
~AWListFormatter() override;
[[nodiscard]] QString convert(const QVariant &_value) const override;
AWListFormatter *copy(const QString &_fileName, int _number) override;
// properties
@ -41,14 +48,18 @@ public:
public slots:
void readConfiguration() override;
int showConfiguration(QWidget *_parent, const QVariant &_args) override;
int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const override;
private:
void translate(void *_ui) override;
Ui::AWListFormatter *ui = nullptr;
void translate() override;
// properties
QString m_filter = "";
QString m_separator = "";
bool m_sorted = false;
QRegularExpression m_regex;
QRegExp m_regex;
};
#endif /* AWLISTFORMATTER_H */

View File

@ -15,6 +15,7 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awnoformatter.h"
#include "ui_awnoformatter.h"
@ -23,13 +24,24 @@
#include "awdebug.h"
AWNoFormatter::AWNoFormatter(QObject *_parent, const QString &_filePath)
AWNoFormatter::AWNoFormatter(QWidget *_parent, const QString &_filePath)
: AWAbstractFormatter(_parent, _filePath)
, ui(new Ui::AWNoFormatter)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty())
AWNoFormatter::readConfiguration();
ui->setupUi(this);
AWNoFormatter::translate();
}
AWNoFormatter::~AWNoFormatter()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete ui;
}
@ -45,49 +57,37 @@ AWNoFormatter *AWNoFormatter::copy(const QString &_fileName, const int _number)
{
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
auto item = new AWNoFormatter(parent(), _fileName);
auto *item = new AWNoFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item);
item->setNumber(_number);
return item;
}
int AWNoFormatter::showConfiguration(QWidget *_parent, const QVariant &_args)
int AWNoFormatter::showConfiguration(const QVariant &_args)
{
Q_UNUSED(_args)
auto dialog = new QDialog(_parent);
auto ui = new Ui::AWNoFormatter();
ui->setupUi(dialog);
translate(ui);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_typeValue->setText("NoFormat");
auto ret = dialog->exec();
if (ret == 1) {
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
writeConfiguration();
}
dialog->deleteLater();
delete ui;
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
writeConfiguration();
return ret;
}
void AWNoFormatter::translate(void *_ui)
void AWNoFormatter::translate()
{
auto ui = reinterpret_cast<Ui::AWNoFormatter *>(_ui);
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_type->setText(i18n("Type"));

View File

@ -15,23 +15,35 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWNOFORMATTER_H
#define AWNOFORMATTER_H
#include "awabstractformatter.h"
namespace Ui
{
class AWNoFormatter;
}
class AWNoFormatter : public AWAbstractFormatter
{
Q_OBJECT
public:
explicit AWNoFormatter(QObject *_parent = nullptr, const QString &_filePath = "");
explicit AWNoFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
~AWNoFormatter() override;
[[nodiscard]] QString convert(const QVariant &_value) const override;
AWNoFormatter *copy(const QString &_fileName, int _number) override;
public slots:
int showConfiguration(QWidget *_parent, const QVariant &_args) override;
int showConfiguration(const QVariant &_args) override;
private:
void translate(void *_ui) override;
Ui::AWNoFormatter *ui = nullptr;
void translate() override;
// properties
};
#endif /* AWNOFORMATTER_H */

View File

@ -15,6 +15,7 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awscriptformatter.h"
#include "ui_awscriptformatter.h"
@ -26,13 +27,24 @@
#include "awdebug.h"
AWScriptFormatter::AWScriptFormatter(QObject *_parent, const QString &_filePath)
AWScriptFormatter::AWScriptFormatter(QWidget *_parent, const QString &_filePath)
: AWAbstractFormatter(_parent, _filePath)
, ui(new Ui::AWScriptFormatter)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty())
AWScriptFormatter::readConfiguration();
ui->setupUi(this);
AWScriptFormatter::translate();
}
AWScriptFormatter::~AWScriptFormatter()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete ui;
}
@ -42,8 +54,9 @@ QString AWScriptFormatter::convert(const QVariant &_value) const
// init engine
QJSEngine engine;
auto fn = engine.evaluate(m_program);
auto result = fn.call({_value.toString()});
QJSValue fn = engine.evaluate(m_program);
QJSValueList args = QJSValueList() << _value.toString();
QJSValue result = fn.call(args);
if (result.isError()) {
qCWarning(LOG_LIB) << "Uncaught exception at line" << result.property("lineNumber").toInt() << ":"
@ -59,9 +72,8 @@ AWScriptFormatter *AWScriptFormatter::copy(const QString &_fileName, const int _
{
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
auto item = new AWScriptFormatter(parent(), _fileName);
auto *item = new AWScriptFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item);
item->setAppendCode(appendCode());
item->setCode(code());
item->setHasReturn(hasReturn());
@ -126,7 +138,7 @@ void AWScriptFormatter::readConfiguration()
{
AWAbstractFormatter::readConfiguration();
QSettings settings(filePath(), QSettings::IniFormat);
QSettings settings(fileName(), QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
setAppendCode(settings.value("X-AW-AppendCode", appendCode()).toBool());
@ -138,15 +150,10 @@ void AWScriptFormatter::readConfiguration()
}
int AWScriptFormatter::showConfiguration(QWidget *_parent, const QVariant &_args)
int AWScriptFormatter::showConfiguration(const QVariant &_args)
{
Q_UNUSED(_args)
auto dialog = new QDialog(_parent);
auto ui = new Ui::AWScriptFormatter();
ui->setupUi(dialog);
translate(ui);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_typeValue->setText("Script");
@ -154,23 +161,19 @@ int AWScriptFormatter::showConfiguration(QWidget *_parent, const QVariant &_args
ui->checkBox_hasReturn->setCheckState(hasReturn() ? Qt::Checked : Qt::Unchecked);
ui->textEdit_code->setPlainText(code());
int ret = dialog->exec();
if (ret == 1) {
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setAppendCode(ui->checkBox_appendCode->checkState() == Qt::Checked);
setHasReturn(ui->checkBox_hasReturn->checkState() == Qt::Checked);
setCode(ui->textEdit_code->toPlainText());
initProgram();
writeConfiguration();
}
dialog->deleteLater();
delete ui;
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setAppendCode(ui->checkBox_appendCode->checkState() == Qt::Checked);
setHasReturn(ui->checkBox_hasReturn->checkState() == Qt::Checked);
setCode(ui->textEdit_code->toPlainText());
initProgram();
writeConfiguration();
return ret;
}
@ -179,7 +182,7 @@ void AWScriptFormatter::writeConfiguration() const
{
AWAbstractFormatter::writeConfiguration();
QSettings settings(writableConfig(), QSettings::IniFormat);
QSettings settings(writtableConfig(), QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup("Desktop Entry");
@ -196,7 +199,7 @@ void AWScriptFormatter::initProgram()
{
// init JS code
if (appendCode())
m_program = QString("(function(value) { %1%2 })").arg(code(), hasReturn() ? "" : "; return output;");
m_program = QString("(function(value) { %1%2 })").arg(code()).arg(hasReturn() ? "" : "; return output;");
else
m_program = code();
@ -204,10 +207,8 @@ void AWScriptFormatter::initProgram()
}
void AWScriptFormatter::translate(void *_ui)
void AWScriptFormatter::translate()
{
auto ui = reinterpret_cast<Ui::AWScriptFormatter *>(_ui);
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_type->setText(i18n("Type"));

View File

@ -15,11 +15,17 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWSCRIPTFORMATTER_H
#define AWSCRIPTFORMATTER_H
#include "awabstractformatter.h"
namespace Ui
{
class AWScriptFormatter;
}
class AWScriptFormatter : public AWAbstractFormatter
{
Q_OBJECT
@ -29,7 +35,8 @@ class AWScriptFormatter : public AWAbstractFormatter
Q_PROPERTY(QString program READ program)
public:
explicit AWScriptFormatter(QObject *_parent = nullptr, const QString &_filePath = "");
explicit AWScriptFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
~AWScriptFormatter() override;
[[nodiscard]] QString convert(const QVariant &_value) const override;
AWScriptFormatter *copy(const QString &_fileName, int _number) override;
// properties
@ -43,15 +50,19 @@ public:
public slots:
void readConfiguration() override;
int showConfiguration(QWidget *_parent, const QVariant &_args) override;
int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const override;
private:
Ui::AWScriptFormatter *ui = nullptr;
void initProgram();
void translate(void *_ui) override;
void translate() override;
// properties
bool m_appendCode = true;
QString m_code = "";
bool m_hasReturn = false;
QString m_program;
};
#endif /* AWSCRIPTFORMATTER_H */

View File

@ -15,6 +15,7 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#include "awstringformatter.h"
#include "ui_awstringformatter.h"
@ -25,13 +26,24 @@
#include "awdebug.h"
AWStringFormatter::AWStringFormatter(QObject *_parent, const QString &_filePath)
AWStringFormatter::AWStringFormatter(QWidget *_parent, const QString &_filePath)
: AWAbstractFormatter(_parent, _filePath)
, ui(new Ui::AWStringFormatter)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty())
AWStringFormatter::readConfiguration();
ui->setupUi(this);
AWStringFormatter::translate();
}
AWStringFormatter::~AWStringFormatter()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
delete ui;
}
@ -39,7 +51,7 @@ QString AWStringFormatter::convert(const QVariant &_value) const
{
qCDebug(LOG_LIB) << "Convert value" << _value;
auto output = QString("%1").arg(_value.toString(), count(), fillChar());
QString output = QString("%1").arg(_value.toString(), count(), fillChar());
if (forceWidth())
output = output.left(count());
@ -51,9 +63,8 @@ AWStringFormatter *AWStringFormatter::copy(const QString &_fileName, const int _
{
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
auto item = new AWStringFormatter(parent(), _fileName);
auto *item = new AWStringFormatter(dynamic_cast<QWidget *>(parent()), _fileName);
AWAbstractFormatter::copyDefaults(item);
item->setCount(count());
item->setFillChar(fillChar());
item->setForceWidth(forceWidth());
@ -109,7 +120,7 @@ void AWStringFormatter::readConfiguration()
{
AWAbstractFormatter::readConfiguration();
QSettings settings(filePath(), QSettings::IniFormat);
QSettings settings(fileName(), QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
setCount(settings.value("X-AW-Width", count()).toInt());
@ -121,15 +132,10 @@ void AWStringFormatter::readConfiguration()
}
int AWStringFormatter::showConfiguration(QWidget *_parent, const QVariant &_args)
int AWStringFormatter::showConfiguration(const QVariant &_args)
{
Q_UNUSED(_args)
auto dialog = new QDialog(_parent);
auto ui = new Ui::AWStringFormatter();
ui->setupUi(dialog);
translate(ui);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_typeValue->setText("String");
@ -137,22 +143,18 @@ int AWStringFormatter::showConfiguration(QWidget *_parent, const QVariant &_args
ui->lineEdit_fill->setText(QString(fillChar()));
ui->checkBox_forceWidth->setCheckState(forceWidth() ? Qt::Checked : Qt::Unchecked);
auto ret = dialog->exec();
if (ret == 1) {
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setCount(ui->spinBox_width->value());
setFillChar(ui->lineEdit_fill->text().at(0));
setForceWidth(ui->checkBox_forceWidth->checkState() == Qt::Checked);
writeConfiguration();
}
dialog->deleteLater();
delete ui;
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setApiVersion(AW_FORMATTER_API);
setStrType(ui->label_typeValue->text());
setCount(ui->spinBox_width->value());
setFillChar(ui->lineEdit_fill->text().at(0));
setForceWidth(ui->checkBox_forceWidth->checkState() == Qt::Checked);
writeConfiguration();
return ret;
}
@ -161,7 +163,7 @@ void AWStringFormatter::writeConfiguration() const
{
AWAbstractFormatter::writeConfiguration();
QSettings settings(writableConfig(), QSettings::IniFormat);
QSettings settings(writtableConfig(), QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup("Desktop Entry");
@ -174,10 +176,8 @@ void AWStringFormatter::writeConfiguration() const
}
void AWStringFormatter::translate(void *_ui)
void AWStringFormatter::translate()
{
auto ui = reinterpret_cast<Ui::AWStringFormatter *>(_ui);
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_type->setText(i18n("Type"));

View File

@ -15,11 +15,17 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef AWSTRINGFORMATTER_H
#define AWSTRINGFORMATTER_H
#include "awabstractformatter.h"
namespace Ui
{
class AWStringFormatter;
}
class AWStringFormatter : public AWAbstractFormatter
{
Q_OBJECT
@ -28,7 +34,8 @@ class AWStringFormatter : public AWAbstractFormatter
Q_PROPERTY(bool forceWidth READ forceWidth WRITE setForceWidth)
public:
explicit AWStringFormatter(QObject *_parent = nullptr, const QString &_filePath = "");
explicit AWStringFormatter(QWidget *_parent = nullptr, const QString &_filePath = "");
~AWStringFormatter() override;
[[nodiscard]] QString convert(const QVariant &_value) const override;
AWStringFormatter *copy(const QString &_fileName, int _number) override;
// properties
@ -41,13 +48,17 @@ public:
public slots:
void readConfiguration() override;
int showConfiguration(QWidget *_parent, const QVariant &_args) override;
int showConfiguration(const QVariant &_args) override;
void writeConfiguration() const override;
private:
void translate(void *_ui) override;
Ui::AWStringFormatter *ui = nullptr;
void translate() override;
// properties
int m_count = 0;
QChar m_fillChar = QChar();
bool m_forceWidth = false;
};
#endif /* AWSTRINGFORMATTER_H */

View File

@ -15,7 +15,8 @@
* along with awesome-widgets. If not, see http://www.gnu.org/licenses/ *
***************************************************************************/
#pragma once
#ifndef EXTITEMAGGREGATOR_H
#define EXTITEMAGGREGATOR_H
#include <KI18n/KLocalizedString>
@ -23,8 +24,6 @@
#include <QSettings>
#include <QStandardPaths>
#include <ranges>
#include "abstractextitemaggregator.h"
#include "awdebug.h"
@ -32,7 +31,7 @@
template <class T> class ExtItemAggregator : public AbstractExtItemAggregator
{
public:
explicit ExtItemAggregator(QObject *_parent, const QString &_type)
explicit ExtItemAggregator(QWidget *_parent, const QString &_type)
: AbstractExtItemAggregator(_parent, _type)
{
qSetMessagePattern(AWDebug::LOG_FORMAT);
@ -50,23 +49,29 @@ public:
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
m_items.clear();
m_activeItems.clear();
};
auto activeItems()
{
return m_items | std::ranges::views::filter([](auto item) { return item->isActive(); });
};
QList<T *> activeItems() { return m_activeItems; };
void editItems()
{
auto ret = exec();
repaintList();
int ret = exec();
qCInfo(LOG_LIB) << "Dialog returns" << ret;
};
void initItems() override
{
m_items.clear();
m_activeItems.clear();
m_items = getItems();
for (auto &item : m_items) {
if (!item->isActive())
continue;
m_activeItems.append(static_cast<T *>(item));
}
};
void initSockets()
@ -74,7 +79,7 @@ public:
// HACK as soon as per one widget instance we have two objects each of
// them will try to control socket, whereas actually only one of them
// should be owner of the socket
for (auto item : m_items)
for (auto &item : m_items)
item->initSocket();
}
@ -82,58 +87,71 @@ public:
{
qCDebug(LOG_LIB) << "Tag" << _tag << "with used type" << _type;
auto found = std::find_if(m_items.cbegin(), m_items.cend(),
[&_tag, &_type](auto item) { return item->tag(_type) == _tag; });
if (found == std::end(m_items)) {
qCWarning(LOG_LIB) << "Could not find item by tag" << _tag;
return nullptr;
T *found = nullptr;
for (auto &item : m_items) {
if (item->tag(_type) != _tag)
continue;
found = static_cast<T *>(item);
break;
}
return static_cast<T *>(*found);
if (found == nullptr)
qCWarning(LOG_LIB) << "Could not find item by tag" << _tag;
return found;
};
T *itemByTagNumber(const int _number) const
{
qCDebug(LOG_LIB) << "Number" << _number;
auto found = std::find_if(m_items.cbegin(), m_items.cend(),
[_number](auto item) { return item->number() == _number; });
if (found == std::end(m_items)) {
qCWarning(LOG_LIB) << "Could not find item by number" << _number;
return nullptr;
T *found = nullptr;
for (auto &item : m_items) {
if (item->number() != _number)
continue;
found = static_cast<T *>(item);
break;
}
return static_cast<T *>(*found);
if (found == nullptr)
qCWarning(LOG_LIB) << "Could not find item by number" << _number;
return found;
};
[[nodiscard]] QList<AbstractExtItem *> items() const override { return m_items; };
private:
QList<AbstractExtItem *> m_items;
QList<T *> m_activeItems;
void doCreateItem(QListWidget *_widget) override { return createItem<T>(_widget); }
void doCreateItem() override { return createItem<T>(); }
QList<AbstractExtItem *> getItems()
{
QList<AbstractExtItem *> items;
for (auto &dir : directories()) {
auto files = QDir(dir).entryList(QDir::Files, QDir::Name);
auto dirs = directories();
for (auto &dir : dirs) {
QStringList files = QDir(dir).entryList(QDir::Files, QDir::Name);
for (auto &file : files) {
// check filename
if (!file.endsWith(".desktop"))
continue;
qCInfo(LOG_LIB) << "Found file" << file << "in" << dir;
auto filePath = QString("%1/%2").arg(dir, file);
QString filePath = QString("%1/%2").arg(dir).arg(file);
// check if already exists
if (std::any_of(items.cbegin(), items.cend(), [&file](auto item) { return item->fileName() == file; }))
if (std::any_of(items.cbegin(), items.cend(),
[&filePath](AbstractExtItem *item) { return (item->fileName() == filePath); }))
continue;
items.append(new T(this, filePath));
}
}
// sort items
std::sort(items.begin(), items.end(), [](auto lhs, auto rhs) { return lhs->number() < rhs->number(); });
std::sort(items.begin(), items.end(),
[](const AbstractExtItem *lhs, const AbstractExtItem *rhs) { return lhs->number() < rhs->number(); });
return items;
};
};
#endif /* EXTITEMAGGREGATOR_H */

View File

@ -20,28 +20,34 @@
#include <KI18n/KLocalizedString>
#include <QDir>
#include <QSettings>
#include <QTextCodec>
#include <qreplytimeout/qreplytimeout.h>
#include "awdebug.h"
ExtNetworkRequest::ExtNetworkRequest(QObject *_parent, const QString &_filePath)
ExtNetworkRequest::ExtNetworkRequest(QWidget *_parent, const QString &_filePath)
: AbstractExtItem(_parent, _filePath)
, ui(new Ui::ExtNetworkRequest)
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
if (!_filePath.isEmpty())
ExtNetworkRequest::readConfiguration();
ui->setupUi(this);
ExtNetworkRequest::translate();
m_values[tag("response")] = "";
// HACK declare as child of nullptr to avoid crash with plasmawindowed
// in the destructor
m_manager = new QNetworkAccessManager(nullptr);
connect(m_manager, &QNetworkAccessManager::finished, this, &ExtNetworkRequest::networkReplyReceived);
connect(this, &ExtNetworkRequest::requestDataUpdate, this, &ExtNetworkRequest::sendRequest);
connect(m_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(networkReplyReceived(QNetworkReply *)));
connect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest()));
}
@ -49,7 +55,11 @@ ExtNetworkRequest::~ExtNetworkRequest()
{
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__;
disconnect(m_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(networkReplyReceived(QNetworkReply *)));
disconnect(this, SIGNAL(requestDataUpdate()), this, SLOT(sendRequest()));
m_manager->deleteLater();
delete ui;
}
@ -57,33 +67,33 @@ ExtNetworkRequest *ExtNetworkRequest::copy(const QString &_fileName, const int _
{
qCDebug(LOG_LIB) << "File" << _fileName << "with number" << _number;
auto item = new ExtNetworkRequest(parent(), _fileName);
auto *item = new ExtNetworkRequest(dynamic_cast<QWidget *>(parent()), _fileName);
copyDefaults(item);
item->setNumber(_number);
item->setUrl(url());
item->setStringUrl(stringUrl());
return item;
}
QString ExtNetworkRequest::url() const
QString ExtNetworkRequest::stringUrl() const
{
return m_url.toString();
return m_stringUrl;
}
QString ExtNetworkRequest::uniq() const
{
return url();
return m_url.toString();
}
void ExtNetworkRequest::setUrl(const QString &_url)
void ExtNetworkRequest::setStringUrl(const QString &_url)
{
qCDebug(LOG_LIB) << "Url" << _url;
m_url = QUrl(_url);
m_stringUrl = _url;
initUrl();
}
@ -91,10 +101,10 @@ void ExtNetworkRequest::readConfiguration()
{
AbstractExtItem::readConfiguration();
QSettings settings(filePath(), QSettings::IniFormat);
QSettings settings(fileName(), QSettings::IniFormat);
settings.beginGroup("Desktop Entry");
setUrl(settings.value("X-AW-Url", url()).toString());
setStringUrl(settings.value("X-AW-Url", stringUrl()).toString());
settings.endGroup();
bumpApi(AW_EXTNETREQUEST_API);
@ -111,42 +121,33 @@ QVariantHash ExtNetworkRequest::run()
}
int ExtNetworkRequest::showConfiguration(QWidget *_parent, const QVariant &_args)
int ExtNetworkRequest::showConfiguration(const QVariant &_args)
{
Q_UNUSED(_args)
auto dialog = new QDialog(_parent);
auto ui = new Ui::ExtNetworkRequest();
ui->setupUi(dialog);
translate(ui);
ui->lineEdit_name->setText(name());
ui->lineEdit_comment->setText(comment());
ui->label_numberValue->setText(QString("%1").arg(number()));
ui->lineEdit_url->setText(url());
ui->lineEdit_url->setText(stringUrl());
ui->checkBox_active->setCheckState(isActive() ? Qt::Checked : Qt::Unchecked);
ui->lineEdit_schedule->setText(cron());
ui->lineEdit_socket->setText(socket());
ui->spinBox_interval->setValue(interval());
auto ret = dialog->exec();
if (ret == 1) {
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setNumber(ui->label_numberValue->text().toInt());
setApiVersion(AW_EXTNETREQUEST_API);
setUrl(ui->lineEdit_url->text());
setActive(ui->checkBox_active->checkState() == Qt::Checked);
setCron(ui->lineEdit_schedule->text());
setSocket(ui->lineEdit_socket->text());
setInterval(ui->spinBox_interval->value());
writeConfiguration();
}
dialog->deleteLater();
delete ui;
int ret = exec();
if (ret != 1)
return ret;
setName(ui->lineEdit_name->text());
setComment(ui->lineEdit_comment->text());
setNumber(ui->label_numberValue->text().toInt());
setApiVersion(AW_EXTNETREQUEST_API);
setStringUrl(ui->lineEdit_url->text());
setActive(ui->checkBox_active->checkState() == Qt::Checked);
setCron(ui->lineEdit_schedule->text());
setSocket(ui->lineEdit_socket->text());
setInterval(ui->spinBox_interval->value());
writeConfiguration();
return ret;
}
@ -155,11 +156,11 @@ void ExtNetworkRequest::writeConfiguration() const
{
AbstractExtItem::writeConfiguration();
QSettings settings(writableConfig(), QSettings::IniFormat);
QSettings settings(writtableConfig(), QSettings::IniFormat);
qCInfo(LOG_LIB) << "Configuration file" << settings.fileName();
settings.beginGroup("Desktop Entry");
settings.setValue("X-AW-Url", url());
settings.setValue("X-AW-Url", stringUrl());
settings.endGroup();
settings.sync();
@ -173,7 +174,7 @@ void ExtNetworkRequest::networkReplyReceived(QNetworkReply *_reply)
}
m_isRunning = false;
m_values[tag("response")] = QString::fromUtf8(_reply->readAll()).trimmed();
m_values[tag("response")] = QTextCodec::codecForMib(106)->toUnicode(_reply->readAll()).trimmed();
emit(dataReceived(m_values));
}
@ -182,15 +183,19 @@ void ExtNetworkRequest::networkReplyReceived(QNetworkReply *_reply)
void ExtNetworkRequest::sendRequest()
{
m_isRunning = true;
auto reply = m_manager->get(QNetworkRequest(m_url));
QNetworkReply *reply = m_manager->get(QNetworkRequest(m_url));
new QReplyTimeout(reply, REQUEST_TIMEOUT);
}
void ExtNetworkRequest::translate(void *_ui)
void ExtNetworkRequest::initUrl()
{
auto ui = reinterpret_cast<Ui::ExtNetworkRequest *>(_ui);
m_url = QUrl(m_stringUrl);
}
void ExtNetworkRequest::translate()
{
ui->label_name->setText(i18n("Name"));
ui->label_comment->setText(i18n("Comment"));
ui->label_number->setText(i18n("Tag"));

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