~ubuntu-branches/debian/experimental/backintime/experimental

« back to all changes in this revision

Viewing changes to gnome/settingsdialog.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Wiltshire
  • Date: 2010-12-03 21:56:53 UTC
  • mfrom: (1.2.1 upstream) (3.1.8 sid)
  • Revision ID: james.westby@ubuntu.com-20101203215653-scx9roloq4m0dqns
Tags: 1.0.4-1
* New upstream release
    Closes: #555293
    LP: #409130 #507246 #528518 #534829 #522618
* Update debian/copyright
* The following patches are either integrated or fixed properly
  upstream: no-chmod-777.patch allow-root-backup.patch
* Refactor remaining patches and make the headers DEP-3 compliant
* Convert to source format 3.0 (quilt) and drop quilt dependency and
  logic
* Don't depend on a specific version of Python; let dh_python choose
  the best option
* Remove the "earlier-than" restriction for the Conflicts on
  backintime-kde4
* Standards version 3.9.1 (no changes required)
* Update my email address

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#    Back In Time
 
2
#    Copyright (C) 2008-2009 Oprea Dan, Bart de Koning, Richard Bailey
 
3
#
 
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.
 
8
#
 
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 General Public License for more details.
 
13
#
 
14
#    You should have received a copy of the GNU General Public License along
 
15
#    with this program; if not, write to the Free Software Foundation, Inc.,
 
16
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
17
 
 
18
 
 
19
import os
 
20
import os.path
 
21
import sys
 
22
import copy
 
23
import pygtk
 
24
pygtk.require("2.0")
 
25
import gtk
 
26
import gobject
 
27
import datetime
 
28
import gettext
 
29
 
 
30
import config
 
31
import messagebox
 
32
import tools
 
33
 
 
34
 
 
35
_=gettext.gettext
 
36
 
 
37
 
 
38
class SettingsDialog(object):
 
39
        
 
40
        def __init__( self, config, snapshots, parent ):
 
41
                
 
42
                self.config = config
 
43
                self.parent = parent
 
44
                self.snapshots = snapshots
 
45
                self.profile_id = self.config.get_current_profile()
 
46
                
 
47
                builder = gtk.Builder()
 
48
                self.builder = builder
 
49
                
 
50
                glade_file = os.path.join(self.config.get_app_path(),
 
51
                        'gnome', 'settingsdialog.glade')
 
52
                
 
53
                builder.add_from_file(glade_file)
 
54
                
 
55
                get = builder.get_object
 
56
                
 
57
                self.dialog = get('SettingsDialog')
 
58
                self.dialog.set_transient_for( parent.window )
 
59
                
 
60
                signals = { 
 
61
                                'on_btn_add_profile_clicked' : self.on_add_profile,
 
62
                                'on_btn_edit_profile_clicked' : self.on_edit_profile,
 
63
                                'on_btn_remove_profile_clicked' : self.on_remove_profile,
 
64
                                'on_btn_add_include_clicked' : self.on_add_include,
 
65
                                'on_btn_add_include_file_clicked' : self.on_add_include_file,
 
66
                                'on_btn_remove_include_clicked' : self.on_remove_include,
 
67
                                'on_btn_add_exclude_clicked' : self.on_add_exclude,
 
68
                                'on_btn_add_exclude_file_clicked' : self.on_add_exclude_file,
 
69
                                'on_btn_add_exclude_folder_clicked' : self.on_add_exclude_folder,
 
70
                                'on_btn_remove_exclude_clicked' : self.on_remove_exclude,
 
71
                                'on_cb_remove_old_backup_toggled' : self.update_remove_old_backups,
 
72
                                'on_cb_min_free_space_toggled' : self.update_min_free_space,
 
73
                                #'on_cb_per_directory_schedule_toggled' : self.on_cb_per_directory_schedule_toggled,
 
74
                                'on_combo_profiles_changed': self.on_combo_profiles_changed,
 
75
                                'on_btn_where_clicked': self.on_btn_where_clicked,
 
76
                                'on_cb_backup_mode_changed': self.on_cb_backup_mode_changed,
 
77
                                'on_cb_auto_host_user_profile_toggled': self.update_host_user_profile
 
78
                        }
 
79
                
 
80
                builder.connect_signals(signals)
 
81
                
 
82
                #profiles
 
83
                self.btn_edit_profile = get( 'btn_edit_profile' )
 
84
                self.btn_add_profile = get( 'btn_add_profile' )
 
85
                self.btn_remove_profile = get( 'btn_remove_profile' )
 
86
                
 
87
                self.disable_combo_changed = True
 
88
                
 
89
                self.store_profiles = gtk.ListStore( str, str )
 
90
                
 
91
                self.combo_profiles = get( 'combo_profiles' )
 
92
                
 
93
                text_renderer = gtk.CellRendererText()
 
94
                self.combo_profiles.pack_start( text_renderer, True )
 
95
                self.combo_profiles.add_attribute( text_renderer, 'text', 0 )
 
96
                
 
97
                self.combo_profiles.set_model( self.store_profiles )
 
98
                
 
99
                self.disable_combo_changed = False
 
