Release v1.4 #11

Merged
0xFEEDC0DE64 merged 16 commits from devel into master 2017-12-17 17:14:39 +01:00
168 changed files with 1871 additions and 1206 deletions

View File

@@ -1,24 +1,27 @@
# Zeiterfassung
This tool helps me assigning my working hours to various accounts at work.
This tool helps me assigning my working hours to projects at work.
![Screenshot of the main window](https://raw.githubusercontent.com/0xFEEDC0DE64/QtZeiterfassung/master/screenshot.png)
## Building from source
The build process has only been tested with gcc. On windows you have to use MinGW (provided by the Qt setup). All necessary config files or translations should be copied over to the build folder. The executable with all plugin lands in your build folder under /bin
The simplest way to get it up and running is to just open it in QtCreator. If you are more like a terminal monkey, you can build it there too:
```
git clone https://github.com/0xFEEDC0DE64/QtZeiterfassung.git
pushd QtZeiterfassung
lrelease translations/zeiterfassung_*.ts
popd
mkdir build_QtZeiterfassung
cd build_QtZeiterfassung
qmake ../QtZeiterfassung
make
make install # to copy Qt's translations
```
## Launching
## Launching (on unix)
```
./zeiterfassung
LD_LIBRARY_PATH=../lib ./zeiterfassung # or just use start.sh
```
## Launching (on win32)
Double click the **zeiterfassung.exe**. Please report any error message like missing libraries or plugins!
## Configuration
This tool saves its configuration using [QSettings](https://doc.qt.io/qt-5/qsettings.html). On linux, the configuration files are placed in `~/.config/db-software/zeiterfassung.conf`. **Be careful!** This config file contains your password in plain text (if you log in correctly). You can alter the code in main.cpp to change the behaviour of QSettings (for example: saving into an ini file at working directory).
![Screenshot of the main window](https://raw.githubusercontent.com/0xFEEDC0DE64/QtZeiterfassung/master/screenshot.png)

11
lrelease.pri Normal file
View File

@@ -0,0 +1,11 @@
isEmpty(QMAKE_LRELEASE) {
win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe
else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease
}
lrelease.input = TRANSLATIONS
lrelease.output = $${OUT_PWD}/translations/${QMAKE_FILE_BASE}.qm
lrelease.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT}
lrelease.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += lrelease
PRE_TARGETDEPS += compiler_lrelease_make_all

View File

@@ -0,0 +1,9 @@
#include "lunchmealplugin.h"
#include <QDebug>
LunchMealPlugin::LunchMealPlugin(QObject *parent) :
ZeiterfassungPlugin(parent)
{
}

View File

@@ -0,0 +1,20 @@
#ifndef LUNCHMEALPLUGIN_H
#define LUNCHMEALPLUGIN_H
#include <QObject>
#include "zeiterfassungplugin.h"
class Q_DECL_EXPORT LunchMealPlugin : public ZeiterfassungPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "dbsoftware.zeiterfassung.plugin/1.0" FILE "lunchmealplugin.json")
Q_INTERFACES(ZeiterfassungPlugin)
public:
explicit LunchMealPlugin(QObject *parent = 0);
// ZeiterfassungPlugin interface
};
#endif // LUNCHMEALPLUGIN_H

View File

@@ -0,0 +1,21 @@
QT += core network gui widgets
TARGET = lunchmealplugin
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 += lunchmealplugin.h
SOURCES += lunchmealplugin.cpp
OTHER_FILES += lunchmealplugin.json

5
plugins/plugins.pro Normal file
View File

@@ -0,0 +1,5 @@
TEMPLATE = subdirs
SUBDIRS += lunchmealplugin \
presenceplugin \
weatherplugin

View File

@@ -0,0 +1,17 @@
#include "presenceplugin.h"
#include <QDebug>
#include "mainwindow.h"
#include "presencewidget.h"
PresencePlugin::PresencePlugin(QObject *parent) :
ZeiterfassungPlugin(parent)
{
qDebug() << "called";
}
void PresencePlugin::attachTo(MainWindow &mainWindow)
{
new PresenceWidget(mainWindow);
}

View File

@@ -0,0 +1,23 @@
#ifndef PRESENCEPLUGIN_H
#define PRESENCEPLUGIN_H
#include <QObject>
#include "zeiterfassungplugin.h"
class MainWindow;
class Q_DECL_EXPORT PresencePlugin : public ZeiterfassungPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "dbsoftware.zeiterfassung.plugin/1.0" FILE "presenceplugin.json")
Q_INTERFACES(ZeiterfassungPlugin)
public:
explicit PresencePlugin(QObject *parent = 0);
// ZeiterfassungPlugin interface
void attachTo(MainWindow &mainWindow);
};
#endif // PRESENCEPLUGIN_H

View File

@@ -0,0 +1,23 @@
QT += core network gui widgets
TARGET = presenceplugin
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 += presenceplugin.h \
presencewidget.h
SOURCES += presenceplugin.cpp \
presencewidget.cpp
OTHER_FILES += presenceplugin.json

View File

@@ -0,0 +1,77 @@
#include "presencewidget.h"
#include <QLabel>
#include <QStatusBar>
#include <QTimer>
#include <QMessageBox>
#include <QStringBuilder>
#include "mainwindow.h"
#include "zeiterfassungapi.h"
PresenceWidget::PresenceWidget(MainWindow &mainWindow) :
QWidget(&mainWindow),
m_mainWindow(mainWindow)
{
m_labelAvailable = new QLabel(this);
m_labelAvailable->setFrameShape(QFrame::Panel);
m_labelAvailable->setFrameShadow(QFrame::Sunken);
m_mainWindow.statusBar()->addWidget(m_labelAvailable);
m_labelNotAvailable = new QLabel(this);
m_labelNotAvailable->setFrameShape(QFrame::Panel);
m_labelNotAvailable->setFrameShadow(QFrame::Sunken);
m_mainWindow.statusBar()->addWidget(m_labelNotAvailable);
auto timer = new QTimer(this);
timer->setInterval(60000);
connect(timer, &QTimer::timeout, this, &PresenceWidget::timeout);
timer->start();
timeout();
}
void PresenceWidget::timeout()
{
if(m_reply)
{
qWarning() << "last request not finished yet!";
return;
}
m_labelAvailable->setText(tr("%0: %1").arg(tr("Available")).arg(tr("???")));
m_labelNotAvailable->setText(tr("%0: %1").arg(tr("Not available")).arg(tr("???")));
m_reply = m_mainWindow.erfassung().doGetPresenceStatus();
connect(m_reply.get(), &ZeiterfassungReply::finished, this, &PresenceWidget::finished);
}
void PresenceWidget::finished()
{
if(!m_reply->success())
{
QMessageBox::warning(&m_mainWindow, tr("Could not get presence status!"),
tr("Could not get presence status!") % "\n\n" % m_reply->message());
goto after;
}
{
int available = 0,
notAvailable = 0;
for(const auto &status : m_reply->presenceStatuses())
{
if(status.presence == QStringLiteral("J"))
available++;
else if(status.presence == QStringLiteral("N"))
notAvailable++;
else
qWarning() << "unknown presence" << status.firstName << status.lastName << status.presence;
}
m_labelAvailable->setText(tr("%0: %1").arg(tr("Available")).arg(available));
m_labelNotAvailable->setText(tr("%0: %1").arg(tr("Not available")).arg(notAvailable));
}
after:
m_reply = Q_NULLPTR;
}

