feat(bal): Group D / D1 - configurable distributed calendar reminders + save-only .ics
D1 - number of reminders (default 3, max 5):
- new NUM_REMINDERS config in plugin_base.py
- new BalSpinBox widget bound to a BalConfig
- new pure helper compute_reminder_offsets(days, count): reminders spread
uniformly across the check-alive period, always before the deadline
(offset >= 1), at most one per available day, de-duplicated, earliest
first (e.g. (30,3)->[30,16,1], (2,3)->[2,1], (1,3)->[1], (0,3)->[])
- create_alarms() rewritten to use it and emit one VALARM per offset with a
DESCRIPTION reminder text
- 'Number of reminders' spin box (range 1..5) added to the settings dialog
and to the Reset list
D1b - save-only .ics (ask where, default to Desktop):
- BalCalendar.desktop_dir() helper (~/Desktop with home fallback)
- open_or_save_calendar() no longer opens the file with a calendar app; it
always shows a 'save as' dialog (.ics filter, default will_event.ics,
starting on the Desktop) and copies the file there, then confirms.
Identical behaviour on Windows/Linux/macOS. save_to_cwd -> save_ics_to.
Follow-up: removed the now-unused 'Calendar App' field from the settings
dialog (and from the Reset list). CALENDAR_APP config and
open_with_default_app left in place (unused) to avoid unrelated changes.
D2 intentionally skipped (per user request).
tests/test_group_d_alarms.py: 7 new tests (NUM_REMINDERS default/change and
all distribution rules). Full suite: 217 passed.
This commit is contained in:
@@ -30,6 +30,25 @@ class BalCalendar:
|
||||
_logger.error(f"starting calendar app {e}")
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def desktop_dir():
|
||||
"""Return the user's Desktop directory (Group D / D1b).
|
||||
|
||||
Used as the initial folder of the "save .ics" dialog. On Windows this is
|
||||
normally ``C:\\Users\\<name>\\Desktop``; on Linux/macOS ``~/Desktop`` is
|
||||
used when it exists. If the Desktop cannot be located the home directory
|
||||
is returned as a safe fallback, so the save dialog always opens
|
||||
somewhere sensible.
|
||||
|
||||
Returns:
|
||||
An absolute directory path (string).
|
||||
"""
|
||||
home = os.path.expanduser("~")
|
||||
desktop = os.path.join(home, "Desktop")
|
||||
if os.path.isdir(desktop):
|
||||
return desktop
|
||||
return home
|
||||
|
||||
|
||||
@staticmethod
|
||||
def format_time(time):
|
||||
|
||||
Reference in New Issue
Block a user