100
                
 
101
                #set current folder
 
102
                #self.fcb_where = get( 'fcb_where' )
 
103
                #self.fcb_where.set_show_hidden( self.parent.show_hidden_files )
 
104
                self.edit_where = get( 'edit_where' )
 
105
                
 
106
                self.cb_auto_host_user_profile = get('cb_auto_host_user_profile')
 
107
                self.lbl_host = get('lbl_host')
 
108
                self.txt_host = get('txt_host')
 
109
                self.lbl_user = get('lbl_user')
 
110
                self.txt_user = get('txt_user')
 
111
                self.lbl_profile = get('lbl_profile')
 
112
                self.txt_profile = get('txt_profile')
 
113
 
 
114
                #automatic backup mode store
 
115
                self.store_backup_mode = gtk.ListStore( str, int )
 
116
                map = self.config.AUTOMATIC_BACKUP_MODES
 
117
                self.rev_automatic_backup_modes = {}
 
118
                keys = map.keys()
 
119
                keys.sort()
 
120
                for key in keys:
 
121
                        self.rev_automatic_backup_modes[ map[key] ] = key
 
122
                        self.store_backup_mode.append( [ map[key], key ] )
 
123
 
 
124
                #automatic backup time store
 
125
                self.store_backup_time = gtk.ListStore( str, int )
 
126
                for t in xrange( 0, 2400, 100 ):
 
127
                        self.store_backup_time.append( [ datetime.time( t/100, t%100 ).strftime("%H:%M"), t ] )
 
128
 
 
129
                #per directory schedule
 
130
                #self.cb_per_directory_schedule = get( 'cb_per_directory_schedule' )
 
131
                #self.lbl_schedule = get( 'lbl_schedule' )
 
132
                
 
133
                #setup include folders
 
134
                self.list_include = get( 'list_include' )
 
135
                
 
136
                pix_renderer = gtk.CellRendererPixbuf()
 
137
                text_renderer = gtk.CellRendererText()
 
138
                
 
139
                column = gtk.TreeViewColumn( _('Include files and folders') )
 
140
                column.pack_start( pix_renderer, False )
 
141
                column.pack_end( text_renderer, True )
 
142
                column.add_attribute( pix_renderer, 'stock-id', 1 )
 
143
                column.add_attribute( text_renderer, 'markup', 0 )
 
144
                self.list_include.append_column( column )
 
145
                
 
146
                #column = gtk.TreeViewColumn( _('Schedule') )
 
147
                #combo_renderer = gtk.CellRendererCombo()
 
148
                #combo_renderer.set_property( 'editable', True )
 
149
                #combo_renderer.set_property( 'has-entry', False )
 
150
                #combo_renderer.set_property( 'model', self.store_backup_mode )
 
151
                #combo_renderer.set_property( 'text-column', 0 )
 
152
                #combo_renderer.connect( 'edited', self.on_automatic_backup_mode_changed )
 
153
                #column.pack_end( combo_renderer, True )
 
154
                #column.add_attribute( combo_renderer, 'text', 2 )
 
155
                
 
156
                #self.include_schedule_column = column
 
157
                
 
158
                self.store_include = gtk.ListStore( str, str, int ) #, str, int )
 
159
                self.list_include.set_model( self.store_include )
 
160
                
 
161
                #setup exclude patterns
 
162
                self.list_exclude = get( 'list_exclude' )
 
163
                
 
164
                pix_renderer = gtk.CellRendererPixbuf()
 
165
                text_renderer = gtk.CellRendererText()
 
166
                
 
167
                column = gtk.TreeViewColumn( _('Exclude patterns, files or folders') )
 
168
                column.pack_start( pix_renderer, False )
 
169
                column.pack_end( text_renderer, True )
 
170
                column.add_attribute( pix_renderer, 'stock-id', 1 )
 
171
                column.add_attribute( text_renderer, 'text', 0 )
 
172
                self.list_exclude.append_column( column )
 
173
                
 
174
                self.store_exclude = gtk.ListStore( str, str )
 
175
                self.list_exclude.set_model( self.store_exclude )
 
176
 
 
177
                get( 'lbl_highly_recommended_excluded' ).set_text( ', '.join(self.config.DEFAULT_EXCLUDE) )
 
178
 
 
179
                #setup automatic backup mode
 
180
                self.cb_backup_mode = get( 'cb_backup_mode' )
 
181
                self.cb_backup_mode.set_model( self.store_backup_mode )
 
182
                
 
183
                self.cb_backup_mode.clear()
 
184
                renderer = gtk.CellRendererText()
 
185
                self.cb_backup_mode.pack_start( renderer, True )
 
186
                self.cb_backup_mode.add_attribute( renderer, 'text', 0 )
 
187
                
 
188
                #setup automatic backup time
 
189
                self.cb_backup_time = get( 'cb_backup_time' )
 
190
                self.cb_backup_time.set_model( self.store_backup_time )
 
191
 
 
192
                self.cb_backup_time.clear()
 
193
                renderer = gtk.CellRendererText()
 
194
                self.cb_backup_time.pack_start( renderer, True )
 
