[hamster-applet] moved date popup out into widgets. much better now!
- From: Toms Baugis <tbaugis src gnome org>
- To: svn-commits-list gnome org
- Subject: [hamster-applet] moved date popup out into widgets. much better now!
- Date: Sat, 25 Apr 2009 15:35:42 -0400 (EDT)
commit eaf6bed0e71c6bf9dfc48aebe9f65f07fa3584a9
Author: Toms Bauģis <toms baugis gmail com>
Date: Sat Apr 25 18:19:33 2009 +0100
moved date popup out into widgets. much better now!
---
data/edit_activity.ui | 22 +++----
hamster/edit_activity.py | 139 +++++------------------------------------
hamster/widgets.py | 155 ++++++++++++++++++++++++++++++++++++++++++++++
po/POTFILES.in | 5 +-
4 files changed, 183 insertions(+), 138 deletions(-)
diff --git a/data/edit_activity.ui b/data/edit_activity.ui
index 8a2d318..1363638 100644
--- a/data/edit_activity.ui
+++ b/data/edit_activity.ui
@@ -80,14 +80,11 @@
<property name="visible">True</property>
<property name="spacing">4</property>
<child>
- <object class="GtkEntry" id="start_date">
+ <object class="GtkAlignment" id="start_date_placeholder">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="width_chars">12</property>
- <signal name="button_press_event" handler="on_date_button_press_event"/>
- <signal name="key_press_event" handler="on_date_key_press_event"/>
- <signal name="focus_out_event" handler="on_date_focus_out_event"/>
- <signal name="focus_in_event" handler="on_date_focus_in_event"/>
+ <child>
+ <placeholder/>
+ </child>
</object>
<packing>
<property name="position">0</property>
@@ -141,14 +138,11 @@
</packing>
</child>
<child>
- <object class="GtkEntry" id="end_date">
+ <object class="GtkAlignment" id="end_date_placeholder">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="width_chars">12</property>
- <signal name="button_press_event" handler="on_date_button_press_event"/>
- <signal name="key_press_event" handler="on_date_key_press_event"/>
- <signal name="focus_out_event" handler="on_date_focus_out_event"/>
- <signal name="focus_in_event" handler="on_date_focus_in_event"/>
+ <child>
+ <placeholder/>
+ </child>
</object>
<packing>
<property name="position">1</property>
diff --git a/hamster/edit_activity.py b/hamster/edit_activity.py
index 76945f3..d3da888 100644
--- a/hamster/edit_activity.py
+++ b/hamster/edit_activity.py
@@ -27,15 +27,13 @@ import gobject
import re
from hamster import dispatcher, storage, SHARED_DATA_DIR, stuff
-from hamster import graphics
+from hamster import graphics, widgets
import hamster.eds
import time
import datetime as dt
import colorsys
-import gobject
-
import cairo, pango
""" TODO:
@@ -356,6 +354,14 @@ class CustomFactController:
start_date = start_date or dt.datetime.now()
end_date = end_date or start_date + dt.timedelta(minutes = 30)
+
+ self.start_date = widgets.HamsterCalendar()
+ self.start_date.connect("date-entered", self.validate_fields)
+ self.get_widget("start_date_placeholder").add(self.start_date)
+ self.end_date = widgets.HamsterCalendar()
+ self.get_widget("end_date_placeholder").add(self.end_date)
+ self.end_date.connect("date-entered", self.validate_fields)
+
self.set_dropdown()
self.refresh_menu()
@@ -368,17 +374,16 @@ class CustomFactController:
self.on_in_progress_toggled(self.get_widget("in_progress"))
- self.init_calendar_window()
self.init_time_window()
self._gui.connect_signals(self)
def update_time(self, start_time, end_time):
self.get_widget("start_time").set_text(self.format_time(start_time))
- self.get_widget('start_date').set_text(self.format_date(start_time))
+ self.start_date.set_date(start_time)
self.get_widget("end_time").set_text(self.format_time(end_time))
- self.get_widget('end_date').set_text(self.format_date(end_time))
+ self.end_date.set_date(end_time)
def draw_preview(self, date, highlight = None):
@@ -386,55 +391,11 @@ class CustomFactController:
self.dayline.draw(day_facts, highlight)
- def init_calendar_window(self):
- self.calendar_window = self._gui.get_object('calendar_window')
- self.date_calendar = gtk.Calendar()
- #self.date_calendar.mark_day(dt.date.today().day) #mark day marks day in all months, hahaha
- self.date_calendar.connect("day-selected", self.on_day_selected)
- self.date_calendar.connect("day-selected-double-click", self.on_day_selected_double_click)
- self.date_calendar.connect("button-press-event", self.on_cal_button_press_event)
- self._gui.get_object("calendar_box").add(self.date_calendar)
-
- def on_cal_button_press_event(self, calendar, event):
- self.prev_cal_day = calendar.get_date()[2]
-
- def on_day_selected_double_click(self, calendar):
- self.prev_cal_day = None
- self.on_day_selected(calendar) #forward
-
- def on_day_selected(self, calendar):
- if self.calendar_window.get_property("visible") == False:
- return
-
- if self.prev_cal_day == calendar.get_date()[2]:
- return
-
- cal_date = calendar.get_date()
-
- date = dt.date(cal_date[0], cal_date[1] + 1, cal_date[2])
-
- widget = None
- if self.get_widget("start_date").is_focus():
- widget = self.get_widget("start_date")
- elif self.get_widget("end_date").is_focus():
- widget = self.get_widget("end_date")
-
- if widget:
- widget.set_text(self.format_date(date))
-
- self.calendar_window.hide()
- self.validate_fields()
-
def init_time_window(self):
self.time_window = self._gui.get_object('time_window')
self.time_tree = self.get_widget('time_tree')
self.time_tree.append_column(gtk.TreeViewColumn("Time", gtk.CellRendererText(), text=0))
-
- def on_date_button_press_event(self, button, event):
- if self.calendar_window.get_property("visible"):
- self.calendar_window.hide()
-
def on_time_button_press_event(self, button, event):
if self.time_window.get_property("visible"):
self.time_window.hide()
@@ -562,7 +523,7 @@ class CustomFactController:
def _get_datetime(self, prefix):
# adds symbolic time to date in seconds
- date = self.figure_date(self.get_widget(prefix + '_date').get_text())
+ date = getattr(self, prefix + '_date').get_date()
time = self.figure_time(self.get_widget(prefix + '_time').get_text())
if time and date:
@@ -623,44 +584,12 @@ class CustomFactController:
self.close_window()
- def figure_date(self, date_str):
- try:
- return dt.datetime.strptime(date_str, "%x")
- except:
- return None
-
- def format_date(self, date):
- if not date:
- return ""
- else:
- return date.strftime("%x")
-
def on_activity_list_key_pressed(self, entry, event):
#treating tab as keydown to be able to cycle through available values
if event.keyval == gtk.keysyms.Tab:
event.keyval = gtk.keysyms.Down
return False
- def on_date_focus_in_event(self, entry, event):
- window = entry.get_parent_window()
- x, y= window.get_origin()
-
- alloc = entry.get_allocation()
-
- date = self.figure_date(entry.get_text())
- if date:
- self.prev_cal_day = date.day #avoid
- self.date_calendar.select_month(date.month-1, date.year)
- self.date_calendar.select_day(date.day)
-
- self.calendar_window.move(x + alloc.x,y + alloc.y + alloc.height)
- self.calendar_window.show_all()
-
- def on_date_focus_out_event(self, event, something):
- self.calendar_window.hide()
- self.validate_fields()
-
-
def on_start_time_focus_in_event(self, entry, event):
self.show_time_window(entry)
@@ -678,7 +607,7 @@ class CustomFactController:
def on_in_progress_toggled(self, check):
self.get_widget("end_time").set_sensitive(not check.get_active())
- self.get_widget("end_date").set_sensitive(not check.get_active())
+ self.end_date.set_sensitive(not check.get_active())
self.validate_fields()
def show_time_window(self, widget, start_time = None):
@@ -747,41 +676,6 @@ class CustomFactController:
self.time_window.show_all()
- def on_date_key_press_event(self, entry, event):
- if self.calendar_window.get_property("visible"):
- cal_date = self.date_calendar.get_date()
- date = dt.date(cal_date[0], cal_date[1], cal_date[2])
- else:
- date = self.figure_date(entry.get_text())
- if not date:
- return
-
- enter_pressed = False
-
- if event.keyval == gtk.keysyms.Up:
- date = date - dt.timedelta(days=1)
- elif event.keyval == gtk.keysyms.Down:
- date = date + dt.timedelta(days=1)
- elif (event.keyval == gtk.keysyms.Return or
- event.keyval == gtk.keysyms.KP_Enter):
- enter_pressed = True
- elif (event.keyval == gtk.keysyms.Escape):
- self.calendar_window.hide()
- elif event.keyval in (gtk.keysyms.Left, gtk.keysyms.Right):
- return False #keep calendar open and allow user to walk in text
- else:
- self.calendar_window.hide()
- return False
-
- if enter_pressed:
- self.prev_cal_day = "borken"
- else:
- self.prev_cal_day = date.day #prev_cal_day is our only way of checking that date is right
-
- self.date_calendar.select_month(date.month, date.year)
- self.date_calendar.select_day(date.day)
- return True
-
def format_time(self, time):
if time == None:
return None
@@ -807,7 +701,7 @@ class CustomFactController:
delta = abs(time - start_time)
end_date = start_datetime + delta
- self.get_widget("end_date").set_text(self.format_date(end_date))
+ self.end_date.set_date(end_date)
widget = self.get_widget("end_time")
@@ -864,7 +758,7 @@ class CustomFactController:
def on_activity_combo_changed(self, combo):
self.validate_fields()
- def validate_fields(self):
+ def validate_fields(self, event = None):
# do not allow empty tasks
activity_text = self.get_widget("activity_combo").child.get_text()
@@ -895,7 +789,8 @@ class CustomFactController:
or (event_key.keyval == gtk.keysyms.w
and event_key.state & gtk.gdk.CONTROL_MASK)):
- if self.calendar_window.get_property("visible") or \
+ if self.start_date.calendar_window.get_property("visible") or \
+ self.end_date.calendar_window.get_property("visible") or \
self.time_window.get_property("visible"):
return False
diff --git a/hamster/widgets.py b/hamster/widgets.py
new file mode 100644
index 0000000..5852da5
--- /dev/null
+++ b/hamster/widgets.py
@@ -0,0 +1,155 @@
+# - coding: utf-8 -
+
+# Copyright (C) 2008-2009 Toms Bauģis <toms.baugis at gmail.com>
+
+# This file is part of Project Hamster.
+
+# Project Hamster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# Project Hamster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Project Hamster. If not, see <http://www.gnu.org/licenses/>.
+
+
+import gtk
+import datetime as dt
+import calendar
+import gobject
+
+class HamsterCalendar(gtk.Entry):
+ """ a text entry widget with calendar popup"""
+ __gsignals__ = {
+ 'date-entered': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
+ }
+
+
+ def __init__(self):
+ gtk.Entry.__init__(self)
+
+ self.prev_cal_day = None #workaround
+ self.calendar_window = gtk.Window(type = gtk.WINDOW_POPUP)
+ calendar_box = gtk.HBox()
+
+
+ self.date_calendar = gtk.Calendar()
+
+ self.date_calendar.connect("day-selected", self.on_day_selected)
+ self.date_calendar.connect("day-selected-double-click", self.on_day_selected_double_click)
+ self.date_calendar.connect("button-press-event", self.on_cal_button_press_event)
+ calendar_box.add(self.date_calendar)
+ self.calendar_window.add(calendar_box)
+
+ self.connect("button-press-event", self.on_button_press_event)
+ self.connect("key-press-event", self.on_key_press_event)
+ self.connect("focus-in-event", self.on_focus_in_event)
+ self.connect("focus-out-event", self.on_focus_out_event)
+ self.show()
+
+ def set_date(self, date):
+ """sets date to specified, using default format"""
+ self.set_text(self.format_date(date))
+
+ def get_date(self):
+ """sets date to specified, using default format"""
+ return self.figure_date(self.get_text())
+
+ def figure_date(self, date_str):
+ try:
+ return dt.datetime.strptime(date_str, "%x")
+ except:
+ return None
+
+ def format_date(self, date):
+ if not date:
+ return ""
+ else:
+ return date.strftime("%x")
+
+ def on_button_press_event(self, button, event):
+ if self.calendar_window.get_property("visible"):
+ self.calendar_window.hide()
+
+ def on_day_selected_double_click(self, calendar):
+ self.prev_cal_day = None
+ self.on_day_selected(calendar) #forward
+
+ def on_cal_button_press_event(self, calendar, event):
+ self.prev_cal_day = calendar.get_date()[2]
+
+ def on_day_selected(self, calendar):
+ if self.calendar_window.get_property("visible") == False:
+ return
+
+ if self.prev_cal_day == calendar.get_date()[2]:
+ return
+
+ cal_date = calendar.get_date()
+
+ date = dt.date(cal_date[0], cal_date[1] + 1, cal_date[2])
+
+ self.set_text(self.format_date(date))
+
+ self.calendar_window.hide()
+ self.emit("date-entered")
+
+
+ def on_focus_in_event(self, entry, event):
+ window = entry.get_parent_window()
+ x, y= window.get_origin()
+
+ alloc = entry.get_allocation()
+
+ date = self.figure_date(entry.get_text())
+ if date:
+ self.prev_cal_day = date.day #avoid
+ self.date_calendar.select_month(date.month-1, date.year)
+ self.date_calendar.select_day(date.day)
+
+ self.calendar_window.move(x + alloc.x,y + alloc.y + alloc.height)
+ self.calendar_window.show_all()
+
+ def on_focus_out_event(self, event, something):
+ self.calendar_window.hide()
+ self.emit("date-entered")
+
+ def on_key_press_event(self, entry, event):
+ if self.calendar_window.get_property("visible"):
+ cal_date = self.date_calendar.get_date()
+ date = dt.date(cal_date[0], cal_date[1], cal_date[2])
+ else:
+ date = self.figure_date(entry.get_text())
+ if not date:
+ return
+
+ enter_pressed = False
+
+ if event.keyval == gtk.keysyms.Up:
+ date = date - dt.timedelta(days=1)
+ elif event.keyval == gtk.keysyms.Down:
+ date = date + dt.timedelta(days=1)
+ elif (event.keyval == gtk.keysyms.Return or
+ event.keyval == gtk.keysyms.KP_Enter):
+ enter_pressed = True
+ elif (event.keyval == gtk.keysyms.Escape):
+ self.calendar_window.hide()
+ elif event.keyval in (gtk.keysyms.Left, gtk.keysyms.Right):
+ return False #keep calendar open and allow user to walk in text
+ else:
+ self.calendar_window.hide()
+ return False
+
+ if enter_pressed:
+ self.prev_cal_day = "borken"
+ else:
+ self.prev_cal_day = date.day #prev_cal_day is our only way of checking that date is right
+
+ self.date_calendar.select_month(date.month, date.year)
+ self.date_calendar.select_day(date.day)
+ return True
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 96b73f9..6a2150a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -8,10 +8,11 @@ data/hamster-applet.schemas.in
[type: gettext/glade]data/applet.ui
[type: gettext/glade]data/stats.ui
hamster/about.py
-hamster/preferences.py
-hamster/edit_activity.py
hamster/applet.py
hamster/db.py
+hamster/edit_activity.py
+hamster/preferences.py
hamster/reports.py
hamster/stats.py
hamster/stuff.py
+hamster/widgets.py
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]