diff options
author | Joris | 2020-06-06 17:44:26 +0200 |
---|---|---|
committer | Joris | 2020-06-06 19:54:03 +0200 |
commit | 1595e0de940a86a7810df0e02e43838d97c0d846 (patch) | |
tree | 9701eeec0d98baa9f6044b1911df68e4c8539819 /src/gui/tasks | |
parent | 6b9195000eb5404c247288b384d7ca2bacc1ab23 (diff) |
Provide nix build
Diffstat (limited to 'src/gui/tasks')
-rw-r--r-- | src/gui/tasks/dialog.py | 78 | ||||
-rw-r--r-- | src/gui/tasks/duration.py | 50 | ||||
-rw-r--r-- | src/gui/tasks/form/state.py | 100 | ||||
-rw-r--r-- | src/gui/tasks/form/widget.py | 184 | ||||
-rw-r--r-- | src/gui/tasks/signal.py | 28 | ||||
-rw-r--r-- | src/gui/tasks/table/menu.py | 49 | ||||
-rw-r--r-- | src/gui/tasks/table/widget.py | 284 | ||||
-rw-r--r-- | src/gui/tasks/test_duration.py | 21 | ||||
-rw-r--r-- | src/gui/tasks/widget.py | 30 |
9 files changed, 0 insertions, 824 deletions
diff --git a/src/gui/tasks/dialog.py b/src/gui/tasks/dialog.py deleted file mode 100644 index 2bf3b6b..0000000 --- a/src/gui/tasks/dialog.py +++ /dev/null @@ -1,78 +0,0 @@ -from PyQt5 import QtCore, QtWidgets -from typing import List - -from model.tag import Tag -from model.task import Task, ValidTaskForm -from model.status import Status -import database -import db.task_tags -import db.tasks -import gui.tasks.form.widget -import service.tasks - -def add(parent_widget, status: Status, add_task_signal): - - def on_add(task_form: ValidTaskForm): - task = service.tasks.create(database.cursor(), status, task_form) - add_task_signal.emit(task, task_form.tags) - - return widget(parent_widget, "Add a task", "add", None, [], on_add) - -def update(parent_widget, update_task_signal, row: int, task: Task, tags: List[int]): - - def on_update(task_form: ValidTaskForm): - updated_task = service.tasks.update(database.cursor(), task, task_form) - update_task_signal.emit(row, updated_task, task_form.tags) - - return widget(parent_widget, "Modify a task", "modify", task, tags, on_update) - -def confirm_delete(parent, rows: List[int], on_confirm): - confirm = QtWidgets.QMessageBox.question( - parent, - "Task deletion", - "Do you really want to delete the selected tasks ?", - QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes, - QtWidgets.QMessageBox.Yes) - - if confirm == QtWidgets.QMessageBox.Yes: - on_confirm() - -def confirm_move(parent, rows: List[int], move_to: Status, on_confirm): - confirm = QtWidgets.QMessageBox.question( - parent, - "Task move", - "Do you really want to move the selected tasks ?", - QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes, - QtWidgets.QMessageBox.Yes) - - if confirm == QtWidgets.QMessageBox.Yes: - on_confirm() - -def widget( - parent: QtWidgets.QWidget, - title: str, - action_title: str, - task: Task, - tags: List[int], - 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.tasks.form.widget.widget( - parent = dialog, - action_title = action_title, - task = task, - tags = tags, - on_validated = on_dialog_validated, - on_cancel = lambda: dialog.reject())) - - return dialog diff --git a/src/gui/tasks/duration.py b/src/gui/tasks/duration.py deleted file mode 100644 index dc948e6..0000000 --- a/src/gui/tasks/duration.py +++ /dev/null @@ -1,50 +0,0 @@ -from PyQt5 import QtGui -from typing import Optional -import math -import re - -import gui.color - -def format(minutes: int): - if minutes >= 60 * 24: - return "" + format_decimal(minutes / 60 / 24) + "d" - elif minutes >= 60: - return "" + format_decimal(minutes / 60) + "h" - elif minutes > 0: - return "" + str(minutes) + "m" - else: - return "" - -def format_decimal(d: float) -> str: - return "{0:.2g}".format(d) - -def parse(duration: str) -> Optional[int]: - duration = duration.strip() - if duration: - result = re.match("^(\d+)(\.(\d+))?([mhd])$", duration.strip()) - if result: - n = int(result.group(1)) - if result.group(3): - d = int(result.group(3)) * pow(10, -1 * len(result.group(3))) - else: - d = 0 - num = n + d - unit = result.group(4) - if unit == "m": - return math.floor(num) - elif unit == "h": - return math.floor(num * 60) - elif unit == "d": - return math.floor(num * 60 * 24) - else: - return None - else: - return 0 - -def color(minutes: int): - if minutes <= 15: - return gui.color.short_duration - elif minutes < 60: - return gui.color.medium_duration - else: - return gui.color.long_duration diff --git a/src/gui/tasks/form/state.py b/src/gui/tasks/form/state.py deleted file mode 100644 index 09e658e..0000000 --- a/src/gui/tasks/form/state.py +++ /dev/null @@ -1,100 +0,0 @@ -from PyQt5 import QtCore -from typing import Optional - -from model.task import ValidTaskForm -from model.difficulty import Difficulty -from model.priority import Priority -import gui.tasks.duration -import gui.tags.list - -class TaskFormEdition: - def __init__( - self, - name, - name_signal, - duration, - duration_signal, - difficulty, - difficulty_signal, - priority, - priority_signal, - tags_signal: gui.tags.list.SelectionSignal, - description, - description_signal): - - self._name = name - self._duration = duration - self._difficulty = difficulty - self._priority = priority - self._tags = [] - self._description = description - self._signal = ValidTaskFormSignal() - - name_signal.connect(lambda n: self.on_name_signal(n)) - duration_signal.connect(lambda d: self.on_duration_signal(d)) - difficulty_signal.connect(lambda d: self.on_difficulty_signal(d)) - priority_signal.connect(lambda p: self.on_priority_signal(p)) - tags_signal.connect(lambda ts: self.on_tags_signal(ts)) - description_signal.connect(lambda d: self.on_description_signal(d)) - - def get(self) -> Optional[ValidTaskForm]: - name = self._name.strip() - duration = gui.tasks.duration.parse(self._duration) - difficulty = self._difficulty - priority = self._priority - description = self._description.strip() - - if name and duration != None: - return ValidTaskForm( - name = name, - duration = duration, - difficulty = difficulty, - priority = priority, - tags = self._tags, - description = description) - else: - return None - - def on_name_signal(self, name: str): - self._name = name - self.emit() - - def on_duration_signal(self, duration: str): - self._duration = duration - self.emit() - - def on_difficulty_signal(self, index: int): - self._difficulty = Difficulty(index) - self.emit() - - def on_priority_signal(self, index: int): - self._priority = Priority(index) - self.emit() - - def on_tags_signal(self, tags: [int]): - self._tags = tags - self.emit() - - def on_description_signal(self, description: str): - self._description = description - self.emit() - - def emit(self): - validForm = self.get() - if validForm: - self._signal.emit(validForm) - - def signal(self): - return self._signal - -class ValidTaskFormSignal(QtCore.QObject): - _signal = QtCore.pyqtSignal(ValidTaskForm, name = "validTaskForm") - - def __init__(self): - QtCore.QObject.__init__(self) - - def emit(self, form: Optional[ValidTaskForm]): - self._signal.emit(form) - - def connect(self, f): - self._signal.connect(f) diff --git a/src/gui/tasks/form/widget.py b/src/gui/tasks/form/widget.py deleted file mode 100644 index 70d506d..0000000 --- a/src/gui/tasks/form/widget.py +++ /dev/null @@ -1,184 +0,0 @@ -from PyQt5 import QtWidgets, QtCore -from typing import Optional, Tuple, List, Any - -from model.task import Task, ValidTaskForm -from model.tag import Tag -from model import difficulty, priority -import gui.icon -import gui.tasks.form.state -import gui.tasks.duration -import gui.tags.list - -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) - - grid = QtWidgets.QWidget(widget) - layout.addWidget(grid) - grid_layout = QtWidgets.QGridLayout(grid) - grid.setLayout(grid_layout) - - init_name = task.name if task is not None else "" - name_input = line_edit(grid, grid_layout, 0, "Name", init_name) - - init_duration = gui.tasks.duration.format(task.duration) if task is not None else "" - duration_input = line_edit(grid, grid_layout, 1, "Duration", init_duration) - - init_difficulty = task.difficulty if task is not None else difficulty.Difficulty.NORMAL - difficulty_input = combo_box( - grid, - grid_layout, - 3, - "Difficulty", - [difficulty.format(d) for d in difficulty.values], - int(init_difficulty)) - - init_priority = task.priority if task is not None else priority.Priority.MIDDLE - priority_input = combo_box( - grid, - grid_layout, - 4, - "Priority", - [priority.format(d) for d in priority.values], - int(init_priority)) - - (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 = gui.tasks.form.state.TaskFormEdition( - init_name, - name_input.textChanged, - init_duration, - duration_input.textChanged, - init_difficulty, - difficulty_input.currentIndexChanged, - init_priority, - priority_input.currentIndexChanged, - 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 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 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 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 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.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("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/tasks/signal.py b/src/gui/tasks/signal.py deleted file mode 100644 index 074e8ec..0000000 --- a/src/gui/tasks/signal.py +++ /dev/null @@ -1,28 +0,0 @@ -from PyQt5 import QtCore -from typing import List - -from model.task import Task - -class AddTask(QtCore.QObject): - _signal = QtCore.pyqtSignal(Task, list, name = "addTask") - - def __init__(self): - QtCore.QObject.__init__(self) - - def emit(self, task: Task, tags: List[int]): - self._signal.emit(task, tags) - - def connect(self, f): - self._signal.connect(f) - -class UpdateTask(QtCore.QObject): - _signal = QtCore.pyqtSignal(int, Task, list, name = "updateTask") - - def __init__(self): - QtCore.QObject.__init__(self) - - def emit(self, row: int, task: Task, tags: List[int]): - self._signal.emit(row, task, tags) - - def connect(self, f): - self._signal.connect(f) 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 diff --git a/src/gui/tasks/test_duration.py b/src/gui/tasks/test_duration.py deleted file mode 100644 index 9d5d9b8..0000000 --- a/src/gui/tasks/test_duration.py +++ /dev/null @@ -1,21 +0,0 @@ -from gui.tasks.duration import format, parse - -def test_format(): - assert format(0) == "" - assert format(0.5) == "0.5m" - assert format(35) == "35m" - assert format(60) == "1h" - assert format(61) == "1h" - assert format(90) == "1.5h" - assert format(1440) == "1d" - -def test_parse(): - assert parse("") == 0 - assert parse("42") == None - assert parse("hey") == None - assert parse("1h30") == None - assert parse("1h30m") == None - assert parse("17m") == 17 - assert parse("90m") == 90 - assert parse("1.5h") == 90 - assert parse("2d") == 2880 diff --git a/src/gui/tasks/widget.py b/src/gui/tasks/widget.py deleted file mode 100644 index 87b15d3..0000000 --- a/src/gui/tasks/widget.py +++ /dev/null @@ -1,30 +0,0 @@ -from PyQt5 import QtWidgets - -from model.status import Status -import gui.tasks.signal -import gui.tasks.table.widget -import gui.icon -import gui.signal - -def widget(parent, on_show: gui.signal.Reload, status: Status): - widget = QtWidgets.QWidget(parent) - - layout = QtWidgets.QVBoxLayout(widget) - widget.setLayout(layout) - - layout.addSpacing(15) - - add_task_signal = gui.tasks.signal.AddTask() - - add_task_button = QtWidgets.QPushButton(" Add a task", widget) - add_task_button.setFixedHeight(30) - add_task_button.setIcon(gui.icon.new_folder(widget.style())) - add_task_button.clicked.connect(lambda: gui.tasks.dialog.add(widget, status, add_task_signal).exec_()) - layout.addWidget(add_task_button) - - layout.addSpacing(20) - - table = gui.tasks.table.widget.Widget(widget, on_show, add_task_signal, status) - layout.addWidget(table) - - return widget |