Skip to content
Snippets Groups Projects
Commit 0e3af8c6 authored by Caspar Martens's avatar Caspar Martens
Browse files

Fix Datetime observability

parent df16688d
Branches
Tags
No related merge requests found
......@@ -6,10 +6,10 @@ template DateTimeEditor : Box {
Box {
orientation: horizontal;
Entry _hour {
Entry _hour_entry {
input-purpose: digits;
tooltip-text: _("Hour digits");
changed => _on_hour_changed();
changed => _on_time_changed();
overwrite-mode: true;
xalign: 0.5;
valign: center;
......@@ -30,10 +30,10 @@ template DateTimeEditor : Box {
]
}
Entry _minute {
Entry _minute_entry {
input-purpose: digits;
tooltip-text: _("Minute digits");
changed => _on_minute_changed();
changed => _on_time_changed();
overwrite-mode: true;
xalign: 0.5;
valign: center;
......@@ -54,10 +54,10 @@ template DateTimeEditor : Box {
]
}
Entry _second {
Entry _second_entry {
input-purpose: digits;
tooltip-text: _("Second digits");
changed => _on_second_changed();
changed => _on_time_changed();
overwrite-mode: true;
xalign: 0.5;
valign: center;
......
......@@ -23,9 +23,9 @@ class DateTimeEditor(Gtk.Box):
__gtype_name__ = 'DateTimeEditor'
_date_chooser: Gtk.Calendar = Gtk.Template.Child()
_hour: Gtk.Text = Gtk.Template.Child()
_minute: Gtk.Text = Gtk.Template.Child()
_second: Gtk.Text = Gtk.Template.Child()
_hour_entry: Gtk.Entry = Gtk.Template.Child()
_minute_entry: Gtk.Entry = Gtk.Template.Child()
_second_entry: Gtk.Entry = Gtk.Template.Child()
def __init__(self, view_model: DateTimeViewModel):
super().__init__()
......@@ -33,13 +33,15 @@ class DateTimeEditor(Gtk.Box):
self._view_model.bind(changed=self.update_date_time)
self._date_chooser.connect('day-selected', self._on_day_selected)
self.update_date_time(self, self._view_model.date_time)
self._enable_time_change_listener = True
self.hour = self._view_model.date_time.hour
self.minute = self._view_model.date_time.minute
self.second = self._view_model.date_time.second
self.update_date_time()
def update_date_time(self, unused_sender, unused_notification: ChangeNotification):
def update_date_time(
self,
unused_sender=None,
unused_notification: ChangeNotification = None,
):
date_time = self._view_model.date_time
time_zone = GLib.TimeZone.new(date_time.tzname())
g_date_time = GLib.DateTime.new(
......@@ -51,49 +53,68 @@ class DateTimeEditor(Gtk.Box):
date_time.minute,
date_time.second
)
self._enable_time_change_listener = False
self._date_chooser.select_day(g_date_time)
self.hour = date_time.hour
self.minute = date_time.minute
self.second = date_time.second
self._enable_time_change_listener = True
@property
def hour(self) -> int:
return self._hour.get_text()
@hour.setter
def hour(self, value):
text = self._hour_entry.get_text()
digits_string = ''.join([i for i in text if i in '0123456789'])
value = int(digits_string or 0)
if value > 23:
value = 23
self._hour.set_text(str(value))
self._view_model.date_time = self._view_model.date_time.replace(hour=value)
if value < 0:
value = 0
return value
@hour.setter
def hour(self, value: int):
self._hour_entry.set_text(str(value).zfill(2))
@property
def minute(self) -> int:
return self._minute.get_text()
@minute.setter
def minute(self, value):
text = self._minute_entry.get_text()
digits_string = ''.join([i for i in text if i in '0123456789'])
value = int(digits_string or 0)
if value > 59:
value = 59
self._minute.set_text(str(value))
self._view_model.date_time = self._view_model.date_time.replace(minute=value)
if value < 0:
value = 0
return value
@minute.setter
def minute(self, value: int):
self._minute_entry.set_text(str(value).zfill(2))
@property
def second(self) -> int:
return self._second.get_text()
@second.setter
def second(self, value):
text = self._second_entry.get_text()
digits_string = ''.join([i for i in text if i in '0123456789'])
value = int(digits_string or 0)
if value > 59:
value = 59
self._second.set_text(str(value))
self._view_model.date_time = self._view_model.date_time.replace(second=value)
if value < 0:
value = 0
return value
@second.setter
def second(self, value: int):
self._second_entry.set_text(str(value).zfill(2))
def _on_day_selected(self, unused_widget):
date_time: GLib.DateTime = self._date_chooser.get_date()
picked_date = self._view_model.date_time.replace(
date_time.get_year(),
date_time.get_month(),
date_time.get_day_of_month()
)
if not self._view_model.date_time == picked_date:
if self._enable_time_change_listener:
date_time: GLib.DateTime = self._date_chooser.get_date()
picked_date = self._view_model.date_time.replace(
date_time.get_year(),
date_time.get_month(),
date_time.get_day_of_month()
)
self._view_model.date_time = picked_date
@Gtk.Template.Callback()
......@@ -102,21 +123,15 @@ class DateTimeEditor(Gtk.Box):
if now.microsecond >= 500_000:
now = now.replace(second=now.second + 1)
self._view_model.date_time = now.replace(microsecond=0)
self._hour.set_text(str(now.hour).zfill(2))
self._minute.set_text(str(now.minute).zfill(2))
self._second.set_text(str(now.second).zfill(2))
@Gtk.Template.Callback()
def _on_hour_changed(self, unused_widget):
if not self._view_model.date_time.minute == self.hour and len(self._hour.get_text()) == 2:
self.hour = int(self.hour)
@Gtk.Template.Callback()
def _on_minute_changed(self, unused_widget):
if not self._view_model.date_time.minute == self.minute and len(self._minute.get_text()) == 2:
self.minute = int(self.minute)
@Gtk.Template.Callback()
def _on_second_changed(self, unused_widget):
if not self._view_model.date_time.second == self.second and len(self._second.get_text()) == 2:
self.second = int(self.second)
def _on_time_changed(self, unused_widget):
if self._enable_time_change_listener and \
len(self._second_entry.get_text()) == \
len(self._minute_entry.get_text()) == \
len(self._hour_entry.get_text()) == 2:
new = self._view_model.date_time.replace(
second=self.second,
minute=self.minute,
hour=self.hour)
self._view_model.date_time = new
......@@ -7,10 +7,10 @@
<object class="GtkBox">
<property name="orientation">horizontal</property>
<child>
<object class="GtkEntry" id="_hour">
<object class="GtkEntry" id="_hour_entry">
<property name="input-purpose">digits</property>
<property name="tooltip-text" translatable="true">Hour digits</property>
<signal name="changed" handler="_on_hour_changed"/>
<signal name="changed" handler="_on_time_changed"/>
<property name="overwrite-mode">true</property>
<property name="xalign">0.5</property>
<property name="valign">center</property>
......@@ -33,10 +33,10 @@
</object>
</child>
<child>
<object class="GtkEntry" id="_minute">
<object class="GtkEntry" id="_minute_entry">
<property name="input-purpose">digits</property>
<property name="tooltip-text" translatable="true">Minute digits</property>
<signal name="changed" handler="_on_minute_changed"/>
<signal name="changed" handler="_on_time_changed"/>
<property name="overwrite-mode">true</property>
<property name="xalign">0.5</property>
<property name="valign">center</property>
......@@ -59,10 +59,10 @@
</object>
</child>
<child>
<object class="GtkEntry" id="_second">
<object class="GtkEntry" id="_second_entry">
<property name="input-purpose">digits</property>
<property name="tooltip-text" translatable="true">Second digits</property>
<signal name="changed" handler="_on_second_changed"/>
<signal name="changed" handler="_on_time_changed"/>
<property name="overwrite-mode">true</property>
<property name="xalign">0.5</property>
<property name="valign">center</property>
......
......@@ -2,7 +2,8 @@
import logging
from datetime import datetime
from blackfennec.util.change_notification_dispatch_mixin import ChangeNotificationDispatchMixin
from blackfennec.util.change_notification_dispatch_mixin import \
ChangeNotificationDispatchMixin
from blackfennec.util.observable import Observable
from base.date_time.date_time import DateTime
from blackfennec.interpretation.interpretation import Interpretation
......@@ -21,14 +22,13 @@ class DateTimeViewModel(ChangeNotificationDispatchMixin):
interpretation
"""
super().__init__()
self._interpretation = interpretation
self._model: DateTime = DateTime(interpretation.structure)
self._model.bind(changed=self._dispatch_change_notification)
@property
def date_time(self) -> datetime:
"""Property for first name"""
return self._model.date_time
@date_time.setter
......
......@@ -22,44 +22,30 @@ def test_can_construct_date_time_editor(date_time_editor):
def test_get_hour(date_time_editor):
assert date_time_editor.hour == '00'
assert date_time_editor.hour == 0
def test_set_hour(date_time_editor):
date_time_editor._hour.set_text('12')
assert date_time_editor.hour == '12'
def test_set_hour_minimal(date_time_editor):
with pytest.raises(ValueError):
date_time_editor.hour = -1
assert date_time_editor.hour == '00'
date_time_editor._hour_entry.set_text('12')
assert date_time_editor.hour == 12
def test_set_hour_maximal(date_time_editor):
date_time_editor._hour.set_text('23')
assert date_time_editor.hour == '23'
date_time_editor._hour_entry.set_text('23')
assert date_time_editor.hour == 23
def test_set_hour_out_of_range(date_time_editor):
date_time_editor.hour = 24
assert date_time_editor.hour == '23'
assert date_time_editor.hour == 23
def test_get_minute(date_time_editor):
assert date_time_editor.minute == '00'
assert date_time_editor.minute == 0
def test_get_second(date_time_editor):
assert date_time_editor.second == '00'
def test_set_now(date_time_editor):
now = datetime.now()
date_time_editor._on_set_to_now(None)
assert int(date_time_editor.hour) == now.hour or int(date_time_editor.hour) == now.hour - 1
assert int(date_time_editor.minute) == now.minute or int(date_time_editor.minute) == now.minute - 1
assert now.second <= int(date_time_editor.second) <= now.second + 20
assert date_time_editor.second == 0
def test_update_date_time(date_time_editor, view_model):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment