2 from rox
import g
, TRUE
, FALSE
, app_options
3 from rox
.Menu
import Menu
4 from rox
.options
import Option
8 import pretty_time
, time
10 from Alarm
import Alarm
12 time_format
= Option('time_format', 'text')
13 main_sticky
= Option('main_sticky', 1)
14 alert_early
= Option('alert_early', 0)
17 (_('/Add Memo...'), 'new_memo', ''),
18 (_('/Show All...'), 'show_all_memos', ''),
19 ('/', '', '<Separator>'),
20 (_('/Options...'), 'show_options',''),
21 (_('/Help'), 'help', ''),
22 (_('/Quit'), 'destroy', ''),
25 class Window(rox
.Window
):
28 def __init__(self
, memo_list
):
29 rox
.Window
.__init
__(self
)
30 self
.set_wmclass('Memo', 'Memo')
31 self
.set_title('Memo')
32 self
.set_resizable(False)
33 if hasattr(self
, 'set_deletable'):
34 self
.set_deletable(False)
35 #self.set_type_hint(g.gdk.WINDOW_TYPE_HINT_DIALOG)
37 self
.tips
= g
.Tooltips()
39 if main_sticky
.int_value
:
42 self
.memo_list
= memo_list
44 self
.prime_in_progress
= False
46 vbox
= g
.VBox(FALSE
, 0)
49 hbox
= g
.HBox(False, 0)
50 vbox
.pack_start(hbox
, expand
= False)
52 self
.time_label
= g
.Label('')
53 self
.time_button
= g
.Button()
54 self
.time_button
.add(self
.time_label
)
55 self
.time_button
.unset_flags(g
.CAN_FOCUS
)
56 hbox
.pack_start(self
.time_button
, expand
= True)
58 hbox
.pack_start(timer
.TimerButton(), expand
= False)
60 self
.list = g
.TreeView(memo_list
.visible
)
61 vbox
.pack_start(self
.list, expand
= TRUE
)
62 self
.list.unset_flags(g
.CAN_FOCUS
)
64 cell
= g
.CellRendererText()
65 column
= g
.TreeViewColumn('Time', cell
, text
= 0)
66 cell
.set_property('xalign', 1)
67 self
.list.append_column(column
)
69 cell
= g
.CellRendererText()
70 column
= g
.TreeViewColumn('Message', cell
, text
= 1)
71 self
.list.append_column(column
)
73 self
.list.set_headers_visible(FALSE
)
75 sel
= self
.list.get_selection()
76 sel
.set_mode(g
.SELECTION_NONE
)
78 def activate(view
, path
, column
):
79 memo
= memo_list
.visible
.get_memo_by_path(path
)
80 from EditBox
import EditBox
83 self
.add_events(g
.gdk
.BUTTON_PRESS_MASK
)
84 self
.list.connect('button-press-event', self
.button_press
)
85 self
.list.connect('row-activated', activate
)
86 self
.time_button
.add_events(g
.gdk
.BUTTON1_MOTION_MASK
)
87 self
.time_button
.connect('button-press-event', self
.button_press
)
88 self
.time_button
.connect('motion-notify-event', self
.button_motion
)
89 self
.time_button
.connect('clicked', self
.time_button_clicked
)
91 menu
.attach(self
, self
)
94 gobject
.timeout_add(10000, self
.update
) # Update clock
96 self
.timeout
= None # For next alarm
98 self
.show_all_box
= None
102 # If we had more than one window, we'd need a remove too...
103 memo_list
.watchers
.append(self
.prime
)
104 app_options
.add_notify(self
.options_changed
)
108 def time_button_clicked(self
, widget
):
109 ev
= g
.get_current_event()
110 if ev
.type == g
.gdk
.MOTION_NOTIFY
and self
.drag_start
:
111 # Fake release from motion handler
112 self
.begin_move_drag(1, self
.drag_start
[0], self
.drag_start
[1], ev
.time
)
113 self
.drag_start
= None
117 def show_options(self
):
120 def options_changed(self
):
121 if time_format
.has_changed
:
124 if main_sticky
.int_value
:
130 if time_format
.value
== 'text':
131 text
= pretty_time
.rough_time(time
.time())
132 self
.tips
.set_tip(self
.time_button
,
133 time
.strftime('%H:%M %a %Y-%m-%d'))
135 # Note: importing gtk breaks strftime for am/pm
136 text
= time
.strftime('%a %d-%b-%Y ') + \
137 pretty_time
.str_time()
138 self
.tips
.set_tip(self
.time_button
, None)
139 self
.time_label
.set_text(text
)
142 year
, month
, day
, hour
, minute
, second
, weekday
, julian
, dst
= t
143 if self
.last_day
!= day
:
144 if self
.last_day
is not None:
145 self
.memo_list
.new_day()
150 def new_memo(self
, widget
= None):
151 from EditBox
import EditBox
155 from rox
import filer
156 filer
.open_dir(rox
.app_dir
+ '/Help')
158 def button_press(self
, widget
, event
):
159 if event
.type != g
.gdk
.BUTTON_PRESS
:
161 elif event
.button
== 2 or event
.button
== 3:
162 menu
.popup(self
, event
)
164 self
.drag_start
= map(int, (event
.x_root
, event
.y_root
))
167 def button_motion(self
, widget
, mev
):
168 if self
.drag_start
is None: return
169 pos
= map(int, (mev
.x_root
, mev
.y_root
))
170 if self
.time_button
.drag_check_threshold(*(self
.drag_start
+ pos
)):
171 self
.time_button
.released()
173 # Release event was ignored (outside the button)
174 self
.time_button_clicked(widget
)
176 def show_all_memos(self
):
177 if self
.show_all_box
:
178 self
.show_all_box
.present()
180 def destroyed(widget
): self
.show_all_box
= None
181 from ShowAll
import ShowAll
182 self
.show_all_box
= ShowAll()
183 self
.show_all_box
.connect('destroy', destroyed
)
184 self
.show_all_box
.show()
186 # Deal with any missed alarms
187 # Set a timeout for the next alarm
190 return # Don't do anything until closed
192 if self
.prime_in_progress
:
193 return # Make this method atomic
195 self
.prime_in_progress
= True
197 missed
, delay
= self
.memo_list
.catch_up( alert_early
.int_value
)
199 if dbus_notify
.is_available():
201 dbus_notify
.notify(m
)
203 # Show the first one.
204 self
.alert_box
= Alarm(missed
[0])
205 def destroyed(widget
):
206 self
.alert_box
= None
208 self
.alert_box
.connect('destroy', destroyed
)
215 self
.alert_box
.show()
218 self
.prime_in_progress
= False
220 def timeout_cb(self
):
221 gobject
.source_remove(self
.timeout
)
226 def schedule(self
, delay
):
228 gobject
.source_remove(self
.timeout
)
230 # Avoid overflows - don't resched more than a day ahead
231 if delay
> 60 * 60 * 24:
234 self
.timeout
= gobject
.timeout_add(int(1000 * delay
), self
.timeout_cb
)