From 6ed4e669ef7cb857c7b0ac774c41e8f9c7758217 Mon Sep 17 00:00:00 2001 From: Joris Date: Fri, 8 May 2020 19:35:08 +0200 Subject: Add duration to tasks --- src/gui/tasks/form/state.py | 46 +++++++++++++++++++++++++++++++------------- src/gui/tasks/form/widget.py | 33 +++++++++++++------------------ src/gui/tasks/table/menu.py | 8 ++++---- src/gui/tasks/table/model.py | 20 +++++++++++++++---- src/gui/tasks/widget.py | 8 ++++---- 5 files changed, 70 insertions(+), 45 deletions(-) (limited to 'src/gui') diff --git a/src/gui/tasks/form/state.py b/src/gui/tasks/form/state.py index 6aedb95..a47aec7 100644 --- a/src/gui/tasks/form/state.py +++ b/src/gui/tasks/form/state.py @@ -1,39 +1,59 @@ from PyQt5 import QtCore +from typing import NamedTuple, Optional -from model.task import TaskForm +from model.task import ValidTaskForm class TaskFormEdition: - def __init__(self, name, name_signal, tag, tag_signal): + def __init__(self, name, name_signal, duration, duration_signal, tag, tag_signal): self._name = name + self._duration = duration self._tag = tag - self._signal = TaskFormSignal() + self._signal = ValidTaskFormSignal() name_signal.connect(lambda name: self.on_name_signal(name)) + duration_signal.connect(lambda duration: self.on_duration_signal(duration)) tag_signal.connect(lambda tag: self.on_tag_signal(tag)) - def get(self): - return TaskForm( - name = self._name, - tag = self._tag) + def get(self) -> Optional[ValidTaskForm]: + name = self._name.strip() + duration = self._duration.strip() + tag = self._tag.strip() + + if name and (duration == '' or duration.isdigit()): + return ValidTaskForm( + name = name, + duration = 0 if duration == '' else int(duration), + tag = tag) + else: + return None def on_name_signal(self, name: str): self._name = name - self._signal.emit(self.get()) + self.emit() + + def on_duration_signal(self, duration: str): + self._duration = duration + self.emit() def on_tag_signal(self, tag: str): self._tag = tag - self._signal.emit(self.get()) + self.emit() + + def emit(self): + validForm = self.get() + if validForm: + self._signal.emit(validForm) def signal(self): return self._signal -class TaskFormSignal(QtCore.QObject): - _signal = QtCore.pyqtSignal(TaskForm, name = 'taskForm') +class ValidTaskFormSignal(QtCore.QObject): + _signal = QtCore.pyqtSignal(ValidTaskForm, name = 'validTaskForm') def __init__(self): QtCore.QObject.__init__(self) - def emit(self, taskForm): - self._signal.emit(taskForm) + def emit(self, form: Optional[ValidTaskForm]): + self._signal.emit(form) def connect(self, f): self._signal.connect(f) diff --git a/src/gui/tasks/form/widget.py b/src/gui/tasks/form/widget.py index 61fa24d..8063d8d 100644 --- a/src/gui/tasks/form/widget.py +++ b/src/gui/tasks/form/widget.py @@ -1,7 +1,8 @@ from PyQt5 import QtWidgets +from typing import Optional import db.tasks -from model.task import Task, TaskForm +from model.task import Task, ValidTaskForm import gui.icons import gui.tasks.form.state @@ -21,6 +22,10 @@ def widget( (name_labelled_input, name_input) = labelled_input(widget, 'Name', init_name) layout.addWidget(name_labelled_input) + init_duration = str(task.duration) if task is not None else '' + (duration_labelled_input, duration_input) = labelled_input(widget, 'Duration', init_duration) + layout.addWidget(duration_labelled_input) + init_tag = task.tag if task is not None else '' (tag_labelled_input, tag_input) = labelled_input(widget, 'Tag', init_tag) layout.addWidget(tag_labelled_input) @@ -28,6 +33,8 @@ def widget( task_form_edition = gui.tasks.form.state.TaskFormEdition( init_name, name_input.textChanged, + init_duration, + duration_input.textChanged, init_tag, tag_input.textChanged) @@ -40,7 +47,6 @@ def widget( return widget -# Use grid ? def labelled_input(parent, label: str, default_value: str): widget = QtWidgets.QWidget(parent) @@ -67,8 +73,8 @@ def buttons(parent, action_title, task_form_signal, on_validate, on_cancel): validate.clicked.connect(on_validate); layout.addWidget(validate) - def on_task_form_signal(task_form): - if validate_form(task_form): + def on_task_form_signal(form: Optional[ValidTaskForm]): + if form: validate.setEnabled(True) else: validate.setDisabled(True) @@ -82,19 +88,6 @@ def buttons(parent, action_title, task_form_signal, on_validate, on_cancel): return widget -def validate(task_form: TaskForm, on_validated): - valid_form = validate_form(task_form) - if valid_form: - on_validated(valid_form) - -def clean_form(task_form: TaskForm): - return TaskForm( - name = task_form.name.strip(), - tag = task_form.tag.strip()) - -def validate_form(task_form: TaskForm): - task_form = clean_form(task_form) - if task_form.name: - return task_form - else: - return None +def validate(form: Optional[ValidTaskForm], on_validated): + if form: + on_validated(form) diff --git a/src/gui/tasks/table/menu.py b/src/gui/tasks/table/menu.py index 4366c25..f89ec92 100644 --- a/src/gui/tasks/table/menu.py +++ b/src/gui/tasks/table/menu.py @@ -2,7 +2,7 @@ from PyQt5 import QtWidgets import db.tasks import gui.tasks.modal -from model.task import Task, TaskForm +from model.task import Task, ValidTaskForm def open(database, table, update_task_signal, position): rows = set([index.row() for index in table.selectedIndexes()]) @@ -34,10 +34,10 @@ def show_update_dialog(database, parent_widget, update_task_signal, row, task): 'Modify a task', 'modify', task, - lambda taskForm: on_update(database, update_task_signal, row, task, taskForm)) + lambda form: on_update(database, update_task_signal, row, task, form)) dialog.exec_() -def on_update(database, update_task_signal, row, task: Task, taskForm: TaskForm): - task = db.tasks.update(database.cursor(), task, taskForm) +def on_update(database, update_task_signal, row, task: Task, form: ValidTaskForm): + task = db.tasks.update(database.cursor(), task, form) update_task_signal.emit(row, task) database.commit() diff --git a/src/gui/tasks/table/model.py b/src/gui/tasks/table/model.py index 90bcc4c..6b8133d 100644 --- a/src/gui/tasks/table/model.py +++ b/src/gui/tasks/table/model.py @@ -7,9 +7,9 @@ import math import util.array import util.range -columns = 3 +columns = 4 -headers = ['Age', 'Name', 'Tag'] +headers = ['Age', 'Name', 'Duration', 'Tag'] default_sort = (0, Qt.AscendingOrder) @@ -31,9 +31,11 @@ class TableModel(QtCore.QAbstractTableModel): task = self._tasks[index.row()] if index.column() == 0: return age_since(task.created_at) - if index.column() == 1: + elif index.column() == 1: return task.name - if index.column() == 2: + elif index.column() == 2: + return pp_duration(task.duration) + elif index.column() == 3: return task.tag else: return QtCore.QVariant() @@ -101,12 +103,22 @@ def age_since(timestamp): else: return '1m' +def pp_duration(minutes: int): + if minutes >= 60 * 24: + return '' + str(math.floor(minutes / 60 / 24)) + 'd' + elif minutes >= 60: + return '' + str(math.floor(minutes / 60)) + 'h' + else: + return '' + str(minutes) + 'm' + def sort_key(task: Task, row: int): if row == 0: return task.created_at elif row == 1: return task.name.lower() elif row == 2: + return task.duration + elif row == 3: return task.tag.lower() def is_reversed(row: int, order: Qt.SortOrder) -> bool: diff --git a/src/gui/tasks/widget.py b/src/gui/tasks/widget.py index bca6585..6fa8bf0 100644 --- a/src/gui/tasks/widget.py +++ b/src/gui/tasks/widget.py @@ -4,7 +4,7 @@ import db.tasks import gui.tasks.signal import gui.tasks.table.widget import gui.icons -from model.task import TaskForm +from model.task import ValidTaskForm def widget(database, parent): widget = QtWidgets.QWidget(parent) @@ -30,10 +30,10 @@ def show_add_dialog(database, parent_widget, add_task_signal): 'Add a task', 'add', None, - lambda taskForm: on_add(database, taskForm, add_task_signal)) + lambda form: on_add(database, form, add_task_signal)) dialog.exec_() -def on_add(database, taskForm: TaskForm, add_task_signal): - task = db.tasks.insert(database.cursor(), taskForm) +def on_add(database, form: ValidTaskForm, add_task_signal): + task = db.tasks.insert(database.cursor(), form) database.commit() add_task_signal.emit(task) -- cgit v1.2.3