[gnome-clocks] Refine the new alarm dialog
- From: Seif Lotfy <seiflotfy src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-clocks] Refine the new alarm dialog
- Date: Mon, 6 Aug 2012 13:47:42 +0000 (UTC)
commit 75aac183fc5cce853ef20d72ff01ec5072e46c4f
Author: Eslam Mostafa <cseslam gmail com>
Date: Sun Aug 5 13:44:18 2012 +0200
Refine the new alarm dialog
Signed-off-by: Seif Lotfy <seif lotfy com>
src/alarm.py | 140 ++++++++++++++++++-----
src/alarms_handler.py | 39 ------
src/clocks.py | 39 ++++--
src/gnome_clocks.py | 9 +-
src/gnome_clocks.py~ | 308 -------------------------------------------------
src/storage.py | 6 +
src/widgets.py | 212 ++++++++++++++++++++--------------
7 files changed, 273 insertions(+), 480 deletions(-)
---
diff --git a/src/alarm.py b/src/alarm.py
index c6d3985..a940a2e 100644
--- a/src/alarm.py
+++ b/src/alarm.py
@@ -1,20 +1,102 @@
-import datetime, vobject, time
+import datetime, vobject, time, os
+
+class ICSHandler():
+ def __init__(self):
+ self.ics_file = 'alarms.ics'
+
+ def add_vevent(self, vobj):
+ with open(self.ics_file, 'r+') as ics:
+ content = ics.read()
+ ics.seek(0)
+ vcal = vobject.readOne(content)
+ vcal.add(vobj)
+ ics.write(vcal.serialize())
+
+ def load_vevents(self):
+ alarms = []
+ if os.path.exists(self.ics_file):
+ with open(self.ics_file, 'r') as ics:
+ vcal = vobject.readOne(ics.read())
+ for item in vcal.components():
+ alarms.append(item)
+ else:
+ self.generate_ics_file()
+ return alarms
+
+ def generate_ics_file(self):
+ vcal = vobject.iCalendar()
+ ics = open('alarms.ics', 'w')
+ ics.write(vcal.serialize())
+ ics.close()
+
+
+ def delete_alarm(self, alarm_uid):
+ with open('alarms.ics', 'r+') as ics:
+ data = vobject.readOne(ics.read())
+ for alarm in vcal.vevent_list:
+ if alarm.uid.value == alarm_uid:
+ #delete event
+ break
+
+ def edit_alarm(self, alarm_uid, new_name=None, new_hour=None, new_mins=None, new_p=None, new_repeat=None):
+ with open(self.ics_file, 'r+') as ics:
+ vcal = vobject.readOne(ics.read())
+ for event in vcal.vevent_list:
+ if event.uid.value == alarm_uid:
+ if new_name:
+ del event.summary
+ event.add('summary').value = new_name
class AlarmItem:
- def __init__(self, name, time, repeat, h, m, p):
- self.name = name
- self.time = time
+ def __init__(self, name=None, repeat=None, h=None, m=None, p=None):
+ self.name = name
self.repeat = repeat
+ self.vevent = None
+ self.uid = None
self.h = h
self.m = m
self.p = p
+
+ def new_from_vevent(self, vevent):
+ self.name = vevent.summary.value
+ self.time = vevent.dtstart.value
+ self.h = int(self.time.strftime("%H"))
+ self.m = int(self.time.strftime("%M"))
+ self.p = self.time.strftime("%p")
+ self.uid = vevent.uid.value
- def set_alarm_time(self, time):
- self.time = time
+ def set_alarm_time(self, h, m, p):
+ self.h = h
+ self.m = m
+ self.p = p
- def get_alarm_time(self):
+ def get_alarm_time(self):
+ time = {}
+ time['h'] = self.h
+ time['m'] = self.m
+ time['p'] = self.p
return self.time
+ def get_time_12h_as_string(self):
+ if self.p == 'AM' or self.p == 'PM':
+ if self.h == 12 or self.h == 0:
+ h = 12
+ else:
+ h = self.h - 12
+ else:
+ h = self.h
+ return "%2i:%2i %s" % (h, self.m, self.p)
+
+
+ def get_time_24h_as_string(self):
+ if self.p == 'AM' or self.p == 'PM':
+ h = self.h + 12
+ if h == 24:
+ h = 12
+ else:
+ h = self.h
+ return "%2i:%2i" % (h, self.m)
+
def set_alarm_name(self, name):
self.name = name
@@ -26,28 +108,26 @@ class AlarmItem:
def get_alarm_repeat(self):
return self.repeat
+
+ def get_uid(self):
+ return self.vevent.uid.value
- def get_vobject(self):
- alarm = vobject.newFromBehavior('vevent')
- alarm.add('summary').value = self.name
- if self.p == 'AM':
- print self.h
- if self.h == 12:
- self.h = 0
- h_end = self.h+1
- m_end = self.m
- elif self.p == 'PM':
- self.h += 12
- h_end = self.h+1
- m_end = self.m
- if self.h == 24:
- self.h = 23
- h_end = 23
- m_end = 59
+ def get_vevent(self):
+ self.vevent = vevent = vobject.newFromBehavior('vevent')
+ vevent.add('summary').value = self.name
+ h = self.h
+ m = self.m
+ if self.p == "PM":
+ h = self.h + 12
+ if h == 24:
+ h = 12
+ elif self.p == "AM":
+ if h == 12:
+ h = 0
+ vevent.add('dtstart').value = datetime.datetime.combine(datetime.date.today(), datetime.time(h, m))
+ vevent.add('dtend').value = datetime.datetime.combine(datetime.date.today(), datetime.time(h, 59))
+ if len(self.repeat) == 0:
+ vevent.add('rrule').value = 'FREQ=DAILY;'
else:
- h_end = self.h
- m_end = 59
- alarm.add('dtstart').value = datetime.datetime.combine(datetime.date.today(), datetime.time(self.h, self.m))
- alarm.add('dtend').value = datetime.datetime.combine(datetime.date.today(), datetime.time(h_end, m_end))
- alarm.add('rrule').value = 'FREQ=WEEKLY;BYDAY=%s' % ','.join(self.repeat)
- return alarm
+ vevent.add('rrule').value = 'FREQ=WEEKLY;BYDAY=%s' % ','.join(self.repeat)
+ return vevent
diff --git a/src/clocks.py b/src/clocks.py
index 2d469aa..9a05e22 100644
--- a/src/clocks.py
+++ b/src/clocks.py
@@ -22,13 +22,12 @@ from gi.repository import Gtk, GObject, Gio, Gdk, Gst, Notify, cairo
from gi.repository.GdkPixbuf import Pixbuf
from widgets import NewWorldClockDialog, DigitalClock, NewAlarmDialog, AlarmWidget, WorldEmpty
-from alarms_handler import AlarmsHandler
from storage import worldclockstorage
from datetime import datetime, timedelta
from pytz import timezone
from timer import TimerWelcomeScreen, TimerScreen, Spinner
-from alarm import AlarmItem
+from alarm import AlarmItem, ICSHandler
import pytz, time, os
@@ -205,22 +204,36 @@ class Alarm (Clock):
self.alarms = []
self.load_alarms()
self.show_all()
+
+ def get_system_clock_format(self):
+ settings = Gio.Settings.new('org.gnome.desktop.interface')
+ systemClockFormat = settings.get_string('clock-format')
+ return systemClockFormat
def load_alarms(self):
- ah = AlarmsHandler()
- alarms = ah.load_alarms()
- for alarm in alarms:
- name = alarm.summary.value
- time = alarm.dtstart.value
- d = AlarmWidget(time)
- view_iter = self.liststore.append([d.drawing.pixbuf, "<b>" + name + "</b>", d])
- d.set_iter(self.liststore, view_iter)
+ handler = ICSHandler()
+ vevents = handler.load_vevents()
+ if vevents:
+ for vevent in vevents:
+ alarm = AlarmItem()
+ alarm.new_from_vevent(vevent)
+ scf = self.get_system_clock_format()
+ if scf == "12h":
+ d = AlarmWidget(alarm.get_time_12h_as_string())
+ else:
+ d = AlarmWidget(alarm.get_time_24h_as_string())
+ view_iter = self.liststore.append([d.drawing.pixbuf, "<b>" + alarm.get_alarm_name() + "</b>", d])
+ d.set_iter(self.liststore, view_iter)
self.show_all()
def add_alarm(self, alarm):
- ah = AlarmsHandler()
- ah.add_alarm(alarm.get_vobject())
- d = AlarmWidget(datetime.utcfromtimestamp(alarm.time))
+ handler = ICSHandler()
+ handler.add_vevent(alarm.get_vevent())
+ scf = self.get_system_clock_format()
+ if scf == "12h":
+ d = AlarmWidget(alarm.get_time_12h_as_string())
+ else:
+ d = AlarmWidget(alarm.get_time_24h_as_string())
view_iter = self.liststore.append([d.drawing.pixbuf, "<b>" + alarm.get_alarm_name() + "</b>", d])
d.set_iter(self.liststore, view_iter)
self.show_all()
diff --git a/src/gnome_clocks.py b/src/gnome_clocks.py
index 68a0213..bb36d13 100755
--- a/src/gnome_clocks.py
+++ b/src/gnome_clocks.py
@@ -27,15 +27,14 @@ import sys
class Window (Gtk.ApplicationWindow):
def __init__ (self, app):
- Gtk.ApplicationWindow.__init__ (self, title="Clocks", application=app)
+ Gtk.ApplicationWindow.__init__ (self, title="Clocks", application=app, hide_titlebar_when_maximized=True)
self.set_wmclass("Clocks", "Clocks")
css_provider = Gtk.CssProvider()
- css_provider.load_from_path("gtk-style.css")
- self.set_hide_titlebar_when_maximized (True)
- #self.maximize ()
- self.set_icon_from_file ('data/preferences-system-time.png')
+ css_provider.load_from_path("../gtk-style.css")
+ #self.set_hide_titlebar_when_maximized (True)
+ self.set_icon_from_file ('../data/preferences-system-time.png')
context = Gtk.StyleContext()
context.add_provider_for_screen (Gdk.Screen.get_default (),
css_provider,
diff --git a/src/storage.py b/src/storage.py
index 1da6dac..aa1cd0e 100644
--- a/src/storage.py
+++ b/src/storage.py
@@ -69,5 +69,11 @@ class WorldClockStorage ():
except Exception, e:
print "--", e
return []
+
+ def delete_all_clocks(self):
+ f = open(DATA_PATH, "w")
+ f.write("")
+ f.close()
worldclockstorage = WorldClockStorage ()
+worldclockstorage.delete_all_clocks()
diff --git a/src/widgets.py b/src/widgets.py
index 6614bbd..ab73c31 100644
--- a/src/widgets.py
+++ b/src/widgets.py
@@ -139,9 +139,9 @@ class DigitalClock ():
def get_image(self):
local_time = self.get_local_time ()
if local_time.tm_hour > 7 and local_time.tm_hour < 19:
- return "data/cities/day.png"
+ return "../data/cities/day.png"
else:
- return "data/cities/night.png"
+ return "../data/cities/night.png"
def get_is_day(self):
local_time = self.get_local_time ()
@@ -172,36 +172,6 @@ class DigitalClock ():
def get_standalone_widget (self):
return self.standalone
-
-class AlarmWidget():
- def __init__(self, t_given):
- self.drawing = DigitalClockDrawing ()
- clockformat = self.get_system_clock_format()
- if clockformat == '12h':
- t = t_given.strftime("%I:%M %p")
- else:
- t = t_given.strftime("%H:%M")
- isDay = self.get_is_day(t)
- if isDay == True:
- img = "data/cities/day.png"
- else:
- img = "data/cities/night.png"
- self.drawing.render(t, img, isDay)
-
- def get_system_clock_format(self):
- settings = Gio.Settings.new('org.gnome.desktop.interface')
- systemClockFormat = settings.get_string('clock-format')
- return systemClockFormat
-
- def get_is_day(self, t):
- if t[6:8] == 'AM':
- return True
- else:
- return False
-
- def set_iter (self, list_store, view_iter):
- self.view_iter = view_iter
- self.list_store = list_store
class DigitalClockStandalone (Gtk.VBox):
def __init__ (self, location):
@@ -346,6 +316,33 @@ class DigitalClockDrawing (Gtk.DrawingArea):
self.pixbuf = pixbuf
return self.pixbuf
+class AlarmWidget():
+ def __init__(self, time_given):
+ self.drawing = DigitalClockDrawing ()
+ clockformat = self.get_system_clock_format()
+ t = time_given
+ isDay = self.get_is_day(t)
+ if isDay == True:
+ img = "../data/cities/day.png"
+ else:
+ img = "../data/cities/night.png"
+ self.drawing.render(t, img, isDay)
+
+ def get_system_clock_format(self):
+ settings = Gio.Settings.new('org.gnome.desktop.interface')
+ systemClockFormat = settings.get_string('clock-format')
+ return systemClockFormat
+
+ def get_is_day(self, t):
+ if t[6:8] == 'AM':
+ return True
+ else:
+ return False
+
+ def set_iter (self, list_store, view_iter):
+ self.view_iter = view_iter
+ self.list_store = list_store
+
class NewAlarmDialog (Gtk.Dialog):
__gsignals__ = {'add-alarm': (GObject.SignalFlags.RUN_LAST,
@@ -368,10 +365,7 @@ class NewAlarmDialog (Gtk.Dialog):
table1.set_col_spacings(9)
content_area = self.get_content_area ()
content_area.pack_start(table1, True, True, 0)
- cancel = self.add_button("Cancel", 0)
- self.save = save = self.add_button("Save", 1)
- save.get_style_context().add_class('raised')
- save.set_sensitive(False)
+ self.add_buttons("Cancel", 0, "Save", 1)
self.connect("response", self.on_response)
table1.set_border_width (5)
@@ -385,21 +379,13 @@ class NewAlarmDialog (Gtk.Dialog):
points.set_alignment(0.5, 0.5)
if cf == "12h":
- houradjust = Gtk.Adjustment(h, 0, 12, 1, 1, 0)
+ if p == "PM":
+ h = h-12
+ self.hourselect = hourselect = AlarmDialogSpin(h, 1, 12)
else:
- houradjust = Gtk.Adjustment(h, 0, 23, 1, 1, 0)
- self.hourselect = hourselect = Gtk.SpinButton()
- hourselect.connect('value-changed', self._on_hours_changed)
- hourselect.set_adjustment(houradjust)
- hourbox = Gtk.Box(True, 0)
- hourbox.pack_start (hourselect, False, True, 0)
+ self.hourselect = hourselect = AlarmDialogSpin(h, 0, 23)
+ self.minuteselect = minuteselect = AlarmDialogSpin(m, 0, 59)
- minuteadjust = Gtk.Adjustment(m, 0, 59, 1, 1, 0)
- self.minuteselect = minuteselect = Gtk.SpinButton()
- minuteselect.connect('value-changed', self._on_minutes_changed)
- minuteselect.set_adjustment(minuteadjust)
- minutebox = Gtk.Box(True, 0)
- minutebox.pack_start (minuteselect, False, True, 0)
if cf == "12h":
@@ -412,15 +398,15 @@ class NewAlarmDialog (Gtk.Dialog):
ampm.set_active(1)
table1.attach (time_label, 0, 1, 0, 1)
- table1.attach (hourbox, 1, 2, 0, 1)
+ table1.attach (hourselect, 1, 2, 0, 1)
table1.attach (points, 2, 3, 0, 1)
- table1.attach (minutebox, 3, 4, 0, 1)
+ table1.attach (minuteselect, 3, 4, 0, 1)
table1.attach (ampm, 4, 5, 0, 1)
else:
table1.attach (time_label, 0, 1, 0, 1)
- table1.attach (hourbox, 1, 2, 0, 1)
+ table1.attach (hourselect, 1, 2, 0, 1)
table1.attach (points, 2, 3, 0, 1)
- table1.attach (minutebox, 3, 4, 0, 1)
+ table1.attach (minuteselect, 3, 4, 0, 1)
name = Gtk.Label ("Name")
name.set_alignment(1.0, 0.5)
@@ -483,88 +469,125 @@ class NewAlarmDialog (Gtk.Dialog):
if id == 0:
self.destroy ()
if id == 1:
- name = self.entry.get_text() #Perfect
- time = self.hourselect.get_value_as_int() * 60 * 60 + self.minuteselect.get_value_as_int() * 60
+ name = self.entry.get_text() #Perfect
repeat = self.repeat_days
+ h = self.hourselect.get_value_as_int()
+ m = self.minuteselect.get_value_as_int()
if self.cf == "12h":
r = self.ampm.get_active()
if r == 0:
- p = 'AM'
+ p = "AM"
else:
- p = 'PM'
- new_alarm = AlarmItem(name, time, repeat, self.hourselect.get_value_as_int(), self.minuteselect.get_value_as_int(), p)
+ p = "PM"
else:
- new_alarm = AlarmItem(name, time, repeat, self.hourselect.get_value_as_int(), self.minuteselect.get_value_as_int(), None)
+ p = None
+ new_alarm = AlarmItem(name, repeat, h, m, p)
self.emit('add-alarm', new_alarm)
self.destroy ()
else:
pass
-
- def _on_hours_changed(self, btn):
- self.check_save_button_status()
-
- def _on_minutes_changed(self, btn):
- self.check_save_button_status()
-
- def check_save_button_status(self):
- if len(self.repeat_days) != 0:
- self.save.set_sensitive(True)
- else:
- self.save.set_sensitive(False)
+
def on_d1_clicked(self, btn):
if btn.get_active() == True:
self.repeat_days.append('MO')
if btn.get_active() == False:
self.repeat_days.remove('MO')
- self.check_save_button_status()
-
+
def on_d2_clicked(self, btn):
if btn.get_active() == True:
self.repeat_days.append('TU')
else:
- self.repeat_days.remove('TU')
- self.check_save_button_status()
+ self.repeat_days.remove('TU')
def on_d3_clicked(self, btn):
if btn.get_active() == True:
self.repeat_days.append('WE')
else:
self.repeat_days.remove('WE')
- self.check_save_button_status()
def on_d4_clicked(self, btn):
if btn.get_active() == True:
self.repeat_days.append('TH')
else:
self.repeat_days.remove('TH')
- self.check_save_button_status()
def on_d5_clicked(self, btn):
if btn.get_active() == True:
self.repeat_days.append('FR')
else:
self.repeat_days.remove('FR')
- self.check_save_button_status()
def on_d6_clicked(self, btn):
if btn.get_active() == True:
self.repeat_days.append('SA')
else:
self.repeat_days.remove('SA')
- self.check_save_button_status()
def on_d7_clicked(self, btn):
if btn.get_active() == True:
self.repeat_days.append('SU')
else:
self.repeat_days.remove('SU')
- self.check_save_button_status()
-
-class ClocksHome(Gtk.Box):
- def __init__(self):
- Gt.Box.__init__(self)
- self.set_orientation(Gtk.Orientation.VERTICAL)
+
+class AlarmDialogSpin(Gtk.Box):
+ def __init__(self, value, min_num, max_num):
+ Gtk.Box.__init__(self)
+ self.get_style_context().add_class('linked')
+ self.max_num = max_num
+ self.min_num = min_num
+ #
+ group = Gtk.SizeGroup()
+ group.set_mode(Gtk.SizeGroupMode.VERTICAL)
+ self.entry = entry = Gtk.Entry()
+ entry.set_size_request(-1, -1)
+ self.entry.set_text(str(value))
+ self.entry.set_max_length(2)
+ self.entry.set_alignment(1)
+ height = self.entry.get_allocated_height()
+
+ group.add_widget(entry)
+ #
+ m_gicon = Gio.ThemedIcon.new_with_default_fallbacks("list-remove-symbolic")
+ m_img = Gtk.Image.new_from_gicon(m_gicon, Gtk.IconSize.MENU)
+ minus = Gtk.Button()
+ # minus.set_size_request(-1, 10)
+ minus.set_image(m_img)
+ minus.connect("clicked", self._on_click_minus)
+ group.add_widget(minus)
+ #
+ p_gicon = Gio.ThemedIcon.new_with_default_fallbacks("list-add-symbolic")
+ p_img = Gtk.Image.new_from_gicon(p_gicon, Gtk.IconSize.MENU)
+ plus = Gtk.Button()
+ #plus.set_size_request(-1, 10)
+ plus.set_image(p_img)
+ plus.connect("clicked", self._on_click_plus)
+ group.add_widget(plus)
+ #
+ self.pack_start(entry, False, False, 0)
+ self.pack_start(minus, False, False, 0)
+ self.pack_start(plus, False, False, 0)
+ self.show_all()
+
+ def get_value_as_int(self):
+ text = self.entry.get_text()
+ return int(text)
+
+ def _on_click_minus(self, btn):
+ value = self.get_value_as_int()
+ if value == self.min_num:
+ new_value = self.max_num
+ else:
+ new_value = value - 1
+ self.entry.set_text(str(new_value))
+
+ def _on_click_plus(self, btn):
+ value = self.get_value_as_int()
+ if value == self.max_num:
+ new_value = self.min_num
+ else:
+ new_value = value + 1
+ self.entry.set_text(str(new_value))
class WorldEmpty(Gtk.Box):
def __init__(self):
@@ -584,3 +607,22 @@ class WorldEmpty(Gtk.Box):
def unselect_all(self):
pass
+
+class AlarmsEmpty(Gtk.Box):
+ def __init__(self):
+ Gtk.Box.__init__(self)
+ self.set_orientation(Gtk.Orientation.VERTICAL)
+ gicon = Gio.ThemedIcon.new_with_default_fallbacks("document-open-recent-symbolic")
+ image = Gtk.Image.new_from_gicon(gicon, Gtk.IconSize.DIALOG)
+ image.set_sensitive (False)
+ text = Gtk.Label("")
+ text.set_markup("<span color='darkgrey'>Select <b>New</b> to add a world clock</span>")
+ self.pack_start(Gtk.Label(""), True, True, 0)
+ self.pack_start(image, False, False, 6)
+ self.pack_start(text, False, False, 6)
+ self.pack_start(Gtk.Label(""), True, True, 0)
+ self.button = Gtk.ToggleButton()
+ self.show_all()
+
+ def unselect_all(self):
+ pass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]