2 from rox
import g
, TRUE
, FALSE
, app_options
3 from rox
.Menu
import Menu
4 from rox
.options
import Option
7 from MenuWindow
import MenuWindow
9 import pretty_time
, time
11 from Alarm
import Alarm
13 time_format
= Option('time_format', 'text')
14 main_sticky
= Option('main_sticky', 1)
15 alert_early
= Option('alert_early', 0)
17 class Window(rox
.Window
, MenuWindow
):
20 def __init__(self
, memo_list
):
21 rox
.Window
.__init
__(self
)
22 MenuWindow
.__init
__(self
)
23 self
.set_wmclass('Memo', 'Memo')
24 self
.set_title('Memo')
25 self
.set_resizable(False)
26 if hasattr(self
, 'set_deletable'):
27 self
.set_deletable(False)
28 #self.set_type_hint(g.gdk.WINDOW_TYPE_HINT_DIALOG)
30 self
.tips
= g
.Tooltips()
32 if main_sticky
.int_value
:
35 self
.memo_list
= memo_list
37 self
.prime_in_progress
= False
39 vbox
= g
.VBox(FALSE
, 0)
42 hbox
= g
.HBox(False, 0)
43 vbox
.pack_start(hbox
, expand
= False)
45 self
.time_label
= g
.Label('')
46 self
.time_button
= g
.Button()
47 self
.time_button
.add(self
.time_label
)
48 self
.time_button
.unset_flags(g
.CAN_FOCUS
)
49 hbox
.pack_start(self
.time_button
, expand
= True)
51 hbox
.pack_start(timer
.TimerButton(), expand
= False)
53 self
.list = g
.TreeView(memo_list
.visible
)
54 vbox
.pack_start(self
.list, expand
= TRUE
)
55 self
.list.unset_flags(g
.CAN_FOCUS
)
57 cell
= g
.CellRendererText()
58 column
= g
.TreeViewColumn('Time', cell
, text
= 0)
59 cell
.set_property('xalign', 1)
60 self
.list.append_column(column
)
62 cell
= g
.CellRendererText()
63 column
= g
.TreeViewColumn('Message', cell
, text
= 1)
64 self
.list.append_column(column
)
66 self
.list.set_headers_visible(FALSE
)
68 sel
= self
.list.get_selection()
69 sel
.set_mode(g
.SELECTION_NONE
)
71 def activate(view
, path
, column
):
72 memo
= memo_list
.visible
.get_memo_by_path(path
)
73 from EditBox
import EditBox
76 self
.add_events(g
.gdk
.BUTTON_PRESS_MASK
)
77 self
.list.connect('button-press-event', self
.button_press
)
78 self
.list.connect('row-activated', activate
)
79 self
.time_button
.add_events(g
.gdk
.BUTTON1_MOTION_MASK
)
80 self
.time_button
.connect('button-press-event', self
.button_press
)
81 self
.time_button
.connect('motion-notify-event', self
.button_motion
)
82 self
.time_button
.connect('clicked', self
.time_button_clicked
)
85 gobject
.timeout_add(10000, self
.update
) # Update clock
87 self
.timeout
= None # For next alarm
89 self
.show_all_box
= None
93 # If we had more than one window, we'd need a remove too...
94 memo_list
.connect("MemoListChanged", self
.prime
)
95 app_options
.add_notify(self
.options_changed
)
99 def time_button_clicked(self
, widget
):
100 ev
= g
.get_current_event()
101 if ev
.type == g
.gdk
.MOTION_NOTIFY
and self
.drag_start
:
102 # Fake release from motion handler
103 self
.begin_move_drag(1, self
.drag_start
[0], self
.drag_start
[1], ev
.time
)
104 self
.drag_start
= None
108 def options_changed(self
):
109 if time_format
.has_changed
:
112 if main_sticky
.int_value
:
118 if time_format
.value
== 'text':
119 text
= pretty_time
.rough_time(time
.time())
120 self
.tips
.set_tip(self
.time_button
,
121 time
.strftime('%H:%M %a %Y-%m-%d'))
123 # Note: importing gtk breaks strftime for am/pm
124 text
= time
.strftime('%a %d-%b-%Y ') + \
125 pretty_time
.str_time()
126 self
.tips
.set_tip(self
.time_button
, None)
127 self
.time_label
.set_text(text
)
130 year
, month
, day
, hour
, minute
, second
, weekday
, julian
, dst
= t
131 if self
.last_day
!= day
:
132 if self
.last_day
is not None:
133 self
.memo_list
.new_day()
138 def button_press(self
, widget
, event
):
139 if event
.type != g
.gdk
.BUTTON_PRESS
:
141 elif event
.button
== 2 or event
.button
== 3:
142 self
.popup_menu(event
)
144 self
.drag_start
= map(int, (event
.x_root
, event
.y_root
))
147 def button_motion(self
, widget
, mev
):
148 if self
.drag_start
is None: return
149 pos
= map(int, (mev
.x_root
, mev
.y_root
))
150 if self
.time_button
.drag_check_threshold(*(self
.drag_start
+ pos
)):
151 self
.time_button
.released()
153 # Release event was ignored (outside the button)
154 self
.time_button_clicked(widget
)
156 # Deal with any missed alarms
157 # Set a timeout for the next alarm
158 def prime(self
, memo_list
= None):
160 return # Don't do anything until closed
162 if self
.prime_in_progress
:
163 return # Make this method atomic
165 self
.prime_in_progress
= True
167 missed
, delay
= self
.memo_list
.catch_up( alert_early
.int_value
)
169 if dbus_notify
.is_available():
171 dbus_notify
.notify(m
)
173 # Show the first one.
174 self
.alert_box
= Alarm(missed
[0])
175 def destroyed(widget
):
176 self
.alert_box
= None
178 self
.alert_box
.connect('destroy', destroyed
)
185 self
.alert_box
.show()
188 self
.prime_in_progress
= False
190 def timeout_cb(self
):
191 gobject
.source_remove(self
.timeout
)
196 def schedule(self
, delay
):
198 gobject
.source_remove(self
.timeout
)
200 # Avoid overflows - don't resched more than a day ahead
201 if delay
> 60 * 60 * 24:
204 self
.timeout
= gobject
.timeout_add(int(1000 * delay
), self
.timeout_cb
)