~woutc/specto/specto-dbus-client

« back to all changes in this revision

Viewing changes to spectlib/gtkconfig.py

  • Committer: Jean-François Fortin Tam
  • Author(s): Wout Clymans
  • Date: 2008-07-22 23:22:49 UTC
  • Revision ID: jeff@kiki-20080722232249-l64srclhp6u6qyrw
WARNING: this commit contains all the significant changes that happened in a specto-woutc branch over the past year. Large change log follows. Some commit log lines were intentionally left out.

- A dialog with debug information is shown when specto has a system/programming error.
- Disable renaming watches in the listview, make it a Jump To action instead
- All mandatory fields have to be filled in now (add and edit watch)
- The error log now shows the lines in color according to the severity
- Better file size cache name
- Added more error-handling
- The filesize is now saved in a different cache file (not in watches.list), may fix issue 37?
- Icons are now shown in the combobox when you add a new watch (buggy, patches welcome)
- Improved the pop3, imap and gmail watches
- The gmail watch now saves what unread mails there already were last time
- Convert HTML entities for the web diff
- Moved some code so the file dialog will show faster
- A watch will be marked updated when you didn't clear it on quit.
- Removed double call to refresh the watch info
- Made a general gtkutil file where you can define widgets used in the edit and add watch windows
- Removed the class name from the logger
- Clear the watch when you open it using the balloon
- Make some watch names clearer
- Error log tab in notifier window
- Added "clear" button in the edit menu
- Show simple diff from webpage difference
- Console mode (specto --console or specto --console --help)
- Watch menu when you right-click a watch entry in the notifier window
- Ability to run a command when a watch is updated
- Ability to run a command when a watch is cleared
- Fields in the add and edit windows are now dynamic; when creating a new watch plugin, you don't have to write all the gui code anymore
- More space for the extra information in the info panel
- code cleanup
- use plugin-system

- Fix issue 150: Gmail.com - that address is disabled in Germany - hence you can't go to messages directly
- Fix issue 93: Gmail library can support no more than 19 new mails
- Fix issue 131: bombs on special characters
- Fix issue 134: harmonized colors
- Fix issue 119: don't let the log file get huge
- Fix issue 143: Site adress in "About" box is not clickable
- Fix issue 146: Per-watch option to prevent URL redirects; To use this option add "redirect = True" to the watch that is allowed to redirect
- Fix issue 145: abnormal behavior with ampersands in a web watch
- Fix issue 51: Specto stores passwords in plaintext (started keyring support)
- Fix issue 135: Proxy support (already proxy support for web watch)
- Fix issue 128: allow specifying a port for mail watches (add 'port = 323' to your watch config)
- Fix issue 132: removing a watch should remove its cache files
- Fix issue 136: Support specific folder monitor over IMAP (add 'folder = work' to your imap watch config)
- Fix issue 63: Google Reader Watch does not support more than 20 items
- Fix issue 39: POP3 & IMAP watches not on par with gmail watch's message counting logic
- Fix issue 100: gmail with google apps should point to the right domain when clicking Jump to
- Fix issue 95: statusbar should show something else when updates are done
- Fix issue 112: hide error log tabs when debug mode is deactivated
- Fix issue 101: show the import dialog after the file chooser
- Fix issue 114: removing a watch should show a confirmation dialog
- Fix issue 73: brackets in watch name lead to startup crash (brackets can now be used in the name!)
- Fix issue 69: startup fails due to wrong glade file path  
- Fix issue 12: provide more information
- Fix issue 13: watch list importing and exporting
- Fix issue 20: Organise specto source into modules
- Fix issue 33: ability to run a command instead of notifying
- Fix issue 54: freedesktop-compliant user directories
- Fix issue 72: "show in window list" preference is not saved
- Fix issue 77: don't mess up if ekiga's sound files are not present
- Fix issue 118: add http:// automatically for web watches (also @gmail.com added for gmail accounts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: UTF8 -*-
 
2
 
 
3
# Specto , Unobtrusive event notifier
 
4
#
 
5
#       gtkutil.py
 
6
#
 
7
# Copyright (c) 2005-2007, Jean-François Fortin Tam
 
8
 
 
9
# This program is free software; you can redistribute it and/or
 
