Imported existing sources

This commit is contained in:
0xFEEDC0DE64
2018-09-17 19:36:22 +02:00
parent 3ce8c5f439
commit 4ff069de1b
23 changed files with 1867 additions and 0 deletions

268
advancedviewdialog.cpp Normal file
View File

@@ -0,0 +1,268 @@
#include "advancedviewdialog.h"
#include "ui_advancedviewdialog.h"
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include <QStringBuilder>
#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());
}
}
}
}

29
advancedviewdialog.h Normal file
View File

@@ -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;
};

81
advancedviewdialog.ui Normal file
View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AdvancedViewDialog</class>
<widget class="QDialog" name="AdvancedViewDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1024</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>Advanced view</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QTreeView" name="bookingsView">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
</widget>
<widget class="QTreeView" name="timeAssignmentsView">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AdvancedViewDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AdvancedViewDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

38
advancedviewplugin.cpp Normal file
View File

@@ -0,0 +1,38 @@
#include "advancedviewplugin.h"
#include <QDebug>
#include <QDir>
#include <QCoreApplication>
#include <QLocale>
#include <QBoxLayout>
#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));
}

24
advancedviewplugin.h Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
#include <QObject>
#include <QTranslator>
#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;
};

0
advancedviewplugin.json Normal file
View File

34
advancedviewplugin.pro Normal file
View File

@@ -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)

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/zeiterfassung/plugins/advancedviewplugin">
<file>images/advanced-view.png</file>
</qresource>
</RCC>

30
advancedviewwidget.cpp Normal file
View File

@@ -0,0 +1,30 @@
#include "advancedviewwidget.h"
#include <QIcon>
#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();
}

20
advancedviewwidget.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include <QToolButton>
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;
};

54
dialogs/bookingdialog.cpp Normal file
View File

@@ -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 &timespan)
{
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);
}

31
dialogs/bookingdialog.h Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include <QTime>
#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 &timespan);
QString getType() const;
void setType(const QString &type);
QString getText() const;
void setText(const QString &text);
private:
Ui::BookingDialog *ui;
};

163
dialogs/bookingdialog.ui Normal file
View File

@@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BookingDialog</class>
<widget class="QDialog" name="BookingDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>237</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Booking</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
<item>
<widget class="QLabel" name="labelTitle">
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>Booking</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="labelTime">
<property name="text">
<string>Time:</string>
</property>
<property name="buddy">
<cstring>timeEditTime</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelTimespan">
<property name="text">
<string>Timespan:</string>
</property>
<property name="buddy">
<cstring>timeEditTimespan</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelType">
<property name="text">
<string>Type:</string>
</property>
<property name="buddy">
<cstring>comboBoxType</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelText">
<property name="text">
<string>Text:</string>
</property>
<property name="buddy">
<cstring>lineEditText</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QTimeEdit" name="timeEditTime">
<property name="displayFormat">
<string notr="true">HH:mm:ss</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QTimeEdit" name="timeEditTimespan">
<property name="displayFormat">
<string notr="true">HH:mm:ss</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEditText"/>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxType">
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
<item>
<property name="text">
<string notr="true">K</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">G</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>BookingDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>BookingDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,119 @@
#include "timeassignmentdialog.h"
#include "ui_timeassignmentdialog.h"
#include <QMap>
#include <QStringBuilder>
#include <QDebug>
#include "zeiterfassungsettings.h"
TimeAssignmentDialog::TimeAssignmentDialog(const QMap<QString, QString> &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 &timespan)
{
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);
}

View File

@@ -0,0 +1,42 @@
#pragma once
#include <QTime>
#include "zeiterfassungdialog.h"
template <class Key, class T> class QMap;
class ZeiterfassungSettings;
namespace Ui { class TimeAssignmentDialog; }
class TimeAssignmentDialog : public ZeiterfassungDialog
{
Q_OBJECT
public:
explicit TimeAssignmentDialog(const QMap<QString, QString> &projects, const ZeiterfassungSettings &settings,
QWidget *parent = Q_NULLPTR);
~TimeAssignmentDialog();
QTime getTime() const;
void setTime(const QTime &time);
QTime getTimespan() const;
void setTimespan(const QTime &timespan);
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;
};

View File

