This commit is contained in:
Fabian 2021-11-28 17:22:39 +01:00
parent e9fb29aa1b
commit 210aaba92b
4 changed files with 215 additions and 80 deletions

View File

@ -2,7 +2,9 @@ import atexit
import base64 import base64
import json import json
import os import os
import time
from collections.abc import MutableMapping from collections.abc import MutableMapping
from copy import deepcopy
from datetime import datetime, date, timedelta from datetime import datetime, date, timedelta
from threading import Thread, Event from threading import Thread, Event
from typing import List, Tuple, Dict from typing import List, Tuple, Dict
@ -193,9 +195,10 @@ class LogCommentsData:
month_str = pdate.strftime("%Y-%m") month_str = pdate.strftime("%Y-%m")
day_str = pdate.strftime("%d") day_str = pdate.strftime("%d")
month = self._data.setdefault(month_str, {}) month = self._data.setdefault(month_str, {})
if month.setdefault(day_str, self._init_day)["log"] == encoded:
return # no changes
month.setdefault(day_str, self._init_day)["log"] = encoded month.setdefault(day_str, self._init_day)["log"] = encoded
# trigger save if necessary # trigger save
if self._data[month_str] != month:
self._data[month_str] = month self._data[month_str] = month
def add_log_entry(self, task: str): def add_log_entry(self, task: str):
@ -241,7 +244,7 @@ class LogCommentsData:
return dict() return dict()
comment_data = self._data[month_str][day_str]["comments"] comment_data = self._data[month_str][day_str]["comments"]
ret = dict() ret = dict()
for k, v in comment_data: for k, v in comment_data.items():
k_dec = base64.b64decode(k.encode("utf-8")).decode("utf-8") k_dec = base64.b64decode(k.encode("utf-8")).decode("utf-8")
v_dec = base64.b64decode(v.encode("utf-8")).decode("utf-8") v_dec = base64.b64decode(v.encode("utf-8")).decode("utf-8")
ret[k_dec] = v_dec ret[k_dec] = v_dec
@ -250,16 +253,17 @@ class LogCommentsData:
def set_comments(self, pdate: date, comments: Dict[str, str]): def set_comments(self, pdate: date, comments: Dict[str, str]):
self._ensure_format(pdate) self._ensure_format(pdate)
encoded = dict() encoded = dict()
for k, v in comments: for k, v in comments.items():
k_enc = base64.b64encode(k.encode("utf-8")).decode("utf-8") k_enc = base64.b64encode(k.encode("utf-8")).decode("utf-8")
v_enc = base64.b64encode(v.encode("utf-8")).decode("utf-8") v_enc = base64.b64encode(v.encode("utf-8")).decode("utf-8")
encoded[k_enc] = v_enc encoded[k_enc] = v_enc
month_str = pdate.strftime("%Y-%m") month_str = pdate.strftime("%Y-%m")
day_str = pdate.strftime("%d") day_str = pdate.strftime("%d")
month = self._data.setdefault(month_str, {}) month = self._data.setdefault(month_str, {})
if month.setdefault(day_str, self._init_day)["comments"] == encoded:
return # no changes
month.setdefault(day_str, self._init_day)["comments"] = encoded month.setdefault(day_str, self._init_day)["comments"] = encoded
# trigger save if necessary # trigger save
if self._data[month_str] != month:
self._data[month_str] = month self._data[month_str] = month
@ -293,8 +297,13 @@ class Log:
return Worklog(self._data) return Worklog(self._data)
# TODO remove
dEV = False
def summary(lcd: LogCommentsData, pdate: date) -> Tuple[Dict[str, timedelta], timedelta]: def summary(lcd: LogCommentsData, pdate: date) -> Tuple[Dict[str, timedelta], timedelta]:
log = lcd.get_log(pdate) log = lcd.get_log(pdate)
if dEV:
if pdate == date.today(): if pdate == date.today():
log.append((datetime.now(), "End")) log.append((datetime.now(), "End"))
tasks_sums = {} tasks_sums = {}
@ -318,15 +327,37 @@ def duration_to_str(duration: timedelta) -> str:
return f"{dhours:02d}:{dmins:02d}" return f"{dhours:02d}:{dmins:02d}"
class Report: class PrevNextable:
def __init__(self, data: LogCommentsData): def __init__(self, data: LogCommentsData):
self._data = data self._data = data
self._date = date.today() self._date = date.today()
self._not_log_len = 0
self._prev = None self._prev = None
self._next = None self._next = None
self._update_prev_next() self._update_prev_next()
def _update_prev_next(self):
self._prev, self._next = self._data.get_prev_next_avail(self._date)
def prev_next_avail(self) -> Tuple[bool, bool]:
return self._prev is not None, self._next is not None
def previous(self):
self._date = self._prev
self._update_prev_next()
def next(self):
self._date = self._next
self._update_prev_next()
def date(self) -> str:
return self._date.strftime("%Y-%m-%d")
class Report(PrevNextable):
def __init__(self, data: LogCommentsData):
super().__init__(data)
self._not_log_len = 0
def report(self) -> Tuple[List[List[str]], int]: def report(self) -> Tuple[List[List[str]], int]:
log = self._data.get_log(self._date) log = self._data.get_log(self._date)
if self._date == date.today(): if self._date == date.today():
@ -365,24 +396,29 @@ class Report:
)) ))
self._data.set_log(self._date, report) self._data.set_log(self._date, report)
def _update_prev_next(self):
self._prev, self._next = self._data.get_prev_next_avail(self._date)
def prev_next_avail(self): class Worklog(PrevNextable):
return self._prev is not None, self._next is not None
def previous(self):
self._date = self._prev
self._update_prev_next()
def next(self):
self._date = self._next
self._update_prev_next()
def date(self):
return self._date.strftime("%Y-%m-%d")
class Worklog:
def __init__(self, data: LogCommentsData): def __init__(self, data: LogCommentsData):
self._data = data super().__init__(data)
self._worklog = []
@property
def worklog(self) -> List[List[str]]:
tasks_summary, total_sum = summary(self._data, self._date)
comments = self._data.get_comments(self._date)
self._worklog = []
for task, duration in tasks_summary.items():
self._worklog.append([task, comments.setdefault(task, ""), duration_to_str(duration)])
self._worklog.append(["Total sum", "", duration_to_str(total_sum)])
return deepcopy(self._worklog)
@worklog.setter
def worklog(self, worklog: List[List[str]]):
log = self._data.get_log(self._date)
set_comments = dict()
for i, (task, comment, duration) in enumerate(worklog[:-1]):
set_comments[task] = comment
if self._worklog[i][0] != task:
log = list(map(lambda x: (x[0], x[1].replace(self._worklog[i][0], task)), log))
self._data.set_comments(self._date, set_comments)
self._data.set_log(self._date, log)