10
# modify it under the terms of the GNU General Public
 
11
# License as published by the Free Software Foundation; either
 
12
# version 2.1 of the License, or (at your option) any later version.
 
13
#
 
14
# This program is distributed in the hope that it will be useful,
 
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
17
# General Public License for more details.
 
18
#
 
19
# You should have received a copy of the GNU General Public
 
20
# License along with this program; if not, write to the
 
21
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
22
# Boston, MA 02111-1307, USA.
 
23
import gtk
 
24
import os
 
25
from spectlib.i18n import _
 
26
import spectlib.util
 
27
 
 
28
 
 
29
class Entry():
 
30
    def __init__(self, label, text=None):
 
31
        self.table = gtk.Table(rows=1, columns=2, homogeneous=True)
 
32
        self.gtkLabel = gtk.Label((label + ":"))
 
33
        self.gtkLabel.set_alignment(xalign=0.0, yalign=0.5)
 
34
        self.gtkLabel.show()
 
35
        self.table.attach(self.gtkLabel, 0, 1, 0, 1)
 
36
 
 
37
        self.entry = gtk.Entry()
 
38
        if text != None:
 
39
            self.entry.set_text(text)
 
40
        self.entry.show()
 
41
        self.table.attach(self.entry, 1, 2, 0, 1)
 
42
        self.table.show()
 
43
        
 
44
    def set_value(self, value):
 
45
        self.entry.set_text(value)
 
46
        
 
47
    def get_value(self):
 
48
        return self.entry.get_text()
 
49
    
 
50
    def get_widget(self):
 
51
        return self.table, self.entry
 
52
    
 
53
    def set_color(self, red, blue, green):
 
54
        self.entry.modify_base( gtk.STATE_NORMAL, gtk.gdk.Color(red, blue, green))
 
55
        
 
56
    def grab_focus(self):
 
57
        self.entry.grab_focus()
 
58
    
 
59
    
 
60
class PasswordEntry():
 
61
    def __init__(self, label, text=None):
 
62
        self.table = gtk.Table(rows=1, columns=2, homogeneous=True)        
 
63
        self.gtkLabel = gtk.Label((label + ":"))
 
64
        self.gtkLabel.set_alignment(xalign=0.0, yalign=0.5)
 
65
        self.gtkLabel.show()
 
66
        self.table.attach(self.gtkLabel, 0, 1, 0, 1)
 
67
        
 
68
        self.entry = gtk.Entry()
 
69
        self.entry.set_visibility(False)        
 
70
        if text != None:
 
71
            self.entry.set_text(text)
 
72
        self.entry.show()
 
73
        self.table.attach(self.entry, 1, 2, 0, 1)
 
74
        self.table.show()
 
75
        
 
76
    def set_value(self, value):
 
77
        self.entry.set_text(value)
 
78
        
 
79
    def get_value(self):
 
80
        return self.entry.get_text()
 
81
    
 
82
    def get_widget(self):
 
83
        return self.table, self.entry
 
84
    
 
85
    def set_color(self, red, blue, green):
 
86
        self.entry.modify_base( gtk.STATE_NORMAL, gtk.gdk.Color(red, blue, green))
 
87
        
 
88
    def grab_focus(self):
 
89
        self.entry.grab_focus()
 
90
        
 
91
    
 
92
class Spinbutton():
 
93
    def __init__(self, label, value=1, lower=1, upper=100, step_incr=1, page_incr=10, page_size=0):
 
94
        self.table = gtk.Table(rows=1, columns=2, homogeneous=True)
 
95
        self.gtkLabel = gtk.Label((label + ":"))
 
96
        self.gtkLabel.set_alignment(xalign=0.0, yalign=0.5)
 
97
        self.gtkLabel.show()
 
98
        self.table.attach(self.gtkLabel, 0, 1, 0, 1)        
 
99
 
 
100
        adjustment = gtk.Adjustment(value, lower, upper, step_incr, page_incr, page_size)
 
101
        self.spinbutton = gtk.SpinButton(adjustment)
 
102
        self.spinbutton.show()
 
103
        self.table.attach(self.spinbutton, 1, 2, 0, 1)
 
104
        self.table.show()
 
