Skip to content

Commit

Permalink
Rework activity combo
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandrePTJ committed Jun 5, 2024
1 parent 98795aa commit 6de20d3
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 23 deletions.
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ set(SRCS
gui/settingsDialog.cpp
gui/taskWidget.cpp
gui/timeSheetListWidgetItem.cpp
gui/timeSheetParamsItemDelegate.cpp
main.cpp
misc/dataReader.cpp
misc/helpers.cpp
models/loggerTreeModel.cpp
models/taskFilterProxyModel.cpp
models/taskListModel.cpp
models/timeSheetParamsModel.cpp
monitor/desktopEventsMonitor.cpp
monitor/kimaiEventsMonitor.cpp
settings/settings.cpp
Expand All @@ -53,12 +55,14 @@ set(HDRS
gui/settingsDialog.h
gui/taskWidget.h
gui/timeSheetListWidgetItem.h
gui/timeSheetParamsItemDelegate.h
misc/customFmt.h
misc/dataReader.h
misc/helpers.h
models/loggerTreeModel.h
models/taskFilterProxyModel.h
models/taskListModel.h
models/timeSheetParamsModel.h
monitor/desktopEventsMonitor.h
monitor/kimaiEventsMonitor.h
settings/settings.h
Expand Down
27 changes: 12 additions & 15 deletions src/gui/activityWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@
#include "misc/customFmt.h"
#include "misc/helpers.h"
#include "timeSheetListWidgetItem.h"
#include "timeSheetParamsItemDelegate.h"

using namespace kemai;

ActivityWidget::ActivityWidget(QWidget* parent) : QWidget(parent), mUi(std::make_unique<Ui::ActivityWidget>())
{
mUi->setupUi(this);

mUi->cbTimeSheetParams->setModel(&mTimeSheetParamsModel);
mUi->cbTimeSheetParams->setItemDelegate(new TimeSheetParamsItemDelegate);

connect(mUi->btStartStop, &QPushButton::clicked, this, &ActivityWidget::onBtStartStopClicked);
connect(&mSecondTimer, &QTimer::timeout, this, &ActivityWidget::onSecondTimeout);

Expand Down Expand Up @@ -77,12 +81,10 @@ void ActivityWidget::stopCurrentTimeSheet()

void ActivityWidget::onSecondTimeout()
{
const auto& now = QDateTime::currentDateTime();
if (mSession && mSession->hasCurrentTimeSheet())
{
mUi->lbDurationTime->setText(helpers::getDurationString(mSession->currentTimeSheet()->beginAt, now));
mUi->lbDurationTime->setText(helpers::getDurationString(mSession->currentTimeSheet()->beginAt, QDateTime::currentDateTime()));
}
else {}
}

void ActivityWidget::onSessionCurrentTimeSheetChanged()
Expand All @@ -93,8 +95,6 @@ void ActivityWidget::onSessionCurrentTimeSheetChanged()
qApp->processEvents();
}

if (mSession->hasCurrentTimeSheet()) {}

updateControls();
}

Expand All @@ -108,6 +108,8 @@ void ActivityWidget::onSessionCacheSynchronizeFinished()
{
onSessionCurrentTimeSheetChanged();
}

mTimeSheetParamsModel.updateDataFromCache(mSession->cache());
}

void ActivityWidget::onHistoryTimeSheetStartRequested(const TimeSheet& timeSheet)
Expand Down Expand Up @@ -165,22 +167,17 @@ void ActivityWidget::updateControls()
return;
}

auto noTimeSheetRunning = !mSession->hasCurrentTimeSheet();
mUi->btStartStop->setEnabled(mPendingStartRequest.has_value() || mSession->hasCurrentTimeSheet());

// bool enableStartStop = !mUi->cbProject->currentText().isEmpty() && !mUi->cbActivity->currentText().isEmpty();
// mUi->btStartStop->setEnabled(enableStartStop);

