From 1595e0de940a86a7810df0e02e43838d97c0d846 Mon Sep 17 00:00:00 2001 From: Joris Date: Sat, 6 Jun 2020 17:44:26 +0200 Subject: Provide nix build --- src/gui/tasks/table/menu.py | 49 -------- src/gui/tasks/table/widget.py | 284 ------------------------------------------ 2 files changed, 333 deletions(-) delete mode 100644 src/gui/tasks/table/menu.py delete mode 100644 src/gui/tasks/table/widget.py (limited to 'src/gui/tasks/table') diff --git a/src/gui/tasks/table/menu.py b/src/gui/tasks/table/menu.py deleted file mode 100644 index 5356be2..0000000 --- a/src/gui/tasks/table/menu.py +++ /dev/null @@ -1,49 +0,0 @@ -from PyQt5 import QtWidgets, QtCore -from typing import List - -import db.tasks -import gui.tasks.dialog -from model.status import Status -from model.task import Task, ValidTaskForm -from model.tag import Tag - -def open(table: QtWidgets.QTableWidget, status: Status, update_task_signal, position): - rows = set([index.row() for index in table.selectedIndexes()]) - - menu = QtWidgets.QMenu(table) - - if len(rows) == 1: - modify_action = menu.addAction(gui.icon.dialog_open(menu.style()), "modify") - else: - modify_action = QtWidgets.QAction(menu) - - delete_action = menu.addAction(gui.icon.trash(menu.style()), "delete") - - if status != Status.READY: - move_to_ready = menu.addAction(gui.icon.task_ready(menu.style()), "move to ready") - else: - move_to_ready = QtWidgets.QAction(menu) - - if status != Status.WAITING: - move_to_waiting = menu.addAction(gui.icon.task_waiting(menu.style()), "move to waiting") - else: - move_to_waiting = QtWidgets.QAction(menu) - - if status != Status.MAYBE: - move_to_maybe = menu.addAction(gui.icon.task_maybe(menu.style()), "move to maybe") - else: - move_to_maybe = QtWidgets.QAction(menu) - - action = menu.exec_(table.mapToGlobal(position + QtCore.QPoint(15, 20))) - if action == modify_action and len(rows) == 1: - row = list(rows)[0] - (task, tags) = table.get_at(row) - gui.tasks.dialog.update(table, update_task_signal, row, task, tags).exec_() - elif action == delete_action: - gui.tasks.dialog.confirm_delete(table, rows, lambda: table.delete_rows(rows)) - elif action == move_to_ready: - gui.tasks.dialog.confirm_move(table, rows, Status.READY, lambda: table.update_status(rows, Status.READY)) - elif action == move_to_waiting: - gui.tasks.dialog.confirm_move(table, rows, Status.WAITING, lambda: table.update_status(rows, Status.WAITING)) - elif action == move_to_maybe: - gui.tasks.dialog.confirm_move(table, rows, Status.MAYBE, lambda: table.update_status(rows, Status.MAYBE)) diff --git a/src/gui/tasks/table/widget.py b/src/gui/tasks/table/widget.py deleted file mode 100644 index aacae2f..0000000 --- a/src/gui/tasks/table/widget.py +++ /dev/null @@ -1,284 +0,0 @@ -from PyQt5 import QtWidgets, QtCore, QtGui -from PyQt5.QtCore import Qt -from typing import List, Tuple -import time -import math - -from model import difficulty, priority -from model.difficulty import Difficulty -from model.priority import Priority -from model.tag import Tag -from model.task import Task -from model.task_tag import TaskTag -from model.status import Status -import database -import db.tags -import db.task_tags -import gui.color -import gui.signal -import gui.tasks.dialog -import gui.tasks.duration -import gui.tasks.signal -import gui.tasks.signal -import gui.tasks.table.menu -import service.tasks -import util.array -import util.range - -class Widget(QtWidgets.QTableWidget): - def __init__( - self, - parent, - on_show: gui.signal.Reload, - add_task_signal: gui.tasks.signal.AddTask, - status: Status): - super().__init__(parent) - - self.init_state(status) - self.sort() - - self.setSelectionBehavior(QtWidgets.QTableView.SelectRows) - self.init_header() - self.setRowCount(len(self._tasks)) - self.setColumnCount(len(self.header_labels())) - self.setColumnWidth(1, 500) - - self.update_view() - self.horizontalHeader().setStretchLastSection(True) - - # Menu - self.setContextMenuPolicy(Qt.CustomContextMenu) - self.customContextMenuRequested.connect(lambda position: gui.tasks.table.menu.open(self, status, self._update_task_signal, position)) - - self.doubleClicked.connect(lambda index: self.on_double_click(index.row())) - add_task_signal.connect(lambda task, tags: self.insert(task, tags)) - self._update_task_signal.connect(lambda row, task, tags: self.update_task(row, task, tags)) - on_show.connect(lambda: self.on_show()) - - def init_state(self, status: Status): - self._update_task_signal = gui.tasks.signal.UpdateTask() - cursor = database.cursor() - self._status = status - self._tasks = service.tasks.get(cursor, self._status) - self._task_tags = db.task_tags.get(cursor) - self._tags = db.tags.get(cursor) - self._sort_column = 0 - self._sort_is_ascending = True - - def init_header(self): - self._header_view = QtWidgets.QHeaderView(Qt.Horizontal, self) - self._header_model = QtGui.QStandardItemModel() - self._header_model.setHorizontalHeaderLabels(self.header_labels()) - self._header_view.setModel(self._header_model) - self._header_view.setSectionsClickable(True) - self._header_view.sectionClicked.connect(self.on_header_click) - self.setHorizontalHeader(self._header_view) - - def on_show(self): - cursor = database.cursor() - self._tasks = service.tasks.get(cursor, self._status) - self._task_tags = db.task_tags.get(cursor) - self._tags = db.tags.get(cursor) - self.setRowCount(len(self._tasks)) - self.sort() - self.update_view() - - def on_header_click(self, column): - if self._sort_column == column: - self._sort_is_ascending = not self._sort_is_ascending - else: - self._sort_is_ascending = True - self._sort_column = column - self.sort() - self._header_model.setHorizontalHeaderLabels(self.header_labels()) - self.update_view() - - def sort(self): - is_rev = self.is_reversed() - self._tasks = sorted( - self._tasks, - key = lambda task: self.sort_key(task, is_rev), - reverse = is_rev) - - def update_task(self, row, task: Task, tags: List[int]): - self._tasks[row] = task - filtred_task_tags = [tt for tt in self._task_tags if tt.task_id in [t.id for t in self._tasks if t.id != task.id]] - new_task_tags = [TaskTag(task_id=task.id, tag_id=tag_id) for tag_id in tags] - self._task_tags = filtred_task_tags + new_task_tags - - # Update task in table - self.sort() - row_after_sort = [i for i in range(len(self._tasks)) if self._tasks[i].id == task.id][0] - if row_after_sort == row: - self.update_row(row) - else: - self.removeRow(row) - self.insertRow(row_after_sort) - self.update_row(row_after_sort) - self.selectRow(row_after_sort) - - def update_view(self): - for row in range(len(self._tasks)): - self.update_row(row) - - def update_row(self, row: int): - task = self._tasks[row] - self.setItem(row, 0, item(age_since(task.created_at))) - self.setItem(row, 1, item(task.name)) - self.setCellWidget(row, 2, colored_label(self, gui.tasks.duration.format(task.duration), gui.tasks.duration.color(task.duration))) - self.setCellWidget(row, 3, colored_label(self, difficulty.format(task.difficulty), difficulty_color(task.difficulty))) - self.setCellWidget(row, 4, colored_label(self, priority.format(task.priority), priority_color(task.priority))) - tag_ids = [tt.tag_id for tt in self._task_tags if tt.task_id == task.id] - res_tags = sorted([tag for tag in self._tags if tag.id in tag_ids], key=lambda t: t.name) - self.setCellWidget(row, 5, render_tags(self, res_tags)) - self.setRowHeight(row, 45) - - def insert(self, task: Task, tags: List[int]) -> int: - is_rev = self.is_reversed() - row = util.array.insert_position( - self.sort_key(task, is_rev), - [self.sort_key(t, is_rev) for t in self._tasks], - is_rev) - self._tasks.insert(row, task) - self._task_tags += [TaskTag(task_id=task.id, tag_id=tag_id) for tag_id in tags] - self.insertRow(row) - self.update_row(row) - self._task_tags += [TaskTag(task_id=task.id, tag_id=tag_id) for tag_id in tags] - self.setRowCount(len(self._tasks)) - return row - - def is_reversed(self) -> bool: - if self._sort_column == 0: - return self._sort_is_ascending - else: - return not self._sort_is_ascending - - def sort_key(self, task: Task, is_reversed: bool): - row = self._sort_column - if row == 0: - return task.created_at - elif row == 1: - return task.name.lower() - elif row == 2: - if is_reversed: - return task.duration - else: - return (task.duration == 0, task.duration) - elif row == 3: - return task.difficulty - elif row == 4: - return task.priority - elif row == 5: - tag_ids = [tt.tag_id for tt in self._task_tags if tt.task_id == task.id] - tags = sorted([tag.name.lower() for tag in self._tags if tag.id in tag_ids]) - key = "".join(tags) - if is_reversed: - return key - else: - return (key == "", key) - - 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] - (task, tags) = self.get_at(row) - gui.tasks.dialog.update(self, self._update_task_signal, row, task, tags).exec_() - elif event.key() == Qt.Key_Delete: - rows = self.get_selected_rows() - gui.tasks.dialog.show_delete(self, rows, lambda: self.delete_rows(rows)) - - def delete_rows(self, rows: List[int]): - task_ids = [task.id for i, task in enumerate(self._tasks) if i in rows] - service.tasks.delete(database.cursor(), task_ids) - self.remove_rows_from_table(rows, task_ids) - - def update_status(self, rows: List[int], status: Status): - task_ids = [task.id for i, task in enumerate(self._tasks) if i in rows] - service.tasks.update_status(database.cursor(), task_ids, status) - self.remove_rows_from_table(rows, task_ids) - - def remove_rows_from_table(self, rows: List[int], task_ids: List[int]): - for row in sorted(rows, reverse=True): - self.removeRow(row) - self._tasks = [t for t in self._tasks if t.id not in task_ids] - self._task_tags = [tt for tt in self._task_tags if tt.task_id in [t.id for t in self._tasks]] - self.setRowCount(len(self._tasks)) - - def get_selected_rows(self): - return list(set([index.row() for index in self.selectedIndexes()])) - - def on_double_click(self, row: int): - (task, tags) = self.get_at(row) - gui.tasks.dialog.update(self, self._update_task_signal, row, task, tags).exec_() - - def get_at(self, row: int) -> Tuple[Task, List[int]]: - task = self._tasks[row] - tags = [tt.tag_id for tt in self._task_tags if tt.task_id == task.id] - return (task, tags) - - def header_labels(self): - labels = ["Age", "Name", "Duration", "Difficulty", "Priority", "Tag"] - if self._sort_is_ascending: - sign = "▼" - else: - sign = "▲" - labels[self._sort_column] = labels[self._sort_column] + " " + sign - return labels - -def item(text: str): - item = QtWidgets.QTableWidgetItem(text) - item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) - return item - -def age_since(timestamp): - diff = int(time.time()) - timestamp - if diff >= 60 * 60 * 24: - return "" + str(math.floor(diff / 60 / 60 / 24)) + "d" - elif diff >= 60 * 60: - return "" + str(math.floor(diff / 60 / 60)) + "h" - elif diff >= 60: - return "" + str(math.floor(diff / 60)) + "m" - else: - return "1m" - -def colored_label(parent, text: str, color: QtGui.QColor): - label = QtWidgets.QLabel(text) - palette = QtGui.QPalette() - palette.setColor(QtGui.QPalette.Text, color) - label.setPalette(palette) - return label - -def render_tags(parent, tags: List[Tag]): - widget = QtWidgets.QWidget(parent) - - layout = QtWidgets.QHBoxLayout(widget) - widget.setLayout(layout) - - for tag in tags: - label = QtWidgets.QLabel(tag.name) - label.setContentsMargins(3, 3, 3, 3) - palette = QtGui.QPalette() - palette.setColor(QtGui.QPalette.Base, QtGui.QColor(tag.color)) - label.setAutoFillBackground(True) - label.setPalette(palette) - layout.addWidget(label) - - return widget - -def difficulty_color(d: Difficulty) -> QtGui.QColor: - if d == Difficulty.EASY: - return gui.color.easy_difficulty - elif d == Difficulty.NORMAL: - return gui.color.normal_difficulty - elif d == Difficulty.HARD: - return gui.color.hard_difficulty - -def priority_color(p: Priority) -> QtGui.QColor: - if p == Priority.LOW: - return gui.color.low_priority - elif p == Priority.MIDDLE: - return gui.color.middle_priority - elif p == Priority.HIGH: - return gui.color.high_priority -- cgit v1.2.3