105
        
 
106
    def set_value(self, value):
 
107
        self.spinbutton.set_value(value)
 
108
        
 
109
    def get_value(self):
 
110
        return self.spinbutton.get_value()
 
111
    
 
112
    def get_widget(self):
 
113
        return self.table, self.spinbutton
 
114
 
 
115
    def set_color(self, red, blue, green):
 
116
        self.spinbutton.modify_base( gtk.STATE_NORMAL, gtk.gdk.Color(red, blue, green))
 
117
        
 
118
    def grab_focus(self):
 
119
        self.spinbutton.grab_focus()
 
120
    
 
121
    
 
122
class CheckButton():
 
123
    def __init__(self, label, value=False):
 
124
        self.table = gtk.Table(rows=1, columns=2, homogeneous=True)        
 
125
        self.gtkLabel = gtk.Label((label + ":"))
 
126
        self.gtkLabel.set_alignment(xalign=0.0, yalign=0.5)
 
127
        self.gtkLabel.show()
 
128
        self.table.attach(self.gtkLabel, 0, 1, 0, 1)
 
129
 
 
130
        self.checkbutton = gtk.CheckButton()
 
131
        self.checkbutton.set_active(value)
 
132
        self.checkbutton.show()
 
133
        self.table.attach(self.checkbutton, 1, 2, 0, 1)
 
134
        self.table.show()
 
135
        
 
136
    def set_value(self, value):
 
137
        self.checkbutton.set_active(value)
 
138
        
 
139
    def get_value(self):
 
140
        return self.checkbutton.get_active()
 
141
    
 
142
    def get_widget(self):
 
143
        return self.table, self.checkbutton
 
144
    
 
145
    def set_color(self, red, blue, green):
 
146
        self.checkbutton.modify_base( gtk.STATE_NORMAL, gtk.gdk.Color(red, blue, green))
 
147
        
 
148
    def grab_focus(self):
 
149
        self.checkbutton.grab_focus()
 
150
    
 
151
        
 
152
class FileChooser():
 
153
    def __init__(self, label, value=False):
 
154
        self.table = gtk.Table(rows=2, columns=1, homogeneous=True)        
 
155
        self.gtkLabel = gtk.Label((label + ":"))
 
156
        self.gtkLabel.set_alignment(xalign=0.0, yalign=0.5)
 
157
        self.gtkLabel.show()
 
158
        self.table.attach(self.gtkLabel, 0, 1, 0, 1)
 
159
 
 
160
        self.filechooser = gtk.FileChooserButton(_("Choose a file"))
 
161
        self.filechooser.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
 
162
        self.filechooser.set_filename(os.environ['HOME'])
 
163
        self.filechooser.show()
 
164
        self.table.attach(self.filechooser, 0, 1, 1, 2)
 
165
        self.table.show()
 
166
        
 
167
    def set_value(self, value):
 
168
        self.filechooser.set_filename(value)
 
169
        
 
170
    def get_value(self):
 
171
        return self.filechooser.get_filename()
 
172
    
 
173
    def get_widget(self):
 
174
        return self.table, self.filechooser
 
175
    
 
176
    def set_color(self, red, blue, green):
 
177
        self.filechooser.modify_base( gtk.STATE_NORMAL, gtk.gdk.Color(red, blue, green))
 
178
        
 
179
    def grab_focus(self):
 
180
        self.filechooser.grab_focus()
 
181
    
 
182
    
 
183
class FolderChooser():
 
184
    def __init__(self, label, value=False):
 
185
        self.table = gtk.Table(rows=2, columns=1, homogeneous=True)        
 
186
        self.gtkLabel = gtk.Label((label + ":"))
 
187
        self.gtkLabel.set_alignment(xalign=0.0, yalign=0.5)
 
188
        self.gtkLabel.show()
 
189
        self.table.attach(self.gtkLabel, 0, 1, 0, 1)
 
190
 
 
191
        self.dirchooser = gtk.FileChooserButton(_("Choose a directory"))
 
192
        self.dirchooser.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
 
193
        self.dirchooser.set_filename(os.environ['HOME'])
 
194
        self.dirchooser.show()
 
195
        self.table.attach(self.dirchooser, 0, 1, 1, 2)
 