195
                self.cb_backup_time.add_attribute( renderer, 'text', 0 )
 
196
                
 
197
                self.hbox_backup_time = get( 'hbox_backup_time' )
 
198
 
 
199
                #setup remove old backups older than
 
200
                self.edit_remove_old_backup_value = get( 'edit_remove_old_backup_value' )
 
201
                self.cb_remove_old_backup_unit = get( 'cb_remove_old_backup_unit' )
 
202
                
 
203
                self.store_remove_old_backup_unit = gtk.ListStore( str, int )
 
204
                self.cb_remove_old_backup_unit.set_model( self.store_remove_old_backup_unit )
 
205
                
 
206
                renderer = gtk.CellRendererText()
 
207
                self.cb_remove_old_backup_unit.pack_start( renderer, True )
 
208
                self.cb_remove_old_backup_unit.add_attribute( renderer, 'text', 0 )
 
209
                
 
210
                self.store_remove_old_backup_unit.clear()
 
211
                map = self.config.REMOVE_OLD_BACKUP_UNITS
 
212
                keys = map.keys()
 
213
                keys.sort()
 
214
                for key in keys:
 
215
                        self.store_remove_old_backup_unit.append( [ map[ key ], key ] )
 
216
                
 
217
                self.cb_remove_old_backup = get( 'cb_remove_old_backup' )
 
218
                
 
219
                #setup min free space
 
220
                self.edit_min_free_space_value = get( 'edit_min_free_space_value' )
 
221
                self.cb_min_free_space_unit = get( 'cb_min_free_space_unit' )
 
222
                
 
223
                self.store_min_free_space_unit = gtk.ListStore( str, int )
 
224
                self.cb_min_free_space_unit.set_model( self.store_min_free_space_unit )
 
225
                
 
226
                renderer = gtk.CellRendererText()
 
227
                self.cb_min_free_space_unit.pack_start( renderer, True )
 
228
                self.cb_min_free_space_unit.add_attribute( renderer, 'text', 0 )
 
229
                
 
230
                self.store_min_free_space_unit.clear()
 
231
                map = self.config.MIN_FREE_SPACE_UNITS
 
232
                keys = map.keys()
 
233
                keys.sort()
 
234
                for key in keys:
 
235
                        self.store_min_free_space_unit.append( [ map[ key ], key ] )
 
236
                                
 
237
                self.cb_min_free_space = get( 'cb_min_free_space' )
 
238
                
 
239
                #don't remove named snapshots
 
240
                self.cb_dont_remove_named_snapshots = get( 'cb_dont_remove_named_snapshots' )
 
241
                
 
242
                #smart remove
 
243
                self.cb_smart_remove = get( 'cb_smart_remove' )
 
244
                
 
245
                #enable notifications
 
246
                self.cb_enable_notifications = get( 'cb_enable_notifications' )
 
247
                self.cb_backup_on_restore = get( 'cb_backup_on_restore' )
 
248
                self.cb_continue_on_errors = get( 'cb_continue_on_errors' )
 
249
                self.cb_use_gloobus_preview = get( 'cb_use_gloobus_preview' )
 
250
                self.cb_use_gloobus_preview.set_active( self.config.get_bool_value( 'gnome.use_gloobus_preview', True ) )
 
251
                self.cb_use_checksum = get( 'cb_use_checksum' )
 
252
 
 
253
                #log level
 
254
                self.store_log_level = gtk.ListStore( int, str )
 
255
                self.combo_log_level = get( 'combo_log_level' )
 
256
 
 
257
                text_renderer = gtk.CellRendererText()
 
258
                self.combo_log_level.pack_start( text_renderer, True )
 
259
                self.combo_log_level.add_attribute( text_renderer, 'text', 1 )
 
260
                
 
261
                self.combo_log_level.set_model( self.store_log_level )
 
262
                
 
263
                self.store_log_level.append( [ 0, _('None') ] )
 
264
                self.store_log_level.append( [ 1, _('Errors') ] )
 
265
                self.store_log_level.append( [ 2, _('Changes & Errors') ] )
 
266
                self.store_log_level.append( [ 3, _('All') ] )
 
267
                
 
268
                #nice & ionice
 
269
                self.cb_run_nice_from_cron = get('cb_run_nice_from_cron')
 
270
                self.cb_run_ionice_from_cron = get('cb_run_ionice_from_cron')
 
271
                self.cb_run_ionice_from_user = get('cb_run_ionice_from_user')
 
272
                self.cb_preserve_acl = get('cb_preserve_acl')
 
273
                self.cb_preserve_xattr = get('cb_preserve_xattr')
 
274
                self.cb_copy_unsafe_links = get('cb_copy_unsafe_links')
 
275
                self.cb_copy_links = get('cb_copy_links')
 
276
                
 
277
                #don't run when on battery
 
278
                self.cb_no_on_battery = get( 'cb_no_on_battery' )
 
279
                if not tools.power_status_available ():
 
280
                        self.cb_no_on_battery.set_sensitive( False )
 
281
                        self.cb_no_on_battery.set_tooltip_text( 'Power status not available from system' )
 
282
 
 
283
                self.update_profiles()
 
