3
# Copyright (C) 2008-2009 Toms Bauģis <toms.baugis at gmail.com>
5
# This file is part of Project Hamster.
7
# Project Hamster is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
12
# Project Hamster is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with Project Hamster. If not, see <http://www.gnu.org/licenses/>.
20
from .hamster.stuff import format_duration
27
class DateInput(gtk.Entry):
28
""" a text entry widget with calendar popup"""
30
'date-entered': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
34
def __init__(self, date = None):
35
gtk.Entry.__init__(self)
37
self.set_width_chars(12) #12 is enough for 12-oct-2009, which is verbose
43
self.prev_cal_day = None #workaround
44
self.popup = gtk.Window(type = gtk.WINDOW_POPUP)
45
calendar_box = gtk.HBox()
47
self.date_calendar = gtk.Calendar()
48
self.date_calendar.mark_day(dt.datetime.today().day)
49
self.date_calendar.connect("day-selected", self._on_day_selected)
50
self.date_calendar.connect("day-selected-double-click",
51
self.__on_day_selected_double_click)
52
self.date_calendar.connect("button-press-event",
53
self._on_cal_button_press_event)
54
calendar_box.add(self.date_calendar)
55
self.popup.add(calendar_box)
57
self.connect("button-press-event", self._on_button_press_event)
58
self.connect("key-press-event", self._on_key_press_event)
59
self.connect("focus-in-event", self._on_focus_in_event)
60
self.connect("focus-out-event", self._on_focus_out_event)
61
self.connect("changed", self._on_text_changed)
64
def set_date(self, date):
65
"""sets date to specified, using default format"""
67
self.set_text(self._format_date(self.date))
70
"""sets date to specified, using default format"""
71
self.date = self._figure_date(self.get_text())
72
self.set_text(self._format_date(self.date))
75
def _figure_date(self, date_str):
77
return dt.datetime.strptime(date_str, "%x")
81
def _format_date(self, date):
85
return date.strftime("%x")
87
def _on_text_changed(self, widget):
90
def __on_day_selected_double_click(self, calendar):
91
self.prev_cal_day = None
92
self._on_day_selected(calendar) #forward
94
def _on_cal_button_press_event(self, calendar, event):
95
self.prev_cal_day = calendar.get_date()[2]
97
def _on_day_selected(self, calendar):
98
if self.popup.get_property("visible") == False:
101
if self.prev_cal_day == calendar.get_date()[2]:
104
cal_date = calendar.get_date()
106
self.date = dt.date(cal_date[0], cal_date[1] + 1, cal_date[2])
107
self.set_text(self._format_date(self.date))
111
self.emit("date-entered")
115
def show_popup(self):
116
window = self.get_parent_window()
117
x, y= window.get_origin()
119
alloc = self.get_allocation()
121
date = self._figure_date(self.get_text())
123
self.prev_cal_day = date.day #avoid
124
self.date_calendar.select_month(date.month - 1, date.year)
125
self.date_calendar.select_day(date.day)
127
self.popup.move(x + alloc.x,y + alloc.y + alloc.height)
128
self.popup.show_all()
130
def _on_focus_in_event(self, entry, event):
133
def _on_button_press_event(self, button, event):
137
def _on_focus_out_event(self, event, something):
140
self.emit("date-entered")
143
def _on_key_press_event(self, entry, event):
144
if self.popup.get_property("visible"):
145
cal_date = self.date_calendar.get_date()
146
date = dt.date(cal_date[0], cal_date[1] + 1, cal_date[2])
148
date = self._figure_date(entry.get_text())
152
enter_pressed = False
154
if event.keyval == gtk.keysyms.Up:
155
date = date - dt.timedelta(days=1)
156
elif event.keyval == gtk.keysyms.Down:
157
date = date + dt.timedelta(days=1)
158
elif (event.keyval == gtk.keysyms.Return or
159
event.keyval == gtk.keysyms.KP_Enter):
161
elif (event.keyval == gtk.keysyms.Escape):
163
elif event.keyval in (gtk.keysyms.Left, gtk.keysyms.Right):
164
return False #keep calendar open and allow user to walk in text
170
self.prev_cal_day = "borken"
172
#prev_cal_day is our only way of checking that date is right
173
self.prev_cal_day = date.day
175
self.date_calendar.select_month(date.month - 1, date.year)
176
self.date_calendar.select_day(date.day)