From af02fa79fda2251b9a9ee410c2493345ddf242a2 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 <0xFEEDC0DE64@gmail.com> Date: Mon, 17 Sep 2018 19:34:33 +0200 Subject: [PATCH] Imported existing sources --- absencedialog.cpp | 84 +++++++++++++++++++++ absencedialog.h | 28 +++++++ absencedialog.ui | 83 +++++++++++++++++++++ absenceplugin.cpp | 38 ++++++++++ absenceplugin.h | 24 ++++++ absenceplugin.json | 0 absenceplugin.pro | 26 +++++++ absenceplugin_resources.qrc | 5 ++ absencesmodel.cpp | 123 +++++++++++++++++++++++++++++++ absencesmodel.h | 51 +++++++++++++ absencewidget.cpp | 23 ++++++ absencewidget.h | 19 +++++ images/absence.png | Bin 0 -> 5690 bytes translations/absenceplugin_de.ts | 88 ++++++++++++++++++++++ translations/absenceplugin_en.ts | 88 ++++++++++++++++++++++ 15 files changed, 680 insertions(+) create mode 100644 absencedialog.cpp create mode 100644 absencedialog.h create mode 100644 absencedialog.ui create mode 100644 absenceplugin.cpp create mode 100644 absenceplugin.h create mode 100644 absenceplugin.json create mode 100644 absenceplugin.pro create mode 100644 absenceplugin_resources.qrc create mode 100644 absencesmodel.cpp create mode 100644 absencesmodel.h create mode 100644 absencewidget.cpp create mode 100644 absencewidget.h create mode 100644 images/absence.png create mode 100644 translations/absenceplugin_de.ts create mode 100644 translations/absenceplugin_en.ts diff --git a/absencedialog.cpp b/absencedialog.cpp new file mode 100644 index 0000000..40c66fa --- /dev/null +++ b/absencedialog.cpp @@ -0,0 +1,84 @@ +#include "absencedialog.h" +#include "ui_absencedialog.h" + +#include +#include +#include +#include +#include +#include + +#include "absencesmodel.h" + +AbsenceDialog::AbsenceDialog(int userId, const QDate &date, ZeiterfassungApi &erfassung, QWidget *parent) : + ZeiterfassungDialog(parent), + ui(new Ui::AbsenceDialog) +{ + ui->setupUi(this); + + ui->labelTitle->setText(tr("Absences for %0").arg(QLocale().toString(date))); + + m_model = new AbsencesModel(userId, date, erfassung, this); + connect(m_model, &AbsencesModel::errorOccured, this, &AbsenceDialog::errorOccured); + + ui->treeView->setModel(m_model); + ui->treeView->setEnabled(m_model->enabled()); + connect(m_model, &AbsencesModel::enabledChanged, ui->treeView, &QWidget::setEnabled); + + connect(ui->treeView, &QWidget::customContextMenuRequested, this, &AbsenceDialog::customContextMenuRequested); +} + +AbsenceDialog::~AbsenceDialog() +{ + delete ui; +} + +void AbsenceDialog::errorOccured(const QString &message) +{ + QMessageBox::warning(this, tr("Could not load absences!"), tr("Could not load absences!") % "\n\n" % message); +} + +void AbsenceDialog::customContextMenuRequested(const QPoint &pos) +{ + auto index = ui->treeView->indexAt(pos); + + if(!index.isValid()) + { + QMenu menu; + auto createAction = menu.addAction(tr("Create absence")); + auto refreshAction = menu.addAction(QIcon(QPixmap(QStringLiteral(":/zeiterfassungguilib/images/refresh.png"))), tr("Refresh absences")); + auto selectedAction = menu.exec(ui->treeView->viewport()->mapToGlobal(pos)); + if(selectedAction == createAction) + { + //TODO + } + else if(selectedAction == refreshAction) + { + m_model->refresh(); + } + } + else + { + auto absence = m_model->absences().at(index.row()); + + QMenu menu; + auto editAction = menu.addAction(tr("Edit absence")); + auto deleteAction = menu.addAction(tr("Delete absence")); + auto selectedAction = menu.exec(ui->treeView->viewport()->mapToGlobal(pos)); + if(selectedAction == editAction) + { + //TODO + } + else if(selectedAction == deleteAction) + { + QMessageBox msgBox; + msgBox.setText(tr("Do you really want to delete the absence?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Cancel); + if(msgBox.exec() == QMessageBox::Yes) + { + //TODO + } + } + } +} diff --git a/absencedialog.h b/absencedialog.h new file mode 100644 index 0000000..9ab7e80 --- /dev/null +++ b/absencedialog.h @@ -0,0 +1,28 @@ +#pragma once + +#include "zeiterfassungdialog.h" + +class QDate; + +class ZeiterfassungApi; + +class AbsencesModel; +namespace Ui { class AbsenceDialog; } + +class AbsenceDialog : public ZeiterfassungDialog +{ + Q_OBJECT + +public: + explicit AbsenceDialog(int userId, const QDate &date, ZeiterfassungApi &erfassung, QWidget *parent = 0); + ~AbsenceDialog(); + +private Q_SLOTS: + void errorOccured(const QString &message); + void customContextMenuRequested(const QPoint &pos); + +private: + Ui::AbsenceDialog *ui; + + AbsencesModel *m_model; +}; diff --git a/absencedialog.ui b/absencedialog.ui new file mode 100644 index 0000000..4db3095 --- /dev/null +++ b/absencedialog.ui @@ -0,0 +1,83 @@ + + + AbsenceDialog + + + + 0 + 0 + 947 + 300 + + + + Absences + + + + + + + 16 + + + + Absences for + + + + + + + Qt::CustomContextMenu + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + AbsenceDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AbsenceDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/absenceplugin.cpp b/absenceplugin.cpp new file mode 100644 index 0000000..2e09928 --- /dev/null +++ b/absenceplugin.cpp @@ -0,0 +1,38 @@ +#include "absenceplugin.h" + +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "stripswidget.h" + +#include "absencewidget.h" + +AbsencePlugin::AbsencePlugin(QObject *parent) : + ZeiterfassungPlugin(parent) +{ + qDebug() << "called"; + + static auto dir = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("translations")); + + if(m_translator.load(QLocale(), QStringLiteral("absenceplugin"), QStringLiteral("_"), dir)) + { + if(!QCoreApplication::installTranslator(&m_translator)) + { + qWarning() << "could not install translation absenceplugin"; + } + } + else + { + qWarning() << "could not load translation absenceplugin"; + } +} + +void AbsencePlugin::attachTo(MainWindow &mainWindow) +{ + for(auto stripsWidget : mainWindow.stripsWidgets()) + stripsWidget->headerLayout()->addWidget(new AbsenceWidget(*stripsWidget)); +} diff --git a/absenceplugin.h b/absenceplugin.h new file mode 100644 index 0000000..b3884b8 --- /dev/null +++ b/absenceplugin.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "zeiterfassungplugin.h" + +class MainWindow; + +class Q_DECL_EXPORT AbsencePlugin : public ZeiterfassungPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "dbsoftware.zeiterfassung.plugin/1.0" FILE "absenceplugin.json") + Q_INTERFACES(ZeiterfassungPlugin) + +public: + explicit AbsencePlugin(QObject *parent = Q_NULLPTR); + + // ZeiterfassungPlugin interface + void attachTo(MainWindow &mainWindow) Q_DECL_OVERRIDE; + +private: + QTranslator m_translator; +}; diff --git a/absenceplugin.json b/absenceplugin.json new file mode 100644 index 0000000..e69de29 diff --git a/absenceplugin.pro b/absenceplugin.pro new file mode 100644 index 0000000..dac0298 --- /dev/null +++ b/absenceplugin.pro @@ -0,0 +1,26 @@ +QT += core network gui widgets + +DBLIBS += zeiterfassungcore zeiterfassunggui + +TARGET = absenceplugin + +HEADERS += absencedialog.h \ + absencesmodel.h \ + absenceplugin.h \ + absencewidget.h + +SOURCES += absencedialog.cpp \ + absencesmodel.cpp \ + absenceplugin.cpp \ + absencewidget.cpp + +FORMS += absencedialog.ui + +RESOURCES += absenceplugin_resources.qrc + +TRANSLATIONS += translations/absenceplugin_en.ts \ + translations/absenceplugin_de.ts + +OTHER_FILES += absenceplugin.json + +include(../plugin.pri) diff --git a/absenceplugin_resources.qrc b/absenceplugin_resources.qrc new file mode 100644 index 0000000..a3b089d --- /dev/null +++ b/absenceplugin_resources.qrc @@ -0,0 +1,5 @@ + + + images/absence.png + + diff --git a/absencesmodel.cpp b/absencesmodel.cpp new file mode 100644 index 0000000..81ac369 --- /dev/null +++ b/absencesmodel.cpp @@ -0,0 +1,123 @@ +#include "absencesmodel.h" + +#include "zeiterfassungapi.h" + +AbsencesModel::AbsencesModel(int userId, const QDate &date, ZeiterfassungApi &erfassung, QObject *parent) : + QAbstractListModel(parent), + m_userId(userId), + m_erfassung(erfassung) +{ + connect(this, &AbsencesModel::dateChanged, this, &AbsencesModel::refresh); + + setDate(date); +} + +bool AbsencesModel::enabled() const +{ + return m_reply == Q_NULLPTR; +} + +const QDate &AbsencesModel::date() const +{ + return m_date; +} + +const QVector &AbsencesModel::absences() const +{ + return m_absences; +} + +int AbsencesModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + + return m_absences.count(); +} + +int AbsencesModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + + return 5; +} + +QVariant AbsencesModel::data(const QModelIndex &index, int role) const +{ + Q_ASSERT(index.row() < m_absences.count()); + const auto &absence = m_absences.at(index.row()); + + switch(role) + { + case Qt::DisplayRole: + case Qt::EditRole: + switch(index.column()) + { + case 0: return absence.compositeId; + case 1: return absence.start; + case 2: return absence.end; + case 3: return absence.hourCategory; + case 4: return absence.text; + } + } + + return QVariant(); +} + +QVariant AbsencesModel::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("Start"); + case 2: return tr("End"); + case 3: return tr("Hour Category"); + case 4: return tr("Text"); + } + } + default: + qt_noop(); + } + + return QVariant(); +} + +void AbsencesModel::refresh() +{ + auto oldEnabled = enabled(); + + m_reply = m_erfassung.doGetAbsences(m_userId, m_date, m_date); + connect(m_reply.get(), &ZeiterfassungReply::finished, this, &AbsencesModel::finished); + + if(oldEnabled != enabled()) + Q_EMIT enabledChanged(enabled()); +} + +void AbsencesModel::setDate(const QDate &date) +{ + if(m_date != date) + Q_EMIT dateChanged(m_date = date); +} + +void AbsencesModel::finished() +{ + if(!m_reply->success()) + Q_EMIT errorOccured(m_reply->message()); + + beginResetModel(); + m_absences = m_reply->absences(); + endResetModel(); + + auto oldEnabled = enabled(); + + m_reply = Q_NULLPTR; + + if(oldEnabled != enabled()) + Q_EMIT enabledChanged(enabled()); +} diff --git a/absencesmodel.h b/absencesmodel.h new file mode 100644 index 0000000..b183f69 --- /dev/null +++ b/absencesmodel.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +#include +#include + +#include "replies/getabsencesreply.h" + +class ZeiterfassungApi; + +class AbsencesModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged) + Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged) + +public: + explicit AbsencesModel(int userId, const QDate &date, ZeiterfassungApi &erfassung, QObject *parent = Q_NULLPTR); + + bool enabled() const; + + const QDate &date() const; + + const QVector &absences() 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); + void dateChanged(const QDate &date); + void errorOccured(const QString &message); + +public Q_SLOTS: + void refresh(); + void setDate(const QDate &date); + +private Q_SLOTS: + void finished(); + +private: + int m_userId; + QDate m_date; + ZeiterfassungApi &m_erfassung; + std::unique_ptr m_reply; + QVector m_absences; +}; diff --git a/absencewidget.cpp b/absencewidget.cpp new file mode 100644 index 0000000..444f87f --- /dev/null +++ b/absencewidget.cpp @@ -0,0 +1,23 @@ +#include "absencewidget.h" + +#include "stripswidget.h" +#include "mainwindow.h" + +#include "absencedialog.h" + +AbsenceWidget::AbsenceWidget(StripsWidget &stripsWidget) : + QToolButton(&stripsWidget), + m_stripsWidget(stripsWidget) +{ + setIcon(QIcon(QStringLiteral(":/zeiterfassung/plugins/absenceplugin/images/absence.png"))); + setText(tr("Absence")); + + connect(this, &QAbstractButton::pressed, this, &AbsenceWidget::pressedSlot); +} + +void AbsenceWidget::pressedSlot() +{ + AbsenceDialog dialog(m_stripsWidget.mainWindow().userInfo().userId, m_stripsWidget.date(), + m_stripsWidget.mainWindow().erfassung(), this); + dialog.exec(); +} diff --git a/absencewidget.h b/absencewidget.h new file mode 100644 index 0000000..a93cc34 --- /dev/null +++ b/absencewidget.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +class StripsWidget; + +class AbsenceWidget : public QToolButton +{ + Q_OBJECT + +public: + explicit AbsenceWidget(StripsWidget &stripsWidget); + +private Q_SLOTS: + void pressedSlot(); + +private: + StripsWidget &m_stripsWidget; +}; diff --git a/images/absence.png b/images/absence.png new file mode 100644 index 0000000000000000000000000000000000000000..4a33f1c5223a28db4e4d344ece90897693645a80 GIT binary patch literal 5690 zcmeAS@N?(olHy`uVBq!ia0y~yU~m9o4mJh`hE=*iw9KwjE?lY82pTxsp|?yz=|?{N3N@eV%Rqu6nIl^wDWi%304= z_}wpmZ~6VzzkU1fTkijQ=zsqIeDkd`{CnSjx4&0i#(INkPHIoAs9WJpmVB$evgWdNW~ldy6`aK3c9Wj`0LsKUvD-s zC)D4Oo?h@@=|Q?nOW1DT<&zg|b(8iLadQdmF%;96o1VI4S93|@r6}cwa!I}7iua64 z(^L2FD7$>EdhY3C)1(`M6&b^sv!&099b=ob`!SQ=zBgQE^Z)XdNEq8%AHH%$rMH#U z%F}69+LB1OS!r8t=SFdtM)k5o9O>#ii6fvweSKTW@1yT}#d7%Td8vp*O0| zRr2KCIuT+bkBET+ZMk@ZM30t5vB`=F=bJ{|>wFGQMDT zN~vVDxM{1v)TF?(v5|FYfLHS+%Z*%BuY8UuD|LKPiBf!0tTNwY>9(fO?CX=4%I^6t z=ruca>i=Md2Br{+mW;CeO`6_J*t}V;9B{8fuy|??_4@sVe zj+6y45^WimA6NCCxOaNBYVFCLQJ1FoOg$y)HC0Q2bHdz-3~zpan?7Uatc3wODqbsp zTJ#xu?Qgqqef#y^6R+KK6IOm(yC7yI&;0Fw@0?!$dnW&i>HGgaKh1Wae=BF!gH_q< zUX@3FlUF;|zvk8J)eEOP{cMxqnDo2e^6952mXwdzytXz?JNUWBR9-?_ww5L3rpm+P z*O(sdy&4t2De?0()2B`~N`~ui?_A;?^_WS?ZC1K?W{kau~d>hz5c6_gx_}nGs{-(e>BZi!vn~n?q+$UbYVEOst zUcK(udse?JJ`?girsn%D_lJpveNT=kTf7$%{5gAV_+6V)H>L~OdZ)j2o|Zdd#d}iM zs^6pT%=MicPF!7j{YdllqqYk3-wV7yVC_&=`Tm{lm%Y2EhyL;BV_;8|SgPmy|HSSu za)R%t30-%okrzQq*&eY1+Z^-l+Y@?*F*WBMFlQ$Vy*a{|Em>N3%(%Ui7?^Wi~Pj^*L$_YOIa8L1E zWArAOnDXKnoAdp8-ZL!BOn)^$|MvF&=T92h<^S$vGC!E|a^}ftuKu>y{k)xbvuiEX z7f*gWb-@LVi|RY}?hMqptI(O8mN)O^&ur*S9p8EFY&6`Zt2U8BlO7EL+_4PI5 z4MkT~5|`GNtZSaW?zeW{#M?@ddD;&=Cr{b9*qEhtmAr(+9FI9avX)jwFBG5;Ia_DUS*h&U8LAzgnkaE5tf}MX%f`d|@fd9=5-p4oP%ykUN%iDy zaR!E#u8n3|Q%|utI;@OHDXW^)`ZMytZ{kE|G+3DKyW_f%s)SUJlukQc8$z#tCn^&7>=rH;${6AMq>tEx_?RCms zht%iSymLr?JWF(ql*KwxxfNjtExWh6PFCTL%dU@I{Bhd*?*<#nkMo(myB!{KY(-;h z>oJ)R!Ri~HxaT~6d^ti;XsMRQHtnVBLc6|aFD-YOs5>)<(aJc*bGBRUyw;zQv$#w5 zlryk6dcK`bB~_Gk&D80`gZZ6 zYR9I9C7#y4cq?gbpxf%NaZjFa36=li_RTXv&TTe(S>4xr&*$y=*v20`f4{PfOvFj2 zzcvoscfN~$FyH$u_C2eWgMq!hPQi4}x4z3lE-VX_=a^UdELn3;$$5L$hQIA(*Y4j9ML$-5d14sQ-NN?-dt>T10bnmq}c`u+)<4t(sEPB`)bB zEl0HyH#Th)yp_R}Y@l|3QcqCFq6MyH9CO~^nmfC{_Vvc;AsO4(+GeLDWPEl@x&3V7 zVt<>jw;!=Gf4|GS@44fh%c^k)4GO|-E|gz>_V&3{sMbY^7yI{>rU*RO%$Hmyrk&y@r<19(u+5m zz5i*uzP^3lBa1KB%Rj%#|EtC<&33curKp7AlC@&jxLbP<>zKU$TkNi0Zq~9`XrWt53VO?tY8O?Hys=PD|V3_D7xV?VC4s+b!{Zd7L(Te=GQ@_*tKH z@4dMFXyJxc0UVsn&F_j+b6$HRHfYvS*(U$*S^evLT0SPhrvt6q&xG9|XV=0sf9ZHjtQr>}fx z=}Pt!p5|*c^6&X%7j<29mv?q|3ecInMfj46;@c8~nd&jS+mzS3-M{$qX1QvC@6ND& zzxHVBZOsl}<0j=hNoD^0&h$8;xSLzMfBs!u&5{?(l8}?s)tc7swzzm-#ZM<0cInkq znF?hRdLn&ZKV6h7cJy!WlW!ry7{B z@rf1HZt=OM>n5v5vAnoGt9x7S;<=>};!`Hhw45|YdWBPu^1}zhyJz03uUIcsr`pnf zOM&gd`F(#RUSH>(ke276{q>^-SKA{C{e)ASB?6Eifck7ZtR@= z>xdwq-9L-Kn*x&E*`*UqTK(EB3PX%q&t~^1=sh^CI%$!?uQPdS@pfCL&-u)+rXbIH zMtA=omFsm0ywB(FZcGmTn%xul->j?YMAYVpLrqNC#SHf*?Mv0k6cjv^HMP-OZ=qdX z%f_+pOTMTAA;}#h%B$9QmWDTC;}j{tWhik0+%^NvHR$kzZ(6p0PRX zRnhK@DJ7iY3wE*fDw*ef()j+8J9a(;Q`2h|mA7V#MC+=$N=n++RN72PVpy&4!L?_r z#nRpmeZOb--gCa&#>aH{aKBA<@3r?qUcC~Fcm1;Yf4(T+_mkB6yUR$+ftKG(F6KnqdTo=E7$|1}8Thp5^&H8z<*{1II+aCL0yyxWB zY{*LLD_H2f(0$LvBY_TgSQX3WJ-T6%o_+S#S7zm;FVBN_7&8A|Id6-}^*aY#qkomV zOx&x=_0~&zhPg<7tI`IsToKPn3wM?M*|cq4TxgVWeZiFcyLHm-@_()MB4Shj9?@BL zPfg+biyl*%J6mRnUtgE7V{%}I`p+30ADw1T{VO`_YS90fy*n>=_i*hgFzwivcAV?+ z-u(;`aU})!4($7=Wbs}+o8j^qUAF3JYoD)4fA_$#?C!t9V{(-f%GbpmeD+cDQI)oM z=>ma>V`gg~@84>?uiya(|N8jWm+OOCYBDYS@4pBvlREw3!!N;}pSk?zTMpdN5SuwS z|BU;@xvQrJ>M;+*I!w%b?;GUJ9LSyRt6KwyMTvgKgT6}a_@t^Q-Z^Bv^ZhhsplyiCd=XOi~j|W)7 zdvY9dWuz>x`MrO2f6L08YdJr~gY?RlJ$tQt|J{<+y%(oiaIJa!>zViUU6*DVY*27o zd{c1)Tk^C*$&L?K=GRVKzW-yW-rWuJxWCJ*%~&lwp?;w#3*-8ndne?#SfBBJk@w^2 zf0M#*qSxzc-#hc~`E=&ZnP;~?R29d~65M*L`}9Ja@bt4M*rIN4Tf5@?nSHnKd|4=+ zdCt#F?AE6@XKFtGe0lTO7pKjOH=S{hdVL@&xvI|ILEs5np!!L%yZ3~>YAq@+e%}}F z$Id$}!_H~hvjn%?s$811_LO$5X`D>GX|A8IecryGy7*C%jy@;wKcT8T#;0?YF~QVI>T!jYG3^(Sv_Yt>6@Ml1}}@n)(lM1?MJP z`cJF8bY|kxpN5{X|F(L(@(^;LWqIj}?ELALM$_k~&s09$V)8k}EJvx&>rL$s!DWXV zwrS_nCY9pTN7U_y3;@m!D;~>-WN+juX{q%{}+v zUs-zf{|^%+{en7_=gG=F`qE_2y{q(ih)~=s?-`ehX=_Qqbr&-1vk2VP1N(hx< zm-afEu_LIPF~u9UO)3(j(1MKQkhx(e)i1oU&|Jo?*09}UfuH7RsGnSYu9|6pMSYpk&x3Q z-_!T@>a9Pww(kG-GXKrLTk*T>Yu;rtlrhd{`<0N(Znt$^*xsM+EDKXx>2+#Yk_ecku^XCIHhe-i%wM|SAiHnYB55w>L_QPF))(Y(yj#%|xG7iTw` ziY^W1T-fpIrfQO4j|1PCMQ1dYA6WQ-YwE%m9T$SSmT~YtzvDD(r{(iMKC^c1>KB z?)#s^!Syd)^TG|-)IUCbVIKVO`uhJ%c76I(99nO9<M$^D0z2ZIL5sRlD>lRY{ z-{4T5t+7{V>4%Ix<+r*m(zle&y|Vk8)9KES>mKj<|M0T^&-Qmay&3ZMr$}Fl@B7M~ z{9kSMtoIK67Yqyx>Imuh&>$a}S3!p5gH`Khf>eVH)PHZj>NIE!*wfX|Wt~$(69C9S B((eEO literal 0 HcmV?d00001 diff --git a/translations/absenceplugin_de.ts b/translations/absenceplugin_de.ts new file mode 100644 index 0000000..131891c --- /dev/null +++ b/translations/absenceplugin_de.ts @@ -0,0 +1,88 @@ + + + + + AbsenceDialog + + + Absences + Abwesenheiten + + + + Absences for %0 + Abwesenheiten für %0 + + + + dd.MM.yyyy + dd.MM.yyyy + + + + Could not load absences! + Konnte Abwesenheiten nicht laden! + + + + Create absence + Abwesenheit erstellen + + + + Refresh absences + Abwesenheiten aktualisieren + + + + Edit absence + Abwesenheit bearbeiten + + + + Delete absence + Abwesenheit löschen + + + + Do you really want to delete the absence? + Möchten Sie die Abwesenheit wirklich löschen? + + + + AbsenceWidget + + + Absence + Abwesenheit + + + + AbsencesModel + + + Id + Id + + + + Start + Start + + + + End + Ende + + + + Hour Category + Stunden Kategorie + + + + Text + Text + + + diff --git a/translations/absenceplugin_en.ts b/translations/absenceplugin_en.ts new file mode 100644 index 0000000..0794cbf --- /dev/null +++ b/translations/absenceplugin_en.ts @@ -0,0 +1,88 @@ + + + + + AbsenceDialog + + + Absences + + + + + Absences for %0 + + + + + dd.MM.yyyy + + + + + Could not load absences! + + + + + Create absence + + + + + Refresh absences + + + + + Edit absence + + + + + Delete absence + + + + + Do you really want to delete the absence? + + + + + AbsenceWidget + + + Absence + + + + + AbsencesModel + + + Id + + + + + Start + + + + + End + + + + + Hour Category + + + + + Text + + + +