Skip to content

Commit

Permalink
Fix calendar selection for repeating tasks
Browse files Browse the repository at this point in the history
After selecting the desired day in the yearly calendar, the
_update_calendar method synced the monthly calendar, thus
triggering the _on_monthly_selected callback. The bug also worked
the other way around. Now, the _update_calendar blocks these
callbacks to prevent the issue.

Fixes GitHub issue #1015
  • Loading branch information
gycsaba96 committed Sep 8, 2024
1 parent a34e8db commit da69e70
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 44 deletions.
2 changes: 0 additions & 2 deletions GTG/gtk/data/recurring_menu.ui
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,11 @@
<!-- without, it covers the section heading -->
<property name="margin-top">6</property>
<property name="show-heading">False</property>
<signal name="day-selected" handler="_on_monthly_selected"/>
</object>
</child>
<child type="_year_calendar">
<object class="GtkCalendar" id="_year_calendar">
<property name="margin-top">6</property>
<signal name="day-selected" handler="_on_yearly_selected"/>
</object>
</child>
</template>
Expand Down
88 changes: 46 additions & 42 deletions GTG/gtk/editor/recurring_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from gettext import gettext as _
from datetime import datetime
from gi.repository import Gtk, Gio, GLib, GObject
from gi.repository.GObject import signal_handler_block
from GTG.core.dirs import UI_DIR


Expand Down Expand Up @@ -66,6 +67,9 @@ def __init__(self, editor, task):

self._is_header_menu_item_shown = False

self._mhandler = self._month_calendar.connect('day-selected',self._on_monthly_selected)
self._yhandler = self._year_calendar.connect('day-selected',self._on_yearly_selected)

self._update_header()
self._update_calendar()

Expand Down Expand Up @@ -200,47 +204,49 @@ def _update_calendar(self, update_monthly=True, update_yearly=True):
Update the calendar widgets with the correct date of the recurring
task, if set.
"""
self._month_calendar.set_property('month', 0)
if self._is_term_set():
need_month_hack = False
if self._selected_recurring_term in ('month', 'year'):
# Recurring monthly/yearly from 'today'
d = self.task.recurring_updated_date.date()
need_month_hack = self._set_selected_term == 'month'
elif self._selected_recurring_term.isdigit():
if len(self._selected_recurring_term) <= 2:
# Recurring monthly from selected date
d = datetime.strptime(f'{self._selected_recurring_term}', '%d')
need_month_hack = True
else:
# Recurring yearly from selected date
val = f'{self._selected_recurring_term[:2:]}-{self._selected_recurring_term[2::]}'
d = datetime.strptime(val, '%m-%d')
m_cal, y_cal = self._month_calendar, self._year_calendar
with signal_handler_block(m_cal, self._mhandler), signal_handler_block(y_cal, self._yhandler):
self._month_calendar.set_property('month', 0)
if self._is_term_set():
need_month_hack = False
if self._selected_recurring_term in ('month', 'year'):
# Recurring monthly/yearly from 'today'
d = self.task.recurring_updated_date.date()
need_month_hack = self._set_selected_term == 'month'
elif self._selected_recurring_term.isdigit():
if len(self._selected_recurring_term) <= 2:
# Recurring monthly from selected date
d = datetime.strptime(f'{self._selected_recurring_term}', '%d')
need_month_hack = True
else:
# Recurring yearly from selected date
val = f'{self._selected_recurring_term[:2:]}-{self._selected_recurring_term[2::]}'
d = datetime.strptime(val, '%m-%d')

d = d.replace(year=datetime.today().year) # Don't be stuck at 1900

d = d.replace(year=datetime.today().year) # Don't be stuck at 1900

else:
return

if update_monthly:
self._month_calendar.set_property('day', d.day)
if need_month_hack:
# Don't show that we're secretly staying on January since it has
# 31 days
month = datetime.today().month
year = datetime.today().year
while True:
try:
d = d.replace(month=month, year=year)
break
except ValueError: # day is out of range for month
month += 1
if month == 13:
month = 1
year += 1
if update_yearly:
gtime = GLib.DateTime.new_local(d.year, d.month, d.day, 0, 0, 0)
self._year_calendar.select_day(gtime)
else:
return

if update_monthly:
self._month_calendar.set_property('day', d.day)
if need_month_hack:
# Don't show that we're secretly staying on January since it has
# 31 days
month = datetime.today().month
year = datetime.today().year
while True:
try:
d = d.replace(month=month, year=year)
break
except ValueError: # day is out of range for month
month += 1
if month == 13:
month = 1
year += 1
if update_yearly:
gtime = GLib.DateTime.new_local(d.year, d.month, d.day, 0, 0, 0)
self._year_calendar.select_day(gtime)

def _on_recurr_every_day(self, widget, action_name, param: None):
self._set_selected_term('day')
Expand All @@ -267,12 +273,10 @@ def _on_recurr_year_today(self, widget, action_name, param: None):
self._set_selected_term('year')
self.set_property('is-task-recurring', True)

@Gtk.Template.Callback()
def _on_monthly_selected(self, widget):
self._set_selected_term(str(self._month_calendar.props.day))
self.set_property('is-task-recurring', True)

@Gtk.Template.Callback()
def _on_yearly_selected(self, widget):
date_string = self._year_calendar.get_date().format(
r'%m%d'
Expand Down

0 comments on commit da69e70

Please sign in to comment.