@@ -0,0 +1,184 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TimeAssignmentDialog</class>
<widget class="QDialog" name="TimeAssignmentDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>307</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Time assignment</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
<item>
<widget class="QLabel" name="labelTitle">
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>Time assignment</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="labelTime">
<property name="text">
<string>Time:</string>
</property>
<property name="buddy">
<cstring>timeEditTime</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelTimespan">
<property name="text">
<string>Timespan:</string>
</property>
<property name="buddy">
<cstring>timeEditTimespan</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelProject">
<property name="text">
<string>Project:</string>
</property>
<property name="buddy">
<cstring>comboBoxProject</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelSubproject">
<property name="text">
<string>Subproject:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelWorkpackage">
<property name="text">
<string>Workpackage:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="labelText">
<property name="text">
<string>Text:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QTimeEdit" name="timeEditTime">
<property name="displayFormat">
<string notr="true">HH:mm:ss</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QTimeEdit" name="timeEditTimespan">
<property name="displayFormat">
<string notr="true">HH:mm:ss</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxProject"/>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBoxSubproject">
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboBoxWorkpackage">
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="comboBoxText">
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>TimeAssignmentDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>TimeAssignmentDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

BIN
images/advanced-view.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

93
models/bookingsmodel.cpp Normal file
View File

@@ -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);
}

37
models/bookingsmodel.h Normal file
View File

@@ -0,0 +1,37 @@
#pragma once
#include <QAbstractListModel>
#include <QVector>
#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;
};

View File

@@ -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);
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include <QAbstractListModel>
#include <QVector>
#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;
};

View File

@@ -0,0 +1,240 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de_DE">
<context>
<name>AdvancedViewDialog</name>
<message>
<location filename="../advancedviewdialog.ui" line="14"/>
<source>Advanced view</source>
<translation>Erweiterte Anzeige</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="56"/>
<source>Create booking</source>
<translation>Buchung erstellen</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="57"/>
<source>Refresh bookings</source>
<translation>Buchungen aktualisieren</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="83"/>
<source>Could not create booking!</source>
<translation>Konnte Buchung nicht erstellen!</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="98"/>
<source>Edit booking</source>
<translation>Buchung bearbeiten</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="99"/>
<source>Delete booking</source>
<translation>Buchung löschen</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="129"/>
<source>Could not edit booking!</source>
<translation>Konnte Buchung nicht bearbeiten!</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="137"/>
<source>Do you really want to delete the booking?</source>
<translation>Möchten Sie die Buchung wirklich löschen?</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="149"/>
<source>Could not delete booking!</source>
<translation>Konnte Buchung nicht löschen!</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="162"/>
<source>Create time assignment</source>
<translation>Kontierung erstellen</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="163"/>
<source>Refresh time assignments</source>
<translation>Kontierungen aktualisieren</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="191"/>
<source>Could not create time assignment!</source>
<translation>Konnte Kontierung nicht erstellen!</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="206"/>
<source>Edit time assignment</source>
<translation>Kontierung bearbeiten</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="207"/>
<source>Delete time assignment</source>
<translation>Kontierung löschen</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="242"/>
<source>Could not edit time assignment!</source>
<translation>Konnte Kontierung nicht bearbeiten!</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="250"/>
<source>Do you really want to delete the time assignment?</source>
<translation>Möchten Sie die Kontierung wirklich löschen?</translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="264"/>
<source>Could not delete time assignment!</source>
<translation>Konnte Kontierung nicht löschen!</translation>
</message>
</context>
<context>
<name>AdvancedViewWidget</name>
<message>
<location filename="../advancedviewwidget.cpp" line="13"/>
<source>Advanced view</source>
<translation>Erweiterte Anzeige</translation>
</message>
</context>
<context>
<name>BookingDialog</name>
<message>
<location filename="../dialogs/bookingdialog.ui" line="20"/>
<location filename="../dialogs/bookingdialog.ui" line="31"/>
<source>Booking</source>
<translation>Buchung</translation>
</message>
<message>
<location filename="../dialogs/bookingdialog.ui" line="40"/>
<source>Time:</source>
<translation>Zeit:</translation>
</message>
<message>
<location filename="../dialogs/bookingdialog.ui" line="50"/>
<source>Timespan:</source>
<translation>Zeitspanne:</translation>
</message>
<message>
<location filename="../dialogs/bookingdialog.ui" line="60"/>
<source>Type:</source>
<translation>Typ:</translation>
</message>
<message>
<location filename="../dialogs/bookingdialog.ui" line="70"/>
<source>Text:</source>
<translation>Text:</translation>
</message>
</context>
<context>
<name>BookingsModel</name>
<message>
<location filename="../models/bookingsmodel.cpp" line="70"/>
<source>ID</source>
<translation>ID</translation>
</message>
<message>
<location filename="../models/bookingsmodel.cpp" line="71"/>
<source>Time</source>
<translation>Zeit</translation>
</message>
<message>
<location filename="../models/bookingsmodel.cpp" line="72"/>
<source>Timespan</source>
<translation>Zeitspanne</translation>
</message>
<message>
<location filename="../models/bookingsmodel.cpp" line="73"/>
<source>Type</source>
<translation>Typ</translation>
</message>
<message>
<location filename="../models/bookingsmodel.cpp" line="74"/>
<source>Text</source>
<translation>Text</translation>
</message>
</context>
<context>
<name>TimeAssignmentDialog</name>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="20"/>
<location filename="../dialogs/timeassignmentdialog.ui" line="31"/>
<source>Time assignment</source>
<translation>Kontierung</translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="40"/>
<source>Time:</source>
<translation>Zeit:</translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="50"/>
<source>Timespan:</source>
<translation>Zeitspanne:</translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="60"/>
<source>Project:</source>
<translation>Projekt:</translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="70"/>
<source>Subproject:</source>
<translation>Subprojekt:</translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="77"/>
<source>Workpackage:</source>
<translation>Arbeitspaket:</translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="84"/>
<source>Text:</source>
<translation>Text:</translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.cpp" line="26"/>
<location filename="../dialogs/timeassignmentdialog.cpp" line="35"/>
<source>%0 (%1)</source>
<translation>%0 (%1)</translation>
</message>
</context>
<context>
<name>TimeAssignmentsModel</name>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="72"/>
<source>ID</source>
<translation>ID</translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="73"/>
<source>Time</source>
<translation>Zeit</translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="74"/>
<source>Timespan</source>
<translation>Zeitspanne</translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="75"/>
<source>Project</source>
<translation>Projekt</translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="76"/>
<source>Subproject</source>
<translation>Subprojekt</translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="77"/>
<source>Workpackage</source>
<translation>Arbeitspaket</translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="78"/>
<source>Text</source>
<translation>Text</translation>
</message>
</context>
</TS>