View File

@@ -0,0 +1,31 @@
#ifndef PRESENCEWIDGET_H
#define PRESENCEWIDGET_H
#include <QWidget>
#include "replies/getpresencestatusreply.h"
class QLabel;
class MainWindow;
class PresenceWidget : public QWidget
{
Q_OBJECT
public:
explicit PresenceWidget(MainWindow &mainWindow);
private Q_SLOTS:
void timeout();
void finished();
private:
MainWindow &m_mainWindow;
QLabel *m_labelAvailable;
QLabel *m_labelNotAvailable;
std::unique_ptr<GetPresenceStatusReply> m_reply;
};
#endif // PRESENCEWIDGET_H

View File

@@ -0,0 +1,9 @@
#include "weatherplugin.h"
#include <QDebug>
WeatherPlugin::WeatherPlugin(QObject *parent) :
ZeiterfassungPlugin(parent)
{
}

View File

@@ -0,0 +1,20 @@
#ifndef WEATHERPLUGIN_H
#define WEATHERPLUGIN_H
#include <QObject>
#include "zeiterfassungplugin.h"
class Q_DECL_EXPORT WeatherPlugin : public ZeiterfassungPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "dbsoftware.zeiterfassung.plugin/1.0" FILE "weatherplugin.json")
Q_INTERFACES(ZeiterfassungPlugin)
public:
explicit WeatherPlugin(QObject *parent = 0);
// ZeiterfassungPlugin interface
};
#endif // WEATHERPLUGIN_H

View File

View File

@@ -0,0 +1,21 @@
QT += core network gui widgets
TARGET = weatherplugin
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 += weatherplugin.h
SOURCES += weatherplugin.cpp
OTHER_FILES += weatherplugin.json

View File

@@ -1,29 +0,0 @@
#ifndef GETTIMEASSIGNMENTSREPLY_H
#define GETTIMEASSIGNMENTSREPLY_H
#include <memory>
#include <QNetworkReply>
#include <QVector>
#include "zeiterfassungreply.h"
#include "zeiterfassungapi.h"
class GetTimeAssignmentsReply : public ZeiterfassungReply
{
Q_OBJECT
public:
GetTimeAssignmentsReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
const QVector<ZeiterfassungApi::TimeAssignment> &timeAssignments() const;
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
QVector<ZeiterfassungApi::TimeAssignment> m_timeAssignments;
};
#endif // GETTIMEASSIGNMENTSREPLY_H

View File

@@ -1,28 +0,0 @@
#ifndef USERINFOREPLY_H
#define USERINFOREPLY_H
#include <memory>
#include <QNetworkReply>
#include "zeiterfassungreply.h"
#include "zeiterfassungapi.h"
class UserInfoReply : public ZeiterfassungReply
{
Q_OBJECT
public:
UserInfoReply(std::unique_ptr<QNetworkReply> &&reply, ZeiterfassungApi *zeiterfassung);
const ZeiterfassungApi::UserInfo &userInfo() const;
private Q_SLOTS:
void requestFinished();
private:
std::unique_ptr<QNetworkReply> m_reply;
ZeiterfassungApi::UserInfo m_userInfo;
};
#endif // USERINFOREPLY_H

View File

@@ -1,11 +0,0 @@
#ifndef TIMEUTILS_H
#define TIMEUTILS_H
#include <QTime>
int timeToSeconds(const QTime &time);
QTime timeBetween(const QTime &l, const QTime &r);
QTime timeAdd(const QTime &l, const QTime &r);
QTime timeNormalise(const QTime &time);
#endif // TIMEUTILS_H

Binary file not shown.

Binary file not shown.

View File

@@ -1,8 +0,0 @@
[General]
password=HAHA
projekte=0000001142, 0000010001, SONSTIGES
subprojekte=
texte=
url=http://localhost:8080/evoApps/
username=danielb
workpackages=[D.1315], [M.0200]

190
zeiterfassung.pro Executable file → Normal file
View File

