from PyQt5 import QtCore, QtWidgets import db.tasks from model.task import Task, TaskForm import gui.icons 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) init_name = task.name if task is not None else '' (name_labelled_input, name_input) = labelled_input(dialog, 'Name', init_name) layout.addWidget(name_labelled_input) init_tag = task.tag if task is not None else '' (tag_labelled_input, tag_input) = labelled_input(dialog, 'Tag', init_tag) layout.addWidget(tag_labelled_input) task_form_edition = TaskFormEdition( init_name, name_input.textChanged, init_tag, tag_input.textChanged) layout.addWidget(buttons( parent = dialog, action_title = action_title, task_form_signal = task_form_edition.signal(), on_validate = lambda: validate(dialog, task_form_edition.get(), on_validated), on_cancel = lambda: dialog.reject())) return dialog # Use grid ? def labelled_input(parent, label: str, default_value: str): widget = QtWidgets.QWidget(parent) layout = QtWidgets.QHBoxLayout(widget) widget.setLayout(layout) label = QtWidgets.QLabel(label, widget) layout.addWidget(label) line_edit = QtWidgets.QLineEdit(widget) if default_value != None: line_edit.setText(default_value) layout.addWidget(line_edit) return (widget, line_edit) 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(task_form): if validate_form(task_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 def validate(dialog, task_form: TaskForm, on_validated): valid_form = validate_form(task_form) if valid_form: on_validated(valid_form) dialog.accept() def clean_form(task_form: TaskForm): return TaskForm( name = task_form.name.strip(), tag = task_form.tag.strip()) def validate_form(task_form: TaskForm): task_form = clean_form(task_form) if task_form.name: return task_form else: return None ##################### # Task form edition # ##################### class TaskFormEdition: def __init__(self, name, name_signal, tag, tag_signal): self._name = name self._tag = tag self._signal = TaskFormSignal() name_signal.connect(lambda name: self.on_name_signal(name)) tag_signal.connect(lambda tag: self.on_tag_signal(tag)) def get(self): return TaskForm( name = self._name, tag = self._tag) def on_name_signal(self, name: str): self._name = name self._signal.emit(self.get()) def on_tag_signal(self, tag: str): self._tag = tag self._signal.emit(self.get()) def signal(self): return self._signal class TaskFormSignal(QtCore.QObject): _signal = QtCore.pyqtSignal(TaskForm, name = 'taskForm') def __init__(self): QtCore.QObject.__init__(self) def emit(self, taskForm): self._signal.emit(taskForm) def connect(self, f): self._signal.connect(f)