diff --git a/images/not-present.png b/images/not-present.png new file mode 100644 index 0000000..ff9da22 Binary files /dev/null and b/images/not-present.png differ diff --git a/images/present.png b/images/present.png new file mode 100644 index 0000000..21232af Binary files /dev/null and b/images/present.png differ diff --git a/images/refresh.png b/images/refresh.png new file mode 100644 index 0000000..f3585b7 Binary files /dev/null and b/images/refresh.png differ 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 + + + +