@@ -1,186 +1,8 @@
QT += network gui widgets uitools
TEMPLATE = subdirs
CONFIG += c++14
CONFIG -= app_bundle
SUBDIRS += plugins \
zeiterfassung \
zeiterfassunglib
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
RC_ICONS = icon.ico
SOURCES += main.cpp \
mainwindow.cpp \
dialogs/aboutmedialog.cpp \
dialogs/authenticationdialog.cpp \
zeiterfassungsettings.cpp \
dialogs/settingsdialog.cpp \
dialogs/languageselectiondialog.cpp \
dialogs/timeassignmentdialog.cpp \
models/timeassignmentsmodel.cpp \
dialogs/bookingdialog.cpp \
models/bookingsmodel.cpp \
dialogs/updatedialog.cpp \
stripswidget.cpp \
timeutils.cpp \
stripfactory.cpp \
zeiterfassungapi.cpp \
replies/loginpagereply.cpp \
replies/loginreply.cpp \
replies/userinforeply.cpp \
replies/getbookingsreply.cpp \
replies/createbookingreply.cpp \
replies/updatebookingreply.cpp \
replies/deletebookingreply.cpp \
replies/gettimeassignmentsreply.cpp \
replies/createtimeassignmentreply.cpp \
replies/updatetimeassignmentreply.cpp \
replies/getprojectsreply.cpp \
replies/getauswertungreply.cpp \
replies/zeiterfassungreply.cpp \
replies/deletetimeassignmentreply.cpp \
replies/getpresencestatusreply.cpp
HEADERS += \
mainwindow.h \
dialogs/aboutmedialog.h \
dialogs/authenticationdialog.h \
zeiterfassungsettings.h \
dialogs/settingsdialog.h \
dialogs/languageselectiondialog.h \
dialogs/timeassignmentdialog.h \
models/timeassignmentsmodel.h \
dialogs/bookingdialog.h \
models/bookingsmodel.h \
dialogs/updatedialog.h \
stripswidget.h \
timeutils.h \
stripfactory.h \
zeiterfassungapi.h \
replies/loginpagereply.h \
replies/loginreply.h \
replies/userinforeply.h \
replies/getbookingsreply.h \
replies/createbookingreply.h \
replies/updatebookingreply.h \
replies/deletebookingreply.h \
replies/gettimeassignmentsreply.h \
replies/createtimeassignmentreply.h \
replies/updatetimeassignmentreply.h \
replies/getprojectsreply.h \
replies/getauswertungreply.h \
replies/zeiterfassungreply.h \
replies/deletetimeassignmentreply.h \
cpp14polyfills.h \
replies/getpresencestatusreply.h
FORMS += \
mainwindow.ui \
dialogs/aboutmedialog.ui \
dialogs/authenticationdialog.ui \
dialogs/settingsdialog.ui \
dialogs/languageselectiondialog.ui \
dialogs/timeassignmentdialog.ui \
dialogs/bookingdialog.ui \
dialogs/updatedialog.ui
RESOURCES += \
resources.qrc
TRANSLATIONS += \
translations/zeiterfassung_en.ts \
translations/zeiterfassung_de.ts
win32 {
CONFIG(debug, release|debug) {
translationsinstall.path = $${OUT_PWD}/debug/translations
themesinstall.path = $${OUT_PWD}/debug/themes
darkthemeinstall.path = $${OUT_PWD}/debug/themes/dark_theme
stripsinstall.path = $${OUT_PWD}/debug/strips
} else {
translationsinstall.path = $${OUT_PWD}/release/translations
themesinstall.path = $${OUT_PWD}/release/themes
darkthemeinstall.path = $${OUT_PWD}/release/themes/dark_theme
stripsinstall.path = $${OUT_PWD}/release/strips
}
}
unix {
translationsinstall.path = $${OUT_PWD}/translations
themesinstall.path = $${OUT_PWD}/themes
darkthemeinstall.path = $${OUT_PWD}/themes/dark_theme
stripsinstall.path = $${OUT_PWD}/strips
}
translationsinstall.files = $$[QT_INSTALL_TRANSLATIONS]/qt_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtbase_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtmultimedia_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtquick1_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtscript_nen.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtxmlpatterns_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qt_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtbase_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtmultimedia_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtquick1_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtscript_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtxmlpatterns_de.qm \
translations/zeiterfassung_en.qm \
translations/zeiterfassung_de.qm
themesinstall.files = themes/dark_theme.qss
darkthemeinstall.files = themes/dark_theme/checkbox_indeterminate_disabled.png \
themes/dark_theme/radio_unchecked.png \
themes/dark_theme/up_arrow.png \
themes/dark_theme/branch_closed-on.png \
themes/dark_theme/checkbox_checked_disabled.png \
themes/dark_theme/checkbox_unchecked.png \
themes/dark_theme/checkbox_indeterminate.png \
themes/dark_theme/stylesheet-branch-more.png \
themes/dark_theme/checkbox_checked.png \
themes/dark_theme/checkbox_unchecked_disabled.png \
themes/dark_theme/radio_checked.png \
themes/dark_theme/checkbox_indeterminate_focus.png \
themes/dark_theme/checkbox_checked_focus.png \
themes/dark_theme/branch_closed.png \
themes/dark_theme/Vsepartoolbar.png \
themes/dark_theme/radio_checked_disabled.png \
themes/dark_theme/left_arrow.png \
themes/dark_theme/Vmovetoolbar.png \
themes/dark_theme/branch_open-on.png \
themes/dark_theme/close.png \
themes/dark_theme/stylesheet-branch-end.png \
themes/dark_theme/stylesheet-vline.png \
themes/dark_theme/down_arrow_disabled.png \
themes/dark_theme/radio_unchecked_disabled.png \
themes/dark_theme/left_arrow_disabled.png \
themes/dark_theme/Hmovetoolbar.png \
themes/dark_theme/close-pressed.png \
themes/dark_theme/up_arrow_disabled.png \
themes/dark_theme/branch_open.png \
themes/dark_theme/radio_checked_focus.png \
themes/dark_theme/sizegrip.png \
themes/dark_theme/checkbox_unchecked_focus.png \
themes/dark_theme/right_arrow_disabled.png \
themes/dark_theme/Hsepartoolbar.png \
themes/dark_theme/undock.png \
themes/dark_theme/transparent.png \
themes/dark_theme/close-hover.png \
themes/dark_theme/radio_unchecked_focus.png \
themes/dark_theme/down_arrow.png \
themes/dark_theme/right_arrow.png
stripsinstall.files = strips/bookingstartstrip.ui \
strips/bookingendstrip.ui \
strips/timeassignmentstrip.ui
INSTALLS += translationsinstall
INSTALLS += themesinstall
INSTALLS += darkthemeinstall
INSTALLS += stripsinstall
plugins.depends += zeiterfassunglib
zeiterfassung.depends += zeiterfassunglib

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,91 @@
COMPILED_TRANSLATIONS += $$[QT_INSTALL_TRANSLATIONS]/qt_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtbase_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtmultimedia_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtquick1_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtscript_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtxmlpatterns_en.qm \
$$[QT_INSTALL_TRANSLATIONS]/qt_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtbase_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtmultimedia_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtquick1_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtscript_de.qm \
$$[QT_INSTALL_TRANSLATIONS]/qtxmlpatterns_de.qm \
$${OUT_PWD}/translations/zeiterfassung_en.qm \
$${OUT_PWD}/translations/zeiterfassung_de.qm \
$${OUT_PWD}/../zeiterfassunglib/translations/zeiterfassunglib_en.qm \
$${OUT_PWD}/../zeiterfassunglib/translations/zeiterfassunglib_de.qm
copy_compiled_translations.input = COMPILED_TRANSLATIONS
copy_compiled_translations.output = $${DESTDIR}/translations/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
copy_compiled_translations.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_compiled_translations.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += copy_compiled_translations
PRE_TARGETDEPS += compiler_copy_compiled_translations_make_all
THEMES += themes/dark_theme.qss
copy_themes.input = THEMES
copy_themes.output = $${DESTDIR}/themes/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
copy_themes.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_themes.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += copy_themes
PRE_TARGETDEPS += compiler_copy_themes_make_all
DARK_THEME_RESOURCES += themes/dark_theme/checkbox_indeterminate_disabled.png \
themes/dark_theme/radio_unchecked.png \
themes/dark_theme/up_arrow.png \
themes/dark_theme/branch_closed-on.png \
themes/dark_theme/checkbox_checked_disabled.png \
themes/dark_theme/checkbox_unchecked.png \
themes/dark_theme/checkbox_indeterminate.png \
themes/dark_theme/stylesheet-branch-more.png \
themes/dark_theme/checkbox_checked.png \
themes/dark_theme/checkbox_unchecked_disabled.png \
themes/dark_theme/radio_checked.png \
themes/dark_theme/checkbox_indeterminate_focus.png \
themes/dark_theme/checkbox_checked_focus.png \
themes/dark_theme/branch_closed.png \
themes/dark_theme/Vsepartoolbar.png \
themes/dark_theme/radio_checked_disabled.png \
themes/dark_theme/left_arrow.png \
themes/dark_theme/Vmovetoolbar.png \
themes/dark_theme/branch_open-on.png \
themes/dark_theme/close.png \
themes/dark_theme/stylesheet-branch-end.png \
themes/dark_theme/stylesheet-vline.png \
themes/dark_theme/down_arrow_disabled.png \
themes/dark_theme/radio_unchecked_disabled.png \
themes/dark_theme/left_arrow_disabled.png \
themes/dark_theme/Hmovetoolbar.png \
themes/dark_theme/close-pressed.png \
themes/dark_theme/up_arrow_disabled.png \
themes/dark_theme/branch_open.png \
themes/dark_theme/radio_checked_focus.png \
themes/dark_theme/sizegrip.png \
themes/dark_theme/checkbox_unchecked_focus.png \
themes/dark_theme/right_arrow_disabled.png \
themes/dark_theme/Hsepartoolbar.png \
themes/dark_theme/undock.png \
themes/dark_theme/transparent.png \
themes/dark_theme/close-hover.png \
themes/dark_theme/radio_unchecked_focus.png \
themes/dark_theme/down_arrow.png \
themes/dark_theme/right_arrow.png
copy_dark_theme_resouces.input = DARK_THEME_RESOURCES
copy_dark_theme_resouces.output = $${DESTDIR}/themes/dark_theme/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
copy_dark_theme_resouces.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_dark_theme_resouces.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += copy_dark_theme_resouces
PRE_TARGETDEPS += compiler_copy_dark_theme_resouces_make_all
STRIPLAYOUTS += strips/bookingstartstrip.ui \
strips/bookingendstrip.ui \
strips/timeassignmentstrip.ui
copy_striplayouts.input = STRIPLAYOUTS
copy_striplayouts.output = $${DESTDIR}/strips/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
copy_striplayouts.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_striplayouts.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += copy_striplayouts
PRE_TARGETDEPS += compiler_copy_striplayouts_make_all

