From 4ff069de1ba7fb0ce03b1d171f9cde432d7470b8 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 <0xFEEDC0DE64@gmail.com> Date: Mon, 17 Sep 2018 19:36:22 +0200 Subject: [PATCH] Imported existing sources --- advancedviewdialog.cpp | 268 ++++++++++++++++++++++++++ advancedviewdialog.h | 29 +++ advancedviewdialog.ui | 81 ++++++++ advancedviewplugin.cpp | 38 ++++ advancedviewplugin.h | 24 +++ advancedviewplugin.json | 0 advancedviewplugin.pro | 34 ++++ advancedviewplugin_resources.qrc | 5 + advancedviewwidget.cpp | 30 +++ advancedviewwidget.h | 20 ++ dialogs/bookingdialog.cpp | 54 ++++++ dialogs/bookingdialog.h | 31 +++ dialogs/bookingdialog.ui | 163 ++++++++++++++++ dialogs/timeassignmentdialog.cpp | 119 ++++++++++++ dialogs/timeassignmentdialog.h | 42 ++++ dialogs/timeassignmentdialog.ui | 184 ++++++++++++++++++ images/advanced-view.png | Bin 0 -> 2772 bytes models/bookingsmodel.cpp | 93 +++++++++ models/bookingsmodel.h | 37 ++++ models/timeassignmentsmodel.cpp | 97 ++++++++++ models/timeassignmentsmodel.h | 38 ++++ translations/advancedviewplugin_de.ts | 240 +++++++++++++++++++++++ translations/advancedviewplugin_en.ts | 240 +++++++++++++++++++++++ 23 files changed, 1867 insertions(+) create mode 100644 advancedviewdialog.cpp create mode 100644 advancedviewdialog.h create mode 100644 advancedviewdialog.ui create mode 100644 advancedviewplugin.cpp create mode 100644 advancedviewplugin.h create mode 100644 advancedviewplugin.json create mode 100644 advancedviewplugin.pro create mode 100644 advancedviewplugin_resources.qrc create mode 100644 advancedviewwidget.cpp create mode 100644 advancedviewwidget.h create mode 100644 dialogs/bookingdialog.cpp create mode 100644 dialogs/bookingdialog.h create mode 100644 dialogs/bookingdialog.ui create mode 100644 dialogs/timeassignmentdialog.cpp create mode 100644 dialogs/timeassignmentdialog.h create mode 100644 dialogs/timeassignmentdialog.ui create mode 100644 images/advanced-view.png create mode 100644 models/bookingsmodel.cpp create mode 100644 models/bookingsmodel.h create mode 100644 models/timeassignmentsmodel.cpp create mode 100644 models/timeassignmentsmodel.h create mode 100644 translations/advancedviewplugin_de.ts create mode 100644 translations/advancedviewplugin_en.ts diff --git a/advancedviewdialog.cpp b/advancedviewdialog.cpp new file mode 100644 index 0000000..7eb5ef4 --- /dev/null +++ b/advancedviewdialog.cpp @@ -0,0 +1,268 @@ +#include "advancedviewdialog.h" +#include "ui_advancedviewdialog.h" + +#include +#include +#include +#include + +#include "replies/createbookingreply.h" +#include "replies/updatebookingreply.h" +#include "replies/deletebookingreply.h" +#include "replies/createtimeassignmentreply.h" +#include "replies/updatetimeassignmentreply.h" +#include "replies/deletetimeassignmentreply.h" + +#include "stripswidget.h" +#include "mainwindow.h" +#include "timeutils.h" +#include "dialogs/bookingdialog.h" +#include "dialogs/timeassignmentdialog.h" +#include "models/bookingsmodel.h" +#include "models/timeassignmentsmodel.h" + +AdvancedViewDialog::AdvancedViewDialog(StripsWidget &stripsWidget, QWidget *parent) : + ZeiterfassungDialog(parent), + ui(new Ui::AdvancedViewDialog), + m_stripsWidget(stripsWidget), + m_bookingsModel(new BookingsModel(stripsWidget, this)), + m_timeAssignmentsModel(new TimeAssignmentsModel(stripsWidget, this)) +{ + ui->setupUi(this); + + ui->bookingsView->setModel(m_bookingsModel); + ui->bookingsView->setEnabled(m_bookingsModel->enabled()); + connect(m_bookingsModel, &BookingsModel::enabledChanged, ui->bookingsView, &QWidget::setEnabled); + connect(ui->bookingsView, &QWidget::customContextMenuRequested, this, &AdvancedViewDialog::contextMenuBooking); + + ui->timeAssignmentsView->setModel(m_timeAssignmentsModel); + ui->timeAssignmentsView->setEnabled(m_timeAssignmentsModel->enabled()); + connect(m_timeAssignmentsModel, &TimeAssignmentsModel::enabledChanged, ui->timeAssignmentsView, &QWidget::setEnabled); + connect(ui->timeAssignmentsView, &QWidget::customContextMenuRequested, this, &AdvancedViewDialog::contextMenuTimeAssignment); +} + +AdvancedViewDialog::~AdvancedViewDialog() +{ + delete ui; +} + +void AdvancedViewDialog::contextMenuBooking(const QPoint &pos) +{ + auto index = ui->bookingsView->indexAt(pos); + + if(!index.isValid()) + { + QMenu menu; + auto createAction = menu.addAction(tr("Create booking")); + auto refreshAction = menu.addAction(QIcon(QPixmap(QStringLiteral(":/zeiterfassungguilib/images/refresh.png"))), tr("Refresh bookings")); + auto selectedAction = menu.exec(ui->bookingsView->viewport()->mapToGlobal(pos)); + if(selectedAction == createAction) + { + BookingDialog dialog(this); + dialog.setTime(timeNormalise(QTime::currentTime())); + again2: + if(dialog.exec() == QDialog::Accepted) + { + auto reply = m_stripsWidget.mainWindow().erfassung().doCreateBooking( + m_stripsWidget.mainWindow().userInfo().userId, + m_stripsWidget.date(), + dialog.getTime(), + dialog.getTimespan(), + dialog.getType(), + dialog.getText() + ); + + reply->waitForFinished(); + + if(reply->success()) + { + m_stripsWidget.refreshBookings(); + } + else + { + QMessageBox::warning(this, tr("Could not create booking!"), tr("Could not create booking!") % "\n\n" % reply->message()); + goto again2; + } + } + } + else if(selectedAction == refreshAction) + { + m_stripsWidget.refreshBookings(); + } + } + else + { + auto booking = m_stripsWidget.bookings().at(index.row()); + + QMenu menu; + auto editAction = menu.addAction(tr("Edit booking")); + auto deleteAction = menu.addAction(tr("Delete booking")); + auto selectedAction = menu.exec(ui->bookingsView->viewport()->mapToGlobal(pos)); + if(selectedAction == editAction) + { + BookingDialog dialog(this); + dialog.setTime(booking.time); + dialog.setTimespan(booking.timespan); + dialog.setType(booking.type); + dialog.setText(booking.text); + again1: + if(dialog.exec() == QDialog::Accepted) + { + auto reply = m_stripsWidget.mainWindow().erfassung().doUpdateBooking( + booking.id, + m_stripsWidget.mainWindow().userInfo().userId, + m_stripsWidget.date(), + dialog.getTime(), + dialog.getTimespan(), + dialog.getType(), + dialog.getText() + ); + + reply->waitForFinished(); + + if(reply->success()) + { + m_stripsWidget.refreshBookings(); + } + else + { + QMessageBox::warning(this, tr("Could not edit booking!"), tr("Could not edit booking!") % "\n\n" % reply->message()); + goto again1; + } + } + } + else if(selectedAction == deleteAction) + { + QMessageBox msgBox; + msgBox.setText(tr("Do you really want to delete the booking?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Cancel); + if(msgBox.exec() == QMessageBox::Yes) + { + auto reply = m_stripsWidget.mainWindow().erfassung().doDeleteBooking(booking.id); + + reply->waitForFinished(); + + if(reply->success()) + m_stripsWidget.refreshBookings(); + else + QMessageBox::warning(this, tr("Could not delete booking!"), tr("Could not delete booking!") % "\n\n" % reply->message()); + } + } + } +} + +void AdvancedViewDialog::contextMenuTimeAssignment(const QPoint &pos) +{ + auto index = ui->timeAssignmentsView->indexAt(pos); + + if(!index.isValid()) + { + QMenu menu; + auto createAction = menu.addAction(tr("Create time assignment")); + auto refreshAction = menu.addAction(QIcon(QPixmap(QStringLiteral(":/zeiterfassungguilib/images/refresh.png"))), tr("Refresh time assignments")); + auto selectedAction = menu.exec(ui->timeAssignmentsView->viewport()->mapToGlobal(pos)); + if(selectedAction == createAction) + { + TimeAssignmentDialog dialog(m_stripsWidget.mainWindow().projects(), + m_stripsWidget.mainWindow().settings(), this); + again2: + if(dialog.exec() == QDialog::Accepted) + { + auto reply = m_stripsWidget.mainWindow().erfassung().doCreateTimeAssignment( + m_stripsWidget.mainWindow().userInfo().userId, + m_stripsWidget.date(), + dialog.getTime(), + dialog.getTimespan(), + dialog.getProject(), + dialog.getSubproject(), + dialog.getWorkpackage(), + dialog.getText() + ); + + reply->waitForFinished(); + + if(reply->success()) + { + m_stripsWidget.refreshTimeAssignments(); + } + else + { + QMessageBox::warning(this, tr("Could not create time assignment!"), tr("Could not create time assignment!") % "\n\n" % reply->message()); + goto again2; + } + } + } + else if(selectedAction == refreshAction) + { + m_stripsWidget.refreshTimeAssignments(); + } + } + else + { + auto timeAssignment = m_stripsWidget.timeAssignments().at(index.row()); + + QMenu menu; + auto editAction = menu.addAction(tr("Edit time assignment")); + auto deleteAction = menu.addAction(tr("Delete time assignment")); + auto selectedAction = menu.exec(ui->timeAssignmentsView->viewport()->mapToGlobal(pos)); + if(selectedAction == editAction) + { + TimeAssignmentDialog dialog(m_stripsWidget.mainWindow().projects(), + m_stripsWidget.mainWindow().settings(), this); + dialog.setTime(timeAssignment.time); + dialog.setTimespan(timeAssignment.timespan); + dialog.setProject(timeAssignment.project); + dialog.setSubproject(timeAssignment.subproject); + dialog.setWorkpackage(timeAssignment.workpackage); + dialog.setText(timeAssignment.text); + again1: + if(dialog.exec() == QDialog::Accepted) + { + auto reply = m_stripsWidget.mainWindow().erfassung().doUpdateTimeAssignment( + timeAssignment.id, + m_stripsWidget.mainWindow().userInfo().userId, + m_stripsWidget.date(), + dialog.getTime(), + dialog.getTimespan(), + dialog.getProject(), + dialog.getSubproject(), + dialog.getWorkpackage(), + dialog.getText() + ); + + reply->waitForFinished(); + + if(reply->success()) + { + m_stripsWidget.refreshTimeAssignments(); + } + else + { + QMessageBox::warning(this, tr("Could not edit time assignment!"), tr("Could not edit time assignment!") % "\n\n" % reply->message()); + goto again1; + } + } + } + else if(selectedAction == deleteAction) + { + QMessageBox msgBox; + msgBox.setText(tr("Do you really want to delete the time assignment?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Cancel); + if(msgBox.exec() == QMessageBox::Yes) + { + auto reply = m_stripsWidget.mainWindow().erfassung().doDeleteTimeAssignment(timeAssignment.id); + + reply->waitForFinished(); + + if(reply->success()) + { + m_stripsWidget.refreshTimeAssignments(); + } + else + QMessageBox::warning(this, tr("Could not delete time assignment!"), tr("Could not delete time assignment!") % "\n\n" % reply->message()); + } + } + } +} diff --git a/advancedviewdialog.h b/advancedviewdialog.h new file mode 100644 index 0000000..9a0c223 --- /dev/null +++ b/advancedviewdialog.h @@ -0,0 +1,29 @@ +#pragma once + +#include "zeiterfassungdialog.h" + +namespace Ui { class AdvancedViewDialog; } +class StripsWidget; +class BookingsModel; +class TimeAssignmentsModel; + +class AdvancedViewDialog : public ZeiterfassungDialog +{ + Q_OBJECT + +public: + explicit AdvancedViewDialog(StripsWidget &stripsWidget, QWidget *parent = Q_NULLPTR); + ~AdvancedViewDialog(); + +private Q_SLOTS: + void contextMenuBooking(const QPoint &pos); + void contextMenuTimeAssignment(const QPoint &pos); + +private: + Ui::AdvancedViewDialog *ui; + + StripsWidget &m_stripsWidget; + + BookingsModel *m_bookingsModel; + TimeAssignmentsModel *m_timeAssignmentsModel; +}; diff --git a/advancedviewdialog.ui b/advancedviewdialog.ui new file mode 100644 index 0000000..0d87750 --- /dev/null +++ b/advancedviewdialog.ui @@ -0,0 +1,81 @@ + + + AdvancedViewDialog + + + + 0 + 0 + 1024 + 480 + + + + Advanced view + + + + + + Qt::Vertical + + + + Qt::CustomContextMenu + + + + + Qt::CustomContextMenu + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + AdvancedViewDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AdvancedViewDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/advancedviewplugin.cpp b/advancedviewplugin.cpp new file mode 100644 index 0000000..3b3f308 --- /dev/null +++ b/advancedviewplugin.cpp @@ -0,0 +1,38 @@ +#include "advancedviewplugin.h" + +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "stripswidget.h" + +#include "advancedviewwidget.h" + +AdvancedViewPlugin::AdvancedViewPlugin(QObject *parent) : + ZeiterfassungPlugin(parent) +{ + qDebug() << "called"; + + static auto dir = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("translations")); + + if(m_translator.load(QLocale(), QStringLiteral("advancedviewplugin"), QStringLiteral("_"), dir)) + { + if(!QCoreApplication::installTranslator(&m_translator)) + { + qWarning() << "could not install translation advancedviewplugin"; + } + } + else + { + qWarning() << "could not load translation advancedviewplugin"; + } +} + +void AdvancedViewPlugin::attachTo(MainWindow &mainWindow) +{ + for(auto stripsWidget : mainWindow.stripsWidgets()) + stripsWidget->headerLayout()->addWidget(new AdvancedViewWidget(*stripsWidget)); +} diff --git a/advancedviewplugin.h b/advancedviewplugin.h new file mode 100644 index 0000000..0e2c7ad --- /dev/null +++ b/advancedviewplugin.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "zeiterfassungplugin.h" + +class MainWindow; + +class Q_DECL_EXPORT AdvancedViewPlugin : public ZeiterfassungPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "dbsoftware.zeiterfassung.plugin/1.0" FILE "advancedviewplugin.json") + Q_INTERFACES(ZeiterfassungPlugin) + +public: + explicit AdvancedViewPlugin(QObject *parent = Q_NULLPTR); + + // ZeiterfassungPlugin interface + void attachTo(MainWindow &mainWindow) Q_DECL_OVERRIDE; + +private: + QTranslator m_translator; +}; diff --git a/advancedviewplugin.json b/advancedviewplugin.json new file mode 100644 index 0000000..e69de29 diff --git a/advancedviewplugin.pro b/advancedviewplugin.pro new file mode 100644 index 0000000..00842f7 --- /dev/null +++ b/advancedviewplugin.pro @@ -0,0 +1,34 @@ +QT += core network gui widgets + +DBLIBS += zeiterfassungcore zeiterfassunggui + +TARGET = advancedviewplugin + +HEADERS += advancedviewdialog.h \ + advancedviewplugin.h \ + advancedviewwidget.h \ + dialogs/bookingdialog.h \ + dialogs/timeassignmentdialog.h \ + models/bookingsmodel.h \ + models/timeassignmentsmodel.h + +SOURCES += advancedviewdialog.cpp \ + advancedviewplugin.cpp \ + advancedviewwidget.cpp \ + dialogs/bookingdialog.cpp \ + dialogs/timeassignmentdialog.cpp \ + models/bookingsmodel.cpp \ + models/timeassignmentsmodel.cpp + +FORMS += advancedviewdialog.ui \ + dialogs/bookingdialog.ui \ + dialogs/timeassignmentdialog.ui + +RESOURCES += advancedviewplugin_resources.qrc + +TRANSLATIONS += translations/advancedviewplugin_en.ts \ + translations/advancedviewplugin_de.ts + +OTHER_FILES += advancedviewplugin.json + +include(../plugin.pri) diff --git a/advancedviewplugin_resources.qrc b/advancedviewplugin_resources.qrc new file mode 100644 index 0000000..6b72660 --- /dev/null +++ b/advancedviewplugin_resources.qrc @@ -0,0 +1,5 @@ + + + images/advanced-view.png + + diff --git a/advancedviewwidget.cpp b/advancedviewwidget.cpp new file mode 100644 index 0000000..be52d8d --- /dev/null +++ b/advancedviewwidget.cpp @@ -0,0 +1,30 @@ +#include "advancedviewwidget.h" + +#include + +#include "stripswidget.h" +#include "advancedviewdialog.h" + +AdvancedViewWidget::AdvancedViewWidget(StripsWidget &stripsWidget) : + QToolButton(&stripsWidget), + m_stripsWidget(stripsWidget) +{ + setIcon(QIcon(QStringLiteral(":/zeiterfassung/plugins/advancedviewplugin/images/advanced-view.png"))); + setText(tr("Advanced view")); + + connect(&stripsWidget, &StripsWidget::dateChanged, this, &AdvancedViewWidget::dateChanged); + dateChanged(stripsWidget.date()); + + connect(this, &QAbstractButton::pressed, this, &AdvancedViewWidget::pressedSlot); +} + +void AdvancedViewWidget::dateChanged(const QDate &date) +{ + setEnabled(date.isValid()); +} + +void AdvancedViewWidget::pressedSlot() +{ + AdvancedViewDialog dialog(m_stripsWidget, this); + dialog.exec(); +} diff --git a/advancedviewwidget.h b/advancedviewwidget.h new file mode 100644 index 0000000..d1004a8 --- /dev/null +++ b/advancedviewwidget.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +class StripsWidget; + +class AdvancedViewWidget : public QToolButton +{ + Q_OBJECT + +public: + explicit AdvancedViewWidget(StripsWidget &stripsWidget); + +private Q_SLOTS: + void dateChanged(const QDate &date); + void pressedSlot(); + +private: + StripsWidget &m_stripsWidget; +}; diff --git a/dialogs/bookingdialog.cpp b/dialogs/bookingdialog.cpp new file mode 100644 index 0000000..a2d42df --- /dev/null +++ b/dialogs/bookingdialog.cpp @@ -0,0 +1,54 @@ +#include "bookingdialog.h" +#include "ui_bookingdialog.h" + +BookingDialog::BookingDialog(QWidget *parent) : + ZeiterfassungDialog(parent), + ui(new Ui::BookingDialog) +{ + ui->setupUi(this); +} + +BookingDialog::~BookingDialog() +{ + delete ui; +} + +QTime BookingDialog::getTime() const +{ + return ui->timeEditTime->time(); +} + +void BookingDialog::setTime(const QTime &time) +{ + ui->timeEditTime->setTime(time); +} + +QTime BookingDialog::getTimespan() const +{ + return ui->timeEditTimespan->time(); +} + +void BookingDialog::setTimespan(const QTime ×pan) +{ + ui->timeEditTimespan->setTime(timespan); +} + +QString BookingDialog::getType() const +{ + return ui->comboBoxType->currentText(); +} + +void BookingDialog::setType(const QString &type) +{ + ui->comboBoxType->setCurrentText(type); +} + +QString BookingDialog::getText() const +{ + return ui->lineEditText->text(); +} + +void BookingDialog::setText(const QString &text) +{ + ui->lineEditText->setText(text); +} diff --git a/dialogs/bookingdialog.h b/dialogs/bookingdialog.h new file mode 100644 index 0000000..841a0db --- /dev/null +++ b/dialogs/bookingdialog.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +#include "zeiterfassungdialog.h" + +namespace Ui { class BookingDialog; } + +class BookingDialog : public ZeiterfassungDialog +{ + Q_OBJECT + +public: + explicit BookingDialog(QWidget *parent = Q_NULLPTR); + ~BookingDialog(); + + QTime getTime() const; + void setTime(const QTime &time); + + QTime getTimespan() const; + void setTimespan(const QTime ×pan); + + QString getType() const; + void setType(const QString &type); + + QString getText() const; + void setText(const QString &text); + +private: + Ui::BookingDialog *ui; +}; diff --git a/dialogs/bookingdialog.ui b/dialogs/bookingdialog.ui new file mode 100644 index 0000000..6e79a85 --- /dev/null +++ b/dialogs/bookingdialog.ui @@ -0,0 +1,163 @@ + + + BookingDialog + + + + 0 + 0 + 400 + 237 + + + + + 16777215 + 0 + + + + Booking + + + + + + + 20 + + + + Booking + + + + + + + + + Time: + + + timeEditTime + + + + + + + Timespan: + + + timeEditTimespan + + + + + + + Type: + + + comboBoxType + + + + + + + Text: + + + lineEditText + + + + + + + HH:mm:ss + + + + + + + HH:mm:ss + + + + + + + + + + true + + + QComboBox::NoInsert + + + + K + + + + + G + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + BookingDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + BookingDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/dialogs/timeassignmentdialog.cpp b/dialogs/timeassignmentdialog.cpp new file mode 100644 index 0000000..13abd07 --- /dev/null +++ b/dialogs/timeassignmentdialog.cpp @@ -0,0 +1,119 @@ +#include "timeassignmentdialog.h" +#include "ui_timeassignmentdialog.h" + +#include +#include +#include + +#include "zeiterfassungsettings.h" + +TimeAssignmentDialog::TimeAssignmentDialog(const QMap &projects, const ZeiterfassungSettings &settings, + QWidget *parent) : + ZeiterfassungDialog(parent), + ui(new Ui::TimeAssignmentDialog) +{ + ui->setupUi(this); + + { + for(const auto &preferedProject : settings.projects()) + { + if(!projects.contains(preferedProject)) + { + qWarning() << "cannot find project" << preferedProject; + continue; + } + + ui->comboBoxProject->addItem(tr("%0 (%1)").arg(projects.value(preferedProject)).arg(preferedProject), preferedProject); + } + + if(settings.projects().count()) + ui->comboBoxProject->insertSeparator(ui->comboBoxProject->count()); + + for(auto iter = projects.constBegin(); iter != projects.constEnd(); iter++) + { + if(!settings.projects().contains(iter.key())) + ui->comboBoxProject->addItem(tr("%0 (%1)").arg(iter.value()).arg(iter.key()), iter.key()); + } + } + + for(const auto &subproject : settings.subprojects()) + ui->comboBoxSubproject->addItem(subproject); + ui->comboBoxSubproject->clearEditText(); + + for(const auto &workpackage : settings.workpackages()) + ui->comboBoxWorkpackage->addItem(workpackage); + ui->comboBoxWorkpackage->clearEditText(); + + for(const auto &text : settings.texts()) + ui->comboBoxText->addItem(text); + ui->comboBoxText->clearEditText(); +} + +TimeAssignmentDialog::~TimeAssignmentDialog() +{ + delete ui; +} + +QTime TimeAssignmentDialog::getTime() const +{ + return ui->timeEditTime->time(); +} + +void TimeAssignmentDialog::setTime(const QTime &time) +{ + ui->timeEditTime->setTime(time); +} + +QTime TimeAssignmentDialog::getTimespan() const +{ + return ui->timeEditTimespan->time(); +} + +void TimeAssignmentDialog::setTimespan(const QTime ×pan) +{ + ui->timeEditTimespan->setTime(timespan); +} + +QString TimeAssignmentDialog::getProject() const +{ + return ui->comboBoxProject->currentData().toString(); +} + +void TimeAssignmentDialog::setProject(const QString &project) +{ + auto index = ui->comboBoxProject->findData(project); + if(index >= 0) + ui->comboBoxProject->setCurrentIndex(index); + else + qWarning() << "could not find project" << project; +} + +QString TimeAssignmentDialog::getSubproject() const +{ + return ui->comboBoxSubproject->currentText(); +} + +void TimeAssignmentDialog::setSubproject(const QString &subproject) +{ + ui->comboBoxSubproject->setCurrentText(subproject); +} + +QString TimeAssignmentDialog::getWorkpackage() const +{ + return ui->comboBoxWorkpackage->currentText(); +} + +void TimeAssignmentDialog::setWorkpackage(const QString &workpackage) +{ + ui->comboBoxWorkpackage->setCurrentText(workpackage); +} + +QString TimeAssignmentDialog::getText() const +{ + return ui->comboBoxText->currentText(); +} + +void TimeAssignmentDialog::setText(const QString &text) +{ + ui->comboBoxText->setCurrentText(text); +} diff --git a/dialogs/timeassignmentdialog.h b/dialogs/timeassignmentdialog.h new file mode 100644 index 0000000..916fd09 --- /dev/null +++ b/dialogs/timeassignmentdialog.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +#include "zeiterfassungdialog.h" + +template class QMap; + +class ZeiterfassungSettings; + +namespace Ui { class TimeAssignmentDialog; } + +class TimeAssignmentDialog : public ZeiterfassungDialog +{ + Q_OBJECT + +public: + explicit TimeAssignmentDialog(const QMap &projects, const ZeiterfassungSettings &settings, + QWidget *parent = Q_NULLPTR); + ~TimeAssignmentDialog(); + + QTime getTime() const; + void setTime(const QTime &time); + + QTime getTimespan() const; + void setTimespan(const QTime ×pan); + + QString getProject() const; + void setProject(const QString &project); + + QString getSubproject() const; + void setSubproject(const QString &subproject); + + QString getWorkpackage() const; + void setWorkpackage(const QString &workpackage); + + QString getText() const; + void setText(const QString &text); + +private: + Ui::TimeAssignmentDialog *ui; +}; diff --git a/dialogs/timeassignmentdialog.ui b/dialogs/timeassignmentdialog.ui new file mode 100644 index 0000000..3587f7c --- /dev/null +++ b/dialogs/timeassignmentdialog.ui @@ -0,0 +1,184 @@ + + + TimeAssignmentDialog + + + + 0 + 0 + 400 + 307 + + + + + 16777215 + 0 + + + + Time assignment + + + + + + + 20 + + + + Time assignment + + + + + + + + + Time: + + + timeEditTime + + + + + + + Timespan: + + + timeEditTimespan + + + + + + + Project: + + + comboBoxProject + + + + + + + Subproject: + + + + + + + Workpackage: + + + + + + + Text: + + + + + + + HH:mm:ss + + + + + + + HH:mm:ss + + + + + + + + + + true + + + QComboBox::NoInsert + + + + + + + true + + + QComboBox::NoInsert + + + + + + + true + + + QComboBox::NoInsert + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + TimeAssignmentDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + TimeAssignmentDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/images/advanced-view.png b/images/advanced-view.png new file mode 100644 index 0000000000000000000000000000000000000000..7a6c875cfd20053e6c267a5d0bc1ea5e3c711c5b GIT binary patch literal 2772 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 T>iF{*sI}_p>gTe~DWM4f!P(AS literal 0 HcmV?d00001 diff --git a/models/bookingsmodel.cpp b/models/bookingsmodel.cpp new file mode 100644 index 0000000..4c59657 --- /dev/null +++ b/models/bookingsmodel.cpp @@ -0,0 +1,93 @@ +#include "bookingsmodel.h" + +#include "stripswidget.h" + +BookingsModel::BookingsModel(StripsWidget &stripsWidget, QObject *parent) : + QAbstractListModel(parent), + m_stripsWidget(stripsWidget) +{ + connect(&stripsWidget, &StripsWidget::bookingsChanged, this, &BookingsModel::bookingsChanged); + connect(&stripsWidget, &StripsWidget::refreshingBookingsChanged, this, &BookingsModel::refreshingChanged); +} + +StripsWidget &BookingsModel::stripsWidget() const +{ + return m_stripsWidget; +} + +bool BookingsModel::enabled() const +{ + return !m_stripsWidget.refreshingBookings(); +} + +int BookingsModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + + return m_stripsWidget.bookings().count(); +} + +int BookingsModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + + return 5; +} + +QVariant BookingsModel::data(const QModelIndex &index, int role) const +{ + Q_ASSERT(index.row() < m_stripsWidget.bookings().count()); + const auto &booking = m_stripsWidget.bookings().at(index.row()); + + switch(role) + { + case Qt::DisplayRole: + case Qt::EditRole: + switch(index.column()) + { + case 0: return booking.id; + case 1: return booking.time; + case 2: return booking.timespan; + case 3: return booking.type; + case 4: return booking.text; + } + } + + return QVariant(); +} + +QVariant BookingsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + switch(orientation) + { + case Qt::Horizontal: + switch(role) + { + case Qt::DisplayRole: + case Qt::EditRole: + switch(section) + { + case 0: return tr("ID"); + case 1: return tr("Time"); + case 2: return tr("Timespan"); + case 3: return tr("Type"); + case 4: return tr("Text"); + } + } + default: + qt_noop(); + } + + return QVariant(); +} + +void BookingsModel::bookingsChanged() +{ + beginResetModel(); + endResetModel(); +} + +void BookingsModel::refreshingChanged(bool refreshing) +{ + Q_EMIT enabledChanged(!refreshing); +} diff --git a/models/bookingsmodel.h b/models/bookingsmodel.h new file mode 100644 index 0000000..fd8b654 --- /dev/null +++ b/models/bookingsmodel.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +#include "zeiterfassungapi.h" + +class StripsWidget; + +class BookingsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged) + +public: + explicit BookingsModel(StripsWidget &stripsWidget, QObject *parent = Q_NULLPTR); + + StripsWidget &stripsWidget() const; + + bool enabled() const; + + // QAbstractItemModel interface + int rowCount(const QModelIndex &parent) const Q_DECL_OVERRIDE; + int columnCount(const QModelIndex &parent) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; + QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE; + +Q_SIGNALS: + void enabledChanged(bool enabled); + +private Q_SLOTS: + void bookingsChanged(); + void refreshingChanged(bool refreshing); + +private: + StripsWidget &m_stripsWidget; +}; diff --git a/models/timeassignmentsmodel.cpp b/models/timeassignmentsmodel.cpp new file mode 100644 index 0000000..73a1a70 --- /dev/null +++ b/models/timeassignmentsmodel.cpp @@ -0,0 +1,97 @@ +#include "timeassignmentsmodel.h" + +#include "stripswidget.h" + +TimeAssignmentsModel::TimeAssignmentsModel(StripsWidget &stripsWidget, QObject *parent) : + QAbstractListModel(parent), + m_stripsWidget(stripsWidget) +{ + connect(&stripsWidget, &StripsWidget::timeAssignmentsChanged, this, &TimeAssignmentsModel::timeAssignmentsChanged); + connect(&stripsWidget, &StripsWidget::refreshingTimeAssignmentsChanged, this, &TimeAssignmentsModel::refreshingChanged); +} + +StripsWidget &TimeAssignmentsModel::stripsWidget() const +{ + return m_stripsWidget; +} + +bool TimeAssignmentsModel::enabled() const +{ + return !m_stripsWidget.refreshingTimeAssignments(); +} + +int TimeAssignmentsModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + + return m_stripsWidget.timeAssignments().count(); +} + +int TimeAssignmentsModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + + return 7; +} + +QVariant TimeAssignmentsModel::data(const QModelIndex &index, int role) const +{ + Q_ASSERT(index.row() < m_stripsWidget.timeAssignments().count()); + const auto &timeAssignment = m_stripsWidget.timeAssignments().at(index.row()); + + switch(role) + { + case Qt::DisplayRole: + case Qt::EditRole: + switch(index.column()) + { + case 0: return timeAssignment.id; + case 1: return timeAssignment.time; + case 2: return timeAssignment.timespan; + case 3: return timeAssignment.project; + case 4: return timeAssignment.subproject; + case 5: return timeAssignment.workpackage; + case 6: return timeAssignment.text; + } + } + + return QVariant(); +} + +QVariant TimeAssignmentsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + switch(orientation) + { + case Qt::Horizontal: + switch(role) + { + case Qt::DisplayRole: + case Qt::EditRole: + switch(section) + { + case 0: return tr("ID"); + case 1: return tr("Time"); + case 2: return tr("Timespan"); + case 3: return tr("Project"); + case 4: return tr("Subproject"); + case 5: return tr("Workpackage"); + case 6: return tr("Text"); + } + } + default: + qt_noop(); + } + + return QVariant(); +} + +void TimeAssignmentsModel::timeAssignmentsChanged() +{ + beginResetModel(); + endResetModel(); +} + +void TimeAssignmentsModel::refreshingChanged(bool refreshing) +{ + Q_EMIT enabledChanged(!refreshing); +} diff --git a/models/timeassignmentsmodel.h b/models/timeassignmentsmodel.h new file mode 100644 index 0000000..cedbcd9 --- /dev/null +++ b/models/timeassignmentsmodel.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +#include "zeiterfassungapi.h" + +class StripsWidget; + +class TimeAssignmentsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged) + +public: + explicit TimeAssignmentsModel(StripsWidget &stripsWidget, QObject *parent = Q_NULLPTR); + + StripsWidget &stripsWidget() const; + + bool enabled() const; + + // QAbstractItemModel interface + int rowCount(const QModelIndex &parent) const Q_DECL_OVERRIDE; + int columnCount(const QModelIndex &parent) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; + QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE; + +Q_SIGNALS: + void stripsWidgetChanged(StripsWidget *stripsWidget); + void enabledChanged(bool enabled); + +private Q_SLOTS: + void timeAssignmentsChanged(); + void refreshingChanged(bool refreshing); + +private: + StripsWidget &m_stripsWidget; +}; diff --git a/translations/advancedviewplugin_de.ts b/translations/advancedviewplugin_de.ts new file mode 100644 index 0000000..b68cae8 --- /dev/null +++ b/translations/advancedviewplugin_de.ts @@ -0,0 +1,240 @@ + + + + + AdvancedViewDialog + + + Advanced view + Erweiterte Anzeige + + + + Create booking + Buchung erstellen + + + + Refresh bookings + Buchungen aktualisieren + + + + Could not create booking! + Konnte Buchung nicht erstellen! + + + + Edit booking + Buchung bearbeiten + + + + Delete booking + Buchung löschen + + + + Could not edit booking! + Konnte Buchung nicht bearbeiten! + + + + Do you really want to delete the booking? + Möchten Sie die Buchung wirklich löschen? + + + + Could not delete booking! + Konnte Buchung nicht löschen! + + + + Create time assignment + Kontierung erstellen + + + + Refresh time assignments + Kontierungen aktualisieren + + + + Could not create time assignment! + Konnte Kontierung nicht erstellen! + + + + Edit time assignment + Kontierung bearbeiten + + + + Delete time assignment + Kontierung löschen + + + + Could not edit time assignment! + Konnte Kontierung nicht bearbeiten! + + + + Do you really want to delete the time assignment? + Möchten Sie die Kontierung wirklich löschen? + + + + Could not delete time assignment! + Konnte Kontierung nicht löschen! + + + + AdvancedViewWidget + + + Advanced view + Erweiterte Anzeige + + + + BookingDialog + + + + Booking + Buchung + + + + Time: + Zeit: + + + + Timespan: + Zeitspanne: + + + + Type: + Typ: + + + + Text: + Text: + + + + BookingsModel + + + ID + ID + + + + Time + Zeit + + + + Timespan + Zeitspanne + + + + Type + Typ + + + + Text + Text + + + + TimeAssignmentDialog + + + + Time assignment + Kontierung + + + + Time: + Zeit: + + + + Timespan: + Zeitspanne: + + + + Project: + Projekt: + + + + Subproject: + Subprojekt: + + + + Workpackage: + Arbeitspaket: + + + + Text: + Text: + + + + + %0 (%1) + %0 (%1) + + + + TimeAssignmentsModel + + + ID + ID + + + + Time + Zeit + + + + Timespan + Zeitspanne + + + + Project + Projekt + + + + Subproject + Subprojekt + + + + Workpackage + Arbeitspaket + + + + Text + Text + + + diff --git a/translations/advancedviewplugin_en.ts b/translations/advancedviewplugin_en.ts new file mode 100644 index 0000000..80acdaf --- /dev/null +++ b/translations/advancedviewplugin_en.ts @@ -0,0 +1,240 @@ + + + + + AdvancedViewDialog + + + Advanced view + + + + + Create booking + + + + + Refresh bookings + + + + + Could not create booking! + + + + + Edit booking + + + + + Delete booking + + + + + Could not edit booking! + + + + + Do you really want to delete the booking? + + + + + Could not delete booking! + + + + + Create time assignment + + + + + Refresh time assignments + + + + + Could not create time assignment! + + + + + Edit time assignment + + + + + Delete time assignment + + + + + Could not edit time assignment! + + + + + Do you really want to delete the time assignment? + + + + + Could not delete time assignment! + + + + + AdvancedViewWidget + + + Advanced view + + + + + BookingDialog + + + + Booking + + + + + Time: + + + + + Timespan: + + + + + Type: + + + + + Text: + + + + + BookingsModel + + + ID + + + + + Time + + + + + Timespan + + + + + Type + + + + + Text + + + + + TimeAssignmentDialog + + + + Time assignment + + + + + Time: + + + + + Timespan: + + + + + Project: + + + + + Subproject: + + + + + Workpackage: + + + + + Text: + + + + + + %0 (%1) + + + + + TimeAssignmentsModel + + + ID + + + + + Time + + + + + Timespan + + + + + Project + + + + + Subproject + + + + + Workpackage + + + + + Text + + + +