from PyQt5 import QtWidgets, QtCore from typing import Optional, Tuple, List, Any from todo.model.task import Task, ValidTaskForm from todo.model.tag import Tag import todo.gui.icon import todo.gui.tasks.form.state import todo.gui.tags.list from todo.util.gui.date_input import DateInput 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) init_name = task.name if task is not None else "" name_input = name_edit(widget, layout, "Nom", init_name) init_due_date = (task.due_date.strftime("%d/%m/%Y") if task.due_date else None) if task else None (due_date_input, due_date_signal) = date_edit(widget, "Échéance", init_due_date) layout.addWidget(due_date_input) (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 = todo.gui.tasks.form.state.TaskFormEdition( init_name, name_input.textChanged, init_due_date, due_date_signal, tags, 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 name_edit( parent, layout: QtWidgets.QVBoxLayout, label: str, default_value: str) -> QtWidgets.QLineEdit: widget = QtWidgets.QWidget(parent) inner_layout = QtWidgets.QVBoxLayout(widget) widget.setLayout(inner_layout) label = QtWidgets.QLabel(label, parent) inner_layout.addWidget(label) edit = QtWidgets.QLineEdit(parent) if default_value != None: edit.setText(default_value) inner_layout.addWidget(edit) layout.addWidget(widget) 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 todo.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 date_edit( parent, label: str, init_date: str ) -> QtWidgets.QLineEdit: widget = QtWidgets.QWidget(parent) layout = QtWidgets.QVBoxLayout(widget) label = QtWidgets.QLabel(label, parent) layout.addWidget(label) date_input = DateInput(init_date, parent) layout.addWidget(date_input) return (widget, date_input.textChanged) 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(todo.gui.icon.dialog_ok(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("Annuler", widget) cancel.setIcon(todo.gui.icon.dialog_cancel(cancel.style())) cancel.clicked.connect(on_cancel) layout.addWidget(cancel) return widget