View File

@@ -0,0 +1,8 @@
SCRIPTS += unix/start.sh
copy_scripts.input = SCRIPTS
copy_scripts.output = $${DESTDIR}/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
copy_scripts.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_scripts.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += copy_scripts
PRE_TARGETDEPS += compiler_copy_scripts_make_all

View File

@@ -0,0 +1,44 @@
CONFIG(debug, release|debug): DEBUG_SIGN = d
LIBRARIES += win32/Qt.conf \
$$OUT_PWD/../lib/zeiterfassunglib.dll \
$$[QT_INSTALL_BINS]/Qt5Core$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_BINS]/Qt5Gui$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_BINS]/Qt5Network$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_BINS]/Qt5Widgets$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_BINS]/libgcc_s_dw2-1.dll \
$$[QT_INSTALL_BINS]/libstdc++-6.dll \
$$[QT_INSTALL_BINS]/libwinpthread-1.dll
copy_libraries.input = LIBRARIES
copy_libraries.output = $${DESTDIR}/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
copy_libraries.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_libraries.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += copy_libraries
PRE_TARGETDEPS += compiler_copy_libraries_make_all
IMAGE_FORMATS += $$[QT_INSTALL_PLUGINS]/imageformats/qgif$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_PLUGINS]/imageformats/qicns$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_PLUGINS]/imageformats/qico$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_PLUGINS]/imageformats/qjpeg$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_PLUGINS]/imageformats/qsvg$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_PLUGINS]/imageformats/qtga$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_PLUGINS]/imageformats/qtiff$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_PLUGINS]/imageformats/qwbmp$${DEBUG_SIGN}.dll \
$$[QT_INSTALL_PLUGINS]/imageformats/qwebp$${DEBUG_SIGN}.dll
copy_image_formats.input = IMAGE_FORMATS
copy_image_formats.output = $${DESTDIR}/plugins/imageformats/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
copy_image_formats.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_image_formats.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += copy_image_formats
PRE_TARGETDEPS += compiler_copy_image_formats_make_all
PLATFORMS += $$[QT_INSTALL_PLUGINS]/platforms/qwindows$${DEBUG_SIGN}.dll
copy_platforms.input = PLATFORMS
copy_platforms.output = $${DESTDIR}/plugins/platforms/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
copy_platforms.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_platforms.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += copy_platforms
PRE_TARGETDEPS += compiler_copy_platforms_make_all

View File

