diff --git a/README.md b/README.md index 92e60d0..0c9fd7c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # fime -Simple time tracking app written with Python and Qt5 +Simple time tracking app written with Python and Qt Some Jira integration is built in. diff --git a/setup.cfg b/setup.cfg index f97f464..f1bbe1d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,7 +2,7 @@ name = fime author = Faerbit author_email = faerbit@posteo.net -description = Simple time tracking app written with Python and Qt5 +description = Simple time tracking app written with Python and Qt long_description = file: README.md long_description_content_type = text/markdown license = MIT License diff --git a/src/fime/data.py b/src/fime/data.py index dff5bec..ab9dbc2 100644 --- a/src/fime/data.py +++ b/src/fime/data.py @@ -54,6 +54,8 @@ class Tasks: return self._jira_tasks def add_jira_task(self, task_name): + if task_name in self._jira_tasks_usage: + self._jira_tasks.remove(task_name) # move to end, to make visible again self._jira_tasks.append(task_name) self._jira_tasks_usage[task_name] = datetime.now() if len(self._jira_tasks_usage) > max_jira_tasks: diff --git a/src/fime/report.py b/src/fime/report.py index 1364c10..b50304a 100644 --- a/src/fime/report.py +++ b/src/fime/report.py @@ -6,18 +6,19 @@ except ImportError: from datetime import datetime from fime.data import Tasks -from fime.util import get_screen_height, get_icon +from fime.util import get_screen_height, get_icon, EditStartedDetector class Report(QtWidgets.QDialog): - class TaskItemCompleter(QtWidgets.QStyledItemDelegate): + class TaskItemCompleter(EditStartedDetector): def __init__(self, tasks: Tasks, parent=None): super().__init__(parent) self._tasks = tasks - def createEditor(self, parent, *_): - editor = QtWidgets.QLineEdit(parent) + def createEditor(self, parent, option, index): + editor = super().createEditor(parent, option, index) completer = QtWidgets.QCompleter(self._tasks.all_tasks, parent) + completer.setFilterMode(QtCore.Qt.MatchFlag.MatchContains) completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) editor.setCompleter(completer) return editor @@ -39,7 +40,14 @@ class Report(QtWidgets.QDialog): self.tableWidget.setColumnCount(3) self.tableWidget.setHorizontalHeaderLabels(["Task", "Start time", "Duration"]) self.tableWidget.cellChanged.connect(self.cell_changed) - self.tableWidget.setItemDelegateForColumn(0, Report.TaskItemCompleter(self._tasks, self)) + taskItemCompleter = Report.TaskItemCompleter(self._tasks, self) + taskItemCompleter.editStarted.connect(self.disable_buttons) + taskItemCompleter.editFinished.connect(self.enable_buttons) + self.tableWidget.setItemDelegateForColumn(0, taskItemCompleter) + editStartedDetector = EditStartedDetector(self) + editStartedDetector.editStarted.connect(self.disable_buttons) + editStartedDetector.editFinished.connect(self.enable_buttons) + self.tableWidget.setItemDelegateForColumn(1, editStartedDetector) self.header = QtWidgets.QHeaderView(QtCore.Qt.Orientation.Horizontal) self.header.setMinimumSectionSize(1) self.header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) @@ -58,30 +66,30 @@ class Report(QtWidgets.QDialog): self.next_button.pressed.connect(self.next) self.next_button.setAutoDefault(False) - new_button = QtWidgets.QPushButton() - new_button.setText("New item") - new_button.setIcon(get_icon("list-add")) - new_button.pressed.connect(self.new_log) - new_button.setAutoDefault(False) + self.new_button = QtWidgets.QPushButton() + self.new_button.setText("New item") + self.new_button.setIcon(get_icon("list-add")) + self.new_button.pressed.connect(self.new_log) + self.new_button.setAutoDefault(False) - del_button = QtWidgets.QPushButton() - del_button.setText("Delete item") - del_button.setIcon(get_icon("list-remove")) - del_button.pressed.connect(self.del_log) - del_button.setAutoDefault(False) + self.del_button = QtWidgets.QPushButton() + self.del_button.setText("Delete item") + self.del_button.setIcon(get_icon("list-remove")) + self.del_button.pressed.connect(self.del_log) + self.del_button.setAutoDefault(False) - ok_button = QtWidgets.QPushButton() - ok_button.setText("OK") - ok_button.setIcon(get_icon("dialog-ok")) - ok_button.pressed.connect(self._accept) - ok_button.setAutoDefault(True) + self.ok_button = QtWidgets.QPushButton() + self.ok_button.setText("OK") + self.ok_button.setIcon(get_icon("dialog-ok")) + self.ok_button.pressed.connect(self._accept) + self.ok_button.setAutoDefault(True) blayout = QtWidgets.QHBoxLayout() blayout.addWidget(self.previous_button) blayout.addWidget(self.next_button) - blayout.addWidget(new_button) - blayout.addWidget(del_button) - blayout.addWidget(ok_button) + blayout.addWidget(self.new_button) + blayout.addWidget(self.del_button) + blayout.addWidget(self.ok_button) layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.tableWidget) @@ -151,6 +159,21 @@ class Report(QtWidgets.QDialog): self._changing_items = False self.tableWidget.editItem(item) + @QtCore.Slot() + def disable_buttons(self): + self.previous_button.setEnabled(False) + self.next_button.setEnabled(False) + self.del_button.setEnabled(False) + self.new_button.setEnabled(False) + self.ok_button.setEnabled(False) + + @QtCore.Slot() + def enable_buttons(self): + self.del_button.setEnabled(True) + self.new_button.setEnabled(True) + self.ok_button.setEnabled(True) + self.update_prev_next() + @QtCore.Slot() def _accept(self): self.save() diff --git a/src/fime/task_edit.py b/src/fime/task_edit.py index 447b65d..9473a92 100644 --- a/src/fime/task_edit.py +++ b/src/fime/task_edit.py @@ -3,7 +3,7 @@ try: except ImportError: from PySide2 import QtCore, QtGui, QtWidgets -from fime.util import get_icon +from fime.util import get_icon, EditStartedDetector class TaskEdit(QtWidgets.QDialog): @@ -17,35 +17,51 @@ class TaskEdit(QtWidgets.QDialog): self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.horizontalHeader().hide() self.tableView.verticalHeader().hide() + editStartedDetector = EditStartedDetector(self) + editStartedDetector.editStarted.connect(self.disable_buttons) + editStartedDetector.editFinished.connect(self.enable_buttons) + self.tableView.setItemDelegate(editStartedDetector) - new_button = QtWidgets.QPushButton() - new_button.setText("New item") - new_button.setIcon(get_icon("list-add")) - new_button.pressed.connect(self.new_task) - new_button.setAutoDefault(False) + self.new_button = QtWidgets.QPushButton() + self.new_button.setText("New item") + self.new_button.setIcon(get_icon("list-add")) + self.new_button.pressed.connect(self.new_task) + self.new_button.setAutoDefault(False) - del_button = QtWidgets.QPushButton() - del_button.setText("Delete item") - del_button.setIcon(get_icon("list-remove")) - del_button.pressed.connect(self.del_task) - del_button.setAutoDefault(False) + self.del_button = QtWidgets.QPushButton() + self.del_button.setText("Delete item") + self.del_button.setIcon(get_icon("list-remove")) + self.del_button.pressed.connect(self.del_task) + self.del_button.setAutoDefault(False) - ok_button = QtWidgets.QPushButton() - ok_button.setText("OK") - ok_button.setIcon(get_icon("dialog-ok")) - ok_button.pressed.connect(self.accept) - ok_button.setAutoDefault(True) + self.ok_button = QtWidgets.QPushButton() + self.ok_button.setText("OK") + self.ok_button.setIcon(get_icon("dialog-ok")) + self.ok_button.pressed.connect(self.accept) + self.ok_button.setAutoDefault(True) blayout = QtWidgets.QHBoxLayout() - blayout.addWidget(new_button) - blayout.addWidget(del_button) - blayout.addWidget(ok_button) + blayout.addWidget(self.new_button) + blayout.addWidget(self.del_button) + blayout.addWidget(self.ok_button) layout = QtWidgets.QVBoxLayout() layout.addWidget(self.tableView) layout.addLayout(blayout) self.setLayout(layout) + @QtCore.Slot() + def disable_buttons(self): + self.del_button.setEnabled(False) + self.new_button.setEnabled(False) + self.ok_button.setEnabled(False) + + @QtCore.Slot() + def enable_buttons(self): + self.del_button.setEnabled(True) + self.new_button.setEnabled(True) + self.ok_button.setEnabled(True) + @QtCore.Slot() def new_task(self): l = self.list.stringList() diff --git a/src/fime/util.py b/src/fime/util.py index 02bc07d..b3738a0 100644 --- a/src/fime/util.py +++ b/src/fime/util.py @@ -1,7 +1,7 @@ try: - from PySide6 import QtGui + from PySide6 import QtCore, QtGui, QtWidgets except ImportError: - from PySide2 import QtGui + from PySide2 import QtCore, QtGui, QtWidgets def get_screen_height(qobject): @@ -16,3 +16,20 @@ def get_icon(icon_name): theme_name = icon_name.replace("-light", "") # respect system theme fallback = QtGui.QIcon(f":/icons/{icon_name}").pixmap(256, 256) return QtGui.QIcon.fromTheme(theme_name, fallback) + + +class EditStartedDetector(QtWidgets.QStyledItemDelegate): + editStarted = QtCore.Signal() + editFinished = QtCore.Signal() + + def __init__(self, parent=None): + super().__init__(parent) + + def createEditor(self, parent, option, index): + editor = super().createEditor(parent, option, index) + self.editStarted.emit() + return editor + + def setModelData(self, editor, model, index): + super().setModelData(editor, model, index) + self.editFinished.emit()