Various improvements

This commit is contained in:
Fabian 2021-11-18 20:11:23 +01:00
parent 922cd87fe0
commit 5753624065
6 changed files with 104 additions and 46 deletions

View File

@ -1,6 +1,6 @@
# fime # 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. Some Jira integration is built in.

View File

@ -2,7 +2,7 @@
name = fime name = fime
author = Faerbit author = Faerbit
author_email = faerbit@posteo.net 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 = file: README.md
long_description_content_type = text/markdown long_description_content_type = text/markdown
license = MIT License license = MIT License

View File

@ -54,6 +54,8 @@ class Tasks:
return self._jira_tasks return self._jira_tasks
def add_jira_task(self, task_name): 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.append(task_name)
self._jira_tasks_usage[task_name] = datetime.now() self._jira_tasks_usage[task_name] = datetime.now()
if len(self._jira_tasks_usage) > max_jira_tasks: if len(self._jira_tasks_usage) > max_jira_tasks:

View File

@ -6,18 +6,19 @@ except ImportError:
from datetime import datetime from datetime import datetime
from fime.data import Tasks 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 Report(QtWidgets.QDialog):
class TaskItemCompleter(QtWidgets.QStyledItemDelegate): class TaskItemCompleter(EditStartedDetector):
def __init__(self, tasks: Tasks, parent=None): def __init__(self, tasks: Tasks, parent=None):
super().__init__(parent) super().__init__(parent)
self._tasks = tasks self._tasks = tasks
def createEditor(self, parent, *_): def createEditor(self, parent, option, index):
editor = QtWidgets.QLineEdit(parent) editor = super().createEditor(parent, option, index)
completer = QtWidgets.QCompleter(self._tasks.all_tasks, parent) completer = QtWidgets.QCompleter(self._tasks.all_tasks, parent)
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
@ -39,7 +40,14 @@ class Report(QtWidgets.QDialog):
self.tableWidget.setColumnCount(3) self.tableWidget.setColumnCount(3)
self.tableWidget.setHorizontalHeaderLabels(["Task", "Start time", "Duration"]) self.tableWidget.setHorizontalHeaderLabels(["Task", "Start time", "Duration"])
self.tableWidget.cellChanged.connect(self.cell_changed) 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 = QtWidgets.QHeaderView(QtCore.Qt.Orientation.Horizontal)
self.header.setMinimumSectionSize(1) self.header.setMinimumSectionSize(1)
self.header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) self.header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
@ -58,30 +66,30 @@ class Report(QtWidgets.QDialog):
self.next_button.pressed.connect(self.next) self.next_button.pressed.connect(self.next)
self.next_button.setAutoDefault(False) self.next_button.setAutoDefault(False)
new_button = QtWidgets.QPushButton() self.new_button = QtWidgets.QPushButton()
new_button.setText("New item") self.new_button.setText("New item")
new_button.setIcon(get_icon("list-add")) self.new_button.setIcon(get_icon("list-add"))
new_button.pressed.connect(self.new_log) self.new_button.pressed.connect(self.new_log)
new_button.setAutoDefault(False) self.new_button.setAutoDefault(False)
del_button = QtWidgets.QPushButton() self.del_button = QtWidgets.QPushButton()
del_button.setText("Delete item") self.del_button.setText("Delete item")
del_button.setIcon(get_icon("list-remove")) self.del_button.setIcon(get_icon("list-remove"))
del_button.pressed.connect(self.del_log) self.del_button.pressed.connect(self.del_log)
del_button.setAutoDefault(False) self.del_button.setAutoDefault(False)
ok_button = QtWidgets.QPushButton() self.ok_button = QtWidgets.QPushButton()
ok_button.setText("OK") self.ok_button.setText("OK")
ok_button.setIcon(get_icon("dialog-ok")) self.ok_button.setIcon(get_icon("dialog-ok"))
ok_button.pressed.connect(self._accept) self.ok_button.pressed.connect(self._accept)
ok_button.setAutoDefault(True) self.ok_button.setAutoDefault(True)
blayout = QtWidgets.QHBoxLayout() blayout = QtWidgets.QHBoxLayout()
blayout.addWidget(self.previous_button) blayout.addWidget(self.previous_button)
blayout.addWidget(self.next_button) blayout.addWidget(self.next_button)
blayout.addWidget(new_button) blayout.addWidget(self.new_button)
blayout.addWidget(del_button) blayout.addWidget(self.del_button)
blayout.addWidget(ok_button) blayout.addWidget(self.ok_button)
layout = QtWidgets.QVBoxLayout(self) layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tableWidget) layout.addWidget(self.tableWidget)
@ -151,6 +159,21 @@ class Report(QtWidgets.QDialog):
self._changing_items = False self._changing_items = False
self.tableWidget.editItem(item) 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() @QtCore.Slot()
def _accept(self): def _accept(self):
self.save() self.save()