@@ -12,18 +12,29 @@
#include <QFileInfo>
#include <QInputDialog>
#include <QStringBuilder>
#include <QLibrary>
#include <QPluginLoader>
#include <QDebug>
#include "zeiterfassungsettings.h"
#include "dialogs/languageselectiondialog.h"
#include "zeiterfassungapi.h"
#include "dialogs/authenticationdialog.h"
#include "zeiterfassungplugin.h"
#include "mainwindow.h"
#include "replies/loginpagereply.h"
#include "replies/loginreply.h"
#include "replies/userinforeply.h"
#include "replies/getuserinforeply.h"
#include "stripfactory.h"
struct {
QTranslator qtTranslator;
QTranslator zeiterfassungTranslator;
QTranslator zeiterfassunglibTranslator;
} translators;
QVector<ZeiterfassungPlugin*> plugins;
bool loadAndInstallTranslator(QTranslator &translator,
const QLocale &locale,
const QString &filename,
@@ -46,49 +57,24 @@ bool loadAndInstallTranslator(QTranslator &translator,
return true;
}
int main(int argc, char *argv[])
bool loadTranslations(QSplashScreen &splashScreen, ZeiterfassungSettings &settings)
{
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
QApplication app(argc, argv);
qSetMessagePattern(QStringLiteral("%{time dd.MM.yyyy HH:mm:ss.zzz} "
"["
"%{if-debug}D%{endif}"
"%{if-info}I%{endif}"
"%{if-warning}W%{endif}"
"%{if-critical}C%{endif}"
"%{if-fatal}F%{endif}"
"] "
"%{function}(): "
"%{message}"));
QCoreApplication::setOrganizationDomain(QStringLiteral("brunner.ninja"));
QCoreApplication::setOrganizationName(QStringLiteral("db-software"));
QCoreApplication::setApplicationName(QStringLiteral("zeiterfassung"));
QCoreApplication::setApplicationVersion(QStringLiteral("1.3.1"));
QSplashScreen splashScreen(QPixmap(QStringLiteral(":/zeiterfassung/images/splash.png")));
splashScreen.showMessage(QCoreApplication::translate("main", "Loading settings..."));
splashScreen.show();
ZeiterfassungSettings settings(&app);
splashScreen.showMessage(QCoreApplication::translate("main", "Loading translations..."));
if(settings.language() == QLocale::AnyLanguage)
{
LanguageSelectionDialog dialog(&splashScreen);
again0:
again:
if(dialog.exec() != QDialog::Accepted)
return -1;
return false;
if(dialog.language() == QLocale::AnyLanguage)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Invalid language selection!"),
QCoreApplication::translate("main", "Invalid language selection!") % "\n\n" %
QCoreApplication::translate("main", "You did not select a valid language!"));
goto again0;
goto again;
}
settings.setLanguage(dialog.language());
@@ -97,19 +83,21 @@ int main(int argc, char *argv[])
QLocale locale(settings.language(), QLocale::Austria);
QLocale::setDefault(locale);
QTranslator qtTranslator(&app);
QTranslator zeiterfassungTranslator(&app);
{
auto translationsDir = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("translations"));
loadAndInstallTranslator(qtTranslator, locale, QStringLiteral("qt"), QStringLiteral("_"), translationsDir);
loadAndInstallTranslator(zeiterfassungTranslator, locale, QStringLiteral("zeiterfassung"), QStringLiteral("_"), translationsDir);
loadAndInstallTranslator(translators.qtTranslator, locale, QStringLiteral("qt"), QStringLiteral("_"), translationsDir);
loadAndInstallTranslator(translators.zeiterfassungTranslator, locale, QStringLiteral("zeiterfassung"), QStringLiteral("_"), translationsDir);
loadAndInstallTranslator(translators.zeiterfassunglibTranslator, locale, QStringLiteral("zeiterfassunglib"), QStringLiteral("_"), translationsDir);
return true;
}
if(!settings.theme().isEmpty())
bool loadTheme(QSplashScreen &splashScreen, ZeiterfassungSettings &settings)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Loading theme..."));
if(settings.theme().isEmpty())
return true;
auto themePath = QDir(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("themes"))).absoluteFilePath(settings.theme());
QFile file(themePath % ".qss");
@@ -119,7 +107,7 @@ int main(int argc, char *argv[])
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load theme!"),
QCoreApplication::translate("main", "Could not load theme!") % "\n\n" %
QCoreApplication::translate("main", "Theme file does not exist!"));
goto after;
return false;
}
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
@@ -127,21 +115,64 @@ int main(int argc, char *argv[])
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load theme!"),
QCoreApplication::translate("main", "Could not load theme!") % "\n\n" %
file.errorString());
goto after;
return false;
}
QTextStream textStream(&file);
app.setStyleSheet(textStream.readAll().replace(QStringLiteral("@THEME_RESOURCES@"), themePath));
qApp->setStyleSheet(textStream.readAll().replace(QStringLiteral("@THEME_RESOURCES@"), themePath));
return true;
}
after:
bool loadStripLayouts(QSplashScreen &splashScreen, StripFactory &stripFactory)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Loading strip layouts..."));
splashScreen.showMessage(QCoreApplication::translate("main", "Loading login page..."));
ZeiterfassungApi erfassung(settings.url(), &app);
if(!stripFactory.load(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("strips"))))
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return false;
}
{
again1:
auto widget = stripFactory.createBookingStartStrip();
if(!widget)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return false;
}
}
{
auto widget = stripFactory.createBookingEndStrip();
if(!widget)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return false;
}
}
{
auto widget = stripFactory.createTimeAssignmentStrip();
if(!widget)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return false;
}
}
return true;
}
bool loadLoginPage(QSplashScreen &splashScreen, ZeiterfassungSettings &settings, ZeiterfassungApi &erfassung)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Loading login page..."));
again:
auto reply = erfassung.doLoginPage();
{
@@ -152,35 +183,43 @@ int main(int argc, char *argv[])
if(!reply->success())
{
bool ok;
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not access Zeiterfassung!"),
QCoreApplication::translate("main", "Could not access Zeiterfassung!") % "\n\n" % reply->message());
bool ok;
auto url = QInputDialog::getText(&splashScreen, QCoreApplication::translate("main", "Base url"),
QCoreApplication::translate("main", "Please enter the base url to the Zeiterfassung:"),
QLineEdit::Normal, settings.url(), &ok);
if(!ok)
return -1;
return false;
settings.setUrl(url);
erfassung.setUrl(url);
goto again1;
}
goto again;
}
return true;
}
bool doAuthentication(QSplashScreen &splashScreen, ZeiterfassungSettings &settings, ZeiterfassungApi &erfassung)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Authenticating..."));
if(settings.username().isNull() || settings.password().isNull())
{
AuthenticationDialog dialog(&splashScreen);
if(dialog.exec() != QDialog::Accepted)
return -1;
return false;
settings.setUsername(dialog.username());
settings.setPassword(dialog.password());
}
{
again2:
again:
auto reply = erfassung.doLogin(settings.username(), settings.password());
{
@@ -197,19 +236,24 @@ int main(int argc, char *argv[])
AuthenticationDialog dialog(&splashScreen);
dialog.setUsername(settings.username());
dialog.setPassword(settings.password());
if(dialog.exec() != QDialog::Accepted)
return -1;
return false;
settings.setUsername(dialog.username());
settings.setPassword(dialog.password());
goto again2;
goto again;
}
}
return true;
}
bool loadUserInfo(QSplashScreen &splashScreen, ZeiterfassungApi &erfassung, GetUserInfoReply::UserInfo &userInfo)
{
splashScreen.showMessage(QCoreApplication::translate("main", "Getting user information..."));
ZeiterfassungApi::UserInfo userInfo;
{
auto reply = erfassung.doUserInfo();
@@ -223,56 +267,123 @@ int main(int argc, char *argv[])
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not get user information!"),
QCoreApplication::translate("main", "Could not get user information!") % "\n\n" % reply->message());
return -1;
return false;
}
userInfo = reply->userInfo();
}
splashScreen.showMessage(QCoreApplication::translate("main", "Loading strip layouts..."));
return true;
}
bool loadPlugins(QSplashScreen &splashScreen)
{
auto ok = true;
QDir dir(
QDir(
QDir(
QCoreApplication::applicationDirPath()
).absoluteFilePath(QStringLiteral("plugins"))
).absoluteFilePath(QStringLiteral("zeiterfassung"))
);
for(const auto &fileInfo : dir.entryInfoList(QDir::Files))
{
if(fileInfo.isSymLink())
continue; // to skip unix so symlinks
if(!QLibrary::isLibrary(fileInfo.filePath()))
continue; // to skip windows junk files
QPluginLoader loader(fileInfo.filePath());
if(!loader.load())
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load plugin %0!"),
QCoreApplication::translate("main", "Could not load plugin %0!").arg(fileInfo.fileName()) %
"\n\n" % loader.errorString());
ok = false;
continue;
}
auto plugin = qobject_cast<ZeiterfassungPlugin*>(loader.instance());
if(!plugin)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Plugin not valid %0!"),
QCoreApplication::translate("main", "Plugin not valid %0!").arg(fileInfo.fileName()) %
"\n\n" % loader.errorString());
ok = false;
continue;
}
plugins.append(plugin);
}
return ok;
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
qSetMessagePattern(QStringLiteral("%{time dd.MM.yyyy HH:mm:ss.zzz} "
"["
"%{if-debug}D%{endif}"
"%{if-info}I%{endif}"
"%{if-warning}W%{endif}"
"%{if-critical}C%{endif}"
"%{if-fatal}F%{endif}"
"] "
"%{function}(): "
"%{message}"));
QCoreApplication::setOrganizationDomain(QStringLiteral("brunner.ninja"));
QCoreApplication::setOrganizationName(QStringLiteral("db-software"));
QCoreApplication::setApplicationName(QStringLiteral("zeiterfassung"));
QCoreApplication::setApplicationVersion(QStringLiteral("1.4"));
QSplashScreen splashScreen(QPixmap(QStringLiteral(":/zeiterfassunglib/images/splash.png")));
splashScreen.showMessage(QCoreApplication::translate("main", "Loading settings..."));
splashScreen.show();
ZeiterfassungSettings settings(&app);
if(!loadTranslations(splashScreen, settings))
return -1;
// not critical if it fails
//if(!loadTheme(splashScreen, settings))
// return -2;
loadTheme(splashScreen, settings);
StripFactory stripFactory(&app);
if(!stripFactory.load(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(QStringLiteral("strips"))))
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return -1;
}
{
auto widget = stripFactory.createBookingStartStrip();
if(!widget)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return -1;
}
}
if(!loadStripLayouts(splashScreen, stripFactory))
return -3;
{
auto widget = stripFactory.createBookingEndStrip();
if(!widget)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return -1;
}
}
ZeiterfassungApi erfassung(settings.url(), &app);
{
auto widget = stripFactory.createTimeAssignmentStrip();
if(!widget)
{
QMessageBox::warning(&splashScreen, QCoreApplication::translate("main", "Could not load strips!"),
QCoreApplication::translate("main", "Could not load strips!") % "\n\n" % stripFactory.errorString());
return -1;
}
}
if(!loadLoginPage(splashScreen, settings, erfassung))
return -4;
if(!doAuthentication(splashScreen, settings, erfassung))
return -5;
GetUserInfoReply::UserInfo userInfo;
if(!loadUserInfo(splashScreen, erfassung, userInfo))
return -6;
loadPlugins(splashScreen);
MainWindow mainWindow(settings, erfassung, userInfo, stripFactory);
mainWindow.show();
splashScreen.finish(&mainWindow);
for(auto plugin : plugins)
plugin->attachTo(mainWindow);
mainWindow.show();
return app.exec();
}