284
        
 
285
        def error_handler( self, message ):
 
286
                messagebox.show_error( self.dialog, self.config, message )
 
287
        
 
288
        def question_handler( self, message ):
 
289
                return gtk.RESPONSE_YES == messagebox.show_question( self.dialog, self.config, message )
 
290
        
 
291
        #def on_automatic_backup_mode_changed( self, renderer, path, new_text ):
 
292
        #       iter = self.store_include.get_iter(path)
 
293
        #       self.store_include.set_value( iter, 2, new_text )
 
294
        #       self.store_include.set_value( iter, 3, self.rev_automatic_backup_modes[new_text] )
 
295
        
 
296
        def on_btn_where_clicked( self, button ):
 
297
                path = self.edit_where.get_text()
 
298
                
 
299
                fcd = gtk.FileChooserDialog( _('Snapshots folder'), self.dialog, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) )
 
300
                if len( path ) > 0:
 
301
                        fcd.set_filename( path )
 
302
                
 
303
                if fcd.run() == gtk.RESPONSE_OK:
 
304
                        new_path = tools.prepare_path( fcd.get_filename() )
 
305
                        fcd.destroy()
 
306
                        if len( path ) > 0 and new_path != path:
 
307
                                if not self.question_handler( _('Are you sure you want to change snapshots folder ?') ):
 
308
                                        return
 
309
                        self.edit_where.set_text( new_path )
 
310
                else:
 
311
                        fcd.destroy()
 
312
 
 
313
        def on_cb_backup_mode_changed( self, *params ):
 
314
                iter = self.cb_backup_mode.get_active_iter()
 
315
 
 
316
                hide_time = True
 
317
 
 
318
                if not iter is None:
 
319
                        backup_mode = self.store_backup_mode.get_value( iter, 1 )
 
320
                        if backup_mode >= self.config.DAY:
 
321
                                hide_time = False
 
322
 
 
323
                if hide_time:
 
324
                        self.hbox_backup_time.hide()
 
325
                else:
 
326
                        self.hbox_backup_time.show()
 
327
 
 
328
        def update_host_user_profile( self, *params ):
 
329
                value = not self.cb_auto_host_user_profile.get_active()
 
330
                self.lbl_host.set_sensitive( value )
 
331
                self.txt_host.set_sensitive( value )
 
332
                self.lbl_user.set_sensitive( value )
 
333
                self.txt_user.set_sensitive( value )
 
334
                self.lbl_profile.set_sensitive( value )
 
335
                self.txt_profile.set_sensitive( value )
 
336
 
 
337
        def on_combo_profiles_changed( self, *params ):
 
338
                if self.disable_combo_changed:
 
339
                        return
 
340
                
 
341
                iter = self.combo_profiles.get_active_iter()
 
342
                if iter is None:
 
343
                        return
 
344
                
 
345
                profile_id = self.store_profiles.get_value( iter, 1 )
 
346
                if profile_id != self.profile_id:
 
347
                        self.save_profile()
 
348
                        self.profile_id = profile_id
 
349
                
 
350
                self.update_profile()
 
351
        
 
352
        def update_profiles( self ):
 
353
                self.disable_combo_changed = True
 
354
                
 
355
                profiles = self.config.get_profiles_sorted_by_name()
 
356
                
 
357
                select_iter = None
 
358
                self.store_profiles.clear()
 
359
 
 
360
                for profile_id in profiles:
 
361
                        iter = self.store_profiles.append( [ self.config.get_profile_name( profile_id ), profile_id ] )
 
362
                        if profile_id == self.profile_id:
 
363
                                select_iter = iter
 
364
                
 
365
                self.disable_combo_changed = False
 
366
                
 
367
                if not select_iter is None:
 
368
                        self.combo_profiles.set_active_iter( select_iter )
 
369
        
 
370
        def update_profile( self ):
 
371
                if self.profile_id == '1':
 
372
                        self.btn_edit_profile.set_sensitive( False )
 
373
                        self.btn_remove_profile.set_sensitive( False )
 
374
                else:
 
375
                        self.btn_edit_profile.set_sensitive( True )
 
376
                        self.btn_remove_profile.set_sensitive( True )
 
377
                
 
378
                #set current folder
 
379
                #self.fcb_where.set_filename( self.config.get_snapshots_path() )
 
380
                self.edit_where.set_text( self.config.get_snapshots_path( self.profile_id ) )
 
381
                self.cb_auto_host_user_profile.set_active( self.config.get_auto_host_user_profile( self.profile_id ) )
 
382
                host, user, profile = self.config.get_host_user_profile( self.profile_id )
 
383
                self.txt_host.set_text( host )
 
384
                self.txt_user.set_text( user )
 
385
                self.txt_profile.set_text( profile )
 
386
                self.update_host_user_profile()
 
387
                
 
388
                #per directory schedule
 
389
                #self.cb_per_directory_schedule.set_active( self.config.get_per_directory_schedule() )
 
390
                
 
391
                #setup include folders
 
392
                #self.update_per_directory_option()
 
393
                
 
394
                self.store_include.clear()
 
