from PyQt5 import QtWidgets, QtCore from typing import Optional, Tuple, List, Any import db.tasks from model.task import Task, ValidTaskForm from model import difficulty, priority import gui.icons import gui.tasks.form.state import gui.tasks.duration class TextEditSignal(QtCore.QObject): _signal = QtCore.pyqtSignal(str, name = 'textEdit') def __init__(self): QtCore.QObject.__init__(self) def emit(self, text: str): self._signal.emit(text) def connect(self, f): self._signal.connect(f) def widget( parent: QtWidgets.QWidget, action_title: str, task: Task, on_validated, on_cancel): widget = QtWidgets.QWidget(parent) layout = QtWidgets.QVBoxLayout(widget) widget.setLayout(layout) grid = QtWidgets.QWidget(widget) layout.addWidget(grid) grid_layout = QtWidgets.QGridLayout(grid) grid.setLayout(grid_layout) init_name = task.name if task is not None else '' name_input = line_edit(grid, grid_layout, 0, 'Name', init_name) init_duration = gui.tasks.duration.format(task.duration) if task is not None else '' duration_input = line_edit(grid, grid_layout, 1, 'Duration', init_duration) init_tag = task.tag if task is not None else '' tag_input = line_edit(grid, grid_layout, 2, 'Tag', init_tag) init_difficulty = task.difficulty if task is not None else difficulty.Difficulty.MEDIUM difficulty_input = combo_box( grid, grid_layout, 3, 'Difficulty', [difficulty.format(d) for d in difficulty.values], int(init_difficulty)) init_priority = task.priority if task is not None else priority.Priority.MEDIUM priority_input = combo_box( grid, grid_layout, 4, 'Priority', [priority.format(d) for d in priority.values], int(init_priority)) init_description = task.description if task is not None else '' (description_input, description_signal) = text_edit(widget, 'Description', init_description) layout.addWidget(description_input) task_form_edition = gui.tasks.form.state.TaskFormEdition( init_name, name_input.textChanged, init_duration, duration_input.textChanged, init_tag, tag_input.textChanged, init_difficulty, difficulty_input.currentIndexChanged, init_priority, priority_input.currentIndexChanged, init_description, description_signal) def on_validate(): form = task_form_edition.get() if form: on_validated(form) layout.addWidget(buttons( parent = widget, action_title = action_title, task_form_signal = task_form_edition.signal(), on_validate = on_validate, on_cancel = on_cancel)) return widget def line_edit( parent, layout: QtWidgets.QGridLayout, n: int, label: str, default_value: str) -> QtWidgets.QLineEdit: label = QtWidgets.QLabel(label, parent) layout.addWidget(label, n, 0) edit = QtWidgets.QLineEdit(parent) if default_value != None: edit.setText(default_value) layout.addWidget(edit, n, 1) return edit def combo_box( parent, layout: QtWidgets.QGridLayout, n: int, label: str, values: List[str], default_value: int) -> QtWidgets.QComboBox: label = QtWidgets.QLabel(label, parent) layout.addWidget(label, n, 0) box = QtWidgets.QComboBox(parent) for value in values: box.addItem(value) if default_value != None: box.setCurrentIndex(default_value) layout.addWidget(box, n, 1) return box def text_edit( parent, label: str, default_value: str) -> Tuple[QtWidgets.QWidget, TextEditSignal]: widget = QtWidgets.QWidget(parent) layout = QtWidgets.QVBoxLayout(widget) signal = TextEditSignal() label = QtWidgets.QLabel(label, parent) layout.addWidget(label) edit = QtWidgets.QTextEdit(parent) if default_value != None: edit.insertPlainText(default_value) layout.addWidget(edit) edit.textChanged.connect(lambda: signal.emit(edit.toPlainText())) return (widget, signal) def buttons(parent, action_title, task_form_signal, on_validate, on_cancel): widget = QtWidgets.QWidget(parent) layout = QtWidgets.QHBoxLayout(widget) validate = QtWidgets.QPushButton(action_title, widget) validate.setDisabled(True) validate.setIcon(gui.icons.dialog_apply(validate.style())) validate.clicked.connect(on_validate); layout.addWidget(validate) def on_task_form_signal(form: Optional[ValidTaskForm]): if form: validate.setEnabled(True) else: validate.setDisabled(True) task_form_signal.connect(on_task_form_signal) cancel = QtWidgets.QPushButton('cancel', widget) cancel.setIcon(gui.icons.dialog_cancel(cancel.style())) cancel.clicked.connect(on_cancel) layout.addWidget(cancel) return widget