View File

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 220 B

View File

Before

Width:  |  Height:  |  Size: 172 B

After

Width:  |  Height:  |  Size: 172 B

View File

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 228 B

View File

Before

Width:  |  Height:  |  Size: 187 B

After

Width:  |  Height:  |  Size: 187 B

View File

Before

Width:  |  Height:  |  Size: 147 B

After

Width:  |  Height:  |  Size: 147 B

View File

Before

Width:  |  Height:  |  Size: 160 B

After

Width:  |  Height:  |  Size: 160 B

View File

Before

Width:  |  Height:  |  Size: 150 B

After

Width:  |  Height:  |  Size: 150 B

View File

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 166 B

View File

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 492 B

View File

Before

Width:  |  Height:  |  Size: 491 B

After

Width:  |  Height:  |  Size: 491 B

View File

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 252 B

View File

Before

Width:  |  Height:  |  Size: 493 B

After

Width:  |  Height:  |  Size: 493 B

View File

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 492 B

View File

Before

Width:  |  Height:  |  Size: 249 B

After

Width:  |  Height:  |  Size: 249 B

View File

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 464 B

View File

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 464 B

View File

Before

Width:  |  Height:  |  Size: 240 B

After

Width:  |  Height:  |  Size: 240 B

View File

Before

Width:  |  Height:  |  Size: 598 B

After

Width:  |  Height:  |  Size: 598 B

View File

Before

Width:  |  Height:  |  Size: 598 B

After

Width:  |  Height:  |  Size: 598 B

View File

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 586 B

View File

Before

Width:  |  Height:  |  Size: 165 B

After

Width:  |  Height:  |  Size: 165 B

View File

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 166 B

View File

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 166 B

View File

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 166 B

View File

Before

Width:  |  Height:  |  Size: 940 B

After

Width:  |  Height:  |  Size: 940 B

View File

Before

Width:  |  Height:  |  Size: 972 B

After

Width:  |  Height:  |  Size: 972 B

View File

Before

Width:  |  Height:  |  Size: 846 B

After

Width:  |  Height:  |  Size: 846 B

View File

Before

Width:  |  Height:  |  Size: 728 B