395
                include_folders = self.config.get_include( self.profile_id )
 
396
                if len( include_folders ) > 0:
 
397
                        for include_folder in include_folders:
 
398
                                if include_folder[1] == 0:
 
399
                                        self.store_include.append( [include_folder[0], gtk.STOCK_DIRECTORY, 0] ) #, self.config.AUTOMATIC_BACKUP_MODES[include_folder[1]], include_folder[1] ] )
 
400
                                else:
 
401
                                        self.store_include.append( [include_folder[0], gtk.STOCK_FILE, include_folder[1]] ) #, self.config.AUTOMATIC_BACKUP_MODES[include_folder[1]], include_folder[1] ] )
 
402
                
 
403
                #setup exclude patterns
 
404
                self.store_exclude.clear()
 
405
                exclude_patterns = self.config.get_exclude( self.profile_id )
 
406
                if len( exclude_patterns ) > 0:
 
407
                        for exclude_pattern in exclude_patterns:
 
408
                                self.store_exclude.append( [exclude_pattern, gtk.STOCK_DELETE] )
 
409
                
 
410
                #setup automatic backup mode
 
411
                i = 0
 
412
                iter = self.store_backup_mode.get_iter_first()
 
413
                default_mode = self.config.get_automatic_backup_mode( self.profile_id )
 
414
                while not iter is None:
 
415
                        if self.store_backup_mode.get_value( iter, 1 ) == default_mode:
 
416
                                self.cb_backup_mode.set_active( i )
 
417
                                break
 
418
                        iter = self.store_backup_mode.iter_next( iter )
 
419
                        i = i + 1
 
420
 
 
421
                #setup automatic backup time
 
422
                i = 0
 
423
                iter = self.store_backup_time.get_iter_first()
 
424
                default_mode = self.config.get_automatic_backup_time( self.profile_id )
 
425
                while not iter is None:
 
426
                        if self.store_backup_time.get_value( iter, 1 ) == default_mode:
 
427
                                self.cb_backup_time.set_active( i )
 
428
                                break
 
429
                        iter = self.store_backup_time.iter_next( iter )
 
430
                        i = i + 1
 
431
                
 
432
                self.on_cb_backup_mode_changed()
 
433
 
 
434
                #setup remove old backups older than
 
435
                enabled, value, unit = self.config.get_remove_old_snapshots( self.profile_id )
 
436
                
 
437
                self.edit_remove_old_backup_value.set_value( float( value ) )
 
438
                
 
439
                i = 0
 
440
                iter = self.store_remove_old_backup_unit.get_iter_first()
 
441
                while not iter is None:
 
442
                        if self.store_remove_old_backup_unit.get_value( iter, 1 ) == unit:
 
443
                                self.cb_remove_old_backup_unit.set_active( i )
 
444
                                break
 
445
                        iter = self.store_remove_old_backup_unit.iter_next( iter )
 
446
                        i = i + 1
 
447
                
 
448
                self.cb_remove_old_backup.set_active( enabled )
 
449
                self.update_remove_old_backups( self.cb_remove_old_backup )
 
450
                
 
451
                #setup min free space
 
452
                enabled, value, unit = self.config.get_min_free_space( self.profile_id )
 
453
                
 
454
                self.edit_min_free_space_value.set_value( float(value) )
 
455
                
 
456
                i = 0
 
457
                iter = self.store_min_free_space_unit.get_iter_first()
 
458
                while not iter is None:
 
459
                        if self.store_min_free_space_unit.get_value( iter, 1 ) == unit:
 
460
                                self.cb_min_free_space_unit.set_active( i )
 
461
                                break
 
462
                        iter = self.store_min_free_space_unit.iter_next( iter )
 
463
                        i = i + 1
 
464
                
 
465
                self.cb_min_free_space.set_active( enabled )
 
466
                self.update_min_free_space( self.cb_min_free_space )
 
467
                
 
468
                #don't remove named snapshots
 
469
                self.cb_dont_remove_named_snapshots.set_active( self.config.get_dont_remove_named_snapshots( self.profile_id ) )
 
470
                
 
471
                #smart remove
 
472
                self.cb_smart_remove.set_active( self.config.get_smart_remove( self.profile_id ) )
 
473
                
 
474
                #enable notifications
 
475
                self.cb_enable_notifications.set_active( self.config.is_notify_enabled( self.profile_id ) )
 
476
                
 
477
                #backup on restore
 
478
                self.cb_backup_on_restore.set_active( self.config.is_backup_on_restore_enabled( self.profile_id ) )
 
479
        
 
480
                #continue on errors
 
481
                self.cb_continue_on_errors.set_active( self.config.continue_on_errors( self.profile_id ) )
 
482
                
 
483
                #use checksum
 
484
                self.cb_use_checksum.set_active( self.config.use_checksum( self.profile_id ) )
 
485
                
 
486
                #log level
 
487
                self.combo_log_level.set_active( self.config.log_level( self.profile_id ) )
 
488
 
 
489
                #run 'nice' from cron
 
490
                self.cb_run_nice_from_cron.set_active(self.config.is_run_nice_from_cron_enabled( self.profile_id ))
 
