From cb64211fcd50ef6692a228198811ddbd368ff194 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 <0xFEEDC0DE64@gmail.com> Date: Mon, 17 Sep 2018 19:51:08 +0200 Subject: [PATCH] Imported existing sources --- images/not-present.png | Bin 0 -> 3600 bytes images/present.png | Bin 0 -> 4125 bytes images/refresh.png | Bin 0 -> 6914 bytes presenceplugin.cpp | 42 +++++++++++++++ presenceplugin.h | 26 +++++++++ presenceplugin.json | 0 presenceplugin.pro | 26 +++++++++ presenceplugin_resources.qrc | 7 +++ presencesettings.cpp | 42 +++++++++++++++ presencesettings.h | 28 ++++++++++ presencesettingswidget.cpp | 24 +++++++++ presencesettingswidget.h | 23 ++++++++ presencewidget.cpp | 86 ++++++++++++++++++++++++++++++ presencewidget.h | 30 +++++++++++ translations/presenceplugin_de.ts | 34 ++++++++++++ translations/presenceplugin_en.ts | 34 ++++++++++++ 16 files changed, 402 insertions(+) create mode 100644 images/not-present.png create mode 100644 images/present.png create mode 100644 images/refresh.png create mode 100644 presenceplugin.cpp create mode 100644 presenceplugin.h create mode 100644 presenceplugin.json create mode 100644 presenceplugin.pro create mode 100644 presenceplugin_resources.qrc create mode 100644 presencesettings.cpp create mode 100644 presencesettings.h create mode 100644 presencesettingswidget.cpp create mode 100644 presencesettingswidget.h create mode 100644 presencewidget.cpp create mode 100644 presencewidget.h create mode 100644 translations/presenceplugin_de.ts create mode 100644 translations/presenceplugin_en.ts diff --git a/images/not-present.png b/images/not-present.png new file mode 100644 index 0000000000000000000000000000000000000000..ff9da22ef0f8322adc9ffe22daf376f5f5e3501c GIT binary patch literal 3600 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 s{H|U97v4Yl`YYdlo;wEzGB literal 0 HcmV?d00001 diff --git a/images/present.png b/images/present.png new file mode 100644 index 0000000000000000000000000000000000000000..21232afc1635828ba7dbaf851e7fb88ccf0e913b GIT binary patch literal 4125 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 YSnOQea)&vMfq{X+)78&qol`;+0EwrQpa1{> literal 0 HcmV?d00001 diff --git a/images/refresh.png b/images/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..f3585b74a877cd7716fb55a1c7392c87164095ac GIT binary patch literal 6914 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 literal 0 HcmV?d00001 diff --git a/presenceplugin.cpp b/presenceplugin.cpp new file mode 100644 index 0000000..c954e20 --- /dev/null +++ b/presenceplugin.cpp @@ -0,0 +1,42 @@ +#include "presenceplugin.h" + +#include +#include +#include +#include +#include + +#include "mainwindow.h" + +#include "presencewidget.h" +#include "presencesettingswidget.h" + +PresencePlugin::PresencePlugin(QObject *parent) : + ZeiterfassungPlugin(parent) +{ + qDebug() << "called"; + + static auto dir = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("translations")); + + if(m_translator.load(QLocale(), QStringLiteral("presenceplugin"), QStringLiteral("_"), dir)) + { + if(!QCoreApplication::installTranslator(&m_translator)) + { + qWarning() << "could not install translation presenceplugin"; + } + } + else + { + qWarning() << "could not load translation presenceplugin"; + } +} + +void PresencePlugin::attachTo(MainWindow &mainWindow) +{ + mainWindow.statusBar()->addWidget(new PresenceWidget(mainWindow)); +} + +SettingsWidget *PresencePlugin::settingsWidget(ZeiterfassungSettings &settings, QWidget *parent) const +{ + return new PresenceSettingsWidget(settings, parent); +} diff --git a/presenceplugin.h b/presenceplugin.h new file mode 100644 index 0000000..2f578dc --- /dev/null +++ b/presenceplugin.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include "zeiterfassungplugin.h" + +class MainWindow; + +class Q_DECL_EXPORT PresencePlugin : public ZeiterfassungPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "dbsoftware.zeiterfassung.plugin/1.0" FILE "presenceplugin.json") + Q_INTERFACES(ZeiterfassungPlugin) + +public: + explicit PresencePlugin(QObject *parent = Q_NULLPTR); + + // ZeiterfassungPlugin interface + void attachTo(MainWindow &mainWindow) Q_DECL_OVERRIDE; + + virtual SettingsWidget *settingsWidget(ZeiterfassungSettings &settings, QWidget *parent = Q_NULLPTR) const Q_DECL_OVERRIDE; + +private: + QTranslator m_translator; +}; diff --git a/presenceplugin.json b/presenceplugin.json new file mode 100644 index 0000000..e69de29 diff --git a/presenceplugin.pro b/presenceplugin.pro new file mode 100644 index 0000000..271336b --- /dev/null +++ b/presenceplugin.pro @@ -0,0 +1,26 @@ +QT += core network gui widgets + +DBLIBS += zeiterfassungcore zeiterfassunggui + +TARGET = presenceplugin + +HEADERS += presenceplugin.h \ + presencewidget.h \ + presencesettings.h \ + presencesettingswidget.h + +SOURCES += presenceplugin.cpp \ + presencewidget.cpp \ + presencesettings.cpp \ + presencesettingswidget.cpp + +FORMS += + +RESOURCES += presenceplugin_resources.qrc + +TRANSLATIONS += translations/presenceplugin_en.ts \ + translations/presenceplugin_de.ts + +OTHER_FILES += presenceplugin.json + +include(../plugin.pri) diff --git a/presenceplugin_resources.qrc b/presenceplugin_resources.qrc new file mode 100644 index 0000000..0e59021 --- /dev/null +++ b/presenceplugin_resources.qrc @@ -0,0 +1,7 @@ + + + images/not-present.png + images/present.png + images/refresh.png + + diff --git a/presencesettings.cpp b/presencesettings.cpp new file mode 100644 index 0000000..ba61eaf --- /dev/null +++ b/presencesettings.cpp @@ -0,0 +1,42 @@ +#include "presencesettings.h" + +#include "zeiterfassungsettings.h" + +const QString PresenceSettings::m_interval("PresencePlugin/interval"); +const int PresenceSettings::m_defaultInterval(60000); + +PresenceSettings::PresenceSettings(ZeiterfassungSettings &settings, QObject *parent) : + QObject(parent), + m_settings(settings) +{ + +} + +int PresenceSettings::interval() const +{ + return m_settings.value(m_interval, m_defaultInterval).toInt(); +} + +bool PresenceSettings::setInterval(int interval) +{ + if(this->interval() == interval) + return true; + + if(interval == m_defaultInterval) + m_settings.remove(m_interval); + else + m_settings.setValue(m_interval, interval); + + m_settings.sync(); + + const auto success = m_settings.status() == QSettings::NoError; + if(success) + Q_EMIT intervalChanged(interval); + else + { + Q_EMIT m_settings.saveErrorOccured(); + Q_EMIT saveErrorOccured(); + } + + return success; +} diff --git a/presencesettings.h b/presencesettings.h new file mode 100644 index 0000000..58f83ad --- /dev/null +++ b/presencesettings.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +class ZeiterfassungSettings; + +class PresenceSettings : public QObject +{ + Q_OBJECT + Q_PROPERTY(int interval READ interval WRITE setInterval NOTIFY intervalChanged) + +public: + PresenceSettings(ZeiterfassungSettings &settings, QObject *parent = Q_NULLPTR); + + int interval() const; + bool setInterval(int interval); + +Q_SIGNALS: + void saveErrorOccured(); + + void intervalChanged(int interval); + +private: + ZeiterfassungSettings &m_settings; + + static const QString m_interval; + static const int m_defaultInterval; +}; diff --git a/presencesettingswidget.cpp b/presencesettingswidget.cpp new file mode 100644 index 0000000..51b2733 --- /dev/null +++ b/presencesettingswidget.cpp @@ -0,0 +1,24 @@ +#include "presencesettingswidget.h" + +#include +#include + +PresenceSettingsWidget::PresenceSettingsWidget(ZeiterfassungSettings &settings, QWidget *parent) : + SettingsWidget(parent), + m_settings(settings) +{ + auto layout = new QFormLayout(this); + layout->setMargin(0); + + m_spinBox = new QSpinBox(this); + m_spinBox->setRange(0, std::numeric_limits::max()); + m_spinBox->setValue(m_settings.interval()); + layout->addRow(tr("Interval(ms):"), m_spinBox); + + setLayout(layout); +} + +bool PresenceSettingsWidget::apply() +{ + return m_settings.setInterval(m_spinBox->value()); +} diff --git a/presencesettingswidget.h b/presencesettingswidget.h new file mode 100644 index 0000000..c9d649b --- /dev/null +++ b/presencesettingswidget.h @@ -0,0 +1,23 @@ +#pragma once + +#include "settingswidget.h" + +#include "presencesettings.h" + +class QSpinBox; + +class PresenceSettingsWidget : public SettingsWidget +{ + Q_OBJECT + +public: + explicit PresenceSettingsWidget(ZeiterfassungSettings &settings, QWidget *parent = Q_NULLPTR); + +public Q_SLOTS: + virtual bool apply() Q_DECL_OVERRIDE; + +private: + PresenceSettings m_settings; + + QSpinBox *m_spinBox; +}; diff --git a/presencewidget.cpp b/presencewidget.cpp new file mode 100644 index 0000000..85af498 --- /dev/null +++ b/presencewidget.cpp @@ -0,0 +1,86 @@ +#include "presencewidget.h" + +#include +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "zeiterfassungapi.h" + +#include "presencesettings.h" + +PresenceWidget::PresenceWidget(MainWindow &mainWindow) : + QPushButton(&mainWindow), + m_mainWindow(mainWindow) +{ + connect(&m_mainWindow, &MainWindow::refreshEverything, this, &PresenceWidget::refresh); + + m_menu = new QMenu(this); + setMenu(m_menu); + + m_action = new QAction(QIcon(QStringLiteral(":zeiterfassung/plugins/presenceplugin/images/refresh.png")), + tr("Refresh presence"), this); + connect(m_action, &QAction::triggered, this, &PresenceWidget::refresh); + m_mainWindow.menuView()->addAction(m_action); + + auto timer = new QTimer(this); + timer->setInterval(PresenceSettings(mainWindow.settings()).interval()); + connect(timer, &QTimer::timeout, this, &PresenceWidget::refresh); + timer->start(); + + refresh(); +} + +void PresenceWidget::refresh() +{ + setText(tr("%0 available, %1 not available").arg(tr("???")).arg(tr("???"))); + m_menu->clear(); + + m_action->setEnabled(false); + + m_reply = m_mainWindow.erfassung().doGetPresenceStatus(); + connect(m_reply.get(), &ZeiterfassungReply::finished, this, &PresenceWidget::finished); +} + +void PresenceWidget::finished() +{ + if(!m_reply->success()) + { + QMessageBox::warning(&m_mainWindow, tr("Could not get presence status!"), + tr("Could not get presence status!") % "\n\n" % m_reply->message()); + goto after; + } + + { + int present = 0, + notPresent = 0; + + for(const auto &status : m_reply->presenceStatuses()) + { + QIcon icon; + if(status.presence == QStringLiteral("J")) + { + present++; + icon = QIcon(QStringLiteral(":zeiterfassung/plugins/presenceplugin/images/present.png")); + } + else if(status.presence == QStringLiteral("N")) + { + notPresent++; + icon = QIcon(QStringLiteral(":zeiterfassung/plugins/presenceplugin/images/not-present.png")); + } + else + qCritical() << "unknown presence" << status.firstName << status.lastName << status.presence; + + m_menu->addAction(icon, tr("%0 %1").arg(status.firstName).arg(status.lastName)); + } + + setText(tr("%0 available, %1 not available").arg(present).arg(notPresent)); + } + + after: + m_action->setEnabled(true); + m_reply = Q_NULLPTR; +} diff --git a/presencewidget.h b/presencewidget.h new file mode 100644 index 0000000..e05b230 --- /dev/null +++ b/presencewidget.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include "replies/getpresencestatusreply.h" + +class QMenu; +class QAction; + +class MainWindow; + +class PresenceWidget : public QPushButton +{ + Q_OBJECT + +public: + explicit PresenceWidget(MainWindow &mainWindow); + +private Q_SLOTS: + void refresh(); + void finished(); + +private: + MainWindow &m_mainWindow; + + QMenu *m_menu; + QAction *m_action; + + std::unique_ptr m_reply; +}; diff --git a/translations/presenceplugin_de.ts b/translations/presenceplugin_de.ts new file mode 100644 index 0000000..5a9aaa7 --- /dev/null +++ b/translations/presenceplugin_de.ts @@ -0,0 +1,34 @@ + + + + + PresenceWidget + + + Refresh presence + Verfügbarkeit aktualisieren + + + + ??? + ??? + + + + + %0 available, %1 not available + %0 verfügbar, %1 nicht verfügbar + + + + + Could not get presence status! + Konnte Verfügbarkeit nicht laden! + + + + %0 %1 + %0 %1 + + + diff --git a/translations/presenceplugin_en.ts b/translations/presenceplugin_en.ts new file mode 100644 index 0000000..3f9a255 --- /dev/null +++ b/translations/presenceplugin_en.ts @@ -0,0 +1,34 @@ + + + + + PresenceWidget + + + Refresh presence + + + + + ??? + + + + + + %0 available, %1 not available + + + + + + Could not get presence status! + + + + + %0 %1 + + + +