Merge lp:~freshapplepy/backintime/gtkbuilder into lp:backintime/1.0
- gtkbuilder
- Merge into release-1.0
Proposed by
Isaiah Heyer
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~freshapplepy/backintime/gtkbuilder |
Merge into: | lp:backintime/1.0 |
Diff against target: |
6008 lines 8 files modified
gnome/app.py (+1063/-1053) gnome/mainwindow.glade (+125/-131) gnome/messagebox.py (+39/-32) gnome/settingsdialog.glade (+215/-214) gnome/settingsdialog.py (+555/-544) gnome/snapshotsdialog.glade (+93/-82) gnome/snapshotsdialog.py (+302/-295) gnome/textinputdialog.glade (+43/-32) |
To merge this branch: | bzr merge lp:~freshapplepy/backintime/gtkbuilder |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Bart de Koning (community) | Approve | ||
Dan | Pending | ||
Review via email: mp+11914@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Isaiah Heyer (freshapplepy) wrote : | # |
> Nice rewrite of the GUI to switch from the libglade to the GTKbuilder format!
Has Dan looked at it yet?
- 616. By Isaiah Heyer
-
Corrected grammar.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'gnome/app.py' |
2 | --- gnome/app.py 2009-06-17 09:49:51 +0000 |
3 | +++ gnome/app.py 2009-10-01 16:35:20 +0000 |
4 | @@ -22,7 +22,7 @@ |
5 | import sys |
6 | |
7 | if len( os.getenv( 'DISPLAY', '' ) ) == 0: |
8 | - os.putenv( 'DISPLAY', ':0.0' ) |
9 | + os.putenv( 'DISPLAY', ':0.0' ) |
10 | |
11 | import pygtk |
12 | pygtk.require("2.0") |
13 | @@ -30,7 +30,6 @@ |
14 | import pynotify |
15 | import threading |
16 | import gobject |
17 | -import gtk.glade |
18 | import gnome |
19 | import gnomevfs |
20 | import datetime |
21 | @@ -57,1061 +56,1072 @@ |
22 | _=gettext.gettext |
23 | |
24 | |
25 | -class AboutDialog( gtk.AboutDialog ): |
26 | - def __init__( self, config, parent ): |
27 | - gtk.AboutDialog.__init__( self ) |
28 | - |
29 | - self.connect( 'close', self.on_close ) |
30 | - self.connect( 'response', self.on_close ) |
31 | - |
32 | - self.set_transient_for( parent ) |
33 | - |
34 | - self.set_name( config.APP_NAME ) |
35 | - self.set_version( config.VERSION ) |
36 | - self.set_copyright( 'Copyright (C) 2008-2009 Oprea Dan' ) |
37 | - self.set_website( 'http://backintime.le-web.org' ) |
38 | - self.set_website_label( 'http://backintime.le-web.org' ) |
39 | - self.set_license( config.get_license() ) |
40 | - authors = config.get_authors() |
41 | - if not authors is None: |
42 | - self.set_authors( authors.split( '\n' ) ) |
43 | - |
44 | - #extra_translations = _('about-translators').strip() |
45 | - #if extra_translations is None: |
46 | - # extra_translations = '' |
47 | - #elif extra_translations == 'about-translators': |
48 | - # extra_translations = '' |
49 | - # |
50 | - #self.set_translator_credits( config.get_translations() + extra_translations ) |
51 | - self.set_translator_credits( config.get_translations() ) |
52 | - |
53 | - def on_close( self, *params ): |
54 | - self.destroy() |
55 | - |
56 | - |
57 | -class MainWindow: |
58 | - def __init__( self, config, app_instance ): |
59 | - self.config = config |
60 | - self.app_instance = app_instance |
61 | - self.snapshots = snapshots.Snapshots( config ) |
62 | - self.special_background_color = 'lightblue' |
63 | - self.popup_menu = None |
64 | - |
65 | - self.folder_path = None |
66 | - self.snapshot_id = '' |
67 | - |
68 | - self.last_take_snapshot_message = None |
69 | - |
70 | - self.glade = gtk.glade.XML( os.path.join( self.config.get_app_path(), 'gnome', 'mainwindow.glade' ), None, 'backintime' ) |
71 | - |
72 | - signals = { |
73 | - 'on_MainWindow_destroy' : gtk.main_quit, |
74 | - 'on_MainWindow_delete_event' : self.on_close, |
75 | - 'on_MainWindow_key_release_event': self.on_key_release_event, |
76 | - 'on_btn_exit_clicked' : self.on_close, |
77 | - 'on_btn_link_clicked' : self.on_btn_link_clicked, |
78 | - 'on_btn_help_clicked' : self.on_btn_help_clicked, |
79 | - 'on_btn_about_clicked' : self.on_btn_about_clicked, |
80 | - 'on_btn_settings_clicked' : self.on_btn_settings_clicked, |
81 | - 'on_btn_backup_clicked' : self.on_btn_backup_clicked, |
82 | - 'on_btn_update_snapshots_clicked' : self.on_btn_update_snapshots_clicked, |
83 | - 'on_btn_snapshot_name_clicked' : self.on_btn_snapshot_name_clicked, |
84 | - 'on_btn_remove_snapshot_clicked' : self.on_btn_remove_snapshot_clicked, |
85 | - 'on_btn_restore_clicked' : self.on_btn_restore_clicked, |
86 | - 'on_btn_copy_clicked' : self.on_btn_copy_clicked, |
87 | - 'on_btn_snapshots_clicked' : self.on_btn_snapshots_clicked, |
88 | - 'on_btn_hidden_files_toggled' : self.on_btn_hidden_files_toggled, |
89 | - 'on_list_places_cursor_changed' : self.on_list_places_cursor_changed, |
90 | - 'on_list_time_line_cursor_changed' : self.on_list_time_line_cursor_changed, |
91 | - 'on_btn_folder_up_clicked' : self.on_btn_fodler_up_clicked, |
92 | - 'on_list_folder_view_row_activated' : self.on_list_folder_view_row_activated, |
93 | - 'on_list_folder_view_popup_menu' : self.on_list_folder_view_popup_menu, |
94 | - 'on_list_folder_view_button_press_event': self.on_list_folder_view_button_press_event, |
95 | - 'on_list_folder_view_drag_data_get': self.on_list_folder_view_drag_data_get, |
96 | - 'on_combo_profiles_changed': self.on_combo_profiles_changed, |
97 | - } |
98 | - |
99 | - self.glade.signal_autoconnect( signals ) |
100 | - |
101 | - self.window = self.glade.get_widget( 'MainWindow' ) |
102 | - self.window.set_title( self.config.APP_NAME ) |
103 | - |
104 | - #icons |
105 | - self.icon_names = fileicons.GnomeFileIcons() |
106 | - |
107 | - #fix a glade bug |
108 | - self.glade.get_widget( 'btn_current_path' ).set_expand( True ) |
109 | - #self.glade.get_widget( 'tb_sep_item' ).set_expand( True ) |
110 | - |
111 | - #profiles |
112 | - self.disable_combo_changed = True |
113 | - self.first_update_all = True |
114 | - |
115 | - self.store_profiles = gtk.ListStore( str, str ) |
116 | - |
117 | - self.combo_profiles = self.glade.get_widget( 'combo_profiles' ) |
118 | - |
119 | - text_renderer = gtk.CellRendererText() |
120 | - self.combo_profiles.pack_start( text_renderer, True ) |
121 | - self.combo_profiles.add_attribute( text_renderer, 'text', 0 ) |
122 | - |
123 | - self.combo_profiles.set_model( self.store_profiles ) |
124 | - |
125 | - self.disable_combo_changed = False |
126 | - |
127 | - #lbl snapshot |
128 | - self.lbl_snapshot = self.glade.get_widget( 'lbl_snapshot' ) |
129 | - |
130 | - #status bar |
131 | - self.status_bar = self.glade.get_widget( 'status_bar' ) |
132 | - self.status_bar.push( 0, _('Done') ) |
133 | - |
134 | - #show hidden files |
135 | - self.show_hidden_files = self.config.get_bool_value( 'gnome.show_hidden_files', False ) |
136 | - self.btn_hidden_files = self.glade.get_widget( 'btn_hidden_files' ) |
137 | - self.btn_hidden_files.set_active( self.show_hidden_files ) |
138 | - #self.btn_hidden_files.set_label( _('Hidden files') ) #!!! |
139 | - |
140 | - #setup places view |
141 | - self.list_places = self.glade.get_widget( 'list_places' ) |
142 | - |
143 | - pix_renderer = gtk.CellRendererPixbuf() |
144 | - text_renderer = gtk.CellRendererText() |
145 | - |
146 | - column = gtk.TreeViewColumn( _('Shortcuts') ) |
147 | - column.pack_start( pix_renderer, False ) |
148 | - column.pack_end( text_renderer, True ) |
149 | - column.add_attribute( pix_renderer, 'icon-name', 2 ) |
150 | - column.add_attribute( text_renderer, 'markup', 0 ) |
151 | - column.set_cell_data_func( pix_renderer, self.places_pix_renderer_function, None ) |
152 | - column.set_cell_data_func( text_renderer, self.places_text_renderer_function, None ) |
153 | - #column.set_alignment( 0.5 ) |
154 | - self.list_places.append_column( column ) |
155 | - |
156 | - #name, icon, path |
157 | - self.store_places = gtk.ListStore( str, str, str ) |
158 | - self.list_places.set_model( self.store_places ) |
159 | - self.list_places.get_selection().set_select_function( self.places_select_function, self.store_places ) |
160 | - |
161 | - #setup folder view |
162 | - self.list_folder_view_widget = self.glade.get_widget( 'list_folder_view_widget' ) |
163 | - self.list_folder_view_shadow = self.glade.get_widget( 'list_folder_view_shadow' ) |
164 | - self.list_folder_view = self.glade.get_widget( 'list_folder_view' ) |
165 | - |
166 | - pix_renderer = gtk.CellRendererPixbuf() |
167 | - text_renderer = gtk.CellRendererText() |
168 | - |
169 | - column = gtk.TreeViewColumn( _('Name') ) |
170 | - column.pack_start( pix_renderer, False ) |
171 | - column.pack_end( text_renderer, True ) |
172 | - column.add_attribute( pix_renderer, 'icon-name', 2 ) |
173 | - column.add_attribute( text_renderer, 'markup', 0 ) |
174 | - column.set_expand( True ) |
175 | - column.set_sizing( gtk.TREE_VIEW_COLUMN_AUTOSIZE ) |
176 | - column.set_sort_column_id( 0 ) |
177 | - self.list_folder_view.append_column( column ) |
178 | - |
179 | - text_renderer = gtk.CellRendererText() |
180 | - column = gtk.TreeViewColumn( _('Size') ) |
181 | - column.pack_end( text_renderer, True ) |
182 | - column.add_attribute( text_renderer, 'markup', 4 ) |
183 | - column.set_sort_column_id( 1 ) |
184 | - self.list_folder_view.append_column( column ) |
185 | - |
186 | - text_renderer = gtk.CellRendererText() |
187 | - column = gtk.TreeViewColumn( _('Date') ) |
188 | - column.pack_end( text_renderer, True ) |
189 | - column.add_attribute( text_renderer, 'markup', 5 ) |
190 | - column.set_sort_column_id( 2 ) |
191 | - self.list_folder_view.append_column( column ) |
192 | - |
193 | - # display name, relative path, icon_name, type (0 - directory, 1 - file), size (str), date, size (int) |
194 | - self.store_folder_view = gtk.ListStore( str, str, str, int, str, str, int ) |
195 | - self.store_folder_view.set_sort_func( 0, self.sort_folder_view_by_column, 0 ) #name |
196 | - self.store_folder_view.set_sort_func( 1, self.sort_folder_view_by_column, 6 ) #size |
197 | - self.store_folder_view.set_sort_func( 2, self.sort_folder_view_by_column, 5 ) #date |
198 | - self.store_folder_view.set_sort_column_id( 0, gtk.SORT_ASCENDING ) |
199 | - |
200 | - self.list_folder_view.set_model( self.store_folder_view ) |
201 | - |
202 | - #setup time line view |
203 | - self.list_time_line = self.glade.get_widget( 'list_time_line' ) |
204 | - |
205 | - text_renderer = gtk.CellRendererText() |
206 | - column = gtk.TreeViewColumn( _('Snapshots'), text_renderer, markup = 0 ) |
207 | - column.set_cell_data_func( text_renderer, self.places_text_renderer_function, None ) |
208 | - self.list_time_line.append_column( column ) |
209 | - |
210 | - #display name, id |
211 | - self.store_time_line = gtk.ListStore( str, str ) |
212 | - self.list_time_line.set_model( self.store_time_line ) |
213 | - self.list_time_line.get_selection().set_select_function( self.places_select_function, self.store_time_line ) |
214 | - self.update_time_line = False |
215 | - |
216 | - #calculate specialBackgroundColor |
217 | - style = self.list_time_line.get_style() |
218 | - bg1 = style.bg[gtk.STATE_NORMAL] |
219 | - bg2 = style.bg[gtk.STATE_SELECTED] |
220 | - self.special_background_color = gtk.gdk.Color( (2 * bg1.red + bg2.red) / 3, (2 * bg1.green + bg2.green) / 3,(2 * bg1.blue + bg2.blue) / 3 ).to_string() |
221 | - |
222 | - #restore size & position |
223 | - main_window_x = self.config.get_int_value( 'gnome.main_window.x', -1 ) |
224 | - main_window_y = self.config.get_int_value( 'gnome.main_window.y', -1 ) |
225 | - if main_window_x >= 0 and main_window_y >= 0: |
226 | - self.window.move( main_window_x, main_window_y ) |
227 | - |
228 | - main_window_width = self.config.get_int_value( 'gnome.main_window.width', -1 ) |
229 | - main_window_height = self.config.get_int_value( 'gnome.main_window.height', -1 ) |
230 | - if main_window_width > 0 and main_window_height > 0: |
231 | - self.window.resize( main_window_width, main_window_height ) |
232 | - |
233 | - main_window_hpaned1 = self.config.get_int_value( 'gnome.main_window.hpaned1', -1 ) |
234 | - main_window_hpaned2 = self.config.get_int_value( 'gnome.main_window.hpaned2', -1 ) |
235 | - if main_window_hpaned1 > 0 and main_window_hpaned2 > 0: |
236 | - self.glade.get_widget('hpaned1').set_position( main_window_hpaned1 ) |
237 | - self.glade.get_widget('hpaned2').set_position( main_window_hpaned2 ) |
238 | - |
239 | - #prepare popup menu ids |
240 | - gtk.stock_add( |
241 | - [ ('backintime.open', _('Open'), 0, 0, 'backintime' ), |
242 | - ('backintime.copy', _('Copy'), 0, 0, 'backintime' ), |
243 | - ('backintime.snapshots', _('Snapshots'), 0, 0, 'backintime' ), |
244 | - ('backintime.diff', _('Diff'), 0, 0, 'backintime' ), |
245 | - ('backintime.restore', _('Restore'), 0, 0, 'backintime' ) ] ) |
246 | - |
247 | - #show main window |
248 | - self.window.show() |
249 | - gnometools.run_gtk_update_loop() |
250 | - |
251 | - self.force_wait_lock_counter = 0 |
252 | - gobject.timeout_add( 1000, self.raise_application ) |
253 | - |
254 | - if not self.config.is_configured(): |
255 | - settingsdialog.SettingsDialog( self.config, self ).run() |
256 | - |
257 | - if not self.config.is_configured(): |
258 | - return |
259 | - |
260 | - if not self.config.can_backup(): |
261 | - messagebox.show_error( self.window, self.config, _('Can\'t find snapshots folder.\nIf it is on a removable drive please plug it and then press OK') ) |
262 | - |
263 | - self.update_profiles() |
264 | - self.update_backup_info() |
265 | - gobject.timeout_add( 1000, self.update_backup_info ) |
266 | - |
267 | - def on_combo_profiles_changed( self, *params ): |
268 | - if self.disable_combo_changed: |
269 | - return |
270 | - |
271 | - iter = self.combo_profiles.get_active_iter() |
272 | - if iter is None: |
273 | - return |
274 | - |
275 | - first_update_all = self.first_update_all |
276 | - |
277 | - profile_id = self.store_profiles.get_value( iter, 1 ) |
278 | - if not first_update_all and profile_id == self.config.get_current_profile(): |
279 | - return |
280 | - |
281 | - self.config.set_current_profile( profile_id ) |
282 | - self.first_update_all = False |
283 | - self.update_all( first_update_all ) |
284 | - |
285 | - def update_profiles( self ): |
286 | - self.disable_combo_changed = True |
287 | - |
288 | - profiles = self.config.get_profiles_sorted_by_name() |
289 | - |
290 | - select_iter = None |
291 | - self.store_profiles.clear() |
292 | - |
293 | - for profile_id in profiles: |
294 | - iter = self.store_profiles.append( [ self.config.get_profile_name( profile_id ), profile_id ] ) |
295 | - if profile_id == self.config.get_current_profile(): |
296 | - select_iter = iter |
297 | - |
298 | - |
299 | - self.disable_combo_changed = False |
300 | - |
301 | - if not select_iter is None: |
302 | - self.combo_profiles.set_active_iter( select_iter ) |
303 | - |
304 | - #self.update_all( True ) |
305 | - |
306 | - def sort_folder_view_by_column( self, treemodel, iter1, iter2, column ): |
307 | - if 0 == column: |
308 | - ascending = 1 |
309 | - if self.store_folder_view.get_sort_column_id()[1] != gtk.SORT_ASCENDING: |
310 | - ascending = -1 |
311 | - |
312 | - type1 = self.store_folder_view.get_value( iter1, 3 ) |
313 | - type2 = self.store_folder_view.get_value( iter2, 3 ) |
314 | - |
315 | - if type1 == 0 and type2 != 0: |
316 | - return -1 * ascending |
317 | - |
318 | - if type1 != 0 and type2 == 0: |
319 | - return 1 * ascending |
320 | - |
321 | - data1 = self.store_folder_view.get_value( iter1, column ) |
322 | - data2 = self.store_folder_view.get_value( iter2, column ) |
323 | - |
324 | - if type(data1) is str: |
325 | - data1 = data1.upper() |
326 | - |
327 | - if type(data2) is str: |
328 | - data2 = data2.upper() |
329 | - |
330 | - #print "sort_folder_view_by_column: " + str( data1 ) + " - " + str( data2 ) |
331 | - |
332 | - if data1 < data2: |
333 | - return -1 |
334 | - |
335 | - if data1 > data2: |
336 | - return 1 |
337 | - |
338 | - return 0 |
339 | - |
340 | - |
341 | - def get_default_startup_folder_and_file( self ): |
342 | - last_path = self.config.get_str_value( 'gnome.last_path', '' ) |
343 | - if len(last_path) > 0 and os.path.isdir(last_path): |
344 | - return ( last_path, None, False ) |
345 | - return ( '/', None, False ) |
346 | - |
347 | - def get_cmd_startup_folder_and_file( self, cmd ): |
348 | - if cmd is None: |
349 | - cmd = self.app_instance.raise_cmd |
350 | - |
351 | - if len( cmd ) < 1: |
352 | - return None |
353 | - |
354 | - path = None |
355 | - show_snapshots = False |
356 | - |
357 | - for arg in cmd.split( '\n' ): |
358 | - if len( arg ) < 1: |
359 | - continue |
360 | - if arg == '-s' or arg == '--snapshots': |
361 | - show_snapshots = True |
362 | - continue |
363 | - if arg[0] == '-': |
364 | - continue |
365 | - if path is None: |
366 | - path = arg |
367 | - |
368 | - if path is None: |
369 | - return None |
370 | - |
371 | - if len( path ) < 1: |
372 | - return None |
373 | - |
374 | - path = os.path.expanduser( path ) |
375 | - path = os.path.abspath( path ) |
376 | - |
377 | - if os.path.isdir( path ): |
378 | - if len( path ) < 1: |
379 | - show_snapshots = False |
380 | - |
381 | - if show_snapshots: |
382 | - return ( os.path.dirname( path ), path, True ) |
383 | - else: |
384 | - return ( path, '', False ) |
385 | - |
386 | - if os.path.isfile( path ): |
387 | - return ( os.path.dirname( path ), path, show_snapshots ) |
388 | - |
389 | - return None |
390 | - |
391 | - def get_startup_folder_and_file( self, cmd = None ): |
392 | - startup_folder = self.get_cmd_startup_folder_and_file( cmd ) |
393 | - if startup_folder is None: |
394 | - return self.get_default_startup_folder_and_file() |
395 | - return startup_folder |
396 | - |
397 | - def update_all( self, init ): |
398 | - #fill lists |
399 | - selected_file = None |
400 | - show_snapshots = False |
401 | - if init: |
402 | - self.folder_path, selected_file, show_snapshots = self.get_startup_folder_and_file() |
403 | - self.snapshot_id = '/' |
404 | - self.snapshots_list = [] |
405 | - |
406 | - self.fill_places() |
407 | - self.fill_time_line( False ) |
408 | - self.update_folder_view( 1, selected_file, show_snapshots ) |
409 | - |
410 | - def places_pix_renderer_function( self, column, renderer, model, iter, user_data ): |
411 | - if len( model.get_value( iter, 1 ) ) == 0: |
412 | - renderer.set_property( 'visible', False ) |
413 | - else: |
414 | - renderer.set_property( 'visible', True ) |
415 | - |
416 | - def places_text_renderer_function( self, column, renderer, model, iter, user_data ): |
417 | - if len( model.get_value( iter, 1 ) ) == 0: |
418 | - renderer.set_property( 'cell-background-set', True ) |
419 | - renderer.set_property( 'cell-background', self.special_background_color ) |
420 | - else: |
421 | - renderer.set_property( 'cell-background-set', False ) |
422 | - |
423 | - def places_select_function( self, info, store ): |
424 | - if len( store.get_value( store.get_iter( info[0] ), 1 ) ) == 0: |
425 | - return False |
426 | - return True |
427 | - |
428 | - def raise_application( self ): |
429 | - raise_cmd = self.app_instance.raise_command() |
430 | - if raise_cmd is None: |
431 | - return True |
432 | - |
433 | - print "Raise cmd: " + raise_cmd |
434 | - self.window.present_with_time( int(time.time()) ) |
435 | - self.window.window.focus() |
436 | - #self.window.present() |
437 | - |
438 | - if len( raise_cmd ) == 0: |
439 | - return True |
440 | - |
441 | - print "Check if the main window is the only top level visible window" |
442 | - for window in gtk.window_list_toplevels(): |
443 | - if window.get_property( 'visible' ): |
444 | - if window != self.window: |
445 | - print "Failed" |
446 | - return True |
447 | - |
448 | - print "OK" |
449 | - |
450 | - folder_and_file = self.get_cmd_startup_folder_and_file( raise_cmd ) |
451 | - if folder_and_file is None: |
452 | - return True |
453 | - |
454 | - folder_path, file_name, show_snapshots = folder_and_file |
455 | - |
456 | - #select now |
457 | - self.snapshot_id = '/' |
458 | - self.list_time_line.get_selection().select_iter( self.store_time_line.get_iter_first() ) |
459 | - |
460 | - #select the specified file |
461 | - self.folder_path = folder_path |
462 | - self.update_folder_view( 1, file_name, show_snapshots ) |
463 | - |
464 | - return True |
465 | - |
466 | - def update_backup_info( self, force_wait_lock = False ): |
467 | - if None is self.glade.get_widget( 'btn_backup' ): |
468 | - return True |
469 | - |
470 | - #print "forceWaitLock: %s" % forceWaitLock |
471 | - |
472 | - if force_wait_lock: |
473 | - self.force_wait_lock_counter = 10 |
474 | - |
475 | - busy = self.snapshots.is_busy() |
476 | - if busy: |
477 | - self.force_wait_lock_counter = 0 |
478 | - |
479 | - if self.force_wait_lock_counter > 0: |
480 | - self.force_wait_lock_counter = self.force_wait_lock_counter - 1 |
481 | - |
482 | - fake_busy = busy or self.force_wait_lock_counter > 0 |
483 | - self.glade.get_widget( 'btn_backup' ).set_sensitive( not fake_busy ) |
484 | - |
485 | - if fake_busy: |
486 | - take_snapshot_message = None |
487 | - |
488 | - if busy: |
489 | - take_snapshot_message = self.snapshots.get_take_snapshot_message() |
490 | - |
491 | - if take_snapshot_message is None: |
492 | - take_snapshot_message = ( 0, '...' ) |
493 | - |
494 | - if take_snapshot_message != self.last_take_snapshot_message: |
495 | - self.last_take_snapshot_message = take_snapshot_message |
496 | - self.status_bar.push( 0, _('Working:') + ' ' + self.last_take_snapshot_message[1].replace( '\n', ' ' ) ) |
497 | - |
498 | - if not self.update_time_line: |
499 | - self.update_time_line = True |
500 | - elif self.update_time_line: |
501 | - self.update_time_line = False |
502 | - snapshots_list = self.snapshots_list |
503 | - |
504 | - self.fill_time_line() |
505 | - |
506 | - #print "New backup: %s" % self.lastBackupList |
507 | - #print "Last backup: %s" % lastBackupList |
508 | - |
509 | - if snapshots_list != self.snapshots_list: |
510 | - self.status_bar.push( 0, _('Done') ) |
511 | - else: |
512 | - self.status_bar.push( 0, _('Done, no backup needed') ) |
513 | - |
514 | - if not fake_busy: |
515 | - self.last_take_snapshot_message = None |
516 | - |
517 | - return True |
518 | - |
519 | - def fill_places( self ): |
520 | - self.store_places.clear() |
521 | - |
522 | - #add global places |
523 | - self.store_places.append( [ "<b>%s</b>" % _('Global'), '', '' ] ) |
524 | - self.store_places.append( [ _('Root'), '/', gtk.STOCK_HARDDISK ] ) |
525 | - self.store_places.append( [ _('Home'), os.path.expanduser( '~' ), gtk.STOCK_HOME ] ) |
526 | - |
527 | - #add bookmarks |
528 | - rawbookmarks = '' |
529 | - |
530 | - try: |
531 | - file = open( os.path.expanduser('~/.gtk-bookmarks') ) |
532 | - rawbookmarks = file.read() |
533 | - file.close() |
534 | - except: |
535 | - pass |
536 | - |
537 | - bookmarks = [] |
538 | - for rawbookmark in rawbookmarks.split( '\n' ): |
539 | - if rawbookmark.startswith( 'file://' ): |
540 | - index = rawbookmark.find( ' ' ) |
541 | - if index > 0: |
542 | - bookmarks.append( ( gnomevfs.unescape_string_for_display( rawbookmark[ 7 : index ] ), rawbookmark[ index + 1 : ] ) ) |
543 | - elif index < 0: |
544 | - index = rawbookmark.rfind( '/' ) |
545 | - if index > 0: |
546 | - bookmarks.append( ( gnomevfs.unescape_string_for_display( rawbookmark[ 7 : ] ), gnomevfs.unescape_string_for_display( rawbookmark[ index + 1 : ] ) ) ) |
547 | - |
548 | - if len( bookmarks ) > 0: |
549 | - self.store_places.append( [ "<b>%s</b>" % _('Bookmarks'), '', '' ] ) |
550 | - for bookmark in bookmarks: |
551 | - self.store_places.append( [ bookmark[1], bookmark[0], self.icon_names.get_icon(bookmark[0]) ] ) |
552 | - |
553 | - #add backup folders |
554 | - include_folders = self.config.get_include_folders() |
555 | - if len( include_folders ) > 0: |
556 | - if len( include_folders ) > 0: |
557 | - self.store_places.append( [ "<b>%s</b>" % _('Backup folders'), '', '' ] ) |
558 | - for folder in include_folders: |
559 | - self.store_places.append( [ folder[0], folder[0], gtk.STOCK_SAVE ] ) |
560 | - |
561 | - def fill_time_line( self, update_folder_view = True ): |
562 | - current_selection = '/' |
563 | - iter = self.list_time_line.get_selection().get_selected()[1] |
564 | - if not iter is None: |
565 | - current_selection = self.store_time_line.get_value( iter, 1 ) |
566 | - |
567 | - self.store_time_line.clear() |
568 | - self.store_time_line.append( [ gnometools.get_snapshot_display_markup( self.snapshots, '/' ), '/' ] ) |
569 | - |
570 | - self.snapshots_list = self.snapshots.get_snapshots_list() |
571 | - |
572 | - groups = [] |
573 | - now = datetime.date.today() |
574 | - |
575 | - #today |
576 | - date = now |
577 | - groups.append( (_('Today'), self.snapshots.get_snapshot_id( date ), []) ) |
578 | - |
579 | - #yesterday |
580 | - date = now - datetime.timedelta( days = 1 ) |
581 | - groups.append( (_('Yesterday'), self.snapshots.get_snapshot_id( date ), []) ) |
582 | - |
583 | - #this week |
584 | - date = now - datetime.timedelta( days = now.weekday() ) |
585 | - groups.append( (_('This week'), self.snapshots.get_snapshot_id( date ), []) ) |
586 | - |
587 | - #last week |
588 | - date = now - datetime.timedelta( days = now.weekday() + 7 ) |
589 | - groups.append( (_('Last week'), self.snapshots.get_snapshot_id( date ), []) ) |
590 | - |
591 | - #fill groups |
592 | - for snapshot_id in self.snapshots_list: |
593 | - found = False |
594 | - |
595 | - for group in groups: |
596 | - if snapshot_id >= group[1]: |
597 | - group[2].append( snapshot_id ) |
598 | - found = True |
599 | - break |
600 | - |
601 | - if not found: |
602 | - year = int( snapshot_id[ 0 : 4 ] ) |
603 | - month = int( snapshot_id[ 4 : 6 ] ) |
604 | - date = datetime.date( year, month, 1 ) |
605 | - |
606 | - group_name = '' |
607 | - if year == now.year: |
608 | - group_name = date.strftime( '%B' ).capitalize() |
609 | - else: |
610 | - group_name = date.strftime( '%B, %Y' ).capitalize() |
611 | - |
612 | - groups.append( ( group_name, self.snapshots.get_snapshot_id( date ), [ snapshot_id ]) ) |
613 | - |
614 | - #fill time_line list |
615 | - for group in groups: |
616 | - if len( group[2] ) > 0: |
617 | - self.store_time_line.append( [ "<b>%s</b>" % group[0], '' ] ); |
618 | - for snapshot_id in group[2]: |
619 | - self.store_time_line.append( [ gnometools.get_snapshot_display_markup( self.snapshots, snapshot_id ), snapshot_id ] ) |
620 | - |
621 | - #select previous item |
622 | - iter = self.store_time_line.get_iter_first() |
623 | - while not iter is None: |
624 | - if current_selection == self.store_time_line.get_value( iter, 1 ): |
625 | - break |
626 | - iter = self.store_time_line.iter_next( iter ) |
627 | - |
628 | - changed = False |
629 | - if iter is None: |
630 | - changed = True |
631 | - iter = self.store_time_line.get_iter_first() |
632 | - |
633 | - self.list_time_line.get_selection().select_iter( iter ) |
634 | - |
635 | - if changed and update_folder_view: |
636 | - self.update_folder_view( 2 ) |
637 | - |
638 | - def on_close( self, *params ): |
639 | - main_window_x, main_window_y = self.window.get_position() |
640 | - main_window_width, main_window_height = self.window.get_size() |
641 | - main_window_hpaned1 = self.glade.get_widget('hpaned1').get_position() |
642 | - main_window_hpaned2 = self.glade.get_widget('hpaned2').get_position() |
643 | - |
644 | - self.config.set_int_value( 'gnome.main_window.x', main_window_x ) |
645 | - self.config.set_int_value( 'gnome.main_window.y', main_window_y ) |
646 | - self.config.set_int_value( 'gnome.main_window.width', main_window_width ) |
647 | - self.config.set_int_value( 'gnome.main_window.height', main_window_height ) |
648 | - self.config.set_int_value( 'gnome.main_window.hpaned1', main_window_hpaned1 ) |
649 | - self.config.set_int_value( 'gnome.main_window.hpaned2', main_window_hpaned2 ) |
650 | - self.config.set_str_value( 'gnome.last_path', self.folder_path ) |
651 | - self.config.set_bool_value( 'gnome.show_hidden_files', self.show_hidden_files ) |
652 | - |
653 | - self.config.save() |
654 | - self.window.destroy() |
655 | - return True |
656 | - |
657 | - def on_list_time_line_cursor_changed( self, list ): |
658 | - if list.get_selection().path_is_selected( list.get_cursor()[ 0 ] ): |
659 | - self.update_folder_view( 2 ) |
660 | - |
661 | - def on_list_places_cursor_changed( self, list ): |
662 | - if list.get_selection().path_is_selected( list.get_cursor()[ 0 ] ): |
663 | - iter = list.get_selection().get_selected()[1] |
664 | - folder_path = self.store_places.get_value( iter, 1 ) |
665 | - if folder_path != self.folder_path: |
666 | - self.folder_path = folder_path |
667 | - self.update_folder_view( 0 ) |
668 | - |
669 | - def on_list_folder_view_drag_data_get( self, widget, drag_context, selection_data, info, timestamp, user_param1 = None ): |
670 | - iter = self.list_folder_view.get_selection().get_selected()[1] |
671 | - if not iter is None: |
672 | - path = self.store_folder_view.get_value( iter, 1 ) |
673 | - path = self.snapshots.get_snapshot_path_to( self.snapshot_id, path ) |
674 | - path = gnomevfs.escape_path_string( path ) |
675 | - selection_data.set_uris( [ 'file://' + path ] ) |
676 | - |
677 | - def on_list_folder_view_button_press_event( self, list, event ): |
678 | - if event.button != 3: |
679 | - return |
680 | - |
681 | - if len( self.store_folder_view ) <= 0: |
682 | - return |
683 | - |
684 | - path = self.list_folder_view.get_path_at_pos( int( event.x ), int( event.y ) ) |
685 | - if path is None: |
686 | - return |
687 | - path = path[0] |
688 | - |
689 | - self.list_folder_view.get_selection().select_path( path ) |
690 | - self.show_folder_view_menu_popup( self.list_folder_view, event.button, event.time ) |
691 | - |
692 | - def on_list_folder_view_popup_menu( self, list ): |
693 | - self.show_folder_view_menu_popup( list, 1, gtk.get_current_event_time() ) |
694 | - |
695 | - def show_folder_view_menu_popup( self, list, button, time ): |
696 | - iter = list.get_selection().get_selected()[1] |
697 | - if iter is None: |
698 | - return |
699 | - |
700 | - #print "popup-menu" |
701 | - self.popup_menu = gtk.Menu() |
702 | - |
703 | - menu_item = gtk.ImageMenuItem( 'backintime.open' ) |
704 | - menu_item.set_image( gtk.image_new_from_icon_name( self.store_folder_view.get_value( iter, 2 ), gtk.ICON_SIZE_MENU ) ) |
705 | - menu_item.connect( 'activate', self.on_list_folder_view_open_item ) |
706 | - self.popup_menu.append( menu_item ) |
707 | - |
708 | - self.popup_menu.append( gtk.SeparatorMenuItem() ) |
709 | - |
710 | - menu_item = gtk.ImageMenuItem( 'backintime.copy' ) |
711 | - menu_item.set_image( gtk.image_new_from_stock( gtk.STOCK_COPY, gtk.ICON_SIZE_MENU ) ) |
712 | - menu_item.connect( 'activate', self.on_list_folder_view_copy_item ) |
713 | - self.popup_menu.append( menu_item ) |
714 | - |
715 | - menu_item = gtk.ImageMenuItem( 'backintime.snapshots' ) |
716 | - menu_item.set_image( gtk.image_new_from_stock( gtk.STOCK_INDEX, gtk.ICON_SIZE_MENU ) ) |
717 | - menu_item.connect( 'activate', self.on_list_folder_view_snapshots_item ) |
718 | - self.popup_menu.append( menu_item ) |
719 | - |
720 | - if len( self.snapshot_id ) > 1: |
721 | - menu_item = gtk.ImageMenuItem( 'backintime.restore' ) |
722 | - menu_item.set_image( gtk.image_new_from_stock( gtk.STOCK_UNDELETE, gtk.ICON_SIZE_MENU ) ) |
723 | - menu_item.connect( 'activate', self.on_list_folder_view_restore_item ) |
724 | - self.popup_menu.append( menu_item ) |
725 | - |
726 | - self.popup_menu.show_all() |
727 | - self.popup_menu.popup( None, None, None, button, time ) |
728 | - |
729 | - def on_list_folder_view_restore_item( self, widget, data = None ): |
730 | - self.on_btn_restore_clicked( self.glade.get_widget( 'btn_restore' ) ) |
731 | - |
732 | - def on_list_folder_view_copy_item( self, widget, data = None ): |
733 | - self.on_btn_copy_clicked( self.glade.get_widget( 'btn_copy' ) ) |
734 | - |
735 | - def on_list_folder_view_snapshots_item( self, widget, data = None ): |
736 | - self.on_btn_snapshots_clicked( self.glade.get_widget( 'btn_snapshots' ) ) |
737 | - |
738 | - def on_list_folder_view_open_item( self, widget, data = None ): |
739 | - iter = self.list_folder_view.get_selection().get_selected()[1] |
740 | - if iter is None: |
741 | - return |
742 | - |
743 | - path = self.store_folder_view.get_value( iter, 1 ) |
744 | - path = self.snapshots.get_snapshot_path_to( self.snapshot_id, path ) |
745 | - cmd = "gnome-open \"%s\" &" % path |
746 | - print cmd |
747 | - os.system( cmd ) |
748 | - |
749 | - def on_list_folder_view_row_activated( self, list, path, column ): |
750 | - iter = list.get_selection().get_selected()[1] |
751 | - path = self.store_folder_view.get_value( iter, 1 ) |
752 | - |
753 | - #directory |
754 | - if 0 == self.store_folder_view.get_value( iter, 3 ): |
755 | - self.folder_path = path |
756 | - self.update_folder_view( 1 ) |
757 | - return |
758 | - |
759 | - #file |
760 | - path = self.snapshots.get_snapshot_path_to( self.snapshot_id, path ) |
761 | - cmd = "gnome-open \"%s\" &" % path |
762 | - print cmd |
763 | - os.system( cmd ) |
764 | - |
765 | - def on_btn_fodler_up_clicked( self, button ): |
766 | - if len( self.folder_path ) <= 1: |
767 | - return |
768 | - |
769 | - index = self.folder_path.rfind( '/' ) |
770 | - if index < 1: |
771 | - parent_path = "/" |
772 | - else: |
773 | - parent_path = self.folder_path[ : index ] |
774 | - |
775 | - self.folder_path = parent_path |
776 | - self.update_folder_view( 1 ) |
777 | - |
778 | - def on_btn_restore_clicked( self, button ): |
779 | - iter = self.list_folder_view.get_selection().get_selected()[1] |
780 | - if not iter is None: |
781 | - button.set_sensitive( False ) |
782 | - gnometools.run_gtk_update_loop() |
783 | - self.snapshots.restore( self.snapshot_id, self.store_folder_view.get_value( iter, 1 ) ) |
784 | - button.set_sensitive( True ) |
785 | - |
786 | - def on_btn_copy_clicked( self, button ): |
787 | - iter = self.list_folder_view.get_selection().get_selected()[1] |
788 | - if iter is None: |
789 | - return |
790 | - |
791 | - path = self.store_folder_view.get_value( iter, 1 ) |
792 | - path = self.snapshots.get_snapshot_path_to( self.snapshot_id, path ) |
793 | - |
794 | - clipboardtools.clipboard_copy_path( path ) |
795 | - |
796 | - def on_btn_hidden_files_toggled( self, button ): |
797 | - if self.folder_path is None: |
798 | - return |
799 | - |
800 | - self.show_hidden_files = button.get_active() |
801 | - self.update_folder_view( 0 ) |
802 | - |
803 | - def on_btn_snapshots_clicked( self, button ): |
804 | - iter = self.list_folder_view.get_selection().get_selected()[1] |
805 | - if iter is None: |
806 | - return |
807 | - |
808 | - path = self.store_folder_view.get_value( iter, 1 ) |
809 | - icon_name = self.store_folder_view.get_value( iter, 2 ) |
810 | - |
811 | - retVal = snapshotsdialog.SnapshotsDialog( self.snapshots, self.window, path, self.snapshots_list, self.snapshot_id, icon_name ).run() |
812 | - |
813 | - #select the specified file |
814 | - if not retVal is None: |
815 | - iter = self.store_time_line.get_iter_first() |
816 | - while not iter is None: |
817 | - snapshot_id = self.store_time_line.get_value( iter, 1 ) |
818 | - if snapshot_id == retVal: |
819 | - break |
820 | - iter = self.store_time_line.iter_next( iter ) |
821 | - |
822 | - if not iter is None: |
823 | - self.list_time_line.get_selection().select_iter( iter ) |
824 | - self.update_folder_view( 2 ) |
825 | - |
826 | - def on_btn_about_clicked( self, button ): |
827 | - AboutDialog( self.config, self.window ).run() |
828 | - |
829 | - def on_help( self ): |
830 | - gnome.help_display('backintime') |
831 | - |
832 | - def on_btn_help_clicked( self, button ): |
833 | - self.on_help() |
834 | - |
835 | - def on_btn_link_clicked( self, button ): |
836 | - os.system( "gnome-open http://backintime.le-web.org &" ) |
837 | - |
838 | - def on_key_release_event( self, widget, event ): |
839 | - if 'F1' == gtk.gdk.keyval_name( event.keyval ) and ( event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK) ) == 0: |
840 | - self.on_help() |
841 | - |
842 | - def on_btn_settings_clicked( self, button ): |
843 | - snapshots_path = self.config.get_snapshots_path() |
844 | - include_folders = self.config.get_include_folders() |
845 | - |
846 | - settingsdialog.SettingsDialog( self.config, self ).run() |
847 | - |
848 | - if snapshots_path != self.config.get_snapshots_path() or include_folders != self.config.get_include_folders(): |
849 | - self.update_all( False ) |
850 | - |
851 | - def on_btn_snapshot_name_clicked( self, button ): |
852 | - iter = self.list_time_line.get_selection().get_selected()[1] |
853 | - if iter is None: |
854 | - return |
855 | - |
856 | - snapshot_id = self.store_time_line.get_value( iter, 1 ) |
857 | - if len( snapshot_id ) <= 1: |
858 | - return |
859 | - |
860 | - old_name = self.snapshots.get_snapshot_name( snapshot_id ) |
861 | - new_name = messagebox.text_input_dialog( self.window, self.config, _('Snapshot Name'), old_name ) |
862 | - if new_name is None: |
863 | - return |
864 | - |
865 | - if old_name == new_name: |
866 | - return |
867 | - |
868 | - self.snapshots.set_snapshot_name( snapshot_id, new_name ) |
869 | - self.store_time_line.set_value( iter, 0, gnometools.get_snapshot_display_markup( self.snapshots, snapshot_id ) ) |
870 | - |
871 | - def on_btn_remove_snapshot_clicked( self, button ): |
872 | - iter = self.list_time_line.get_selection().get_selected()[1] |
873 | - if iter is None: |
874 | - return |
875 | - |
876 | - snapshot_id = self.store_time_line.get_value( iter, 1 ) |
877 | - if len( snapshot_id ) <= 1: |
878 | - return |
879 | - |
880 | - if gtk.RESPONSE_YES == messagebox.show_question( self.window, self.config, _('Are you sure you want to remove the snapshot:\n<b>%s</b>') % self.snapshots.get_snapshot_display_name( snapshot_id ) ): |
881 | - print "Remove Snapshot: %s" % snapshot_id |
882 | - self.snapshots.remove_snapshot( snapshot_id ) |
883 | - self.fill_time_line() |
884 | - |
885 | - def on_btn_backup_clicked( self, button ): |
886 | - button.set_sensitive( False ) |
887 | - self.updatetime_line = True |
888 | - |
889 | - if self.snapshots.is_busy(): |
890 | - self.update_backup_info() |
891 | - return |
892 | - |
893 | - backintime.take_snapshot_now_async( self.config ) |
894 | - self.update_backup_info( True ) |
895 | - |
896 | - def on_btn_update_snapshots_clicked( self, button ): |
897 | - self.fill_time_line( False ) |
898 | - self.update_folder_view( 2 ) |
899 | - |
900 | - def update_folder_view( self, changed_from, selected_file = None, show_snapshots = False ): #0 - places, 1 - folder view, 2 - time_line |
901 | - #update backup time |
902 | - if 2 == changed_from: |
903 | - iter = self.list_time_line.get_selection().get_selected()[1] |
904 | - self.snapshot_id = self.store_time_line.get_value( iter, 1 ) |
905 | - #self.lblTime.set_markup( "<b>%s</b>" % backupTime ) |
906 | - |
907 | - tooltip = '' |
908 | - text = '' |
909 | - if len( self.snapshot_id ) > 1: |
910 | - name = self.snapshots.get_snapshot_display_id( self.snapshot_id ) |
911 | - text = _('Snapshot: %s') % name |
912 | - tooltip = _('View the snapshot made at %s') % name |
913 | - else: |
914 | - tooltip = _('View the current disk content') |
915 | - text = _('Now') |
916 | - |
917 | - self.lbl_snapshot.set_markup( ' <b>' + text + '</b> ' ) |
918 | - self.lbl_snapshot.set_tooltip_text( tooltip ) |
919 | - |
920 | - #update selected places item |
921 | - if 1 == changed_from: |
922 | - iter = self.store_places.get_iter_first() |
923 | - while not iter is None: |
924 | - place_path = self.store_places.get_value( iter, 1 ) |
925 | - if place_path == self.folder_path: |
926 | - break |
927 | - iter = self.store_places.iter_next( iter ) |
928 | - |
929 | - if iter is None: |
930 | - self.list_places.get_selection().unselect_all() |
931 | - else: |
932 | - self.list_places.get_selection().select_iter( iter ) |
933 | - |
934 | - #update folder view |
935 | - |
936 | - full_path = self.snapshots.get_snapshot_path_to( self.snapshot_id, self.folder_path ) |
937 | - all_files = [] |
938 | - files = [] |
939 | - folder_exists = os.path.isdir( full_path ) |
940 | - |
941 | - if folder_exists: |
942 | - try: |
943 | - all_files = os.listdir( full_path ) |
944 | - all_files.sort() |
945 | - except: |
946 | - pass |
947 | - |
948 | - files = [] |
949 | - for file in all_files: |
950 | - if len( file ) == 0: |
951 | - continue |
952 | - |
953 | - if not self.show_hidden_files: |
954 | - if file[ 0 ] == '.': |
955 | - continue |
956 | - if file[ -1 ] == '~': |
957 | - continue |
958 | - |
959 | - path = os.path.join( full_path, file ) |
960 | - |
961 | - file_size = -1 |
962 | - file_date = -1 |
963 | - |
964 | - try: |
965 | - file_stat = os.stat( path ) |
966 | - file_size = file_stat[stat.ST_SIZE] |
967 | - file_date = file_stat[stat.ST_MTIME] |
968 | - except: |
969 | - pass |
970 | - |
971 | - #format size |
972 | - file_size_int = file_size |
973 | - if file_size_int < 0: |
974 | - file_size_int = 0 |
975 | - |
976 | - if file_size < 0: |
977 | - file_size = 'unknown' |
978 | - elif file_size < 1024: |
979 | - file_size = str( file_size ) + ' bytes' |
980 | - elif file_size < 1024 * 1024: |
981 | - file_size = file_size / 1024 |
982 | - file_size = str( file_size ) + ' KB' |
983 | - elif file_size < 1024 * 1024 * 1024: |
984 | - file_size = file_size / ( 1024 * 1024 ) |
985 | - file_size = str( file_size ) + ' MB' |
986 | - else: |
987 | - file_size = file_size / ( 1024 * 1024 * 1024 ) |
988 | - file_size = str( file_size ) + ' GB' |
989 | - |
990 | - #format date |
991 | - if file_date < 0: |
992 | - file_date = 'unknown' |
993 | - else: |
994 | - file_date = datetime.datetime.fromtimestamp(file_date).isoformat(' ') |
995 | - |
996 | - if os.path.isdir( path ): |
997 | - files.append( [ file, file_size, file_date, self.icon_names.get_icon(path), file_size_int, 0 ] ) |
998 | - else: |
999 | - files.append( [ file, file_size, file_date, self.icon_names.get_icon(path), file_size_int, 1 ] ) |
1000 | - |
1001 | - #try to keep old selected file |
1002 | - if selected_file is None: |
1003 | - selected_file = '' |
1004 | - iter = self.list_folder_view.get_selection().get_selected()[1] |
1005 | - if not iter is None: |
1006 | - selected_file = self.store_folder_view.get_value( iter, 1 ) |
1007 | - |
1008 | - self.list_folder_view_widget.show() |
1009 | - self.list_folder_view_shadow.hide() |
1010 | - else: |
1011 | - self.list_folder_view_widget.hide() |
1012 | - self.list_folder_view_shadow.show() |
1013 | - |
1014 | - #populate the list |
1015 | - self.store_folder_view.clear() |
1016 | - |
1017 | - selected_iter = None |
1018 | - for item in files: |
1019 | - rel_path = os.path.join( self.folder_path, item[0] ) |
1020 | - new_iter = self.store_folder_view.append( [ item[0], rel_path, item[3], item[5], item[1], item[2], item[4] ] ) |
1021 | - if selected_file == rel_path: |
1022 | - selected_iter = new_iter |
1023 | - |
1024 | - #select old item or the first item |
1025 | - if len( files ) > 0: |
1026 | - if selected_iter is None: |
1027 | - selected_iter = self.store_folder_view.get_iter_first() |
1028 | - self.list_folder_view.get_selection().select_iter( selected_iter ) |
1029 | - self.list_folder_view.drag_source_set( gtk.gdk.BUTTON1_MASK | gtk.gdk.BUTTON3_MASK, gtk.target_list_add_uri_targets(), gtk.gdk.ACTION_COPY ) |
1030 | - else: |
1031 | - self.list_folder_view.drag_source_unset() |
1032 | - |
1033 | - #update folderup button state |
1034 | - self.glade.get_widget( 'btn_folder_up' ).set_sensitive( len( self.folder_path ) > 1 ) |
1035 | - |
1036 | - #update restore button state |
1037 | - self.glade.get_widget( 'btn_restore' ).set_sensitive( len( self.snapshot_id ) > 1 and len( self.store_folder_view ) > 0 ) |
1038 | - |
1039 | - #update remove/name snapshot buttons |
1040 | - self.glade.get_widget( 'btn_snapshot_name' ).set_sensitive( len( self.snapshot_id ) > 1 ) |
1041 | - self.glade.get_widget( 'btn_remove_snapshot' ).set_sensitive( len( self.snapshot_id ) > 1 ) |
1042 | - |
1043 | - #update copy button state |
1044 | - self.glade.get_widget( 'btn_copy' ).set_sensitive( len( self.store_folder_view ) > 0 ) |
1045 | - |
1046 | - #update snapshots button state |
1047 | - self.glade.get_widget( 'btn_snapshots' ).set_sensitive( len( self.store_folder_view ) > 0 ) |
1048 | - |
1049 | - #display current folder |
1050 | - self.glade.get_widget( 'edit_current_path' ).set_text( self.folder_path ) |
1051 | - |
1052 | - #show snapshots |
1053 | - if show_snapshots: |
1054 | - self.on_btn_snapshots_clicked( None ) |
1055 | +class AboutDialog(gtk.AboutDialog): |
1056 | + |
1057 | + def __init__( self, config, parent ): |
1058 | + |
1059 | + gtk.AboutDialog.__init__( self ) |
1060 | + |
1061 | + self.connect( 'close', self.on_close ) |
1062 | + self.connect( 'response', self.on_close ) |
1063 | + |
1064 | + self.set_transient_for( parent ) |
1065 | + |
1066 | + self.set_name( config.APP_NAME ) |
1067 | + self.set_version( config.VERSION ) |
1068 | + self.set_copyright( 'Copyright (C) 2008-2009 Oprea Dan' ) |
1069 | + self.set_website( 'http://backintime.le-web.org' ) |
1070 | + self.set_website_label( 'http://backintime.le-web.org' ) |
1071 | + self.set_license( config.get_license() ) |
1072 | + authors = config.get_authors() |
1073 | + if not authors is None: |
1074 | + self.set_authors( authors.split( '\n' ) ) |
1075 | + |
1076 | + #extra_translations = _('about-translators').strip() |
1077 | + #if extra_translations is None: |
1078 | + # extra_translations = '' |
1079 | + #elif extra_translations == 'about-translators': |
1080 | + # extra_translations = '' |
1081 | + # |
1082 | + #self.set_translator_credits( config.get_translations() + extra_translations ) |
1083 | + self.set_translator_credits( config.get_translations() ) |
1084 | + |
1085 | + def on_close( self, *params ): |
1086 | + self.destroy() |
1087 | + |
1088 | + |
1089 | +class MainWindow(object): |
1090 | + |
1091 | + def __init__( self, config, app_instance ): |
1092 | + |
1093 | + self.config = config |
1094 | + self.app_instance = app_instance |
1095 | + self.snapshots = snapshots.Snapshots( config ) |
1096 | + self.special_background_color = 'lightblue' |
1097 | + self.popup_menu = None |
1098 | + |
1099 | + self.folder_path = None |
1100 | + self.snapshot_id = '' |
1101 | + |
1102 | + self.last_take_snapshot_message = None |
1103 | + |
1104 | + |
1105 | + builder = gtk.Builder() |
1106 | + self.builder = builder |
1107 | + |
1108 | + glade_file = os.path.join(self.config.get_app_path(), 'gnome', |
1109 | + 'mainwindow.glade') |
1110 | + |
1111 | + builder.add_from_file(glade_file) |
1112 | + |
1113 | + signals = { |
1114 | + 'on_MainWindow_destroy' : gtk.main_quit, |
1115 | + 'on_MainWindow_delete_event' : self.on_close, |
1116 | + 'on_MainWindow_key_release_event': self.on_key_release_event, |
1117 | + 'on_btn_exit_clicked' : self.on_close, |
1118 | + 'on_btn_link_clicked' : self.on_btn_link_clicked, |
1119 | + 'on_btn_help_clicked' : self.on_btn_help_clicked, |
1120 | + 'on_btn_about_clicked' : self.on_btn_about_clicked, |
1121 | + 'on_btn_settings_clicked' : self.on_btn_settings_clicked, |
1122 | + 'on_btn_backup_clicked' : self.on_btn_backup_clicked, |
1123 | + 'on_btn_update_snapshots_clicked' : self.on_btn_update_snapshots_clicked, |
1124 | + 'on_btn_snapshot_name_clicked' : self.on_btn_snapshot_name_clicked, |
1125 | + 'on_btn_remove_snapshot_clicked' : self.on_btn_remove_snapshot_clicked, |
1126 | + 'on_btn_restore_clicked' : self.on_btn_restore_clicked, |
1127 | + 'on_btn_copy_clicked' : self.on_btn_copy_clicked, |
1128 | + 'on_btn_snapshots_clicked' : self.on_btn_snapshots_clicked, |
1129 | + 'on_btn_hidden_files_toggled' : self.on_btn_hidden_files_toggled, |
1130 | + 'on_list_places_cursor_changed' : self.on_list_places_cursor_changed, |
1131 | + 'on_list_time_line_cursor_changed' : self.on_list_time_line_cursor_changed, |
1132 | + 'on_btn_folder_up_clicked' : self.on_btn_fodler_up_clicked, |
1133 | + 'on_list_folder_view_row_activated' : self.on_list_folder_view_row_activated, |
1134 | + 'on_list_folder_view_popup_menu' : self.on_list_folder_view_popup_menu, |
1135 | + 'on_list_folder_view_button_press_event': self.on_list_folder_view_button_press_event, |
1136 | + 'on_list_folder_view_drag_data_get': self.on_list_folder_view_drag_data_get, |
1137 | + 'on_combo_profiles_changed': self.on_combo_profiles_changed, |
1138 | + } |
1139 | + |
1140 | + builder.connect_signals(signals) |
1141 | + |
1142 | + self.window = self.builder.get_object( 'MainWindow' ) |
1143 | + self.window.set_title( self.config.APP_NAME ) |
1144 | + |
1145 | + #icons |
1146 | + self.icon_names = fileicons.GnomeFileIcons() |
1147 | + |
1148 | + #fix a glade bug |
1149 | + self.builder.get_object( 'btn_current_path' ).set_expand( True ) |
1150 | + #self.builder.get_object( 'tb_sep_item' ).set_expand( True ) |
1151 | + |
1152 | + #profiles |
1153 | + self.disable_combo_changed = True |
1154 | + self.first_update_all = True |
1155 | + |
1156 | + self.store_profiles = gtk.ListStore( str, str ) |
1157 | + |
1158 | + self.combo_profiles = self.builder.get_object( 'combo_profiles' ) |
1159 | + |
1160 | + text_renderer = gtk.CellRendererText() |
1161 | + self.combo_profiles.pack_start( text_renderer, True ) |
1162 | + self.combo_profiles.add_attribute( text_renderer, 'text', 0 ) |
1163 | + |
1164 | + self.combo_profiles.set_model( self.store_profiles ) |
1165 | + |
1166 | + self.disable_combo_changed = False |
1167 | + |
1168 | + #lbl snapshot |
1169 | + self.lbl_snapshot = self.builder.get_object( 'lbl_snapshot' ) |
1170 | + |
1171 | + #status bar |
1172 | + self.status_bar = self.builder.get_object( 'status_bar' ) |
1173 | + self.status_bar.push( 0, _('Done') ) |
1174 | + |
1175 | + #show hidden files |
1176 | + self.show_hidden_files = self.config.get_bool_value( 'gnome.show_hidden_files', False ) |
1177 | + self.btn_hidden_files = self.builder.get_object( 'btn_hidden_files' ) |
1178 | + self.btn_hidden_files.set_active( self.show_hidden_files ) |
1179 | + #self.btn_hidden_files.set_label( _('Hidden files') ) #!!! |
1180 | + |
1181 | + #setup places view |
1182 | + self.list_places = self.builder.get_object( 'list_places' ) |
1183 | + |
1184 | + pix_renderer = gtk.CellRendererPixbuf() |
1185 | + text_renderer = gtk.CellRendererText() |
1186 | + |
1187 | + column = gtk.TreeViewColumn( _('Shortcuts') ) |
1188 | + column.pack_start( pix_renderer, False ) |
1189 | + column.pack_end( text_renderer, True ) |
1190 | + column.add_attribute( pix_renderer, 'icon-name', 2 ) |
1191 | + column.add_attribute( text_renderer, 'markup', 0 ) |
1192 | + column.set_cell_data_func( pix_renderer, self.places_pix_renderer_function, None ) |
1193 | + column.set_cell_data_func( text_renderer, self.places_text_renderer_function, None ) |
1194 | + #column.set_alignment( 0.5 ) |
1195 | + self.list_places.append_column( column ) |
1196 | + |
1197 | + #name, icon, path |
1198 | + self.store_places = gtk.ListStore( str, str, str ) |
1199 | + self.list_places.set_model( self.store_places ) |
1200 | + self.list_places.get_selection().set_select_function( self.places_select_function, self.store_places ) |
1201 | + |
1202 | + #setup folder view |
1203 | + self.list_folder_view_widget = self.builder.get_object( 'list_folder_view_widget' ) |
1204 | + self.list_folder_view_shadow = self.builder.get_object( 'list_folder_view_shadow' ) |
1205 | + self.list_folder_view = self.builder.get_object( 'list_folder_view' ) |
1206 | + |
1207 | + pix_renderer = gtk.CellRendererPixbuf() |
1208 | + text_renderer = gtk.CellRendererText() |
1209 | + |
1210 | + column = gtk.TreeViewColumn( _('Name') ) |
1211 | + column.pack_start( pix_renderer, False ) |
1212 | + column.pack_end( text_renderer, True ) |
1213 | + column.add_attribute( pix_renderer, 'icon-name', 2 ) |
1214 | + column.add_attribute( text_renderer, 'markup', 0 ) |
1215 | + column.set_expand( True ) |
1216 | + column.set_sizing( gtk.TREE_VIEW_COLUMN_AUTOSIZE ) |
1217 | + column.set_sort_column_id( 0 ) |
1218 | + self.list_folder_view.append_column( column ) |
1219 | + |
1220 | + text_renderer = gtk.CellRendererText() |
1221 | + column = gtk.TreeViewColumn( _('Size') ) |
1222 | + column.pack_end( text_renderer, True ) |
1223 | + column.add_attribute( text_renderer, 'markup', 4 ) |
1224 | + column.set_sort_column_id( 1 ) |
1225 | + self.list_folder_view.append_column( column ) |
1226 | + |
1227 | + text_renderer = gtk.CellRendererText() |
1228 | + column = gtk.TreeViewColumn( _('Date') ) |
1229 | + column.pack_end( text_renderer, True ) |
1230 | + column.add_attribute( text_renderer, 'markup', 5 ) |
1231 | + column.set_sort_column_id( 2 ) |
1232 | + self.list_folder_view.append_column( column ) |
1233 | + |
1234 | + # display name, relative path, icon_name, type (0 - directory, 1 - file), size (str), date, size (int) |
1235 | + self.store_folder_view = gtk.ListStore( str, str, str, int, str, str, int ) |
1236 | + self.store_folder_view.set_sort_func( 0, self.sort_folder_view_by_column, 0 ) #name |
1237 | + self.store_folder_view.set_sort_func( 1, self.sort_folder_view_by_column, 6 ) #size |
1238 | + self.store_folder_view.set_sort_func( 2, self.sort_folder_view_by_column, 5 ) #date |
1239 | + self.store_folder_view.set_sort_column_id( 0, gtk.SORT_ASCENDING ) |
1240 | + |
1241 | + self.list_folder_view.set_model( self.store_folder_view ) |
1242 | + |
1243 | + #setup time line view |
1244 | + self.list_time_line = self.builder.get_object( 'list_time_line' ) |
1245 | + |
1246 | + text_renderer = gtk.CellRendererText() |
1247 | + column = gtk.TreeViewColumn( _('Snapshots'), text_renderer, markup = 0 ) |
1248 | + column.set_cell_data_func( text_renderer, self.places_text_renderer_function, None ) |
1249 | + self.list_time_line.append_column( column ) |
1250 | + |
1251 | + #display name, id |
1252 | + self.store_time_line = gtk.ListStore( str, str ) |
1253 | + self.list_time_line.set_model( self.store_time_line ) |
1254 | + self.list_time_line.get_selection().set_select_function( self.places_select_function, self.store_time_line ) |
1255 | + self.update_time_line = False |
1256 | + |
1257 | + #calculate specialBackgroundColor |
1258 | + style = self.list_time_line.get_style() |
1259 | + bg1 = style.bg[gtk.STATE_NORMAL] |
1260 | + bg2 = style.bg[gtk.STATE_SELECTED] |
1261 | + self.special_background_color = gtk.gdk.Color( (2 * bg1.red + bg2.red) / 3, (2 * bg1.green + bg2.green) / 3,(2 * bg1.blue + bg2.blue) / 3 ).to_string() |
1262 | + |
1263 | + #restore size & position |
1264 | + main_window_x = self.config.get_int_value( 'gnome.main_window.x', -1 ) |
1265 | + main_window_y = self.config.get_int_value( 'gnome.main_window.y', -1 ) |
1266 | + if main_window_x >= 0 and main_window_y >= 0: |
1267 | + self.window.move( main_window_x, main_window_y ) |
1268 | + |
1269 | + main_window_width = self.config.get_int_value( 'gnome.main_window.width', -1 ) |
1270 | + main_window_height = self.config.get_int_value( 'gnome.main_window.height', -1 ) |
1271 | + if main_window_width > 0 and main_window_height > 0: |
1272 | + self.window.resize( main_window_width, main_window_height ) |
1273 | + |
1274 | + main_window_hpaned1 = self.config.get_int_value( 'gnome.main_window.hpaned1', -1 ) |
1275 | + main_window_hpaned2 = self.config.get_int_value( 'gnome.main_window.hpaned2', -1 ) |
1276 | + if main_window_hpaned1 > 0 and main_window_hpaned2 > 0: |
1277 | + self.builder.get_object('hpaned1').set_position( main_window_hpaned1 ) |
1278 | + self.builder.get_object('hpaned2').set_position( main_window_hpaned2 ) |
1279 | + |
1280 | + #prepare popup menu ids |
1281 | + gtk.stock_add( |
1282 | + [ ('backintime.open', _('Open'), 0, 0, 'backintime' ), |
1283 | + ('backintime.copy', _('Copy'), 0, 0, 'backintime' ), |
1284 | + ('backintime.snapshots', _('Snapshots'), 0, 0, 'backintime' ), |
1285 | + ('backintime.diff', _('Diff'), 0, 0, 'backintime' ), |
1286 | + ('backintime.restore', _('Restore'), 0, 0, 'backintime' ) ] ) |
1287 | + |
1288 | + #show main window |
1289 | + self.window.show() |
1290 | + gnometools.run_gtk_update_loop() |
1291 | + |
1292 | + self.force_wait_lock_counter = 0 |
1293 | + gobject.timeout_add( 1000, self.raise_application ) |
1294 | + |
1295 | + if not self.config.is_configured(): |
1296 | + settingsdialog.SettingsDialog( self.config, self ).run() |
1297 | + |
1298 | + if not self.config.is_configured(): |
1299 | + return |
1300 | + |
1301 | + if not self.config.can_backup(): |
1302 | + messagebox.show_error( self.window, self.config, _('Can\'t find snapshots folder.\nIf it is on a removable drive please plug it and then press OK') ) |
1303 | + |
1304 | + self.update_profiles() |
1305 | + self.update_backup_info() |
1306 | + gobject.timeout_add( 1000, self.update_backup_info ) |
1307 | + |
1308 | + def on_combo_profiles_changed( self, *params ): |
1309 | + if self.disable_combo_changed: |
1310 | + return |
1311 | + |
1312 | + iter = self.combo_profiles.get_active_iter() |
1313 | + if iter is None: |
1314 | + return |
1315 | + |
1316 | + first_update_all = self.first_update_all |
1317 | + |
1318 | + profile_id = self.store_profiles.get_value( iter, 1 ) |
1319 | + if not first_update_all and profile_id == self.config.get_current_profile(): |
1320 | + return |
1321 | + |
1322 | + self.config.set_current_profile( profile_id ) |
1323 | + self.first_update_all = False |
1324 | + self.update_all( first_update_all ) |
1325 | + |
1326 | + def update_profiles( self ): |
1327 | + self.disable_combo_changed = True |
1328 | + |
1329 | + profiles = self.config.get_profiles_sorted_by_name() |
1330 | + |
1331 | + select_iter = None |
1332 | + self.store_profiles.clear() |
1333 | + |
1334 | + for profile_id in profiles: |
1335 | + iter = self.store_profiles.append( [ self.config.get_profile_name( profile_id ), profile_id ] ) |
1336 | + if profile_id == self.config.get_current_profile(): |
1337 | + select_iter = iter |
1338 | + |
1339 | + |
1340 | + self.disable_combo_changed = False |
1341 | + |
1342 | + if not select_iter is None: |
1343 | + self.combo_profiles.set_active_iter( select_iter ) |
1344 | + |
1345 | + #self.update_all( True ) |
1346 | + |
1347 | + def sort_folder_view_by_column( self, treemodel, iter1, iter2, column ): |
1348 | + if 0 == column: |
1349 | + ascending = 1 |
1350 | + if self.store_folder_view.get_sort_column_id()[1] != gtk.SORT_ASCENDING: |
1351 | + ascending = -1 |
1352 | + |
1353 | + type1 = self.store_folder_view.get_value( iter1, 3 ) |
1354 | + type2 = self.store_folder_view.get_value( iter2, 3 ) |
1355 | + |
1356 | + if type1 == 0 and type2 != 0: |
1357 | + return -1 * ascending |
1358 | + |
1359 | + if type1 != 0 and type2 == 0: |
1360 | + return 1 * ascending |
1361 | + |
1362 | + data1 = self.store_folder_view.get_value( iter1, column ) |
1363 | + data2 = self.store_folder_view.get_value( iter2, column ) |
1364 | + |
1365 | + if type(data1) is str: |
1366 | + data1 = data1.upper() |
1367 | + |
1368 | + if type(data2) is str: |
1369 | + data2 = data2.upper() |
1370 | + |
1371 | + #print "sort_folder_view_by_column: " + str( data1 ) + " - " + str( data2 ) |
1372 | + |
1373 | + if data1 < data2: |
1374 | + return -1 |
1375 | + |
1376 | + if data1 > data2: |
1377 | + return 1 |
1378 | + |
1379 | + return 0 |
1380 | + |
1381 | + |
1382 | + def get_default_startup_folder_and_file( self ): |
1383 | + last_path = self.config.get_str_value( 'gnome.last_path', '' ) |
1384 | + if len(last_path) > 0 and os.path.isdir(last_path): |
1385 | + return ( last_path, None, False ) |
1386 | + return ( '/', None, False ) |
1387 | + |
1388 | + def get_cmd_startup_folder_and_file( self, cmd ): |
1389 | + if cmd is None: |
1390 | + cmd = self.app_instance.raise_cmd |
1391 | + |
1392 | + if len( cmd ) < 1: |
1393 | + return None |
1394 | + |
1395 | + path = None |
1396 | + show_snapshots = False |
1397 | + |
1398 | + for arg in cmd.split( '\n' ): |
1399 | + if len( arg ) < 1: |
1400 | + continue |
1401 | + if arg == '-s' or arg == '--snapshots': |
1402 | + show_snapshots = True |
1403 | + continue |
1404 | + if arg[0] == '-': |
1405 | + continue |
1406 | + if path is None: |
1407 | + path = arg |
1408 | + |
1409 | + if path is None: |
1410 | + return None |
1411 | + |
1412 | + if len( path ) < 1: |
1413 | + return None |
1414 | + |
1415 | + path = os.path.expanduser( path ) |
1416 | + path = os.path.abspath( path ) |
1417 | + |
1418 | + if os.path.isdir( path ): |
1419 | + if len( path ) < 1: |
1420 | + show_snapshots = False |
1421 | + |
1422 | + if show_snapshots: |
1423 | + return ( os.path.dirname( path ), path, True ) |
1424 | + else: |
1425 | + return ( path, '', False ) |
1426 | + |
1427 | + if os.path.isfile( path ): |
1428 | + return ( os.path.dirname( path ), path, show_snapshots ) |
1429 | + |
1430 | + return None |
1431 | + |
1432 | + def get_startup_folder_and_file( self, cmd = None ): |
1433 | + startup_folder = self.get_cmd_startup_folder_and_file( cmd ) |
1434 | + if startup_folder is None: |
1435 | + return self.get_default_startup_folder_and_file() |
1436 | + return startup_folder |
1437 | + |
1438 | + def update_all( self, init ): |
1439 | + #fill lists |
1440 | + selected_file = None |
1441 | + show_snapshots = False |
1442 | + if init: |
1443 | + self.folder_path, selected_file, show_snapshots = self.get_startup_folder_and_file() |
1444 | + self.snapshot_id = '/' |
1445 | + self.snapshots_list = [] |
1446 | + |
1447 | + self.fill_places() |
1448 | + self.fill_time_line( False ) |
1449 | + self.update_folder_view( 1, selected_file, show_snapshots ) |
1450 | + |
1451 | + def places_pix_renderer_function( self, column, renderer, model, iter, user_data ): |
1452 | + if len( model.get_value( iter, 1 ) ) == 0: |
1453 | + renderer.set_property( 'visible', False ) |
1454 | + else: |
1455 | + renderer.set_property( 'visible', True ) |
1456 | + |
1457 | + def places_text_renderer_function( self, column, renderer, model, iter, user_data ): |
1458 | + if len( model.get_value( iter, 1 ) ) == 0: |
1459 | + renderer.set_property( 'cell-background-set', True ) |
1460 | + renderer.set_property( 'cell-background', self.special_background_color ) |
1461 | + else: |
1462 | + renderer.set_property( 'cell-background-set', False ) |
1463 | + |
1464 | + def places_select_function( self, info, store ): |
1465 | + if len( store.get_value( store.get_iter( info[0] ), 1 ) ) == 0: |
1466 | + return False |
1467 | + return True |
1468 | + |
1469 | + def raise_application( self ): |
1470 | + raise_cmd = self.app_instance.raise_command() |
1471 | + if raise_cmd is None: |
1472 | + return True |
1473 | + |
1474 | + print "Raise cmd: " + raise_cmd |
1475 | + self.window.present_with_time( int(time.time()) ) |
1476 | + self.window.window.focus() |
1477 | + #self.window.present() |
1478 | + |
1479 | + if len( raise_cmd ) == 0: |
1480 | + return True |
1481 | + |
1482 | + print "Check if the main window is the only top level visible window" |
1483 | + for window in gtk.window_list_toplevels(): |
1484 | + if window.get_property( 'visible' ): |
1485 | + if window != self.window: |
1486 | + print "Failed" |
1487 | + return True |
1488 | + |
1489 | + print "OK" |
1490 | + |
1491 | + folder_and_file = self.get_cmd_startup_folder_and_file( raise_cmd ) |
1492 | + if folder_and_file is None: |
1493 | + return True |
1494 | + |
1495 | + folder_path, file_name, show_snapshots = folder_and_file |
1496 | + |
1497 | + #select now |
1498 | + self.snapshot_id = '/' |
1499 | + self.list_time_line.get_selection().select_iter( self.store_time_line.get_iter_first() ) |
1500 | + |
1501 | + #select the specified file |
1502 | + self.folder_path = folder_path |
1503 | + self.update_folder_view( 1, file_name, show_snapshots ) |
1504 | + |
1505 | + return True |
1506 | + |
1507 | + def update_backup_info( self, force_wait_lock = False ): |
1508 | + if None is self.builder.get_object( 'btn_backup' ): |
1509 | + return True |
1510 | + |
1511 | + #print "forceWaitLock: %s" % forceWaitLock |
1512 | + |
1513 | + if force_wait_lock: |
1514 | + self.force_wait_lock_counter = 10 |
1515 | + |
1516 | + busy = self.snapshots.is_busy() |
1517 | + if busy: |
1518 | + self.force_wait_lock_counter = 0 |
1519 | + |
1520 | + if self.force_wait_lock_counter > 0: |
1521 | + self.force_wait_lock_counter = self.force_wait_lock_counter - 1 |
1522 | + |
1523 | + fake_busy = busy or self.force_wait_lock_counter > 0 |
1524 | + self.builder.get_object( 'btn_backup' ).set_sensitive( not fake_busy ) |
1525 | + |
1526 | + if fake_busy: |
1527 | + take_snapshot_message = None |
1528 | + |
1529 | + if busy: |
1530 | + take_snapshot_message = self.snapshots.get_take_snapshot_message() |
1531 | + |
1532 | + if take_snapshot_message is None: |
1533 | + take_snapshot_message = ( 0, '...' ) |
1534 | + |
1535 | + if take_snapshot_message != self.last_take_snapshot_message: |
1536 | + self.last_take_snapshot_message = take_snapshot_message |
1537 | + self.status_bar.push( 0, _('Working:') + ' ' + self.last_take_snapshot_message[1].replace( '\n', ' ' ) ) |
1538 | + |
1539 | + if not self.update_time_line: |
1540 | + self.update_time_line = True |
1541 | + elif self.update_time_line: |
1542 | + self.update_time_line = False |
1543 | + snapshots_list = self.snapshots_list |
1544 | + |
1545 | + self.fill_time_line() |
1546 | + |
1547 | + #print "New backup: %s" % self.lastBackupList |
1548 | + #print "Last backup: %s" % lastBackupList |
1549 | + |
1550 | + if snapshots_list != self.snapshots_list: |
1551 | + self.status_bar.push( 0, _('Done') ) |
1552 | + else: |
1553 | + self.status_bar.push( 0, _('Done, no backup needed') ) |
1554 | + |
1555 | + if not fake_busy: |
1556 | + self.last_take_snapshot_message = None |
1557 | + |
1558 | + return True |
1559 | + |
1560 | + def fill_places( self ): |
1561 | + self.store_places.clear() |
1562 | + |
1563 | + #add global places |
1564 | + self.store_places.append( [ "<b>%s</b>" % _('Global'), '', '' ] ) |
1565 | + self.store_places.append( [ _('Root'), '/', gtk.STOCK_HARDDISK ] ) |
1566 | + self.store_places.append( [ _('Home'), os.path.expanduser( '~' ), gtk.STOCK_HOME ] ) |
1567 | + |
1568 | + #add bookmarks |
1569 | + rawbookmarks = '' |
1570 | + |
1571 | + try: |
1572 | + file = open( os.path.expanduser('~/.gtk-bookmarks') ) |
1573 | + rawbookmarks = file.read() |
1574 | + file.close() |
1575 | + except: |
1576 | + pass |
1577 | + |
1578 | + bookmarks = [] |
1579 | + for rawbookmark in rawbookmarks.split( '\n' ): |
1580 | + if rawbookmark.startswith( 'file://' ): |
1581 | + index = rawbookmark.find( ' ' ) |
1582 | + if index > 0: |
1583 | + bookmarks.append( ( gnomevfs.unescape_string_for_display( rawbookmark[ 7 : index ] ), rawbookmark[ index + 1 : ] ) ) |
1584 | + elif index < 0: |
1585 | + index = rawbookmark.rfind( '/' ) |
1586 | + if index > 0: |
1587 | + bookmarks.append( ( gnomevfs.unescape_string_for_display( rawbookmark[ 7 : ] ), gnomevfs.unescape_string_for_display( rawbookmark[ index + 1 : ] ) ) ) |
1588 | + |
1589 | + if len( bookmarks ) > 0: |
1590 | + self.store_places.append( [ "<b>%s</b>" % _('Bookmarks'), '', '' ] ) |
1591 | + for bookmark in bookmarks: |
1592 | + self.store_places.append( [ bookmark[1], bookmark[0], self.icon_names.get_icon(bookmark[0]) ] ) |
1593 | + |
1594 | + #add backup folders |
1595 | + include_folders = self.config.get_include_folders() |
1596 | + if len( include_folders ) > 0: |
1597 | + if len( include_folders ) > 0: |
1598 | + self.store_places.append( [ "<b>%s</b>" % _('Backup folders'), '', '' ] ) |
1599 | + for folder in include_folders: |
1600 | + self.store_places.append( [ folder[0], folder[0], gtk.STOCK_SAVE ] ) |
1601 | + |
1602 | + def fill_time_line( self, update_folder_view = True ): |
1603 | + current_selection = '/' |
1604 | + iter = self.list_time_line.get_selection().get_selected()[1] |
1605 | + if not iter is None: |
1606 | + current_selection = self.store_time_line.get_value( iter, 1 ) |
1607 | + |
1608 | + self.store_time_line.clear() |
1609 | + self.store_time_line.append( [ gnometools.get_snapshot_display_markup( self.snapshots, '/' ), '/' ] ) |
1610 | + |
1611 | + self.snapshots_list = self.snapshots.get_snapshots_list() |
1612 | + |
1613 | + groups = [] |
1614 | + now = datetime.date.today() |
1615 | + |
1616 | + #today |
1617 | + date = now |
1618 | + groups.append( (_('Today'), self.snapshots.get_snapshot_id( date ), []) ) |
1619 | + |
1620 | + #yesterday |
1621 | + date = now - datetime.timedelta( days = 1 ) |
1622 | + groups.append( (_('Yesterday'), self.snapshots.get_snapshot_id( date ), []) ) |
1623 | + |
1624 | + #this week |
1625 | + date = now - datetime.timedelta( days = now.weekday() ) |
1626 | + groups.append( (_('This week'), self.snapshots.get_snapshot_id( date ), []) ) |
1627 | + |
1628 | + #last week |
1629 | + date = now - datetime.timedelta( days = now.weekday() + 7 ) |
1630 | + groups.append( (_('Last week'), self.snapshots.get_snapshot_id( date ), []) ) |
1631 | + |
1632 | + #fill groups |
1633 | + for snapshot_id in self.snapshots_list: |
1634 | + found = False |
1635 | + |
1636 | + for group in groups: |
1637 | + if snapshot_id >= group[1]: |
1638 | + group[2].append( snapshot_id ) |
1639 | + found = True |
1640 | + break |
1641 | + |
1642 | + if not found: |
1643 | + year = int( snapshot_id[ 0 : 4 ] ) |
1644 | + month = int( snapshot_id[ 4 : 6 ] ) |
1645 | + date = datetime.date( year, month, 1 ) |
1646 | + |
1647 | + group_name = '' |
1648 | + if year == now.year: |
1649 | + group_name = date.strftime( '%B' ).capitalize() |
1650 | + else: |
1651 | + group_name = date.strftime( '%B, %Y' ).capitalize() |
1652 | + |
1653 | + groups.append( ( group_name, self.snapshots.get_snapshot_id( date ), [ snapshot_id ]) ) |
1654 | + |
1655 | + #fill time_line list |
1656 | + for group in groups: |
1657 | + if len( group[2] ) > 0: |
1658 | + self.store_time_line.append( [ "<b>%s</b>" % group[0], '' ] ); |
1659 | + for snapshot_id in group[2]: |
1660 | + self.store_time_line.append( [ gnometools.get_snapshot_display_markup( self.snapshots, snapshot_id ), snapshot_id ] ) |
1661 | + |
1662 | + #select previous item |
1663 | + iter = self.store_time_line.get_iter_first() |
1664 | + while not iter is None: |
1665 | + if current_selection == self.store_time_line.get_value( iter, 1 ): |
1666 | + break |
1667 | + iter = self.store_time_line.iter_next( iter ) |
1668 | + |
1669 | + changed = False |
1670 | + if iter is None: |
1671 | + changed = True |
1672 | + iter = self.store_time_line.get_iter_first() |
1673 | + |
1674 | + self.list_time_line.get_selection().select_iter( iter ) |
1675 | + |
1676 | + if changed and update_folder_view: |
1677 | + self.update_folder_view( 2 ) |
1678 | + |
1679 | + def on_close( self, *params ): |
1680 | + main_window_x, main_window_y = self.window.get_position() |
1681 | + main_window_width, main_window_height = self.window.get_size() |
1682 | + main_window_hpaned1 = self.builder.get_object('hpaned1').get_position() |
1683 | + main_window_hpaned2 = self.builder.get_object('hpaned2').get_position() |
1684 | + |
1685 | + self.config.set_int_value( 'gnome.main_window.x', main_window_x ) |
1686 | + self.config.set_int_value( 'gnome.main_window.y', main_window_y ) |
1687 | + self.config.set_int_value( 'gnome.main_window.width', main_window_width ) |
1688 | + self.config.set_int_value( 'gnome.main_window.height', main_window_height ) |
1689 | + self.config.set_int_value( 'gnome.main_window.hpaned1', main_window_hpaned1 ) |
1690 | + self.config.set_int_value( 'gnome.main_window.hpaned2', main_window_hpaned2 ) |
1691 | + self.config.set_str_value( 'gnome.last_path', self.folder_path ) |
1692 | + self.config.set_bool_value( 'gnome.show_hidden_files', self.show_hidden_files ) |
1693 | + |
1694 | + self.config.save() |
1695 | + self.window.destroy() |
1696 | + return True |
1697 | + |
1698 | + def on_list_time_line_cursor_changed( self, list ): |
1699 | + if list.get_selection().path_is_selected( list.get_cursor()[ 0 ] ): |
1700 | + self.update_folder_view( 2 ) |
1701 | + |
1702 | + def on_list_places_cursor_changed( self, list ): |
1703 | + if list.get_selection().path_is_selected( list.get_cursor()[ 0 ] ): |
1704 | + iter = list.get_selection().get_selected()[1] |
1705 | + folder_path = self.store_places.get_value( iter, 1 ) |
1706 | + if folder_path != self.folder_path: |
1707 | + self.folder_path = folder_path |
1708 | + self.update_folder_view( 0 ) |
1709 | + |
1710 | + def on_list_folder_view_drag_data_get( self, widget, drag_context, selection_data, info, timestamp, user_param1 = None ): |
1711 | + iter = self.list_folder_view.get_selection().get_selected()[1] |
1712 | + if not iter is None: |
1713 | + path = self.store_folder_view.get_value( iter, 1 ) |
1714 | + path = self.snapshots.get_snapshot_path_to( self.snapshot_id, path ) |
1715 | + path = gnomevfs.escape_path_string( path ) |
1716 | + selection_data.set_uris( [ 'file://' + path ] ) |
1717 | + |
1718 | + def on_list_folder_view_button_press_event( self, list, event ): |
1719 | + if event.button != 3: |
1720 | + return |
1721 | + |
1722 | + if len( self.store_folder_view ) <= 0: |
1723 | + return |
1724 | + |
1725 | + path = self.list_folder_view.get_path_at_pos( int( event.x ), int( event.y ) ) |
1726 | + if path is None: |
1727 | + return |
1728 | + path = path[0] |
1729 | + |
1730 | + self.list_folder_view.get_selection().select_path( path ) |
1731 | + self.show_folder_view_menu_popup( self.list_folder_view, event.button, event.time ) |
1732 | + |
1733 | + def on_list_folder_view_popup_menu( self, list ): |
1734 | + self.show_folder_view_menu_popup( list, 1, gtk.get_current_event_time() ) |
1735 | + |
1736 | + def show_folder_view_menu_popup( self, list, button, time ): |
1737 | + iter = list.get_selection().get_selected()[1] |
1738 | + if iter is None: |
1739 | + return |
1740 | + |
1741 | + #print "popup-menu" |
1742 | + self.popup_menu = gtk.Menu() |
1743 | + |
1744 | + menu_item = gtk.ImageMenuItem( 'backintime.open' ) |
1745 | + menu_item.set_image( gtk.image_new_from_icon_name( self.store_folder_view.get_value( iter, 2 ), gtk.ICON_SIZE_MENU ) ) |
1746 | + menu_item.connect( 'activate', self.on_list_folder_view_open_item ) |
1747 | + self.popup_menu.append( menu_item ) |
1748 | + |
1749 | + self.popup_menu.append( gtk.SeparatorMenuItem() ) |
1750 | + |
1751 | + menu_item = gtk.ImageMenuItem( 'backintime.copy' ) |
1752 | + menu_item.set_image( gtk.image_new_from_stock( gtk.STOCK_COPY, gtk.ICON_SIZE_MENU ) ) |
1753 | + menu_item.connect( 'activate', self.on_list_folder_view_copy_item ) |
1754 | + self.popup_menu.append( menu_item ) |
1755 | + |
1756 | + menu_item = gtk.ImageMenuItem( 'backintime.snapshots' ) |
1757 | + menu_item.set_image( gtk.image_new_from_stock( gtk.STOCK_INDEX, gtk.ICON_SIZE_MENU ) ) |
1758 | + menu_item.connect( 'activate', self.on_list_folder_view_snapshots_item ) |
1759 | + self.popup_menu.append( menu_item ) |
1760 | + |
1761 | + if len( self.snapshot_id ) > 1: |
1762 | + menu_item = gtk.ImageMenuItem( 'backintime.restore' ) |
1763 | + menu_item.set_image( gtk.image_new_from_stock( gtk.STOCK_UNDELETE, gtk.ICON_SIZE_MENU ) ) |
1764 | + menu_item.connect( 'activate', self.on_list_folder_view_restore_item ) |
1765 | + self.popup_menu.append( menu_item ) |
1766 | + |
1767 | + self.popup_menu.show_all() |
1768 | + self.popup_menu.popup( None, None, None, button, time ) |
1769 | + |
1770 | + def on_list_folder_view_restore_item( self, widget, data = None ): |
1771 | + self.on_btn_restore_clicked( self.builder.get_object( 'btn_restore' ) ) |
1772 | + |
1773 | + def on_list_folder_view_copy_item( self, widget, data = None ): |
1774 | + self.on_btn_copy_clicked( self.builder.get_object( 'btn_copy' ) ) |
1775 | + |
1776 | + def on_list_folder_view_snapshots_item( self, widget, data = None ): |
1777 | + self.on_btn_snapshots_clicked( self.builder.get_object( 'btn_snapshots' ) ) |
1778 | + |
1779 | + def on_list_folder_view_open_item( self, widget, data = None ): |
1780 | + iter = self.list_folder_view.get_selection().get_selected()[1] |
1781 | + if iter is None: |
1782 | + return |
1783 | + |
1784 | + path = self.store_folder_view.get_value( iter, 1 ) |
1785 | + path = self.snapshots.get_snapshot_path_to( self.snapshot_id, path ) |
1786 | + cmd = "gnome-open \"%s\" &" % path |
1787 | + print cmd |
1788 | + os.system( cmd ) |
1789 | + |
1790 | + def on_list_folder_view_row_activated( self, list, path, column ): |
1791 | + iter = list.get_selection().get_selected()[1] |
1792 | + path = self.store_folder_view.get_value( iter, 1 ) |
1793 | + |
1794 | + #directory |
1795 | + if 0 == self.store_folder_view.get_value( iter, 3 ): |
1796 | + self.folder_path = path |
1797 | + self.update_folder_view( 1 ) |
1798 | + return |
1799 | + |
1800 | + #file |
1801 | + path = self.snapshots.get_snapshot_path_to( self.snapshot_id, path ) |
1802 | + cmd = "gnome-open \"%s\" &" % path |
1803 | + print cmd |
1804 | + os.system( cmd ) |
1805 | + |
1806 | + def on_btn_fodler_up_clicked( self, button ): |
1807 | + if len( self.folder_path ) <= 1: |
1808 | + return |
1809 | + |
1810 | + index = self.folder_path.rfind( '/' ) |
1811 | + if index < 1: |
1812 | + parent_path = "/" |
1813 | + else: |
1814 | + parent_path = self.folder_path[ : index ] |
1815 | + |
1816 | + self.folder_path = parent_path |
1817 | + self.update_folder_view( 1 ) |
1818 | + |
1819 | + def on_btn_restore_clicked( self, button ): |
1820 | + iter = self.list_folder_view.get_selection().get_selected()[1] |
1821 | + if not iter is None: |
1822 | + button.set_sensitive( False ) |
1823 | + gnometools.run_gtk_update_loop() |
1824 | + self.snapshots.restore( self.snapshot_id, self.store_folder_view.get_value( iter, 1 ) ) |
1825 | + button.set_sensitive( True ) |
1826 | + |
1827 | + def on_btn_copy_clicked( self, button ): |
1828 | + iter = self.list_folder_view.get_selection().get_selected()[1] |
1829 | + if iter is None: |
1830 | + return |
1831 | + |
1832 | + path = self.store_folder_view.get_value( iter, 1 ) |
1833 | + path = self.snapshots.get_snapshot_path_to( self.snapshot_id, path ) |
1834 | + |
1835 | + clipboardtools.clipboard_copy_path( path ) |
1836 | + |
1837 | + def on_btn_hidden_files_toggled( self, button ): |
1838 | + if self.folder_path is None: |
1839 | + return |
1840 | + |
1841 | + self.show_hidden_files = button.get_active() |
1842 | + self.update_folder_view( 0 ) |
1843 | + |
1844 | + def on_btn_snapshots_clicked( self, button ): |
1845 | + iter = self.list_folder_view.get_selection().get_selected()[1] |
1846 | + if iter is None: |
1847 | + return |
1848 | + |
1849 | + path = self.store_folder_view.get_value( iter, 1 ) |
1850 | + icon_name = self.store_folder_view.get_value( iter, 2 ) |
1851 | + |
1852 | + retVal = snapshotsdialog.SnapshotsDialog( self.snapshots, self.window, path, self.snapshots_list, self.snapshot_id, icon_name ).run() |
1853 | + |
1854 | + #select the specified file |
1855 | + if not retVal is None: |
1856 | + iter = self.store_time_line.get_iter_first() |
1857 | + while not iter is None: |
1858 | + snapshot_id = self.store_time_line.get_value( iter, 1 ) |
1859 | + if snapshot_id == retVal: |
1860 | + break |
1861 | + iter = self.store_time_line.iter_next( iter ) |
1862 | + |
1863 | + if not iter is None: |
1864 | + self.list_time_line.get_selection().select_iter( iter ) |
1865 | + self.update_folder_view( 2 ) |
1866 | + |
1867 | + def on_btn_about_clicked( self, button ): |
1868 | + AboutDialog( self.config, self.window ).run() |
1869 | + |
1870 | + def on_help( self ): |
1871 | + gnome.help_display('backintime') |
1872 | + |
1873 | + def on_btn_help_clicked( self, button ): |
1874 | + self.on_help() |
1875 | + |
1876 | + def on_btn_link_clicked( self, button ): |
1877 | + os.system( "gnome-open http://backintime.le-web.org &" ) |
1878 | + |
1879 | + def on_key_release_event( self, widget, event ): |
1880 | + if 'F1' == gtk.gdk.keyval_name( event.keyval ) and ( event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK) ) == 0: |
1881 | + self.on_help() |
1882 | + |
1883 | + def on_btn_settings_clicked( self, button ): |
1884 | + snapshots_path = self.config.get_snapshots_path() |
1885 | + include_folders = self.config.get_include_folders() |
1886 | + |
1887 | + settingsdialog.SettingsDialog( self.config, self ).run() |
1888 | + |
1889 | + if snapshots_path != self.config.get_snapshots_path() or include_folders != self.config.get_include_folders(): |
1890 | + self.update_all( False ) |
1891 | + |
1892 | + def on_btn_snapshot_name_clicked( self, button ): |
1893 | + iter = self.list_time_line.get_selection().get_selected()[1] |
1894 | + if iter is None: |
1895 | + return |
1896 | + |
1897 | + snapshot_id = self.store_time_line.get_value( iter, 1 ) |
1898 | + if len( snapshot_id ) <= 1: |
1899 | + return |
1900 | + |
1901 | + old_name = self.snapshots.get_snapshot_name( snapshot_id ) |
1902 | + new_name = messagebox.text_input_dialog( self.window, self.config, _('Snapshot Name'), old_name ) |
1903 | + if new_name is None: |
1904 | + return |
1905 | + |
1906 | + if old_name == new_name: |
1907 | + return |
1908 | + |
1909 | + self.snapshots.set_snapshot_name( snapshot_id, new_name ) |
1910 | + self.store_time_line.set_value( iter, 0, gnometools.get_snapshot_display_markup( self.snapshots, snapshot_id ) ) |
1911 | + |
1912 | + def on_btn_remove_snapshot_clicked( self, button ): |
1913 | + iter = self.list_time_line.get_selection().get_selected()[1] |
1914 | + if iter is None: |
1915 | + return |
1916 | + |
1917 | + snapshot_id = self.store_time_line.get_value( iter, 1 ) |
1918 | + if len( snapshot_id ) <= 1: |
1919 | + return |
1920 | + |
1921 | + if gtk.RESPONSE_YES == messagebox.show_question( self.window, self.config, _('Are you sure you want to remove the snapshot:\n<b>%s</b>') % self.snapshots.get_snapshot_display_name( snapshot_id ) ): |
1922 | + print "Remove Snapshot: %s" % snapshot_id |
1923 | + self.snapshots.remove_snapshot( snapshot_id ) |
1924 | + self.fill_time_line() |
1925 | + |
1926 | + def on_btn_backup_clicked( self, button ): |
1927 | + button.set_sensitive( False ) |
1928 | + self.updatetime_line = True |
1929 | + |
1930 | + if self.snapshots.is_busy(): |
1931 | + self.update_backup_info() |
1932 | + return |
1933 | + |
1934 | + backintime.take_snapshot_now_async( self.config ) |
1935 | + self.update_backup_info( True ) |
1936 | + |
1937 | + def on_btn_update_snapshots_clicked( self, button ): |
1938 | + self.fill_time_line( False ) |
1939 | + self.update_folder_view( 2 ) |
1940 | + |
1941 | + def update_folder_view( self, changed_from, selected_file = None, show_snapshots = False ): #0 - places, 1 - folder view, 2 - time_line |
1942 | + #update backup time |
1943 | + if 2 == changed_from: |
1944 | + iter = self.list_time_line.get_selection().get_selected()[1] |
1945 | + self.snapshot_id = self.store_time_line.get_value( iter, 1 ) |
1946 | + #self.lblTime.set_markup( "<b>%s</b>" % backupTime ) |
1947 | + |
1948 | + tooltip = '' |
1949 | + text = '' |
1950 | + if len( self.snapshot_id ) > 1: |
1951 | + name = self.snapshots.get_snapshot_display_id( self.snapshot_id ) |
1952 | + text = _('Snapshot: %s') % name |
1953 | + tooltip = _('View the snapshot made at %s') % name |
1954 | + else: |
1955 | + tooltip = _('View the current disk content') |
1956 | + text = _('Now') |
1957 | + |
1958 | + self.lbl_snapshot.set_markup( ' <b>' + text + '</b> ' ) |
1959 | + self.lbl_snapshot.set_tooltip_text( tooltip ) |
1960 | + |
1961 | + #update selected places item |
1962 | + if 1 == changed_from: |
1963 | + iter = self.store_places.get_iter_first() |
1964 | + while not iter is None: |
1965 | + place_path = self.store_places.get_value( iter, 1 ) |
1966 | + if place_path == self.folder_path: |
1967 | + break |
1968 | + iter = self.store_places.iter_next( iter ) |
1969 | + |
1970 | + if iter is None: |
1971 | + self.list_places.get_selection().unselect_all() |
1972 | + else: |
1973 | + self.list_places.get_selection().select_iter( iter ) |
1974 | + |
1975 | + #update folder view |
1976 | + |
1977 | + full_path = self.snapshots.get_snapshot_path_to( self.snapshot_id, self.folder_path ) |
1978 | + all_files = [] |
1979 | + files = [] |
1980 | + folder_exists = os.path.isdir( full_path ) |
1981 | + |
1982 | + if folder_exists: |
1983 | + try: |
1984 | + all_files = os.listdir( full_path ) |
1985 | + all_files.sort() |
1986 | + except: |
1987 | + pass |
1988 | + |
1989 | + files = [] |
1990 | + for file in all_files: |
1991 | + if len( file ) == 0: |
1992 | + continue |
1993 | + |
1994 | + if not self.show_hidden_files: |
1995 | + if file[ 0 ] == '.': |
1996 | + continue |
1997 | + if file[ -1 ] == '~': |
1998 | + continue |
1999 | + |
2000 | + path = os.path.join( full_path, file ) |
2001 | + |
2002 | + file_size = -1 |
2003 | + file_date = -1 |
2004 | + |
2005 | + try: |
2006 | + file_stat = os.stat( path ) |
2007 | + file_size = file_stat[stat.ST_SIZE] |
2008 | + file_date = file_stat[stat.ST_MTIME] |
2009 | + except: |
2010 | + pass |
2011 | + |
2012 | + #format size |
2013 | + file_size_int = file_size |
2014 | + if file_size_int < 0: |
2015 | + file_size_int = 0 |
2016 | + |
2017 | + if file_size < 0: |
2018 | + file_size = 'unknown' |
2019 | + elif file_size < 1024: |
2020 | + file_size = str( file_size ) + ' bytes' |
2021 | + elif file_size < 1024 * 1024: |
2022 | + file_size = file_size / 1024 |
2023 | + file_size = str( file_size ) + ' KB' |
2024 | + elif file_size < 1024 * 1024 * 1024: |
2025 | + file_size = file_size / ( 1024 * 1024 ) |
2026 | + file_size = str( file_size ) + ' MB' |
2027 | + else: |
2028 | + file_size = file_size / ( 1024 * 1024 * 1024 ) |
2029 | + file_size = str( file_size ) + ' GB' |
2030 | + |
2031 | + #format date |
2032 | + if file_date < 0: |
2033 | + file_date = 'unknown' |
2034 | + else: |
2035 | + file_date = datetime.datetime.fromtimestamp(file_date).isoformat(' ') |
2036 | + |
2037 | + if os.path.isdir( path ): |
2038 | + files.append( [ file, file_size, file_date, self.icon_names.get_icon(path), file_size_int, 0 ] ) |
2039 | + else: |
2040 | + files.append( [ file, file_size, file_date, self.icon_names.get_icon(path), file_size_int, 1 ] ) |
2041 | + |
2042 | + #try to keep old selected file |
2043 | + if selected_file is None: |
2044 | + selected_file = '' |
2045 | + iter = self.list_folder_view.get_selection().get_selected()[1] |
2046 | + if not iter is None: |
2047 | + selected_file = self.store_folder_view.get_value( iter, 1 ) |
2048 | + |
2049 | + self.list_folder_view_widget.show() |
2050 | + self.list_folder_view_shadow.hide() |
2051 | + else: |
2052 | + self.list_folder_view_widget.hide() |
2053 | + self.list_folder_view_shadow.show() |
2054 | + |
2055 | + #populate the list |
2056 | + self.store_folder_view.clear() |
2057 | + |
2058 | + selected_iter = None |
2059 | + for item in files: |
2060 | + rel_path = os.path.join( self.folder_path, item[0] ) |
2061 | + new_iter = self.store_folder_view.append( [ item[0], rel_path, item[3], item[5], item[1], item[2], item[4] ] ) |
2062 | + if selected_file == rel_path: |
2063 | + selected_iter = new_iter |
2064 | + |
2065 | + #select old item or the first item |
2066 | + if len( files ) > 0: |
2067 | + if selected_iter is None: |
2068 | + selected_iter = self.store_folder_view.get_iter_first() |
2069 | + self.list_folder_view.get_selection().select_iter( selected_iter ) |
2070 | + self.list_folder_view.drag_source_set( gtk.gdk.BUTTON1_MASK | gtk.gdk.BUTTON3_MASK, gtk.target_list_add_uri_targets(), gtk.gdk.ACTION_COPY ) |
2071 | + else: |
2072 | + self.list_folder_view.drag_source_unset() |
2073 | + |
2074 | + #update folderup button state |
2075 | + self.builder.get_object( 'btn_folder_up' ).set_sensitive( len( self.folder_path ) > 1 ) |
2076 | + |
2077 | + #update restore button state |
2078 | + self.builder.get_object( 'btn_restore' ).set_sensitive( len( self.snapshot_id ) > 1 and len( self.store_folder_view ) > 0 ) |
2079 | + |
2080 | + #update remove/name snapshot buttons |
2081 | + self.builder.get_object( 'btn_snapshot_name' ).set_sensitive( len( self.snapshot_id ) > 1 ) |
2082 | + self.builder.get_object( 'btn_remove_snapshot' ).set_sensitive( len( self.snapshot_id ) > 1 ) |
2083 | + |
2084 | + #update copy button state |
2085 | + self.builder.get_object( 'btn_copy' ).set_sensitive( len( self.store_folder_view ) > 0 ) |
2086 | + |
2087 | + #update snapshots button state |
2088 | + self.builder.get_object( 'btn_snapshots' ).set_sensitive( len( self.store_folder_view ) > 0 ) |
2089 | + |
2090 | + #display current folder |
2091 | + self.builder.get_object( 'edit_current_path' ).set_text( self.folder_path ) |
2092 | + |
2093 | + #show snapshots |
2094 | + if show_snapshots: |
2095 | + self.on_btn_snapshots_clicked( None ) |
2096 | |
2097 | |
2098 | def open_url( dialog, link, user_data ): |
2099 | - os.system( "gnome-open \"%s\" &" % link ) |
2100 | + os.system( "gnome-open \"%s\" &" % link ) |
2101 | |
2102 | |
2103 | if __name__ == '__main__': |
2104 | - cfg = backintime.start_app( 'backintime-gnome', ['-s', '--snapshots'] ) |
2105 | - |
2106 | - raise_cmd = '' |
2107 | - if len( sys.argv ) > 1: |
2108 | - raise_cmd = '\n'.join( sys.argv[ 1 : ] ) |
2109 | - |
2110 | - app_instance = guiapplicationinstance.GUIApplicationInstance( cfg.get_app_instance_file(), raise_cmd ) |
2111 | - |
2112 | - gnome_props = { gnome.PARAM_APP_DATADIR : '/usr/share' } |
2113 | - gnome.program_init( 'backintime', cfg.VERSION, properties = gnome_props ) |
2114 | - |
2115 | - gtk.about_dialog_set_url_hook( open_url, None ) |
2116 | - |
2117 | - logger.openlog() |
2118 | - main_window = MainWindow( cfg, app_instance ) |
2119 | - if cfg.is_configured(): |
2120 | - gtk.main() |
2121 | - logger.closelog() |
2122 | - |
2123 | - app_instance.exit_application() |
2124 | + cfg = backintime.start_app( 'backintime-gnome', ['-s', '--snapshots'] ) |
2125 | + |
2126 | + raise_cmd = '' |
2127 | + if len( sys.argv ) > 1: |
2128 | + raise_cmd = '\n'.join( sys.argv[ 1 : ] ) |
2129 | + |
2130 | + app_instance = guiapplicationinstance.GUIApplicationInstance( cfg.get_app_instance_file(), raise_cmd ) |
2131 | + |
2132 | + gnome_props = { gnome.PARAM_APP_DATADIR : '/usr/share' } |
2133 | + gnome.program_init( 'backintime', cfg.VERSION, properties = gnome_props ) |
2134 | + |
2135 | + gtk.about_dialog_set_url_hook( open_url, None ) |
2136 | + |
2137 | + logger.openlog() |
2138 | + main_window = MainWindow( cfg, app_instance ) |
2139 | + if cfg.is_configured(): |
2140 | + gtk.main() |
2141 | + logger.closelog() |
2142 | + |
2143 | + app_instance.exit_application() |
2144 | |
2145 | |
2146 | === modified file 'gnome/mainwindow.glade' |
2147 | --- gnome/mainwindow.glade 2009-05-27 08:45:25 +0000 |
2148 | +++ gnome/mainwindow.glade 2009-10-01 16:35:20 +0000 |
2149 | @@ -1,8 +1,8 @@ |
2150 | <?xml version="1.0"?> |
2151 | -<glade-interface> |
2152 | - <!-- interface-requires gtk+ 2.16 --> |
2153 | +<interface> |
2154 | + <requires lib="gtk+" version="2.16"/> |
2155 | <!-- interface-naming-policy toplevel-contextual --> |
2156 | - <widget class="GtkWindow" id="MainWindow"> |
2157 | + <object class="GtkWindow" id="MainWindow"> |
2158 | <property name="title" translatable="yes">Back In Time</property> |
2159 | <property name="window_position">center</property> |
2160 | <property name="icon_name">gtk-save</property> |
2161 | @@ -10,173 +10,173 @@ |
2162 | <signal name="key_release_event" handler="on_MainWindow_key_release_event"/> |
2163 | <signal name="delete_event" handler="on_MainWindow_delete_event"/> |
2164 | <child> |
2165 | - <widget class="GtkVBox" id="vbox1"> |
2166 | + <object class="GtkVBox" id="vbox1"> |
2167 | <property name="visible">True</property> |
2168 | <child> |
2169 | - <widget class="GtkToolbar" id="toolbar1"> |
2170 | + <object class="GtkToolbar" id="toolbar1"> |
2171 | <property name="visible">True</property> |
2172 | <child> |
2173 | - <widget class="GtkToolButton" id="btn_backup"> |
2174 | + <object class="GtkToolButton" id="btn_backup"> |
2175 | <property name="visible">True</property> |
2176 | - <property name="tooltip" translatable="yes">Take snapshot</property> |
2177 | + <property name="tooltip_text" translatable="yes">Take snapshot</property> |
2178 | <property name="label" translatable="yes">Backup Now</property> |
2179 | <property name="stock_id">gtk-save</property> |
2180 | <signal name="clicked" handler="on_btn_backup_clicked"/> |
2181 | - </widget> |
2182 | + </object> |
2183 | <packing> |
2184 | <property name="expand">False</property> |
2185 | <property name="homogeneous">True</property> |
2186 | </packing> |
2187 | </child> |
2188 | <child> |
2189 | - <widget class="GtkToolButton" id="btn_update_snapshots"> |
2190 | + <object class="GtkToolButton" id="btn_update_snapshots"> |
2191 | <property name="visible">True</property> |
2192 | - <property name="tooltip" translatable="yes">Update snapshots</property> |
2193 | + <property name="tooltip_text" translatable="yes">Update snapshots</property> |
2194 | <property name="label" translatable="yes">Update snapshots</property> |
2195 | <property name="stock_id">gtk-refresh</property> |
2196 | <signal name="clicked" handler="on_btn_update_snapshots_clicked"/> |
2197 | - </widget> |
2198 | + </object> |
2199 | <packing> |
2200 | <property name="expand">False</property> |
2201 | <property name="homogeneous">True</property> |
2202 | </packing> |
2203 | </child> |
2204 | <child> |
2205 | - <widget class="GtkToolButton" id="btn_snapshot_name"> |
2206 | + <object class="GtkToolButton" id="btn_snapshot_name"> |
2207 | <property name="visible">True</property> |
2208 | - <property name="tooltip" translatable="yes">Snapshot Name</property> |
2209 | + <property name="tooltip_text" translatable="yes">Snapshot Name</property> |
2210 | <property name="label" translatable="yes">Snapshot Name</property> |
2211 | <property name="stock_id">gtk-edit</property> |
2212 | <signal name="clicked" handler="on_btn_snapshot_name_clicked"/> |
2213 | - </widget> |
2214 | + </object> |
2215 | <packing> |
2216 | <property name="expand">False</property> |
2217 | <property name="homogeneous">True</property> |
2218 | </packing> |
2219 | </child> |
2220 | <child> |
2221 | - <widget class="GtkToolButton" id="btn_remove_snapshot"> |
2222 | + <object class="GtkToolButton" id="btn_remove_snapshot"> |
2223 | <property name="visible">True</property> |
2224 | - <property name="tooltip" translatable="yes">Remove Snapshot</property> |
2225 | + <property name="tooltip_text" translatable="yes">Remove Snapshot</property> |
2226 | <property name="label" translatable="yes">Remove Snapshot</property> |
2227 | <property name="stock_id">gtk-delete</property> |
2228 | <signal name="clicked" handler="on_btn_remove_snapshot_clicked"/> |
2229 | - </widget> |
2230 | + </object> |
2231 | <packing> |
2232 | <property name="expand">False</property> |
2233 | <property name="homogeneous">True</property> |
2234 | </packing> |
2235 | </child> |
2236 | <child> |
2237 | - <widget class="GtkSeparatorToolItem" id="toolbutton1"> |
2238 | + <object class="GtkSeparatorToolItem" id="toolbutton1"> |
2239 | <property name="visible">True</property> |
2240 | - </widget> |
2241 | + </object> |
2242 | <packing> |
2243 | <property name="expand">False</property> |
2244 | </packing> |
2245 | </child> |
2246 | <child> |
2247 | - <widget class="GtkToolButton" id="btn_settings"> |
2248 | + <object class="GtkToolButton" id="btn_settings"> |
2249 | <property name="visible">True</property> |
2250 | - <property name="tooltip" translatable="yes">Settings</property> |
2251 | + <property name="tooltip_text" translatable="yes">Settings</property> |
2252 | <property name="label" translatable="yes">Settings</property> |
2253 | <property name="stock_id">gtk-preferences</property> |
2254 | <signal name="clicked" handler="on_btn_settings_clicked"/> |
2255 | - </widget> |
2256 | - <packing> |
2257 | - <property name="expand">False</property> |
2258 | - <property name="homogeneous">True</property> |
2259 | - </packing> |
2260 | - </child> |
2261 | - <child> |
2262 | - <widget class="GtkSeparatorToolItem" id="toolbutton5"> |
2263 | - <property name="visible">True</property> |
2264 | - </widget> |
2265 | - <packing> |
2266 | - <property name="expand">False</property> |
2267 | - <property name="homogeneous">True</property> |
2268 | - </packing> |
2269 | - </child> |
2270 | - <child> |
2271 | - <widget class="GtkToolButton" id="btn_about"> |
2272 | - <property name="visible">True</property> |
2273 | - <property name="tooltip" translatable="yes">About</property> |
2274 | + </object> |
2275 | + <packing> |
2276 | + <property name="expand">False</property> |
2277 | + <property name="homogeneous">True</property> |
2278 | + </packing> |
2279 | + </child> |
2280 | + <child> |
2281 | + <object class="GtkSeparatorToolItem" id="toolbutton5"> |
2282 | + <property name="visible">True</property> |
2283 | + </object> |
2284 | + <packing> |
2285 | + <property name="expand">False</property> |
2286 | + <property name="homogeneous">True</property> |
2287 | + </packing> |
2288 | + </child> |
2289 | + <child> |
2290 | + <object class="GtkToolButton" id="btn_about"> |
2291 | + <property name="visible">True</property> |
2292 | + <property name="tooltip_text" translatable="yes">About</property> |
2293 | <property name="label" translatable="yes">About</property> |
2294 | <property name="stock_id">gtk-about</property> |
2295 | <signal name="clicked" handler="on_btn_about_clicked"/> |
2296 | - </widget> |
2297 | + </object> |
2298 | <packing> |
2299 | <property name="expand">False</property> |
2300 | <property name="homogeneous">True</property> |
2301 | </packing> |
2302 | </child> |
2303 | <child> |
2304 | - <widget class="GtkToolButton" id="btn_help"> |
2305 | + <object class="GtkToolButton" id="btn_help"> |
2306 | <property name="visible">True</property> |
2307 | - <property name="tooltip" translatable="yes">Help</property> |
2308 | + <property name="tooltip_text" translatable="yes">Help</property> |
2309 | <property name="label" translatable="yes">Help</property> |
2310 | <property name="stock_id">gtk-help</property> |
2311 | <signal name="clicked" handler="on_btn_help_clicked"/> |
2312 | - </widget> |
2313 | + </object> |
2314 | <packing> |
2315 | <property name="expand">False</property> |
2316 | <property name="homogeneous">True</property> |
2317 | </packing> |
2318 | </child> |
2319 | <child> |
2320 | - <widget class="GtkSeparatorToolItem" id="toolbutton2"> |
2321 | + <object class="GtkSeparatorToolItem" id="toolbutton2"> |
2322 | <property name="visible">True</property> |
2323 | - </widget> |
2324 | + </object> |
2325 | <packing> |
2326 | <property name="expand">False</property> |
2327 | </packing> |
2328 | </child> |
2329 | <child> |
2330 | - <widget class="GtkToolButton" id="btn_exit"> |
2331 | + <object class="GtkToolButton" id="btn_exit"> |
2332 | <property name="visible">True</property> |
2333 | - <property name="tooltip" translatable="yes">Exit</property> |
2334 | + <property name="tooltip_text" translatable="yes">Exit</property> |
2335 | <property name="label" translatable="yes">Exit</property> |
2336 | <property name="stock_id">gtk-quit</property> |
2337 | <signal name="clicked" handler="on_btn_exit_clicked"/> |
2338 | - </widget> |
2339 | + </object> |
2340 | <packing> |
2341 | <property name="expand">False</property> |
2342 | <property name="homogeneous">True</property> |
2343 | </packing> |
2344 | </child> |
2345 | <child> |
2346 | - <widget class="GtkSeparatorToolItem" id="toolbutton8"> |
2347 | + <object class="GtkSeparatorToolItem" id="toolbutton8"> |
2348 | <property name="visible">True</property> |
2349 | - </widget> |
2350 | + </object> |
2351 | <packing> |
2352 | <property name="expand">False</property> |
2353 | <property name="homogeneous">True</property> |
2354 | </packing> |
2355 | </child> |
2356 | - </widget> |
2357 | + </object> |
2358 | <packing> |
2359 | <property name="expand">False</property> |
2360 | <property name="position">0</property> |
2361 | </packing> |
2362 | </child> |
2363 | <child> |
2364 | - <widget class="GtkVBox" id="vbox2"> |
2365 | + <object class="GtkVBox" id="vbox2"> |
2366 | <property name="visible">True</property> |
2367 | <property name="orientation">vertical</property> |
2368 | <property name="spacing">2</property> |
2369 | <child> |
2370 | - <widget class="GtkHBox" id="hbox1"> |
2371 | + <object class="GtkHBox" id="hbox1"> |
2372 | <property name="visible">True</property> |
2373 | <property name="spacing">5</property> |
2374 | <child> |
2375 | - <widget class="GtkHBox" id="hbox2"> |
2376 | + <object class="GtkHBox" id="hbox2"> |
2377 | <property name="visible">True</property> |
2378 | <child> |
2379 | - <widget class="GtkLabel" id="label1"> |
2380 | + <object class="GtkLabel" id="label1"> |
2381 | <property name="visible">True</property> |
2382 | <property name="label" translatable="yes">Profile:</property> |
2383 | <property name="single_line_mode">True</property> |
2384 | - </widget> |
2385 | + </object> |
2386 | <packing> |
2387 | <property name="expand">False</property> |
2388 | <property name="padding">5</property> |
2389 | @@ -184,16 +184,16 @@ |
2390 | </packing> |
2391 | </child> |
2392 | <child> |
2393 | - <widget class="GtkComboBox" id="combo_profiles"> |
2394 | + <object class="GtkComboBox" id="combo_profiles"> |
2395 | <property name="visible">True</property> |
2396 | <signal name="changed" handler="on_combo_profiles_changed"/> |
2397 | - </widget> |
2398 | + </object> |
2399 | <packing> |
2400 | <property name="pack_type">end</property> |
2401 | <property name="position">1</property> |
2402 | </packing> |
2403 | </child> |
2404 | - </widget> |
2405 | + </object> |
2406 | <packing> |
2407 | <property name="position">0</property> |
2408 | </packing> |
2409 | @@ -202,7 +202,7 @@ |
2410 | <placeholder/> |
2411 | </child> |
2412 | <child> |
2413 | - <widget class="GtkLinkButton" id="linkbutton1"> |
2414 | + <object class="GtkLinkButton" id="linkbutton1"> |
2415 | <property name="label">backintime.le-web.org</property> |
2416 | <property name="visible">True</property> |
2417 | <property name="can_focus">True</property> |
2418 | @@ -210,28 +210,28 @@ |
2419 | <property name="relief">none</property> |
2420 | <property name="xalign">1</property> |
2421 | <property name="uri">http://backintime.le-web.org</property> |
2422 | - </widget> |
2423 | + </object> |
2424 | <packing> |
2425 | <property name="expand">False</property> |
2426 | <property name="position">2</property> |
2427 | </packing> |
2428 | </child> |
2429 | - </widget> |
2430 | + </object> |
2431 | <packing> |
2432 | <property name="expand">False</property> |
2433 | <property name="position">0</property> |
2434 | </packing> |
2435 | </child> |
2436 | <child> |
2437 | - <widget class="GtkHSeparator" id="hseparator1"> |
2438 | + <object class="GtkHSeparator" id="hseparator1"> |
2439 | <property name="visible">True</property> |
2440 | - </widget> |
2441 | + </object> |
2442 | <packing> |
2443 | <property name="expand">False</property> |
2444 | <property name="position">1</property> |
2445 | </packing> |
2446 | </child> |
2447 | - </widget> |
2448 | + </object> |
2449 | <packing> |
2450 | <property name="expand">False</property> |
2451 | <property name="padding">2</property> |
2452 | @@ -239,11 +239,11 @@ |
2453 | </packing> |
2454 | </child> |
2455 | <child> |
2456 | - <widget class="GtkHPaned" id="hpaned1"> |
2457 | + <object class="GtkHPaned" id="hpaned1"> |
2458 | <property name="visible">True</property> |
2459 | <property name="can_focus">True</property> |
2460 | <child> |
2461 | - <widget class="GtkScrolledWindow" id="scrolledwindow1"> |
2462 | + <object class="GtkScrolledWindow" id="scrolledwindow1"> |
2463 | <property name="width_request">200</property> |
2464 | <property name="visible">True</property> |
2465 | <property name="can_focus">True</property> |
2466 | @@ -251,131 +251,131 @@ |
2467 | <property name="vscrollbar_policy">automatic</property> |
2468 | <property name="shadow_type">in</property> |
2469 | <child> |
2470 | - <widget class="GtkTreeView" id="list_time_line"> |
2471 | + <object class="GtkTreeView" id="list_time_line"> |
2472 | <property name="visible">True</property> |
2473 | <property name="can_focus">True</property> |
2474 | <property name="search_column">0</property> |
2475 | <signal name="cursor_changed" handler="on_list_time_line_cursor_changed"/> |
2476 | - </widget> |
2477 | + </object> |
2478 | </child> |
2479 | - </widget> |
2480 | + </object> |
2481 | <packing> |
2482 | <property name="resize">False</property> |
2483 | <property name="shrink">True</property> |
2484 | </packing> |
2485 | </child> |
2486 | <child> |
2487 | - <widget class="GtkFrame" id="frame5"> |
2488 | + <object class="GtkFrame" id="frame5"> |
2489 | <property name="visible">True</property> |
2490 | <property name="border_width">3</property> |
2491 | <property name="label_xalign">0</property> |
2492 | <child> |
2493 | - <widget class="GtkVBox" id="vbox6"> |
2494 | + <object class="GtkVBox" id="vbox6"> |
2495 | <property name="visible">True</property> |
2496 | <property name="border_width">5</property> |
2497 | <child> |
2498 | - <widget class="GtkToolbar" id="toolbar3"> |
2499 | + <object class="GtkToolbar" id="toolbar3"> |
2500 | <property name="visible">True</property> |
2501 | <child> |
2502 | - <widget class="GtkToolButton" id="btn_folder_up"> |
2503 | + <object class="GtkToolButton" id="btn_folder_up"> |
2504 | <property name="visible">True</property> |
2505 | - <property name="tooltip" translatable="yes">Parent folder</property> |
2506 | + <property name="tooltip_text" translatable="yes">Parent folder</property> |
2507 | <property name="label" translatable="yes">Up</property> |
2508 | <property name="stock_id">gtk-go-up</property> |
2509 | <signal name="clicked" handler="on_btn_folder_up_clicked"/> |
2510 | - </widget> |
2511 | + </object> |
2512 | <packing> |
2513 | <property name="expand">False</property> |
2514 | <property name="homogeneous">True</property> |
2515 | </packing> |
2516 | </child> |
2517 | <child> |
2518 | - <widget class="GtkToolItem" id="btn_current_path"> |
2519 | + <object class="GtkToolItem" id="btn_current_path"> |
2520 | <property name="visible">True</property> |
2521 | <child> |
2522 | - <widget class="GtkEntry" id="edit_current_path"> |
2523 | + <object class="GtkEntry" id="edit_current_path"> |
2524 | <property name="visible">True</property> |
2525 | <property name="can_focus">True</property> |
2526 | <property name="editable">False</property> |
2527 | - </widget> |
2528 | + </object> |
2529 | </child> |
2530 | - </widget> |
2531 | + </object> |
2532 | <packing> |
2533 | <property name="expand">False</property> |
2534 | </packing> |
2535 | </child> |
2536 | <child> |
2537 | - <widget class="GtkToggleToolButton" id="btn_hidden_files"> |
2538 | + <object class="GtkToggleToolButton" id="btn_hidden_files"> |
2539 | <property name="visible">True</property> |
2540 | - <property name="tooltip" translatable="yes">Show hidden files</property> |
2541 | + <property name="tooltip_text" translatable="yes">Show hidden files</property> |
2542 | <property name="label" translatable="yes">Hidden files</property> |
2543 | <property name="stock_id">gtk-add</property> |
2544 | <signal name="toggled" handler="on_btn_hidden_files_toggled"/> |
2545 | - </widget> |
2546 | + </object> |
2547 | <packing> |
2548 | <property name="expand">False</property> |
2549 | <property name="homogeneous">True</property> |
2550 | </packing> |
2551 | </child> |
2552 | <child> |
2553 | - <widget class="GtkSeparatorToolItem" id="toolbutton3"> |
2554 | + <object class="GtkSeparatorToolItem" id="toolbutton3"> |
2555 | <property name="visible">True</property> |
2556 | - </widget> |
2557 | + </object> |
2558 | <packing> |
2559 | <property name="expand">False</property> |
2560 | </packing> |
2561 | </child> |
2562 | <child> |
2563 | - <widget class="GtkToolButton" id="btn_restore"> |
2564 | + <object class="GtkToolButton" id="btn_restore"> |
2565 | <property name="visible">True</property> |
2566 | - <property name="tooltip" translatable="yes">Restore</property> |
2567 | + <property name="tooltip_text" translatable="yes">Restore</property> |
2568 | <property name="label" translatable="yes">Restore</property> |
2569 | <property name="stock_id">gtk-undelete</property> |
2570 | <signal name="clicked" handler="on_btn_restore_clicked"/> |
2571 | - </widget> |
2572 | + </object> |
2573 | <packing> |
2574 | <property name="expand">False</property> |
2575 | <property name="homogeneous">True</property> |
2576 | </packing> |
2577 | </child> |
2578 | <child> |
2579 | - <widget class="GtkToolButton" id="btn_copy"> |
2580 | + <object class="GtkToolButton" id="btn_copy"> |
2581 | <property name="visible">True</property> |
2582 | - <property name="tooltip" translatable="yes">Copy</property> |
2583 | + <property name="tooltip_text" translatable="yes">Copy</property> |
2584 | <property name="label" translatable="yes">Copy</property> |
2585 | <property name="stock_id">gtk-copy</property> |
2586 | <signal name="clicked" handler="on_btn_copy_clicked"/> |
2587 | - </widget> |
2588 | + </object> |
2589 | <packing> |
2590 | <property name="expand">False</property> |
2591 | <property name="homogeneous">True</property> |
2592 | </packing> |
2593 | </child> |
2594 | <child> |
2595 | - <widget class="GtkToolButton" id="btn_snapshots"> |
2596 | + <object class="GtkToolButton" id="btn_snapshots"> |
2597 | <property name="visible">True</property> |
2598 | - <property name="tooltip" translatable="yes">Snapshots</property> |
2599 | + <property name="tooltip_text" translatable="yes">Snapshots</property> |
2600 | <property name="label" translatable="yes">Snapshots</property> |
2601 | <property name="stock_id">gtk-index</property> |
2602 | <signal name="clicked" handler="on_btn_snapshots_clicked"/> |
2603 | - </widget> |
2604 | + </object> |
2605 | <packing> |
2606 | <property name="expand">False</property> |
2607 | <property name="homogeneous">True</property> |
2608 | </packing> |
2609 | </child> |
2610 | - </widget> |
2611 | + </object> |
2612 | <packing> |
2613 | <property name="expand">False</property> |
2614 | <property name="position">0</property> |
2615 | </packing> |
2616 | </child> |
2617 | <child> |
2618 | - <widget class="GtkHPaned" id="hpaned2"> |
2619 | + <object class="GtkHPaned" id="hpaned2"> |
2620 | <property name="visible">True</property> |
2621 | <property name="can_focus">True</property> |
2622 | <child> |
2623 | - <widget class="GtkScrolledWindow" id="scrolledwindow"> |
2624 | + <object class="GtkScrolledWindow" id="scrolledwindow"> |
2625 | <property name="width_request">200</property> |
2626 | <property name="visible">True</property> |
2627 | <property name="can_focus">True</property> |
2628 | @@ -383,25 +383,25 @@ |
2629 | <property name="vscrollbar_policy">automatic</property> |
2630 | <property name="shadow_type">in</property> |
2631 | <child> |
2632 | - <widget class="GtkTreeView" id="list_places"> |
2633 | + <object class="GtkTreeView" id="list_places"> |
2634 | <property name="visible">True</property> |
2635 | <property name="can_focus">True</property> |
2636 | <property name="search_column">0</property> |
2637 | <signal name="cursor_changed" handler="on_list_places_cursor_changed"/> |
2638 | - </widget> |
2639 | + </object> |
2640 | </child> |
2641 | - </widget> |
2642 | + </object> |
2643 | <packing> |
2644 | <property name="resize">False</property> |
2645 | <property name="shrink">True</property> |
2646 | </packing> |
2647 | </child> |
2648 | <child> |
2649 | - <widget class="GtkHBox" id="hbox5"> |
2650 | + <object class="GtkHBox" id="hbox5"> |
2651 | <property name="visible">True</property> |
2652 | <property name="homogeneous">True</property> |
2653 | <child> |
2654 | - <widget class="GtkScrolledWindow" id="list_folder_view_widget"> |
2655 | + <object class="GtkScrolledWindow" id="list_folder_view_widget"> |
2656 | <property name="width_request">350</property> |
2657 | <property name="height_request">400</property> |
2658 | <property name="visible">True</property> |
2659 | @@ -410,7 +410,7 @@ |
2660 | <property name="vscrollbar_policy">automatic</property> |
2661 | <property name="shadow_type">in</property> |
2662 | <child> |
2663 | - <widget class="GtkTreeView" id="list_folder_view"> |
2664 | + <object class="GtkTreeView" id="list_folder_view"> |
2665 | <property name="visible">True</property> |
2666 | <property name="can_focus">True</property> |
2667 | <property name="has_focus">True</property> |
2668 | @@ -418,84 +418,78 @@ |
2669 | <signal name="row_activated" handler="on_list_folder_view_row_activated"/> |
2670 | <signal name="popup_menu" handler="on_list_folder_view_popup_menu"/> |
2671 | <signal name="drag_data_get" handler="on_list_folder_view_drag_data_get"/> |
2672 | - </widget> |
2673 | + </object> |
2674 | </child> |
2675 | - </widget> |
2676 | + </object> |
2677 | <packing> |
2678 | <property name="position">0</property> |
2679 | </packing> |
2680 | </child> |
2681 | <child> |
2682 | - <widget class="GtkFrame" id="list_folder_view_shadow"> |
2683 | + <object class="GtkFrame" id="list_folder_view_shadow"> |
2684 | <property name="label_xalign">0</property> |
2685 | <property name="shadow_type">in</property> |
2686 | <child> |
2687 | - <widget class="GtkLabel" id="label17"> |
2688 | + <object class="GtkLabel" id="label17"> |
2689 | <property name="visible">True</property> |
2690 | - <property name="label" translatable="yes"><b>This folder don't exist |
2691 | + <property name="label" translatable="yes"><b>This folder does not exist |
2692 | in current snapshot !</b></property> |
2693 | <property name="use_markup">True</property> |
2694 | <property name="justify">center</property> |
2695 | - </widget> |
2696 | + </object> |
2697 | </child> |
2698 | - <child> |
2699 | + <child type="label_item"> |
2700 | <placeholder/> |
2701 | - <packing> |
2702 | - <property name="type">label_item</property> |
2703 | - </packing> |
2704 | </child> |
2705 | - </widget> |
2706 | + </object> |
2707 | <packing> |
2708 | <property name="position">1</property> |
2709 | </packing> |
2710 | </child> |
2711 | - </widget> |
2712 | + </object> |
2713 | <packing> |
2714 | <property name="resize">True</property> |
2715 | <property name="shrink">True</property> |
2716 | </packing> |
2717 | </child> |
2718 | - </widget> |
2719 | + </object> |
2720 | <packing> |
2721 | <property name="position">1</property> |
2722 | </packing> |
2723 | </child> |
2724 | - </widget> |
2725 | + </object> |
2726 | </child> |
2727 | - <child> |
2728 | - <widget class="GtkLabel" id="lbl_snapshot"> |
2729 | + <child type="label"> |
2730 | + <object class="GtkLabel" id="lbl_snapshot"> |
2731 | <property name="visible">True</property> |
2732 | <property name="has_tooltip">True</property> |
2733 | <property name="use_markup">True</property> |
2734 | - </widget> |
2735 | - <packing> |
2736 | - <property name="type">label_item</property> |
2737 | - </packing> |
2738 | + </object> |
2739 | </child> |
2740 | - </widget> |
2741 | + </object> |
2742 | <packing> |
2743 | <property name="resize">True</property> |
2744 | <property name="shrink">True</property> |
2745 | </packing> |
2746 | </child> |
2747 | - </widget> |
2748 | + </object> |
2749 | <packing> |
2750 | <property name="position">3</property> |
2751 | </packing> |
2752 | </child> |
2753 | <child> |
2754 | - <widget class="GtkStatusbar" id="status_bar"> |
2755 | + <object class="GtkStatusbar" id="status_bar"> |
2756 | <property name="visible">True</property> |
2757 | <property name="has_tooltip">True</property> |
2758 | <property name="spacing">5</property> |
2759 | - </widget> |
2760 | + </object> |
2761 | <packing> |
2762 | <property name="expand">False</property> |
2763 | <property name="pack_type">end</property> |
2764 | <property name="position">1</property> |
2765 | </packing> |
2766 | </child> |
2767 | - </widget> |
2768 | + </object> |
2769 | </child> |
2770 | - </widget> |
2771 | -</glade-interface> |
2772 | + </object> |
2773 | +</interface> |
2774 | |
2775 | === modified file 'gnome/messagebox.py' |
2776 | --- gnome/messagebox.py 2009-06-10 10:16:27 +0000 |
2777 | +++ gnome/messagebox.py 2009-10-01 16:35:20 +0000 |
2778 | @@ -31,40 +31,47 @@ |
2779 | |
2780 | |
2781 | def show_question( parent, config, message ): |
2782 | - dialog = gtk.MessageDialog( parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO ) |
2783 | - dialog.set_markup( message ) |
2784 | - dialog.set_title( config.APP_NAME ) |
2785 | - retVal = dialog.run() |
2786 | - dialog.destroy() |
2787 | - return retVal |
2788 | + dialog = gtk.MessageDialog( parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO ) |
2789 | + dialog.set_markup( message ) |
2790 | + dialog.set_title( config.APP_NAME ) |
2791 | + retVal = dialog.run() |
2792 | + dialog.destroy() |
2793 | + return retVal |
2794 | |
2795 | def show_error( parent, config, message ): |
2796 | - dialog = gtk.MessageDialog( parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK ) |
2797 | - dialog.set_markup( message ) |
2798 | - dialog.set_title( config.APP_NAME ) |
2799 | - retVal = dialog.run() |
2800 | - dialog.destroy() |
2801 | - return retVal |
2802 | + dialog = gtk.MessageDialog( parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK ) |
2803 | + dialog.set_markup( message ) |
2804 | + dialog.set_title( config.APP_NAME ) |
2805 | + retVal = dialog.run() |
2806 | + dialog.destroy() |
2807 | + return retVal |
2808 | |
2809 | def text_input_dialog( parent, config, title, default_value = '' ): |
2810 | - glade = gtk.glade.XML( os.path.join( config.get_app_path(), 'gnome', 'textinputdialog.glade' ), None, 'backintime' ) |
2811 | - dialog = glade.get_widget( 'TextInputDialog' ) |
2812 | - dialog.set_title( title ) |
2813 | - dialog.set_transient_for( parent ) |
2814 | - |
2815 | - edit = glade.get_widget( 'edit_text' ) |
2816 | - |
2817 | - if not default_value is None: |
2818 | - edit.set_text( default_value ) |
2819 | - |
2820 | - edit.grab_focus() |
2821 | - |
2822 | - text = None |
2823 | - if gtk.RESPONSE_OK == dialog.run(): |
2824 | - text = edit.get_text() |
2825 | - else: |
2826 | - text = default_value |
2827 | - |
2828 | - dialog.destroy() |
2829 | - return text |
2830 | + |
2831 | + builder = gtk.Builder() |
2832 | + |
2833 | + glade_file = os.path.join(config.get_app_path(), 'gnome', |
2834 | + 'textinputdialog.glade') |
2835 | + |
2836 | + builder.add_from_file(glade_file) |
2837 | + |
2838 | + dialog = builder.get_object( 'TextInputDialog' ) |
2839 | + dialog.set_title( title ) |
2840 | + dialog.set_transient_for( parent ) |
2841 | + |
2842 | + edit = builder.get_object( 'edit_text' ) |
2843 | + |
2844 | + if not default_value is None: |
2845 | + edit.set_text( default_value ) |
2846 | + |
2847 | + edit.grab_focus() |
2848 | + |
2849 | + text = None |
2850 | + if gtk.RESPONSE_OK == dialog.run(): |
2851 | + text = edit.get_text() |
2852 | + else: |
2853 | + text = default_value |
2854 | + |
2855 | + dialog.destroy() |
2856 | + return text |
2857 | |
2858 | |
2859 | === modified file 'gnome/settingsdialog.glade' |
2860 | --- gnome/settingsdialog.glade 2009-05-27 12:43:59 +0000 |
2861 | +++ gnome/settingsdialog.glade 2009-10-01 16:35:20 +0000 |
2862 | @@ -1,8 +1,8 @@ |
2863 | <?xml version="1.0"?> |
2864 | -<glade-interface> |
2865 | - <!-- interface-requires gtk+ 2.16 --> |
2866 | +<interface> |
2867 | + <requires lib="gtk+" version="2.16"/> |
2868 | <!-- interface-naming-policy toplevel-contextual --> |
2869 | - <widget class="GtkDialog" id="SettingsDialog"> |
2870 | + <object class="GtkDialog" id="SettingsDialog"> |
2871 | <property name="border_width">5</property> |
2872 | <property name="title" translatable="yes">Settings</property> |
2873 | <property name="modal">True</property> |
2874 | @@ -11,213 +11,206 @@ |
2875 | <property name="icon_name">gtk-preferences</property> |
2876 | <property name="type_hint">dialog</property> |
2877 | <property name="has_separator">False</property> |
2878 | - <signal name="response" handler="on_SettingsDialog_response"/> |
2879 | <child internal-child="vbox"> |
2880 | - <widget class="GtkVBox" id="dialog-vbox2"> |
2881 | + <object class="GtkVBox" id="dialog-vbox2"> |
2882 | <property name="visible">True</property> |
2883 | <property name="spacing">2</property> |
2884 | <child> |
2885 | - <widget class="GtkHBox" id="hbox5"> |
2886 | + <object class="GtkHBox" id="hbox5"> |
2887 | <property name="visible">True</property> |
2888 | <property name="spacing">5</property> |
2889 | <child> |
2890 | - <widget class="GtkLabel" id="label2"> |
2891 | + <object class="GtkLabel" id="label2"> |
2892 | <property name="visible">True</property> |
2893 | <property name="label" translatable="yes">Profile:</property> |
2894 | - </widget> |
2895 | + </object> |
2896 | <packing> |
2897 | <property name="expand">False</property> |
2898 | <property name="position">0</property> |
2899 | </packing> |
2900 | </child> |
2901 | <child> |
2902 | - <widget class="GtkComboBox" id="combo_profiles"> |
2903 | + <object class="GtkComboBox" id="combo_profiles"> |
2904 | <property name="visible">True</property> |
2905 | <signal name="changed" handler="on_combo_profiles_changed"/> |
2906 | - </widget> |
2907 | + </object> |
2908 | <packing> |
2909 | <property name="position">1</property> |
2910 | </packing> |
2911 | </child> |
2912 | <child> |
2913 | - <widget class="GtkHBox" id="hbox6"> |
2914 | + <object class="GtkHBox" id="hbox6"> |
2915 | <property name="visible">True</property> |
2916 | <property name="spacing">5</property> |
2917 | <property name="homogeneous">True</property> |
2918 | <child> |
2919 | - <widget class="GtkButton" id="btn_edit_profile"> |
2920 | + <object class="GtkButton" id="btn_edit_profile"> |
2921 | <property name="label" translatable="yes">gtk-edit</property> |
2922 | <property name="visible">True</property> |
2923 | <property name="can_focus">True</property> |
2924 | <property name="receives_default">True</property> |
2925 | <property name="use_stock">True</property> |
2926 | <signal name="clicked" handler="on_btn_edit_profile_clicked"/> |
2927 | - </widget> |
2928 | + </object> |
2929 | <packing> |
2930 | <property name="expand">False</property> |
2931 | <property name="position">0</property> |
2932 | </packing> |
2933 | </child> |
2934 | <child> |
2935 | - <widget class="GtkButton" id="btn_add_profile"> |
2936 | + <object class="GtkButton" id="btn_add_profile"> |
2937 | <property name="label" translatable="yes">gtk-new</property> |
2938 | <property name="visible">True</property> |
2939 | <property name="can_focus">True</property> |
2940 | <property name="receives_default">True</property> |
2941 | <property name="use_stock">True</property> |
2942 | <signal name="clicked" handler="on_btn_add_profile_clicked"/> |
2943 | - </widget> |
2944 | + </object> |
2945 | <packing> |
2946 | <property name="expand">False</property> |
2947 | <property name="position">1</property> |
2948 | </packing> |
2949 | </child> |
2950 | <child> |
2951 | - <widget class="GtkButton" id="btn_remove_profile"> |
2952 | + <object class="GtkButton" id="btn_remove_profile"> |
2953 | <property name="label" translatable="yes">gtk-delete</property> |
2954 | <property name="visible">True</property> |
2955 | <property name="can_focus">True</property> |
2956 | <property name="receives_default">True</property> |
2957 | <property name="use_stock">True</property> |
2958 | <signal name="clicked" handler="on_btn_remove_profile_clicked"/> |
2959 | - </widget> |
2960 | + </object> |
2961 | <packing> |
2962 | <property name="expand">False</property> |
2963 | <property name="position">2</property> |
2964 | </packing> |
2965 | </child> |
2966 | - </widget> |
2967 | + </object> |
2968 | <packing> |
2969 | <property name="expand">False</property> |
2970 | <property name="position">2</property> |
2971 | </packing> |
2972 | </child> |
2973 | - </widget> |
2974 | + </object> |
2975 | <packing> |
2976 | <property name="expand">False</property> |
2977 | <property name="position">1</property> |
2978 | </packing> |
2979 | </child> |
2980 | <child> |
2981 | - <widget class="GtkHSeparator" id="hseparator1"> |
2982 | + <object class="GtkHSeparator" id="hseparator1"> |
2983 | <property name="visible">True</property> |
2984 | - </widget> |
2985 | + </object> |
2986 | <packing> |
2987 | <property name="expand">False</property> |
2988 | <property name="position">2</property> |
2989 | </packing> |
2990 | </child> |
2991 | <child> |
2992 | - <widget class="GtkNotebook" id="notebook1"> |
2993 | + <object class="GtkNotebook" id="notebook1"> |
2994 | <property name="visible">True</property> |
2995 | <property name="can_focus">True</property> |
2996 | <child> |
2997 | - <widget class="GtkVBox" id="vbox2"> |
2998 | + <object class="GtkVBox" id="vbox2"> |
2999 | <property name="visible">True</property> |
3000 | <property name="border_width">5</property> |
3001 | <property name="spacing">5</property> |
3002 | <child> |
3003 | - <widget class="GtkFrame" id="frame1"> |
3004 | + <object class="GtkFrame" id="frame1"> |
3005 | <property name="visible">True</property> |
3006 | <property name="label_xalign">0</property> |
3007 | <property name="shadow_type">none</property> |
3008 | <child> |
3009 | - <widget class="GtkAlignment" id="alignment1"> |
3010 | + <object class="GtkAlignment" id="alignment1"> |
3011 | <property name="visible">True</property> |
3012 | <property name="left_padding">12</property> |
3013 | <child> |
3014 | - <widget class="GtkHBox" id="hbox4"> |
3015 | + <object class="GtkHBox" id="hbox4"> |
3016 | <property name="visible">True</property> |
3017 | <child> |
3018 | - <widget class="GtkEntry" id="edit_where"> |
3019 | + <object class="GtkEntry" id="edit_where"> |
3020 | <property name="visible">True</property> |
3021 | <property name="can_focus">True</property> |
3022 | <property name="editable">False</property> |
3023 | <property name="invisible_char">●</property> |
3024 | - </widget> |
3025 | + </object> |
3026 | <packing> |
3027 | <property name="position">0</property> |
3028 | </packing> |
3029 | </child> |
3030 | <child> |
3031 | - <widget class="GtkButton" id="btn_where"> |
3032 | + <object class="GtkButton" id="btn_where"> |
3033 | <property name="visible">True</property> |
3034 | <property name="can_focus">True</property> |
3035 | <property name="receives_default">True</property> |
3036 | <signal name="clicked" handler="on_btn_where_clicked"/> |
3037 | <child> |
3038 | - <widget class="GtkImage" id="image1"> |
3039 | + <object class="GtkImage" id="image1"> |
3040 | <property name="visible">True</property> |
3041 | <property name="stock">gtk-directory</property> |
3042 | - </widget> |
3043 | + </object> |
3044 | </child> |
3045 | - </widget> |
3046 | + </object> |
3047 | <packing> |
3048 | <property name="expand">False</property> |
3049 | <property name="position">1</property> |
3050 | </packing> |
3051 | </child> |
3052 | - </widget> |
3053 | + </object> |
3054 | </child> |
3055 | - </widget> |
3056 | + </object> |
3057 | </child> |
3058 | - <child> |
3059 | - <widget class="GtkLabel" id="label4"> |
3060 | + <child type="label"> |
3061 | + <object class="GtkLabel" id="label4"> |
3062 | <property name="visible">True</property> |
3063 | <property name="label" translatable="yes"><b>Where to save snapshots</b></property> |
3064 | <property name="use_markup">True</property> |
3065 | - </widget> |
3066 | - <packing> |
3067 | - <property name="type">label_item</property> |
3068 | - </packing> |
3069 | + </object> |
3070 | </child> |
3071 | - </widget> |
3072 | + </object> |
3073 | <packing> |
3074 | <property name="expand">False</property> |
3075 | <property name="position">0</property> |
3076 | </packing> |
3077 | </child> |
3078 | <child> |
3079 | - <widget class="GtkFrame" id="frame2"> |
3080 | + <object class="GtkFrame" id="frame2"> |
3081 | <property name="visible">True</property> |
3082 | <property name="label_xalign">0</property> |
3083 | <property name="shadow_type">none</property> |
3084 | <child> |
3085 | - <widget class="GtkAlignment" id="alignment2"> |
3086 | + <object class="GtkAlignment" id="alignment2"> |
3087 | <property name="visible">True</property> |
3088 | <property name="left_padding">12</property> |
3089 | <child> |
3090 | - <widget class="GtkComboBox" id="cb_backup_mode"> |
3091 | + <object class="GtkComboBox" id="cb_backup_mode"> |
3092 | <property name="visible">True</property> |
3093 | - </widget> |
3094 | + </object> |
3095 | </child> |
3096 | - </widget> |
3097 | + </object> |
3098 | </child> |
3099 | - <child> |
3100 | - <widget class="GtkLabel" id="lbl_schedule"> |
3101 | + <child type="label"> |
3102 | + <object class="GtkLabel" id="lbl_schedule"> |
3103 | <property name="visible">True</property> |
3104 | <property name="label" translatable="yes"><b>Schedule</b></property> |
3105 | <property name="use_markup">True</property> |
3106 | - </widget> |
3107 | - <packing> |
3108 | - <property name="type">label_item</property> |
3109 | - </packing> |
3110 | + </object> |
3111 | </child> |
3112 | - </widget> |
3113 | + </object> |
3114 | <packing> |
3115 | <property name="expand">False</property> |
3116 | <property name="position">1</property> |
3117 | </packing> |
3118 | </child> |
3119 | <child> |
3120 | - <widget class="GtkHBox" id="hbox1"> |
3121 | + <object class="GtkHBox" id="hbox1"> |
3122 | <property name="visible">True</property> |
3123 | <child> |
3124 | - <widget class="GtkLabel" id="label3"> |
3125 | + <object class="GtkLabel" id="label3"> |
3126 | <property name="visible">True</property> |
3127 | <property name="xalign">0</property> |
3128 | <property name="yalign">0.49000000953674316</property> |
3129 | - </widget> |
3130 | + </object> |
3131 | <packing> |
3132 | <property name="expand">False</property> |
3133 | <property name="position">0</property> |
3134 | @@ -226,30 +219,29 @@ |
3135 | <child> |
3136 | <placeholder/> |
3137 | </child> |
3138 | - </widget> |
3139 | + </object> |
3140 | <packing> |
3141 | <property name="position">2</property> |
3142 | </packing> |
3143 | </child> |
3144 | - </widget> |
3145 | + </object> |
3146 | </child> |
3147 | - <child> |
3148 | - <widget class="GtkLabel" id="label11"> |
3149 | + <child type="tab"> |
3150 | + <object class="GtkLabel" id="label11"> |
3151 | <property name="visible">True</property> |
3152 | <property name="label" translatable="yes">General</property> |
3153 | - </widget> |
3154 | + </object> |
3155 | <packing> |
3156 | <property name="tab_fill">False</property> |
3157 | - <property name="type">tab</property> |
3158 | </packing> |
3159 | </child> |
3160 | <child> |
3161 | - <widget class="GtkVBox" id="vbox7"> |
3162 | + <object class="GtkVBox" id="vbox7"> |
3163 | <property name="visible">True</property> |
3164 | <property name="border_width">5</property> |
3165 | <property name="spacing">5</property> |
3166 | <child> |
3167 | - <widget class="GtkScrolledWindow" id="scrolledwindow4"> |
3168 | + <object class="GtkScrolledWindow" id="scrolledwindow4"> |
3169 | <property name="width_request">300</property> |
3170 | <property name="height_request">250</property> |
3171 | <property name="visible">True</property> |
3172 | @@ -258,78 +250,77 @@ |
3173 | <property name="vscrollbar_policy">automatic</property> |
3174 | <property name="shadow_type">in</property> |
3175 | <child> |
3176 | - <widget class="GtkTreeView" id="list_include"> |
3177 | + <object class="GtkTreeView" id="list_include"> |
3178 | <property name="visible">True</property> |
3179 | <property name="can_focus">True</property> |
3180 | - </widget> |
3181 | + </object> |
3182 | </child> |
3183 | - </widget> |
3184 | + </object> |
3185 | <packing> |
3186 | <property name="position">0</property> |
3187 | </packing> |
3188 | </child> |
3189 | <child> |
3190 | - <widget class="GtkHBox" id="hbox2"> |
3191 | + <object class="GtkHBox" id="hbox2"> |
3192 | <property name="visible">True</property> |
3193 | <property name="spacing">5</property> |
3194 | <property name="homogeneous">True</property> |
3195 | <child> |
3196 | - <widget class="GtkButton" id="btn_add_include"> |
3197 | + <object class="GtkButton" id="btn_add_include"> |
3198 | <property name="label" translatable="yes">gtk-add</property> |
3199 | <property name="visible">True</property> |
3200 | <property name="can_focus">True</property> |
3201 | <property name="receives_default">True</property> |
3202 | <property name="use_stock">True</property> |
3203 | <signal name="clicked" handler="on_btn_add_include_clicked"/> |
3204 | - </widget> |
3205 | + </object> |
3206 | <packing> |
3207 | <property name="expand">False</property> |
3208 | <property name="position">0</property> |
3209 | </packing> |
3210 | </child> |
3211 | <child> |
3212 | - <widget class="GtkButton" id="btn_remove_include"> |
3213 | + <object class="GtkButton" id="btn_remove_include"> |
3214 | <property name="label" translatable="yes">gtk-remove</property> |
3215 | <property name="visible">True</property> |
3216 | <property name="can_focus">True</property> |
3217 | <property name="receives_default">True</property> |
3218 | <property name="use_stock">True</property> |
3219 | <signal name="clicked" handler="on_btn_remove_include_clicked"/> |
3220 | - </widget> |
3221 | + </object> |
3222 | <packing> |
3223 | <property name="expand">False</property> |
3224 | <property name="position">1</property> |
3225 | </packing> |
3226 | </child> |
3227 | - </widget> |
3228 | + </object> |
3229 | <packing> |
3230 | <property name="expand">False</property> |
3231 | <property name="position">1</property> |
3232 | </packing> |
3233 | </child> |
3234 | - </widget> |
3235 | + </object> |
3236 | <packing> |
3237 | <property name="position">1</property> |
3238 | </packing> |
3239 | </child> |
3240 | - <child> |
3241 | - <widget class="GtkLabel" id="label12"> |
3242 | + <child type="tab"> |
3243 | + <object class="GtkLabel" id="label12"> |
3244 | <property name="visible">True</property> |
3245 | <property name="label" translatable="yes">Include</property> |
3246 | - </widget> |
3247 | + </object> |
3248 | <packing> |
3249 | <property name="position">1</property> |
3250 | <property name="tab_fill">False</property> |
3251 | - <property name="type">tab</property> |
3252 | </packing> |
3253 | </child> |
3254 | <child> |
3255 | - <widget class="GtkVBox" id="vbox8"> |
3256 | + <object class="GtkVBox" id="vbox8"> |
3257 | <property name="visible">True</property> |
3258 | <property name="border_width">5</property> |
3259 | <property name="spacing">5</property> |
3260 | <child> |
3261 | - <widget class="GtkScrolledWindow" id="scrolledwindow5"> |
3262 | + <object class="GtkScrolledWindow" id="scrolledwindow5"> |
3263 | <property name="width_request">180</property> |
3264 | <property name="height_request">120</property> |
3265 | <property name="visible">True</property> |
3266 | @@ -338,97 +329,96 @@ |
3267 | <property name="vscrollbar_policy">automatic</property> |
3268 | <property name="shadow_type">in</property> |
3269 | <child> |
3270 | - <widget class="GtkTreeView" id="list_exclude"> |
3271 | + <object class="GtkTreeView" id="list_exclude"> |
3272 | <property name="visible">True</property> |
3273 | <property name="can_focus">True</property> |
3274 | - </widget> |
3275 | + </object> |
3276 | </child> |
3277 | - </widget> |
3278 | + </object> |
3279 | <packing> |
3280 | <property name="position">0</property> |
3281 | </packing> |
3282 | </child> |
3283 | <child> |
3284 | - <widget class="GtkHBox" id="hbox3"> |
3285 | + <object class="GtkHBox" id="hbox3"> |
3286 | <property name="visible">True</property> |
3287 | <property name="spacing">5</property> |
3288 | <property name="homogeneous">True</property> |
3289 | <child> |
3290 | - <widget class="GtkButton" id="btn_add_exclude"> |
3291 | + <object class="GtkButton" id="btn_add_exclude"> |
3292 | <property name="label" translatable="yes">gtk-add</property> |
3293 | <property name="visible">True</property> |
3294 | <property name="can_focus">True</property> |
3295 | <property name="receives_default">True</property> |
3296 | <property name="use_stock">True</property> |
3297 | <signal name="clicked" handler="on_btn_add_exclude_clicked"/> |
3298 | - </widget> |
3299 | + </object> |
3300 | <packing> |
3301 | <property name="expand">False</property> |
3302 | <property name="position">0</property> |
3303 | </packing> |
3304 | </child> |
3305 | <child> |
3306 | - <widget class="GtkButton" id="btn_add_exclude_file"> |
3307 | + <object class="GtkButton" id="btn_add_exclude_file"> |
3308 | <property name="label" translatable="yes">Add file</property> |
3309 | <property name="visible">True</property> |
3310 | <property name="can_focus">True</property> |
3311 | <property name="receives_default">True</property> |
3312 | <signal name="clicked" handler="on_btn_add_exclude_file_clicked"/> |
3313 | - </widget> |
3314 | + </object> |
3315 | <packing> |
3316 | <property name="position">1</property> |
3317 | </packing> |
3318 | </child> |
3319 | <child> |
3320 | - <widget class="GtkButton" id="btn_add_exclude_folder"> |
3321 | + <object class="GtkButton" id="btn_add_exclude_folder"> |
3322 | <property name="label" translatable="yes">Add folder</property> |
3323 | <property name="visible">True</property> |
3324 | <property name="can_focus">True</property> |
3325 | <property name="receives_default">True</property> |
3326 | <signal name="clicked" handler="on_btn_add_exclude_folder_clicked"/> |
3327 | - </widget> |
3328 | + </object> |
3329 | <packing> |
3330 | <property name="position">2</property> |
3331 | </packing> |
3332 | </child> |
3333 | <child> |
3334 | - <widget class="GtkButton" id="btn_remove_exclude"> |
3335 | + <object class="GtkButton" id="btn_remove_exclude"> |
3336 | <property name="label" translatable="yes">gtk-remove</property> |
3337 | <property name="visible">True</property> |
3338 | <property name="can_focus">True</property> |
3339 | <property name="receives_default">True</property> |
3340 | <property name="use_stock">True</property> |
3341 | <signal name="clicked" handler="on_btn_remove_exclude_clicked"/> |
3342 | - </widget> |
3343 | + </object> |
3344 | <packing> |
3345 | <property name="expand">False</property> |
3346 | <property name="position">3</property> |
3347 | </packing> |
3348 | </child> |
3349 | - </widget> |
3350 | + </object> |
3351 | <packing> |
3352 | <property name="expand">False</property> |
3353 | <property name="position">1</property> |
3354 | </packing> |
3355 | </child> |
3356 | - </widget> |
3357 | + </object> |
3358 | <packing> |
3359 | <property name="position">2</property> |
3360 | </packing> |
3361 | </child> |
3362 | - <child> |
3363 | - <widget class="GtkLabel" id="label13"> |
3364 | + <child type="tab"> |
3365 | + <object class="GtkLabel" id="label13"> |
3366 | <property name="visible">True</property> |
3367 | <property name="label" translatable="yes">Exclude</property> |
3368 | - </widget> |
3369 | + </object> |
3370 | <packing> |
3371 | <property name="position">2</property> |
3372 | <property name="tab_fill">False</property> |
3373 | - <property name="type">tab</property> |
3374 | </packing> |
3375 | </child> |
3376 | <child> |
3377 | - <widget class="GtkTable" id="table2"> |
3378 | + <object class="GtkTable" id="table2"> |
3379 | <property name="visible">True</property> |
3380 | <property name="border_width">5</property> |
3381 | <property name="n_rows">5</property> |
3382 | @@ -436,13 +426,13 @@ |
3383 | <property name="column_spacing">5</property> |
3384 | <property name="row_spacing">5</property> |
3385 | <child> |
3386 | - <widget class="GtkCheckButton" id="cb_dont_remove_named_snapshots"> |
3387 | + <object class="GtkCheckButton" id="cb_dont_remove_named_snapshots"> |
3388 | <property name="label" translatable="yes">Don't remove named snapshots</property> |
3389 | <property name="visible">True</property> |
3390 | <property name="can_focus">True</property> |
3391 | <property name="receives_default">False</property> |
3392 | <property name="draw_indicator">True</property> |
3393 | - </widget> |
3394 | + </object> |
3395 | <packing> |
3396 | <property name="right_attach">3</property> |
3397 | <property name="top_attach">4</property> |
3398 | @@ -451,77 +441,77 @@ |
3399 | </packing> |
3400 | </child> |
3401 | <child> |
3402 | - <widget class="GtkComboBox" id="cb_min_free_space_unit"> |
3403 | - <property name="visible">True</property> |
3404 | - </widget> |
3405 | - <packing> |
3406 | - <property name="left_attach">2</property> |
3407 | - <property name="right_attach">3</property> |
3408 | - <property name="top_attach">1</property> |
3409 | - <property name="bottom_attach">2</property> |
3410 | - <property name="y_options">GTK_FILL</property> |
3411 | - </packing> |
3412 | - </child> |
3413 | - <child> |
3414 | - <widget class="GtkComboBox" id="cb_remove_old_backup_unit"> |
3415 | - <property name="visible">True</property> |
3416 | - </widget> |
3417 | - <packing> |
3418 | - <property name="left_attach">2</property> |
3419 | - <property name="right_attach">3</property> |
3420 | - <property name="y_options">GTK_FILL</property> |
3421 | - </packing> |
3422 | - </child> |
3423 | - <child> |
3424 | - <widget class="GtkSpinButton" id="edit_remove_old_backup_value"> |
3425 | - <property name="visible">True</property> |
3426 | - <property name="can_focus">True</property> |
3427 | - <property name="adjustment">1 1 1000 1 0 0</property> |
3428 | - <property name="numeric">True</property> |
3429 | - </widget> |
3430 | - <packing> |
3431 | - <property name="left_attach">1</property> |
3432 | - <property name="right_attach">2</property> |
3433 | - <property name="y_options">GTK_FILL</property> |
3434 | - </packing> |
3435 | - </child> |
3436 | - <child> |
3437 | - <widget class="GtkSpinButton" id="edit_min_free_space_value"> |
3438 | - <property name="visible">True</property> |
3439 | - <property name="can_focus">True</property> |
3440 | - <property name="adjustment">1 1 1000 1 0 0</property> |
3441 | - <property name="numeric">True</property> |
3442 | - </widget> |
3443 | - <packing> |
3444 | - <property name="left_attach">1</property> |
3445 | - <property name="right_attach">2</property> |
3446 | - <property name="top_attach">1</property> |
3447 | - <property name="bottom_attach">2</property> |
3448 | - <property name="y_options">GTK_FILL</property> |
3449 | - </packing> |
3450 | - </child> |
3451 | - <child> |
3452 | - <widget class="GtkCheckButton" id="cb_remove_old_backup"> |
3453 | + <object class="GtkComboBox" id="cb_min_free_space_unit"> |
3454 | + <property name="visible">True</property> |
3455 | + </object> |
3456 | + <packing> |
3457 | + <property name="left_attach">2</property> |
3458 | + <property name="right_attach">3</property> |
3459 | + <property name="top_attach">1</property> |
3460 | + <property name="bottom_attach">2</property> |
3461 | + <property name="y_options">GTK_FILL</property> |
3462 | + </packing> |
3463 | + </child> |
3464 | + <child> |
3465 | + <object class="GtkComboBox" id="cb_remove_old_backup_unit"> |
3466 | + <property name="visible">True</property> |
3467 | + </object> |
3468 | + <packing> |
3469 | + <property name="left_attach">2</property> |
3470 | + <property name="right_attach">3</property> |
3471 | + <property name="y_options">GTK_FILL</property> |
3472 | + </packing> |
3473 | + </child> |
3474 | + <child> |
3475 | + <object class="GtkSpinButton" id="edit_remove_old_backup_value"> |
3476 | + <property name="visible">True</property> |
3477 | + <property name="can_focus">True</property> |
3478 | + <property name="adjustment">adjustment2</property> |
3479 | + <property name="numeric">True</property> |
3480 | + </object> |
3481 | + <packing> |
3482 | + <property name="left_attach">1</property> |
3483 | + <property name="right_attach">2</property> |
3484 | + <property name="y_options">GTK_FILL</property> |
3485 | + </packing> |
3486 | + </child> |
3487 | + <child> |
3488 | + <object class="GtkSpinButton" id="edit_min_free_space_value"> |
3489 | + <property name="visible">True</property> |
3490 | + <property name="can_focus">True</property> |
3491 | + <property name="adjustment">adjustment1</property> |
3492 | + <property name="numeric">True</property> |
3493 | + </object> |
3494 | + <packing> |
3495 | + <property name="left_attach">1</property> |
3496 | + <property name="right_attach">2</property> |
3497 | + <property name="top_attach">1</property> |
3498 | + <property name="bottom_attach">2</property> |
3499 | + <property name="y_options">GTK_FILL</property> |
3500 | + </packing> |
3501 | + </child> |
3502 | + <child> |
3503 | + <object class="GtkCheckButton" id="cb_remove_old_backup"> |
3504 | <property name="label" translatable="yes">Older than:</property> |
3505 | <property name="visible">True</property> |
3506 | <property name="can_focus">True</property> |
3507 | <property name="receives_default">False</property> |
3508 | <property name="draw_indicator">True</property> |
3509 | <signal name="toggled" handler="on_cb_remove_old_backup_toggled"/> |
3510 | - </widget> |
3511 | + </object> |
3512 | <packing> |
3513 | <property name="y_options">GTK_FILL</property> |
3514 | </packing> |
3515 | </child> |
3516 | <child> |
3517 | - <widget class="GtkCheckButton" id="cb_min_free_space"> |
3518 | + <object class="GtkCheckButton" id="cb_min_free_space"> |
3519 | <property name="label" translatable="yes">If free space is less than:</property> |
3520 | <property name="visible">True</property> |
3521 | <property name="can_focus">True</property> |
3522 | <property name="receives_default">False</property> |
3523 | <property name="draw_indicator">True</property> |
3524 | <signal name="toggled" handler="on_cb_min_free_space_toggled"/> |
3525 | - </widget> |
3526 | + </object> |
3527 | <packing> |
3528 | <property name="top_attach">1</property> |
3529 | <property name="bottom_attach">2</property> |
3530 | @@ -529,13 +519,13 @@ |
3531 | </packing> |
3532 | </child> |
3533 | <child> |
3534 | - <widget class="GtkCheckButton" id="cb_smart_remove"> |
3535 | + <object class="GtkCheckButton" id="cb_smart_remove"> |
3536 | <property name="label" translatable="yes">Smart remove</property> |
3537 | <property name="visible">True</property> |
3538 | <property name="can_focus">True</property> |
3539 | <property name="receives_default">False</property> |
3540 | <property name="draw_indicator">True</property> |
3541 | - </widget> |
3542 | + </object> |
3543 | <packing> |
3544 | <property name="right_attach">3</property> |
3545 | <property name="top_attach">2</property> |
3546 | @@ -544,14 +534,14 @@ |
3547 | </packing> |
3548 | </child> |
3549 | <child> |
3550 | - <widget class="GtkLabel" id="label10"> |
3551 | + <object class="GtkLabel" id="label10"> |
3552 | <property name="visible">True</property> |
3553 | <property name="xalign">0</property> |
3554 | <property name="label" translatable="yes">- keep all snapshots from today and yesterday |
3555 | - keep one snapshot for the last week and one for two weeks ago |
3556 | - keep one snapshot per month for all previous months of this year |
3557 | - keep one snapshot per year for all previous years</property> |
3558 | - </widget> |
3559 | + </object> |
3560 | <packing> |
3561 | <property name="right_attach">3</property> |
3562 | <property name="top_attach">3</property> |
3563 | @@ -560,35 +550,34 @@ |
3564 | <property name="x_padding">20</property> |
3565 | </packing> |
3566 | </child> |
3567 | - </widget> |
3568 | + </object> |
3569 | <packing> |
3570 | <property name="position">3</property> |
3571 | </packing> |
3572 | </child> |
3573 | - <child> |
3574 | - <widget class="GtkLabel" id="label14"> |
3575 | + <child type="tab"> |
3576 | + <object class="GtkLabel" id="label14"> |
3577 | <property name="visible">True</property> |
3578 | <property name="label" translatable="yes">Auto-remove</property> |
3579 | - </widget> |
3580 | + </object> |
3581 | <packing> |
3582 | <property name="position">3</property> |
3583 | <property name="tab_fill">False</property> |
3584 | - <property name="type">tab</property> |
3585 | </packing> |
3586 | </child> |
3587 | <child> |
3588 | - <widget class="GtkVBox" id="vbox5"> |
3589 | + <object class="GtkVBox" id="vbox5"> |
3590 | <property name="visible">True</property> |
3591 | <property name="border_width">5</property> |
3592 | <property name="spacing">5</property> |
3593 | <child> |
3594 | - <widget class="GtkCheckButton" id="cb_enable_notifications"> |
3595 | + <object class="GtkCheckButton" id="cb_enable_notifications"> |
3596 | <property name="label" translatable="yes">Enable notifications</property> |
3597 | <property name="visible">True</property> |
3598 | <property name="can_focus">True</property> |
3599 | <property name="receives_default">False</property> |
3600 | <property name="draw_indicator">True</property> |
3601 | - </widget> |
3602 | + </object> |
3603 | <packing> |
3604 | <property name="expand">False</property> |
3605 | <property name="position">0</property> |
3606 | @@ -597,33 +586,32 @@ |
3607 | <child> |
3608 | <placeholder/> |
3609 | </child> |
3610 | - </widget> |
3611 | + </object> |
3612 | <packing> |
3613 | <property name="position">4</property> |
3614 | </packing> |
3615 | </child> |
3616 | - <child> |
3617 | - <widget class="GtkLabel" id="label1"> |
3618 | + <child type="tab"> |
3619 | + <object class="GtkLabel" id="label1"> |
3620 | <property name="visible">True</property> |
3621 | <property name="label" translatable="yes">Options</property> |
3622 | - </widget> |
3623 | + </object> |
3624 | <packing> |
3625 | <property name="position">4</property> |
3626 | <property name="tab_fill">False</property> |
3627 | - <property name="type">tab</property> |
3628 | </packing> |
3629 | </child> |
3630 | <child> |
3631 | - <widget class="GtkVBox" id="vbox9"> |
3632 | + <object class="GtkVBox" id="vbox9"> |
3633 | <property name="visible">True</property> |
3634 | <property name="border_width">5</property> |
3635 | <property name="spacing">5</property> |
3636 | <child> |
3637 | - <widget class="GtkLabel" id="label15"> |
3638 | + <object class="GtkLabel" id="label15"> |
3639 | <property name="visible">True</property> |
3640 | <property name="label" translatable="yes"><b>Change this options only if you really know what you are doing !</b></property> |
3641 | <property name="use_markup">True</property> |
3642 | - </widget> |
3643 | + </object> |
3644 | <packing> |
3645 | <property name="expand">False</property> |
3646 | <property name="padding">10</property> |
3647 | @@ -631,102 +619,115 @@ |
3648 | </packing> |
3649 | </child> |
3650 | <child> |
3651 | - <widget class="GtkCheckButton" id="cb_per_directory_schedule"> |
3652 | + <object class="GtkCheckButton" id="cb_per_directory_schedule"> |
3653 | <property name="label" translatable="yes">Enable schedule per included folder (see Include tab; default: disabled)</property> |
3654 | <property name="visible">True</property> |
3655 | <property name="can_focus">True</property> |
3656 | <property name="receives_default">False</property> |
3657 | <property name="draw_indicator">True</property> |
3658 | <signal name="toggled" handler="on_cb_per_directory_schedule_toggled"/> |
3659 | - </widget> |
3660 | + </object> |
3661 | <packing> |
3662 | <property name="expand">False</property> |
3663 | <property name="position">1</property> |
3664 | </packing> |
3665 | </child> |
3666 | <child> |
3667 | - <widget class="GtkCheckButton" id="cb_run_nice_from_cron"> |
3668 | + <object class="GtkCheckButton" id="cb_run_nice_from_cron"> |
3669 | <property name="label" translatable="yes">Run 'nice' as cron job (default: enabled)</property> |
3670 | <property name="visible">True</property> |
3671 | <property name="can_focus">True</property> |
3672 | <property name="receives_default">False</property> |
3673 | <property name="draw_indicator">True</property> |
3674 | - </widget> |
3675 | + </object> |
3676 | <packing> |
3677 | <property name="expand">False</property> |
3678 | <property name="position">2</property> |
3679 | </packing> |
3680 | </child> |
3681 | <child> |
3682 | - <widget class="GtkLabel" id="label16"> |
3683 | + <object class="GtkLabel" id="label16"> |
3684 | <property name="visible">True</property> |
3685 | - </widget> |
3686 | + </object> |
3687 | <packing> |
3688 | <property name="position">3</property> |
3689 | </packing> |
3690 | </child> |
3691 | - </widget> |
3692 | + </object> |
3693 | <packing> |
3694 | <property name="position">5</property> |
3695 | </packing> |
3696 | </child> |
3697 | - <child> |
3698 | - <widget class="GtkLabel" id="label6"> |
3699 | + <child type="tab"> |
3700 | + <object class="GtkLabel" id="label6"> |
3701 | <property name="visible">True</property> |
3702 | <property name="label" translatable="yes">Expert Options</property> |
3703 | - </widget> |
3704 | + </object> |
3705 | <packing> |
3706 | <property name="position">5</property> |
3707 | <property name="tab_fill">False</property> |
3708 | - <property name="type">tab</property> |
3709 | </packing> |
3710 | </child> |
3711 | - </widget> |
3712 | + </object> |
3713 | <packing> |
3714 | <property name="position">3</property> |
3715 | </packing> |
3716 | </child> |
3717 | <child internal-child="action_area"> |
3718 | - <widget class="GtkHButtonBox" id="dialog-action_area2"> |
3719 | + <object class="GtkHButtonBox" id="dialog-action_area2"> |
3720 | <property name="layout_style">end</property> |
3721 | <child> |
3722 | - <widget class="GtkButton" id="btn_ok"> |
3723 | + <object class="GtkButton" id="btn_cancel"> |
3724 | + <property name="label" translatable="yes">gtk-cancel</property> |
3725 | + <property name="visible">True</property> |
3726 | + <property name="can_focus">True</property> |
3727 | + <property name="receives_default">True</property> |
3728 | + <property name="use_stock">True</property> |
3729 | + </object> |
3730 | + <packing> |
3731 | + <property name="expand">False</property> |
3732 | + <property name="fill">False</property> |
3733 | + <property name="position">0</property> |
3734 | + </packing> |
3735 | + </child> |
3736 | + <child> |
3737 | + <object class="GtkButton" id="btn_ok"> |
3738 | <property name="label" translatable="yes">gtk-ok</property> |
3739 | - <property name="response_id">-5</property> |
3740 | - <property name="visible">True</property> |
3741 | - <property name="can_focus">True</property> |
3742 | - <property name="receives_default">True</property> |
3743 | - <property name="use_stock">True</property> |
3744 | - </widget> |
3745 | - <packing> |
3746 | - <property name="expand">False</property> |
3747 | - <property name="fill">False</property> |
3748 | - <property name="position">0</property> |
3749 | - </packing> |
3750 | - </child> |
3751 | - <child> |
3752 | - <widget class="GtkButton" id="btn_cancel"> |
3753 | - <property name="label" translatable="yes">gtk-cancel</property> |
3754 | - <property name="response_id">-6</property> |
3755 | - <property name="visible">True</property> |
3756 | - <property name="can_focus">True</property> |
3757 | - <property name="receives_default">True</property> |
3758 | - <property name="use_stock">True</property> |
3759 | - </widget> |
3760 | + <property name="visible">True</property> |
3761 | + <property name="can_focus">True</property> |
3762 | + <property name="receives_default">True</property> |
3763 | + <property name="use_stock">True</property> |
3764 | + </object> |
3765 | <packing> |
3766 | <property name="expand">False</property> |
3767 | <property name="fill">False</property> |
3768 | <property name="position">1</property> |
3769 | </packing> |
3770 | </child> |
3771 | - </widget> |
3772 | + </object> |
3773 | <packing> |
3774 | <property name="expand">False</property> |
3775 | <property name="pack_type">end</property> |
3776 | <property name="position">0</property> |
3777 | </packing> |
3778 | </child> |
3779 | - </widget> |
3780 | + </object> |
3781 | </child> |
3782 | - </widget> |
3783 | -</glade-interface> |
3784 | + <action-widgets> |
3785 | + <action-widget response="-6">btn_cancel</action-widget> |
3786 | + <action-widget response="-5">btn_ok</action-widget> |
3787 | + </action-widgets> |
3788 | + </object> |
3789 | + <object class="GtkAdjustment" id="adjustment1"> |
3790 | + <property name="value">1</property> |
3791 | + <property name="lower">1</property> |
3792 | + <property name="upper">1000</property> |
3793 | + <property name="step_increment">1</property> |
3794 | + </object> |
3795 | + <object class="GtkAdjustment" id="adjustment2"> |
3796 | + <property name="value">1</property> |
3797 | + <property name="lower">1</property> |
3798 | + <property name="upper">1000</property> |
3799 | + <property name="step_increment">1</property> |
3800 | + </object> |
3801 | +</interface> |
3802 | |
3803 | === modified file 'gnome/settingsdialog.py' |
3804 | --- gnome/settingsdialog.py 2009-06-10 11:33:16 +0000 |
3805 | +++ gnome/settingsdialog.py 2009-10-01 16:35:20 +0000 |
3806 | @@ -24,7 +24,6 @@ |
3807 | pygtk.require("2.0") |
3808 | import gtk |
3809 | import gobject |
3810 | -import gtk.glade |
3811 | import datetime |
3812 | import gettext |
3813 | |
3814 | @@ -36,546 +35,558 @@ |
3815 | _=gettext.gettext |
3816 | |
3817 | |
3818 | -class SettingsDialog: |
3819 | - def __init__( self, config, parent ): |
3820 | - self.config = config |
3821 | - self.parent = parent |
3822 | - |
3823 | - self.glade = gtk.glade.XML( os.path.join( self.config.get_app_path(), 'gnome', 'settingsdialog.glade' ), None, 'backintime' ) |
3824 | - self.dialog = self.glade.get_widget( 'SettingsDialog' ) |
3825 | - self.dialog.set_transient_for( parent.window ) |
3826 | - |
3827 | - signals = { |
3828 | - 'on_btn_add_profile_clicked' : self.on_add_profile, |
3829 | - 'on_btn_edit_profile_clicked' : self.on_edit_profile, |
3830 | - 'on_btn_remove_profile_clicked' : self.on_remove_profile, |
3831 | - 'on_btn_add_include_clicked' : self.on_add_include, |
3832 | - 'on_btn_remove_include_clicked' : self.on_remove_include, |
3833 | - 'on_btn_add_exclude_clicked' : self.on_add_exclude, |
3834 | - 'on_btn_add_exclude_file_clicked' : self.on_add_exclude_file, |
3835 | - 'on_btn_add_exclude_folder_clicked' : self.on_add_exclude_folder, |
3836 | - 'on_btn_remove_exclude_clicked' : self.on_remove_exclude, |
3837 | - 'on_cb_remove_old_backup_toggled' : self.update_remove_old_backups, |
3838 | - 'on_cb_min_free_space_toggled' : self.update_min_free_space, |
3839 | - 'on_cb_per_directory_schedule_toggled' : self.on_cb_per_directory_schedule_toggled, |
3840 | - 'on_combo_profiles_changed': self.on_combo_profiles_changed, |
3841 | - 'on_btn_where_clicked': self.on_btn_where_clicked, |
3842 | - } |
3843 | - |
3844 | - self.glade.signal_autoconnect( signals ) |
3845 | - |
3846 | - #profiles |
3847 | - self.btn_edit_profile = self.glade.get_widget( 'btn_edit_profile' ) |
3848 | - self.btn_add_profile = self.glade.get_widget( 'btn_add_profile' ) |
3849 | - self.btn_remove_profile = self.glade.get_widget( 'btn_remove_profile' ) |
3850 | - self.combo_profiles = self.glade.get_widget( 'combo_profiles' ) |
3851 | - |
3852 | - self.disable_combo_changed = True |
3853 | - |
3854 | - self.store_profiles = gtk.ListStore( str, str ) |
3855 | - |
3856 | - self.combo_profiles = self.glade.get_widget( 'combo_profiles' ) |
3857 | - |
3858 | - text_renderer = gtk.CellRendererText() |
3859 | - self.combo_profiles.pack_start( text_renderer, True ) |
3860 | - self.combo_profiles.add_attribute( text_renderer, 'text', 0 ) |
3861 | - |
3862 | - self.combo_profiles.set_model( self.store_profiles ) |
3863 | - |
3864 | - self.disable_combo_changed = False |
3865 | - |
3866 | - #set current folder |
3867 | - #self.fcb_where = self.glade.get_widget( 'fcb_where' ) |
3868 | - #self.fcb_where.set_show_hidden( self.parent.show_hidden_files ) |
3869 | - self.edit_where = self.glade.get_widget( 'edit_where' ) |
3870 | - |
3871 | - #automatic backup mode store |
3872 | - self.store_backup_mode = gtk.ListStore( str, int ) |
3873 | - default_automatic_backup_mode_index = 0 |
3874 | - map = self.config.AUTOMATIC_BACKUP_MODES |
3875 | - self.rev_automatic_backup_modes = {} |
3876 | - keys = map.keys() |
3877 | - keys.sort() |
3878 | - for key in keys: |
3879 | - self.rev_automatic_backup_modes[ map[key] ] = key |
3880 | - self.store_backup_mode.append( [ map[key], key ] ) |
3881 | - |
3882 | - #per directory schedule |
3883 | - self.cb_per_directory_schedule = self.glade.get_widget( 'cb_per_directory_schedule' ) |
3884 | - self.lbl_schedule = self.glade.get_widget( 'lbl_schedule' ) |
3885 | - |
3886 | - #setup include folders |
3887 | - self.list_include = self.glade.get_widget( 'list_include' ) |
3888 | - |
3889 | - pix_renderer = gtk.CellRendererPixbuf() |
3890 | - text_renderer = gtk.CellRendererText() |
3891 | - |
3892 | - column = gtk.TreeViewColumn( _('Include folders') ) |
3893 | - column.pack_start( pix_renderer, False ) |
3894 | - column.pack_end( text_renderer, True ) |
3895 | - column.add_attribute( pix_renderer, 'stock-id', 1 ) |
3896 | - column.add_attribute( text_renderer, 'markup', 0 ) |
3897 | - self.list_include.append_column( column ) |
3898 | - |
3899 | - column = gtk.TreeViewColumn( _('Schedule') ) |
3900 | - combo_renderer = gtk.CellRendererCombo() |
3901 | - combo_renderer.set_property( 'editable', True ) |
3902 | - combo_renderer.set_property( 'has-entry', False ) |
3903 | - combo_renderer.set_property( 'model', self.store_backup_mode ) |
3904 | - combo_renderer.set_property( 'text-column', 0 ) |
3905 | - combo_renderer.connect( 'edited', self.on_automatic_backup_mode_changed ) |
3906 | - column.pack_end( combo_renderer, True ) |
3907 | - column.add_attribute( combo_renderer, 'text', 2 ) |
3908 | - |
3909 | - self.include_schedule_column = column |
3910 | - |
3911 | - self.store_include = gtk.ListStore( str, str, str, int ) |
3912 | - self.list_include.set_model( self.store_include ) |
3913 | - |
3914 | - #setup exclude patterns |
3915 | - self.list_exclude = self.glade.get_widget( 'list_exclude' ) |
3916 | - |
3917 | - pix_renderer = gtk.CellRendererPixbuf() |
3918 | - text_renderer = gtk.CellRendererText() |
3919 | - |
3920 | - column = gtk.TreeViewColumn( _('Patterns, files or folders') ) |
3921 | - column.pack_start( pix_renderer, False ) |
3922 | - column.pack_end( text_renderer, True ) |
3923 | - column.add_attribute( pix_renderer, 'stock-id', 1 ) |
3924 | - column.add_attribute( text_renderer, 'markup', 0 ) |
3925 | - self.list_exclude.append_column( column ) |
3926 | - |
3927 | - self.store_exclude = gtk.ListStore( str, str ) |
3928 | - self.list_exclude.set_model( self.store_exclude ) |
3929 | - |
3930 | - #setup automatic backup mode |
3931 | - self.cb_backup_mode = self.glade.get_widget( 'cb_backup_mode' ) |
3932 | - self.cb_backup_mode.set_model( self.store_backup_mode ) |
3933 | - |
3934 | - self.cb_backup_mode.clear() |
3935 | - renderer = gtk.CellRendererText() |
3936 | - self.cb_backup_mode.pack_start( renderer, True ) |
3937 | - self.cb_backup_mode.add_attribute( renderer, 'text', 0 ) |
3938 | - |
3939 | - #setup remove old backups older than |
3940 | - self.edit_remove_old_backup_value = self.glade.get_widget( 'edit_remove_old_backup_value' ) |
3941 | - self.cb_remove_old_backup_unit = self.glade.get_widget( 'cb_remove_old_backup_unit' ) |
3942 | - |
3943 | - self.store_remove_old_backup_unit = gtk.ListStore( str, int ) |
3944 | - self.cb_remove_old_backup_unit.set_model( self.store_remove_old_backup_unit ) |
3945 | - |
3946 | - renderer = gtk.CellRendererText() |
3947 | - self.cb_remove_old_backup_unit.pack_start( renderer, True ) |
3948 | - self.cb_remove_old_backup_unit.add_attribute( renderer, 'text', 0 ) |
3949 | - |
3950 | - self.store_remove_old_backup_unit.clear() |
3951 | - map = self.config.REMOVE_OLD_BACKUP_UNITS |
3952 | - keys = map.keys() |
3953 | - keys.sort() |
3954 | - for key in keys: |
3955 | - self.store_remove_old_backup_unit.append( [ map[ key ], key ] ) |
3956 | - |
3957 | - self.cb_remove_old_backup = self.glade.get_widget( 'cb_remove_old_backup' ) |
3958 | - |
3959 | - #setup min free space |
3960 | - self.edit_min_free_space_value = self.glade.get_widget( 'edit_min_free_space_value' ) |
3961 | - self.cb_min_free_space_unit = self.glade.get_widget( 'cb_min_free_space_unit' ) |
3962 | - |
3963 | - self.store_min_free_space_unit = gtk.ListStore( str, int ) |
3964 | - self.cb_min_free_space_unit.set_model( self.store_min_free_space_unit ) |
3965 | - |
3966 | - renderer = gtk.CellRendererText() |
3967 | - self.cb_min_free_space_unit.pack_start( renderer, True ) |
3968 | - self.cb_min_free_space_unit.add_attribute( renderer, 'text', 0 ) |
3969 | - |
3970 | - self.store_min_free_space_unit.clear() |
3971 | - map = self.config.MIN_FREE_SPACE_UNITS |
3972 | - keys = map.keys() |
3973 | - keys.sort() |
3974 | - for key in keys: |
3975 | - self.store_min_free_space_unit.append( [ map[ key ], key ] ) |
3976 | - |
3977 | - self.cb_min_free_space = self.glade.get_widget( 'cb_min_free_space' ) |
3978 | - |
3979 | - #don't remove named snapshots |
3980 | - self.cb_dont_remove_named_snapshots = self.glade.get_widget( 'cb_dont_remove_named_snapshots' ) |
3981 | - self.cb_dont_remove_named_snapshots.set_active( self.config.get_dont_remove_named_snapshots() ) |
3982 | - |
3983 | - #smart remove |
3984 | - self.cb_smart_remove = self.glade.get_widget( 'cb_smart_remove' ) |
3985 | - |
3986 | - #enable notifications |
3987 | - self.cb_enable_notifications = self.glade.get_widget( 'cb_enable_notifications' ) |
3988 | - |
3989 | - self.update_profiles() |
3990 | - |
3991 | - def error_handler( self, message ): |
3992 | - messagebox.show_error( self.dialog, self.config, message ) |
3993 | - |
3994 | - def question_handler( self, message ): |
3995 | - return gtk.RESPONSE_YES == messagebox.show_question( self.dialog, self.config, message ) |
3996 | - |
3997 | - def on_automatic_backup_mode_changed( self, renderer, path, new_text ): |
3998 | - iter = self.store_include.get_iter(path) |
3999 | - self.store_include.set_value( iter, 2, new_text ) |
4000 | - self.store_include.set_value( iter, 3, self.rev_automatic_backup_modes[new_text] ) |
4001 | - |
4002 | - def on_btn_where_clicked( self, button ): |
4003 | - path = self.edit_where.get_text() |
4004 | - |
4005 | - 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) ) |
4006 | - if len( path ) > 0: |
4007 | - fcd.set_filename( path ) |
4008 | - |
4009 | - if fcd.run() == gtk.RESPONSE_OK: |
4010 | - new_path = tools.prepare_path( fcd.get_filename() ) |
4011 | - fcd.destroy() |
4012 | - if len( path ) > 0 and new_path != path: |
4013 | - if not self.question_handler( _('Are you sure you want to change snapshots folder ?') ): |
4014 | - return |
4015 | - self.edit_where.set_text( new_path ) |
4016 | - else: |
4017 | - fcd.destroy() |
4018 | - |
4019 | - def on_combo_profiles_changed( self, *params ): |
4020 | - if self.disable_combo_changed: |
4021 | - return |
4022 | - |
4023 | - iter = self.combo_profiles.get_active_iter() |
4024 | - if iter is None: |
4025 | - return |
4026 | - |
4027 | - profile_id = self.store_profiles.get_value( iter, 1 ) |
4028 | - if profile_id != self.config.get_current_profile(): |
4029 | - self.save_profile() |
4030 | - self.config.set_current_profile( profile_id ) |
4031 | - |
4032 | - self.update_profile() |
4033 | - |
4034 | - def update_profiles( self ): |
4035 | - self.disable_combo_changed = True |
4036 | - |
4037 | - profiles = self.config.get_profiles_sorted_by_name() |
4038 | - |
4039 | - select_iter = None |
4040 | - self.store_profiles.clear() |
4041 | - |
4042 | - for profile_id in profiles: |
4043 | - iter = self.store_profiles.append( [ self.config.get_profile_name( profile_id ), profile_id ] ) |
4044 | - if profile_id == self.config.get_current_profile(): |
4045 | - select_iter = iter |
4046 | - |
4047 | - self.disable_combo_changed = False |
4048 | - |
4049 | - if not select_iter is None: |
4050 | - self.combo_profiles.set_active_iter( select_iter ) |
4051 | - |
4052 | - def update_profile( self ): |
4053 | - if self.config.get_current_profile() == '1': |
4054 | - self.btn_edit_profile.set_sensitive( False ) |
4055 | - self.btn_remove_profile.set_sensitive( False ) |
4056 | - else: |
4057 | - self.btn_edit_profile.set_sensitive( True ) |
4058 | - self.btn_remove_profile.set_sensitive( True ) |
4059 | - |
4060 | - #set current folder |
4061 | - #self.fcb_where.set_filename( self.config.get_snapshots_path() ) |
4062 | - self.edit_where.set_text( self.config.get_snapshots_path() ) |
4063 | - |
4064 | - #per directory schedule |
4065 | - self.cb_per_directory_schedule.set_active( self.config.get_per_directory_schedule() ) |
4066 | - |
4067 | - #setup include folders |
4068 | - self.update_per_directory_option() |
4069 | - |
4070 | - self.store_include.clear() |
4071 | - include_folders = self.config.get_include_folders() |
4072 | - if len( include_folders ) > 0: |
4073 | - for include_folder in include_folders: |
4074 | - self.store_include.append( [include_folder[0], gtk.STOCK_DIRECTORY, self.config.AUTOMATIC_BACKUP_MODES[include_folder[1]], include_folder[1] ] ) |
4075 | - |
4076 | - #setup exclude patterns |
4077 | - self.store_exclude.clear() |
4078 | - exclude_patterns = self.config.get_exclude_patterns() |
4079 | - if len( exclude_patterns ) > 0: |
4080 | - for exclude_pattern in exclude_patterns: |
4081 | - self.store_exclude.append( [exclude_pattern, gtk.STOCK_DELETE] ) |
4082 | - |
4083 | - #setup automatic backup mode |
4084 | - i = 0 |
4085 | - iter = self.store_backup_mode.get_iter_first() |
4086 | - default_mode = self.config.get_automatic_backup_mode() |
4087 | - while not iter is None: |
4088 | - if self.store_backup_mode.get_value( iter, 1 ) == default_mode: |
4089 | - self.cb_backup_mode.set_active( i ) |
4090 | - break |
4091 | - iter = self.store_backup_mode.iter_next( iter ) |
4092 | - i = i + 1 |
4093 | - |
4094 | - #setup remove old backups older than |
4095 | - enabled, value, unit = self.config.get_remove_old_snapshots() |
4096 | - |
4097 | - self.edit_remove_old_backup_value.set_value( float( value ) ) |
4098 | - |
4099 | - i = 0 |
4100 | - iter = self.store_remove_old_backup_unit.get_iter_first() |
4101 | - while not iter is None: |
4102 | - if self.store_remove_old_backup_unit.get_value( iter, 1 ) == unit: |
4103 | - self.cb_remove_old_backup_unit.set_active( i ) |
4104 | - break |
4105 | - iter = self.store_remove_old_backup_unit.iter_next( iter ) |
4106 | - i = i + 1 |
4107 | - |
4108 | - self.cb_remove_old_backup.set_active( enabled ) |
4109 | - self.update_remove_old_backups( self.cb_remove_old_backup ) |
4110 | - |
4111 | - #setup min free space |
4112 | - enabled, value, unit = self.config.get_min_free_space() |
4113 | - |
4114 | - self.edit_min_free_space_value.set_value( float(value) ) |
4115 | - |
4116 | - i = 0 |
4117 | - iter = self.store_min_free_space_unit.get_iter_first() |
4118 | - while not iter is None: |
4119 | - if self.store_min_free_space_unit.get_value( iter, 1 ) == unit: |
4120 | - self.cb_min_free_space_unit.set_active( i ) |
4121 | - break |
4122 | - iter = self.store_min_free_space_unit.iter_next( iter ) |
4123 | - i = i + 1 |
4124 | - |
4125 | - self.cb_min_free_space.set_active( enabled ) |
4126 | - self.update_min_free_space( self.cb_min_free_space ) |
4127 | - |
4128 | - #don't remove named snapshots |
4129 | - self.cb_dont_remove_named_snapshots.set_active( self.config.get_dont_remove_named_snapshots() ) |
4130 | - |
4131 | - #smart remove |
4132 | - self.cb_smart_remove.set_active( self.config.get_smart_remove() ) |
4133 | - |
4134 | - #enable notifications |
4135 | - self.cb_enable_notifications.set_active( self.config.is_notify_enabled() ) |
4136 | - |
4137 | - #run 'nice' from cron |
4138 | - self.cb_run_nice_from_cron = self.glade.get_widget( 'cb_run_nice_from_cron' ) |
4139 | - self.cb_run_nice_from_cron.set_active( self.config.is_run_nice_from_cron_enabled() ) |
4140 | - |
4141 | - def save_profile( self ): |
4142 | - #snapshots path |
4143 | - snapshots_path = self.edit_where.get_text() |
4144 | - |
4145 | - #hack |
4146 | - if snapshots_path.startswith( '//' ): |
4147 | - snapshots_path = snapshots_path[ 1 : ] |
4148 | - |
4149 | - #include list |
4150 | - include_list = [] |
4151 | - iter = self.store_include.get_iter_first() |
4152 | - while not iter is None: |
4153 | - include_list.append( ( self.store_include.get_value( iter, 0 ), self.store_include.get_value( iter, 3 ) ) ) |
4154 | - iter = self.store_include.iter_next( iter ) |
4155 | - |
4156 | - #exclude patterns |
4157 | - exclude_list = [] |
4158 | - iter = self.store_exclude.get_iter_first() |
4159 | - while not iter is None: |
4160 | - exclude_list.append( self.store_exclude.get_value( iter, 0 ) ) |
4161 | - iter = self.store_exclude.iter_next( iter ) |
4162 | - |
4163 | - #check if back folder changed |
4164 | - #if len( self.config.get_snapshots_path() ) > 0 and self.config.get_snapshots_path() != snapshots_path: |
4165 | - # if gtk.RESPONSE_YES != messagebox.show_question( self.dialog, self.config, _('Are you sure you want to change snapshots folder ?') ): |
4166 | - # return False |
4167 | - |
4168 | - #ok let's save to config |
4169 | - self.config.set_snapshots_path( snapshots_path ) |
4170 | - #if not msg is None: |
4171 | - # messagebox.show_error( self.dialog, self.config, msg ) |
4172 | - # return False |
4173 | - |
4174 | - self.config.set_include_folders( include_list ) |
4175 | - self.config.set_exclude_patterns( exclude_list ) |
4176 | - |
4177 | - #global schedule |
4178 | - self.config.set_automatic_backup_mode( self.store_backup_mode.get_value( self.cb_backup_mode.get_active_iter(), 1 ) ) |
4179 | - |
4180 | - #auto-remove snapshots |
4181 | - self.config.set_remove_old_snapshots( |
4182 | - self.cb_remove_old_backup.get_active(), |
4183 | - int( self.edit_remove_old_backup_value.get_value() ), |
4184 | - self.store_remove_old_backup_unit.get_value( self.cb_remove_old_backup_unit.get_active_iter(), 1 ) ) |
4185 | - self.config.set_min_free_space( |
4186 | - self.cb_min_free_space.get_active(), |
4187 | - int( self.edit_min_free_space_value.get_value() ), |
4188 | - self.store_min_free_space_unit.get_value( self.cb_min_free_space_unit.get_active_iter(), 1 ) ) |
4189 | - self.config.set_dont_remove_named_snapshots( self.cb_dont_remove_named_snapshots.get_active() ) |
4190 | - self.config.set_smart_remove( self.cb_smart_remove.get_active() ) |
4191 | - |
4192 | - #options |
4193 | - self.config.set_notify_enabled( self.cb_enable_notifications.get_active() ) |
4194 | - |
4195 | - #expert options |
4196 | - self.config.set_per_directory_schedule( self.cb_per_directory_schedule.get_active() ) |
4197 | - self.config.set_run_nice_from_cron_enabled( self.cb_run_nice_from_cron.get_active() ) |
4198 | - |
4199 | - def update_remove_old_backups( self, button ): |
4200 | - enabled = self.cb_remove_old_backup.get_active() |
4201 | - self.edit_remove_old_backup_value.set_sensitive( enabled ) |
4202 | - self.cb_remove_old_backup_unit.set_sensitive( enabled ) |
4203 | - |
4204 | - def update_min_free_space( self, button ): |
4205 | - enabled = self.cb_min_free_space.get_active() |
4206 | - self.edit_min_free_space_value.set_sensitive( enabled ) |
4207 | - self.cb_min_free_space_unit.set_sensitive( enabled ) |
4208 | - |
4209 | - def on_cb_per_directory_schedule_toggled( self, button ): |
4210 | - self.update_per_directory_option() |
4211 | - |
4212 | - def update_per_directory_option( self ): |
4213 | - if self.cb_per_directory_schedule.get_active(): |
4214 | - if self.list_include.get_column(1) == None: |
4215 | - self.list_include.append_column( self.include_schedule_column ) |
4216 | - self.cb_backup_mode.hide() |
4217 | - self.lbl_schedule.hide() |
4218 | - else: |
4219 | - if self.list_include.get_column(1) != None: |
4220 | - self.list_include.remove_column( self.include_schedule_column ) |
4221 | - self.lbl_schedule.show() |
4222 | - self.cb_backup_mode.show() |
4223 | - |
4224 | - def run( self ): |
4225 | - self.config.set_question_handler( self.question_handler ) |
4226 | - self.config.set_error_handler( self.error_handler ) |
4227 | - |
4228 | - self.config_copy_dict = copy.copy( self.config.dict ) |
4229 | - self.current_profile_org = self.config.get_current_profile() |
4230 | - |
4231 | - while True: |
4232 | - if gtk.RESPONSE_OK == self.dialog.run(): |
4233 | - if not self.validate(): |
4234 | - continue |
4235 | - else: |
4236 | - self.config.dict = self.config_copy_dict |
4237 | - |
4238 | - break |
4239 | - |
4240 | - self.config.set_current_profile( self.current_profile_org ) |
4241 | - self.config.clear_handlers() |
4242 | - |
4243 | - self.dialog.destroy() |
4244 | - |
4245 | - def on_add_profile( self, button ): |
4246 | - name = messagebox.text_input_dialog( self.dialog, self.config, _('New profile'), None ) |
4247 | - if name is None: |
4248 | - return |
4249 | - if len( name ) <= 0: |
4250 | - return |
4251 | - |
4252 | - if not self.config.add_profile( name ): |
4253 | - return |
4254 | - |
4255 | - self.update_profiles() |
4256 | - |
4257 | - def on_edit_profile( self, button ): |
4258 | - name = messagebox.text_input_dialog( self.dialog, self.config, _('Rename profile'), None ) |
4259 | - if name is None: |
4260 | - return |
4261 | - if len( name ) <= 0: |
4262 | - return |
4263 | - |
4264 | - if not self.config.set_profile_name( name ): |
4265 | - return |
4266 | - |
4267 | - self.update_profiles() |
4268 | - |
4269 | - def on_remove_profile( self, button ): |
4270 | - 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() ): |
4271 | - self.config.remove_profile() |
4272 | - self.update_profiles() |
4273 | - |
4274 | - def on_add_include( self, button ): |
4275 | - 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) ) |
4276 | - fcd.set_show_hidden( self.parent.show_hidden_files ) |
4277 | - |
4278 | - if fcd.run() == gtk.RESPONSE_OK: |
4279 | - include_folder = tools.prepare_path( fcd.get_filename() ) |
4280 | - |
4281 | - iter = self.store_include.get_iter_first() |
4282 | - while not iter is None: |
4283 | - if self.store_include.get_value( iter, 0 ) == include_folder: |
4284 | - break |
4285 | - iter = self.store_include.iter_next( iter ) |
4286 | - |
4287 | - if iter is None: |
4288 | - self.store_include.append( [include_folder, gtk.STOCK_DIRECTORY, self.config.AUTOMATIC_BACKUP_MODES[self.config.NONE], self.config.NONE ] ) |
4289 | - |
4290 | - fcd.destroy() |
4291 | - |
4292 | - def on_remove_include( self, button ): |
4293 | - store, iter = self.list_include.get_selection().get_selected() |
4294 | - if not iter is None: |
4295 | - store.remove( iter ) |
4296 | - |
4297 | - def add_exclude_( self, pattern ): |
4298 | - pattern = pattern.strip() |
4299 | - if len( pattern ) == 0: |
4300 | - return |
4301 | - |
4302 | - iter = self.store_exclude.get_iter_first() |
4303 | - while not iter is None: |
4304 | - if self.store_exclude.get_value( iter, 0 ) == pattern: |
4305 | - return |
4306 | - iter = self.store_exclude.iter_next( iter ) |
4307 | - |
4308 | - self.store_exclude.append( [pattern, gtk.STOCK_DELETE] ) |
4309 | - |
4310 | - def on_add_exclude( self, button ): |
4311 | - pattern = messagebox.text_input_dialog( self.dialog, self.config, _('Exclude pattern') ) |
4312 | - if pattern is None: |
4313 | - return |
4314 | - |
4315 | - if pattern.find( ':' ) >= 0: |
4316 | - messagebox.show_error( self.dialog, self.config, _('Exclude patterns can\'t contain \':\' char !') ) |
4317 | - return |
4318 | - |
4319 | - self.add_exclude_( pattern ) |
4320 | - |
4321 | - def on_add_exclude_file( self, button ): |
4322 | - fcd = gtk.FileChooserDialog( _('Exclude file'), self.dialog, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) ) |
4323 | - fcd.set_show_hidden( self.parent.show_hidden_files ) |
4324 | - |
4325 | - if fcd.run() == gtk.RESPONSE_OK: |
4326 | - pattern = tools.prepare_path( fcd.get_filename() ) |
4327 | - self.add_exclude_( pattern ) |
4328 | - |
4329 | - fcd.destroy() |
4330 | - |
4331 | - def on_add_exclude_folder( self, button ): |
4332 | - 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) ) |
4333 | - fcd.set_show_hidden( self.parent.show_hidden_files ) |
4334 | - |
4335 | - if fcd.run() == gtk.RESPONSE_OK: |
4336 | - pattern = tools.prepare_path( fcd.get_filename() ) |
4337 | - self.add_exclude_( pattern ) |
4338 | - |
4339 | - fcd.destroy() |
4340 | - |
4341 | - def on_remove_exclude( self, button ): |
4342 | - store, iter = self.list_exclude.get_selection().get_selected() |
4343 | - if not iter is None: |
4344 | - store.remove( iter ) |
4345 | - |
4346 | - def on_cancel( self, button ): |
4347 | - self.dialog.destroy() |
4348 | - |
4349 | - def validate( self ): |
4350 | - self.save_profile() |
4351 | - |
4352 | - if not self.config.check_config(): |
4353 | - return False |
4354 | - |
4355 | - if not self.config.setup_cron(): |
4356 | - return False |
4357 | - |
4358 | - self.config.save() |
4359 | - return True |
4360 | - |
4361 | +class SettingsDialog(object): |
4362 | + |
4363 | + def __init__( self, config, parent ): |
4364 | + |
4365 | + self.config = config |
4366 | + self.parent = parent |
4367 | + |
4368 | + builder = gtk.Builder() |
4369 | + self.builder = builder |
4370 | + |
4371 | + glade_file = os.path.join(self.config.get_app_path(), |
4372 | + 'gnome', 'settingsdialog.glade') |
4373 | + |
4374 | + builder.add_from_file(glade_file) |
4375 | + |
4376 | + get = builder.get_object |
4377 | + |
4378 | + self.dialog = get('SettingsDialog') |
4379 | + self.dialog.set_transient_for( parent.window ) |
4380 | + |
4381 | + signals = { |
4382 | + 'on_btn_add_profile_clicked' : self.on_add_profile, |
4383 | + 'on_btn_edit_profile_clicked' : self.on_edit_profile, |
4384 | + 'on_btn_remove_profile_clicked' : self.on_remove_profile, |
4385 | + 'on_btn_add_include_clicked' : self.on_add_include, |
4386 | + 'on_btn_remove_include_clicked' : self.on_remove_include, |
4387 | + 'on_btn_add_exclude_clicked' : self.on_add_exclude, |
4388 | + 'on_btn_add_exclude_file_clicked' : self.on_add_exclude_file, |
4389 | + 'on_btn_add_exclude_folder_clicked' : self.on_add_exclude_folder, |
4390 | + 'on_btn_remove_exclude_clicked' : self.on_remove_exclude, |
4391 | + 'on_cb_remove_old_backup_toggled' : self.update_remove_old_backups, |
4392 | + 'on_cb_min_free_space_toggled' : self.update_min_free_space, |
4393 | + 'on_cb_per_directory_schedule_toggled' : self.on_cb_per_directory_schedule_toggled, |
4394 | + 'on_combo_profiles_changed': self.on_combo_profiles_changed, |
4395 | + 'on_btn_where_clicked': self.on_btn_where_clicked, |
4396 | + } |
4397 | + |
4398 | + builder.connect_signals(signals) |
4399 | + |
4400 | + #profiles |
4401 | + self.btn_edit_profile = get( 'btn_edit_profile' ) |
4402 | + self.btn_add_profile = get( 'btn_add_profile' ) |
4403 | + self.btn_remove_profile = get( 'btn_remove_profile' ) |
4404 | + self.combo_profiles = get( 'combo_profiles' ) |
4405 | + |
4406 | + self.disable_combo_changed = True |
4407 | + |
4408 | + self.store_profiles = gtk.ListStore( str, str ) |
4409 | + |
4410 | + self.combo_profiles = get( 'combo_profiles' ) |
4411 | + |
4412 | + text_renderer = gtk.CellRendererText() |
4413 | + self.combo_profiles.pack_start( text_renderer, True ) |
4414 | + self.combo_profiles.add_attribute( text_renderer, 'text', 0 ) |
4415 | + |
4416 | + self.combo_profiles.set_model( self.store_profiles ) |
4417 | + |
4418 | + self.disable_combo_changed = False |
4419 | + |
4420 | + #set current folder |
4421 | + #self.fcb_where = get( 'fcb_where' ) |
4422 | + #self.fcb_where.set_show_hidden( self.parent.show_hidden_files ) |
4423 | + self.edit_where = get( 'edit_where' ) |
4424 | + |
4425 | + #automatic backup mode store |
4426 | + self.store_backup_mode = gtk.ListStore( str, int ) |
4427 | + default_automatic_backup_mode_index = 0 |
4428 | + map = self.config.AUTOMATIC_BACKUP_MODES |
4429 | + self.rev_automatic_backup_modes = {} |
4430 | + keys = map.keys() |
4431 | + keys.sort() |
4432 | + for key in keys: |
4433 | + self.rev_automatic_backup_modes[ map[key] ] = key |
4434 | + self.store_backup_mode.append( [ map[key], key ] ) |
4435 | + |
4436 | + #per directory schedule |
4437 | + self.cb_per_directory_schedule = get( 'cb_per_directory_schedule' ) |
4438 | + self.lbl_schedule = get( 'lbl_schedule' ) |
4439 | + |
4440 | + #setup include folders |
4441 | + self.list_include = get( 'list_include' ) |
4442 | + |
4443 | + pix_renderer = gtk.CellRendererPixbuf() |
4444 | + text_renderer = gtk.CellRendererText() |
4445 | + |
4446 | + column = gtk.TreeViewColumn( _('Include folders') ) |
4447 | + column.pack_start( pix_renderer, False ) |
4448 | + column.pack_end( text_renderer, True ) |
4449 | + column.add_attribute( pix_renderer, 'stock-id', 1 ) |
4450 | + column.add_attribute( text_renderer, 'markup', 0 ) |
4451 | + self.list_include.append_column( column ) |
4452 | + |
4453 | + column = gtk.TreeViewColumn( _('Schedule') ) |
4454 | + combo_renderer = gtk.CellRendererCombo() |
4455 | + combo_renderer.set_property( 'editable', True ) |
4456 | + combo_renderer.set_property( 'has-entry', False ) |
4457 | + combo_renderer.set_property( 'model', self.store_backup_mode ) |
4458 | + combo_renderer.set_property( 'text-column', 0 ) |
4459 | + combo_renderer.connect( 'edited', self.on_automatic_backup_mode_changed ) |
4460 | + column.pack_end( combo_renderer, True ) |
4461 | + column.add_attribute( combo_renderer, 'text', 2 ) |
4462 | + |
4463 | + self.include_schedule_column = column |
4464 | + |
4465 | + self.store_include = gtk.ListStore( str, str, str, int ) |
4466 | + self.list_include.set_model( self.store_include ) |
4467 | + |
4468 | + #setup exclude patterns |
4469 | + self.list_exclude = get( 'list_exclude' ) |
4470 | + |
4471 | + pix_renderer = gtk.CellRendererPixbuf() |
4472 | + text_renderer = gtk.CellRendererText() |
4473 | + |
4474 | + column = gtk.TreeViewColumn( _('Patterns, files or folders') ) |
4475 | + column.pack_start( pix_renderer, False ) |
4476 | + column.pack_end( text_renderer, True ) |
4477 | + column.add_attribute( pix_renderer, 'stock-id', 1 ) |
4478 | + column.add_attribute( text_renderer, 'markup', 0 ) |
4479 | + self.list_exclude.append_column( column ) |
4480 | + |
4481 | + self.store_exclude = gtk.ListStore( str, str ) |
4482 | + self.list_exclude.set_model( self.store_exclude ) |
4483 | + |
4484 | + #setup automatic backup mode |
4485 | + self.cb_backup_mode = get( 'cb_backup_mode' ) |
4486 | + self.cb_backup_mode.set_model( self.store_backup_mode ) |
4487 | + |
4488 | + self.cb_backup_mode.clear() |
4489 | + renderer = gtk.CellRendererText() |
4490 | + self.cb_backup_mode.pack_start( renderer, True ) |
4491 | + self.cb_backup_mode.add_attribute( renderer, 'text', 0 ) |
4492 | + |
4493 | + #setup remove old backups older than |
4494 | + self.edit_remove_old_backup_value = get( 'edit_remove_old_backup_value' ) |
4495 | + self.cb_remove_old_backup_unit = get( 'cb_remove_old_backup_unit' ) |
4496 | + |
4497 | + self.store_remove_old_backup_unit = gtk.ListStore( str, int ) |
4498 | + self.cb_remove_old_backup_unit.set_model( self.store_remove_old_backup_unit ) |
4499 | + |
4500 | + renderer = gtk.CellRendererText() |
4501 | + self.cb_remove_old_backup_unit.pack_start( renderer, True ) |
4502 | + self.cb_remove_old_backup_unit.add_attribute( renderer, 'text', 0 ) |
4503 | + |
4504 | + self.store_remove_old_backup_unit.clear() |
4505 | + map = self.config.REMOVE_OLD_BACKUP_UNITS |
4506 | + keys = map.keys() |
4507 | + keys.sort() |
4508 | + for key in keys: |
4509 | + self.store_remove_old_backup_unit.append( [ map[ key ], key ] ) |
4510 | + |
4511 | + self.cb_remove_old_backup = get( 'cb_remove_old_backup' ) |
4512 | + |
4513 | + #setup min free space |
4514 | + self.edit_min_free_space_value = get( 'edit_min_free_space_value' ) |
4515 | + self.cb_min_free_space_unit = get( 'cb_min_free_space_unit' ) |
4516 | + |
4517 | + self.store_min_free_space_unit = gtk.ListStore( str, int ) |
4518 | + self.cb_min_free_space_unit.set_model( self.store_min_free_space_unit ) |
4519 | + |
4520 | + renderer = gtk.CellRendererText() |
4521 | + self.cb_min_free_space_unit.pack_start( renderer, True ) |
4522 | + self.cb_min_free_space_unit.add_attribute( renderer, 'text', 0 ) |
4523 | + |
4524 | + self.store_min_free_space_unit.clear() |
4525 | + map = self.config.MIN_FREE_SPACE_UNITS |
4526 | + keys = map.keys() |
4527 | + keys.sort() |
4528 | + for key in keys: |
4529 | + self.store_min_free_space_unit.append( [ map[ key ], key ] ) |
4530 | + |
4531 | + self.cb_min_free_space = get( 'cb_min_free_space' ) |
4532 | + |
4533 | + #don't remove named snapshots |
4534 | + self.cb_dont_remove_named_snapshots = get( 'cb_dont_remove_named_snapshots' ) |
4535 | + self.cb_dont_remove_named_snapshots.set_active( self.config.get_dont_remove_named_snapshots() ) |
4536 | + |
4537 | + #smart remove |
4538 | + self.cb_smart_remove = get( 'cb_smart_remove' ) |
4539 | + |
4540 | + #enable notifications |
4541 | + self.cb_enable_notifications = get( 'cb_enable_notifications' ) |
4542 | + |
4543 | + self.update_profiles() |
4544 | + |
4545 | + def error_handler( self, message ): |
4546 | + messagebox.show_error( self.dialog, self.config, message ) |
4547 | + |
4548 | + def question_handler( self, message ): |
4549 | + return gtk.RESPONSE_YES == messagebox.show_question( self.dialog, self.config, message ) |
4550 | + |
4551 | + def on_automatic_backup_mode_changed( self, renderer, path, new_text ): |
4552 | + iter = self.store_include.get_iter(path) |
4553 | + self.store_include.set_value( iter, 2, new_text ) |
4554 | + self.store_include.set_value( iter, 3, self.rev_automatic_backup_modes[new_text] ) |
4555 | + |
4556 | + def on_btn_where_clicked( self, button ): |
4557 | + path = self.edit_where.get_text() |
4558 | + |
4559 | + 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) ) |
4560 | + if len( path ) > 0: |
4561 | + fcd.set_filename( path ) |
4562 | + |
4563 | + if fcd.run() == gtk.RESPONSE_OK: |
4564 | + new_path = tools.prepare_path( fcd.get_filename() ) |
4565 | + fcd.destroy() |
4566 | + if len( path ) > 0 and new_path != path: |
4567 | + if not self.question_handler( _('Are you sure you want to change snapshots folder ?') ): |
4568 | + return |
4569 | + self.edit_where.set_text( new_path ) |
4570 | + else: |
4571 | + fcd.destroy() |
4572 | + |
4573 | + def on_combo_profiles_changed( self, *params ): |
4574 | + if self.disable_combo_changed: |
4575 | + return |
4576 | + |
4577 | + iter = self.combo_profiles.get_active_iter() |
4578 | + if iter is None: |
4579 | + return |
4580 | + |
4581 | + profile_id = self.store_profiles.get_value( iter, 1 ) |
4582 | + if profile_id != self.config.get_current_profile(): |
4583 | + self.save_profile() |
4584 | + self.config.set_current_profile( profile_id ) |
4585 | + |
4586 | + self.update_profile() |
4587 | + |
4588 | + def update_profiles( self ): |
4589 | + self.disable_combo_changed = True |
4590 | + |
4591 | + profiles = self.config.get_profiles_sorted_by_name() |
4592 | + |
4593 | + select_iter = None |
4594 | + self.store_profiles.clear() |
4595 | + |
4596 | + for profile_id in profiles: |
4597 | + iter = self.store_profiles.append( [ self.config.get_profile_name( profile_id ), profile_id ] ) |
4598 | + if profile_id == self.config.get_current_profile(): |
4599 | + select_iter = iter |
4600 | + |
4601 | + self.disable_combo_changed = False |
4602 | + |
4603 | + if not select_iter is None: |
4604 | + self.combo_profiles.set_active_iter( select_iter ) |
4605 | + |
4606 | + def update_profile( self ): |
4607 | + if self.config.get_current_profile() == '1': |
4608 | + self.btn_edit_profile.set_sensitive( False ) |
4609 | + self.btn_remove_profile.set_sensitive( False ) |
4610 | + else: |
4611 | + self.btn_edit_profile.set_sensitive( True ) |
4612 | + self.btn_remove_profile.set_sensitive( True ) |
4613 | + |
4614 | + #set current folder |
4615 | + #self.fcb_where.set_filename( self.config.get_snapshots_path() ) |
4616 | + self.edit_where.set_text( self.config.get_snapshots_path() ) |
4617 | + |
4618 | + #per directory schedule |
4619 | + self.cb_per_directory_schedule.set_active( self.config.get_per_directory_schedule() ) |
4620 | + |
4621 | + #setup include folders |
4622 | + self.update_per_directory_option() |
4623 | + |
4624 | + self.store_include.clear() |
4625 | + include_folders = self.config.get_include_folders() |
4626 | + if len( include_folders ) > 0: |
4627 | + for include_folder in include_folders: |
4628 | + self.store_include.append( [include_folder[0], gtk.STOCK_DIRECTORY, self.config.AUTOMATIC_BACKUP_MODES[include_folder[1]], include_folder[1] ] ) |
4629 | + |
4630 | + #setup exclude patterns |
4631 | + self.store_exclude.clear() |
4632 | + exclude_patterns = self.config.get_exclude_patterns() |
4633 | + if len( exclude_patterns ) > 0: |
4634 | + for exclude_pattern in exclude_patterns: |
4635 | + self.store_exclude.append( [exclude_pattern, gtk.STOCK_DELETE] ) |
4636 | + |
4637 | + #setup automatic backup mode |
4638 | + i = 0 |
4639 | + iter = self.store_backup_mode.get_iter_first() |
4640 | + default_mode = self.config.get_automatic_backup_mode() |
4641 | + while not iter is None: |
4642 | + if self.store_backup_mode.get_value( iter, 1 ) == default_mode: |
4643 | + self.cb_backup_mode.set_active( i ) |
4644 | + break |
4645 | + iter = self.store_backup_mode.iter_next( iter ) |
4646 | + i = i + 1 |
4647 | + |
4648 | + #setup remove old backups older than |
4649 | + enabled, value, unit = self.config.get_remove_old_snapshots() |
4650 | + |
4651 | + self.edit_remove_old_backup_value.set_value( float( value ) ) |
4652 | + |
4653 | + i = 0 |
4654 | + iter = self.store_remove_old_backup_unit.get_iter_first() |
4655 | + while not iter is None: |
4656 | + if self.store_remove_old_backup_unit.get_value( iter, 1 ) == unit: |
4657 | + self.cb_remove_old_backup_unit.set_active( i ) |
4658 | + break |
4659 | + iter = self.store_remove_old_backup_unit.iter_next( iter ) |
4660 | + i = i + 1 |
4661 | + |
4662 | + self.cb_remove_old_backup.set_active( enabled ) |
4663 | + self.update_remove_old_backups( self.cb_remove_old_backup ) |
4664 | + |
4665 | + #setup min free space |
4666 | + enabled, value, unit = self.config.get_min_free_space() |
4667 | + |
4668 | + self.edit_min_free_space_value.set_value( float(value) ) |
4669 | + |
4670 | + i = 0 |
4671 | + iter = self.store_min_free_space_unit.get_iter_first() |
4672 | + while not iter is None: |
4673 | + if self.store_min_free_space_unit.get_value( iter, 1 ) == unit: |
4674 | + self.cb_min_free_space_unit.set_active( i ) |
4675 | + break |
4676 | + iter = self.store_min_free_space_unit.iter_next( iter ) |
4677 | + i = i + 1 |
4678 | + |
4679 | + self.cb_min_free_space.set_active( enabled ) |
4680 | + self.update_min_free_space( self.cb_min_free_space ) |
4681 | + |
4682 | + #don't remove named snapshots |
4683 | + self.cb_dont_remove_named_snapshots.set_active( self.config.get_dont_remove_named_snapshots() ) |
4684 | + |
4685 | + #smart remove |
4686 | + self.cb_smart_remove.set_active( self.config.get_smart_remove() ) |
4687 | + |
4688 | + #enable notifications |
4689 | + self.cb_enable_notifications.set_active( self.config.is_notify_enabled() ) |
4690 | + |
4691 | + #run 'nice' from cron |
4692 | + self.cb_run_nice_from_cron = self.builder.get_object('cb_run_nice_from_cron') |
4693 | + self.cb_run_nice_from_cron.set_active(self.config.is_run_nice_from_cron_enabled()) |
4694 | + |
4695 | + def save_profile( self ): |
4696 | + #snapshots path |
4697 | + snapshots_path = self.edit_where.get_text() |
4698 | + |
4699 | + #hack |
4700 | + if snapshots_path.startswith( '//' ): |
4701 | + snapshots_path = snapshots_path[ 1 : ] |
4702 | + |
4703 | + #include list |
4704 | + include_list = [] |
4705 | + iter = self.store_include.get_iter_first() |
4706 | + while not iter is None: |
4707 | + include_list.append( ( self.store_include.get_value( iter, 0 ), self.store_include.get_value( iter, 3 ) ) ) |
4708 | + iter = self.store_include.iter_next( iter ) |
4709 | + |
4710 | + #exclude patterns |
4711 | + exclude_list = [] |
4712 | + iter = self.store_exclude.get_iter_first() |
4713 | + while not iter is None: |
4714 | + exclude_list.append( self.store_exclude.get_value( iter, 0 ) ) |
4715 | + iter = self.store_exclude.iter_next( iter ) |
4716 | + |
4717 | + #check if back folder changed |
4718 | + #if len( self.config.get_snapshots_path() ) > 0 and self.config.get_snapshots_path() != snapshots_path: |
4719 | + # if gtk.RESPONSE_YES != messagebox.show_question( self.dialog, self.config, _('Are you sure you want to change snapshots folder ?') ): |
4720 | + # return False |
4721 | + |
4722 | + #ok let's save to config |
4723 | + self.config.set_snapshots_path( snapshots_path ) |
4724 | + #if not msg is None: |
4725 | + # messagebox.show_error( self.dialog, self.config, msg ) |
4726 | + # return False |
4727 | + |
4728 | + self.config.set_include_folders( include_list ) |
4729 | + self.config.set_exclude_patterns( exclude_list ) |
4730 | + |
4731 | + #global schedule |
4732 | + self.config.set_automatic_backup_mode( self.store_backup_mode.get_value( self.cb_backup_mode.get_active_iter(), 1 ) ) |
4733 | + |
4734 | + #auto-remove snapshots |
4735 | + self.config.set_remove_old_snapshots( |
4736 | + self.cb_remove_old_backup.get_active(), |
4737 | + int( self.edit_remove_old_backup_value.get_value() ), |
4738 | + self.store_remove_old_backup_unit.get_value( self.cb_remove_old_backup_unit.get_active_iter(), 1 ) ) |
4739 | + self.config.set_min_free_space( |
4740 | + self.cb_min_free_space.get_active(), |
4741 | + int( self.edit_min_free_space_value.get_value() ), |
4742 | + self.store_min_free_space_unit.get_value( self.cb_min_free_space_unit.get_active_iter(), 1 ) ) |
4743 | + self.config.set_dont_remove_named_snapshots( self.cb_dont_remove_named_snapshots.get_active() ) |
4744 | + self.config.set_smart_remove( self.cb_smart_remove.get_active() ) |
4745 | + |
4746 | + #options |
4747 | + self.config.set_notify_enabled( self.cb_enable_notifications.get_active() ) |
4748 | + |
4749 | + #expert options |
4750 | + self.config.set_per_directory_schedule( self.cb_per_directory_schedule.get_active() ) |
4751 | + self.config.set_run_nice_from_cron_enabled( self.cb_run_nice_from_cron.get_active() ) |
4752 | + |
4753 | + def update_remove_old_backups( self, button ): |
4754 | + enabled = self.cb_remove_old_backup.get_active() |
4755 | + self.edit_remove_old_backup_value.set_sensitive( enabled ) |
4756 | + self.cb_remove_old_backup_unit.set_sensitive( enabled ) |
4757 | + |
4758 | + def update_min_free_space( self, button ): |
4759 | + enabled = self.cb_min_free_space.get_active() |
4760 | + self.edit_min_free_space_value.set_sensitive( enabled ) |
4761 | + self.cb_min_free_space_unit.set_sensitive( enabled ) |
4762 | + |
4763 | + def on_cb_per_directory_schedule_toggled( self, button ): |
4764 | + self.update_per_directory_option() |
4765 | + |
4766 | + def update_per_directory_option( self ): |
4767 | + if self.cb_per_directory_schedule.get_active(): |
4768 | + if self.list_include.get_column(1) == None: |
4769 | + self.list_include.append_column( self.include_schedule_column ) |
4770 | + self.cb_backup_mode.hide() |
4771 | + self.lbl_schedule.hide() |
4772 | + else: |
4773 | + if self.list_include.get_column(1) != None: |
4774 | + self.list_include.remove_column( self.include_schedule_column ) |
4775 | + self.lbl_schedule.show() |
4776 | + self.cb_backup_mode.show() |
4777 | + |
4778 | + def run( self ): |
4779 | + self.config.set_question_handler( self.question_handler ) |
4780 | + self.config.set_error_handler( self.error_handler ) |
4781 | + |
4782 | + self.config_copy_dict = copy.copy( self.config.dict ) |
4783 | + self.current_profile_org = self.config.get_current_profile() |
4784 | + |
4785 | + while True: |
4786 | + if gtk.RESPONSE_OK == self.dialog.run(): |
4787 | + if not self.validate(): |
4788 | + continue |
4789 | + else: |
4790 | + self.config.dict = self.config_copy_dict |
4791 | + |
4792 | + break |
4793 | + |
4794 | + self.config.set_current_profile( self.current_profile_org ) |
4795 | + self.config.clear_handlers() |
4796 | + |
4797 | + self.dialog.destroy() |
4798 | + |
4799 | + def on_add_profile(self, button, data=None): |
4800 | + |
4801 | + name = messagebox.text_input_dialog( self.dialog, self.config, _('New profile'), None ) |
4802 | + if name is None: |
4803 | + return |
4804 | + if len( name ) <= 0: |
4805 | + return |
4806 | + |
4807 | + if not self.config.add_profile( name ): |
4808 | + return |
4809 | + |
4810 | + self.update_profiles() |
4811 | + |
4812 | + def on_edit_profile( self, button ): |
4813 | + name = messagebox.text_input_dialog( self.dialog, self.config, _('Rename profile'), None ) |
4814 | + if name is None: |
4815 | + return |
4816 | + if len( name ) <= 0: |
4817 | + return |
4818 | + |
4819 | + if not self.config.set_profile_name( name ): |
4820 | + return |
4821 | + |
4822 | + self.update_profiles() |
4823 | + |
4824 | + def on_remove_profile( self, button ): |
4825 | + 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() ): |
4826 | + self.config.remove_profile() |
4827 | + self.update_profiles() |
4828 | + |
4829 | + def on_add_include( self, button ): |
4830 | + 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) ) |
4831 | + fcd.set_show_hidden( self.parent.show_hidden_files ) |
4832 | + |
4833 | + if fcd.run() == gtk.RESPONSE_OK: |
4834 | + include_folder = tools.prepare_path( fcd.get_filename() ) |
4835 | + |
4836 | + iter = self.store_include.get_iter_first() |
4837 | + while not iter is None: |
4838 | + if self.store_include.get_value( iter, 0 ) == include_folder: |
4839 | + break |
4840 | + iter = self.store_include.iter_next( iter ) |
4841 | + |
4842 | + if iter is None: |
4843 | + self.store_include.append( [include_folder, gtk.STOCK_DIRECTORY, self.config.AUTOMATIC_BACKUP_MODES[self.config.NONE], self.config.NONE ] ) |
4844 | + |
4845 | + fcd.destroy() |
4846 | + |
4847 | + def on_remove_include( self, button ): |
4848 | + store, iter = self.list_include.get_selection().get_selected() |
4849 | + if not iter is None: |
4850 | + store.remove( iter ) |
4851 | + |
4852 | + def add_exclude_( self, pattern ): |
4853 | + pattern = pattern.strip() |
4854 | + if len( pattern ) == 0: |
4855 | + return |
4856 | + |
4857 | + iter = self.store_exclude.get_iter_first() |
4858 | + while not iter is None: |
4859 | + if self.store_exclude.get_value( iter, 0 ) == pattern: |
4860 | + return |
4861 | + iter = self.store_exclude.iter_next( iter ) |
4862 | + |
4863 | + self.store_exclude.append( [pattern, gtk.STOCK_DELETE] ) |
4864 | + |
4865 | + def on_add_exclude( self, button ): |
4866 | + pattern = messagebox.text_input_dialog( self.dialog, self.config, _('Exclude pattern') ) |
4867 | + if pattern is None: |
4868 | + return |
4869 | + |
4870 | + if pattern.find( ':' ) >= 0: |
4871 | + messagebox.show_error( self.dialog, self.config, _('Exclude patterns can\'t contain \':\' char !') ) |
4872 | + return |
4873 | + |
4874 | + self.add_exclude_( pattern ) |
4875 | + |
4876 | + def on_add_exclude_file( self, button ): |
4877 | + fcd = gtk.FileChooserDialog( _('Exclude file'), self.dialog, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) ) |
4878 | + fcd.set_show_hidden( self.parent.show_hidden_files ) |
4879 | + |
4880 | + if fcd.run() == gtk.RESPONSE_OK: |
4881 | + pattern = tools.prepare_path( fcd.get_filename() ) |
4882 | + self.add_exclude_( pattern ) |
4883 | + |
4884 | + fcd.destroy() |
4885 | + |
4886 | + def on_add_exclude_folder( self, button ): |
4887 | + 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) ) |
4888 | + fcd.set_show_hidden( self.parent.show_hidden_files ) |
4889 | + |
4890 | + if fcd.run() == gtk.RESPONSE_OK: |
4891 | + pattern = tools.prepare_path( fcd.get_filename() ) |
4892 | + self.add_exclude_( pattern ) |
4893 | + |
4894 | + fcd.destroy() |
4895 | + |
4896 | + def on_remove_exclude( self, button ): |
4897 | + store, iter = self.list_exclude.get_selection().get_selected() |
4898 | + if not iter is None: |
4899 | + store.remove( iter ) |
4900 | + |
4901 | + def on_cancel( self, button ): |
4902 | + self.dialog.destroy() |
4903 | + |
4904 | + def validate( self ): |
4905 | + self.save_profile() |
4906 | + |
4907 | + if not self.config.check_config(): |
4908 | + return False |
4909 | + |
4910 | + if not self.config.setup_cron(): |
4911 | + return False |
4912 | + |
4913 | + self.config.save() |
4914 | + return True |
4915 | + |
4916 | |
4917 | === modified file 'gnome/snapshotsdialog.glade' |
4918 | --- gnome/snapshotsdialog.glade 2009-04-27 13:43:00 +0000 |
4919 | +++ gnome/snapshotsdialog.glade 2009-10-01 16:35:20 +0000 |
4920 | @@ -1,176 +1,176 @@ |
4921 | -<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
4922 | -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> |
4923 | -<!--Generated with glade3 3.4.5 on Mon Apr 27 12:51:19 2009 --> |
4924 | -<glade-interface> |
4925 | - <widget class="GtkDialog" id="SnapshotsDialog"> |
4926 | +<?xml version="1.0"?> |
4927 | +<interface> |
4928 | + <requires lib="gtk+" version="2.16"/> |
4929 | + <!-- interface-naming-policy toplevel-contextual --> |
4930 | + <object class="GtkDialog" id="SnapshotsDialog"> |
4931 | <property name="border_width">5</property> |
4932 | <property name="title" translatable="yes">Snapshots</property> |
4933 | <property name="modal">True</property> |
4934 | - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> |
4935 | - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> |
4936 | + <property name="window_position">center-on-parent</property> |
4937 | + <property name="type_hint">dialog</property> |
4938 | <property name="skip_taskbar_hint">True</property> |
4939 | <property name="skip_pager_hint">True</property> |
4940 | - <property name="transient_for">MainWindow</property> |
4941 | <property name="has_separator">False</property> |
4942 | <child internal-child="vbox"> |
4943 | - <widget class="GtkVBox" id="dialog-vbox3"> |
4944 | + <object class="GtkVBox" id="dialog-vbox3"> |
4945 | <property name="visible">True</property> |
4946 | <property name="spacing">2</property> |
4947 | <child> |
4948 | - <widget class="GtkVBox" id="vbox3"> |
4949 | + <object class="GtkVBox" id="vbox3"> |
4950 | <property name="visible">True</property> |
4951 | <property name="spacing">2</property> |
4952 | <child> |
4953 | - <widget class="GtkEntry" id="edit_path"> |
4954 | + <object class="GtkEntry" id="edit_path"> |
4955 | <property name="visible">True</property> |
4956 | <property name="can_focus">True</property> |
4957 | <property name="editable">False</property> |
4958 | - </widget> |
4959 | + </object> |
4960 | <packing> |
4961 | <property name="expand">False</property> |
4962 | <property name="padding">2</property> |
4963 | + <property name="position">0</property> |
4964 | </packing> |
4965 | </child> |
4966 | <child> |
4967 | - <widget class="GtkToolbar" id="toolbar2"> |
4968 | + <object class="GtkToolbar" id="toolbar2"> |
4969 | <property name="visible">True</property> |
4970 | <child> |
4971 | - <widget class="GtkToolButton" id="btn_copy_snapshot"> |
4972 | + <object class="GtkToolButton" id="btn_copy_snapshot"> |
4973 | <property name="visible">True</property> |
4974 | - <property name="tooltip" translatable="yes">Copy</property> |
4975 | + <property name="tooltip_text" translatable="yes">Copy</property> |
4976 | <property name="label" translatable="yes">Copy</property> |
4977 | <property name="stock_id">gtk-copy</property> |
4978 | <signal name="clicked" handler="on_btn_copy_snapshot_clicked"/> |
4979 | - </widget> |
4980 | + </object> |
4981 | <packing> |
4982 | + <property name="expand">False</property> |
4983 | <property name="homogeneous">True</property> |
4984 | </packing> |
4985 | </child> |
4986 | <child> |
4987 | - <widget class="GtkToolButton" id="btn_restore_snapshot"> |
4988 | + <object class="GtkToolButton" id="btn_restore_snapshot"> |
4989 | <property name="visible">True</property> |
4990 | - <property name="tooltip" translatable="yes">Restore</property> |
4991 | + <property name="tooltip_text" translatable="yes">Restore</property> |
4992 | <property name="label" translatable="yes">Restore</property> |
4993 | <property name="stock_id">gtk-undelete</property> |
4994 | <signal name="clicked" handler="on_btn_restore_snapshot_clicked"/> |
4995 | - </widget> |
4996 | + </object> |
4997 | <packing> |
4998 | + <property name="expand">False</property> |
4999 | <property name="homogeneous">True</property> |
5000 | </packing> |
The diff has been truncated for viewing.
Nice rewrite of the GUI to switch from the libglade to the GTKbuilder format!