diff --git a/plugins/advancedviewplugin/advancedviewplugin.cpp b/plugins/advancedviewplugin/advancedviewplugin.cpp new file mode 100644 index 0000000..e4124ba --- /dev/null +++ b/plugins/advancedviewplugin/advancedviewplugin.cpp @@ -0,0 +1,19 @@ +#include "advancedviewplugin.h" + +#include + +#include "mainwindow.h" +#include "stripswidget.h" +#include "advancedviewwidget.h" + +AdvancedViewPlugin::AdvancedViewPlugin(QObject *parent) : + ZeiterfassungPlugin(parent) +{ + Q_INIT_RESOURCE(advancedviewplugin_resources); +} + +void AdvancedViewPlugin::attachTo(MainWindow &mainWindow) +{ + for(auto stripsWidget : mainWindow.stripsWidgets()) + stripsWidget->headerLayout()->addWidget(new AdvancedViewWidget(*stripsWidget)); +} diff --git a/plugins/advancedviewplugin/advancedviewplugin.h b/plugins/advancedviewplugin/advancedviewplugin.h new file mode 100644 index 0000000..e4a08e8 --- /dev/null +++ b/plugins/advancedviewplugin/advancedviewplugin.h @@ -0,0 +1,23 @@ +#ifndef ADVANCEDVIEWPLUGIN_H +#define ADVANCEDVIEWPLUGIN_H + +#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); +}; + +#endif // ADVANCEDVIEWPLUGIN_H diff --git a/plugins/advancedviewplugin/advancedviewplugin.json b/plugins/advancedviewplugin/advancedviewplugin.json new file mode 100644 index 0000000..e69de29 diff --git a/plugins/advancedviewplugin/advancedviewplugin.pro b/plugins/advancedviewplugin/advancedviewplugin.pro new file mode 100644 index 0000000..a4436d6 --- /dev/null +++ b/plugins/advancedviewplugin/advancedviewplugin.pro @@ -0,0 +1,41 @@ +QT += core network gui widgets + +TARGET = advancedviewplugin +TEMPLATE = lib + +CONFIG += shared c++14 + +DESTDIR = $${OUT_PWD}/../../bin/plugins/zeiterfassung + +LIBS += -L$$OUT_PWD/../../lib -lzeiterfassunglib + +INCLUDEPATH += $$PWD/../../zeiterfassunglib +DEPENDPATH += $$PWD/../../zeiterfassunglib + +DEFINES += QT_DEPRECATED_WARNINGS QT_DISABLE_DEPRECATED_BEFORE=0x060000 QT_MESSAGELOGCONTEXT + +HEADERS += advanvedviewdialog.h \ + advancedviewplugin.h \ + advancedviewwidget.h \ + dialogs/bookingdialog.h \ + dialogs/timeassignmentdialog.h \ + models/bookingsmodel.h \ + models/timeassignmentsmodel.h + +SOURCES += advanvedviewdialog.cpp \ + advancedviewplugin.cpp \ + advancedviewwidget.cpp \ + dialogs/bookingdialog.cpp \ + dialogs/timeassignmentdialog.cpp \ + models/bookingsmodel.cpp \ + models/timeassignmentsmodel.cpp + +FORMS += advanvedviewdialog.ui \ + dialogs/bookingdialog.ui \ + dialogs/timeassignmentdialog.ui + +RESOURCES += advancedviewplugin_resources.qrc + +TRANSLATIONS += + +OTHER_FILES += advancedviewplugin.json diff --git a/plugins/advancedviewplugin/advancedviewplugin_resources.qrc b/plugins/advancedviewplugin/advancedviewplugin_resources.qrc new file mode 100644 index 0000000..c0cfae7 --- /dev/null +++ b/plugins/advancedviewplugin/advancedviewplugin_resources.qrc @@ -0,0 +1,5 @@ + + + images/advanced-view.png + + diff --git a/plugins/advancedviewplugin/advancedviewwidget.cpp b/plugins/advancedviewplugin/advancedviewwidget.cpp new file mode 100644 index 0000000..a48699c --- /dev/null +++ b/plugins/advancedviewplugin/advancedviewwidget.cpp @@ -0,0 +1,29 @@ +#include "advancedviewwidget.h" + +#include + +#include "stripswidget.h" +#include "advanvedviewdialog.h" + +AdvancedViewWidget::AdvancedViewWidget(StripsWidget &stripsWidget) : + QPushButton(&stripsWidget), + m_stripsWidget(stripsWidget) +{ + setIcon(QIcon(QStringLiteral(":/zeiterfassunglib/plugins/advancedviewplugin/images/advanced-view.png"))); + + 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() +{ + AdvanvedViewDialog dialog(m_stripsWidget); + dialog.exec(); +} diff --git a/plugins/advancedviewplugin/advancedviewwidget.h b/plugins/advancedviewplugin/advancedviewwidget.h new file mode 100644 index 0000000..cb3bcd9 --- /dev/null +++ b/plugins/advancedviewplugin/advancedviewwidget.h @@ -0,0 +1,23 @@ +#ifndef ADVANCEDVIEWWIDGET_H +#define ADVANCEDVIEWWIDGET_H + +#include + +class StripsWidget; + +class AdvancedViewWidget : public QPushButton +{ + Q_OBJECT + +public: + explicit AdvancedViewWidget(StripsWidget &stripsWidget); + +private Q_SLOTS: + void dateChanged(const QDate &date); + void pressedSlot(); + +private: + StripsWidget &m_stripsWidget; +}; + +#endif // ADVANCEDVIEWWIDGET_H diff --git a/plugins/advancedviewplugin/advanvedviewdialog.cpp b/plugins/advancedviewplugin/advanvedviewdialog.cpp new file mode 100644 index 0000000..bcc77a9 --- /dev/null +++ b/plugins/advancedviewplugin/advanvedviewdialog.cpp @@ -0,0 +1,293 @@ +#include "advanvedviewdialog.h" +#include "ui_advanvedviewdialog.h" + +#include +#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" + +AdvanvedViewDialog::AdvanvedViewDialog(StripsWidget &stripsWidget) : + QDialog(&stripsWidget.mainWindow()), + ui(new Ui::AdvanvedViewDialog), + 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, &AdvanvedViewDialog::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, &AdvanvedViewDialog::contextMenuTimeAssignment); +} + +AdvanvedViewDialog::~AdvanvedViewDialog() +{ + delete ui; +} + +void AdvanvedViewDialog::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(":/zeiterfassunglib/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() + ); + + { + QEventLoop eventLoop; + connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + } + + 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() + ); + + { + QEventLoop eventLoop; + connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + } + + 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); + + { + QEventLoop eventLoop; + connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + } + + 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 AdvanvedViewDialog::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(":/zeiterfassunglib/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() + ); + + { + QEventLoop eventLoop; + connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + } + + 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() + ); + + { + QEventLoop eventLoop; + connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + } + + 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); + + { + QEventLoop eventLoop; + connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); + eventLoop.exec(); + } + + 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/plugins/advancedviewplugin/advanvedviewdialog.h b/plugins/advancedviewplugin/advanvedviewdialog.h new file mode 100644 index 0000000..4423716 --- /dev/null +++ b/plugins/advancedviewplugin/advanvedviewdialog.h @@ -0,0 +1,32 @@ +#ifndef ADVANVEDVIEWDIALOG_H +#define ADVANVEDVIEWDIALOG_H + +#include + +namespace Ui { class AdvanvedViewDialog; } +class StripsWidget; +class BookingsModel; +class TimeAssignmentsModel; + +class AdvanvedViewDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AdvanvedViewDialog(StripsWidget &stripsWidget); + ~AdvanvedViewDialog(); + +private Q_SLOTS: + void contextMenuBooking(const QPoint &pos); + void contextMenuTimeAssignment(const QPoint &pos); + +private: + Ui::AdvanvedViewDialog *ui; + + StripsWidget &m_stripsWidget; + + BookingsModel *m_bookingsModel; + TimeAssignmentsModel *m_timeAssignmentsModel; +}; + +#endif // ADVANVEDVIEWDIALOG_H diff --git a/plugins/advancedviewplugin/advanvedviewdialog.ui b/plugins/advancedviewplugin/advanvedviewdialog.ui new file mode 100644 index 0000000..0ad8f3f --- /dev/null +++ b/plugins/advancedviewplugin/advanvedviewdialog.ui @@ -0,0 +1,81 @@ + + + AdvanvedViewDialog + + + + 0 + 0 + 1024 + 480 + + + + Advanced view + + + + + + Qt::Vertical + + + + Qt::CustomContextMenu + + + + + Qt::CustomContextMenu + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + AdvanvedViewDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AdvanvedViewDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/zeiterfassunglib/dialogs/bookingdialog.cpp b/plugins/advancedviewplugin/dialogs/bookingdialog.cpp similarity index 100% rename from zeiterfassunglib/dialogs/bookingdialog.cpp rename to plugins/advancedviewplugin/dialogs/bookingdialog.cpp diff --git a/zeiterfassunglib/dialogs/bookingdialog.h b/plugins/advancedviewplugin/dialogs/bookingdialog.h similarity index 100% rename from zeiterfassunglib/dialogs/bookingdialog.h rename to plugins/advancedviewplugin/dialogs/bookingdialog.h diff --git a/zeiterfassunglib/dialogs/bookingdialog.ui b/plugins/advancedviewplugin/dialogs/bookingdialog.ui similarity index 100% rename from zeiterfassunglib/dialogs/bookingdialog.ui rename to plugins/advancedviewplugin/dialogs/bookingdialog.ui diff --git a/zeiterfassunglib/dialogs/timeassignmentdialog.cpp b/plugins/advancedviewplugin/dialogs/timeassignmentdialog.cpp similarity index 100% rename from zeiterfassunglib/dialogs/timeassignmentdialog.cpp rename to plugins/advancedviewplugin/dialogs/timeassignmentdialog.cpp diff --git a/zeiterfassunglib/dialogs/timeassignmentdialog.h b/plugins/advancedviewplugin/dialogs/timeassignmentdialog.h similarity index 100% rename from zeiterfassunglib/dialogs/timeassignmentdialog.h rename to plugins/advancedviewplugin/dialogs/timeassignmentdialog.h diff --git a/zeiterfassunglib/dialogs/timeassignmentdialog.ui b/plugins/advancedviewplugin/dialogs/timeassignmentdialog.ui similarity index 100% rename from zeiterfassunglib/dialogs/timeassignmentdialog.ui rename to plugins/advancedviewplugin/dialogs/timeassignmentdialog.ui diff --git a/plugins/advancedviewplugin/images/advanced-view.png b/plugins/advancedviewplugin/images/advanced-view.png new file mode 100644 index 0000000..7a6c875 Binary files /dev/null and b/plugins/advancedviewplugin/images/advanced-view.png differ diff --git a/plugins/advancedviewplugin/models/bookingsmodel.cpp b/plugins/advancedviewplugin/models/bookingsmodel.cpp new file mode 100644 index 0000000..14ece31 --- /dev/null +++ b/plugins/advancedviewplugin/models/bookingsmodel.cpp @@ -0,0 +1,88 @@ +#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, [=](bool refreshing){ enabledChanged(!refreshing); }); +} + +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(); +} diff --git a/zeiterfassunglib/models/bookingsmodel.h b/plugins/advancedviewplugin/models/bookingsmodel.h similarity index 67% rename from zeiterfassunglib/models/bookingsmodel.h rename to plugins/advancedviewplugin/models/bookingsmodel.h index c6a0e5e..0c02b3e 100644 --- a/zeiterfassunglib/models/bookingsmodel.h +++ b/plugins/advancedviewplugin/models/bookingsmodel.h @@ -12,14 +12,12 @@ class StripsWidget; class ZEITERFASSUNGLIBSHARED_EXPORT BookingsModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(StripsWidget* stripsWidget READ stripsWidget WRITE setStripsWidget NOTIFY stripsWidgetChanged) Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged) public: - explicit BookingsModel(QObject *parent = Q_NULLPTR); + explicit BookingsModel(StripsWidget &stripsWidget, QObject *parent = Q_NULLPTR); - StripsWidget *stripsWidget() const; - void setStripsWidget(StripsWidget *stripsWidget); + StripsWidget &stripsWidget() const; bool enabled() const; @@ -30,16 +28,13 @@ public: 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 bookingsChanged(); - void refreshingChanged(bool refreshing); private: - StripsWidget *m_stripsWidget; - bool m_enabled; + StripsWidget &m_stripsWidget; }; #endif // BOOKINGSMODEL_H diff --git a/plugins/advancedviewplugin/models/timeassignmentsmodel.cpp b/plugins/advancedviewplugin/models/timeassignmentsmodel.cpp new file mode 100644 index 0000000..b33930b --- /dev/null +++ b/plugins/advancedviewplugin/models/timeassignmentsmodel.cpp @@ -0,0 +1,92 @@ +#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, [=](bool refreshing){ enabledChanged(!refreshing); }); +} + +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(); +} diff --git a/zeiterfassunglib/models/timeassignmentsmodel.h b/plugins/advancedviewplugin/models/timeassignmentsmodel.h similarity index 75% rename from zeiterfassunglib/models/timeassignmentsmodel.h rename to plugins/advancedviewplugin/models/timeassignmentsmodel.h index a860a40..b4bb8f3 100644 --- a/zeiterfassunglib/models/timeassignmentsmodel.h +++ b/plugins/advancedviewplugin/models/timeassignmentsmodel.h @@ -12,14 +12,12 @@ class StripsWidget; class ZEITERFASSUNGLIBSHARED_EXPORT TimeAssignmentsModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(StripsWidget* stripsWidget READ stripsWidget WRITE setStripsWidget NOTIFY stripsWidgetChanged) Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged) public: - explicit TimeAssignmentsModel(QObject *parent = Q_NULLPTR); + explicit TimeAssignmentsModel(StripsWidget &stripsWidget, QObject *parent = Q_NULLPTR); - StripsWidget *stripsWidget() const; - void setStripsWidget(StripsWidget *stripsWidget); + StripsWidget &stripsWidget() const; bool enabled() const; @@ -38,8 +36,7 @@ private Q_SLOTS: void refreshingChanged(bool refreshing); private: - StripsWidget *m_stripsWidget; - bool m_enabled; + StripsWidget &m_stripsWidget; }; #endif // TIMEASSIGNMENTSMODEL_H diff --git a/plugins/lunchmealplugin/lunchmealplugin.h b/plugins/lunchmealplugin/lunchmealplugin.h index e73e062..c5626a8 100644 --- a/plugins/lunchmealplugin/lunchmealplugin.h +++ b/plugins/lunchmealplugin/lunchmealplugin.h @@ -12,7 +12,7 @@ class Q_DECL_EXPORT LunchMealPlugin : public ZeiterfassungPlugin Q_INTERFACES(ZeiterfassungPlugin) public: - explicit LunchMealPlugin(QObject *parent = 0); + explicit LunchMealPlugin(QObject *parent = Q_NULLPTR); // ZeiterfassungPlugin interface }; diff --git a/plugins/plugins.pro b/plugins/plugins.pro index 5335e51..e062acc 100644 --- a/plugins/plugins.pro +++ b/plugins/plugins.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs -SUBDIRS += lunchmealplugin \ +SUBDIRS += advancedviewplugin \ + lunchmealplugin \ presenceplugin \ weatherplugin diff --git a/plugins/presenceplugin/presenceplugin.h b/plugins/presenceplugin/presenceplugin.h index 5ccdc86..362c0f1 100644 --- a/plugins/presenceplugin/presenceplugin.h +++ b/plugins/presenceplugin/presenceplugin.h @@ -14,7 +14,7 @@ class Q_DECL_EXPORT PresencePlugin : public ZeiterfassungPlugin Q_INTERFACES(ZeiterfassungPlugin) public: - explicit PresencePlugin(QObject *parent = 0); + explicit PresencePlugin(QObject *parent = Q_NULLPTR); // ZeiterfassungPlugin interface void attachTo(MainWindow &mainWindow); diff --git a/plugins/weatherplugin/weatherplugin.h b/plugins/weatherplugin/weatherplugin.h index 9db873d..f8abc9b 100644 --- a/plugins/weatherplugin/weatherplugin.h +++ b/plugins/weatherplugin/weatherplugin.h @@ -12,7 +12,7 @@ class Q_DECL_EXPORT WeatherPlugin : public ZeiterfassungPlugin Q_INTERFACES(ZeiterfassungPlugin) public: - explicit WeatherPlugin(QObject *parent = 0); + explicit WeatherPlugin(QObject *parent = Q_NULLPTR); // ZeiterfassungPlugin interface }; diff --git a/zeiterfassunglib/mainwindow.cpp b/zeiterfassunglib/mainwindow.cpp index da35f4b..6c3e90d 100644 --- a/zeiterfassunglib/mainwindow.cpp +++ b/zeiterfassunglib/mainwindow.cpp @@ -21,21 +21,13 @@ #include "stripfactory.h" #include "stripswidget.h" #include "dialogs/aboutmedialog.h" -#include "dialogs/bookingdialog.h" -#include "dialogs/timeassignmentdialog.h" #include "dialogs/settingsdialog.h" #include "dialogs/updatedialog.h" -#include "models/bookingsmodel.h" -#include "models/timeassignmentsmodel.h" #include "replies/getprojectsreply.h" #include "replies/getauswertungreply.h" -#include "replies/updatebookingreply.h" -#include "replies/deletebookingreply.h" #include "replies/createbookingreply.h" -#include "replies/updatetimeassignmentreply.h" -#include "replies/deletetimeassignmentreply.h" #include "replies/createtimeassignmentreply.h" -#include "replies/createbookingreply.h" +#include "replies/updatetimeassignmentreply.h" MainWindow::MainWindow(ZeiterfassungSettings &settings, ZeiterfassungApi &erfassung, const GetUserInfoReply::UserInfo &userInfo, StripFactory &stripFactory, QWidget *parent) : @@ -47,15 +39,13 @@ MainWindow::MainWindow(ZeiterfassungSettings &settings, ZeiterfassungApi &erfass m_stripFactory(stripFactory), m_getProjectsReply(Q_NULLPTR), m_getAuswertungReply(Q_NULLPTR), - m_bookingsModel(new BookingsModel(this)), - m_timeAssignmentsModel(new TimeAssignmentsModel(this)), m_currentStripWidget(Q_NULLPTR) { ui->setupUi(this); for(quint8 i = 0; i < 7; i++) { - m_stripsWidgets[i] = new StripsWidget(m_erfassung, m_userInfo.userId, m_stripFactory, m_projects, ui->widgetWeek); + m_stripsWidgets[i] = new StripsWidget(*this, ui->widgetWeek); connect(m_stripsWidgets[i], &StripsWidget::refreshingChanged, this, &MainWindow::refreshingChanged); ui->layoutWeek->addWidget(m_stripsWidgets[i]); } @@ -100,14 +90,6 @@ MainWindow::MainWindow(ZeiterfassungSettings &settings, ZeiterfassungApi &erfass connect(ui->pushButtonStart, &QAbstractButton::pressed, this, &MainWindow::pushButtonStartPressed); connect(ui->pushButtonEnd, &QAbstractButton::pressed, this, &MainWindow::pushButtonEndPressed); - ui->treeViewBookings->setModel(m_bookingsModel); - connect(m_bookingsModel, &BookingsModel::enabledChanged, ui->treeViewBookings, &QWidget::setEnabled); - connect(ui->treeViewBookings, &QWidget::customContextMenuRequested, this, &MainWindow::contextMenuBooking); - - ui->treeViewTimeAssignments->setModel(m_timeAssignmentsModel); - connect(m_timeAssignmentsModel, &TimeAssignmentsModel::enabledChanged, ui->treeViewTimeAssignments, &QWidget::setEnabled); - connect(ui->treeViewTimeAssignments, &QWidget::customContextMenuRequested, this, &MainWindow::contextMenuTimeAssignment); - ui->statusbar->addPermanentWidget(m_balanceLabel = new QLabel(ui->statusbar)); m_balanceLabel->setFrameShape(QFrame::Panel); m_balanceLabel->setFrameShadow(QFrame::Sunken); @@ -166,6 +148,16 @@ StripFactory &MainWindow::stripFactory() const return m_stripFactory; } +const QMap &MainWindow::projects() const +{ + return m_projects; +} + +const std::array &MainWindow::stripsWidgets() const +{ + return m_stripsWidgets; +} + void MainWindow::getProjectsFinished() { if(m_getProjectsReply->success()) @@ -244,225 +236,6 @@ void MainWindow::getAuswertungFinished() m_getAuswertungReply = Q_NULLPTR; } -void MainWindow::contextMenuBooking(const QPoint &pos) -{ - auto index = ui->treeViewBookings->indexAt(pos); - - if(!index.isValid()) - { - QMenu menu; - auto createAction = menu.addAction(tr("Create booking")); - auto refreshAction = menu.addAction(QIcon(QPixmap(QStringLiteral(":/zeiterfassunglib/images/refresh.png"))), tr("Refresh bookings")); - auto selectedAction = menu.exec(ui->treeViewBookings->viewport()->mapToGlobal(pos)); - if(selectedAction == createAction) - { - BookingDialog dialog(this); - dialog.setTime(timeNormalise(QTime::currentTime())); - again2: - if(dialog.exec() == QDialog::Accepted) - { - auto reply = m_erfassung.doCreateBooking(m_userInfo.userId, ui->dateEditDate->date(), - dialog.getTime(), dialog.getTimespan(), - dialog.getType(), dialog.getText()); - - { - QEventLoop eventLoop; - connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); - eventLoop.exec(); - } - - if(reply->success()) - { - m_currentStripWidget->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_currentStripWidget->refreshBookings(); - } - } - else - { - auto booking = m_currentStripWidget->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->treeViewBookings->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_erfassung.doUpdateBooking(booking.id, m_userInfo.userId, ui->dateEditDate->date(), - dialog.getTime(), dialog.getTimespan(), - dialog.getType(), dialog.getText()); - - { - QEventLoop eventLoop; - connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); - eventLoop.exec(); - } - - if(reply->success()) - { - m_currentStripWidget->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_erfassung.doDeleteBooking(booking.id); - - { - QEventLoop eventLoop; - connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); - eventLoop.exec(); - } - - if(reply->success()) - m_currentStripWidget->refreshBookings(); - else - QMessageBox::warning(this, tr("Could not delete booking!"), tr("Could not delete booking!") % "\n\n" % reply->message()); - } - } - } -} - -void MainWindow::contextMenuTimeAssignment(const QPoint &pos) -{ - auto index = ui->treeViewTimeAssignments->indexAt(pos); - - if(!index.isValid()) - { - QMenu menu; - auto createAction = menu.addAction(tr("Create time assignment")); - auto refreshAction = menu.addAction(QIcon(QPixmap(QStringLiteral(":/zeiterfassunglib/images/refresh.png"))), tr("Refresh time assignments")); - auto selectedAction = menu.exec(ui->treeViewTimeAssignments->viewport()->mapToGlobal(pos)); - if(selectedAction == createAction) - { - TimeAssignmentDialog dialog(m_projects, m_settings, this); - again2: - if(dialog.exec() == QDialog::Accepted) - { - auto reply = m_erfassung.doCreateTimeAssignment(m_userInfo.userId, ui->dateEditDate->date(), - dialog.getTime(), dialog.getTimespan(), - dialog.getProject(), dialog.getSubproject(), - dialog.getWorkpackage(), dialog.getText()); - - { - QEventLoop eventLoop; - connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); - eventLoop.exec(); - } - - if(reply->success()) - { - m_currentStripWidget->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_currentStripWidget->refreshTimeAssignments(); - } - } - else - { - auto timeAssignment = m_currentStripWidget->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->treeViewTimeAssignments->viewport()->mapToGlobal(pos)); - if(selectedAction == editAction) - { - TimeAssignmentDialog dialog(m_projects, m_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_erfassung.doUpdateTimeAssignment(timeAssignment.id, m_userInfo.userId, ui->dateEditDate->date(), - dialog.getTime(), dialog.getTimespan(), - dialog.getProject(), dialog.getSubproject(), - dialog.getWorkpackage(), dialog.getText()); - - { - QEventLoop eventLoop; - connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); - eventLoop.exec(); - } - - if(reply->success()) - { - m_currentStripWidget->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_erfassung.doDeleteTimeAssignment(timeAssignment.id); - - { - QEventLoop eventLoop; - connect(reply.get(), &ZeiterfassungReply::finished, &eventLoop, &QEventLoop::quit); - eventLoop.exec(); - } - - if(reply->success()) - { - m_currentStripWidget->refreshTimeAssignments(); - } - else - QMessageBox::warning(this, tr("Could not delete time assignment!"), tr("Could not delete time assignment!") % "\n\n" % reply->message()); - } - } - } -} - void MainWindow::pushButtonStartPressed() { auto bookingsChanged = false; @@ -642,9 +415,6 @@ void MainWindow::dateChanged(bool force) m_currentStripWidget = m_stripsWidgets[i]; - m_bookingsModel->setStripsWidget(m_currentStripWidget); - m_timeAssignmentsModel->setStripsWidget(m_currentStripWidget); - minimumTimeChanged(); startEnabledChanged(); endEnabledChanged(); diff --git a/zeiterfassunglib/mainwindow.h b/zeiterfassunglib/mainwindow.h index a41e9cc..c74ae2a 100644 --- a/zeiterfassunglib/mainwindow.h +++ b/zeiterfassunglib/mainwindow.h @@ -41,11 +41,12 @@ public: const GetUserInfoReply::UserInfo &userInfo() const; StripFactory &stripFactory() const; + const QMap &projects() const; + const std::array &stripsWidgets() const; + private Q_SLOTS: void getProjectsFinished(); void getAuswertungFinished(); - void contextMenuBooking(const QPoint &pos); - void contextMenuTimeAssignment(const QPoint &pos); void pushButtonStartPressed(); void pushButtonEndPressed(); void dateChanged(bool force = false); diff --git a/zeiterfassunglib/mainwindow.ui b/zeiterfassunglib/mainwindow.ui index 1097f45..9bfdf0b 100644 --- a/zeiterfassunglib/mainwindow.ui +++ b/zeiterfassunglib/mainwindow.ui @@ -167,70 +167,26 @@ - - - 0 + + + QFrame::NoFrame - - - QFrame::NoFrame + + QFrame::Plain + + + true + + + + + 0 + 0 + 1393 + 440 + - - QFrame::Plain - - - true - - - Optimized view - - - - - 0 - 0 - 1389 - 409 - - - - - - - - Qt::Vertical - - - Advanced view - - - - Bookings - - - - - - Qt::CustomContextMenu - - - - - - - - Time assignments - - - - - - Qt::CustomContextMenu - - - - - + diff --git a/zeiterfassunglib/models/bookingsmodel.cpp b/zeiterfassunglib/models/bookingsmodel.cpp deleted file mode 100644 index cc95afd..0000000 --- a/zeiterfassunglib/models/bookingsmodel.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "bookingsmodel.h" - -#include - -#include "stripswidget.h" - -BookingsModel::BookingsModel(QObject *parent) : - QAbstractListModel(parent), - m_stripsWidget(Q_NULLPTR), - m_enabled(false) -{ -} - -StripsWidget *BookingsModel::stripsWidget() const -{ - return m_stripsWidget; -} - -void BookingsModel::setStripsWidget(StripsWidget *stripsWidget) -{ - if(m_stripsWidget != stripsWidget) - { - if(m_stripsWidget) - { - disconnect(m_stripsWidget, &StripsWidget::bookingsChanged, this, &BookingsModel::bookingsChanged); - disconnect(m_stripsWidget, &StripsWidget::refreshingBookingsChanged, this, &BookingsModel::refreshingChanged); - } - - beginResetModel(); - Q_EMIT stripsWidgetChanged(m_stripsWidget = stripsWidget); - endResetModel(); - - if(m_stripsWidget) - { - connect(m_stripsWidget, &StripsWidget::bookingsChanged, this, &BookingsModel::bookingsChanged); - connect(m_stripsWidget, &StripsWidget::refreshingBookingsChanged, this, &BookingsModel::refreshingChanged); - - if(m_enabled == m_stripsWidget->refreshingBookings()) - Q_EMIT enabledChanged(m_enabled = !m_stripsWidget->refreshingBookings()); - } - else if(m_enabled) - Q_EMIT enabledChanged(m_enabled = false); - } -} - -bool BookingsModel::enabled() const -{ - return m_enabled; -} - -int BookingsModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - - return m_stripsWidget ? m_stripsWidget->bookings().count() : 0; -} - -int BookingsModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - - return 5; -} - -QVariant BookingsModel::data(const QModelIndex &index, int role) const -{ - Q_ASSERT(m_stripsWidget != Q_NULLPTR); - 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) -{ - if(m_enabled == refreshing) - Q_EMIT enabledChanged(m_enabled = !refreshing); -} diff --git a/zeiterfassunglib/models/timeassignmentsmodel.cpp b/zeiterfassunglib/models/timeassignmentsmodel.cpp deleted file mode 100644 index 6080dc3..0000000 --- a/zeiterfassunglib/models/timeassignmentsmodel.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "timeassignmentsmodel.h" - -#include - -#include "stripswidget.h" - -TimeAssignmentsModel::TimeAssignmentsModel(QObject *parent) : - QAbstractListModel(parent), - m_stripsWidget(Q_NULLPTR), - m_enabled(false) -{ -} - -StripsWidget *TimeAssignmentsModel::stripsWidget() const -{ - return m_stripsWidget; -} - -void TimeAssignmentsModel::setStripsWidget(StripsWidget *stripsWidget) -{ - if(m_stripsWidget != stripsWidget) - { - if(m_stripsWidget) - { - disconnect(m_stripsWidget, &StripsWidget::timeAssignmentsChanged, this, &TimeAssignmentsModel::timeAssignmentsChanged); - disconnect(m_stripsWidget, &StripsWidget::refreshingTimeAssignmentsChanged, this, &TimeAssignmentsModel::refreshingChanged); - } - - beginResetModel(); - m_stripsWidget = stripsWidget; - endResetModel(); - - if(m_stripsWidget) - { - connect(m_stripsWidget, &StripsWidget::timeAssignmentsChanged, this, &TimeAssignmentsModel::timeAssignmentsChanged); - connect(m_stripsWidget, &StripsWidget::refreshingTimeAssignmentsChanged, this, &TimeAssignmentsModel::refreshingChanged); - - if(m_enabled == m_stripsWidget->refreshingTimeAssignments()) - Q_EMIT enabledChanged(m_enabled = !m_stripsWidget->refreshingTimeAssignments()); - } - else if(m_enabled) - Q_EMIT enabledChanged(m_enabled = false); - } -} - -bool TimeAssignmentsModel::enabled() const -{ - return m_enabled; -} - -int TimeAssignmentsModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - - return m_stripsWidget ? m_stripsWidget->timeAssignments().count() : 0; -} - -int TimeAssignmentsModel::columnCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - - return 7; -} - -QVariant TimeAssignmentsModel::data(const QModelIndex &index, int role) const -{ - Q_ASSERT(m_stripsWidget != Q_NULLPTR); - 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) -{ - if(m_enabled == refreshing) - Q_EMIT enabledChanged(m_enabled = !refreshing); -} diff --git a/zeiterfassunglib/stripswidget.cpp b/zeiterfassunglib/stripswidget.cpp index 6b00f52..07814bc 100644 --- a/zeiterfassunglib/stripswidget.cpp +++ b/zeiterfassunglib/stripswidget.cpp @@ -7,27 +7,58 @@ #include #include +#include "mainwindow.h" #include "zeiterfassungapi.h" #include "timeutils.h" #include "stripfactory.h" -StripsWidget::StripsWidget(ZeiterfassungApi &erfassung, int userId, StripFactory &stripFactory, - const QMap &projects, QWidget *parent) : +StripsWidget::StripsWidget(MainWindow &mainWindow, QWidget *parent) : QWidget(parent), - m_erfassung(erfassung), - m_userId(userId), - m_stripFactory(stripFactory), - m_projects(projects), - m_layout(new QVBoxLayout(this)), + m_mainWindow(mainWindow), m_refreshing(false), m_refreshingBookings(false), m_refreshingTimeAssignments(false), m_startEnabled(false), - m_endEnabled(false), - m_getBookingsReply(Q_NULLPTR), - m_getTimeAssignmentsReply(Q_NULLPTR) + m_endEnabled(false) { - setLayout(m_layout); + auto layout = new QVBoxLayout(this); + + m_headerLayout = new QHBoxLayout(this); + m_label = new QLabel(this); + { + auto font = m_label->font(); + font.setBold(true); + m_label->setFont(font); + } + m_headerLayout->addWidget(m_label, 1); + layout->addLayout(m_headerLayout); + + m_stripsLayout = new QVBoxLayout(this); + layout->addLayout(m_stripsLayout); + + layout->addStretch(1); + + setLayout(layout); +} + +MainWindow &StripsWidget::mainWindow() const +{ + return m_mainWindow; +} + +QBoxLayout *StripsWidget::headerLayout() const +{ + return m_headerLayout; +} + +QBoxLayout *StripsWidget::stripsLayout() const +{ + return m_stripsLayout; +} + +QLabel *StripsWidget::label() const +{ + return m_label; } const QDate &StripsWidget::date() const @@ -37,8 +68,20 @@ const QDate &StripsWidget::date() const void StripsWidget::setDate(const QDate &date) { - m_date = date; - refresh(); + if(m_date != date) + { + Q_EMIT dateChanged(m_date = date); + + if(m_date.isValid()) + m_label->setText(tr("%0 (%1)") + .arg(std::array { tr("Monday"), tr("Tuesday"), tr("Wednesday"), tr("Thursday"), + tr("Friday"), tr("Saturday"), tr("Sunday") }[m_date.dayOfWeek() - 1]) + .arg(m_date.toString(tr("dd.MM.yyyy")))); + else + m_label->setText(tr("Invalid")); + + refresh(); + } } const QVector &StripsWidget::bookings() const @@ -95,14 +138,13 @@ void StripsWidget::refresh() { clearStrips(); - m_layout->addWidget(new QLabel(tr("Loading..."), this)); - m_layout->addStretch(1); + m_stripsLayout->addWidget(new QLabel(tr("Loading..."), this)); - refreshBookings(); - refreshTimeAssignments(); + refreshBookings(false); + refreshTimeAssignments(false); } -void StripsWidget::refreshBookings() +void StripsWidget::refreshBookings(bool createLabel) { if(!m_date.isValid()) { @@ -110,7 +152,14 @@ void StripsWidget::refreshBookings() return; } - if(m_bookings.count()) + if(createLabel) + { + clearStrips(); + + m_stripsLayout->addWidget(new QLabel(tr("Loading..."), this)); + } + + if(!m_bookings.empty()) { m_bookings.clear(); Q_EMIT bookingsChanged(m_bookings); @@ -124,11 +173,11 @@ void StripsWidget::refreshBookings() invalidateValues(); - m_getBookingsReply = m_erfassung.doGetBookings(m_userId, m_date, m_date); + m_getBookingsReply = m_mainWindow.erfassung().doGetBookings(m_mainWindow.userInfo().userId, m_date, m_date); connect(m_getBookingsReply.get(), &ZeiterfassungReply::finished, this, &StripsWidget::getBookingsFinished); } -void StripsWidget::refreshTimeAssignments() +void StripsWidget::refreshTimeAssignments(bool createLabel) { if(!m_date.isValid()) { @@ -136,7 +185,14 @@ void StripsWidget::refreshTimeAssignments() return; } - if(m_timeAssignments.count()) + if(createLabel) + { + clearStrips(); + + m_stripsLayout->addWidget(new QLabel(tr("Loading..."), this)); + } + + if(!m_timeAssignments.empty()) { m_timeAssignments.clear(); Q_EMIT timeAssignmentsChanged(m_timeAssignments); @@ -150,7 +206,7 @@ void StripsWidget::refreshTimeAssignments() invalidateValues(); - m_getTimeAssignmentsReply = m_erfassung.doGetTimeAssignments(m_userId, m_date, m_date); + m_getTimeAssignmentsReply = m_mainWindow.erfassung().doGetTimeAssignments(m_mainWindow.userInfo().userId, m_date, m_date); connect(m_getTimeAssignmentsReply.get(), &ZeiterfassungReply::finished, this, &StripsWidget::getTimeAssignmentsFinished); } @@ -199,7 +255,7 @@ bool StripsWidget::createStrips() { auto breakTime = timeBetween(lastBooking->time, startBooking.time); auto label = new QLabel(tr("%0: %1").arg(tr("Break")).arg(tr("%0h").arg(breakTime.toString(tr("HH:mm")))), this); - m_layout->addWidget(label); + m_stripsLayout->addWidget(label); } lastBooking = &startBooking; @@ -392,7 +448,7 @@ bool StripsWidget::createStrips() auto label = new QLabel(tr("%0: %1") .arg(tr("Assigned time")) .arg(tr("%0h").arg(timeAssignmentTime.toString(tr("HH:mm")))), this); - m_layout->addWidget(label); + m_stripsLayout->addWidget(label); } else { @@ -406,7 +462,7 @@ bool StripsWidget::createStrips() "Your bookings and time assignments for this day are in an illegal state!") % "\n" % errorMessage, this); label->setStyleSheet("color: red;"); - m_layout->addWidget(label); + m_stripsLayout->addWidget(label); } if(m_timeAssignmentTime != timeAssignmentTime) @@ -424,33 +480,16 @@ bool StripsWidget::createStrips() if(m_endEnabled != endEnabled) Q_EMIT endEnabledChanged(m_endEnabled = endEnabled); - m_layout->addStretch(1); - return !errorMessage.isEmpty(); } void StripsWidget::clearStrips() { - while(QLayoutItem *item = m_layout->takeAt(0)) + while(QLayoutItem *item = m_stripsLayout->takeAt(0)) { delete item->widget(); delete item; } - - auto label = new QLabel(this); - if(m_date.isValid()) - label->setText(tr("%0 (%1)") - .arg(std::array { tr("Monday"), tr("Tuesday"), tr("Wednesday"), tr("Thursday"), - tr("Friday"), tr("Saturday"), tr("Sunday") }[m_date.dayOfWeek() - 1]) - .arg(m_date.toString(tr("dd.MM.yyyy")))); - else - label->setText(tr("Invalid")); - { - auto font = label->font(); - font.setBold(true); - label->setFont(font); - } - m_layout->addWidget(label); } void StripsWidget::getBookingsFinished() @@ -507,10 +546,10 @@ void StripsWidget::invalidateValues() Q_EMIT endEnabledChanged(m_endEnabled = false); } -QString StripsWidget::buildProjectString(const QString &project) +QString StripsWidget::buildProjectString(const QString &project) const { - if(m_projects.contains(project)) - return m_projects.value(project) % "\n" % project; + if(m_mainWindow.projects().contains(project)) + return m_mainWindow.projects().value(project) % "\n" % project; else { qWarning() << "could not find project" << project; @@ -520,7 +559,7 @@ QString StripsWidget::buildProjectString(const QString &project) QWidget *StripsWidget::appendBookingStartStrip(int id, const QTime &time) { - auto widget = m_stripFactory.createBookingStartStrip(this).release(); + auto widget = m_mainWindow.stripFactory().createBookingStartStrip(this).release(); if(auto labelTime = widget->findChild(QStringLiteral("labelTime"))) labelTime->setProperty("text", time.toString(tr("HH:mm"))); @@ -532,14 +571,14 @@ QWidget *StripsWidget::appendBookingStartStrip(int id, const QTime &time) else qWarning() << "no labelId found!"; - m_layout->addWidget(widget); + m_stripsLayout->addWidget(widget); return widget; } QWidget *StripsWidget::appendBookingEndStrip(int id, const QTime &time) { - auto widget = m_stripFactory.createBookingEndStrip(this).release(); + auto widget = m_mainWindow.stripFactory().createBookingEndStrip(this).release(); if(auto labelTime = widget->findChild(QStringLiteral("labelTime"))) labelTime->setProperty("text", time.toString(tr("HH:mm"))); @@ -551,14 +590,14 @@ QWidget *StripsWidget::appendBookingEndStrip(int id, const QTime &time) else qWarning() << "no labelId found!"; - m_layout->addWidget(widget); + m_stripsLayout->addWidget(widget); return widget; } QWidget *StripsWidget::appendTimeAssignmentStrip(int id, const QTime &duration, const QString &project, const QString &subproject, const QString &workpackage, const QString &text) { - auto widget = m_stripFactory.createTimeAssignmentStrip(this).release(); + auto widget = m_mainWindow.stripFactory().createTimeAssignmentStrip(this).release(); if(auto labelTime = widget->findChild(QStringLiteral("labelTime"))) labelTime->setProperty("text", duration == QTime(0, 0) ? tr("Open") : duration.toString(tr("HH:mm"))); @@ -590,7 +629,7 @@ QWidget *StripsWidget::appendTimeAssignmentStrip(int id, const QTime &duration, else qWarning() << "no labelText found!"; - m_layout->addWidget(widget); + m_stripsLayout->addWidget(widget); return widget; } diff --git a/zeiterfassunglib/stripswidget.h b/zeiterfassunglib/stripswidget.h index 8995538..76e48d7 100644 --- a/zeiterfassunglib/stripswidget.h +++ b/zeiterfassunglib/stripswidget.h @@ -11,19 +11,24 @@ #include "replies/gettimeassignmentsreply.h" class QBoxLayout; -template class QMap; +class QLabel; template class QVector; -class ZeiterfassungApi; -class StripFactory; +class MainWindow; class ZEITERFASSUNGLIBSHARED_EXPORT StripsWidget : public QWidget { Q_OBJECT public: - explicit StripsWidget(ZeiterfassungApi &erfassung, int userId, StripFactory &stripFactory, - const QMap &projects, QWidget *parent = Q_NULLPTR); + explicit StripsWidget(MainWindow &mainWindow, QWidget *parent = Q_NULLPTR); + + MainWindow &mainWindow() const; + + QBoxLayout *headerLayout() const; + QBoxLayout *stripsLayout() const; + + QLabel *label() const; const QDate &date() const; void setDate(const QDate &date); @@ -41,12 +46,14 @@ public: bool endEnabled() const; void refresh(); - void refreshBookings(); - void refreshTimeAssignments(); + void refreshBookings(bool createLabel = true); + void refreshTimeAssignments(bool createLabel = true); bool createStrips(); void clearStrips(); Q_SIGNALS: + void dateChanged(const QDate &date); + void bookingsChanged(const QVector &bookings); void timeAssignmentsChanged(const QVector &timeAssignments); @@ -64,21 +71,20 @@ private Q_SLOTS: void getTimeAssignmentsFinished(); private: - void invalidateValues(); - - QString buildProjectString(const QString &project); + void invalidateValues(); + QString buildProjectString(const QString &project) const; QWidget *appendBookingStartStrip(int id, const QTime &time); QWidget *appendBookingEndStrip(int id, const QTime &time); QWidget *appendTimeAssignmentStrip(int id, const QTime &duration, const QString &project, const QString &subproject, const QString &workpackage, const QString &text); - ZeiterfassungApi &m_erfassung; - int m_userId; - StripFactory &m_stripFactory; - const QMap &m_projects; + MainWindow &m_mainWindow; - QBoxLayout *m_layout; + QBoxLayout *m_headerLayout; + QBoxLayout *m_stripsLayout; + + QLabel *m_label; QDate m_date; diff --git a/zeiterfassunglib/translations/zeiterfassunglib_de.ts b/zeiterfassunglib/translations/zeiterfassunglib_de.ts index db4389c..bbace03 100644 --- a/zeiterfassunglib/translations/zeiterfassunglib_de.ts +++ b/zeiterfassunglib/translations/zeiterfassunglib_de.ts @@ -376,8 +376,8 @@ - - + + Start Kommen @@ -477,13 +477,13 @@ Zeiterfassung - %0 (%1) - - + + Could not open auswertung! - + Could not open default PDF viewer! Konnte den PDF-Anzeiger nicht öffnen! @@ -503,147 +503,147 @@ Text - - - - + + + + %0: %1 %0: %1 - - + + ??? ??? - - + + Balance Saldo - - + + Holidays Urlaubstage - - + + Could not load bookings! Konnte Buchungen nicht laden! - + Could not load Auswertung! - + %0h %0h - + Could not delete booking! Konnte Buchung nicht löschen! - + Edit booking Buchung bearbeiten - + Delete booking Buchung löschen - + Could not edit booking! Konnte Buchung nicht bearbeiten! - + Create booking Buchung erstellen - - + + n/a n/v - + Refresh bookings Buchungen aktualisieren - - - + + + Could not create booking! Konnte Buchung nicht erstellen! - + Do you really want to delete the booking? Möchten Sie die Buchung wirklich löschen? - + Refresh time assignments Kontierungen aktualisieren - + 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! - - + + %0 (%1) %0 (%1) - + Create time assignment Kontierung erstellen - - + + Could not create time assignment! Konnte Kontierung nicht erstellen! - - + + Switch Wechseln @@ -728,178 +728,178 @@ StripsWidget - + Loading... Lade... - + Missing booking! Kontierung fehlend! - + Expected start booking, instead got type %0 Booking ID: %1 - - + + %0: %1 %0: %1 - + Break Pause - - - + + + %0h %0h - - - - - + + + + + HH:mm HH:mm - + Missing time assignment! Kontierung fehlend! - - - + + + Expected %0 but received %1 in time assignment. Time assignment ID: %2 - - - - - - - - + + + + + + + + HH:mm:ss HH:mm:ss - - + + There is another booking after an unfinished time assignment. Booking ID: %0 Time assignment ID: %1 - - - + + + There is another time assignment after an unfinished time assignment. Time assignment ID: %0 Time assignment ID: %1 - + The last time assignment is finished without end booking Time assignment ID: %0 - + Expected end booking, instead got type %0 Booking ID: %1 - + Missing time assignment! Missing: %0 Kontierung fehlend! %0 nicht kontiert - + Assigned time Kontierte Zeit - + dd.MM.yyyy dd.MM.yyyy - + %0 (%1) %0 (%1) - + Time assignment time longer than booking time! Time assignment: %0 Booking: %1 - + Strip rendering aborted due error. Your bookings and time assignments for this day are in an illegal state! - + Monday Montag - + Tuesday Dienstag - + Wednesday Mittwoch - + Thursday Donnerstag - + Friday Freitag - + Saturday Samstag - + Sunday Sonntag - + Invalid Ungültig - + Open Offen diff --git a/zeiterfassunglib/translations/zeiterfassunglib_en.ts b/zeiterfassunglib/translations/zeiterfassunglib_en.ts index 7fb33eb..c58d108 100644 --- a/zeiterfassunglib/translations/zeiterfassunglib_en.ts +++ b/zeiterfassunglib/translations/zeiterfassunglib_en.ts @@ -376,8 +376,8 @@ - - + + Start @@ -492,158 +492,158 @@ - - + + ??? - - + + Could not load bookings! - + Could not load Auswertung! - - + + n/a - + %0h - - - - + + + + %0: %1 - - + + Balance - - + + Holidays - + 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! - - + + Could not open auswertung! - + Could not open default PDF viewer! - - + + Switch - - + + %0 (%1) @@ -728,178 +728,178 @@ StripsWidget - + Loading... - + Missing booking! - + Expected start booking, instead got type %0 Booking ID: %1 - - + + %0: %1 - + Break - - - + + + %0h - - - - - + + + + + HH:mm - + Missing time assignment! - - - + + + Expected %0 but received %1 in time assignment. Time assignment ID: %2 - - - - - - - - + + + + + + + + HH:mm:ss - - + + There is another booking after an unfinished time assignment. Booking ID: %0 Time assignment ID: %1 - - - + + + There is another time assignment after an unfinished time assignment. Time assignment ID: %0 Time assignment ID: %1 - + The last time assignment is finished without end booking Time assignment ID: %0 - + Expected end booking, instead got type %0 Booking ID: %1 - + Missing time assignment! Missing: %0 - + Time assignment time longer than booking time! Time assignment: %0 Booking: %1 - + Assigned time - + Strip rendering aborted due error. Your bookings and time assignments for this day are in an illegal state! - + %0 (%1) - + Monday - + Tuesday - + Wednesday - + Thursday - + Friday - + Saturday - + Sunday - + dd.MM.yyyy - + Invalid - + Open diff --git a/zeiterfassunglib/zeiterfassunglib.pro b/zeiterfassunglib/zeiterfassunglib.pro index 4b10025..62c40c9 100644 --- a/zeiterfassunglib/zeiterfassunglib.pro +++ b/zeiterfassunglib/zeiterfassunglib.pro @@ -19,13 +19,9 @@ SOURCES += mainwindow.cpp \ zeiterfassungsettings.cpp \ dialogs/aboutmedialog.cpp \ dialogs/authenticationdialog.cpp \ - dialogs/bookingdialog.cpp \ dialogs/languageselectiondialog.cpp \ dialogs/settingsdialog.cpp \ - dialogs/timeassignmentdialog.cpp \ dialogs/updatedialog.cpp \ - models/bookingsmodel.cpp \ - models/timeassignmentsmodel.cpp \ replies/createbookingreply.cpp \ replies/createtimeassignmentreply.cpp \ replies/deletebookingreply.cpp \ @@ -40,7 +36,7 @@ SOURCES += mainwindow.cpp \ replies/updatebookingreply.cpp \ replies/updatetimeassignmentreply.cpp \ replies/zeiterfassungreply.cpp \ - replies/getuserinforeply.cpp + replies/getuserinforeply.cpp HEADERS += cpp14polyfills.h \ mainwindow.h \ @@ -53,13 +49,9 @@ HEADERS += cpp14polyfills.h \ zeiterfassungsettings.h \ dialogs/aboutmedialog.h \ dialogs/authenticationdialog.h \ - dialogs/bookingdialog.h \ dialogs/languageselectiondialog.h \ dialogs/settingsdialog.h \ - dialogs/timeassignmentdialog.h \ dialogs/updatedialog.h \ - models/bookingsmodel.h \ - models/timeassignmentsmodel.h \ replies/createbookingreply.h \ replies/createtimeassignmentreply.h \ replies/deletebookingreply.h \ @@ -74,16 +66,14 @@ HEADERS += cpp14polyfills.h \ replies/updatebookingreply.h \ replies/updatetimeassignmentreply.h \ replies/zeiterfassungreply.h \ - replies/getuserinforeply.h + replies/getuserinforeply.h FORMS += mainwindow.ui \ dialogs/updatedialog.ui \ dialogs/settingsdialog.ui \ dialogs/languageselectiondialog.ui \ dialogs/authenticationdialog.ui \ - dialogs/bookingdialog.ui \ - dialogs/aboutmedialog.ui \ - dialogs/timeassignmentdialog.ui + dialogs/aboutmedialog.ui RESOURCES += resources.qrc diff --git a/zeiterfassunglib/zeiterfassungplugin.h b/zeiterfassunglib/zeiterfassungplugin.h index 33eee20..1b170c0 100644 --- a/zeiterfassunglib/zeiterfassungplugin.h +++ b/zeiterfassunglib/zeiterfassungplugin.h @@ -13,10 +13,9 @@ class ZEITERFASSUNGLIBSHARED_EXPORT ZeiterfassungPlugin : public QObject Q_OBJECT public: - explicit ZeiterfassungPlugin(QObject *parent = 0); + explicit ZeiterfassungPlugin(QObject *parent = Q_NULLPTR); virtual void attachTo(MainWindow &mainWindow) { Q_UNUSED(mainWindow) } - virtual void attachTo(StripsWidget &stripsWidget) { Q_UNUSED(stripsWidget) } }; Q_DECLARE_INTERFACE(ZeiterfassungPlugin, "dbsoftware.zeiterfassung.plugin/1.0")