View File

@ -1,3 +1,5 @@
from typing import List, Optional
try: try:
from PySide6 import QtCore, QtGui, QtWidgets from PySide6 import QtCore, QtGui, QtWidgets
except ImportError: except ImportError:
@ -5,7 +7,7 @@ except ImportError:
from datetime import datetime from datetime import datetime
from fime.data import Tasks from fime.data import Tasks, Report
from fime.util import get_screen_height, get_icon, EditStartedDetector from fime.util import get_screen_height, get_icon, EditStartedDetector
@ -25,8 +27,8 @@ class Report(QtWidgets.QDialog):
def __init__(self, tasks: Tasks, parent, *args, **kwargs): def __init__(self, tasks: Tasks, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs) super().__init__(parent, *args, **kwargs)
self._report = None self._report: Optional[Report] = None
self._report_data = None self._report_data: Optional[List[List[str]]] = None
self._changing_items = False self._changing_items = False
self._new_log_task = "" self._new_log_task = ""
self._new_log_pos = -1 self._new_log_pos = -1
@ -81,7 +83,7 @@ class Report(QtWidgets.QDialog):
self.ok_button.setText("OK") self.ok_button.setText("OK")
self.ok_button.setIcon(get_icon("dialog-ok")) self.ok_button.setIcon(get_icon("dialog-ok"))
self.ok_button.pressed.connect(self._accept) self.ok_button.pressed.connect(self._accept)
self.ok_button.setAutoDefault(True) self.ok_button.setAutoDefault(False)
blayout = QtWidgets.QHBoxLayout() blayout = QtWidgets.QHBoxLayout()
blayout.addWidget(self.previous_button) blayout.addWidget(self.previous_button)
@ -95,7 +97,7 @@ class Report(QtWidgets.QDialog):
layout.addLayout(blayout) layout.addLayout(blayout)
self.setLayout(layout) self.setLayout(layout)
def set_data(self, data): def set_data(self, data: Report):
self._report = data self._report = data
self.update_title() self.update_title()
self.refresh_table() self.refresh_table()
@ -137,9 +139,9 @@ class Report(QtWidgets.QDialog):
) )
def update_prev_next(self): def update_prev_next(self):
prev, _next = self._report.prev_next_avail() prev, next_ = self._report.prev_next_avail()
self.previous_button.setEnabled(prev) self.previous_button.setEnabled(prev)
self.next_button.setEnabled(_next) self.next_button.setEnabled(next_)
@QtCore.Slot() @QtCore.Slot()
def del_log(self): def del_log(self):

