diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ea07c2..f9290ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,3 @@ -# 0.4.2 - - * Improve Statistics widget height - * Improve SaveDialog widget width - * Make Tags and TimeLog optional features that can be switched on/off in Settings (enabled by default) - # 0.4.1 * Allow time log entries to be edited directly in their table cells diff --git a/bouquin/db.py b/bouquin/db.py index 3e2886b..c6846e9 100644 --- a/bouquin/db.py +++ b/bouquin/db.py @@ -61,8 +61,6 @@ class DBConfig: idle_minutes: int = 15 # 0 = never lock theme: str = "system" move_todos: bool = False - tags: bool = True - time_log: bool = True locale: str = "en" diff --git a/bouquin/locales/en.json b/bouquin/locales/en.json index e367254..9b70cfd 100644 --- a/bouquin/locales/en.json +++ b/bouquin/locales/en.json @@ -238,7 +238,5 @@ "export_csv_error_message": "Could not write CSV file:\n{error}", "export_pdf": "Export PDF", "export_pdf_error_title": "PDF export failed", - "export_pdf_error_message": "Could not write PDF file:\n{error}", - "enable_tags_feature": "Enable Tags", - "enable_time_log_feature": "Enable Time Logging" + "export_pdf_error_message": "Could not write PDF file:\n{error}" } diff --git a/bouquin/main_window.py b/bouquin/main_window.py index 97e5ccf..b5dab36 100644 --- a/bouquin/main_window.py +++ b/bouquin/main_window.py @@ -66,7 +66,7 @@ from .statistics_dialog import StatisticsDialog from . import strings from .tags_widget import PageTagsWidget from .theme import ThemeManager -from .time_log import TimeLogWidget +from .time_log import TimeLogWidget, TimeReportDialog from .toolbar import ToolBar @@ -219,10 +219,18 @@ class MainWindow(QMainWindow): act_backup.setShortcut("Ctrl+Shift+B") act_backup.triggered.connect(self._backup) file_menu.addAction(act_backup) + act_tags = QAction(strings._("main_window_manage_tags_accessible_flag"), self) + act_tags.setShortcut("Ctrl+T") + act_tags.triggered.connect(self.tags._open_manager) + file_menu.addAction(act_tags) act_stats = QAction(strings._("main_window_statistics_accessible_flag"), self) act_stats.setShortcut("Shift+Ctrl+S") act_stats.triggered.connect(self._open_statistics) file_menu.addAction(act_stats) + act_time_report = QAction(strings._("time_log_report"), self) + act_time_report.setShortcut("Ctrl+Shift+L") + act_time_report.triggered.connect(self._open_time_report) + file_menu.addAction(act_time_report) file_menu.addSeparator() act_quit = QAction("&" + strings._("quit"), self) act_quit.setShortcut("Ctrl+Q") @@ -312,12 +320,6 @@ class MainWindow(QMainWindow): self._load_selected_date() self._refresh_calendar_marks() - # Hide tags and time log widgets if not enabled - if not self.cfg.tags: - self.tags.hide() - if not self.cfg.time_log: - self.time_log.hide() - # Restore window position from settings self.settings = QSettings(APP_ORG, APP_NAME) self._restore_window_position() @@ -1318,12 +1320,11 @@ class MainWindow(QMainWindow): self.cfg.idle_minutes = getattr(new_cfg, "idle_minutes", self.cfg.idle_minutes) self.cfg.theme = getattr(new_cfg, "theme", self.cfg.theme) self.cfg.move_todos = getattr(new_cfg, "move_todos", self.cfg.move_todos) - self.cfg.tags = getattr(new_cfg, "tags", self.cfg.tags) - self.cfg.time_log = getattr(new_cfg, "time_log", self.cfg.time_log) self.cfg.locale = getattr(new_cfg, "locale", self.cfg.locale) # Persist once save_db_config(self.cfg) + # Apply idle setting immediately (restart the timer with new interval if it changed) self._apply_idle_minutes(self.cfg.idle_minutes) @@ -1340,13 +1341,6 @@ class MainWindow(QMainWindow): self._load_selected_date() self._refresh_calendar_marks() - # Show or hide the tags and time_log features depending on what the settings are now. - self.tags.hide() if not self.cfg.tags else self.tags.show() - if not self.cfg.time_log: - self.time_log.hide() - else: - self.time_log.show() - # ------------ Statistics handler --------------- # def _open_statistics(self): @@ -1364,6 +1358,11 @@ class MainWindow(QMainWindow): dlg._heatmap.date_clicked.connect(on_date_clicked) dlg.exec() + # ------------ Timesheet report handler --------------- # + def _open_time_report(self): + dlg = TimeReportDialog(self.db, self) + dlg.exec() + # ------------ Window positioning --------------- # def _restore_window_position(self): geom = self.settings.value("main/geometry", None) diff --git a/bouquin/save_dialog.py b/bouquin/save_dialog.py index 6b4e05d..bc40cc7 100644 --- a/bouquin/save_dialog.py +++ b/bouquin/save_dialog.py @@ -2,7 +2,6 @@ from __future__ import annotations import datetime -from PySide6.QtGui import QFontMetrics from PySide6.QtWidgets import ( QDialog, QVBoxLayout, @@ -23,24 +22,13 @@ class SaveDialog(QDialog): Used for explicitly saving a new version of a page. """ super().__init__(parent) - self.setWindowTitle(strings._("enter_a_name_for_this_version")) - v = QVBoxLayout(self) v.addWidget(QLabel(strings._("enter_a_name_for_this_version"))) - self.note = QLineEdit() now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - text = strings._("new_version_i_saved_at") + f" {now}" - self.note.setText(text) + self.note.setText(strings._("new_version_i_saved_at") + f" {now}") v.addWidget(self.note) - - # make dialog wide enough for the line edit text - fm = QFontMetrics(self.note.font()) - text_width = fm.horizontalAdvance(text) + 20 - self.note.setMinimumWidth(text_width) - self.adjustSize() - bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) diff --git a/bouquin/settings.py b/bouquin/settings.py index 5a52f18..6578237 100644 --- a/bouquin/settings.py +++ b/bouquin/settings.py @@ -41,8 +41,6 @@ def load_db_config() -> DBConfig: idle = s.value("ui/idle_minutes", 15, type=int) theme = s.value("ui/theme", "system", type=str) move_todos = s.value("ui/move_todos", False, type=bool) - tags = s.value("ui/tags", True, type=bool) - time_log = s.value("ui/time_log", True, type=bool) locale = s.value("ui/locale", "en", type=str) return DBConfig( path=path, @@ -50,8 +48,6 @@ def load_db_config() -> DBConfig: idle_minutes=idle, theme=theme, move_todos=move_todos, - tags=tags, - time_log=time_log, locale=locale, ) @@ -63,6 +59,4 @@ def save_db_config(cfg: DBConfig) -> None: s.setValue("ui/idle_minutes", str(cfg.idle_minutes)) s.setValue("ui/theme", str(cfg.theme)) s.setValue("ui/move_todos", str(cfg.move_todos)) - s.setValue("ui/tags", str(cfg.tags)) - s.setValue("ui/time_log", str(cfg.time_log)) s.setValue("ui/locale", str(cfg.locale)) diff --git a/bouquin/settings_dialog.py b/bouquin/settings_dialog.py index 47209ba..7a9c73a 100644 --- a/bouquin/settings_dialog.py +++ b/bouquin/settings_dialog.py @@ -98,26 +98,13 @@ class SettingsDialog(QDialog): behaviour_group = QGroupBox(strings._("behaviour")) behaviour_layout = QVBoxLayout(behaviour_group) - # Checkbox moving self.move_todos = QCheckBox( strings._("move_yesterdays_unchecked_todos_to_today_on_startup") ) self.move_todos.setChecked(self.current_settings.move_todos) self.move_todos.setCursor(Qt.PointingHandCursor) + behaviour_layout.addWidget(self.move_todos) - - # Tags - self.tags = QCheckBox(strings._("enable_tags_feature")) - self.tags.setChecked(self.current_settings.tags) - self.tags.setCursor(Qt.PointingHandCursor) - behaviour_layout.addWidget(self.tags) - - # Time logging - self.time_log = QCheckBox(strings._("enable_time_log_feature")) - self.time_log.setChecked(self.current_settings.time_log) - self.time_log.setCursor(Qt.PointingHandCursor) - behaviour_layout.addWidget(self.time_log) - form.addRow(behaviour_group) # Encryption settings @@ -249,8 +236,6 @@ class SettingsDialog(QDialog): idle_minutes=self.idle_spin.value(), theme=selected_theme.value, move_todos=self.move_todos.isChecked(), - tags=self.tags.isChecked(), - time_log=self.time_log.isChecked(), locale=self.locale_combobox.currentText(), ) diff --git a/bouquin/statistics_dialog.py b/bouquin/statistics_dialog.py index 4d07680..7a644bd 100644 --- a/bouquin/statistics_dialog.py +++ b/bouquin/statistics_dialog.py @@ -98,7 +98,7 @@ class DateHeatmap(QWidget): def minimumSizeHint(self) -> QSize: sz = self.sizeHint() - return QSize(min(350, sz.width()), sz.height()) + return QSize(min(300, sz.width()), sz.height()) def paintEvent(self, event): super().paintEvent(event) @@ -249,7 +249,6 @@ class StatisticsDialog(QDialog): self.setWindowTitle(strings._("statistics")) self.setMinimumWidth(600) - self.setMinimumHeight(350) root = QVBoxLayout(self) ( diff --git a/tests/test_settings_dialog.py b/tests/test_settings_dialog.py index 50a5751..4301de4 100644 --- a/tests/test_settings_dialog.py +++ b/tests/test_settings_dialog.py @@ -20,8 +20,6 @@ def test_settings_dialog_config_roundtrip(qtbot, tmp_db_cfg, fresh_db): dlg.idle_spin.setValue(3) dlg.theme_light.setChecked(True) dlg.move_todos.setChecked(True) - dlg.tags.setChecked(False) - dlg.time_log.setChecked(False) # Auto-accept the modal QMessageBox that _compact_btn_clicked() shows def _auto_accept_msgbox(): @@ -36,9 +34,6 @@ def test_settings_dialog_config_roundtrip(qtbot, tmp_db_cfg, fresh_db): dlg._save() cfg = dlg.config assert cfg.idle_minutes == 3 - assert cfg.move_todos is True - assert cfg.tags is False - assert cfg.time_log is False assert cfg.theme in ("light", "dark", "system")