3
# Copyright Ryan Rushton ryan@rrdesign.ca
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU Library General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
23
from desktopagnostic import Color, config
24
from desktopagnostic.ui import ColorButton
27
from awn import extras
28
from awn.extras import _
31
class ClockPrefs(gobject.GObject):
33
# not using gobject.property because of
34
# http://bugzilla.gnome.org/show_bug.cgi?id=593241
36
'date_before_time': (bool, _('Date before time'),
37
_('Whether to show the date next to the time, instead of below it.'),
39
gobject.PARAM_READWRITE),
40
'twelve_hour': (bool, _('12 hour mode'),
41
_('Whether to show the time in 12 hour mode (as opposed to 24 hour mode).'),
43
gobject.PARAM_READWRITE),
44
'font_face': (str, _('Font face'),
45
_('The font face for the date and time text.'),
47
gobject.PARAM_READWRITE),
48
'font_color': (Color, _('Font color'),
49
_('The text color of the date and time.'),
50
gobject.PARAM_READWRITE),
51
'font_shadow_color': (Color, _('Font shadow color'),
52
_('The font shadow color of the date and time.'),
53
gobject.PARAM_READWRITE),
54
'calendar_command': (str, _('Calendar command'),
55
_('Command to execute when a calendar day is double-clicked.'),
56
'', gobject.PARAM_READWRITE),
57
'adjust_datetime_command': (str, _('Adjust date/time command'),
58
_('Command to execute when the user wishes to adjust the date/time.'),
59
'', gobject.PARAM_READWRITE),
60
'orientation': (gtk.Orientation, _('dock orientation'),
61
_('The orientation of the dock (horizontal/vertical)'),
62
gtk.ORIENTATION_HORIZONTAL,
63
gobject.PARAM_READWRITE)}
67
'font_shadow_color': 0xcccc
71
'dbt': 'date-before-time',
72
'hour12': 'twelve-hour',
73
'font_face': 'font-face',
74
'font_color': 'font-color',
75
'font_shadow_color': 'font-shadow-color'}
78
'calendar': 'calendar_command',
79
'adjust_datetime': 'adjust_datetime_command'
82
def do_get_property(self, param):
83
attr = '__%s' % param.name.replace('-', '_')
84
return getattr(self, attr, None)
86
def do_set_property(self, param, value):
87
attr = '__%s' % param.name.replace('-', '_')
88
setattr(self, attr, value)
90
def __init__(self, applet):
91
super(ClockPrefs, self).__init__()
93
self.config = awn.config_get_default_for_applet(self.applet)
94
for key, prop in self.pref_map.iteritems():
95
self.config.bind(config.GROUP_DEFAULT, key,
96
self, prop, False, config.BIND_METHOD_FALLBACK)
97
for key, prop in self.cmd_pref_map.iteritems():
98
self.config.bind('commands', key, self, prop, False,
99
config.BIND_METHOD_FALLBACK)
100
self.on_applet_pos_changed(self.applet, self.applet.props.position)
101
self.applet.connect('position-changed', self.on_applet_pos_changed)
102
self.menu = self.build_menu()
105
def on_applet_pos_changed(self, applet, pos):
106
if pos in (gtk.POS_TOP, gtk.POS_BOTTOM):
107
self.props.orientation = gtk.ORIENTATION_HORIZONTAL
109
self.props.orientation = gtk.ORIENTATION_VERTICAL
111
def date_before_time_enabled(self):
112
return self.props.date_before_time and \
113
self.props.orientation == gtk.ORIENTATION_HORIZONTAL
115
def build_image_menu_item(self, menu, icon_name, activate_callback, label=None):
117
item = gtk.ImageMenuItem(icon_name)
119
item = awn.image_menu_item_new_with_label(label)
120
item.set_image(gtk.image_new_from_stock(icon_name, gtk.ICON_SIZE_MENU))
121
item.connect('activate', activate_callback)
124
def build_menu(self):
125
popup_menu = self.applet.create_default_menu()
127
self.build_image_menu_item(popup_menu, gtk.STOCK_COPY,
130
self.build_image_menu_item(popup_menu, gtk.STOCK_COPY,
133
self.build_image_menu_item(popup_menu, gtk.STOCK_PREFERENCES,
135
self.build_image_menu_item(popup_menu, gtk.STOCK_EDIT,
137
_('Adjust Date & Time'))
138
about_item = self.applet.create_about_item('Copyright © 2007 Ryan Rushton',
139
awn.APPLET_LICENSE_GPLV2,
140
extras.__version__, None,
141
'http://wiki.awn-project.org/Digital_Clock',
143
'awn-applet-digital-clock',
144
None, ['Ryan Rushton', 'Mark Lee'],
146
popup_menu.append(about_item)
148
popup_menu.show_all()
151
def show_prefs(self, widget):
152
if self.window is None:
153
self.window = PrefsDialog(self)
154
self.window.show_all()
156
def copy_date(self, widget):
158
txt = time.strftime('%A, %B %d, %Y')
161
def copy_time(self, widget):
163
if self.props.twelve_hour:
164
h = time.strftime('%I').lstrip('0')
165
txt = h + time.strftime(':%M:%S %p')
167
txt = time.strftime('%H:%M:%S')
170
def time_admin(self, widget):
171
subprocess.Popen(self.props.adjust_datetime_command, shell=True)
174
class HRadioGroup(gtk.Frame):
176
def __init__(self, label=None):
177
super(HRadioGroup, self).__init__(label)
178
self.hbox = gtk.HBox(5, False)
179
super(HRadioGroup, self).add(self.hbox)
181
self.connect('notify::sensitive', self.on_sensitive_changed)
183
def add_radio(self, label=None, use_underline=True, signals={},
186
if len(self.buttons) > 0:
187
group = self.buttons[0]
188
radio = gtk.RadioButton(group=group, label=label, use_underline=use_underline)
189
for signal, args in signals.iteritems():
190
radio.connect(signal, *args)
192
self.buttons.append(radio)
195
def on_sensitive_changed(self, pspec):
196
for button in self.buttons:
197
button.props.sensitive = self.props.sensitive
200
class CommandSelector:
201
def __init__(self, label, prefs, options, property_name):
202
model = gtk.ListStore(str, str)
204
self.prop = property_name
205
self.dropdown = gtk.ComboBox(model)
206
cell = gtk.CellRendererText()
207
self.dropdown.pack_start(cell, True)
208
self.dropdown.add_attribute(cell, 'text', 0)
209
self.options = options
211
value = getattr(prefs.props, self.prop)
214
for option in options:
216
self.option_map[option[1]] = idx
217
if option[1] == value:
218
self.dropdown.props.active = idx
221
model.append([_('Custom'), None])
222
self.custom = gtk.Entry()
223
self.custom.props.sensitive = not active_set
225
self.dropdown.props.active = len(self.options)
226
self.custom.props.text = value
227
self.label = mnemonic_label(label, self.dropdown)
228
prefs.connect('notify::%s' % self.prop, self.on_prop_changed)
229
self.dropdown.connect('changed', self.on_dropdown_changed)
230
self.custom.connect('changed', self.on_custom_changed)
232
def on_prop_changed(self, obj, pspec):
233
value = getattr(self.prefs.props, self.prop)
234
self.dropdown.active = self.option_map.get(value, len(self.options))
236
def on_dropdown_changed(self, dropdown):
237
idx = dropdown.props.active
238
self.custom.props.sensitive = (idx == len(self.options))
239
if self.custom.props.sensitive:
240
if self.custom.props.text == '':
241
self.custom.props.text = getattr(self.prefs.props, self.prop)
242
self.custom.select_region(0, len(self.custom.props.text))
244
active_iter = self.dropdown.get_active_iter()
245
value = self.dropdown.props.model.get_value(active_iter, 1)
246
setattr(self.prefs.props, self.prop, value)
248
def on_custom_changed(self, entry):
249
setattr(self.prefs.props, self.prop, entry.props.text)
251
def attach_to_table(self, table, row):
252
table.attach(self.label, 0, 1, row, row + 1, yoptions=gtk.SHRINK)
253
table.attach(self.dropdown, 1, 2, row, row + 1, yoptions=gtk.SHRINK)
254
table.attach(self.custom, 1, 2, row + 1, row + 2, yoptions=gtk.SHRINK)
257
def mnemonic_label(mnemonic, widget):
259
label.set_text_with_mnemonic(mnemonic)
260
label.set_mnemonic_widget(widget)
264
class PrefsDialog(gtk.Dialog):
265
def __init__(self, prefs):
266
title = _('%s Preferences') % prefs.applet.props.display_name
267
super(PrefsDialog, self).__init__(title, prefs.applet)
268
self.props.icon_name = 'gtk-preferences'
270
self.font_replace = None
273
self.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
274
self.connect('response', lambda dialog, response: dialog.hide())
275
self.prefs.connect('notify::orientation', self.on_orient_changed)
278
notebook = gtk.Notebook()
280
table = gtk.Table(5, 2)
281
table.props.row_spacing = 5
282
table.props.column_spacing = 5
284
text_font_button = gtk.FontButton(self.prefs.props.font_face)
285
text_font_button.connect('font-set', self.font_changed, 'font_face')
286
text_font_label = mnemonic_label('Font _Face:', text_font_button)
287
table.attach(text_font_label, 0, 1, 0, 1)
288
table.attach(text_font_button, 1, 2, 0, 1)
290
text_color_button = ColorButton.with_color(self.prefs.props.font_color)
291
text_color_button.connect('color-set', self.color_changed,
293
text_color_label = mnemonic_label(_('Font _Color:'), text_color_button)
294
table.attach(text_color_label, 0, 1, 1, 2)
295
table.attach(text_color_button, 1, 2, 1, 2)
296
# * font shadow color
297
text_shadow_color_button = \
298
ColorButton.with_color(self.prefs.props.font_shadow_color)
299
text_shadow_color_button.connect('color-set', self.color_changed,
301
text_shadow_color_label = mnemonic_label(_('Font _Shadow Color:'),
303
table.attach(text_shadow_color_label, 0, 1, 2, 3)
304
table.attach(text_shadow_color_button, 1, 2, 2, 3)
305
# * clock type: 12/24 hour
306
clock_type = HRadioGroup(_('Clock Type'))
307
clock_type.add_radio(_('_12 Hour'),
308
signals={'toggled': (self.radiobutton_changed,
310
clock_type.add_radio(_('_24 Hour'),
311
active=not self.prefs.props.twelve_hour)
312
table.attach(clock_type, 0, 2, 3, 4)
313
# * clock style: time beside date
314
self.clock_style = HRadioGroup(_('Date Position'))
315
self.clock_style.add_radio(_('_Left'),
316
signals={'toggled': (self.radiobutton_changed,
317
'date_before_time')})
318
self.clock_style.add_radio(_('_Bottom'),
319
active=not self.prefs.props.date_before_time)
320
self.set_clock_style_sensitivity()
321
table.attach(self.clock_style, 0, 2, 4, 5)
322
appearance_label = mnemonic_label(_('_Appearance'), table)
323
notebook.append_page(table, appearance_label)
325
cmd_table = gtk.Table(4, 2)
326
cmd_table.props.row_spacing = 5
327
cmd_table.props.column_spacing = 5
328
cmd_label = mnemonic_label(_('C_ommands'), cmd_table)
330
cal_options = [[_('Evolution (default)'), 'evolution calendar:///?startdate=%02(year)d%02(month)d%02(day)dT120000']]
331
calendar_cmd = CommandSelector(_('Run Cal_endar:'), self.prefs,
332
cal_options, 'calendar-command')
333
calendar_cmd.attach_to_table(cmd_table, 0)
335
time_options = [[_('GNOME System Tools (default)'), 'gksudo time-admin']]
336
time_cmd = CommandSelector(_('Run _Time Admin:'), self.prefs,
337
time_options, 'adjust-datetime-command')
338
time_cmd.attach_to_table(cmd_table, 2)
339
notebook.append_page(cmd_table, cmd_label)
340
self.vbox.add(notebook)
342
def radiobutton_changed(self, check, prop):
343
setattr(self.prefs.props, prop, check.get_active())
345
def font_changed(self, font_btn, prop):
346
font = self.clean_font_name(font_btn.get_font_name())
347
setattr(self.prefs.props, prop, font)
349
def clean_font_name(self, font_face):
350
if self.font_replace is None:
351
attrs = ['Condensed', 'Book', 'Oblique', 'Bold', 'Italic',
352
'Regular', 'Medium', 'Light']
353
self.font_replace = re.compile('(?:%s ?)*[\d ]*$' % '|'.join(attrs))
354
return self.font_replace.sub('', font_face)
356
def color_changed(self, color_btn, prop):
357
setattr(self.prefs.props, prop, color_btn.props.da_color)
359
def on_orient_changed(self, prefs, pspec):
360
self.set_clock_style_sensitivity()
362
def set_clock_style_sensitivity(self):
363
self.clock_style.props.sensitive = \
364
(self.prefs.props.orientation == gtk.ORIENTATION_HORIZONTAL)
366
# vim: set ts=4 sts=4 sw=4 et ai cindent :