from PyQt5 import QtWidgets, QtCore, QtGui from typing import Optional, Tuple, List, Any from todo.model.tag import Tag, ValidTagForm from todo.model import difficulty, priority import todo.gui.icon import todo.gui.tags.panel.form.state import todo.gui.color def widget( parent: QtWidgets.QWidget, action_title: str, tag: Tag, 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 = tag.name if tag is not None else "" name_input = line_edit(grid, grid_layout, 0, "Name", init_name) init_color = tag.color if tag is not None else "#FFFFFF" color_input = color_edit(grid, grid_layout, 1, "Color", QtGui.QColor(init_color)) tag_form_edition = todo.gui.tags.panel.form.state.TagFormEdition( init_name, name_input.textChanged, init_color, color_input.textChanged) def on_validate(): form = tag_form_edition.get() if form: on_validated(form) layout.addWidget(buttons( parent = widget, action_title = action_title, tag_form_signal = tag_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 color_edit( parent, layout: QtWidgets.QGridLayout, n: int, label: str, init_color: QtGui.QColor) -> QtWidgets.QLineEdit: label = QtWidgets.QLabel(label, parent) layout.addWidget(label, n, 0) edit = ColorInput(init_color, parent) layout.addWidget(edit, n, 1) return edit class ColorInput(QtWidgets.QLineEdit): def __init__(self, init_color: QtGui.QColor, parent): super().__init__(parent) self.setReadOnly(True) self.installEventFilter(self) self._color = init_color self.update(init_color) self._is_editing = False def eventFilter(self, source, event): if source is self and event.type() == QtCore.QEvent.FocusIn: if not self._is_editing: self._is_editing = True color = QtWidgets.QColorDialog.getColor(self._color, self) if color.isValid(): self.update(color) else: self._is_editing = False self.clearFocus() return super(ColorInput, self).eventFilter(source, event) def update(self, color: QtGui.QColor): self._color = color self.setText(color.name().upper()) palette = QtGui.QPalette() palette.setColor(QtGui.QPalette.Base, color) palette.setColor(QtGui.QPalette.Text, color) self.setPalette(palette) def buttons(parent, action_title, tag_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_tag_form_signal(form: Optional[ValidTagForm]): if form: validate.setEnabled(True) else: validate.setDisabled(True) tag_form_signal.connect(on_tag_form_signal) cancel = QtWidgets.QPushButton("cancel", widget) cancel.setIcon(todo.gui.icon.dialog_cancel(cancel.style())) cancel.clicked.connect(on_cancel) layout.addWidget(cancel) return widget