~woutc/specto/specto-dbus-client

« back to all changes in this revision

Viewing changes to spectlib/main.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:
27
27
global GTK
28
28
global DEBUG #the DEBUG constant which controls how much info is output
29
29
 
30
 
import gobject
31
 
import os, sys
32
 
from datetime import datetime
 
30
import os, sys, gobject
33
31
 
34
32
import spectlib.util as util
35
 
from spectlib.watch import Watch_io, Watch_collection
 
33
from spectlib.watch import Watch_collection, Watch_io
 
34
from spectlib.console import Console
36
35
from spectlib.logger import Logger
37
 
from spectlib.specto_gconf import Specto_gconf
 
36
from spectlib.tools.specto_gconf import Specto_gconf
38
37
from spectlib.i18n import _
39
 
from spectlib.import_export import Import_watch
40
 
from spectlib import networkmanager as conmgr
41
 
 
42
 
#for the initial ping test
43
 
from urllib2 import urlopen
44
 
from time import sleep
45
 
import time
46
 
import thread
 
38
from spectlib.tools import networkmanager as conmgr
47
39
 
48
40
#create a gconf object
49
41
specto_gconf = Specto_gconf("/apps/specto")
65
57
    GTK = False
66
58
else:
67
59
    GTK = True
68
 
    from spectlib.trayicon import Tray
69
60
    from spectlib.notifier import Notifier
70
 
    from spectlib.preferences import Preferences
71
 
    from spectlib.add_watch import Add_watch
72
 
    from spectlib.about import About
73
 
    from spectlib.edit_watch import Edit_watch
74
 
    from spectlib.logger import Log_dialog
75
 
    
 
61
        
76
62
class Specto:
77
63
    """ The main Specto class. """
78
 
    add_w = ""
79
 
    edit_w = ""
80
 
    error_l = ""
81
 
    about = ""
82
 
    export = ""
83
64
 
84
65
    def __init__(self):
85
66
        self.DEBUG = DEBUG
 
67
        self.util = util
 
68
        
 
69
        self.PATH = self.util.get_path()
 
70
        self.SRC_PATH = self.util.get_path("src")
 
71
        self.SPECTO_DIR = self.util.get_path("specto")
 
72
        self.CACHE_DIR = self.util.get_path("tmp")
 
73
        self.FILE = self.util.get_file()
 
74
 
86
75
        import gettext #this is for the glade files
87
76
        self.glade_gettext = gettext.textdomain("specto")
88
77
        self.logger = Logger(self)
89
78
        self.check_instance() #see if specto is already running
90
 
        self.util = util
91
 
        self.PATH = self.util.get_path()
92
79
        self.specto_gconf = specto_gconf
93
80
        self.check_default_settings()#if this is the first run of specto, set the default values for gconf. Whenever you add some gconf preference for specto, this function will also need to be updated.
94
81
        self.GTK = GTK
95
 
        if GTK:
96
 
            self.tray = Tray(self)
 
82
                
 
83
        self.connection_manager = conmgr.get_net_listener()
 
84
        
 
85
        #create the watch collection and add the watches
 
86
        self.watch_db = Watch_collection(self)
 
87
        self.watch_io = Watch_io(self.FILE)
 
88
        values = self.watch_io.read_all_watches()
 
89
        try:
 
90
            self.watch_db.create(values)
 
91
        except AttributeError, error_fields:
 
92
            self.logger.log("Specto could not create a corrupted watch.", "critical", "Specto")
 
93
 
 
94
        if sys.argv[1:]:
 
95
            if "--console" in sys.argv[1:][0]:
 
96
                self.logger.log("Console mode enabled.", "debug", "Specto")
 
97
                self.GTK = False
 
98
                self.CONSOLE = True
 
99
                try:
 
100
                    args = sys.argv[1:][1]
 
101
                except:
 
102
                    args = ""
 
103
                self.console = Console(self, args)
 
104
                self.console.start_watches()
 
105
                                
 
106
        elif self.GTK:
 
107
            self.GTK = True
 
108
            self.CONSOLE = False
97
109
            self.icon_theme = gtk.icon_theme_get_default()
 
110
            self.notifier = Notifier(self)
98
111
            
99
 
        self.watch_io = Watch_io(os.environ['HOME'] + "/.specto/" + "watches.list")
100
 
        
101
 
        #read all the watches from a file        
102
 
        values = self.watch_io.read_all_watches()