After

Width:  |  Height:  |  Size: 728 B

View File

Before

Width:  |  Height:  |  Size: 760 B

After

Width:  |  Height:  |  Size: 760 B

View File

Before

Width:  |  Height:  |  Size: 646 B

After

Width:  |  Height:  |  Size: 646 B

View File

Before

Width:  |  Height:  |  Size: 160 B

After

Width:  |  Height:  |  Size: 160 B

View File

Before

Width:  |  Height:  |  Size: 160 B

After

Width:  |  Height:  |  Size: 160 B

View File

Before

Width:  |  Height:  |  Size: 129 B

After

Width:  |  Height:  |  Size: 129 B

View File

Before

Width:  |  Height:  |  Size: 224 B

After

Width:  |  Height:  |  Size: 224 B

View File

Before

Width:  |  Height:  |  Size: 182 B

After

Width:  |  Height:  |  Size: 182 B

View File

Before

Width:  |  Height:  |  Size: 239 B

After

Width:  |  Height:  |  Size: 239 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 578 B

After

Width:  |  Height:  |  Size: 578 B

View File

Before

Width:  |  Height:  |  Size: 158 B

After

Width:  |  Height:  |  Size: 158 B

View File

Before

Width:  |  Height:  |  Size: 159 B

After

Width:  |  Height:  |  Size: 159 B

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de_DE">
<context>
<name>bookingEndStrip</name>
<message>
<location filename="../strips/bookingendstrip.ui" line="72"/>
<source>END</source>
<translation>GEHEN</translation>
</message>
</context>
<context>
<name>bookingStartStrip</name>
<message>
<location filename="../strips/bookingstartstrip.ui" line="72"/>
<source>START</source>
<translation>KOMMEN</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.cpp" line="347"/>
<source>Loading settings...</source>
<translation>Lade Einstellungen...</translation>
</message>
<message>
<location filename="../main.cpp" line="62"/>
<source>Loading translations...</source>
<translation>Lade Übersetzungen...</translation>
</message>
<message>
<location filename="../main.cpp" line="74"/>
<location filename="../main.cpp" line="75"/>
<source>Invalid language selection!</source>
<translation>Ungültige Sprachauswahl!</translation>
</message>
<message>
<location filename="../main.cpp" line="76"/>
<source>You did not select a valid language!</source>
<translation>Sie haben keine gültige Sprachauswahl getroffen!</translation>
</message>
<message>
<location filename="../main.cpp" line="96"/>
<source>Loading theme...</source>
<translation>Lade Aussehen...</translation>
</message>
<message>
<location filename="../main.cpp" line="107"/>
<location filename="../main.cpp" line="108"/>
<location filename="../main.cpp" line="115"/>
<location filename="../main.cpp" line="116"/>
<source>Could not load theme!</source>
<translation>Konnte Aussehen nicht laden!</translation>
</message>
<message>
<location filename="../main.cpp" line="109"/>
<source>Theme file does not exist!</source>
<translation>Aussehen-Datei existiert nicht!</translation>
</message>
<message>
<location filename="../main.cpp" line="173"/>
<source>Loading login page...</source>
<translation>Lade Login-Seite...</translation>
</message>
<message>
<location filename="../main.cpp" line="186"/>
<location filename="../main.cpp" line="187"/>
<source>Could not access Zeiterfassung!</source>
<translation>Konnte Zeiterfassung nicht erreichen!</translation>
</message>
<message>
<location filename="../main.cpp" line="190"/>
<source>Base url</source>
<translation>Basis URL</translation>
</message>
<message>
<location filename="../main.cpp" line="191"/>
<source>Please enter the base url to the Zeiterfassung:</source>
<translation>Bitte geben Sie die Basis URL zur Zeiterfassung ein:</translation>
</message>
<message>
<location filename="../main.cpp" line="208"/>
<source>Authenticating...</source>
<translation>Authentifiziere...</translation>
</message>
<message>
<location filename="../main.cpp" line="233"/>
<location filename="../main.cpp" line="234"/>
<source>Could not authenticate with Zeiterfassung!</source>
<translation>Konnte nicht mit Zeiterfassung authentifizieren!</translation>
</message>
<message>
<location filename="../main.cpp" line="255"/>
<source>Getting user information...</source>
<translation>Hole Benutzer Information...</translation>
</message>
<message>
<location filename="../main.cpp" line="268"/>
<location filename="../main.cpp" line="269"/>
<source>Could not get user information!</source>
<translation>Konnte Benutzer Information nicht holen!</translation>
</message>
<message>
<location filename="../main.cpp" line="302"/>
<location filename="../main.cpp" line="303"/>
<source>Could not load plugin %0!</source>
<translation>Konnte Plugin %0 nicht laden!</translation>
</message>
<message>
<location filename="../main.cpp" line="313"/>
<location filename="../main.cpp" line="314"/>
<source>Plugin not valid %0!</source>
<translation>Plugin %0 nicht gültig!</translation>
</message>
<message>
<location filename="../main.cpp" line="129"/>
<source>Loading strip layouts...</source>
<translation>Lade Streifenlayouts...</translation>
</message>
<message>
<location filename="../main.cpp" line="133"/>
<location filename="../main.cpp" line="134"/>
<location filename="../main.cpp" line="142"/>
<location filename="../main.cpp" line="143"/>
<location filename="../main.cpp" line="152"/>
<location filename="../main.cpp" line="153"/>
<location filename="../main.cpp" line="162"/>
<location filename="../main.cpp" line="163"/>
<source>Could not load strips!</source>
<translation>Konnte Streifenlayouts nicht laden!</translation>
</message>
</context>
</TS>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
<name>bookingEndStrip</name>
<message>
<location filename="../strips/bookingendstrip.ui" line="72"/>
<source>END</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>bookingStartStrip</name>
<message>
<location filename="../strips/bookingstartstrip.ui" line="72"/>
<source>START</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.cpp" line="347"/>
<source>Loading settings...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="62"/>
<source>Loading translations...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="74"/>
<location filename="../main.cpp" line="75"/>
<source>Invalid language selection!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="76"/>
<source>You did not select a valid language!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="96"/>
<source>Loading theme...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="107"/>
<location filename="../main.cpp" line="108"/>
<location filename="../main.cpp" line="115"/>
<location filename="../main.cpp" line="116"/>
<source>Could not load theme!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="109"/>
<source>Theme file does not exist!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="173"/>
<source>Loading login page...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="186"/>
<location filename="../main.cpp" line="187"/>
<source>Could not access Zeiterfassung!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="190"/>
<source>Base url</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="191"/>
<source>Please enter the base url to the Zeiterfassung:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="208"/>
<source>Authenticating...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="233"/>
<location filename="../main.cpp" line="234"/>
<source>Could not authenticate with Zeiterfassung!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="255"/>
<source>Getting user information...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="268"/>
<location filename="../main.cpp" line="269"/>
<source>Could not get user information!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="302"/>
<location filename="../main.cpp" line="303"/>
<source>Could not load plugin %0!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="313"/>
<location filename="../main.cpp" line="314"/>
<source>Plugin not valid %0!</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="129"/>
<source>Loading strip layouts...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../main.cpp" line="133"/>
<location filename="../main.cpp" line="134"/>
<location filename="../main.cpp" line="142"/>
<location filename="../main.cpp" line="143"/>
<location filename="../main.cpp" line="152"/>
<location filename="../main.cpp" line="153"/>
<location filename="../main.cpp" line="162"/>
<location filename="../main.cpp" line="163"/>
<source>Could not load strips!</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