196
        self.table.show()
 
197
        
 
198
    def set_value(self, value):
 
199
        self.dirchooser.set_filename(value)
 
200
        
 
201
    def get_value(self):
 
202
        return self.dirchooser.get_filename()
 
203
    
 
204
    def get_widget(self):
 
205
        return self.table, self.dirchooser
 
206
    
 
207
    def set_color(self, red, blue, green):
 
208
        self.dirchooser.modify_base( gtk.STATE_NORMAL, gtk.gdk.Color(red, blue, green))
 
209
        
 
210
    def grab_focus(self):
 
211
        self.dirchooser.grab_focus()
 
212
    
 
213
    
 
214
class Scale():
 
215
    def __init__(self, label, value=0, lower=0, upper=100, step_incr=1.0, page_incr=1.0,page_size=10):
 
216
        self.table = gtk.Table(rows=2, columns=1, homogeneous=False)
 
217
                        
 
218
        self.gtkLabel = gtk.Label((label + ":"))
 
219
        self.gtkLabel.set_alignment(xalign=0.0, yalign=0.5)
 
220
        self.gtkLabel.show()
 
221
        self.table.attach(self.gtkLabel, 0, 1, 0, 1)
 
222
        
 
223
        self.value = value
 
224
        self.lower = lower
 
225
        self.upper = upper
 
226
        self.step_incr = step_incr
 
227
        self.page_incr = page_incr
 
228
        self.page_size = page_size
 
229
 
 
230
        _adjustment = gtk.Adjustment(value, lower, upper, step_incr, page_incr, page_size)
 
231
        self.scale = gtk.HScale(adjustment=_adjustment)
 
232
        self.scale.set_digits(1)
 
233
        self.scale.set_value_pos(gtk.POS_RIGHT)
 
234
        self.scale.show()
 
235
        self.table.attach(self.scale, 0, 1, 1, 2)
 
236
        self.table.show()
 
237
        
 
238
    def set_value(self, value):
 
239
        _adjustment = gtk.Adjustment(value, self.lower, self.upper, self.step_incr, self.page_incr, self.page_size)
 
240
        self.scale.set_adjustment(_adjustment)
 
241
 
 
242
    def get_value(self):
 
243
        return self.scale.get_value()
 
244
    
 
245
    def get_widget(self):
 
246
        return self.table, self.scale
 
247
    
 
248
    def set_color(self, red, blue, green):
 
249
        self.scale.modify_base( gtk.STATE_NORMAL, gtk.gdk.Color(red, blue, green))
 
250
        
 
251
    def grab_focus(self):
 
252
        self.scale.grab_focus()
 
253
    
 
254
    
 
255
class RemoveDialog():
 
256
    def __init__(self, title, text):
 
257
        dialog = gtk.Dialog(title, None, gtk.DIALOG_MODAL | gtk.DIALOG_NO_SEPARATOR | gtk.DIALOG_DESTROY_WITH_PARENT, None)
 
258
        #HIG tricks
 
259
        dialog.set_has_separator(False)
 
260
        
 
261
        dialog.add_button(gtk.STOCK_REMOVE, 3)
 
262
        dialog.add_button(gtk.STOCK_CANCEL, -1)
 
263
 
 
264
        dialog.label_hbox = gtk.HBox(spacing=6)
 
265
        
 
266
        
 
267
        icon = gtk.Image()
 
268
        icon.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
 
269
        dialog.label_hbox.pack_start(icon, True, True, 6)
 
270
        icon.show()
 
271
 
 
272
        text = text.replace("&", "&")
 
273
        label = gtk.Label(text)
 
274
        label.set_use_markup(True)
 
275
        dialog.label_hbox.pack_start(label, True, True, 6)#here, pack means "cram the label right at the start of the vbox before the buttons"
 
276
        label.show()
 
277
        
 
278
        dialog.vbox.pack_start(dialog.label_hbox, True, True, 12)
 
279
        dialog.label_hbox.show()
 
280
        
 
281
        icon = gtk.gdk.pixbuf_new_from_file(spectlib.util.get_path() + 'icons/specto_window_icon.svg' )
 
282
        dialog.set_icon(icon)
 