View File

@ -35,6 +35,5 @@ class EditStartedDetector(QtWidgets.QStyledItemDelegate):
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
editor = super().createEditor(parent, option, index) editor = super().createEditor(parent, option, index)
editor.editingFinished.connect(self.editFinished) editor.editingFinished.connect(self.editFinished)
editor.selectionChanged.connect(self.editFinished)
self.editStarted.emit() self.editStarted.emit()
return editor return editor

View File

@ -1,6 +1,9 @@
import enum import enum
from functools import reduce from datetime import datetime
from functools import reduce, partial
from typing import Optional, List, Tuple
from fime.data import Worklog
from fime.progressindicator import ProgressIndicator from fime.progressindicator import ProgressIndicator
from fime.task_completer import TaskCompleter from fime.task_completer import TaskCompleter
from fime.util import get_icon, get_screen_height, EditStartedDetector from fime.util import get_icon, get_screen_height, EditStartedDetector
@ -15,20 +18,20 @@ from fime.util import get_screen_width
import fime.icons import fime.icons
class Worklog(QtWidgets.QDialog): class WorklogDialog(QtWidgets.QDialog):
class TabTable(QtWidgets.QTableWidget): class TabTable(QtWidgets.QTableWidget):
def __init__(self, parent, *args, **kwargs): def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs) super().__init__(parent, *args, **kwargs)
def focusNextPrevChild(self, next): def focusNextPrevChild(self, next_):
if self.currentColumn() == 1: if self.currentColumn() == 1:
event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
QtCore.Qt.Key_Down if next else QtCore.Qt.Key_Up, QtCore.Qt.Key_Down if next_ else QtCore.Qt.Key_Up,
QtCore.Qt.NoModifier) QtCore.Qt.NoModifier)
self.keyPressEvent(event) self.keyPressEvent(event)
if event.isAccepted(): if event.isAccepted():
return True return True
return super().focusNextPrevChild(next) return super().focusNextPrevChild(next_)
class ClickWidget(QtWidgets.QWidget): class ClickWidget(QtWidgets.QWidget):
def __init__(self, item, table, parent, *args, **kwargs): def __init__(self, item, table, parent, *args, **kwargs):
@ -64,18 +67,32 @@ class Worklog(QtWidgets.QDialog):
self.text_changed.emit(self.document().toPlainText(), self.row) self.text_changed.emit(self.document().toPlainText(), self.row)
class TaskItemCompleter(EditStartedDetector): class TaskItemCompleter(EditStartedDetector):
edit_finished_row = QtCore.Signal(int)
def __init__(self, config, parent=None): def __init__(self, config, parent=None):
super().__init__(parent) super().__init__(parent)
self.config = config self.config = config
#self.row = -1
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
editor = super().createEditor(parent, option, index) editor = super().createEditor(parent, option, index)
#self.row = index.row()
#editor.editingFinished.connect(partial(self.edit_finished_row_target, index.row()))
#editor.editingFinished.connect(self.edit_finished_row_target)
#self.editFinished.connect(self.edit_finished_row_target)
#self.editFinished.connect(partial(self.edit_finished_row_target, index.row()))
completer = TaskCompleter(self.config) completer = TaskCompleter(self.config)
completer.setFilterMode(QtCore.Qt.MatchFlag.MatchContains) completer.setFilterMode(QtCore.Qt.MatchFlag.MatchContains)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
editor.setCompleter(completer) editor.setCompleter(completer)
return editor return editor
@QtCore.Slot()
def edit_finished_row_target(self, row):
#def edit_finished_row_target(self):
self.edit_finished_row.emit(row)
#self.edit_finished_row.emit(self.row)
class Status(enum.Enum): class Status(enum.Enum):
PROGRESS = enum.auto() PROGRESS = enum.auto()
OK = enum.auto() OK = enum.auto()
@ -87,23 +104,27 @@ class Worklog(QtWidgets.QDialog):
self.setWindowTitle("Worklog") self.setWindowTitle("Worklog")
self._changing_items = False self._changing_items = False
self._report_data = [] self._worklog: Optional[Worklog] = None
self._status = [] self._worklog_data: List[List[str]] = []
self._status: List[Tuple[WorklogDialog.Status, str]] = []
self.row_height = None self.row_height = None
self.focussed = False self._focussed = False
self.tableWidget = Worklog.TabTable(self) #self.tableWidget = WorklogDialog.TabTable(self)
self.tableWidget = QtWidgets.QTableWidget(self)
self.tableWidget.setColumnCount(3) self.tableWidget.setColumnCount(3)
self.tableWidget.setHorizontalHeaderLabels(["Task", "Comment", "Duration"]) self.tableWidget.setHorizontalHeaderLabels(["Task", "Comment", "Duration"])
self.tableWidget.cellChanged.connect(self.cell_changed) self.tableWidget.cellChanged.connect(self.cell_changed)
taskItemCompleter = Worklog.TaskItemCompleter(config, self) taskItemCompleter = WorklogDialog.TaskItemCompleter(config, self)
taskItemCompleter.editStarted.connect(self.disable_buttons) taskItemCompleter.editStarted.connect(self.disable_buttons)
taskItemCompleter.editFinished.connect(self.enable_ok) taskItemCompleter.editFinished.connect(self.enable_buttons)
#taskItemCompleter.editFinished.connect(self.ensure_stati)
#taskItemCompleter.edit_finished_row.connect(self.update_status_view)
self.tableWidget.setItemDelegateForColumn(0, taskItemCompleter) self.tableWidget.setItemDelegateForColumn(0, taskItemCompleter)
self.hheader = QtWidgets.QHeaderView(QtCore.Qt.Orientation.Horizontal) self.hheader = QtWidgets.QHeaderView(QtCore.Qt.Orientation.Horizontal)
self.hheader.setMinimumSectionSize(10) self.hheader.setMinimumSectionSize(10)
self.tableWidget.setHorizontalHeader(self.hheader) self.tableWidget.setHorizontalHeader(self.hheader)
self.hheader.setSectionResizeMode(self.hheader.logicalIndex(0), QtWidgets.QHeaderView.Stretch) self.hheader.setSectionResizeMode(self.hheader.logicalIndex(0), QtWidgets.QHeaderView.Fixed)
self.hheader.setSectionResizeMode(self.hheader.logicalIndex(1), QtWidgets.QHeaderView.Fixed) self.hheader.setSectionResizeMode(self.hheader.logicalIndex(1), QtWidgets.QHeaderView.Fixed)
self.hheader.resizeSection(self.hheader.logicalIndex(1), get_screen_width(self) * 0.2) self.hheader.resizeSection(self.hheader.logicalIndex(1), get_screen_width(self) * 0.2)
self.hheader.setSectionResizeMode(self.hheader.logicalIndex(2), QtWidgets.QHeaderView.ResizeToContents) self.hheader.setSectionResizeMode(self.hheader.logicalIndex(2), QtWidgets.QHeaderView.ResizeToContents)
@ -113,6 +134,18 @@ class Worklog(QtWidgets.QDialog):
self.tableWidget.setVerticalHeader(self.vheader) self.tableWidget.setVerticalHeader(self.vheader)
self.tableWidget.setMaximumWidth(get_screen_width(self) * 0.8) self.tableWidget.setMaximumWidth(get_screen_width(self) * 0.8)
self.previous_button = QtWidgets.QPushButton()
self.previous_button.setText("Previous")
self.previous_button.setIcon(get_icon("arrow-left"))
self.previous_button.pressed.connect(self.previous)
self.previous_button.setAutoDefault(False)
self.next_button = QtWidgets.QPushButton()
self.next_button.setText("Next")
self.next_button.setIcon(get_icon("arrow-right"))
self.next_button.pressed.connect(self.next)
self.next_button.setAutoDefault(False)
self.upload_button = QtWidgets.QPushButton() self.upload_button = QtWidgets.QPushButton()
self.upload_button.setText("Upload") self.upload_button.setText("Upload")
self.upload_button.setIcon(get_icon("cloud-upload")) self.upload_button.setIcon(get_icon("cloud-upload"))
@ -124,10 +157,12 @@ class Worklog(QtWidgets.QDialog):
self.ok_button = QtWidgets.QPushButton() self.ok_button = QtWidgets.QPushButton()
self.ok_button.setText("OK") self.ok_button.setText("OK")
self.ok_button.setIcon(get_icon("dialog-ok")) self.ok_button.setIcon(get_icon("dialog-ok"))
#self.ok_button.pressed.connect(self._accept) self.ok_button.pressed.connect(self._accept)
self.ok_button.setAutoDefault(True) self.ok_button.setAutoDefault(False)
alayout = QtWidgets.QHBoxLayout() alayout = QtWidgets.QHBoxLayout()
alayout.addWidget(self.previous_button)
alayout.addWidget(self.next_button)
alayout.addSpacerItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Expanding)) alayout.addSpacerItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Expanding))
alayout.addWidget(self.upload_button) alayout.addWidget(self.upload_button)
alayout.addWidget(self.ok_button) alayout.addWidget(self.ok_button)
@ -137,64 +172,93 @@ class Worklog(QtWidgets.QDialog):
layout.addLayout(alayout) layout.addLayout(alayout)
self.setLayout(layout) self.setLayout(layout)
def set_data(self, data): def set_data(self, worklog: Worklog):
self._report_data = data self._worklog = worklog
for i, _ in enumerate(self._report_data):
self._status.append((Worklog.Status.PROGRESS, "Fetching"))
self.refresh_table() self.refresh_table()
self.update_title()
self.update_prev_next()
def update_status(self, row, new_status, status_text="Could not find specified issue"): def update_status(self, row, new_status, status_text="Could not find specified issue"):
self._status[row] = (new_status, status_text) self._status[row] = (new_status, status_text)
self.update_status_view(row) self.update_status_view(row)
all_ok = reduce(lambda acc, it: acc and it[0] is Worklog.Status.OK, self._status, True) all_ok = reduce(lambda acc, it: acc and it[0] is WorklogDialog.Status.OK, self._status, True)
if all_ok: if all_ok:
self.upload_button.setEnabled(True) self.upload_button.setEnabled(True)
def save(self):
self._worklog.worklog = self._worklog_data
def update_title(self):
self.setWindowTitle(f"Worklog {self._worklog.date()}")
def refresh_table(self): def refresh_table(self):
self._worklog_data = self._worklog.worklog
for i, _ in enumerate(self._worklog_data[:-1]):
self._status.append((WorklogDialog.Status.PROGRESS, "Fetching"))
self._changing_items = True self._changing_items = True
if not self.row_height: if not self.row_height:
self.tableWidget.setRowCount(1) self.tableWidget.setRowCount(1)
item = QtWidgets.QTableWidgetItem("test") item = QtWidgets.QTableWidgetItem("test")
self.tableWidget.setItem(0, 0, item) self.tableWidget.setItem(0, 0, item)
self.row_height = self.tableWidget.rowHeight(0) self.row_height = self.tableWidget.rowHeight(0)
self.tableWidget.setRowCount(len(self._report_data)) self.tableWidget.setRowCount(len(self._worklog_data))
for row, _ in enumerate(self._report_data): for row, _ in enumerate(self._worklog_data):
item0 = QtWidgets.QTableWidgetItem(self._report_data[row][0]) item0 = QtWidgets.QTableWidgetItem(self._worklog_data[row][0])
self.tableWidget.setItem(row, 0, item0) self.tableWidget.setItem(row, 0, item0)
if row == len(self._worklog_data) - 1:
self.tableWidget.removeCellWidget(row, 0)
item0.setFlags(item0.flags() & QtCore.Qt.ItemIsEnabled)
item1 = QtWidgets.QTableWidgetItem("")
self.tableWidget.setItem(row, 1, item1)
item1.setFlags(item1.flags() & QtCore.Qt.ItemIsEnabled)
else:
self.update_status_view(row) self.update_status_view(row)
text_edit = Worklog.TableTextEdit(self._report_data[row][1], row, self) text_edit = WorklogDialog.TableTextEdit(self._worklog_data[row][1], row, self)
text_edit.textChanged.connect(self.on_resize) text_edit.textChanged.connect(self.on_resize)
text_edit.setFrameStyle(QtWidgets.QFrame.NoFrame) text_edit.setFrameStyle(QtWidgets.QFrame.NoFrame)
text_edit.text_changed.connect(self.text_edit_changed) text_edit.text_changed.connect(self.text_edit_changed)
self.tableWidget.setCellWidget(row, 1, text_edit) self.tableWidget.setCellWidget(row, 1, text_edit)
if row == 0 and not self.focussed: if row == 0 and not self._focussed:
text_edit.setFocus() text_edit.setFocus()
self.focussed = True self._focussed = True
item2 = QtWidgets.QTableWidgetItem(self._report_data[row][2]) item2 = QtWidgets.QTableWidgetItem(self._worklog_data[row][2])
self.tableWidget.setItem(row, 2, item2) self.tableWidget.setItem(row, 2, item2)
item2.setFlags(item2.flags() & QtCore.Qt.ItemIsEnabled) item2.setFlags(item2.flags() & QtCore.Qt.ItemIsEnabled)
self._changing_items = False self._changing_items = False
self.tableWidget.resizeColumnToContents(0) self.tableWidget.resizeColumnToContents(0)
desired_width = self.tableWidget.columnWidth(0) + self.tableWidget.columnWidth(1) + self.tableWidget.columnWidth(2) self.tableWidget.setColumnWidth(0, self.tableWidget.columnWidth(0) + self.row_height)
desired_width = self.tableWidget.columnWidth(0) + self.tableWidget.columnWidth(1) + self.tableWidget.columnWidth(2) + 4
self.tableWidget.setMinimumWidth(min(desired_width, self.tableWidget.maximumWidth())) self.tableWidget.setMinimumWidth(min(desired_width, self.tableWidget.maximumWidth()))
self.adjustSize()
screen = QtGui.QGuiApplication.screenAt(self.pos()) screen = QtGui.QGuiApplication.screenAt(self.pos())
x = ((screen.size().width() - self.tableWidget.width()) // 2) + screen.geometry().left() x = ((screen.size().width() - self.tableWidget.width()) // 2) + screen.geometry().left()
y = ((screen.size().height() - self.height()) // 2) + screen.geometry().top() y = ((screen.size().height() - self.height()) // 2) + screen.geometry().top()
self.move(x, y) self.move(x, y)
@QtCore.Slot()
def ensure_stati(self):
print("ensure_stati")
for i in range(len(self._worklog_data)-1):
cw = self.tableWidget.cellWidget(i, 0)
if type(cw) is not WorklogDialog.ClickWidget:
print(f"ensure_stati: {self.tableWidget.item(i, 0).text()}")
self.update_status_view(i)
#print(cw)
def update_status_view(self, row): def update_status_view(self, row):
if self._status[row][0] is Worklog.Status.PROGRESS: print(self.tableWidget.item(row, 0).text())
if self._status[row][0] is WorklogDialog.Status.PROGRESS:
icon = ProgressIndicator(self) icon = ProgressIndicator(self)
icon.setMaximumSize(QtCore.QSize(self.row_height * 0.75, self.row_height * 0.75)) icon.setMaximumSize(QtCore.QSize(self.row_height * 0.75, self.row_height * 0.75))
icon.setAnimationDelay(70) icon.setAnimationDelay(70)
icon.startAnimation() icon.startAnimation()
else: else:
if self._status[row][0] is Worklog.Status.OK: if self._status[row][0] is WorklogDialog.Status.OK:
item_name = "dialog-ok" item_name = "dialog-ok"
elif self._status[row][0] is Worklog.Status.ERROR: elif self._status[row][0] is WorklogDialog.Status.ERROR:
item_name = "edit-delete-remove" item_name = "edit-delete-remove"
icon = QtWidgets.QLabel() icon = QtWidgets.QLabel()
icon.setPixmap(get_icon(item_name).pixmap(self.row_height * 0.75, self.row_height * 0.75)) icon.setPixmap(get_icon(item_name).pixmap(self.row_height * 0.75, self.row_height * 0.75))
@ -204,7 +268,7 @@ class Worklog(QtWidgets.QDialog):
layout.setContentsMargins(self.row_height * 0.1, self.row_height * 0.1, layout.setContentsMargins(self.row_height * 0.1, self.row_height * 0.1,
self.row_height * 0.1, self.row_height * 0.1) self.row_height * 0.1, self.row_height * 0.1)
wdgt = Worklog.ClickWidget(self.tableWidget.item(row, 0), self.tableWidget, self) wdgt = WorklogDialog.ClickWidget(self.tableWidget.item(row, 0), self.tableWidget, self)
wdgt.setLayout(layout) wdgt.setLayout(layout)
self.tableWidget.setCellWidget(row, 0, wdgt) self.tableWidget.setCellWidget(row, 0, wdgt)
@ -214,21 +278,55 @@ class Worklog(QtWidgets.QDialog):
@QtCore.Slot() @QtCore.Slot()
def disable_buttons(self): def disable_buttons(self):
self.previous_button.setEnabled(False)
self.next_button.setEnabled(False)
self.upload_button.setEnabled(False) self.upload_button.setEnabled(False)
self.ok_button.setEnabled(False) self.ok_button.setEnabled(False)
@QtCore.Slot() @QtCore.Slot()
def enable_ok(self): def enable_buttons(self):
self.ok_button.setEnabled(True) self.ok_button.setEnabled(True)
self.update_prev_next()
def update_prev_next(self):
prev, next_ = self._worklog.prev_next_avail()
self.previous_button.setEnabled(prev)
self.next_button.setEnabled(next_)
@QtCore.Slot()
def previous(self):
self.save()
self._worklog.previous()
self.update_title()
self._focussed = False
self.refresh_table()
self.update_prev_next()
@QtCore.Slot()
def next(self):
self.save()
self._worklog.next()
self.update_title()
self._focussed = False
self.refresh_table()
self.update_prev_next()
@QtCore.Slot() @QtCore.Slot()
def cell_changed(self, row, _): def cell_changed(self, row, _):
#print(f"{datetime.now()} cell_changed: {self._changing_items}")
if self._changing_items: if self._changing_items:
return return
self._report_data[row][0] = self.tableWidget.item(row, 0).text() print(f"{datetime.now()} cell_changed")
self.update_status(row, Worklog.Status.PROGRESS, "Fetching") self._worklog_data[row][0] = self.tableWidget.item(row, 0).text()
self.save()
self.update_status(row, WorklogDialog.Status.PROGRESS, "Fetching")
self.refresh_table() self.refresh_table()
@QtCore.Slot() @QtCore.Slot()
def text_edit_changed(self, text, row): def text_edit_changed(self, text, row):
self._report_data[row][1] = text self._worklog_data[row][1] = text
@QtCore.Slot()
def _accept(self):
self.save()
self.accept()