491
 
 
492
                #run 'ionice' from cron
 
493
                self.cb_run_ionice_from_cron.set_active(self.config.is_run_ionice_from_cron_enabled( self.profile_id ))
 
494
                
 
495
                #run 'ionice' from user
 
496
                self.cb_run_ionice_from_user.set_active(self.config.is_run_ionice_from_user_enabled( self.profile_id ))
 
497
                
 
498
                #don't run when on battery
 
499
                self.cb_no_on_battery.set_active( self.config.is_no_on_battery_enabled( self.profile_id ) )
 
500
        
 
501
                #ACL & xattr
 
502
                self.cb_preserve_acl.set_active(self.config.preserve_acl( self.profile_id ))
 
503
                self.cb_preserve_xattr.set_active(self.config.preserve_xattr( self.profile_id ))
 
504
                self.cb_copy_unsafe_links.set_active(self.config.copy_unsafe_links( self.profile_id ))
 
505
                self.cb_copy_links.set_active(self.config.copy_links( self.profile_id ))
 
506
                
 
507
        def save_profile( self ):
 
508
                #profile_id = self.config.get_current_profile()
 
509
                #snapshots path
 
510
                snapshots_path = self.edit_where.get_text()
 
511
                
 
512
                #hack
 
513
                if snapshots_path.startswith( '//' ):
 
514
                        snapshots_path = snapshots_path[ 1 : ]
 
515
                
 
516
                #include list 
 
517
                include_list = []
 
518
                iter = self.store_include.get_iter_first()
 
519
                while not iter is None:
 
520
                        #include_list.append( ( self.store_include.get_value( iter, 0 ), self.store_include.get_value( iter, 3 ) ) )
 
521
                        value = self.store_include.get_value( iter, 0 )
 
522
                        type = self.store_include.get_value( iter, 2 )
 
523
                        include_list.append( ( value, type ) )
 
524
                        iter = self.store_include.iter_next( iter )
 
525
                
 
526
                #exclude patterns
 
527
                exclude_list = []
 
528
                iter = self.store_exclude.get_iter_first()
 
529
                while not iter is None:
 
530
                        exclude_list.append( self.store_exclude.get_value( iter, 0 ) )
 
531
                        iter = self.store_exclude.iter_next( iter )
 
532
                
 
533
                #check if back folder changed
 
534
                #if len( self.config.get_snapshots_path() ) > 0 and self.config.get_snapshots_path() != snapshots_path:
 
535
                #   if gtk.RESPONSE_YES != messagebox.show_question( self.dialog, self.config, _('Are you sure you want to change snapshots folder ?') ):
 
536
                #          return False 
 
537
                
 
538
                #ok let's save to config
 
539
                self.config.set_auto_host_user_profile( self.cb_auto_host_user_profile.get_active(), self.profile_id )
 
540
                self.config.set_host_user_profile( self.txt_host.get_text(), self.txt_user.get_text(), self.txt_profile.get_text(), self.profile_id )
 
541
                self.config.set_snapshots_path( snapshots_path, self.profile_id )
 
542
 
 
543
                #if not msg is None:
 
544
                #   messagebox.show_error( self.dialog, self.config, msg )
 
545
                #   return False
 
546
 
 
547
                self.config.set_include( include_list, self.profile_id )
 
548
                self.config.set_exclude( exclude_list, self.profile_id )
 
549
                
 
550
                #global schedule
 
551
                self.config.set_automatic_backup_mode( self.store_backup_mode.get_value( self.cb_backup_mode.get_active_iter(), 1 ), self.profile_id )
 
552
                self.config.set_automatic_backup_time( self.store_backup_time.get_value( self.cb_backup_time.get_active_iter(), 1 ), self.profile_id )
 
553
                
 
554
                #auto-remove snapshots
 
555
                self.config.set_remove_old_snapshots( 
 
556
                                                self.cb_remove_old_backup.get_active(), 
 
557
                                                int( self.edit_remove_old_backup_value.get_value() ),
 
558
                                                self.store_remove_old_backup_unit.get_value( self.cb_remove_old_backup_unit.get_active_iter(), 1 ),
 
559
                                                self.profile_id )
 
560
                self.config.set_min_free_space( 
 
561
                                                self.cb_min_free_space.get_active(), 
 
562
                                                int( self.edit_min_free_space_value.get_value() ),
 
563
                                                self.store_min_free_space_unit.get_value( self.cb_min_free_space_unit.get_active_iter(), 1 ),
 
564
                                                self.profile_id )
 
565
                self.config.set_dont_remove_named_snapshots( self.cb_dont_remove_named_snapshots.get_active(), self.profile_id )
 
566
                self.config.set_smart_remove( self.cb_smart_remove.get_active(), self.profile_id )
 
567
                
 
568
                #options
 
569
                self.config.set_notify_enabled( self.cb_enable_notifications.get_active(), self.profile_id )
 
570
                self.config.set_backup_on_restore( self.cb_backup_on_restore.get_active(), self.profile_id )
 
571
                self.config.set_continue_on_errors( self.cb_continue_on_errors.get_active(), self.profile_id )
 