283
        self.dialog = dialog
 
284
        
 
285
    def show(self):
 
286
        answer = self.dialog.run()
 
287
        if answer == 3:
 
288
            self.dialog.destroy()
 
289
            return True
 
290
        else:
 
291
            self.dialog.destroy()
 
292
            return False
 
293
        
 
294
class ErrorDialog():
 
295
    def __init__(self, specto, error_message):
 
296
        #create tree
 
297
        self.specto = specto
 
298
        gladefile= self.specto.PATH + 'glade/notifier.glade'
 
299
        windowname= "error_dialog"
 
300
        self.wTree=gtk.glade.XML(gladefile,windowname, self.specto.glade_gettext)
 
301
        
 
302
        dic={
 
303
        "on_send_clicked": self.send,
 
304
        "on_ok_clicked": self.delete_event,
 
305
        }
 
306
        #attach the events
 
307
        self.wTree.signal_autoconnect(dic)
 
308
        
 
309
        self.error_dialog = self.wTree.get_widget("error_dialog")
 
310
        self.error_dialog.show()
 
311
        icon = gtk.gdk.pixbuf_new_from_file(self.specto.PATH + 'icons/specto_window_icon.png' )
 
312
        self.error_dialog.set_icon(icon)
 
313
                
 
314
        self.errorwindow = gtk.TextBuffer(None)
 
315
        self.wTree.get_widget("error_message").set_buffer(self.errorwindow) 
 
316
        self.errorwindow.set_text(error_message)
 
317
        
 
318
        self.wTree.get_widget("image").set_from_stock(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_DIALOG)
 
319
 
 
320
        self.wTree.get_widget("label4").set_use_markup(True)
 
321
        self.wTree.get_widget("label4").set_label("<b>Specto had an error!</b>\nPlease fill a bug report so we can fix it!") 
 
322
        
 
323
    def send(self, *args):
 
324
        url = "http://code.google.com/p/specto/issues/entry"
 
325
        os.system(spectlib.util.return_webpage(url) + " &")
 
326
        
 
327
    def delete_event(self, widget, *args):
 
328
        """ Destroy the window. """
 
329
        self.error_dialog.destroy()
 
330
        return True
 
331
        
 
332
def create_widget(table, widget_type, value, label, position):
 
333
    i = position
 
334
    watch_options = {}
 
335
        
 
336
    if not widget_type == "scale":
 
337
        gtkLabel = gtk.Label((label + ":"))
 
338
        gtkLabel.set_alignment(xalign=0.0, yalign=0.5)
 
339
        gtkLabel.show()
 
340
        table.attach(gtkLabel, 0, 1, i, i + 1)
 
341
    
 
342
    if widget_type == "entry":
 
343
        entry = gtk.Entry()
 
344
        entry.show()
 
345
        watch_options.update({value:entry})
 
346
        table.attach(entry, 1, 2, i, i + 1)
 
347
    elif widget_type == "password":
 
348
        entry = gtk.Entry()
 
349
        entry.set_visibility(False)
 
350
        entry.show()
 
351
        watch_options.update({value:entry})
 
352
        table.attach(entry, 1, 2, i, i + 1)
 
353
    elif widget_type == "scale":
 
354
        scale_table = gtk.Table(rows=2, columns=1, homogeneous=False)
 
355
                        
 
356
        adjustment_label = gtk.Label((label + ":"))
 
357
        adjustment_label.set_alignment(xalign=0.0, yalign=0.5)
 
358
        adjustment_label.show()
 
359
        scale_table.attach(adjustment_label, 0, 1, 0, 1)
 
360
 
 
361
        _adjustment = gtk.Adjustment(value=2.0, lower=0, upper=50, step_incr=0.1, page_incr=1.0, page_size=10)
 
362
        scale = gtk.HScale(adjustment=_adjustment)
 
363
        scale.set_digits(1)
 
364
        scale.set_value_pos(gtk.POS_RIGHT)
 
365
        scale.show()
 
366
        scale_table.attach(scale, 0, 1, 1, 2)
 
367
        
 
368
        watch_options.update({value:scale})
 
369
        scale_table.show()
 
370
        table.attach(scale_table, 0, 2, i, i + 1)
 
