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.icon 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.NORMAL 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.MIDDLE 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.icon.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.icon.dialog_cancel(cancel.style())) cancel.clicked.connect(on_cancel) layout.addWidget(cancel) return widget