From 57614cefa1a53d17f8d66e87d7a9142295699e77 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 11 Dec 2025 15:45:03 +1100 Subject: [PATCH] Add 'Change Date' button to the History Dialog (same as the one used in Time log dialogs) --- CHANGELOG.md | 1 + bouquin/history_dialog.py | 68 +++++++++++++++++++++++++++++++++++++-- bouquin/locales/en.json | 8 ++--- bouquin/main_window.py | 2 +- bouquin/time_log.py | 12 +++---- 5 files changed, 78 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26e9853..76b8115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * New Invoicing feature! This is tied to time logging and (optionally) documents and reminders features. * Add 'Last week' to Time Report dialog range option + * Add 'Change Date' button to the History Dialog (same as the one used in Time log dialogs) # 0.6.4 diff --git a/bouquin/history_dialog.py b/bouquin/history_dialog.py index 5966470..c145cce 100644 --- a/bouquin/history_dialog.py +++ b/bouquin/history_dialog.py @@ -5,11 +5,14 @@ import html as _html import re from datetime import datetime -from PySide6.QtCore import Qt, Slot +from PySide6.QtCore import QDate, Qt, Slot from PySide6.QtWidgets import ( QAbstractItemView, + QCalendarWidget, QDialog, + QDialogButtonBox, QHBoxLayout, + QLabel, QListWidget, QListWidgetItem, QMessageBox, @@ -20,6 +23,7 @@ from PySide6.QtWidgets import ( ) from . import strings +from .theme import ThemeManager def _markdown_to_text(s: str) -> str: @@ -73,16 +77,29 @@ def _colored_unified_diff_html(old_md: str, new_md: str) -> str: class HistoryDialog(QDialog): """Show versions for a date, preview, diff, and allow revert.""" - def __init__(self, db, date_iso: str, parent=None): + def __init__( + self, db, date_iso: str, parent=None, themes: ThemeManager | None = None + ): super().__init__(parent) self.setWindowTitle(f"{strings._('history')} — {date_iso}") self._db = db self._date = date_iso + self._themes = themes self._versions = [] # list[dict] from DB self._current_id = None # id of current root = QVBoxLayout(self) + # --- Top: date label + change-date button + date_row = QHBoxLayout() + self.date_label = QLabel(strings._("date_label").format(date=date_iso)) + date_row.addWidget(self.date_label) + date_row.addStretch(1) + self.change_date_btn = QPushButton(strings._("change_date")) + self.change_date_btn.clicked.connect(self._on_change_date_clicked) + date_row.addWidget(self.change_date_btn) + root.addLayout(date_row) + # Top: list of versions top = QHBoxLayout() self.list = QListWidget() @@ -120,6 +137,53 @@ class HistoryDialog(QDialog): self._load_versions() + @Slot() + def _on_change_date_clicked(self) -> None: + """Let the user choose a different date and reload entries.""" + + # Start from current dialog date; fall back to today if invalid + current_qdate = QDate.fromString(self._date, Qt.ISODate) + if not current_qdate.isValid(): + current_qdate = QDate.currentDate() + + dlg = QDialog(self) + dlg.setWindowTitle(strings._("select_date_title")) + + layout = QVBoxLayout(dlg) + + calendar = QCalendarWidget(dlg) + calendar.setSelectedDate(current_qdate) + layout.addWidget(calendar) + # Apply the same theming as the main sidebar calendar + if self._themes is not None: + self._themes.register_calendar(calendar) + + buttons = QDialogButtonBox( + QDialogButtonBox.Ok | QDialogButtonBox.Cancel, parent=dlg + ) + buttons.accepted.connect(dlg.accept) + buttons.rejected.connect(dlg.reject) + layout.addWidget(buttons) + + if dlg.exec() != QDialog.Accepted: + return + + new_qdate = calendar.selectedDate() + new_iso = new_qdate.toString(Qt.ISODate) + if new_iso == self._date: + # No change + return + + # Update state + self._date = new_iso + + # Update window title and header label + self.setWindowTitle(strings._("for").format(date=new_iso)) + self.date_label.setText(strings._("date_label").format(date=new_iso)) + + # Reload entries for the newly selected date + self._load_versions() + # --- Data/UX helpers --- def _load_versions(self): # [{id,version_no,created_at,note,is_current}] diff --git a/bouquin/locales/en.json b/bouquin/locales/en.json index dbd8330..332f13d 100644 --- a/bouquin/locales/en.json +++ b/bouquin/locales/en.json @@ -251,10 +251,10 @@ "select_project_title": "Select project", "time_log": "Time log", "time_log_collapsed_hint": "Time log", - "time_log_date_label": "Time log date: {date}", - "time_log_change_date": "Change date", - "time_log_select_date_title": "Select time log date", - "time_log_for": "Time log for {date}", + "date_label": "Date: {date}", + "change_date": "Change date", + "select_date_title": "Select date", + "for": "For {date}", "time_log_no_date": "Time log", "time_log_no_entries": "No time entries yet", "time_log_report": "Time log report", diff --git a/bouquin/main_window.py b/bouquin/main_window.py index 2def58e..44b9f50 100644 --- a/bouquin/main_window.py +++ b/bouquin/main_window.py @@ -1354,7 +1354,7 @@ class MainWindow(QMainWindow): else: date_iso = self._current_date_iso() - dlg = HistoryDialog(self.db, date_iso, self) + dlg = HistoryDialog(self.db, date_iso, self, themes=self.themes) if dlg.exec() == QDialog.Accepted: # refresh editor + calendar (head pointer may have changed) self._load_selected_date(date_iso) diff --git a/bouquin/time_log.py b/bouquin/time_log.py index 7ca4e09..1adf3c3 100644 --- a/bouquin/time_log.py +++ b/bouquin/time_log.py @@ -277,7 +277,7 @@ class TimeLogDialog(QDialog): self.close_after_add = close_after_add - self.setWindowTitle(strings._("time_log_for").format(date=date_iso)) + self.setWindowTitle(strings._("for").format(date=date_iso)) self.resize(900, 600) root = QVBoxLayout(self) @@ -285,12 +285,12 @@ class TimeLogDialog(QDialog): # --- Top: date label + change-date button date_row = QHBoxLayout() - self.date_label = QLabel(strings._("time_log_date_label").format(date=date_iso)) + self.date_label = QLabel(strings._("date_label").format(date=date_iso)) date_row.addWidget(self.date_label) date_row.addStretch(1) - self.change_date_btn = QPushButton(strings._("time_log_change_date")) + self.change_date_btn = QPushButton(strings._("change_date")) self.change_date_btn.clicked.connect(self._on_change_date_clicked) date_row.addWidget(self.change_date_btn) @@ -477,7 +477,7 @@ class TimeLogDialog(QDialog): current_qdate = QDate.currentDate() dlg = QDialog(self) - dlg.setWindowTitle(strings._("time_log_select_date_title")) + dlg.setWindowTitle(strings._("select_date_title")) layout = QVBoxLayout(dlg) @@ -508,8 +508,8 @@ class TimeLogDialog(QDialog): self._date_iso = new_iso # Update window title and header label - self.setWindowTitle(strings._("time_log_for").format(date=new_iso)) - self.date_label.setText(strings._("time_log_date_label").format(date=new_iso)) + self.setWindowTitle(strings._("for").format(date=new_iso)) + self.date_label.setText(strings._("date_label").format(date=new_iso)) # Reload entries for the newly selected date self._reload_entries()