diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ce76a8d..3ace2e4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,6 +91,7 @@ for more details. To avoid manual labor there is automatic cmake target named * 'true ? foo : bar' construction is allowed and recommended for one-line assignment. * Any global pointer should be assign to `nullptr` after deletion and before initialization. Exception: if object is deleted into class destructor. +* Do not use semicolon in qml files unless it is required. Comments -------- diff --git a/patches/qt5.4-qml-dialogs-qtconcurrent-and-qloggingcategory.patch b/patches/qt5.4-qml-dialogs-qtconcurrent-and-qloggingcategory.patch index bbf481c..cef8088 100644 --- a/patches/qt5.4-qml-dialogs-qtconcurrent-and-qloggingcategory.patch +++ b/patches/qt5.4-qml-dialogs-qtconcurrent-and-qloggingcategory.patch @@ -1,4 +1,4 @@ - diff --git a/sources/awesome-widget/package/contents/ui/advanced.qml b/sources/awesome-widget/package/contents/ui/advanced.qml +diff --git a/sources/awesome-widget/package/contents/ui/advanced.qml b/sources/awesome-widget/package/contents/ui/advanced.qml index 01bcd58..1ec7ba6 100644 --- a/sources/awesome-widget/package/contents/ui/advanced.qml +++ b/sources/awesome-widget/package/contents/ui/advanced.qml @@ -90,7 +90,7 @@ index 01bcd58..1ec7ba6 100644 plasmoid.configuration[key] = importConfig[key] } diff --git a/sources/awesome-widget/package/contents/ui/main.qml b/sources/awesome-widget/package/contents/ui/main.qml -index 23e9690..ec83b91 100644 +index 41abc9a..966cc43 100644 --- a/sources/awesome-widget/package/contents/ui/main.qml +++ b/sources/awesome-widget/package/contents/ui/main.qml @@ -17,7 +17,6 @@ @@ -101,7 +101,17 @@ index 23e9690..ec83b91 100644 import QtQuick.Layouts 1.1 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore -@@ -110,27 +109,6 @@ Item { +@@ -36,9 +35,6 @@ Item { + AWActions { + id: awActions + } +- BugReport { +- id: bugReport +- } + + property bool debug: awActions.isDebugEnabled() + property variant tooltipSettings: { +@@ -113,27 +109,6 @@ Item { } } @@ -129,7 +139,15 @@ index 23e9690..ec83b91 100644 Component.onCompleted: { if (debug) console.debug() -@@ -216,7 +194,12 @@ Item { +@@ -222,14 +197,18 @@ Item { + function action_reportBug() { + if (debug) console.debug() + +- bugReport.reset() +- bugReport.open() ++ awActions.showLegacyInfo() + } + function action_requestKey() { if (debug) console.debug() @@ -144,6 +162,13 @@ index 23e9690..ec83b91 100644 + awActions.sendNotification("tag", message) } } +diff --git a/sources/awesome-widget/package/contents/ui/qmldir b/sources/awesome-widget/package/contents/ui/qmldir +index b31d53f..c5315a3 100644 +--- a/sources/awesome-widget/package/contents/ui/qmldir ++++ b/sources/awesome-widget/package/contents/ui/qmldir +@@ -1,2 +1 @@ + singleton general 1.0 general.qml +-BugReport ./BugReport.qml diff --git a/sources/awesome-widget/plugin/awconfighelper.cpp b/sources/awesome-widget/plugin/awconfighelper.cpp index 6263b30..5f61d2a 100644 --- a/sources/awesome-widget/plugin/awconfighelper.cpp diff --git a/sources/awesome-widget/package/contents/ui/BugReport.qml b/sources/awesome-widget/package/contents/ui/BugReport.qml new file mode 100644 index 0000000..10f27b6 --- /dev/null +++ b/sources/awesome-widget/package/contents/ui/BugReport.qml @@ -0,0 +1,154 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Controls 1.3 as QtControls +import QtQuick.Dialogs 1.2 as QtDialogs + +import org.kde.plasma.private.awesomewidget 1.0 + + +QtDialogs.Dialog { + id: reportDialog + AWActions { + id: awActions + } + AWBugReporter { + id: awBugReporter + } + + width: 480 + height: 640 + property bool debug: awActions.isDebugEnabled() + + + title: i18n("Report a bug") + standardButtons: QtDialogs.StandardButton.Ok | QtDialogs.StandardButton.Cancel | QtDialogs.StandardButton.Reset + + QtControls.TextField { + id: title + width: parent.width + placeholderText: i18n("Report subject") + } + Column { + id: body + width: parent.width + anchors.top: title.bottom + anchors.bottom: parent.bottom + + QtControls.GroupBox { + width: parent.width + height: parent.height / 5 + title: i18n("Description") + QtControls.TextArea { + id: description + width: parent.width + height: parent.height + textFormat: TextEdit.PlainText + } + } + QtControls.GroupBox { + width: parent.width + height: parent.height / 5 + title: i18n("Steps to reproduce") + QtControls.TextArea { + id: reproduce + width: parent.width + height: parent.height + textFormat: TextEdit.PlainText + } + } + QtControls.GroupBox { + width: parent.width + height: parent.height / 5 + title: i18n("Expected result") + QtControls.TextArea { + id: expected + width: parent.width + height: parent.height + textFormat: TextEdit.PlainText + } + } + QtControls.GroupBox { + width: parent.width + height: parent.height * 2 / 5 + title: i18n("Logs") + Row { + id: debugCmdLabel + width: parent.width + QtControls.Label { + width: parent.width * 2 / 5 + horizontalAlignment: Text.AlignJustify + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + text: i18n("Use command") + } + QtControls.TextField { + id: customTime + width: parent.width * 3 / 5 + readOnly: true + text: "QT_LOGGING_RULES=*=true plasmawindowed org.kde.plasma.awesomewidget" + } + } + QtControls.Button { + id: logButton + anchors.top: debugCmdLabel.bottom + width: parent.width + text: i18n("Load log file") + onClicked: logPath.open() + } + QtControls.TextArea { + anchors.top: logButton.bottom + anchors.bottom: parent.bottom + id: logBody + width: parent.width + textFormat: TextEdit.PlainText + } + + QtDialogs.FileDialog { + id: logPath + title: i18n("Open log file") + onAccepted: + logBody.text = awActions.getFileContent(logPath.fileUrl.toString().replace("file://", "")) + } + } + } + + onAccepted: { + if (debug) console.debug() + + var text = awBugReporter.generateText(description.text, reproduce.text, + expected.text, logBody.text) + awBugReporter.sendBugReport(title.text, text) + } + + onReset: { + if (debug) console.debug() + + title.text = "" + description.text = "" + reproduce.text = "" + expected.text = "" + } + + Component.onCompleted: { + if (debug) console.debug() + + awBugReporter.doConnect() + } +} + diff --git a/sources/awesome-widget/package/contents/ui/about.qml b/sources/awesome-widget/package/contents/ui/about.qml index 6cde341..e33237d 100644 --- a/sources/awesome-widget/package/contents/ui/about.qml +++ b/sources/awesome-widget/package/contents/ui/about.qml @@ -70,7 +70,7 @@ Item { horizontalAlignment: Text.AlignLeft textFormat: Text.RichText text: awActions.getAboutText("links") - onLinkActivated: Qt.openUrlExternally(link); + onLinkActivated: Qt.openUrlExternally(link) } QtControls.Label { @@ -103,7 +103,7 @@ Item { horizontalAlignment: Text.AlignJustify textFormat: Text.RichText text: awActions.getAboutText("3rdparty") - onLinkActivated: Qt.openUrlExternally(link); + onLinkActivated: Qt.openUrlExternally(link) } QtControls.Label { @@ -114,7 +114,7 @@ Item { verticalAlignment: Text.AlignTop textFormat: Text.RichText text: awActions.getAboutText("thanks") - onLinkActivated: Qt.openUrlExternally(link); + onLinkActivated: Qt.openUrlExternally(link) } } } diff --git a/sources/awesome-widget/package/contents/ui/advanced.qml b/sources/awesome-widget/package/contents/ui/advanced.qml index d3e2549..d70eddb 100644 --- a/sources/awesome-widget/package/contents/ui/advanced.qml +++ b/sources/awesome-widget/package/contents/ui/advanced.qml @@ -288,7 +288,7 @@ Item { for (var i = 0; i < model.length; i++) { if (model[i]["name"] == plasmoid.configuration.tempUnits) { if (debug) console.info("Found", model[i]["name"], "on", i) - tempUnits.currentIndex = i; + tempUnits.currentIndex = i } } } diff --git a/sources/awesome-widget/package/contents/ui/appearance.qml b/sources/awesome-widget/package/contents/ui/appearance.qml index c0bf432..6acfa72 100644 --- a/sources/awesome-widget/package/contents/ui/appearance.qml +++ b/sources/awesome-widget/package/contents/ui/appearance.qml @@ -138,7 +138,7 @@ Item { for (var i = 0; i < model.length; i++) { if (model[i]["name"] == plasmoid.configuration.fontWeight) { if (debug) console.info("Found", model[i]["name"], "on", i) - fontWeight.currentIndex = i; + fontWeight.currentIndex = i } } } @@ -175,7 +175,7 @@ Item { for (var i = 0; i < model.length; i++) { if (model[i]["name"] == plasmoid.configuration.fontStyle) { if (debug) console.info("Found", model[i]["name"], "on", i) - fontStyle.currentIndex = i; + fontStyle.currentIndex = i } } } diff --git a/sources/awesome-widget/package/contents/ui/dataengine.qml b/sources/awesome-widget/package/contents/ui/dataengine.qml index a3b7c98..a536dee 100644 --- a/sources/awesome-widget/package/contents/ui/dataengine.qml +++ b/sources/awesome-widget/package/contents/ui/dataengine.qml @@ -93,7 +93,7 @@ Item { for (var i=0; iproject homepage") - onLinkActivated: Qt.openUrlExternally(link); + onLinkActivated: Qt.openUrlExternally(link) } Row { @@ -333,7 +336,7 @@ Item { onClicked: awFormatter.showDialog(awKeys.dictKeys(true)) } QtControls.Button { - width: parent.width * 2 / 5 + width: parent.width * 5 / 15 text: i18n("Preview") onClicked: { lock = false @@ -341,6 +344,22 @@ Item { plasmoid.configuration.queueLimit, false) } } + QtControls.Button { + width: parent.width / 15 + iconName: "view-history" + menu: QtControls.Menu { + id: historyConfig + Instantiator { + model: awTelemetryHandler.get("awwidgetconfig") + QtControls.MenuItem { + text: modelData + onTriggered: textPattern.text = modelData + } + onObjectAdded: historyConfig.insertItem(index, object) + onObjectRemoved: historyConfig.removeItem(object) + } + } + } } QtControls.TextArea { @@ -380,6 +399,6 @@ Item { compiledText.text = newText.replace(/ /g, " ") compiledText.open() - lock = true; + lock = true } } diff --git a/sources/awesome-widget/plugin/awactions.cpp b/sources/awesome-widget/plugin/awactions.cpp index 31f15bf..e87ef7f 100644 --- a/sources/awesome-widget/plugin/awactions.cpp +++ b/sources/awesome-widget/plugin/awactions.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -56,6 +57,23 @@ void AWActions::checkUpdates(const bool showAnyway) } +QString AWActions::getFileContent(const QString path) const +{ + qCDebug(LOG_AW) << "Get content from file" << path; + + QFile inputFile(path); + if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCWarning(LOG_AW) << "Could not open file as text" + << inputFile.fileName(); + return QString(); + } + + QString output = inputFile.readAll(); + inputFile.close(); + return output; +} + + // HACK: since QML could not use QLoggingCategory I need this hack bool AWActions::isDebugEnabled() const { @@ -80,6 +98,21 @@ void AWActions::showReadme() const } +void AWActions::showLegacyInfo() const +{ + QMessageBox *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) const { diff --git a/sources/awesome-widget/plugin/awactions.h b/sources/awesome-widget/plugin/awactions.h index 7185667..1c568cc 100644 --- a/sources/awesome-widget/plugin/awactions.h +++ b/sources/awesome-widget/plugin/awactions.h @@ -33,8 +33,10 @@ public: explicit AWActions(QObject *parent = nullptr); virtual ~AWActions(); Q_INVOKABLE void checkUpdates(const bool showAnyway = false); + Q_INVOKABLE QString getFileContent(const QString path) const; Q_INVOKABLE bool isDebugEnabled() const; Q_INVOKABLE bool runCmd(const QString cmd = QString("/usr/bin/true")) const; + Q_INVOKABLE void showLegacyInfo() const; Q_INVOKABLE void showReadme() const; // configuration slots Q_INVOKABLE QString getAboutText(const QString type diff --git a/sources/awesome-widget/plugin/awbugreporter.cpp b/sources/awesome-widget/plugin/awbugreporter.cpp new file mode 100644 index 0000000..fdd28be --- /dev/null +++ b/sources/awesome-widget/plugin/awbugreporter.cpp @@ -0,0 +1,163 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#include "awbugreporter.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "awdebug.h" + + +AWBugReporter::AWBugReporter(QObject *parent) + : QObject(parent) +{ + qCDebug(LOG_AW) << __PRETTY_FUNCTION__; +} + + +AWBugReporter::~AWBugReporter() +{ + qCDebug(LOG_AW) << __PRETTY_FUNCTION__; +} + + +void AWBugReporter::doConnect() +{ + // additional method for testing needs + connect(this, SIGNAL(replyReceived(const int, const QString)), this, + SLOT(showInformation(const int, const QString))); +} + + +QString AWBugReporter::generateText(const QString description, + const QString reproduce, + const QString expected, + const QString logs) const +{ + // do not log logs here, it may have quite large size + qCDebug(LOG_AW) << "Generate text with description" << description + << "steps" << reproduce << "and expected result" + << expected; + + QString output; + output += QString("**Description**\n\n%1\n\n").arg(description); + output += QString("**Step to reproduce**\n\n%1\n\n").arg(reproduce); + output += QString("**Expected result**\n\n%1\n\n").arg(expected); + output += QString("**Version**\n\n%1\n\n") + .arg(getBuildData().join(QString("\n"))); + // append logs + output += QString("**Logs**\n\n%1").arg(logs); + + return output; +} + + +void AWBugReporter::sendBugReport(const QString title, const QString body) +{ + qCDebug(LOG_AW) << "Send bug report with title" << title << "and body" + << body; + + QNetworkAccessManager *manager = new QNetworkAccessManager(nullptr); + connect(manager, SIGNAL(finished(QNetworkReply *)), this, + SLOT(issueReplyRecieved(QNetworkReply *))); + + QNetworkRequest request(QUrl(BUGTRACKER_API)); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + // generate payload + QVariantMap payload; + payload[QString("title")] = title; + payload[QString("body")] = body; + payload[QString("labels")] = QStringList() << QString("from application"); + // convert to QByteArray to send request + QByteArray data + = QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact); + qCInfo(LOG_AW) << "Send request with body" << data.data() << "and size" + << data.size(); + + manager->post(request, data); +} + + +void AWBugReporter::issueReplyRecieved(QNetworkReply *reply) +{ + if (reply->error() != QNetworkReply::NoError) { + qCWarning(LOG_AW) << "An error occurs" << reply->error() + << "with message" << reply->errorString(); + return emit(replyReceived(0, QString())); + } + + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error); + if (error.error != QJsonParseError::NoError) { + qCWarning(LOG_AW) << "Parse error" << error.errorString(); + return emit(replyReceived(0, QString())); + } + reply->deleteLater(); + + // convert to map + QVariantMap response = jsonDoc.toVariant().toMap(); + QString url = response[QString("html_url")].toString(); + int number = response[QString("number")].toInt(); + + return emit(replyReceived(number, url)); +} + + +void AWBugReporter::showInformation(const int number, const QString url) +{ + qCDebug(LOG_AW) << "Created issue with number" << number << "and url" + << url; + + // cache url first + m_lastBugUrl = url; + + QMessageBox *msgBox = new QMessageBox(nullptr); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->setModal(false); + msgBox->setWindowTitle(i18n("Issue created")); + msgBox->setText(i18n("Issue %1 has been created", number)); + msgBox->setStandardButtons(QMessageBox::Open | QMessageBox::Close); + msgBox->setIcon(QMessageBox::Information); + + msgBox->open(this, SLOT(userReplyOnBugReport(QAbstractButton *))); +} + + +void AWBugReporter::userReplyOnBugReport(QAbstractButton *button) +{ + QMessageBox::ButtonRole ret + = static_cast(sender())->buttonRole(button); + qCInfo(LOG_AW) << "User select" << ret; + + switch (ret) { + case QMessageBox::AcceptRole: + QDesktopServices::openUrl(m_lastBugUrl); + break; + case QMessageBox::RejectRole: + default: + break; + } +} diff --git a/sources/awesome-widget/plugin/awbugreporter.h b/sources/awesome-widget/plugin/awbugreporter.h new file mode 100644 index 0000000..a241a2c --- /dev/null +++ b/sources/awesome-widget/plugin/awbugreporter.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#ifndef AWBUGREPORTER_H +#define AWBUGREPORTER_H + +#include + + +class QAbstractButton; +class QNetworkReply; + +class AWBugReporter : public QObject +{ + Q_OBJECT + +public: + explicit AWBugReporter(QObject *parent = nullptr); + virtual ~AWBugReporter(); + Q_INVOKABLE void doConnect(); + Q_INVOKABLE QString generateText(const QString description, + const QString reproduce, + const QString expected, + const QString logs) const; + Q_INVOKABLE void sendBugReport(const QString title, const QString body); + +signals: + void replyReceived(const int number, const QString url); + +private slots: + void issueReplyRecieved(QNetworkReply *reply); + void showInformation(const int number, const QString url); + void userReplyOnBugReport(QAbstractButton *button); + +private: + QString m_lastBugUrl; +}; + + +#endif /* AWBUGREPORTER_H */ diff --git a/sources/awesome-widget/plugin/awdataaggregator.cpp b/sources/awesome-widget/plugin/awdataaggregator.cpp index 805ccec..89f910c 100644 --- a/sources/awesome-widget/plugin/awdataaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataaggregator.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.cpp b/sources/awesome-widget/plugin/awdataengineaggregator.cpp index 9148b73..62bbbda 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.cpp +++ b/sources/awesome-widget/plugin/awdataengineaggregator.cpp @@ -17,6 +17,8 @@ #include "awdataengineaggregator.h" +#include + #include "awdebug.h" #include "awkeys.h" @@ -25,6 +27,9 @@ AWDataEngineAggregator::AWDataEngineAggregator(QObject *parent) : QObject(parent) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + + // required to define Qt::QueuedConnection for signal-slot connection + qRegisterMetaType("Plasma::DataEngine::Data"); } @@ -98,4 +103,39 @@ void AWDataEngineAggregator::reconnectSources(const int interval) m_dataEngines[QString("extsysmon")]->connectAllSources(parent(), interval); m_dataEngines[QString("time")]->connectSource(QString("Local"), parent(), 1000); + +#ifdef BUILD_FUTURE + createQueuedConnection(); +#endif /* BUILD_FUTURE */ +} + + +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; + if (dataEngine == QString("time")) + sources.append(QString("Local")); + else + sources = 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); + } + } } diff --git a/sources/awesome-widget/plugin/awdataengineaggregator.h b/sources/awesome-widget/plugin/awdataengineaggregator.h index 11afab3..fb4bfe8 100644 --- a/sources/awesome-widget/plugin/awdataengineaggregator.h +++ b/sources/awesome-widget/plugin/awdataengineaggregator.h @@ -44,6 +44,7 @@ public slots: void reconnectSources(const int interval); private: + void createQueuedConnection(); Plasma::DataEngineConsumer *m_consumer = nullptr; QHash m_dataEngines; }; diff --git a/sources/awesome-widget/plugin/awesomewidget.cpp b/sources/awesome-widget/plugin/awesomewidget.cpp index e327c47..a4828b3 100644 --- a/sources/awesome-widget/plugin/awesomewidget.cpp +++ b/sources/awesome-widget/plugin/awesomewidget.cpp @@ -20,9 +20,11 @@ #include #include "awactions.h" +#include "awbugreporter.h" #include "awconfighelper.h" #include "awformatterconfigfactory.h" #include "awkeys.h" +#include "awtelemetryhandler.h" void AWPlugin::registerTypes(const char *uri) @@ -30,8 +32,10 @@ void AWPlugin::registerTypes(const char *uri) Q_ASSERT(uri == QLatin1String("org.kde.plasma.private.awesomewidget")); qmlRegisterType(uri, 1, 0, "AWActions"); + qmlRegisterType(uri, 1, 0, "AWBugReporter"); qmlRegisterType(uri, 1, 0, "AWConfigHelper"); qmlRegisterType(uri, 1, 0, "AWFormatterConfigFactory"); qmlRegisterType(uri, 1, 0, "AWKeys"); + qmlRegisterType(uri, 1, 0, "AWTelemetryHandler"); } diff --git a/sources/awesome-widget/plugin/awkeyoperations.cpp b/sources/awesome-widget/plugin/awkeyoperations.cpp index 9388053..f1b11c1 100644 --- a/sources/awesome-widget/plugin/awkeyoperations.cpp +++ b/sources/awesome-widget/plugin/awkeyoperations.cpp @@ -79,30 +79,24 @@ QStringList AWKeyOperations::dictKeys() const { QStringList allKeys; // weather - for (int i = m_extWeather->activeItems().count() - 1; i >= 0; i--) { - allKeys.append( - m_extWeather->activeItems().at(i)->tag(QString("weatherId"))); - allKeys.append( - m_extWeather->activeItems().at(i)->tag(QString("weather"))); - allKeys.append( - m_extWeather->activeItems().at(i)->tag(QString("humidity"))); - allKeys.append( - m_extWeather->activeItems().at(i)->tag(QString("pressure"))); - allKeys.append( - m_extWeather->activeItems().at(i)->tag(QString("temperature"))); - allKeys.append( - m_extWeather->activeItems().at(i)->tag(QString("timestamp"))); + for (auto item : m_extWeather->activeItems()) { + allKeys.append(item->tag(QString("weatherId"))); + allKeys.append(item->tag(QString("weather"))); + allKeys.append(item->tag(QString("humidity"))); + allKeys.append(item->tag(QString("pressure"))); + allKeys.append(item->tag(QString("temperature"))); + allKeys.append(item->tag(QString("timestamp"))); } // cpuclock & cpu - for (int i = QThread::idealThreadCount() - 1; i >= 0; 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 (int i = m_devices[QString("temp")].count() - 1; i >= 0; i--) + for (int i = 0; i < m_devices[QString("temp")].count(); i++) allKeys.append(QString("temp%1").arg(i)); // hdd - for (int i = m_devices[QString("mount")].count() - 1; i >= 0; i--) { + for (int i = 0; i < m_devices[QString("mount")].count(); i++) { allKeys.append(QString("hddmb%1").arg(i)); allKeys.append(QString("hddgb%1").arg(i)); allKeys.append(QString("hddfreemb%1").arg(i)); @@ -112,15 +106,15 @@ QStringList AWKeyOperations::dictKeys() const allKeys.append(QString("hdd%1").arg(i)); } // hdd speed - for (int i = m_devices[QString("disk")].count() - 1; i >= 0; i--) { + for (int i = 0; i < m_devices[QString("disk")].count(); i++) { allKeys.append(QString("hddr%1").arg(i)); allKeys.append(QString("hddw%1").arg(i)); } // hdd temp - for (int i = m_devices[QString("hdd")].count() - 1; i >= 0; i--) + for (int i = 0; i < m_devices[QString("hdd")].count(); i++) allKeys.append(QString("hddtemp%1").arg(i)); // network - for (int i = m_devices[QString("net")].count() - 1; i >= 0; i--) { + for (int i = 0; i < m_devices[QString("net")].count(); i++) { allKeys.append(QString("downunits%1").arg(i)); allKeys.append(QString("upunits%1").arg(i)); allKeys.append(QString("downtotalkb%1").arg(i)); @@ -137,43 +131,38 @@ QStringList AWKeyOperations::dictKeys() const = QDir(QString("/sys/class/power_supply")) .entryList(QStringList() << QString("BAT*"), QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); - for (int i = allBatteryDevices.count() - 1; i >= 0; i--) + for (int i = 0; i < allBatteryDevices.count(); i++) allKeys.append(QString("bat%1").arg(i)); // package manager - for (int i = m_extUpgrade->activeItems().count() - 1; i >= 0; i--) - allKeys.append( - m_extUpgrade->activeItems().at(i)->tag(QString("pkgcount"))); + for (auto item : m_extUpgrade->activeItems()) + allKeys.append(item->tag(QString("pkgcount"))); // quotes - for (int i = m_extQuotes->activeItems().count() - 1; i >= 0; i--) { - allKeys.append(m_extQuotes->activeItems().at(i)->tag(QString("ask"))); - allKeys.append( - m_extQuotes->activeItems().at(i)->tag(QString("askchg"))); - allKeys.append( - m_extQuotes->activeItems().at(i)->tag(QString("percaskchg"))); - allKeys.append(m_extQuotes->activeItems().at(i)->tag(QString("bid"))); - allKeys.append( - m_extQuotes->activeItems().at(i)->tag(QString("bidchg"))); - allKeys.append( - m_extQuotes->activeItems().at(i)->tag(QString("percbidchg"))); - allKeys.append(m_extQuotes->activeItems().at(i)->tag(QString("price"))); - allKeys.append( - m_extQuotes->activeItems().at(i)->tag(QString("pricechg"))); - allKeys.append( - m_extQuotes->activeItems().at(i)->tag(QString("percpricechg"))); + for (auto item : m_extQuotes->activeItems()) { + allKeys.append(item->tag(QString("ask"))); + allKeys.append(item->tag(QString("askchg"))); + allKeys.append(item->tag(QString("percaskchg"))); + allKeys.append(item->tag(QString("bid"))); + allKeys.append(item->tag(QString("bidchg"))); + allKeys.append(item->tag(QString("percbidchg"))); + allKeys.append(item->tag(QString("price"))); + allKeys.append(item->tag(QString("pricechg"))); + allKeys.append(item->tag(QString("percpricechg"))); } // custom - for (int i = m_extScripts->activeItems().count() - 1; i >= 0; i--) - allKeys.append( - m_extScripts->activeItems().at(i)->tag(QString("custom"))); + for (auto item : m_extScripts->activeItems()) + allKeys.append(item->tag(QString("custom"))); // bars - for (int i = m_graphicalItems->activeItems().count() - 1; i >= 0; i--) - allKeys.append( - m_graphicalItems->activeItems().at(i)->tag(QString("bar"))); + for (auto item : m_graphicalItems->activeItems()) + allKeys.append(item->tag(QString("bar"))); // static keys QStringList staticKeys = QString(STATIC_KEYS).split(QChar(',')); std::for_each(staticKeys.cbegin(), staticKeys.cend(), [&allKeys](const QString &key) { allKeys.append(key); }); + // sort in valid order + allKeys.sort(); + std::reverse(allKeys.begin(), allKeys.end()); + return allKeys; } diff --git a/sources/awesome-widget/plugin/awkeysaggregator.cpp b/sources/awesome-widget/plugin/awkeysaggregator.cpp index 6d25922..184cc04 100644 --- a/sources/awesome-widget/plugin/awkeysaggregator.cpp +++ b/sources/awesome-widget/plugin/awkeysaggregator.cpp @@ -32,6 +32,10 @@ AWKeysAggregator::AWKeysAggregator(QObject *parent) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + // sort time keys + m_timeKeys.sort(); + std::reverse(m_timeKeys.begin(), m_timeKeys.end()); + // default formatters // memory m_formatter[QString("mem")] = FormatterType::Float; diff --git a/sources/awesome-widget/plugin/awtelemetryhandler.cpp b/sources/awesome-widget/plugin/awtelemetryhandler.cpp new file mode 100644 index 0000000..19b5345 --- /dev/null +++ b/sources/awesome-widget/plugin/awtelemetryhandler.cpp @@ -0,0 +1,224 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + +#include "awtelemetryhandler.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "awdebug.h" + + +AWTelemetryHandler::AWTelemetryHandler(QObject *parent, const QString clientId) + : QObject(parent) +{ + qCDebug(LOG_AW) << __PRETTY_FUNCTION__; + + m_genericConfig = QString("%1/awesomewidgets/general.ini") + .arg(QStandardPaths::writableLocation( + QStandardPaths::GenericDataLocation)); + m_localFile = QString("%1/awesomewidgets/telemetry.ini") + .arg(QStandardPaths::writableLocation( + QStandardPaths::GenericDataLocation)); + + init(); + // override client id if any + if (!clientId.isEmpty()) + m_clientId = clientId; +} + + +AWTelemetryHandler::~AWTelemetryHandler() +{ + qCDebug(LOG_AW) << __PRETTY_FUNCTION__; +} + + +QStringList AWTelemetryHandler::get(const QString group) const +{ + qCDebug(LOG_AW) << "Get stored data for group" << group; + + QStringList values; + + QSettings settings(m_localFile, QSettings::IniFormat); + settings.beginGroup(group); + for (auto key : settings.childKeys()) + values.append(settings.value(key).toString()); + settings.endGroup(); + + return values; +} + + +QString AWTelemetryHandler::getLast(const QString group) const +{ + qCDebug(LOG_AW) << "Get last stored data for group" << group; + + return get(group).last(); +} + + +bool AWTelemetryHandler::put(const QString group, const QString value) const +{ + qCDebug(LOG_AW) << "Store data with group" << group << "and value" << value; + + QSettings settings(m_localFile, QSettings::IniFormat); + settings.beginGroup(group); + // values will be stored as num=value inside specified group + // load all values to memory + QStringList saved; + for (auto key : settings.childKeys()) + saved.append(settings.value(key).toString()); + // check if this value is already saved + if (saved.contains(value)) { + qCInfo(LOG_AW) << "Configuration" << value << "for group" << group + << "is already saved"; + return false; + } + saved.append(value); + // remove old ones + while (saved.count() > m_storeCount) + saved.takeFirst(); + // clear group + settings.remove(QString("")); + // and save now + for (auto value : saved) { + QString key = getKey(settings.childKeys().count()); + settings.setValue(key, value); + } + + // sync settings + settings.endGroup(); + settings.sync(); + // return status + return (settings.status() == QSettings::NoError); +} + + +void AWTelemetryHandler::uploadTelemetry(const QString group, + const QString value) +{ + qCDebug(LOG_AW) << "Upload data with group" << group << "and value" + << value; + if (!m_uploadEnabled) { + qCInfo(LOG_AW) << "Upload disabled by configuration"; + return; + } + + QNetworkAccessManager *manager = new QNetworkAccessManager(nullptr); + connect(manager, SIGNAL(finished(QNetworkReply *)), this, + SLOT(telemetryReplyRecieved(QNetworkReply *))); + + QUrl url(REMOTE_TELEMETRY_URL); + url.setPort(REMOTE_TELEMETRY_PORT); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + // generate payload + QVariantMap payload; + payload[QString("api")] = AWTEAPI; + payload[QString("client_id")] = m_clientId; + payload[QString("metadata")] = value; + payload[QString("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[QString("message")].toString(); + qCInfo(LOG_AW) << "Server reply on telemetry" << message; + + return emit(replyReceived(message)); +} + + +QString AWTelemetryHandler::getKey(const int count) const +{ + qCDebug(LOG_AW) << "Get key for keys count" << count; + + return QString("%1").arg(count, 3, 10, QChar('0')); +} + + +void AWTelemetryHandler::init() +{ + QSettings settings(m_genericConfig, QSettings::IniFormat); + settings.beginGroup(QString("Telemetry")); + + // unique client id + m_clientId + = settings.value(QString("ClientID"), QUuid::createUuid().toString()) + .toString(); + setConfiguration(QString("ClientID"), m_clientId, false); + // count items to store + m_storeCount = settings.value(QString("StoreHistory"), 100).toInt(); + setConfiguration(QString("StoreHistory"), m_storeCount, false); + // check if upload enabled + m_uploadEnabled = settings.value(QString("Upload"), false).toBool(); + setConfiguration(QString("Upload"), m_uploadEnabled, false); + + settings.endGroup(); +} + + +bool AWTelemetryHandler::setConfiguration(const QString key, + const QVariant value, + const bool override) const +{ + qCDebug(LOG_AW) << "Set configuration key" << key << "to value" << value + << "force override enabled" << override; + + QSettings settings(m_genericConfig, QSettings::IniFormat); + settings.beginGroup(QString("Telemetry")); + if (settings.childKeys().contains(key) && !override) + return true; + + settings.setValue(key, value); + settings.endGroup(); + settings.sync(); + + return (settings.status() == QSettings::NoError); +} diff --git a/sources/awesome-widget/plugin/awtelemetryhandler.h b/sources/awesome-widget/plugin/awtelemetryhandler.h new file mode 100644 index 0000000..f8b11a0 --- /dev/null +++ b/sources/awesome-widget/plugin/awtelemetryhandler.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#ifndef AWTELEMETRYHANDLER_H +#define AWTELEMETRYHANDLER_H + +#include +#include + + +class QAbstractButton; +class QNetworkReply; + +class AWTelemetryHandler : public QObject +{ + Q_OBJECT + +public: + const char *REMOTE_TELEMETRY_URL = "http://arcanis.me/telemetry"; + const int REMOTE_TELEMETRY_PORT = 8080; + + explicit AWTelemetryHandler(QObject *parent = nullptr, + const QString clientId = QString()); + virtual ~AWTelemetryHandler(); + Q_INVOKABLE QStringList get(const QString group) const; + Q_INVOKABLE QString getLast(const QString group) const; + Q_INVOKABLE bool put(const QString group, const QString value) const; + Q_INVOKABLE void uploadTelemetry(const QString group, const QString value); + +signals: + void replyReceived(QString message); + +private slots: + void telemetryReplyRecieved(QNetworkReply *reply); + +private: + QString getKey(const int count) const; + void init(); + bool setConfiguration(const QString key, const QVariant value, + const bool override) const; + QString m_clientId; + QString m_genericConfig; + QString m_localFile; + int m_storeCount = 0; + bool m_uploadEnabled = false; +}; + + +#endif /* AWTELEMETRYHANDLER_H */ diff --git a/sources/awesome-widget/plugin/awupdatehelper.cpp b/sources/awesome-widget/plugin/awupdatehelper.cpp index bd9c59a..37becf3 100644 --- a/sources/awesome-widget/plugin/awupdatehelper.cpp +++ b/sources/awesome-widget/plugin/awupdatehelper.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include "awdebug.h" @@ -145,13 +144,16 @@ void AWUpdateHelper::userReplyOnUpdates(QAbstractButton *button) void AWUpdateHelper::versionReplyRecieved(QNetworkReply *reply, const bool showAnyway) { - qCDebug(LOG_AW) << "Return code" << reply->error() << "with message" - << reply->errorString() << "and show anyway" << showAnyway; + qCDebug(LOG_AW) << "Show message anyway" << showAnyway; + 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 ((reply->error() != QNetworkReply::NoError) - || (error.error != QJsonParseError::NoError)) { + if (error.error != QJsonParseError::NoError) { qCWarning(LOG_AW) << "Parse error" << error.errorString(); return; } diff --git a/sources/awesomewidgets/extquotes.cpp b/sources/awesomewidgets/extquotes.cpp index aead4a3..de54b63 100644 --- a/sources/awesomewidgets/extquotes.cpp +++ b/sources/awesomewidgets/extquotes.cpp @@ -188,15 +188,17 @@ void ExtQuotes::writeConfiguration() const void ExtQuotes::quotesReplyReceived(QNetworkReply *reply) { - qCDebug(LOG_LIB) << "Return code" << reply->error() << "with message" - << reply->errorString(); + if (reply->error() != QNetworkReply::NoError) { + qCWarning(LOG_AW) << "An error occurs" << reply->error() + << "with message" << reply->errorString(); + return; + } m_isRunning = false; QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error); reply->deleteLater(); - if ((reply->error() != QNetworkReply::NoError) - || (error.error != QJsonParseError::NoError)) { + if (error.error != QJsonParseError::NoError) { qCWarning(LOG_LIB) << "Parse error" << error.errorString(); return; } diff --git a/sources/awesomewidgets/extweather.cpp b/sources/awesomewidgets/extweather.cpp index 3035efa..75da21d 100644 --- a/sources/awesomewidgets/extweather.cpp +++ b/sources/awesomewidgets/extweather.cpp @@ -336,15 +336,17 @@ void ExtWeather::writeConfiguration() const void ExtWeather::weatherReplyReceived(QNetworkReply *reply) { - qCDebug(LOG_LIB) << "Return code" << reply->error() << "with message" - << reply->errorString(); + if (reply->error() != QNetworkReply::NoError) { + qCWarning(LOG_AW) << "An error occurs" << reply->error() + << "with message" << reply->errorString(); + return; + } m_isRunning = false; QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error); reply->deleteLater(); - if ((reply->error() != QNetworkReply::NoError) - || (error.error != QJsonParseError::NoError)) { + if (error.error != QJsonParseError::NoError) { qCWarning(LOG_LIB) << "Parse error" << error.errorString(); return; } diff --git a/sources/desktop-panel/package/contents/ui/about.qml b/sources/desktop-panel/package/contents/ui/about.qml index ba648f7..723dea3 100644 --- a/sources/desktop-panel/package/contents/ui/about.qml +++ b/sources/desktop-panel/package/contents/ui/about.qml @@ -71,7 +71,7 @@ Item { horizontalAlignment: Text.AlignLeft textFormat: Text.RichText text: dpAdds.getAboutText("links") - onLinkActivated: Qt.openUrlExternally(link); + onLinkActivated: Qt.openUrlExternally(link) } QtControls.Label { @@ -104,7 +104,7 @@ Item { horizontalAlignment: Text.AlignJustify textFormat: Text.RichText text: dpAdds.getAboutText("3rdparty") - onLinkActivated: Qt.openUrlExternally(link); + onLinkActivated: Qt.openUrlExternally(link) } QtControls.Label { @@ -115,7 +115,7 @@ Item { verticalAlignment: Text.AlignTop textFormat: Text.RichText text: dpAdds.getAboutText("thanks") - onLinkActivated: Qt.openUrlExternally(link); + onLinkActivated: Qt.openUrlExternally(link) } } } diff --git a/sources/desktop-panel/package/contents/ui/activeapp.qml b/sources/desktop-panel/package/contents/ui/activeapp.qml index 64009c7..865352d 100644 --- a/sources/desktop-panel/package/contents/ui/activeapp.qml +++ b/sources/desktop-panel/package/contents/ui/activeapp.qml @@ -138,7 +138,7 @@ Item { for (var i = 0; i < model.length; i++) { if (model[i]["name"] == plasmoid.configuration.currentFontWeight) { if (debug) console.info("Found", model[i]["name"], "on", i) - fontWeight.currentIndex = i; + fontWeight.currentIndex = i } } } @@ -175,7 +175,7 @@ Item { for (var i = 0; i < model.length; i++) { if (model[i]["name"] == plasmoid.configuration.currentFontStyle) { if (debug) console.info("Found", model[i]["name"], "on", i) - fontStyle.currentIndex = i; + fontStyle.currentIndex = i } } } diff --git a/sources/desktop-panel/package/contents/ui/advanced.qml b/sources/desktop-panel/package/contents/ui/advanced.qml index 684fd15..256281f 100644 --- a/sources/desktop-panel/package/contents/ui/advanced.qml +++ b/sources/desktop-panel/package/contents/ui/advanced.qml @@ -188,7 +188,7 @@ Item { for (var i = 0; i < model.length; i++) { if (model[i]["name"] == plasmoid.configuration.tooltipType) { if (debug) console.info("Found", model[i]["name"], "on", i) - tooltipType.currentIndex = i; + tooltipType.currentIndex = i } } } diff --git a/sources/desktop-panel/package/contents/ui/inactiveapp.qml b/sources/desktop-panel/package/contents/ui/inactiveapp.qml index 09ad20d..391240a 100644 --- a/sources/desktop-panel/package/contents/ui/inactiveapp.qml +++ b/sources/desktop-panel/package/contents/ui/inactiveapp.qml @@ -138,7 +138,7 @@ Item { for (var i = 0; i < model.length; i++) { if (model[i]["name"] == plasmoid.configuration.fontWeight) { if (debug) console.info("Found", model[i]["name"], "on", i) - fontWeight.currentIndex = i; + fontWeight.currentIndex = i } } } @@ -175,7 +175,7 @@ Item { for (var i = 0; i < model.length; i++) { if (model[i]["name"] == plasmoid.configuration.fontStyle) { if (debug) console.info("Found", model[i]["name"], "on", i) - fontStyle.currentIndex = i; + fontStyle.currentIndex = i } } } diff --git a/sources/desktop-panel/package/contents/ui/main.qml b/sources/desktop-panel/package/contents/ui/main.qml index 20f8732..40efb02 100644 --- a/sources/desktop-panel/package/contents/ui/main.qml +++ b/sources/desktop-panel/package/contents/ui/main.qml @@ -83,7 +83,7 @@ Item { MouseArea { hoverEnabled: true anchors.fill: parent - onClicked: dpAdds.setCurrentDesktop(index + 1); + onClicked: dpAdds.setCurrentDesktop(index + 1) onEntered: needTooltipUpdate() } diff --git a/sources/desktop-panel/package/contents/ui/widget.qml b/sources/desktop-panel/package/contents/ui/widget.qml index 77cd05c..5f235ce 100644 --- a/sources/desktop-panel/package/contents/ui/widget.qml +++ b/sources/desktop-panel/package/contents/ui/widget.qml @@ -48,7 +48,7 @@ Item { verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap text: i18n("Detailed information may be found on project homepage") - onLinkActivated: Qt.openUrlExternally(link); + onLinkActivated: Qt.openUrlExternally(link) } Row { diff --git a/sources/extsysmonsources/batterysource.cpp b/sources/extsysmonsources/batterysource.cpp index 1f2e337..22d1fbf 100644 --- a/sources/extsysmonsources/batterysource.cpp +++ b/sources/extsysmonsources/batterysource.cpp @@ -103,7 +103,7 @@ void BatterySource::run() { // adaptor QFile acFile(QString("%1/AC/online").arg(m_acpiPath)); - if (acFile.open(QIODevice::ReadOnly)) + if (acFile.open(QIODevice::ReadOnly | QIODevice::Text)) m_values[QString("battery/ac")] = (QString(acFile.readLine()).trimmed().toInt() == 1); acFile.close(); @@ -116,8 +116,8 @@ void BatterySource::run() QString("%1/BAT%2/energy_now").arg(m_acpiPath).arg(i)); QFile fullLevelFile( QString("%1/BAT%2/energy_full").arg(m_acpiPath).arg(i)); - if ((currentLevelFile.open(QIODevice::ReadOnly)) - && (fullLevelFile.open(QIODevice::ReadOnly))) { + if ((currentLevelFile.open(QIODevice::ReadOnly | QIODevice::Text)) + && (fullLevelFile.open(QIODevice::ReadOnly | QIODevice::Text))) { float batCurrent = QString(currentLevelFile.readLine()).trimmed().toFloat(); float batFull diff --git a/sources/extsysmonsources/gpuloadsource.cpp b/sources/extsysmonsources/gpuloadsource.cpp index 482c468..dcefab8 100644 --- a/sources/extsysmonsources/gpuloadsource.cpp +++ b/sources/extsysmonsources/gpuloadsource.cpp @@ -56,10 +56,14 @@ QString GPULoadSource::autoGpu() { QString gpu = QString("disable"); QFile moduleFile(QString("/proc/modules")); - if (!moduleFile.open(QIODevice::ReadOnly)) + if (!moduleFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCWarning(LOG_AW) << "Could not open file as text" + << moduleFile.fileName(); return gpu; + } QString output = moduleFile.readAll(); + moduleFile.close(); if (output.contains(QString("fglrx"))) gpu = QString("ati"); else if (output.contains(QString("nvidia"))) diff --git a/sources/extsysmonsources/gputempsource.cpp b/sources/extsysmonsources/gputempsource.cpp index 437c143..17f607e 100644 --- a/sources/extsysmonsources/gputempsource.cpp +++ b/sources/extsysmonsources/gputempsource.cpp @@ -57,10 +57,14 @@ QString GPUTemperatureSource::autoGpu() { QString gpu = QString("disable"); QFile moduleFile(QString("/proc/modules")); - if (!moduleFile.open(QIODevice::ReadOnly)) + if (!moduleFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCWarning(LOG_AW) << "Could not open file as text" + << moduleFile.fileName(); return gpu; + } QString output = moduleFile.readAll(); + moduleFile.close(); if (output.contains(QString("fglrx"))) gpu = QString("ati"); else if (output.contains(QString("nvidia"))) diff --git a/sources/extsysmonsources/processessource.cpp b/sources/extsysmonsources/processessource.cpp index 7cdcdf3..63fe151 100644 --- a/sources/extsysmonsources/processessource.cpp +++ b/sources/extsysmonsources/processessource.cpp @@ -87,15 +87,17 @@ void ProcessesSource::run() for (auto dir : directories) { QFile statusFile(QString("/proc/%1/status").arg(dir)); - if (!statusFile.open(QIODevice::ReadOnly)) + if (!statusFile.open(QIODevice::ReadOnly | QIODevice::Text)) continue; QFile cmdFile(QString("/proc/%1/cmdline").arg(dir)); - if (!cmdFile.open(QIODevice::ReadOnly)) + if (!cmdFile.open(QIODevice::ReadOnly | QIODevice::Text)) continue; QString output = statusFile.readAll(); if (output.contains(QString("running"))) running.append(cmdFile.readAll()); + statusFile.close(); + cmdFile.close(); } m_values[QString("ps/running/count")] = running.count(); diff --git a/sources/test/CMakeLists.txt b/sources/test/CMakeLists.txt index c2821a5..2a903bf 100644 --- a/sources/test/CMakeLists.txt +++ b/sources/test/CMakeLists.txt @@ -16,7 +16,7 @@ include_directories( ${Kf5_INCLUDE} ) -## library +# library set(AWTESTLIBRARY_HEADERS awtestlibrary.h) set(AWTESTLIBRARY_SOURCES awtestlibrary.cpp) add_library(${SUBPROJECT}-awtest STATIC ${AWTESTLIBRARY_SOURCES} ${AWTESTLIBRARY_HEADERS}) @@ -24,18 +24,20 @@ target_link_libraries(${SUBPROJECT}-awtest ${Qt_LIBRARIES} ${Qt5Test_LIBRARIES}) set(LIBRARY_TEST_SET ${SUBPROJECT}-awtest ${PROJECT_LIBRARY} ${PROJECT_MONITORSOURCES} ${Qt_LIBRARIES} ${Kf5_LIBRARIES} ${Qt5Test_LIBRARIES}) -## modules +# modules set(TEST_MODULES abstractextitem extquotes extscript extupgrade extweather abstractformatter datetimeformatter floatformatter listformatter noformatter scriptformatter stringformatter extitemaggregator batterysource desktopsource gpuloadsource gputempsource hddtempsource networksource playersource processessource - awconfighelper awkeycache awkeys awpatternfunctions awupdatehelper + awbugreporter awconfighelper awkeycache awkeys awpatternfunctions awtelemetryhandler awupdatehelper dpplugin) foreach (TEST_MODULE ${TEST_MODULES}) set(${TEST_MODULE}_HEADERS test${TEST_MODULE}.h) set(${TEST_MODULE}_SOURCES test${TEST_MODULE}.cpp) - if (TEST_MODULE MATCHES "awconfighelper") + if (TEST_MODULE MATCHES "awbugreporter") + set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awbugreporter.cpp) + elseif (TEST_MODULE MATCHES "awconfighelper") set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awconfighelper.cpp) elseif (TEST_MODULE MATCHES "awkeycache") set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awkeycache.cpp) @@ -55,13 +57,17 @@ foreach (TEST_MODULE ${TEST_MODULES}) set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awformatterhelper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awkeysaggregator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awpatternfunctions.cpp) + elseif (TEST_MODULE MATCHES "awtelemetryhandler") + set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awtelemetryhandler.cpp) elseif (TEST_MODULE MATCHES "awupdatehelper") set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../awesome-widget/plugin/awupdatehelper.cpp) elseif (TEST_MODULE MATCHES "dpplugin") set(${TEST_MODULE}_SOURCES ${${TEST_MODULE}_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../desktop-panel/plugin/dpadds.cpp ${PROJECT_TRDPARTY_DIR}/fontdialog/fontdialog.cpp) - endif (TEST_MODULE MATCHES "awconfighelper") + endif (TEST_MODULE MATCHES "awbugreporter") add_executable(${SUBPROJECT}-${TEST_MODULE} ${${TEST_MODULE}_HEADERS} ${${TEST_MODULE}_SOURCES}) target_link_libraries(${SUBPROJECT}-${TEST_MODULE} ${LIBRARY_TEST_SET}) - add_test(NAME ${TEST_MODULE} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT}-${TEST_MODULE}) + if (NOT TEST_MODULE MATCHES "awbugreporter") + add_test(NAME ${TEST_MODULE} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT}-${TEST_MODULE}) + endif (NOT TEST_MODULE MATCHES "awbugreporter") endforeach (TEST_MODULE) diff --git a/sources/test/testawbugreporter.cpp b/sources/test/testawbugreporter.cpp new file mode 100644 index 0000000..a2c116d --- /dev/null +++ b/sources/test/testawbugreporter.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#include "testawbugreporter.h" + +#include + +#include "awbugreporter.h" +#include "awtestlibrary.h" + + +void TestAWBugReporter::initTestCase() +{ + plugin = new AWBugReporter(this); +} + + +void TestAWBugReporter::cleanupTestCase() +{ + delete plugin; +} + + +void TestAWBugReporter::test_generateText() +{ + data = AWTestLibrary::randomStringList(4); + QString output + = plugin->generateText(data.at(0), data.at(1), data.at(2), data.at(3)); + + for (auto string : data) + QVERIFY(output.contains(string)); +} + + +void TestAWBugReporter::test_sendBugReport() +{ + QSignalSpy spy(plugin, SIGNAL(replyReceived(bool, QString))); + plugin->sendBugReport( + AWTestLibrary::randomString(), + plugin->generateText(data.at(0), data.at(1), data.at(2), data.at(3))); + + QVERIFY(spy.wait(5000)); + QVariantList arguments = spy.takeFirst(); + + QVERIFY(arguments.at(0).toInt() > 0); + QVERIFY(!arguments.at(1).toString().isEmpty()); +} + + +QTEST_MAIN(TestAWBugReporter); diff --git a/sources/test/testawbugreporter.h b/sources/test/testawbugreporter.h new file mode 100644 index 0000000..4a02f98 --- /dev/null +++ b/sources/test/testawbugreporter.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#ifndef TESTAWBUGREPORTER_H +#define TESTAWBUGREPORTER_H + +#include + + +class AWBugReporter; + +class TestAWBugReporter : public QObject +{ + Q_OBJECT + +private slots: + // initialization + void initTestCase(); + void cleanupTestCase(); + // test + void test_generateText(); + void test_sendBugReport(); + +private: + AWBugReporter *plugin = nullptr; + QStringList data; +}; + + +#endif /* TESTAWBUGREPORTER_H */ diff --git a/sources/test/testawtelemetryhandler.cpp b/sources/test/testawtelemetryhandler.cpp new file mode 100644 index 0000000..9d2f04a --- /dev/null +++ b/sources/test/testawtelemetryhandler.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#include "testawtelemetryhandler.h" + +#include + +#include "awtelemetryhandler.h" +#include "awtestlibrary.h" + + +void TestAWTelemetryHandler::initTestCase() +{ + plugin = new AWTelemetryHandler(this, telemetryId); + telemetryData = AWTestLibrary::randomString(); + telemetryGroup = AWTestLibrary::randomString(); +} + + +void TestAWTelemetryHandler::cleanupTestCase() +{ + delete plugin; +} + + +void TestAWTelemetryHandler::test_put() +{ + QVERIFY(plugin->put(telemetryGroup, telemetryData)); +} + + +void TestAWTelemetryHandler::test_get() +{ + QStringList output = plugin->get(telemetryGroup); + + QVERIFY(!output.isEmpty()); + QCOMPARE(QSet::fromList(output).count(), output.count()); + QVERIFY(output.contains(telemetryData)); +} + + +void TestAWTelemetryHandler::test_getLast() +{ + QCOMPARE(telemetryData, plugin->getLast(telemetryGroup)); +} + + +void TestAWTelemetryHandler::test_uploadTelemetry() +{ + QSignalSpy spy(plugin, SIGNAL(replyReceived(QString))); + plugin->uploadTelemetry(telemetryValidGroup, telemetryData); + + QVERIFY(spy.wait(5000)); + QVariantList arguments = spy.takeFirst(); + + QCOMPARE(arguments.at(0).toString(), QString("saved")); +} + + +QTEST_MAIN(TestAWTelemetryHandler); diff --git a/sources/test/testawtelemetryhandler.h b/sources/test/testawtelemetryhandler.h new file mode 100644 index 0000000..f55498e --- /dev/null +++ b/sources/test/testawtelemetryhandler.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * This file is part of awesome-widgets * + * * + * awesome-widgets is free software: you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * awesome-widgets is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * + ***************************************************************************/ + + +#ifndef TESTAWTELEMETRYHANDLER_H +#define TESTAWTELEMETRYHANDLER_H + +#include + + +class AWTelemetryHandler; + +class TestAWTelemetryHandler : public QObject +{ + Q_OBJECT + +private slots: + // initialization + void initTestCase(); + void cleanupTestCase(); + // test + void test_put(); + void test_get(); + void test_getLast(); + void test_uploadTelemetry(); + +private: + AWTelemetryHandler *plugin = nullptr; + QString telemetryData; + QString telemetryGroup; + QString telemetryId = QString("autotest"); + QString telemetryValidGroup = QString("awwidgetconfig"); +}; + + +#endif /* TESTAWTELEMETRYHANDLER_H */ diff --git a/sources/translations/awesome-widgets.pot b/sources/translations/awesome-widgets.pot index aa82a1b..0106fdc 100644 --- a/sources/translations/awesome-widgets.pot +++ b/sources/translations/awesome-widgets.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-08-03 16:10+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -35,6 +35,33 @@ msgstr "" msgid "About" msgstr "" +msgid "Report a bug" +msgstr "" + +msgid "Report subject" +msgstr "" + +msgid "Description" +msgstr "" + +msgid "Steps to reproduce" +msgstr "" + +msgid "Expected result" +msgstr "" + +msgid "Logs" +msgstr "" + +msgid "Use command" +msgstr "" + +msgid "Load log file" +msgstr "" + +msgid "Open log file" +msgstr "" + msgid "Acknowledgment" msgstr "" @@ -269,6 +296,9 @@ msgstr "" msgid "Check updates" msgstr "" +msgid "Report bug" +msgstr "" + msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " "To enable them just make needed checkbox checked." @@ -378,6 +408,12 @@ msgstr "" msgid "Run %1" msgstr "" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "" @@ -420,6 +456,12 @@ msgstr "" msgid "Select font" msgstr "" +msgid "Issue created" +msgstr "" + +msgid "Issue %1 has been created" +msgstr "" + msgid "AC online" msgstr "" diff --git a/sources/translations/en.po b/sources/translations/en.po index 2fd7652..83c11ee 100644 --- a/sources/translations/en.po +++ b/sources/translations/en.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-07-06 19:36+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" "PO-Revision-Date: 2016-07-06 19:37+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: English \n" @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" -"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Lokalize 2.0\n" msgid "Widget" @@ -36,6 +36,35 @@ msgstr "DataEngine" msgid "About" msgstr "About" +msgid "Report a bug" +msgstr "" + +msgid "Report subject" +msgstr "" + +#, fuzzy +msgid "Description" +msgstr "Direction" + +msgid "Steps to reproduce" +msgstr "" + +msgid "Expected result" +msgstr "" + +msgid "Logs" +msgstr "" + +#, fuzzy +msgid "Use command" +msgstr "Edit command" + +msgid "Load log file" +msgstr "" + +msgid "Open log file" +msgstr "" + msgid "Acknowledgment" msgstr "Acknowledgment" @@ -270,6 +299,9 @@ msgstr "Show README" msgid "Check updates" msgstr "Check updates" +msgid "Report bug" +msgstr "" + msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " "To enable them just make needed checkbox checked." @@ -383,6 +415,12 @@ msgstr "Preview" msgid "Run %1" msgstr "Run %1" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "Version %1 (build date %2)" @@ -425,6 +463,12 @@ msgstr "Special thanks to %1" msgid "Select font" msgstr "Select font" +msgid "Issue created" +msgstr "" + +msgid "Issue %1 has been created" +msgstr "" + msgid "AC online" msgstr "AC online" diff --git a/sources/translations/es.po b/sources/translations/es.po index 447e353..746cc55 100644 --- a/sources/translations/es.po +++ b/sources/translations/es.po @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Ernesto Avilés Vázquez , 2014-2016 # Evgeniy Alekseev , 2014-2015 @@ -9,14 +9,15 @@ msgid "" msgstr "" "Project-Id-Version: Awesome widgets\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-07-06 19:36+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" "PO-Revision-Date: 2016-08-03 15:30+0000\n" "Last-Translator: Ernesto Avilés Vázquez \n" -"Language-Team: Spanish (http://www.transifex.com/arcanis/awesome-widgets/language/es/)\n" +"Language-Team: Spanish (http://www.transifex.com/arcanis/awesome-widgets/" +"language/es/)\n" +"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" msgid "Widget" @@ -37,6 +38,35 @@ msgstr "DataEngine" msgid "About" msgstr "Acerca de" +msgid "Report a bug" +msgstr "" + +msgid "Report subject" +msgstr "" + +#, fuzzy +msgid "Description" +msgstr "Dirección" + +msgid "Steps to reproduce" +msgstr "" + +msgid "Expected result" +msgstr "" + +msgid "Logs" +msgstr "" + +#, fuzzy +msgid "Use command" +msgstr "Editar orden" + +msgid "Load log file" +msgstr "" + +msgid "Open log file" +msgstr "" + msgid "Acknowledgment" msgstr "Reconocimiento" @@ -271,10 +301,16 @@ msgstr "Mostrar el README" msgid "Check updates" msgstr "Comprobar actualizaciones" +msgid "Report bug" +msgstr "" + msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " "To enable them just make needed checkbox checked." -msgstr "Las etiquetas para CPU, reloj de CPU, memoria, swap y red soportan ventanas emergentes. Para habilitarlas, simplemente marca las casillas correspondientes." +msgstr "" +"Las etiquetas para CPU, reloj de CPU, memoria, swap y red soportan ventanas " +"emergentes. Para habilitarlas, simplemente marca las casillas " +"correspondientes." msgid "Number of values for tooltips" msgstr "Número de valores para las ventanas emergentes" @@ -328,9 +364,11 @@ msgid "Battery inactive color" msgstr "Color de la batería inactiva" msgid "" -"Detailed information may be found on project homepage" -msgstr "Puedes encontrar información detallada en el sitio del proyecto" +"Detailed information may be found on project homepage" +msgstr "" +"Puedes encontrar información detallada en el sitio del proyecto" msgid "Bgcolor" msgstr "Color de fondo" @@ -380,6 +418,12 @@ msgstr "Vista previa" msgid "Run %1" msgstr "Ejecutar %1" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "Versión %1 (fecha de construcción %2)" @@ -422,6 +466,12 @@ msgstr "Agradecimientos especiales a %1" msgid "Select font" msgstr "Elegir tipo de letra" +msgid "Issue created" +msgstr "" + +msgid "Issue %1 has been created" +msgstr "" + msgid "AC online" msgstr "Alimentación conectada" @@ -557,9 +607,13 @@ msgstr "Etiqueta" msgid "" "

Use YAHOO! finance ticker to get quotes for the " "instrument. Refer to http://finance.yahoo.com/

" -msgstr "

Usa el tablero electrónico de YAHOO! para obtener la cotización del medio. Dirígete a http://finance.yahoo.com/

" +"text-decoration: underline; color:#0057ae;\">http://finance.yahoo.com/

" +msgstr "" +"

Usa el tablero electrónico de YAHOO! para obtener la " +"cotización del medio. Dirígete a http://finance.yahoo." +"com/

" msgid "Ticker" msgstr "Tablero" diff --git a/sources/translations/fr.po b/sources/translations/fr.po index 3d9e8e6..4edb9f6 100644 --- a/sources/translations/fr.po +++ b/sources/translations/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-07-06 19:36+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" "PO-Revision-Date: 2015-07-31 22:16+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: French \n" @@ -38,6 +38,34 @@ msgstr "Moteur de données" msgid "About" msgstr "À propos" +msgid "Report a bug" +msgstr "" + +msgid "Report subject" +msgstr "" + +msgid "Description" +msgstr "" + +msgid "Steps to reproduce" +msgstr "" + +msgid "Expected result" +msgstr "" + +msgid "Logs" +msgstr "" + +#, fuzzy +msgid "Use command" +msgstr "Modifier la commande" + +msgid "Load log file" +msgstr "" + +msgid "Open log file" +msgstr "" + msgid "Acknowledgment" msgstr "À savoir" @@ -277,6 +305,9 @@ msgstr "Voir le README" msgid "Check updates" msgstr "Vérifier les mises à jour" +msgid "Report bug" +msgstr "" + #, fuzzy msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " @@ -399,6 +430,12 @@ msgstr "" msgid "Run %1" msgstr "Éxecuter %1" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "Version %1 (build date %2)" @@ -441,6 +478,12 @@ msgstr "" msgid "Select font" msgstr "Sélectionner une couleur" +msgid "Issue created" +msgstr "" + +msgid "Issue %1 has been created" +msgstr "" + msgid "AC online" msgstr "Alimentation branchée" diff --git a/sources/translations/nl_NL.po b/sources/translations/nl_NL.po index 9865eb2..f21c509 100644 --- a/sources/translations/nl_NL.po +++ b/sources/translations/nl_NL.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Awesome widgets\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-08-03 16:10+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" "PO-Revision-Date: 2016-07-09 08:47+0000\n" "Last-Translator: Heimen Stoffels \n" "Language-Team: Dutch (Netherlands) (http://www.transifex.com/arcanis/awesome-" @@ -38,6 +38,35 @@ msgstr "DataEngine" msgid "About" msgstr "Over" +msgid "Report a bug" +msgstr "" + +msgid "Report subject" +msgstr "" + +#, fuzzy +msgid "Description" +msgstr "Richting" + +msgid "Steps to reproduce" +msgstr "" + +msgid "Expected result" +msgstr "" + +msgid "Logs" +msgstr "" + +#, fuzzy +msgid "Use command" +msgstr "Commando bewerken" + +msgid "Load log file" +msgstr "" + +msgid "Open log file" +msgstr "" + msgid "Acknowledgment" msgstr "Erkenning" @@ -272,6 +301,9 @@ msgstr "README weergeven" msgid "Check updates" msgstr "Controleren op updates" +msgid "Report bug" +msgstr "" + msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " "To enable them just make needed checkbox checked." @@ -385,6 +417,12 @@ msgstr "Voorbeeld" msgid "Run %1" msgstr "%1 uitvoeren" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "Versie %1 (bouwdatum %2)" @@ -427,6 +465,12 @@ msgstr "Veel dank aan %1" msgid "Select font" msgstr "Lettertype selecteren" +msgid "Issue created" +msgstr "" + +msgid "Issue %1 has been created" +msgstr "" + msgid "AC online" msgstr "AC online" diff --git a/sources/translations/pl.po b/sources/translations/pl.po index 6cfe14a..1d4e605 100644 --- a/sources/translations/pl.po +++ b/sources/translations/pl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-07-06 19:36+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -35,6 +35,35 @@ msgstr "Silnik danych" msgid "About" msgstr "O..." +msgid "Report a bug" +msgstr "" + +msgid "Report subject" +msgstr "" + +#, fuzzy +msgid "Description" +msgstr "Kierunek" + +msgid "Steps to reproduce" +msgstr "" + +msgid "Expected result" +msgstr "" + +msgid "Logs" +msgstr "" + +#, fuzzy +msgid "Use command" +msgstr "Polecenie edycji" + +msgid "Load log file" +msgstr "" + +msgid "Open log file" +msgstr "" + msgid "Acknowledgment" msgstr "Potwierdzenie" @@ -269,6 +298,9 @@ msgstr "Pokaż README" msgid "Check updates" msgstr "Sprawdź aktualizacje" +msgid "Report bug" +msgstr "" + msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " "To enable them just make needed checkbox checked." @@ -384,6 +416,12 @@ msgstr "Przegląd" msgid "Run %1" msgstr "Wykonać %1" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "Wersja %1 (data budowy %2)" @@ -426,6 +464,12 @@ msgstr "Specjalnie podziękowania dla %1" msgid "Select font" msgstr "Wybierz czcionkę" +msgid "Issue created" +msgstr "" + +msgid "Issue %1 has been created" +msgstr "" + msgid "AC online" msgstr "Zasilanie zewnętrzne podłączone" diff --git a/sources/translations/pt_BR.po b/sources/translations/pt_BR.po index cba4fe7..112ab27 100644 --- a/sources/translations/pt_BR.po +++ b/sources/translations/pt_BR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-07-06 19:36+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" "PO-Revision-Date: 2015-07-31 22:21+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Russian \n" @@ -37,6 +37,35 @@ msgstr "Engine de dados" msgid "About" msgstr "Sobre" +msgid "Report a bug" +msgstr "" + +msgid "Report subject" +msgstr "" + +#, fuzzy +msgid "Description" +msgstr "Direção" + +msgid "Steps to reproduce" +msgstr "" + +msgid "Expected result" +msgstr "" + +msgid "Logs" +msgstr "" + +#, fuzzy +msgid "Use command" +msgstr "Editar comandos" + +msgid "Load log file" +msgstr "" + +msgid "Open log file" +msgstr "" + msgid "Acknowledgment" msgstr "Confirmação" @@ -279,6 +308,9 @@ msgstr "Mostrar README" msgid "Check updates" msgstr "Checar por atualizações" +msgid "Report bug" +msgstr "" + #, fuzzy msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " @@ -400,6 +432,12 @@ msgstr "" msgid "Run %1" msgstr "Rodar %1" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "Versão: %1 (data de compilação %2)" @@ -442,6 +480,12 @@ msgstr "" msgid "Select font" msgstr "Selecionar fonte" +msgid "Issue created" +msgstr "" + +msgid "Issue %1 has been created" +msgstr "" + msgid "AC online" msgstr "Carregador conectado" diff --git a/sources/translations/ru.po b/sources/translations/ru.po index 2552ccf..c82a678 100644 --- a/sources/translations/ru.po +++ b/sources/translations/ru.po @@ -6,16 +6,16 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-07-06 19:36+0300\n" -"PO-Revision-Date: 2016-07-06 19:37+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" +"PO-Revision-Date: 2016-08-27 02:56+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" -"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Lokalize 2.0\n" msgid "Widget" @@ -36,6 +36,33 @@ msgstr "DataEngine" msgid "About" msgstr "О программе" +msgid "Report a bug" +msgstr "Сообщить об ошибке" + +msgid "Report subject" +msgstr "Тема" + +msgid "Description" +msgstr "Описание" + +msgid "Steps to reproduce" +msgstr "Как воспроизвести" + +msgid "Expected result" +msgstr "Ожидаемый результат" + +msgid "Logs" +msgstr "Логи" + +msgid "Use command" +msgstr "Используйте команду" + +msgid "Load log file" +msgstr "Загрузить лог" + +msgid "Open log file" +msgstr "Открыть лог" + msgid "Acknowledgment" msgstr "Благодарности" @@ -270,6 +297,9 @@ msgstr "Показать README" msgid "Check updates" msgstr "Проверить обновления" +msgid "Report bug" +msgstr "Сообщить об ошибке" + msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " "To enable them just make needed checkbox checked." @@ -383,6 +413,12 @@ msgstr "Предварительный просмотр" msgid "Run %1" msgstr "Запуск %1" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "Версия %1 (дата сборки %2)" @@ -425,6 +461,12 @@ msgstr "Отдельное спасибо %1" msgid "Select font" msgstr "Выберете шрифт" +msgid "Issue created" +msgstr "Сообщение создано" + +msgid "Issue %1 has been created" +msgstr "Тикет %1 был создан" + msgid "AC online" msgstr "AC подключен" diff --git a/sources/translations/uk.po b/sources/translations/uk.po index 16834a5..c5147d4 100644 --- a/sources/translations/uk.po +++ b/sources/translations/uk.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-07-06 19:36+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" "PO-Revision-Date: 2016-08-09 22:22+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Ukrainian \n" @@ -36,6 +36,35 @@ msgstr "DataEngine" msgid "About" msgstr "Про програму" +msgid "Report a bug" +msgstr "" + +msgid "Report subject" +msgstr "" + +#, fuzzy +msgid "Description" +msgstr "Напрямок" + +msgid "Steps to reproduce" +msgstr "" + +msgid "Expected result" +msgstr "" + +msgid "Logs" +msgstr "" + +#, fuzzy +msgid "Use command" +msgstr "Редагувати команду" + +msgid "Load log file" +msgstr "" + +msgid "Open log file" +msgstr "" + msgid "Acknowledgment" msgstr "Подяка" @@ -270,6 +299,9 @@ msgstr "Показати README" msgid "Check updates" msgstr "Шукати оновлення" +msgid "Report bug" +msgstr "" + msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " "To enable them just make needed checkbox checked." @@ -384,6 +416,12 @@ msgstr "Попередній перегляд" msgid "Run %1" msgstr "Запуск %1" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "Версія %1 (дата створення %2)" @@ -426,6 +464,12 @@ msgstr "Особлива подяка %1" msgid "Select font" msgstr "Оберіть шрифт" +msgid "Issue created" +msgstr "" + +msgid "Issue %1 has been created" +msgstr "" + msgid "AC online" msgstr "AC підключений" diff --git a/sources/translations/zh.po b/sources/translations/zh.po index 3316d35..320ab9c 100644 --- a/sources/translations/zh.po +++ b/sources/translations/zh.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/arcan1s/awesome-widgets/issues\n" -"POT-Creation-Date: 2016-07-06 19:36+0300\n" +"POT-Creation-Date: 2016-09-01 15:36+0300\n" "PO-Revision-Date: 2015-07-31 22:24+0300\n" "Last-Translator: Evgeniy Alekseev \n" "Language-Team: Russian \n" @@ -36,6 +36,35 @@ msgstr "数据引擎" msgid "About" msgstr "关于" +msgid "Report a bug" +msgstr "" + +msgid "Report subject" +msgstr "" + +#, fuzzy +msgid "Description" +msgstr "方向" + +msgid "Steps to reproduce" +msgstr "" + +msgid "Expected result" +msgstr "" + +msgid "Logs" +msgstr "" + +#, fuzzy +msgid "Use command" +msgstr "编辑命令" + +msgid "Load log file" +msgstr "" + +msgid "Open log file" +msgstr "" + msgid "Acknowledgment" msgstr "感谢" @@ -270,6 +299,9 @@ msgstr "显示帮助文档" msgid "Check updates" msgstr "检查更新" +msgid "Report bug" +msgstr "" + msgid "" "CPU, CPU clock, memory, swap and network labels support graphical tooltip. " "To enable them just make needed checkbox checked." @@ -385,6 +417,12 @@ msgstr "预览" msgid "Run %1" msgstr "运行 %1" +msgid "Not supported" +msgstr "" + +msgid "You are using mammoth's Qt version, try to update it first!" +msgstr "" + msgid "Version %1 (build date %2)" msgstr "版本 %1 (编译时间 %2)" @@ -427,6 +465,12 @@ msgstr "特别感谢 %1" msgid "Select font" msgstr "选择字体" +msgid "Issue created" +msgstr "" + +msgid "Issue %1 has been created" +msgstr "" + msgid "AC online" msgstr "外接电源使用中" diff --git a/sources/version.h.in b/sources/version.h.in index b52da4d..74319cc 100644 --- a/sources/version.h.in +++ b/sources/version.h.in @@ -36,11 +36,13 @@ #define AWEWAPI 3 // formatter api version #define AWEFAPI 2 +// telemetry api version +#define AWTEAPI 1 // network requests timeout, ms #define REQUEST_TIMEOUT 3000 // available time keys #define TIME_KEYS \ - "dddd,ddd,dd,d,MMMM,MMM,MM,M,yyyy,yy,hh,h,HH,H,mm,m,ss,s,t,ap,a,AP,A" + "d,dd,ddd,dddd,M,MM,MMM,MMMM,yy,yyyy,h,hh,H,HH,m,mm,s,ss,t,a,ap,A,AP" // static keys #define STATIC_KEYS \ "time,isotime,shorttime,longtime,tstime,ctime,uptime,cuptime,cpucl,cpu," \ @@ -61,6 +63,7 @@ #define VERSION_API \ "https://api.github.com/repos/arcan1s/awesome-widgets/releases" #define BUGTRACKER "https://github.com/arcan1s/awesome-widgets/issues" +#define BUGTRACKER_API "http://arcanis.me/repos/arcan1s/awesome-widgets/issues" #define TRANSLATION "https://github.com/arcan1s/awesome-widgets/issues/14" #define AUR_PACKAGES \ "https://aur.archlinux.org/packages/plasma5-applet-awesome-widgets/"