572
                self.config.set_use_checksum( self.cb_use_checksum.get_active(), self.profile_id )
 
573
                self.config.set_log_level( self.store_log_level.get_value( self.combo_log_level.get_active_iter(), 0 ), self.profile_id )
 
574
                
 
575
                #expert options
 
576
                #self.config.set_per_directory_schedule( self.cb_per_directory_schedule.get_active() )
 
577
                self.config.set_run_nice_from_cron_enabled( self.cb_run_nice_from_cron.get_active(), self.profile_id )
 
578
                self.config.set_run_ionice_from_cron_enabled( self.cb_run_ionice_from_cron.get_active(), self.profile_id )
 
579
                self.config.set_run_ionice_from_user_enabled( self.cb_run_ionice_from_user.get_active(), self.profile_id )
 
580
                self.config.set_no_on_battery_enabled( self.cb_no_on_battery.get_active(), self.profile_id )
 
581
 
 
582
                self.config.set_preserve_acl( self.cb_preserve_acl.get_active(), self.profile_id )
 
583
                self.config.set_preserve_xattr( self.cb_preserve_xattr.get_active(), self.profile_id )
 
584
                self.config.set_copy_unsafe_links( self.cb_copy_unsafe_links.get_active(), self.profile_id )
 
585
                self.config.set_copy_links( self.cb_copy_links.get_active(), self.profile_id )
 
586
        
 
587
        def update_remove_old_backups( self, button ):
 
588
                enabled = self.cb_remove_old_backup.get_active()
 
589
                self.edit_remove_old_backup_value.set_sensitive( enabled )
 
590
                self.cb_remove_old_backup_unit.set_sensitive( enabled )
 
591
        
 
592
        def update_min_free_space( self, button ):
 
593
                enabled = self.cb_min_free_space.get_active()
 
594
                self.edit_min_free_space_value.set_sensitive( enabled )
 
595
                self.cb_min_free_space_unit.set_sensitive( enabled )
 
596
        
 
597
        #def on_cb_per_directory_schedule_toggled( self, button ):
 
598
        #       self.update_per_directory_option()
 
599
        
 
600
        #def update_per_directory_option( self ):
 
601
        #       if self.cb_per_directory_schedule.get_active():
 
602
        #               if self.list_include.get_column(1) == None:
 
603
        #                       self.list_include.append_column( self.include_schedule_column )
 
604
        #               self.cb_backup_mode.hide()
 
605
        #               self.lbl_schedule.hide()
 
606
        #       else:
 
607
        #               if self.list_include.get_column(1) != None:
 
608
        #                       self.list_include.remove_column( self.include_schedule_column )
 
609
        #               self.lbl_schedule.show()
 
610
        #               self.cb_backup_mode.show()
 
611
        
 
612
        def run( self ):
 
613
                self.config.set_question_handler( self.question_handler )
 
614
                self.config.set_error_handler( self.error_handler )
 
615
                
 
616
                self.config_copy_dict = copy.copy( self.config.dict )
 
617
                
 
618
                while True:
 
619
                        if gtk.RESPONSE_OK == self.dialog.run():
 
620
                                if not self.validate():
 
621
                                        continue
 
622
                        else:
 
623
                                self.config.dict = self.config_copy_dict
 
624
                        break
 
625
                
 
626
                self.config.clear_handlers()
 
627
                self.dialog.destroy()
 
628
           
 
629
        def update_snapshots_location( self ):
 
630
                '''Update snapshot location dialog'''
 
631
                self.config.set_question_handler( self.question_handler )
 
632
                self.config.set_error_handler( self.error_handler )
 
633
                self.snapshots.update_snapshots_location()
 
634
 
 
635
        def on_add_profile(self, button, data=None):
 
636
                
 
637
                name = messagebox.text_input_dialog( self.dialog, self.config, _('New profile'), None )
 
638
                if name is None:
 
639
                        return
 
640
                if len( name ) <= 0:
 
641
                        return
 
642
        
 
643
                profile_id = self.config.add_profile( name )
 
644
                if profile_id is None:
 
645
                        return
 
646
        
 
647
                self.profile_id = profile_id
 
648
                self.update_profiles()
 
649
        
 
650
        def on_edit_profile( self, button ):
 
651
                name = messagebox.text_input_dialog( self.dialog, self.config, _('Rename profile'), None )
 
652
                if name is None:
 
653
                        return
 
654
                if len( name ) <= 0:
 
655
                        return
 
656
                
 
657
                if not self.config.set_profile_name( name, self.profile_id ):
 
658
                        return
 
659
                
 
660
                self.update_profiles()
 
661
        
 
662
        def on_remove_profile( self, button ):
 
663
                if gtk.RESPONSE_YES == messagebox.show_question( self.dialog, self.config, _('Are you sure you want to delete the profile "%s" ?') % self.config.get_profile_name() ):
 
664
                        self.config.remove_profile( self.profile_id )
 
665
                        self.profile_id = '1'
 
666
                        self.update_profiles()
 
667
        
 
668
        def on_add_include( self, button ):
 
669
                fcd = gtk.FileChooserDialog( _('Include folder'), self.dialog, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) )
 
