From 19a7dbf6db3fb6211c8b3112cf83878fbb3f97e8 Mon Sep 17 00:00:00 2001 From: Faerbit Date: Mon, 24 Feb 2020 15:41:08 +0100 Subject: [PATCH] Implemented report stuff: editing and switching days. --- data.py | 52 +++++++++++++++++++++++++++---- main.py | 6 ++++ report.py | 92 ++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 113 insertions(+), 37 deletions(-) diff --git a/data.py b/data.py index 769e79d..802e177 100644 --- a/data.py +++ b/data.py @@ -2,7 +2,7 @@ import os import json import base64 import atexit -from datetime import datetime, date, timedelta +from datetime import datetime, date, time, timedelta from threading import Thread, Event from collections.abc import MutableMapping @@ -117,10 +117,14 @@ class Log: def log(self, task, ptime=None): if ptime is None: ptime = datetime.now() + # round to nearest minute + round_min = timedelta(minutes=round(ptime.second/60)) + ptime = ptime - timedelta(seconds=ptime.second) + round_min + # month dance necessary to trigger Data.__setitem__ month = self._data.setdefault(ptime.strftime("%Y-%m"), {}) month.setdefault(ptime.strftime("%d"), [])\ - .append(f"{ptime.strftime('%H:%M:%S')} {base64.b64encode(task.encode('utf-8')).decode('utf-8')}") - self._data[ptime.strftime("%Y-%m")] = month # necessary to trigger Data.__setitem__ + .append(f"{ptime.strftime('%H:%M')} {base64.b64encode(task.encode('utf-8')).decode('utf-8')}") + self._data[ptime.strftime("%Y-%m")] = month def last_log(self, pdate=date.today()): if pdate.strftime("%Y-%m") not in self._data or pdate.strftime("%d") not in self._data[pdate.strftime("%Y-%m")]: @@ -128,12 +132,23 @@ class Log: return base64.b64decode( self._data[pdate.strftime("%Y-%m")][pdate.strftime("%d")][-1].split()[1].encode("utf-8")).decode("utf-8") - def report(self, pdate=date.today()): + def report(self, pdate=None): + if pdate is None: + pdate = date.today() + return Report(self._data, pdate) + + +class Report: + def __init__(self, data, pdate): + self._data = data + self._date = pdate + + def report(self): tmp = [] - for e in self._data[pdate.strftime("%Y-%m")][pdate.strftime("%d")]: + for e in self._data[self._date.strftime("%Y-%m")][self._date.strftime("%d")]: tstr, b64str = e.split() task = base64.b64decode(b64str.encode("utf-8")).decode("utf-8") - start_time = datetime.combine(pdate, datetime.strptime(tstr, "%H:%M:%S").time()) + start_time = datetime.combine(self._date, datetime.strptime(tstr, "%H:%M").time()) tmp.append((task, start_time)) ret = [] @@ -155,3 +170,28 @@ class Log: dmins, _ = divmod(rem, 60) ret.append(("Sum", "", f"{dhours:02d}:{dmins:02d}")) return ret + + def save(self, report): + report = report[:-2] # cut of sum display + save_list = [] + for tstr, ttime, _ in report: + b64str = base64.b64encode(tstr.encode("utf-8")).decode("utf-8") + save_string = f"{ttime} {b64str}" + save_list.append(save_string) + # month dance necessary to trigger Data.__setitem__ + month = self._data[self._date.strftime("%Y-%m")] + if month[self._date.strftime("%d")] == save_list: # no changes + return + month[self._date.strftime("%d")] = save_list + self._data[self._date.strftime("%Y-%m")] = month + + def prev_next_avail(self): + prev = (self._date - timedelta(days=1)).strftime("%d") in self._data[self._date.strftime("%Y-%m")] + _next = (self._date + timedelta(days=1)).strftime("%d") in self._data[self._date.strftime("%Y-%m")] + return prev, _next + + def previous(self): + self._date = self._date - timedelta(days=1) + + def next(self): + self._date = self._date + timedelta(days=1) diff --git a/main.py b/main.py index ecd721b..96900a9 100644 --- a/main.py +++ b/main.py @@ -34,12 +34,18 @@ class App: self.taskEdit.accepted.connect(self.tasks_edited) self.reportDialog = Report(None) + self.taskEdit.accepted.connect(self.tasks_edited) @QtCore.Slot() def tasks_edited(self): self.tasks.tasks = self.taskEdit.tasks self.update_tray_menu() + @QtCore.Slot() + def report_done(self): + self.active_task = self.log.last_log() or "Nothing" + self.update_tray_menu() + def change_task(self, task): self.active_task = task self.log.log(task) diff --git a/report.py b/report.py index 05f89af..15dca02 100644 --- a/report.py +++ b/report.py @@ -4,6 +4,9 @@ from PySide2 import QtCore, QtGui, QtWidgets class Report(QtWidgets.QDialog): def __init__(self, parent, *args, **kwargs): super().__init__(parent, *args, **kwargs) + self._report = None + self._report_data = None + self.setWindowTitle("Report") self.tableWidget = QtWidgets.QTableWidget() @@ -13,23 +16,29 @@ class Report(QtWidgets.QDialog): self.header = QtWidgets.QHeaderView(QtCore.Qt.Orientation.Horizontal) self.tableWidget.setHorizontalHeader(self.header) - new_button = QtWidgets.QPushButton() - new_button.setText("New item") - new_button.setIcon(QtGui.QIcon.fromTheme("list-add")) - new_button.pressed.connect(self.new_task) + self.previous_button = QtWidgets.QPushButton() + self.previous_button.setText("Previous") + self.previous_button.setIcon(QtGui.QIcon.fromTheme("arrow-left")) + self.previous_button.pressed.connect(self.previous) + + self.next_button = QtWidgets.QPushButton() + self.next_button.setText("Next") + self.next_button.setIcon(QtGui.QIcon.fromTheme("arrow-right")) + self.next_button.pressed.connect(self.next) del_button = QtWidgets.QPushButton() del_button.setText("Delete item") del_button.setIcon(QtGui.QIcon.fromTheme("list-remove")) - del_button.pressed.connect(self.del_task) + del_button.pressed.connect(self.del_log) ok_button = QtWidgets.QPushButton() ok_button.setText("OK") ok_button.setIcon(QtGui.QIcon.fromTheme("dialog-ok-apply")) - ok_button.pressed.connect(self.accept) + ok_button.pressed.connect(self._accept) blayout = QtWidgets.QHBoxLayout() - blayout.addWidget(new_button) + blayout.addWidget(self.previous_button) + blayout.addWidget(self.next_button) blayout.addWidget(del_button) blayout.addWidget(ok_button) @@ -39,12 +48,25 @@ class Report(QtWidgets.QDialog): self.setLayout(layout) def set_data(self, data): - self.tableWidget.setRowCount(len(data)) + self._report = data + self._report_data = self._report.report() + self.refresh_table() + self.update_prev_next() - for row, _ in enumerate(data): - self.tableWidget.setItem(row, 0, QtWidgets.QTableWidgetItem(data[row][0])) - self.tableWidget.setItem(row, 1, QtWidgets.QTableWidgetItem(data[row][1])) - self.tableWidget.setItem(row, 2, QtWidgets.QTableWidgetItem(data[row][2])) + def refresh_table(self): + self.tableWidget.setRowCount(len(self._report_data)) + + for row, _ in enumerate(self._report_data): + item0 = QtWidgets.QTableWidgetItem(self._report_data[row][0]) + self.tableWidget.setItem(row, 0, item0) + item1 = QtWidgets.QTableWidgetItem(self._report_data[row][1]) + self.tableWidget.setItem(row, 1, item1) + item2 = QtWidgets.QTableWidgetItem(self._report_data[row][2]) + self.tableWidget.setItem(row, 2, item2) + item0.setFlags(item0.flags() & QtCore.Qt.ItemIsEnabled) + item2.setFlags(item2.flags() & QtCore.Qt.ItemIsEnabled) + if row > len(self._report_data) - 3: + item1.setFlags(item1.flags() & QtCore.Qt.ItemIsEnabled) self.tableWidget.resizeColumnsToContents() @@ -57,26 +79,34 @@ class Report(QtWidgets.QDialog): self.tableWidget.setMinimumHeight(min((self.tableWidget.rowCount() + 2) * self.tableWidget.rowHeight(0), self.tableWidget.screen().size().height() * 0.8)) - @QtCore.Slot() - def new_task(self): - l = self.list.stringList() - l.append("") - self.list.setStringList(l) - i = self.list.index(len(l) - 1) - self.tableView.setCurrentIndex(i) - self.tableView.edit(i) + def update_prev_next(self): + prev, _next = self._report.prev_next_avail() + self.previous_button.setEnabled(prev) + self.next_button.setEnabled(_next) @QtCore.Slot() - def del_task(self): - l = self.list.stringList() - del l[self.tableView.currentIndex().row()] - self.list.setStringList(l) + def del_log(self): + row = self.tableWidget.currentRow() + if row > len(self._report_data) - 3: + return + del self._report_data[row] + self.refresh_table() - @property - def tasks(self): - ret = self.list.stringList() - return list(filter(None, ret)) # filter empty strings + @QtCore.Slot() + def _accept(self): + self._report.save(self._report_data) + self.accept() - @tasks.setter - def tasks(self, tasks): - self.list.setStringList(tasks) + @QtCore.Slot() + def previous(self): + self._report.save(self._report_data) + self._report.previous() + self.refresh_table() + self.update_prev_next() + + @QtCore.Slot() + def next(self): + self._report.save(self._report_data) + self._report.next() + self.refresh_table() + self.update_prev_next()