1
zeiterfassung/unix/start.sh Executable file
View File

@@ -0,0 +1 @@
LD_LIBRARY_PATH=../lib ./zeiterfassung

View File

37
zeiterfassung/zeiterfassung.pro Executable file
View File

@@ -0,0 +1,37 @@
QT += core network gui widgets
TARGET = zeiterfassung
TEMPLATE = app
CONFIG += c++14
CONFIG -= app_bundle
DESTDIR = $${OUT_PWD}/../bin
LIBS += -L$$OUT_PWD/../lib -lzeiterfassunglib
INCLUDEPATH += $$PWD/../zeiterfassunglib
DEPENDPATH += $$PWD/../zeiterfassunglib
DEFINES += QT_DEPRECATED_WARNINGS QT_DISABLE_DEPRECATED_BEFORE=0x060000 QT_MESSAGELOGCONTEXT
RC_ICONS = icon.ico
SOURCES += main.cpp
HEADERS +=
FORMS += strips/bookingstartstrip.ui \
strips/bookingendstrip.ui \
strips/timeassignmentstrip.ui
RESOURCES +=
TRANSLATIONS += translations/zeiterfassung_en.ts \
translations/zeiterfassung_de.ts
include(../lrelease.pri)
include(installs.pri)
unix: include(installs_unix.pri)
win32: include(installs_win32.pri)

View File

@@ -1,10 +1,9 @@
#include "aboutmedialog.h"
#include "ui_aboutmedialog.h"
AboutMeDialog::AboutMeDialog(const ZeiterfassungApi::UserInfo &userInfo, QWidget *parent) :
AboutMeDialog::AboutMeDialog(const GetUserInfoReply::UserInfo &userInfo, QWidget *parent) :
QDialog(parent),
ui(new Ui::AboutMeDialog),
m_userInfo(userInfo)
ui(new Ui::AboutMeDialog)
{
ui->setupUi(this);

View File

@@ -3,21 +3,21 @@
#include <QDialog>
#include "zeiterfassungapi.h"
#include "zeiterfassunglib_global.h"
#include "replies/getuserinforeply.h"
namespace Ui { class AboutMeDialog; }
class AboutMeDialog : public QDialog
class ZEITERFASSUNGLIBSHARED_EXPORT AboutMeDialog : public QDialog
{
Q_OBJECT
public:
explicit AboutMeDialog(const ZeiterfassungApi::UserInfo &userInfo, QWidget *parent = Q_NULLPTR);
explicit AboutMeDialog(const GetUserInfoReply::UserInfo &userInfo, QWidget *parent = Q_NULLPTR);
~AboutMeDialog();
private:
Ui::AboutMeDialog *ui;
const ZeiterfassungApi::UserInfo &m_userInfo;
};
#endif // ABOUTMEDIALOG_H

View File

@@ -3,11 +3,13 @@
#include <QDialog>
#include "zeiterfassunglib_global.h"
namespace Ui {
class AuthenticationDialog;
}
class AuthenticationDialog : public QDialog
class ZEITERFASSUNGLIBSHARED_EXPORT AuthenticationDialog : public QDialog
{
Q_OBJECT

View File

@@ -37,7 +37,7 @@
</size>
</property>
<property name="pixmap">
<pixmap resource="../resources.qrc">:/zeiterfassung/images/authentication.png</pixmap>
<pixmap resource="../resources.qrc">:/zeiterfassunglib/images/authentication.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>

View File

@@ -4,9 +4,11 @@
#include <QDialog>
#include <QTime>
#include "zeiterfassunglib_global.h"
namespace Ui { class BookingDialog; }
class BookingDialog : public QDialog
class ZEITERFASSUNGLIBSHARED_EXPORT BookingDialog : public QDialog
{
Q_OBJECT

View File

@@ -4,9 +4,11 @@
#include <QDialog>
#include <QLocale>
#include "zeiterfassunglib_global.h"
namespace Ui { class LanguageSelectionDialog; }
class LanguageSelectionDialog : public QDialog
class ZEITERFASSUNGLIBSHARED_EXPORT LanguageSelectionDialog : public QDialog
{
Q_OBJECT

View File

@@ -3,10 +3,12 @@
#include <QDialog>
#include "zeiterfassunglib_global.h"
class ZeiterfassungSettings;
namespace Ui { class SettingsDialog; }
class SettingsDialog : public QDialog
class ZEITERFASSUNGLIBSHARED_EXPORT SettingsDialog : public QDialog
{
Q_OBJECT

View File

@@ -4,13 +4,15 @@
#include <QDialog>
#include <QTime>
#include "zeiterfassunglib_global.h"
template <class Key, class T> class QMap;
class ZeiterfassungSettings;
namespace Ui { class TimeAssignmentDialog; }
class TimeAssignmentDialog : public QDialog
class ZEITERFASSUNGLIBSHARED_EXPORT TimeAssignmentDialog : public QDialog
{
Q_OBJECT

View File

@@ -4,13 +4,15 @@
#include <QDialog>
#include <QUrl>
#include "zeiterfassunglib_global.h"
class QNetworkAccessManager;
class QNetworkReply;
class ZeiterfassungSettings;
namespace Ui { class UpdateDialog; }
class UpdateDialog : public QDialog
class ZEITERFASSUNGLIBSHARED_EXPORT UpdateDialog : public QDialog
{
Q_OBJECT

Some files were not shown because too many files have changed in this diff Show More