diff options
Diffstat (limited to 'src/gui/tags/panel')
-rw-r--r-- | src/gui/tags/panel/dialog.py | 65 | ||||
-rw-r--r-- | src/gui/tags/panel/form/state.py | 58 | ||||
-rw-r--r-- | src/gui/tags/panel/form/widget.py | 137 | ||||
-rw-r--r-- | src/gui/tags/panel/signal.py | 27 | ||||
-rw-r--r-- | src/gui/tags/panel/table/menu.py | 36 | ||||
-rw-r--r-- | src/gui/tags/panel/table/model.py | 104 | ||||
-rw-r--r-- | src/gui/tags/panel/table/widget.py | 73 | ||||
-rw-r--r-- | src/gui/tags/panel/widget.py | 30 |
8 files changed, 0 insertions, 530 deletions
diff --git a/src/gui/tags/panel/dialog.py b/src/gui/tags/panel/dialog.py deleted file mode 100644 index f0ca986..0000000 --- a/src/gui/tags/panel/dialog.py +++ /dev/null @@ -1,65 +0,0 @@ -from PyQt5 import QtCore, QtWidgets - -from model.tag import Tag, ValidTagForm - -import db.tags -import gui.tags.panel.form.widget -import database - -def add(parent_widget, add_tag_signal): - - def on_add(form: ValidTagForm): - tag = db.tags.insert(database.cursor(), form) - database.commit() - add_tag_signal.emit(tag) - - return widget(parent_widget, "Add a tag", "add", None, on_add) - -def update(parent_widget, update_tag_signal, row, tag): - - def on_update(form: ValidTagForm): - updated_tag = db.tags.update(database.cursor(), tag, form) - update_tag_signal.emit(row, updated_tag) - database.commit() - - return widget(parent_widget, "Modify a tag", "modify", tag, on_update) - -def show_delete(table, rows): - confirm = QtWidgets.QMessageBox.question( - table, - "Tag deletion", - "Do you really want to delete the selected tags ?", - QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes, - QtWidgets.QMessageBox.Yes) - - if confirm == QtWidgets.QMessageBox.Yes: - db.tags.delete(database.cursor(), table.model().row_ids(rows)) - database.commit() - table.model().delete_tags(rows) - -def widget( - parent: QtWidgets.QWidget, - title: str, - action_title: str, - tag: Tag, - on_validated): - - dialog = QtWidgets.QDialog(parent) - dialog.setWindowTitle(title) - dialog.setMinimumSize(QtCore.QSize(320, 240)) - - layout = QtWidgets.QVBoxLayout(dialog) - dialog.setLayout(layout) - - def on_dialog_validated(form): - dialog.accept() - on_validated(form) - - layout.addWidget(gui.tags.panel.form.widget.widget( - parent = dialog, - action_title = action_title, - tag = tag, - on_validated = on_dialog_validated, - on_cancel = lambda: dialog.reject())) - - return dialog diff --git a/src/gui/tags/panel/form/state.py b/src/gui/tags/panel/form/state.py deleted file mode 100644 index fbec956..0000000 --- a/src/gui/tags/panel/form/state.py +++ /dev/null @@ -1,58 +0,0 @@ -from PyQt5 import QtCore -from typing import Optional - -from model.tag import ValidTagForm - -class TagFormEdition: - def __init__( - self, - name, - name_signal, - color, - color_signal): - - self._name = name - self._color = color - self._signal = ValidTagFormSignal() - - name_signal.connect(lambda n: self.on_name_signal(n)) - color_signal.connect(lambda d: self.on_color_signal(d)) - - def get(self) -> Optional[ValidTagForm]: - name = self._name.strip() - color = self._color.strip() - - if name and color: - return ValidTagForm( - name = name, - color = color) - else: - return None - - def on_name_signal(self, name: str): - self._name = name - self.emit() - - def on_color_signal(self, color: str): - self._color = color - self.emit() - - def emit(self): - validForm = self.get() - if validForm: - self._signal.emit(validForm) - - def signal(self): - return self._signal - -class ValidTagFormSignal(QtCore.QObject): - _signal = QtCore.pyqtSignal(ValidTagForm, name = "validTagForm") - - def __init__(self): - QtCore.QObject.__init__(self) - - def emit(self, form: Optional[ValidTagForm]): - self._signal.emit(form) - - def connect(self, f): - self._signal.connect(f) diff --git a/src/gui/tags/panel/form/widget.py b/src/gui/tags/panel/form/widget.py deleted file mode 100644 index 7079e57..0000000 --- a/src/gui/tags/panel/form/widget.py +++ /dev/null @@ -1,137 +0,0 @@ -from PyQt5 import QtWidgets, QtCore, QtGui -from typing import Optional, Tuple, List, Any - -from model.tag import Tag, ValidTagForm -from model import difficulty, priority -import gui.icon -import gui.tags.panel.form.state -import 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 = 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(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(gui.icon.dialog_cancel(cancel.style())) - cancel.clicked.connect(on_cancel) - layout.addWidget(cancel) - - return widget diff --git a/src/gui/tags/panel/signal.py b/src/gui/tags/panel/signal.py deleted file mode 100644 index 022abde..0000000 --- a/src/gui/tags/panel/signal.py +++ /dev/null @@ -1,27 +0,0 @@ -from PyQt5 import QtCore - -from model.tag import Tag - -class AddTag(QtCore.QObject): - _signal = QtCore.pyqtSignal(Tag, name = "addTag") - - def __init__(self): - QtCore.QObject.__init__(self) - - def emit(self, tag): - self._signal.emit(tag) - - def connect(self, f): - self._signal.connect(f) - -class UpdateTag(QtCore.QObject): - _signal = QtCore.pyqtSignal(int, Tag, name = "updateTag") - - def __init__(self): - QtCore.QObject.__init__(self) - - def emit(self, row, tag): - self._signal.emit(row, tag) - - def connect(self, f): - self._signal.connect(f) diff --git a/src/gui/tags/panel/table/menu.py b/src/gui/tags/panel/table/menu.py deleted file mode 100644 index f9ee148..0000000 --- a/src/gui/tags/panel/table/menu.py +++ /dev/null @@ -1,36 +0,0 @@ -from PyQt5 import QtWidgets, QtCore - -from model.tag import Tag, ValidTagForm -import database -import db.tags -import db.task_tags -import gui.tags.panel.dialog - -def open(table, update_tag_signal, position): - rows = set([index.row() for index in table.selectedIndexes()]) - - menu = QtWidgets.QMenu(table) - - actions = 0 - - if len(rows) == 1: - modify_action = menu.addAction(gui.icon.dialog_open(menu.style()), "modify") - actions += 1 - else: - modify_action = QtWidgets.QAction(menu) - - tags = table.model().row_ids(rows) - if not db.task_tags.one_is_used(database.cursor(), tags): - delete_action = menu.addAction(gui.icon.trash(menu.style()), "delete") - actions += 1 - else: - delete_action = QtWidgets.QAction(menu) - - if actions > 0: - action = menu.exec_(table.mapToGlobal(position + QtCore.QPoint(15, 20))) - if action == modify_action and len(rows) == 1: - row = list(rows)[0] - tag = table.model().get_at(row) - gui.tags.panel.dialog.update(table, update_tag_signal, row, tag).exec_() - elif action == delete_action: - gui.tags.panel.dialog.show_delete(table, rows) diff --git a/src/gui/tags/panel/table/model.py b/src/gui/tags/panel/table/model.py deleted file mode 100644 index 00ca785..0000000 --- a/src/gui/tags/panel/table/model.py +++ /dev/null @@ -1,104 +0,0 @@ -from PyQt5 import QtCore, QtWidgets, QtGui -from PyQt5.QtCore import Qt -from typing import List - -from model.tag import Tag -import time -import math -import util.array -import util.range -import gui.color - -columns = 1 - -headers = ["Name", "Color"] - -default_sort = (0, Qt.AscendingOrder) - -class TableModel(QtCore.QAbstractTableModel): - def __init__(self, tags): - super(TableModel, self).__init__() - self._tags = tags - - def headerData(self, section, orientation, role): - if role == Qt.DisplayRole and orientation == Qt.Horizontal: - return headers[section] - elif role == Qt.DisplayRole and orientation == Qt.Vertical: - return section + 1 - else: - return QtCore.QVariant() - - def data(self, index, role): - tag = self._tags[index.row()] - - if role == Qt.DisplayRole: - if index.column() == 0: - return tag.name - elif index.column() == 1: - return tag.color - elif role == Qt.BackgroundRole: - return QtGui.QBrush(QtGui.QColor(tag.color)) - else: - return QtCore.QVariant() - - def rowCount(self, index): - return len(self._tags) - - def columnCount(self, index): - return columns - - def get_at(self, row): - if row >= 0 and row < len(self._tags): - return self._tags[row] - - def insert_tag(self, header: QtWidgets.QHeaderView, tag: Tag) -> int: - at = self.insert_position(header, tag) - self.beginInsertRows(QtCore.QModelIndex(), at, at) - self._tags.insert(at, tag) - self.endInsertRows() - return at - - def insert_position(self, header: QtWidgets.QHeaderView, tag: Tag) -> int: - row = header.sortIndicatorSection() - order = header.sortIndicatorOrder() - is_rev = is_reversed(row, order) - return util.array.insert_position( - sort_key(tag, row, is_rev), - [sort_key(t, row, is_rev) for t in self._tags], - is_rev) - - def update_tag(self, header: QtWidgets.QHeaderView, row, tag: Tag) -> int: - self.delete_tag_range(row, 1) - return self.insert_tag(header, tag) - - def delete_tags(self, indexes): - for range in reversed(util.range.from_indexes(indexes)): - self.delete_tag_range(range.start, range.length) - return True - - def delete_tag_range(self, row, rows): - self.beginRemoveRows(QtCore.QModelIndex(), row, row + rows - 1) - self._tags = self._tags[:row] + self._tags[row + rows:] - self.endRemoveRows() - return True - - def row_ids(self, rows): - return [tag.id for i, tag in enumerate(self._tags) if i in rows] - - def sort(self, row: int, order: Qt.SortOrder): - self.layoutAboutToBeChanged.emit() - is_rev = is_reversed(row, order) - self._tags = sorted( - self._tags, - key = lambda tag: sort_key(tag, row, is_rev), - reverse = is_rev) - self.layoutChanged.emit() - -def sort_key(tag: Tag, row: int, is_reversed: bool): - if row == 0: - return tag.name.lower() - elif row == 1: - return tag.color - -def is_reversed(row: int, order: Qt.SortOrder) -> bool: - return order == Qt.DescendingOrder diff --git a/src/gui/tags/panel/table/widget.py b/src/gui/tags/panel/table/widget.py deleted file mode 100644 index 0ef67c2..0000000 --- a/src/gui/tags/panel/table/widget.py +++ /dev/null @@ -1,73 +0,0 @@ -from PyQt5 import QtWidgets -from PyQt5.QtCore import Qt - -from model.tag import Tag, ValidTagForm -import database -import db.tags -import db.task_tags -import gui.tags.panel.dialog -import gui.tags.panel.signal -import gui.tags.panel.table.menu -import gui.tags.panel.table.model - -class Widget(QtWidgets.QTableView): - - def __init__(self, parent, add_tag_signal): - super().__init__(parent) - - self._update_tag_signal = gui.tags.panel.signal.UpdateTag() - - tags = db.tags.get(database.cursor()) - table_model = gui.tags.panel.table.model.TableModel(tags) - - self.setModel(table_model) - self.sortByColumn( - gui.tags.panel.table.model.default_sort[0], - gui.tags.panel.table.model.default_sort[1]) - self.setSortingEnabled(True) - self.setSelectionBehavior(QtWidgets.QTableView.SelectRows) - self.horizontalHeader().setStretchLastSection(True) - self.resizeColumns() - - self.doubleClicked.connect(lambda index: self.on_double_click(index.row())) - - # # Menu - self.setContextMenuPolicy(Qt.CustomContextMenu) - self.customContextMenuRequested.connect(lambda position: gui.tags.panel.table.menu.open(self, self._update_tag_signal, position)) - - add_tag_signal.connect(lambda tag: self.insert(tag)) - self._update_tag_signal.connect(lambda row, tag: self.update(row, tag)) - - def insert(self, tag): - self.model().insert_tag(self.horizontalHeader(), tag) - self.resizeColumns() - - def update(self, row, tag): - row = self.model().update_tag(self.horizontalHeader(), row, tag) - self.selectRow(row) - self.resizeColumns() - - def resizeColumns(self): - for column in range(gui.tags.panel.table.model.columns): - self.resizeColumnToContents(column) - - def keyPressEvent(self, event): - super().keyPressEvent(event) - if event.key() in (Qt.Key_Return, Qt.Key_Enter): - rows = self.get_selected_rows() - if len(rows) == 1: - row = rows[0] - tag = self.model().get_at(row) - gui.tags.panel.dialog.update(self, self._update_tag_signal, row, tag).exec_() - elif event.key() == Qt.Key_Delete: - rows = self.get_selected_rows() - tags = self.model().row_ids(rows) - if not db.task_tags.one_is_used(database.cursor(), tags): - gui.tags.panel.dialog.show_delete(self, rows) - - def get_selected_rows(self): - return list(set([index.row() for index in self.selectedIndexes()])) - - def on_double_click(self, row: int): - tag = self.model().get_at(row) - gui.tags.panel.dialog.update(self, self._update_tag_signal, row, tag).exec_() diff --git a/src/gui/tags/panel/widget.py b/src/gui/tags/panel/widget.py deleted file mode 100644 index faca1da..0000000 --- a/src/gui/tags/panel/widget.py +++ /dev/null @@ -1,30 +0,0 @@ -from PyQt5 import QtWidgets - -import gui.tags.panel.dialog -import gui.tags.panel.signal -import gui.tags.panel.table.widget -import gui.icon - -def widget(parent): - widget = QtWidgets.QWidget(parent) - - layout = QtWidgets.QVBoxLayout(widget) - widget.setLayout(layout) - - layout.addSpacing(15) - - add_tag_signal = gui.tags.panel.signal.AddTag() - - add_tag_button = QtWidgets.QPushButton(" Add a tag", widget) - add_tag_button.setFixedHeight(30) - add_tag_button.setIcon(gui.icon.new_folder(widget.style())) - - add_tag_button.clicked.connect(lambda: gui.tags.panel.dialog.add(widget, add_tag_signal).exec_()) - layout.addWidget(add_tag_button) - - layout.addSpacing(20) - - table = gui.tags.panel.table.widget.Widget(widget, add_tag_signal) - layout.addWidget(table) - - return widget |