371
    elif widget_type == "checkbox":
 
372
        checkbox = gtk.CheckButton()
 
373
        checkbox.show()
 
374
        watch_options.update({value:checkbox})                
 
375
        table.attach(checkbox, 1, 2, i, i + 1)
 
376
    elif widget_type == "filechooser":
 
377
        filechooser = gtk.FileChooserButton(_("Choose a file"))
 
378
        filechooser.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
 
379
        filechooser.show()
 
380
        watch_options.update({value:filechooser})                        
 
381
        table.attach(filechooser, 1, 2, i, i + 1)
 
382
    elif widget_type == "dirchooser":
 
383
        dirchooser = gtk.FileChooserButton(_("Choose a directory"))
 
384
        dirchooser.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
 
385
        dirchooser.show()
 
386
        watch_options.update({value:dirchooser})                        
 
387
        table.attach(dirchooser, 1, 2, i, i + 1)
 
388
    elif widget_type == "calendar":
 
389
        calendar = gtk.Calendar()
 
390
        #calendar.show()
 
391
        watch_options.update({value:calendar})                        
 
392
        table.attach(calendar, 1, 2, i, i + 1)
 
393
    elif widget_type == "time":
 
394
        time_table = gtk.Table(rows=1, columns=2, homogeneous=False)
 
395
        minutes_adjustment = gtk.Adjustment(value=1, lower=1, upper=60, step_incr=1, page_incr=10, page_size=0)
 
396
        hours_adjustment = gtk.Adjustment(value=1, lower=1, upper=24, step_incr=1, page_incr=10, page_size=0)
 
397
        hours = gtk.SpinButton(hours_adjustment)
 
398
        hours.show()
 
399
        minutes = gtk.SpinButton(minutes_adjustment)
 
400
        minutes.show()
 
401
        time_table.attach(hours, 1, 2, 1, 2)
 
402
        time_table.attach(minutes, 2, 3, 1, 2)
 
403
        #time_table.show()
 
404
        watch_options.update({value:( hours, minutes )})
 
405
        table.attach(time_table, 1, 2, i, i + 1)
 
406
 
 
407
    return watch_options, table
 
408
 
 
409
    
 
410
def set_widget_value(widget_type, widget, value):
 
411
    if widget_type == "entry" or widget_type == "password":
 
412
        widget.set_text(value)
 
413
    elif widget_type == "scale":
 
414
        _adjustment = gtk.Adjustment(value=value * 100, lower=0, upper=50, step_incr=0.1, page_incr=1.0, page_size=10)
 
415
        widget.set_adjustment(_adjustment)
 
416
    elif widget_type == "checkbox":
 
417
        if value == "True" or value == True:
 
418
            widget.set_active(1)
 
419
        else:
 
420
            widget.set_active(0)
 
421
    elif widget_type == "filechooser" or widget_type == "dirchooser":
 
422
        widget.set_filename(value)
 
423
    elif widget_type == "calendar":
 
424
        try: #if value = string
 
425
            value = value.replace("(", "")
 
426
            value = value.replace(")", "")
 
427
            value = value.split(",")
 
428
        except: # value = tuple
 
429
            pass
 
430
        widget.select_month(int(value[1]), int(value[0]))
 
431
        widget.select_day(int(value[2]))
 
432
    elif widget_type == "time":
 
433
        widget[0].set_value(int(value[0]))
 
434
        widget[1].set_value(int(value[1]))
 
435
        
 
436
    
 
437
def get_widget_value(widget_type, value):
 
438
    result = ""
 
439
    if widget_type == "entry" or widget_type == "password":
 
440
        result = value.values()[0].get_text()
 
441
    elif widget_type == "scale":
 
442
        result = value.values()[0].get_value()
 
443
    elif widget_type == "checkbox":
 
444
        result = value.values()[0].get_active()
 
445
    elif widget_type == "filechooser" or widget_type == "dirchooser":
 
446
        result = value.values()[0].get_filename()
 
447
    elif widget_type == "calendar":
 
448
        result = value.values()[0].get_date()
 
449
    elif widget_type == "time":
 
450
        result = ( value.values()[0][0].get_value(), value.values()[0][1].get_value())
 
451
        
 
452
    return result