if (noTimeSheetRunning)
if (mSession->hasCurrentTimeSheet())
{
mUi->btStartStop->setIcon(QIcon(":/icons/play"));
mUi->lbDurationTime->clear();
mUi->btStartStop->setIcon(QIcon(":/icons/stop"));
}
else
{
mUi->btStartStop->setIcon(QIcon(":/icons/stop"));
mUi->btStartStop->setIcon(QIcon(":/icons/play"));
mUi->lbDurationTime->clear();
}

emit currentActivityChanged(noTimeSheetRunning);
}

void ActivityWidget::updateRecentTimeSheetsView()
Expand Down
5 changes: 2 additions & 3 deletions src/gui/activityWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "client/kimaiClient.h"
#include "context/kemaiSession.h"
#include "models/timeSheetParamsModel.h"

namespace Ui {
class ActivityWidget;
Expand All @@ -23,9 +24,6 @@ class ActivityWidget : public QWidget
void setKemaiSession(std::shared_ptr<KemaiSession> kemaiSession);
void stopCurrentTimeSheet();

signals:
void currentActivityChanged(bool started);

private:
void onBtStartStopClicked();

Expand All @@ -48,6 +46,7 @@ class ActivityWidget : public QWidget
QTimer mSecondTimer;
std::shared_ptr<KemaiSession> mSession;
std::optional<TimeSheet> mPendingStartRequest;
TimeSheetParamsModel mTimeSheetParamsModel;
};

} // namespace kemai
5 changes: 1 addition & 4 deletions src/gui/activityWidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
<number>12</number>
</property>
<item>
<widget class="QLineEdit" name="lineEdit">
<widget class="QComboBox" name="cbTimeSheetParams">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
Expand All @@ -72,9 +72,6 @@
<pointsize>12</pointsize>
</font>
</property>
<property name="frame">
<bool>true</bool>
</property>
<property name="placeholderText">
<string>What are you working on ?</string>
</property>
Expand Down
1 change: 0 additions & 1 deletion src/gui/mainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ MainWindow::MainWindow() : mUi(std::make_unique<Ui::MainWindow>())
connect(mActRefreshCache, &QAction::triggered, this, &MainWindow::onActionRefreshCacheTriggered);
connect(mSystemTrayIcon, &QSystemTrayIcon::activated, this, &MainWindow::onSystemTrayActivated);
connect(&mUpdater, &KemaiUpdater::checkFinished, this, &MainWindow::onNewVersionCheckFinished);
connect(mActivityWidget, &ActivityWidget::currentActivityChanged, this, &MainWindow::onActivityChanged);
connect(mActGroupProfiles, &QActionGroup::triggered, this, &MainWindow::onProfilesActionGroupTriggered);
connect(mActAboutKemai, &QAction::triggered, this, &MainWindow::onActionAboutKemaiTriggered);
connect(mActShowLogWidget, &QAction::triggered, &mLoggerWidget, &QWidget::show);
Expand Down
60 changes: 60 additions & 0 deletions src/gui/timeSheetParamsItemDelegate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "timeSheetParamsItemDelegate.h"

#include <QApplication>
#include <QPainter>
#include <QStyle>

#include "models/timeSheetParamsModel.h"

using namespace kemai;

static const auto gIndicatorWidth = 2;
static const auto gTextSpacing = 2;
static const auto gTextLeftOffset = gIndicatorWidth + gTextSpacing;
static const auto gPadding = 4;

// gIndicatorWidth + gPadding (1 x blue rect + 1 x empty)
// | |
// || < gPadding >
// || Customer name
// || < gTextSpacing >
// || Project name (on gProjectMaxWidth) < gTextSpacing > Activity name
// || < gPadding >

void TimeSheetParamsItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
// Indicate selection
auto isSelected = (option.state & QStyle::State_Selected) != 0;
if (isSelected)
{
painter->fillRect(option.rect, option.palette.mid());
painter->fillRect(QRect(option.rect.topLeft(), QSize(gIndicatorWidth, option.rect.height())), option.palette.highlight());
}