670
                fcd.set_show_hidden( self.parent.show_hidden_files  )
 
671
                
 
672
                if fcd.run() == gtk.RESPONSE_OK:
 
673
                        include_folder = tools.prepare_path( fcd.get_filename() )
 
674
                        
 
675
                        iter = self.store_include.get_iter_first()
 
676
                        while not iter is None:
 
677
                                if self.store_include.get_value( iter, 0 ) == include_folder:
 
678
                                        break
 
679
                                iter = self.store_include.iter_next( iter )
 
680
                        
 
681
                        if iter is None:
 
682
                                #self.store_include.append( [include_folder, gtk.STOCK_DIRECTORY, self.config.AUTOMATIC_BACKUP_MODES[self.config.NONE], self.config.NONE ] )
 
683
                                self.store_include.append( [ include_folder, gtk.STOCK_DIRECTORY, 0 ] )
 
684
                
 
685
                fcd.destroy()
 
686
        
 
687
        def on_add_include_file( self, button ):
 
688
                fcd = gtk.FileChooserDialog( _('Include file'), self.dialog, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) )
 
689
                fcd.set_show_hidden( self.parent.show_hidden_files  )
 
690
                
 
691
                if fcd.run() == gtk.RESPONSE_OK:
 
692
                        include_file = tools.prepare_path( fcd.get_filename() )
 
693
                        
 
694
                        iter = self.store_include.get_iter_first()
 
695
                        while not iter is None:
 
696
                                if self.store_include.get_value( iter, 0 ) == include_file:
 
697
                                        break
 
698
                                iter = self.store_include.iter_next( iter )
 
699
                        
 
700
                        if iter is None:
 
701
                                #self.store_include.append( [include_folder, gtk.STOCK_DIRECTORY, self.config.AUTOMATIC_BACKUP_MODES[self.config.NONE], self.config.NONE ] )
 
702
                                self.store_include.append( [ include_file, gtk.STOCK_FILE, 1 ] )
 
703
                
 
704
                fcd.destroy()
 
705
        
 
706
        def on_remove_include( self, button ):
 
707
                store, iter = self.list_include.get_selection().get_selected()
 
708
                if not iter is None:
 
709
                        store.remove( iter )
 
710
        
 
711
        def add_exclude_( self, pattern ):
 
712
                pattern = pattern.strip()
 
713
                if len( pattern ) == 0:
 
714
                        return
 
715
                
 
716
                iter = self.store_exclude.get_iter_first()
 
717
                while not iter is None:
 
718
                        if self.store_exclude.get_value( iter, 0 ) == pattern:
 
719
                                return
 
720
                        iter = self.store_exclude.iter_next( iter )
 
721
                
 
722
                self.store_exclude.append( [pattern, gtk.STOCK_DELETE] )
 
723
        
 
724
        def on_add_exclude( self, button ):
 
725
                pattern = messagebox.text_input_dialog( self.dialog, self.config, _('Exclude pattern') )
 
726
                if pattern is None:
 
727
                        return
 
728
                
 
729
                if pattern.find( ':' ) >= 0:
 
730
                        messagebox.show_error( self.dialog, self.config, _('Exclude patterns can\'t contain \':\' char !') )
 
731
                        return
 
732
 
 
733
                self.add_exclude_( pattern )
 
734
        
 
735
        def on_add_exclude_file( self, button ):
 
736
                fcd = gtk.FileChooserDialog( _('Exclude file'), self.dialog, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) )
 
737
                fcd.set_show_hidden( self.parent.show_hidden_files  )
 
738
                
 
739
                if fcd.run() == gtk.RESPONSE_OK:
 
740
                        pattern = tools.prepare_path( fcd.get_filename() )
 
741
                        self.add_exclude_( pattern )
 
742
                
 
743
                fcd.destroy()
 
744
        
 
745
        def on_add_exclude_folder( self, button ):
 
746
                fcd = gtk.FileChooserDialog( _('Exclude folder'), self.dialog, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) )
 
747
                fcd.set_show_hidden( self.parent.show_hidden_files  )
 
748
                
 
749
                if fcd.run() == gtk.RESPONSE_OK:
 
750
                        pattern = tools.prepare_path( fcd.get_filename() )
 
751
                        self.add_exclude_( pattern )
 
752
                
 
753
                fcd.destroy()
 
754
        
 
755
        def on_remove_exclude( self, button ):
 
756
                store, iter = self.list_exclude.get_selection().get_selected()
 
757
                if not iter is None:
 
758
                        store.remove( iter )
 
759
        
 
760
        def on_cancel( self, button ):
 
761
                self.dialog.destroy()
 
762
        
 
763
        def validate( self ):
 
764
                self.save_profile()
 
765
                
 
766
                if not self.config.check_config():
 
767
                        return False
 
768
                
 
769
                if not self.config.setup_cron():
 
770
                        return False
 
771
                
 
772
                self.config.set_bool_value( 'gnome.use_gloobus_preview', self.cb_use_gloobus_preview.get_active() )
 
773
 
 
774
                self.config.save()
 
775
                return True
 
776