View File

@@ -0,0 +1,240 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
<name>AdvancedViewDialog</name>
<message>
<location filename="../advancedviewdialog.ui" line="14"/>
<source>Advanced view</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="56"/>
<source>Create booking</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="57"/>
<source>Refresh bookings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="83"/>
<source>Could not create booking!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="98"/>
<source>Edit booking</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="99"/>
<source>Delete booking</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="129"/>
<source>Could not edit booking!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="137"/>
<source>Do you really want to delete the booking?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="149"/>
<source>Could not delete booking!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="162"/>
<source>Create time assignment</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="163"/>
<source>Refresh time assignments</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="191"/>
<source>Could not create time assignment!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="206"/>
<source>Edit time assignment</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="207"/>
<source>Delete time assignment</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="242"/>
<source>Could not edit time assignment!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="250"/>
<source>Do you really want to delete the time assignment?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../advancedviewdialog.cpp" line="264"/>
<source>Could not delete time assignment!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>AdvancedViewWidget</name>
<message>
<location filename="../advancedviewwidget.cpp" line="13"/>
<source>Advanced view</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>BookingDialog</name>
<message>
<location filename="../dialogs/bookingdialog.ui" line="20"/>
<location filename="../dialogs/bookingdialog.ui" line="31"/>
<source>Booking</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/bookingdialog.ui" line="40"/>
<source>Time:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/bookingdialog.ui" line="50"/>
<source>Timespan:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/bookingdialog.ui" line="60"/>
<source>Type:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/bookingdialog.ui" line="70"/>
<source>Text:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>BookingsModel</name>
<message>
<location filename="../models/bookingsmodel.cpp" line="70"/>
<source>ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/bookingsmodel.cpp" line="71"/>
<source>Time</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/bookingsmodel.cpp" line="72"/>
<source>Timespan</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/bookingsmodel.cpp" line="73"/>
<source>Type</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/bookingsmodel.cpp" line="74"/>
<source>Text</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>TimeAssignmentDialog</name>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="20"/>
<location filename="../dialogs/timeassignmentdialog.ui" line="31"/>
<source>Time assignment</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="40"/>
<source>Time:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="50"/>
<source>Timespan:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="60"/>
<source>Project:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="70"/>
<source>Subproject:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="77"/>
<source>Workpackage:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.ui" line="84"/>
<source>Text:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../dialogs/timeassignmentdialog.cpp" line="26"/>
<location filename="../dialogs/timeassignmentdialog.cpp" line="35"/>
<source>%0 (%1)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>TimeAssignmentsModel</name>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="72"/>
<source>ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="73"/>
<source>Time</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="74"/>
<source>Timespan</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="75"/>
<source>Project</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="76"/>
<source>Subproject</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="77"/>
<source>Workpackage</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../models/timeassignmentsmodel.cpp" line="78"/>
<source>Text</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>