diff --git a/plugins/plugins.pro b/plugins/plugins.pro
index dab007d..5a6d1f5 100644
--- a/plugins/plugins.pro
+++ b/plugins/plugins.pro
@@ -6,4 +6,5 @@ SUBDIRS += advancedviewplugin \
presenceplugin \
reportsplugin \
updaterplugin \
- weatherplugin
+ weatherplugin \
+ webradioplugin
diff --git a/plugins/webradioplugin/images/web-radio.png b/plugins/webradioplugin/images/web-radio.png
new file mode 100644
index 0000000..c68d7c1
Binary files /dev/null and b/plugins/webradioplugin/images/web-radio.png differ
diff --git a/plugins/webradioplugin/translations/webradioplugin_de.ts b/plugins/webradioplugin/translations/webradioplugin_de.ts
new file mode 100644
index 0000000..c21f851
--- /dev/null
+++ b/plugins/webradioplugin/translations/webradioplugin_de.ts
@@ -0,0 +1,101 @@
+
+
+
+
+ WebRadioDialog
+
+
+ Radio
+ Radio
+
+
+
+ Play
+ Abspielen
+
+
+
+ Pause
+ Pause
+
+
+
+ Stop
+ Stop
+
+
+
+ Stopped
+ Gestoppt
+
+
+
+ Playing
+ Wird abgespielt
+
+
+
+ Paused
+ Pausiert
+
+
+
+
+ Unknown
+ Unbekannt
+
+
+
+ Unknown media
+ Unbekanntes Medium
+
+
+
+ No media
+ Kein Medium
+
+
+
+ Loading media...
+ Lade Medium...
+
+
+
+ Loaded media
+ Medium geladen
+
+
+
+ Stalled media
+ Medium angehalten
+
+
+
+ Buffering media
+ Puffere Medium
+
+
+
+ Buffered media
+ Medium gepuffert
+
+
+
+ End of media
+ Ende des Mediums
+
+
+
+ Invalid media
+ Ungültiges Medium
+
+
+
+ WebRadioPlugin
+
+
+ Play webradio
+ Webradio spielen
+
+
+
diff --git a/plugins/webradioplugin/translations/webradioplugin_en.ts b/plugins/webradioplugin/translations/webradioplugin_en.ts
new file mode 100644
index 0000000..e84a249
--- /dev/null
+++ b/plugins/webradioplugin/translations/webradioplugin_en.ts
@@ -0,0 +1,101 @@
+
+
+
+
+ WebRadioDialog
+
+
+ Radio
+
+
+
+
+ Play
+
+
+
+
+ Pause
+
+
+
+
+ Stop
+
+
+
+
+ Stopped
+
+
+
+
+ Playing
+
+
+
+
+ Paused
+
+
+
+
+
+ Unknown
+
+
+
+
+ Unknown media
+
+
+
+
+ No media
+
+
+
+
+ Loading media...
+
+
+
+
+ Loaded media
+
+
+
+
+ Stalled media
+
+
+
+
+ Buffering media
+
+
+
+
+ Buffered media
+
+
+
+
+ End of media
+
+
+
+
+ Invalid media
+
+
+
+
+ WebRadioPlugin
+
+
+ Play webradio
+
+
+
+
diff --git a/plugins/webradioplugin/webradiodialog.cpp b/plugins/webradioplugin/webradiodialog.cpp
new file mode 100644
index 0000000..b8ddc01
--- /dev/null
+++ b/plugins/webradioplugin/webradiodialog.cpp
@@ -0,0 +1,134 @@
+#include "webradiodialog.h"
+#include "ui_webradiodialog.h"
+
+#include "mainwindow.h"
+#include "zeiterfassungsettings.h"
+
+WebRadioDialog::WebRadioDialog(MainWindow &mainWindow) :
+ QDialog(&mainWindow),
+ ui(new Ui::WebRadioDialog),
+ m_mainWindow(mainWindow),
+ m_player(new QMediaPlayer(this))
+{
+ ui->setupUi(this);
+
+ connect(m_player, &QMediaPlayer::stateChanged, this, &WebRadioDialog::stateChanged);
+ connect(m_player, &QMediaPlayer::stateChanged, this, &WebRadioDialog::updateWidgets);
+ connect(m_player, &QMediaPlayer::mediaStatusChanged, this, &WebRadioDialog::mediaStatusChanged);
+ connect(m_player, &QMediaPlayer::mediaStatusChanged, this, &WebRadioDialog::updateWidgets);
+ connect(m_player, static_cast(&QMediaPlayer::error), this, &WebRadioDialog::error);
+
+ for(const auto &url : m_mainWindow.settings().value(QStringLiteral("WebRadioPlugin/urls"), QStringList {
+ QStringLiteral("http://stream.drumandbass.fm:9002"),
+ QStringLiteral("http://stream.trap.fm:6002"),
+ QStringLiteral("http://stream.dubbase.fm:7002"),
+ QStringLiteral("http://lw1.mp3.tb-group.fm/hb.mp3"),
+ QStringLiteral("http://lw1.mp3.tb-group.fm/tb.mp3"),
+ QStringLiteral("http://lw1.mp3.tb-group.fm/tt.mp3"),
+ QStringLiteral("http://lw1.mp3.tb-group.fm/ht.mp3"),
+ QStringLiteral("http://lw1.mp3.tb-group.fm/trb.mp3"),
+ QStringLiteral("http://lw1.mp3.tb-group.fm/ct.mp3"),
+ QStringLiteral("http://lw1.mp3.tb-group.fm/clt.mp3"),
+ QStringLiteral("https://live.helsinki.at:8088/live160.ogg")
+ }).toStringList())
+ {
+ ui->comboBox->addItem(url, url);
+ }
+
+ ui->comboBox->setCurrentIndex(ui->comboBox->findData(m_mainWindow.settings().value(QStringLiteral("WebRadioPlugin/lastUrl")).toString()));
+
+ connect(ui->comboBox, static_cast(&QComboBox::currentIndexChanged),
+ this, &WebRadioDialog::currentIndexChanged);
+
+ connect(ui->comboBox, static_cast(&QComboBox::currentIndexChanged),
+ this, &WebRadioDialog::updateWidgets);
+
+ connect(ui->pushButtonPlay, &QAbstractButton::pressed, this, &WebRadioDialog::play);
+ connect(ui->pushButtonPause, &QAbstractButton::pressed, m_player, &QMediaPlayer::pause);
+ connect(ui->pushButtonStop, &QAbstractButton::pressed, m_player, &QMediaPlayer::stop);
+
+ m_player->setVolume(m_mainWindow.settings().value(QStringLiteral("WebRadioPlugin/volume"), 100).toInt());
+ ui->horizontalSlider->setValue(m_player->volume());
+ connect(ui->horizontalSlider, &QAbstractSlider::valueChanged, this, &WebRadioDialog::volumeChanged);
+
+ stateChanged(m_player->state());
+ mediaStatusChanged(m_player->mediaStatus());
+ currentIndexChanged(ui->comboBox->currentIndex());
+ updateWidgets();
+}
+
+WebRadioDialog::~WebRadioDialog()
+{
+ delete ui;
+}
+
+void WebRadioDialog::stateChanged(QMediaPlayer::State newState)
+{
+ switch(newState)
+ {
+ case QMediaPlayer::StoppedState: ui->labelState->setText(tr("Stopped")); break;
+ case QMediaPlayer::PlayingState: ui->labelState->setText(tr("Playing")); break;
+ case QMediaPlayer::PausedState: ui->labelState->setText(tr("Paused")); break;
+ default:
+ qWarning() << "unknown state" << newState;
+ ui->labelState->setText(tr("Unknown"));
+ }
+}
+
+void WebRadioDialog::mediaStatusChanged(QMediaPlayer::MediaStatus status)
+{
+ switch(status)
+ {
+ case QMediaPlayer::UnknownMediaStatus: ui->labelMediaStatus->setText(tr("Unknown media")); break;
+ case QMediaPlayer::NoMedia: ui->labelMediaStatus->setText(tr("No media")); break;
+ case QMediaPlayer::LoadingMedia: ui->labelMediaStatus->setText(tr("Loading media...")); break;
+ case QMediaPlayer::LoadedMedia: ui->labelMediaStatus->setText(tr("Loaded media")); break;
+ case QMediaPlayer::StalledMedia: ui->labelMediaStatus->setText(tr("Stalled media")); break;
+ case QMediaPlayer::BufferingMedia: ui->labelMediaStatus->setText(tr("Buffering media")); break;
+ case QMediaPlayer::BufferedMedia: ui->labelMediaStatus->setText(tr("Buffered media")); break;
+ case QMediaPlayer::EndOfMedia: ui->labelMediaStatus->setText(tr("End of media")); break;
+ case QMediaPlayer::InvalidMedia: ui->labelMediaStatus->setText(tr("Invalid media")); break;
+ default:
+ qWarning() << "unknown mediaStatus" << status;
+ ui->labelMediaStatus->setText(tr("Unknown"));
+ }
+}
+
+void WebRadioDialog::error(QMediaPlayer::Error error)
+{
+ qWarning() << error;
+}
+
+void WebRadioDialog::currentIndexChanged(int index)
+{
+ if(index == -1)
+ m_player->setMedia(QMediaContent());
+ else
+ m_player->setMedia(QMediaContent(QUrl(ui->comboBox->currentData().toString())));
+}
+
+void WebRadioDialog::play()
+{
+ if(ui->comboBox->currentIndex() == -1)
+ return;
+
+ m_mainWindow.settings().setValue(QStringLiteral("WebRadioPlugin/lastUrl"), ui->comboBox->currentData().toString());
+
+ m_player->play();
+}
+
+void WebRadioDialog::updateWidgets()
+{
+ ui->comboBox->setEnabled(m_player->state() != QMediaPlayer::PlayingState);
+ ui->pushButtonPlay->setEnabled(ui->comboBox->currentIndex() > -1 &&
+ (m_player->state() == QMediaPlayer::StoppedState || m_player->state() == QMediaPlayer::PausedState) &&
+ (m_player->mediaStatus() == QMediaPlayer::LoadedMedia || m_player->mediaStatus() == QMediaPlayer::BufferedMedia));
+ ui->pushButtonPause->setEnabled(m_player->state() == QMediaPlayer::PlayingState || m_player->state() == QMediaPlayer::PausedState);
+ ui->pushButtonStop->setEnabled(m_player->state() == QMediaPlayer::PlayingState || m_player->state() == QMediaPlayer::PausedState);
+}
+
+void WebRadioDialog::volumeChanged(int volume)
+{
+ m_mainWindow.settings().setValue(QStringLiteral("WebRadioPlugin/volume"), volume);
+ m_player->setVolume(volume);
+}
diff --git a/plugins/webradioplugin/webradiodialog.h b/plugins/webradioplugin/webradiodialog.h
new file mode 100644
index 0000000..ed40035
--- /dev/null
+++ b/plugins/webradioplugin/webradiodialog.h
@@ -0,0 +1,36 @@
+#ifndef WEBRADIODIALOG_H
+#define WEBRADIODIALOG_H
+
+#include
+#include
+
+class MainWindow;
+
+namespace Ui { class WebRadioDialog; }
+
+class WebRadioDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit WebRadioDialog(MainWindow &mainWindow);
+ ~WebRadioDialog();
+
+private Q_SLOTS:
+ void stateChanged(QMediaPlayer::State newState);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void error(QMediaPlayer::Error error);
+ void currentIndexChanged(int index);
+ void volumeChanged(int volume);
+ void play();
+
+private:
+ void updateWidgets();
+
+ Ui::WebRadioDialog *ui;
+
+ MainWindow &m_mainWindow;
+ QMediaPlayer *m_player;
+};
+
+#endif // WEBRADIODIALOG_H
diff --git a/plugins/webradioplugin/webradiodialog.ui b/plugins/webradioplugin/webradiodialog.ui
new file mode 100644
index 0000000..5758e10
--- /dev/null
+++ b/plugins/webradioplugin/webradiodialog.ui
@@ -0,0 +1,135 @@
+
+
+ WebRadioDialog
+
+
+
+ 0
+ 0
+ 494
+ 155
+
+
+
+ Radio
+
+
+ -
+
+
+ -
+
+
-
+
+
+
+ 0
+ 50
+
+
+
+ Play
+
+
+
+ -
+
+
+
+ 0
+ 50
+
+
+
+ Pause
+
+
+
+ -
+
+
+
+ 0
+ 50
+
+
+
+ Stop
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+
+ -
+
+
-
+
+
+ state
+
+
+
+ -
+
+
+ mediaStatus
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Close
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ WebRadioDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ WebRadioDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/plugins/webradioplugin/webradioplugin.cpp b/plugins/webradioplugin/webradioplugin.cpp
new file mode 100644
index 0000000..9a749d7
--- /dev/null
+++ b/plugins/webradioplugin/webradioplugin.cpp
@@ -0,0 +1,39 @@
+#include "webradioplugin.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mainwindow.h"
+
+#include "webradiodialog.h"
+
+WebRadioPlugin::WebRadioPlugin(QObject *parent) :
+ ZeiterfassungPlugin(parent)
+{
+ qDebug() << "called";
+
+ static auto dir = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("translations"));
+
+ if(m_translator.load(QLocale(), QStringLiteral("webradioplugin"), QStringLiteral("_"), dir))
+ {
+ if(!QCoreApplication::installTranslator(&m_translator))
+ {
+ qWarning() << "could not install translation webradioplugin";
+ }
+ }
+ else
+ {
+ qWarning() << "could not load translation webradioplugin";
+ }
+}
+
+void WebRadioPlugin::attachTo(MainWindow &mainWindow)
+{
+ auto dialog = new WebRadioDialog(mainWindow);
+ mainWindow.menuTools()->addAction(QIcon(QStringLiteral(":/zeiterfassung/plugins/webradioplugin/images/web-radio.png")),
+ tr("Play webradio"), dialog, &QWidget::show);
+}
diff --git a/plugins/webradioplugin/webradioplugin.h b/plugins/webradioplugin/webradioplugin.h
new file mode 100644
index 0000000..e11932d
--- /dev/null
+++ b/plugins/webradioplugin/webradioplugin.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include
+#include
+
+#include "zeiterfassungplugin.h"
+
+class Q_DECL_EXPORT WebRadioPlugin : public ZeiterfassungPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "dbsoftware.zeiterfassung.plugin/1.0" FILE "webradioplugin.json")
+ Q_INTERFACES(ZeiterfassungPlugin)
+
+public:
+ explicit WebRadioPlugin(QObject *parent = Q_NULLPTR);
+
+ // ZeiterfassungPlugin interface
+ void attachTo(MainWindow &mainWindow) Q_DECL_OVERRIDE;
+
+private:
+ QTranslator m_translator;
+};
diff --git a/plugins/webradioplugin/webradioplugin.json b/plugins/webradioplugin/webradioplugin.json
new file mode 100644
index 0000000..e69de29
diff --git a/plugins/webradioplugin/webradioplugin.pro b/plugins/webradioplugin/webradioplugin.pro
new file mode 100644
index 0000000..28eb042
--- /dev/null
+++ b/plugins/webradioplugin/webradioplugin.pro
@@ -0,0 +1,37 @@
+QT += core network gui widgets multimedia
+
+TARGET = webradioplugin
+TEMPLATE = lib
+
+CONFIG += shared c++14
+
+DESTDIR = $${OUT_PWD}/../../bin/plugins/zeiterfassung
+
+LIBS += -L$$OUT_PWD/../../lib -lzeiterfassungcorelib -lzeiterfassungguilib
+
+INCLUDEPATH += $$PWD/../../zeiterfassungcorelib $$PWD/../../zeiterfassungguilib
+DEPENDPATH += $$PWD/../../zeiterfassungcorelib $$PWD/../../zeiterfassungguilib
+
+DEFINES += QT_DEPRECATED_WARNINGS QT_DISABLE_DEPRECATED_BEFORE=0x060000 QT_MESSAGELOGCONTEXT
+
+HEADERS += webradiodialog.h \
+ webradioplugin.h
+
+SOURCES += webradiodialog.cpp \
+ webradioplugin.cpp
+
+FORMS += webradiodialog.ui
+
+RESOURCES += webradioplugin_resources.qrc
+
+TRANSLATIONS += translations/webradioplugin_en.ts \
+ translations/webradioplugin_de.ts
+
+OTHER_FILES += webradioplugin.json
+
+include(../../lrelease.pri)
+
+COMPILED_TRANSLATIONS += $${OUT_PWD}/translations/webradioplugin_en.qm \
+ $${OUT_PWD}/translations/webradioplugin_de.qm
+
+include(../copy_translations.pri)
diff --git a/plugins/webradioplugin/webradioplugin_resources.qrc b/plugins/webradioplugin/webradioplugin_resources.qrc
new file mode 100644
index 0000000..f7b12b5
--- /dev/null
+++ b/plugins/webradioplugin/webradioplugin_resources.qrc
@@ -0,0 +1,5 @@
+
+
+ images/web-radio.png
+
+