103
 
        
104
 
        #create the watch collection and add the watches
105
 
        self.watch_db = Watch_collection()
106
 
        self.watch_db.add(self, values)
107
 
                
108
 
        self.preferences_initialized = False
109
 
        self.notifier_initialized = False        
110
112
        #listen for gconf keys
111
113
        self.specto_gconf.notify_entry("debug_mode", self.key_changed, "debug")
112
114
 
113
 
        self.connection_manager = conmgr.get_net_listener()
114
 
 
115
 
        if GTK:
116
 
            self.create_notifier_entries()
 
115
        if self.GTK:
117
116
            if self.specto_gconf.get_entry("always_show_icon") == False:
118
117
                #if the user has not requested the tray icon to be shown at all times, it's impossible that the notifier is hidden on startup, so we must show it.
119
 
                self.notifier_keep_hidden = False
120
 
                self.toggle_notifier()
 
118
                self.notifier_hide = False
121
119
            elif self.specto_gconf.get_entry("show_notifier")==True:
122
 
                self.notifier_keep_hidden = False
 
120
                self.notifier_hide = False
123
121
                self.toggle_notifier()
124
122
            elif self.specto_gconf.get_entry("show_notifier")==False:
125
 
                self.notifier_keep_hidden = True
126
 
                self.toggle_notifier()
127
 
                self.notifier_keep_hidden = False
 
123
                self.notifier_hide = True
128
124
            else:#just in case the entry was never created in gconf
129
125
                self.notifier_keep_hidden = False
130
 
                self.toggle_notifier()        
131
 
        if GTK:
 
126
            
 
127
            for watch in self.watch_db:
 
128
                self.notifier.add_notifier_entry(watch.id)
 
129
                
 
130
            self.notifier.refresh_all_watches()
 
131
            
 
132
        if self.GTK:
132
133
            gtk.main()
133
134
        else:
134
 
            self.go = gobject.MainLoop()
135
 
            self.go.run()
136
 
            
 
135
            try:
 
136
                self.go = gobject.MainLoop()
 
137
                self.go.run()
 
138
            except (KeyboardInterrupt, SystemExit):
 
139
                sys.exit(0)
 
140
 
137
141
    def key_changed(self, *args):
138
142
        """ Listen for gconf keys. """
139
143
        label = args[3]
143
147
 
144
148
    def check_default_settings(self):
145
149
        """ This is used to set the default settings properly the first time Specto is run, without using gconf schemas """
 
150
        #check if the ekiga sounds exists
 
151
        if os.path.exists("/usr/share/sounds/ekiga/voicemail.wav"):
 
152
            update_sound = "/usr/share/sounds/ekiga/voicemail.wav"
 
153
        else:
 
154
            update_sound = ""
 
155
            
