Imported existing sources
This commit is contained in:
BIN
images/not-present.png
Normal file
BIN
images/not-present.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
images/present.png
Normal file
BIN
images/present.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
BIN
images/refresh.png
Normal file
BIN
images/refresh.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
42
presenceplugin.cpp
Normal file
42
presenceplugin.cpp
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#include "presenceplugin.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QLocale>
|
||||||
|
#include <QStatusBar>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
26
presenceplugin.h
Normal file
26
presenceplugin.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTranslator>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
};
|
0
presenceplugin.json
Normal file
0
presenceplugin.json
Normal file
26
presenceplugin.pro
Normal file
26
presenceplugin.pro
Normal file
@@ -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)
|
7
presenceplugin_resources.qrc
Normal file
7
presenceplugin_resources.qrc
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/zeiterfassung/plugins/presenceplugin">
|
||||||
|
<file>images/not-present.png</file>
|
||||||
|
<file>images/present.png</file>
|
||||||
|
<file>images/refresh.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
42
presencesettings.cpp
Normal file
42
presencesettings.cpp
Normal file
@@ -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;
|
||||||
|
}
|
28
presencesettings.h
Normal file
28
presencesettings.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
24
presencesettingswidget.cpp
Normal file
24
presencesettingswidget.cpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#include "presencesettingswidget.h"
|
||||||
|
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QSpinBox>
|
||||||
|
|
||||||
|
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<int>::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());
|
||||||
|
}
|
23
presencesettingswidget.h
Normal file
23
presencesettingswidget.h
Normal file
@@ -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;
|
||||||
|
};
|
86
presencewidget.cpp
Normal file
86
presencewidget.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#include "presencewidget.h"
|
||||||
|
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
30
presencewidget.h
Normal file
30
presencewidget.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
#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<GetPresenceStatusReply> m_reply;
|
||||||
|
};
|
34
translations/presenceplugin_de.ts
Normal file
34
translations/presenceplugin_de.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="de_DE">
|
||||||
|
<context>
|
||||||
|
<name>PresenceWidget</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="25"/>
|
||||||
|
<source>Refresh presence</source>
|
||||||
|
<translation>Verfügbarkeit aktualisieren</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="39"/>
|
||||||
|
<source>???</source>
|
||||||
|
<translation>???</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="39"/>
|
||||||
|
<location filename="../presencewidget.cpp" line="80"/>
|
||||||
|
<source>%0 available, %1 not available</source>
|
||||||
|
<translation>%0 verfügbar, %1 nicht verfügbar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="52"/>
|
||||||
|
<location filename="../presencewidget.cpp" line="53"/>
|
||||||
|
<source>Could not get presence status!</source>
|
||||||
|
<translation>Konnte Verfügbarkeit nicht laden!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="77"/>
|
||||||
|
<source>%0 %1</source>
|
||||||
|
<translation>%0 %1</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
34
translations/presenceplugin_en.ts
Normal file
34
translations/presenceplugin_en.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="en_US">
|
||||||
|
<context>
|
||||||
|
<name>PresenceWidget</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="25"/>
|
||||||
|
<source>Refresh presence</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="39"/>
|
||||||
|
<source>???</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="39"/>
|
||||||
|
<location filename="../presencewidget.cpp" line="80"/>
|
||||||
|
<source>%0 available, %1 not available</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="52"/>
|
||||||
|
<location filename="../presencewidget.cpp" line="53"/>
|
||||||
|
<source>Could not get presence status!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../presencewidget.cpp" line="77"/>
|
||||||
|
<source>%0 %1</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
Reference in New Issue
Block a user