aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris2020-05-09 15:04:24 +0200
committerJoris2020-05-09 15:04:24 +0200
commitb5658771fd9b1a50e10a0004dd1934c746505446 (patch)
tree3869beb864e0b2f664094233c67cfab573b08559
parent3c946e02e59a05ea0b04aa6c95ce38d9d1f8ae30 (diff)
downloadtodo-b5658771fd9b1a50e10a0004dd1934c746505446.tar.gz
todo-b5658771fd9b1a50e10a0004dd1934c746505446.tar.bz2
todo-b5658771fd9b1a50e10a0004dd1934c746505446.zip
Enable task modification and deletion with keyboard and mouse
-rw-r--r--src/gui/tasks/dialog.py64
-rw-r--r--src/gui/tasks/modal.py32
-rw-r--r--src/gui/tasks/table/menu.py24
-rw-r--r--src/gui/tasks/table/widget.py79
-rw-r--r--src/gui/tasks/widget.py20
5 files changed, 122 insertions, 97 deletions
diff --git a/src/gui/tasks/dialog.py b/src/gui/tasks/dialog.py
new file mode 100644
index 0000000..2e0d8d4
--- /dev/null
+++ b/src/gui/tasks/dialog.py
@@ -0,0 +1,64 @@
+from PyQt5 import QtCore, QtWidgets
+
+from model.task import Task, ValidTaskForm
+
+import db.tasks
+import gui.tasks.form.widget
+
+def add(database, parent_widget, add_task_signal):
+
+ def on_add(form: ValidTaskForm):
+ task = db.tasks.insert(database.cursor(), form)
+ database.commit()
+ add_task_signal.emit(task)
+
+ return widget(parent_widget, 'Add a task', 'add', None, on_add)
+
+def update(database, parent_widget, update_task_signal, row, task):
+
+ def on_update(form: ValidTaskForm):
+ updated_task = db.tasks.update(database.cursor(), task, form)
+ update_task_signal.emit(row, updated_task)
+ database.commit()
+
+ return widget(parent_widget, 'Modify a task', 'modify', task, on_update)
+
+def show_delete(database, table, rows):
+ confirm = QtWidgets.QMessageBox.question(
+ table,
+ 'Task deletion',
+ 'Do you really want to delete the selected tasks ?',
+ QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes,
+ QtWidgets.QMessageBox.Yes)
+
+ if confirm == QtWidgets.QMessageBox.Yes:
+ db.tasks.delete(database.cursor(), table.model().row_ids(rows))
+ database.commit()
+ table.model().delete_tasks(rows)
+
+def widget(
+ parent: QtWidgets.QWidget,
+ title: str,
+ action_title: str,
+ task: Task,
+ on_validated):
+
+ dialog = QtWidgets.QDialog(parent)
+ dialog.setWindowTitle(title)
+ dialog.setMinimumSize(QtCore.QSize(320, 240))
+
+ layout = QtWidgets.QVBoxLayout(dialog)
+ dialog.setLayout(layout)
+
+ def on_dialog_validated(form):
+ dialog.accept()
+ on_validated(form)
+
+ layout.addWidget(gui.tasks.form.widget.widget(
+ parent = dialog,
+ action_title = action_title,
+ task = task,
+ on_validated = on_dialog_validated,
+ on_cancel = lambda: dialog.reject()))
+
+ return dialog
diff --git a/src/gui/tasks/modal.py b/src/gui/tasks/modal.py
deleted file mode 100644
index 3662947..0000000
--- a/src/gui/tasks/modal.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from PyQt5 import QtCore, QtWidgets
-
-from model.task import Task
-
-import gui.tasks.form.widget
-
-def dialog(
- parent: QtWidgets.QWidget,
- title: str,
- action_title: str,
- task: Task,
- on_validated):
-
- dialog = QtWidgets.QDialog(parent)
- dialog.setWindowTitle(title)
- dialog.setMinimumSize(QtCore.QSize(320, 240))
-
- layout = QtWidgets.QVBoxLayout(dialog)
- dialog.setLayout(layout)
-
- layout.addWidget(gui.tasks.form.widget.widget(
- parent = dialog,
- action_title = action_title,
- task = task,
- on_validated = lambda form: on_dialog_validated(dialog, on_validated, form),
- on_cancel = lambda: dialog.reject()))
-
- return dialog
-
-def on_dialog_validated(dialog, on_validated, f):
- dialog.accept()
- on_validated(f)
diff --git a/src/gui/tasks/table/menu.py b/src/gui/tasks/table/menu.py
index f89ec92..51f7330 100644
--- a/src/gui/tasks/table/menu.py
+++ b/src/gui/tasks/table/menu.py
@@ -1,7 +1,7 @@
from PyQt5 import QtWidgets
import db.tasks
-import gui.tasks.modal
+import gui.tasks.dialog
from model.task import Task, ValidTaskForm
def open(database, table, update_task_signal, position):
@@ -20,24 +20,6 @@ def open(database, table, update_task_signal, position):
if action == modify_action and len(rows) == 1:
row = list(rows)[0]
task = table.model().get_at(row)
- show_update_dialog(database, table, update_task_signal, row, task)
+ gui.tasks.dialog.update(database, table, update_task_signal, row, task).exec_()
elif action == delete_action:
- confirm = QtWidgets.QMessageBox.question(table, 'Task deletion', 'Do you really want to delete the selected tasks ?', QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.Yes)
- if confirm == QtWidgets.QMessageBox.Yes:
- db.tasks.delete(database.cursor(), table.model().row_ids(rows))
- database.commit()
- table.model().delete_tasks(rows)
-
-def show_update_dialog(database, parent_widget, update_task_signal, row, task):
- dialog = gui.tasks.modal.dialog(
- parent_widget,
- 'Modify a task',
- 'modify',
- task,
- lambda form: on_update(database, update_task_signal, row, task, form))
- dialog.exec_()
-
-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()
+ gui.tasks.dialog.show_delete(database, table, rows)
diff --git a/src/gui/tasks/table/widget.py b/src/gui/tasks/table/widget.py
index a990c0e..95ebe44 100644
--- a/src/gui/tasks/table/widget.py
+++ b/src/gui/tasks/table/widget.py
@@ -5,42 +5,67 @@ import db.tasks
import gui.tasks.signal
import gui.tasks.table.menu
import gui.tasks.table.model
+import gui.tasks.dialog
+from model.task import Task, ValidTaskForm
-def widget(database, parent, add_task_signal):
- table = QtWidgets.QTableView(parent)
+class Widget(QtWidgets.QTableView):
- tasks = db.tasks.get(database.cursor())
- table_model = gui.tasks.table.model.TableModel(tasks)
+ def __init__(self, database, parent, add_task_signal):
+ super().__init__(parent)
- table.setModel(table_model)
- table.sortByColumn(
+ self._database = database
+ self._update_task_signal = gui.tasks.signal.UpdateTask()
+
+ tasks = db.tasks.get(self._database.cursor())
+ table_model = gui.tasks.table.model.TableModel(tasks)
+
+ self.setModel(table_model)
+ self.sortByColumn(
gui.tasks.table.model.default_sort[0],
gui.tasks.table.model.default_sort[1])
- table.setSortingEnabled(True)
- table.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
- table.horizontalHeader().setStretchLastSection(True)
- resizeColumns(table)
+ self.setSortingEnabled(True)
+ self.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
+ self.horizontalHeader().setStretchLastSection(True)
+ self.resizeColumns()
+
+ self.doubleClicked.connect(lambda index: self.on_double_click(index.row()))
+
+ # Menu
+ self.setContextMenuPolicy(Qt.CustomContextMenu)
+ self.customContextMenuRequested.connect(lambda position: gui.tasks.table.menu.open(self._database, self, self._update_task_signal, position))
- update_task_signal = gui.tasks.signal.UpdateTask()
+ add_task_signal.get().connect(lambda task: self.insert(task))
+ self._update_task_signal.get().connect(lambda row, task: self.update(row, task))
- # Menu
- table.setContextMenuPolicy(Qt.CustomContextMenu)
- table.customContextMenuRequested.connect(lambda position: gui.tasks.table.menu.open(database, table, update_task_signal, position))
+ def insert(self, task):
+ self.model().insert_task(self.horizontalHeader(), task)
+ self.resizeColumns()
- add_task_signal.get().connect(lambda task: insert(table, task))
- update_task_signal.get().connect(lambda row, task: update(table, row, task))
+ def update(self, row, task):
+ row = self.model().update_task(self.horizontalHeader(), row, task)
+ self.selectRow(row)
+ self.resizeColumns()
- return table
+ def resizeColumns(self):
+ for column in range(gui.tasks.table.model.columns):
+ self.resizeColumnToContents(column)
-def insert(table, task):
- table.model().insert_task(table.horizontalHeader(), task)
- resizeColumns(table)
+ def keyPressEvent(self, event):
+ super().keyPressEvent(event)
+ if event.key() in (Qt.Key_Return, Qt.Key_Enter):
+ rows = self.get_selected_rows()
+ if len(rows) == 1:
+ row = rows[0]
+ task = self.model().get_at(row)
+ gui.tasks.dialog.update(
+ self._database, self, self._update_task_signal, row, task).exec_()
+ elif event.key() == Qt.Key_Delete:
+ rows = self.get_selected_rows()
+ gui.tasks.dialog.show_delete(self._database, self, rows)
-def update(table, row, task):
- row = table.model().update_task(table.horizontalHeader(), row, task)
- table.selectRow(row)
- resizeColumns(table)
+ def get_selected_rows(self):
+ return list(set([index.row() for index in self.selectedIndexes()]))
-def resizeColumns(table):
- for column in range(gui.tasks.table.model.columns):
- table.resizeColumnToContents(column)
+ def on_double_click(self, row: int):
+ task = self.model().get_at(row)
+ gui.tasks.dialog.update(self._database, self, self._update_task_signal, row, task).exec_()
diff --git a/src/gui/tasks/widget.py b/src/gui/tasks/widget.py
index 6fa8bf0..0462f54 100644
--- a/src/gui/tasks/widget.py
+++ b/src/gui/tasks/widget.py
@@ -1,6 +1,5 @@
from PyQt5 import QtWidgets, QtCore
-import db.tasks
import gui.tasks.signal
import gui.tasks.table.widget
import gui.icons
@@ -16,24 +15,11 @@ def widget(database, parent):
add_task_button = QtWidgets.QPushButton('Add a task', widget)
add_task_button.setIcon(gui.icons.new_folder(widget.style()))
- add_task_button.clicked.connect(lambda: show_add_dialog(database, widget, add_task_signal))
+ add_task_button.clicked.connect(lambda: gui.tasks.dialog.add(
+ database, widget, add_task_signal).exec_())
layout.addWidget(add_task_button)
- table = gui.tasks.table.widget.widget(database, widget, add_task_signal)
+ table = gui.tasks.table.widget.Widget(database, widget, add_task_signal)
layout.addWidget(table)
return widget
-
-def show_add_dialog(database, parent_widget, add_task_signal):
- dialog = gui.tasks.modal.dialog(
- parent_widget,
- 'Add a task',
- 'add',
- None,
- lambda form: on_add(database, form, add_task_signal))
- dialog.exec_()
-
-def on_add(database, form: ValidTaskForm, add_task_signal):
- task = db.tasks.insert(database.cursor(), form)
- database.commit()
- add_task_signal.emit(task)