from PyQt5 import QtWidgets, QtCore from typing import Optional, Tuple, List, Any from model.task import Task, ValidTaskForm from model.tag import Tag from model import difficulty, priority import gui.icon import gui.tasks.form.state import gui.tasks.duration import gui.tags.list 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, tags: List[int], 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_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)) (tags_list_widget, tags_signal) = tags_selection(widget, tags) layout.addWidget(tags_list_widget) 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_difficulty, difficulty_input.currentIndexChanged, init_priority, priority_input.currentIndexChanged, tags_signal, 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 tags_selection(parent, init_tags: List[int]) -> QtWidgets.QWidget: return gui.tags.list.widget(parent, init_tags) 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