View File

@ -3,7 +3,7 @@ try:
except ImportError: except ImportError:
from PySide2 import QtCore, QtGui, QtWidgets from PySide2 import QtCore, QtGui, QtWidgets
from fime.util import get_icon from fime.util import get_icon, EditStartedDetector
class TaskEdit(QtWidgets.QDialog): class TaskEdit(QtWidgets.QDialog):
@ -17,35 +17,51 @@ class TaskEdit(QtWidgets.QDialog):
self.tableView.horizontalHeader().setStretchLastSection(True) self.tableView.horizontalHeader().setStretchLastSection(True)
self.tableView.horizontalHeader().hide() self.tableView.horizontalHeader().hide()
self.tableView.verticalHeader().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() self.new_button = QtWidgets.QPushButton()
new_button.setText("New item") self.new_button.setText("New item")
new_button.setIcon(get_icon("list-add")) self.new_button.setIcon(get_icon("list-add"))
new_button.pressed.connect(self.new_task) self.new_button.pressed.connect(self.new_task)
new_button.setAutoDefault(False) self.new_button.setAutoDefault(False)
del_button = QtWidgets.QPushButton() self.del_button = QtWidgets.QPushButton()
del_button.setText("Delete item") self.del_button.setText("Delete item")
del_button.setIcon(get_icon("list-remove")) self.del_button.setIcon(get_icon("list-remove"))
del_button.pressed.connect(self.del_task) self.del_button.pressed.connect(self.del_task)
del_button.setAutoDefault(False) self.del_button.setAutoDefault(False)
ok_button = QtWidgets.QPushButton() self.ok_button = QtWidgets.QPushButton()
ok_button.setText("OK") self.ok_button.setText("OK")
ok_button.setIcon(get_icon("dialog-ok")) self.ok_button.setIcon(get_icon("dialog-ok"))
ok_button.pressed.connect(self.accept) self.ok_button.pressed.connect(self.accept)
ok_button.setAutoDefault(True) self.ok_button.setAutoDefault(True)
blayout = QtWidgets.QHBoxLayout() blayout = QtWidgets.QHBoxLayout()
blayout.addWidget(new_button) blayout.addWidget(self.new_button)
blayout.addWidget(del_button) blayout.addWidget(self.del_button)
blayout.addWidget(ok_button) blayout.addWidget(self.ok_button)
layout = QtWidgets.QVBoxLayout() layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.tableView) layout.addWidget(self.tableView)
layout.addLayout(blayout) layout.addLayout(blayout)
self.setLayout(layout) 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() @QtCore.Slot()
def new_task(self): def new_task(self):
l = self.list.stringList() l = self.list.stringList()

View File

@ -1,7 +1,7 @@
try: try:
from PySide6 import QtGui from PySide6 import QtCore, QtGui, QtWidgets
except ImportError: except ImportError:
from PySide2 import QtGui from PySide2 import QtCore, QtGui, QtWidgets
def get_screen_height(qobject): def get_screen_height(qobject):
@ -16,3 +16,20 @@ def get_icon(icon_name):
theme_name = icon_name.replace("-light", "") # respect system theme theme_name = icon_name.replace("-light", "") # respect system theme
fallback = QtGui.QIcon(f":/icons/{icon_name}").pixmap(256, 256) fallback = QtGui.QIcon(f":/icons/{icon_name}").pixmap(256, 256)
return QtGui.QIcon.fromTheme(theme_name, fallback) 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()