const auto textX = option.rect.left() + gTextLeftOffset;
const auto textH = option.fontMetrics.height();
const auto widthThird = option.rect.width() / 3;
const auto secondLineY = option.rect.top() + gPadding + option.fontMetrics.height() + gTextSpacing;

// Customer
auto headerRect = QRect(textX, option.rect.top() + gPadding, option.rect.width(), textH);
qApp->style()->drawItemText(painter, headerRect, Qt::AlignLeft, option.palette, isSelected, index.data(TimeSheetParamsModel::CustomerName).toString());

// Project
auto projectRect = QRect(textX, secondLineY, widthThird, textH);
qApp->style()->drawItemText(painter, projectRect, Qt::AlignLeft, option.palette, isSelected, index.data(TimeSheetParamsModel::ProjectName).toString());

// Activity
auto activityRect = QRect(textX + widthThird, secondLineY, 2 * widthThird, textH);
qApp->style()->drawItemText(painter, activityRect, Qt::AlignLeft, option.palette, isSelected, index.data(TimeSheetParamsModel::ActivityName).toString());

if (option.showDecorationSelected)
{
qDebug() << index.data().toString();
}
}

QSize TimeSheetParamsItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
return {option.rect.width(), option.fontMetrics.height() * 2 + gTextSpacing + 2 * gPadding};
}
14 changes: 14 additions & 0 deletions src/gui/timeSheetParamsItemDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <QStyledItemDelegate>

namespace kemai {

class TimeSheetParamsItemDelegate : public QStyledItemDelegate
{
public:
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
};

} // namespace kemai
61 changes: 61 additions & 0 deletions src/models/timeSheetParamsModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "timeSheetParamsModel.h"

using namespace kemai;

void TimeSheetParamsModel::updateDataFromCache(const KimaiCache& cache)
{
beginResetModel();

for (const auto& customer : cache.customers())
{
for (const auto& project : cache.projects(customer.id))
{
for (const auto& activity : cache.activities(project.id))
{
m_timeSheetParams.emplace_back(TimeSheetParams{
.customer = customer.name, .project = project.name, .activity = activity.name, .projectId = project.id, .activityId = activity.id});
}
}
}

endResetModel();
}

QVariant TimeSheetParamsModel::data(const QModelIndex& index, int role) const
{

if (!index.isValid() || (index.row() > m_timeSheetParams.size()))
{
return {};
}

const auto& params = m_timeSheetParams.at(index.row());
switch (role)
{
case Qt::DisplayRole:
return QString("%1 / %2 / %3").arg(params.customer, params.project, params.activity);

case CustomerName:
return params.customer;

case ProjectName:
return params.project;

case ActivityName:
return params.activity;

case ProjectIdRole:
return params.projectId;

case ActivityIdRole:
return params.activityId;

default:
return {};
}
}

int TimeSheetParamsModel::rowCount(const QModelIndex& /*parent*/) const
{
return static_cast<int>(m_timeSheetParams.size());
}
38 changes: 38 additions & 0 deletions src/models/timeSheetParamsModel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <QAbstractListModel>

#include <client/kimaiCache.h>

namespace kemai {

class TimeSheetParamsModel : public QAbstractListModel
{
public:
enum TimeSheetParamsModelRole
{
CustomerName = Qt::UserRole + 1,
ProjectName,
ActivityName,
ProjectIdRole,
ActivityIdRole
};

void updateDataFromCache(const KimaiCache& cache);

QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;

private:
struct TimeSheetParams
{
QString customer;
QString project;
QString activity;
int projectId;
int activityId;
};
std::vector<TimeSheetParams> m_timeSheetParams;
};

} // namespace kemai

0 comments on commit 6de20d3

Please sign in to comment.