146
156
        self.default_settings=(
147
157
            ["always_show_icon", False], #having it True would be against the HIG!
148
158
            ["debug_mode", False],
155
165
            ["show_toolbar", True],
156
166
            ["sort_function", "name"],
157
167
            ["sort_order", "asc"],
158
 
            ["update_sound", "/usr/share/sounds/ekiga/voicemail.wav"],
 
168
            ["update_sound", update_sound],
159
169
            ["use_update_sound", False],
160
170
            ["window_notifier_height", 500],
161
171
            ["window_notifier_width", 500]
166
176
 
167
177
    def check_instance(self):
168
178
        """ Check if specto is already running. """
169
 
        pidfile = os.environ['HOME'] + "/.specto/" + "specto.pid"
 
179
        pidfile = self.SPECTO_DIR + "/" + "specto.pid"
170
180
        if not os.path.exists(pidfile):
171
181
            f = open(pidfile, "w")
172
182
            f.close()
187
197
        f=open(pidfile, "w")
188
198
        f.write(str(os.getpid()))
189
199
        f.close()        
190
 
 
191
 
    def recreate_tray(self, *args):
192
 
        """
193
 
        Recreate a tray icon if the notification area unexpectedly quits.
194
 
        """
195
 
        try:self.tray.destroy()
196
 
        except:pass
197
 
        self.tray = ""
198
 
        self.tray = Tray(self)
199
 
        self.watch_db.count_updated_watches()
200
 
 
201
 
    def create_all_watches(self, value_db):
202
 
        """
203
 
        Create the watches at startup.
204
 
        """
205
 
        for i in value_db:
206
 
            self.create_watch(value_db[i])
207
 
            if GTK:
208
 
                while gtk.events_pending():
209
 
                    gtk.main_iteration_do(False)
210
 
                    
211
 
        if self.specto_gconf.get_entry("show_deactivated_watches")== True:
212
 
            self.notifier.wTree.get_widget("display_all_watches").set_active(True)
213
 
        self.notifier.toggle_show_deactivated_watches(startup=True)#True makes startup=True, only used on the first startup to avoid duplicate watches.
214
 
        
215
 
        #start the active watches
216
 
        if self.notifier_initialized:            
217
 
            self.notifier.refresh()
218
 
            
219
 
    def create_notifier_entries(self):
220
 
        for watch in self.watch_db:
221
 
            self.create_notifier_entry(watch)
222
 
            
223
 
    def create_notifier_entry(self, watch):
224
 
        """ Add a watch to the watches repository. """
225
 
        if not self.notifier_initialized:
226
 
            self.notifier = Notifier(self)
227
 
            #self.notifier.restore_size_and_position()#fixme: is this necessary? this makes specto output stuff for nothing.
228
 
        self.notifier.add_notifier_entry(watch.id)
229
 
##        try:
230
 
##            if watch.updated:
231
 
##                self.toggle_updated(watch.id)
232
 
##        except:
233
 
##            pass
234
 
##            
235
 
##        try:
236
 
##            if watch.active == False:
237
 
##                self.notifier.deactivate(watch.id)
238
 
##        except:
239
 
##            pass
240
 
    
241
 
    def clear_watch(self, id):
242
 
        """ Mark a watch as not updated. """
243
 
        new_values = {}
244
 
        self.watch_db[id].updated = False
245
 
        new_values['name'] = self.watch_db[id].name
246
 
        new_values['updated'] = False
247
 
        self.watch_io.write_options(new_values)
248
 
    
249
 
        self.count_updated_watches()
250
 
        
 
200
                
251
201
    def mark_watch_status(self, status, id):
252
202
        """ get the watch status (updating, updated, idle) """
253
 
        self.notifier.mark_watch_status(status, id)
254
 
 
255
 
    def set_status(self, id, status):
256
 
        """ Set the status from a watch (active/not active). """
257
 
        new_values = {}
258
 
        new_values['name'] = self.watch_db[id].name
259
 
        new_values['active'] = status
260
 
        if status == False:
261
 
            new_values['updated'] = False
262
 
            self.watch_db[id].updated = False
263
 
            self.notifier.clear_watch('',id)
264
 
        self.watch_db[id].active = status
265
 
        self.watch_io.write_options(new_values)
266
 
            
267
 
    def replace_name(self, orig, new):
268
 
        """ Replace the name from a watch in watches.list. """
269
 
        self.watch_io.replace_name(orig, new)
270
 
 
271
 
    def start_watch(self, id):
272
 
        """ Start a watch. """
273
 
        self.notifier.toggle_updating(True, id)
274
 
        self.watch_db[id].start_watch()
275
 
        self.logger.log(_("watch \"%s\" started") % self.watch_db[id].name, "info", self.__class__)
276
 
 
277
 
    def stop_watch(self, id):
278
 
        """ Stop a watch. """
279
 
        self.watch_db[id].stop_watch()
280
 
        self.logger.log(_("watch \"%s\" stopped") % self.watch_db[id].name, "info", self.__class__)
281
 
 
282
 
    def add_watch(self, values):
283
 
        """ Add a new watch. """
284
 
        new_values = {}
285
 
        new_values['name'] = values['name']
286
 
        new_values['type'] = values['type']
287
 
        new_values['refresh'] = self.set_interval(values['refresh_value'], values['refresh_unit'])
288
 
 
289
 
        if int(values['type']) == 0: #web
290
 
            new_values['uri'] = values['url']
291
 
            new_values['error_margin'] = values['error_margin']
292
 
 
293
 
        elif int(values['type']) == 1: #mail
294
 
            if int(values['prot']) == 0 or int(values['prot']) == 1:
295
 
                new_values['host'] = values['host']
296
 
                new_values['ssl'] = values['ssl']
297
 
 
298
 
            new_values['username'] = values['username']
299
 
            new_values['password'] = values['password']
300
 
            new_values['prot'] = values['prot']
301
 
        
302
 
        elif int(values['type']) == 2: #file
303
 
            new_values['file'] = values['file']
304
 
            new_values['mode'] = values['mode']
305
 
            
306
 
        elif int(values['type']) == 3: #process
307
 
            new_values['process'] = values['process']
308
 
 
309
 
        elif int(values['type']) == 4: #port
310
 
            new_values['port'] = values['port']
311
 
        
312
 
        elif int(values['type']) == 5: #google reader
313
 
            new_values['username'] = values['username']
314
 
            new_values['password'] = values['password']
315
 
 
316
 
        id = self.create_watch(new_values)
317
 
        self.start_watch(id)
318
 
 
319
 
        self.watch_io.write_options(new_values)
320
 
        
321
 
    def edit_watch(self, values):
322
 
        """ Edit a watch. """
323
 
        new_values = {}
324
 
        new_values['name'] = values['name']
325
 
        new_values['type'] = values['type']
326
 
        new_values['refresh'] = self.set_interval(values['refresh_value'], values['refresh_unit'])
327
 
 
328
 
        if int(values['type']) == 0: #web
329
 
            new_values['uri'] = values['url']
330
 
            new_values['error_margin'] = values['error_margin']
331
 
 
332
 
        elif int(values['type']) == 1: #mail
333
 
            if int(values['prot']) != 2: #gmail doesn't need a host and SSL it seems, so this is updated only of it's another kind of mail watch
334
 
                new_values['host'] = values['host']
335
 
                new_values['ssl'] = values['ssl']
336
 
                
337
 
            new_values['username'] = values['username']
338
 
            new_values['password'] = values['password']
339
 
            new_values['prot'] = values['prot']
340
 
        
341
 
        elif int(values['type']) == 2: #file
342
 
            new_values['file'] = values['file']
343
 
            
344
 
        elif int(values['type']) == 3: #process
345
 
            new_values['process'] = values['process']
346
 
 
347
 
        elif int(values['type']) == 4: #port
348
 
            new_values['port'] = values['port']
349
 
            
350
 
        elif int(values['type']) == 5: #google reader
351
 
            new_values['username'] = values['username']
352
 
            new_values['password'] = values['password']
353
 
            
354
 
        self.watch_io.write_options(new_values)
355
 
        self.notifier.show_watch_info()
356
 
 
357
 
    def remove_watch(self, name, id):
358
 
        """ Remove a watch. """
359
 
        try:
360
 
            self.stop_watch(id)
361
 
        except:
362
 
            pass
363
 
        del self.watch_db[id]
364
 
        self.count_updated_watches()
365
 
        self.watch_io.remove_watch(name)#do not clear the watch after removing it or it will mess up the watches.list
366
 
        self.notifier.model.remove(self.notifier.iter[id])
367
 
        
368
 
    def count_updated_watches(self):
369
 
        """ Count the number of updated watches for the tooltip. """
370
 
        for i in self.watch_db:
371
 
            if self.watch_db[i].updated == True:
372
 
                self.tray.set_icon_state_excited()#change the tray icon color to orange
373
 
                tooltip_updated_watches[self.watch_db[i].type] += 1
374
 
        if tooltip_updated_watches.values() == [0,0,0,0,0,0]:#there are no more watches to clear, reset the tray icon
375
 
            self.tray.set_icon_state_normal()
376
 
            self.notifier.wTree.get_widget("button_clear_all").set_sensitive(False)
377
 
 
378
 
        self.tray.show_tooltip(tooltip_updated_watches)
379
 
 
380
 
    def toggle_updated(self, id):
381
 
        """
382
 
        When a watch is updated: change name in notifier window,
383
 
        change the tray icon state, play a sound, ...
384
 
        """
385
 
        new_values = {}
386
 
        now = datetime.today()
387
 
        
388
 
        #TODO:XXX:GETTEXT
389
 
        new_values['last_updated'] = now.strftime("%A %d %b %Y %H:%M")
390
 
        self.watch_db[id].last_updated = now.strftime("%A %d %b %Y %H:%M")
391
 
        
392
 
        self.watch_db[id].updated = True
393
 
        
394
 
        if self.notifier_initialized: self.notifier.toggle_updated(id)
395
 
        new_values['name'] = self.watch_db[id].name
396
 
        new_values['updated'] = True 
397
 
        self.watch_io.write_options(new_values) #write the watches state in watches.list
398
 
        
399
 
        self.count_updated_watches() #show the tooltip
400
 
        
401
 
    def toggle_all_cleared(self):
402
 
        """ Set the state from all the watches back to 'not updated'. """
403
 
        for i in self.watch_db:
404
 
            new_values = {}
405
 
            self.watch_db[i].updated = False
406
 
            new_values['name'] = self.watch_db[i].name
407
 
            new_values['updated'] = False
408
 
            self.watch_io.write_options(new_values)
409
 
            
410
 
        self.count_updated_watches()
411
 
 
412
 
    def set_interval(self, refresh, refresh_unit):
413
 
        """
414
 
        Set the interval between the update checks.
415
 
        refresh = number
416
 
        refresh_unit = days, hours, minutes,... in values of 0, 1, 2, 3.
417
 
        """
418
 
        new_refresh = 0
419
 
        if refresh_unit == 0:#seconds
420
 
            new_refresh = refresh * 1000
421
 
        elif refresh_unit == 1:#minutes
422
 
            new_refresh = refresh * 60 * 1000
423
 
        elif refresh_unit == 2:#hours
424
 
            new_refresh = (refresh * 60) * 60 * 1000
425
 
        elif refresh_unit == 3:#days
426
 
            new_refresh = ((refresh * 60) * 60) * 24 *1000
427
 
        
428
 
        return new_refresh
429
 
        
430
 
    def get_interval(self, value):
431
 
        """ Get the interval between 2 updates. """
432
 
        if ((value / 60) / 60) / 24 / 1000 > 0:
433
 
            refresh_value = ((value / 60) / 60) / 24 / 1000
434
 
            type = 3
435
 
        elif (value / 60) / 60 / 1000 > 0:
436
 
            refresh_value = (value / 60) / 60 / 1000
437
 
            type = 2
438
 
        elif value / 60 / 1000 > 0:
439
 
            refresh_value = value / 60 / 1000
440
 
            type = 1
441
 
        else:
442
 
            refresh_value = value / 1000
443
 
            type = 0
444
 
            
445
 
        return refresh_value, type
 
203
        if self.GTK:
 
204
            self.notifier.mark_watch_status(status, id)
 
205
        elif self.CONSOLE:
 
206
            self.console.mark_watch_status(status, id)
446
207
 
447
208
    def toggle_notifier(self, *args):
448
209
        """
450
211
        It will save the size, position, and the last state when you closed Specto.
451
212
        """
452
213
        #Creating the notifier window, but keeping it hidden
453
 
        if not self.notifier_initialized and self.notifier_keep_hidden:
454
 
            self.notifier = Notifier(self)
455
 
            #self.notifier.restore_size_and_position()#this is NOT needed here because it already does that on instanciation on the line above -kiddo
456
 
            self.notifier.notifier.hide()            
457
 
        #Creating the notifier window and displaying it
458
 
        elif not self.notifier_initialized and not self.notifier_keep_hidden:
459
 
            self.notifier = Notifier(self)
460
 
            #self.notifier.restore_size_and_position()#this is NOT needed here because it already does that on instanciation on the line above -kiddo
461
 
            self.notifier.notifier.show()
462
 
 
463
 
        elif self.notifier_initialized:
464
 
            if self.notifier.get_state()==True and self.notifier_keep_hidden:
465
 
                self.logger.log(_("notifier: reappear"), "debug", self.__class__)
466
 
                self.specto_gconf.set_entry("show_notifier", True)
467
 
                self.notifier.restore_size_and_position()#to make sure that the x and y positions don't jump around
468
 
                self.notifier.notifier.show()
469
 
            elif self.notifier.get_state()==True and not self.notifier_keep_hidden:
470
 
                self.logger.log(_("notifier: hide"), "debug", self.__class__)
471
 
                self.specto_gconf.set_entry("show_notifier", False)
472
 
                self.notifier.notifier.hide()
473
 
            else:
474
 
                self.logger.log(_("notifier: reappear"), "debug", self.__class__)
475
 
                self.specto_gconf.set_entry("show_notifier", True)
476
 
                self.notifier.restore_size_and_position()#to make sure that the x and y positions don't jump around
477
 
                self.notifier.notifier.show()
478
 
        self.notifier_initialized = True
479
 
 
480
 
    def show_preferences(self, *args):
481
 
        """ Show the preferences window. """
482
 
        if not self.preferences_initialized or self.preferences.get_state() == True:
483
 
            self.logger.log(_("preferences: create"), "debug", self.__class__)
484
 
            self.pref=Preferences(self)
485
 
        else:
486
 
            self.logger.log(_("preferences: reappear"), "debug", self.__class__)
487
 
            self.pref.show()
488
 
            
489
 
    def show_error_log(self, *args):
490
 
        """ Show the error log. """
491
 
        if self.error_l == "":
492
 
            self.error_l= Log_dialog(self)
493
 
            self.logger.log(_("error log: create"), "debug", self.__class__)
494
 
        elif self.error_l.log_dialog.flags() & gtk.MAPPED:
495
 
            self.logger.log(_("error log: already visible"), "debug", self.__class__)
496
 
        else:
497
 
            self.error_l= Log_dialog(self)
498
 
            self.logger.log(_("error log: recreate"), "debug", self.__class__)
499
 
                    
500
 
    def show_add_watch(self, *args):
501
 
        """ Show the add watch window. """
502
 
        if self.add_w == "":
503
 
            self.add_w= Add_watch(self)
504
 
            self.logger.log(_("add watch: create"), "debug", self.__class__)
505
 
        elif self.add_w.add_watch.flags() & gtk.MAPPED:
506
 
            self.logger.log(_("add watch: already visible"), "debug", self.__class__)
507
 
        else:
508
 
            self.add_w= Add_watch(self)
509
 
            self.logger.log(_("add watch: recreate"), "debug", self.__class__)
510
 
 
511
 
    def show_edit_watch(self, id, *args):
512
 
        """ Show the edit watch window. """
513
 
        selected = ""
514
 
        if not id == -1:
515
 
            selected = self.watch_db[id]
516
 
        else:
517
 
            for i in self.watch_db:
518
 
                if self.watch_db[i].name == args[0]:
519
 
                    selected = self.watch_db[i]
520
 
 
521
 
        if self.edit_w == "":
522
 
            self.edit_w= Edit_watch(self, selected)
523
 
            self.logger.log(_("edit watch: create"), "debug", self.__class__)
524
 
        elif self.edit_w.edit_watch.flags() & gtk.MAPPED:
525
 
            self.logger.log(_("edit watch: already visible"), "debug", self.__class__)
526
 
        else:
527
 
            self.edit_w= Edit_watch(self, selected)
528
 
            self.logger.log(_("edit watch: recreate"), "debug", self.__class__)
529
 
 
530
 
    def show_about(self, *args):
531
 
        """ Show the about window. """
532
 
        if self.about == "":
533
 
            self.about = About(self)
534
 
        elif self.about.about.flags() & gtk.MAPPED:
535
 
            pass
536
 
        else:
537
 
            self.about = About(self)
538
 
            
539
 
    def show_help(self, *args):
540
 
        """ Show the help web page. """
541
 
        self.util.show_webpage("http://code.google.com/p/specto/w/list")
542
 
        
543
 
    def import_export_watches(self, action):
544
 
        """ Show the import/export window. """
545
 
        if self.export == "":
546
 
            self.export = Import_watch(self, action)
547
 
        elif self.export.import_watch.flags() & gtk.MAPPED:
548
 
            pass
549
 
        else:
550
 
            self.export = Import_watch(self, action)        
 
214
        if self.notifier.get_state()==True and not self.notifier_hide:
 
215
            self.specto_gconf.set_entry("show_notifier", True)
 
216
            self.notifier.restore_size_and_position()#to make sure that the x and y positions don't jump around
 
217
            self.notifier.notifier.show()
 
218
            self.notifier_hide = True
 
219
        elif self.notifier.get_state()==True and self.notifier_hide:
 
220
            self.notifier.save_size_and_position()
 
221
            self.specto_gconf.set_entry("show_notifier", False)
 
222
            self.notifier.notifier.hide()
 
223
            self.notifier_hide = False
 
224
        else:
 
225
            self.specto_gconf.set_entry("show_notifier", True)
 
226
            self.notifier.restore_size_and_position()#to make sure that the x and y positions don't jump around
 
227
            self.notifier.notifier.show()
 
228
            self.notifier_hide = True
551
229
       
552
230
    def quit(self, *args):
553
231
        """ Save the save and position from the notifier and quit Specto. """
554
 
        if self.notifier.get_state()==True and not self.notifier_keep_hidden:
 
232
        if self.notifier.get_state()==True and self.notifier_hide:
555
233
            self.notifier.save_size_and_position()#when quitting specto abruptly, remember the notifier window properties
556
234
        try:
557
235
            gtk.main_quit()