4
* Copyright 2013 Tony George <teejee2008@gmail.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
28
public class RestoreWindow : Gtk.Dialog{
29
private Box vbox_main;
30
private Box hbox_action;
31
private Notebook notebook;
34
private Label lbl_header_partitions;
35
private TreeView tv_partitions;
36
private ScrolledWindow sw_partitions;
37
private TreeViewColumn col_device_target;
38
private TreeViewColumn col_fs;
39
private TreeViewColumn col_size;
40
private TreeViewColumn col_used;
41
private TreeViewColumn col_label;
42
private TreeViewColumn col_dist;
45
private Label lbl_header_bootloader;
46
private CheckButton chk_restore_grub2;
47
private ComboBox cmb_boot_device;
50
private Label lbl_exclude;
51
private Box vbox_exclude;
52
private LinkButton lnk_default_list;
53
private TreeView tv_exclude;
54
private ScrolledWindow sw_exclude;
55
private TreeViewColumn col_exclude;
56
private Toolbar toolbar_exclude;
57
private ToolButton btn_remove;
58
private ToolButton btn_warning;
59
private ToolButton btn_reset_exclude_list;
61
private MenuToolButton btn_exclude;
62
private Gtk.Menu menu_exclude;
63
private ImageMenuItem menu_exclude_add_file;
64
private ImageMenuItem menu_exclude_add_folder;
65
private ImageMenuItem menu_exclude_add_folder_contents;
67
private MenuToolButton btn_include;
68
private Gtk.Menu menu_include;
69
private ImageMenuItem menu_include_add_file;
70
private ImageMenuItem menu_include_add_folder;
72
private Gee.ArrayList<string> temp_exclude_list;
75
private Button btn_cancel;
76
private Button btn_restore;
78
public RestoreWindow () {
79
this.title = _("Restore");
80
this.window_position = WindowPosition.CENTER_ON_PARENT;
81
this.set_destroy_with_parent (true);
82
this.set_modal (true);
83
this.set_default_size (500, 400);
87
this.icon = new Gdk.Pixbuf.from_file (App.share_folder + """/pixmaps/timeshift.png""");
90
log_error (e.message);
94
vbox_main = get_content_area ();
97
notebook = new Notebook ();
99
vbox_main.pack_start (notebook, true, true, 0);
101
//target device tab -------------------------------------------------
104
lbl_exclude = new Label (_("Target"));
107
Box vbox_target = new Box (Orientation.VERTICAL, 6);
108
vbox_target.margin = 6;
109
notebook.append_page (vbox_target, lbl_exclude);
111
//lbl_header_partitions
112
lbl_header_partitions = new Gtk.Label("<b>" + _("Target Device") + ":</b>");
113
lbl_header_partitions.xalign = (float) 0.0;
114
lbl_header_partitions.set_use_markup(true);
115
vbox_target.add(lbl_header_partitions);
118
tv_partitions = new TreeView();
119
tv_partitions.get_selection().mode = SelectionMode.SINGLE;
120
tv_partitions.set_rules_hint (true);
121
tv_partitions.button_release_event.connect(tv_partitions_button_press_event);
124
sw_partitions = new ScrolledWindow(null, null);
125
sw_partitions.set_shadow_type (ShadowType.ETCHED_IN);
126
sw_partitions.add (tv_partitions);
127
sw_partitions.expand = true;
128
vbox_target.add(sw_partitions);
131
col_device_target = new TreeViewColumn();
132
col_device_target.title = _("Device");
133
col_device_target.spacing = 1;
135
CellRendererPixbuf cell_device_icon = new CellRendererPixbuf ();
136
cell_device_icon.stock_id = Stock.HARDDISK;
137
cell_device_icon.xpad = 1;
138
col_device_target.pack_start (cell_device_icon, false);
140
CellRendererText cell_device_target = new CellRendererText ();
141
col_device_target.pack_start (cell_device_target, false);
142
col_device_target.set_cell_data_func (cell_device_target, cell_device_target_render);
144
tv_partitions.append_column(col_device_target);
147
col_fs = new TreeViewColumn();
148
col_fs.title = _("Type");
149
CellRendererText cell_fs = new CellRendererText ();
150
cell_fs.xalign = (float) 0.5;
151
col_fs.pack_start (cell_fs, false);
152
col_fs.set_cell_data_func (cell_fs, cell_fs_render);
153
tv_partitions.append_column(col_fs);
156
col_size = new TreeViewColumn();
157
col_size.title = _("Size");
158
CellRendererText cell_size = new CellRendererText ();
159
cell_size.xalign = (float) 1.0;
160
col_size.pack_start (cell_size, false);
161
col_size.set_cell_data_func (cell_size, cell_size_render);
162
tv_partitions.append_column(col_size);
165
col_used = new TreeViewColumn();
166
col_used.title = _("Used");
167
CellRendererText cell_used = new CellRendererText ();
168
cell_used.xalign = (float) 1.0;
169
col_used.pack_start (cell_used, false);
170
col_used.set_cell_data_func (cell_used, cell_used_render);
171
tv_partitions.append_column(col_used);
174
col_label = new TreeViewColumn();
175
col_label.title = _("Label");
176
CellRendererText cell_label = new CellRendererText ();
177
col_label.pack_start (cell_label, false);
178
col_label.set_cell_data_func (cell_label, cell_label_render);
179
tv_partitions.append_column(col_label);
182
col_dist = new TreeViewColumn();
183
col_dist.title = _("System");
184
CellRendererText cell_dist = new CellRendererText ();
185
col_dist.pack_start (cell_dist, false);
186
col_dist.set_cell_data_func (cell_dist, cell_dist_render);
187
tv_partitions.append_column(col_dist);
189
//bootloader options -------------------------------------------
191
//lbl_header_bootloader
192
lbl_header_bootloader = new Gtk.Label("<b>" +_("Bootloader") + ":</b>");
193
lbl_header_bootloader.set_use_markup(true);
194
lbl_header_bootloader.xalign = (float) 0.0;
195
vbox_target.add(lbl_header_bootloader);
198
Box hbox_grub = new Box (Orientation.HORIZONTAL, 6);
199
hbox_grub.margin_right = 6;
200
hbox_grub.margin_bottom = 6;
201
vbox_target.add (hbox_grub);
203
string grub_msg = _("Re-install GRUB2 bootloader on the target device (recommended)");
206
chk_restore_grub2 = new CheckButton.with_label(_("Re-install GRUB2") + ":");
207
chk_restore_grub2.active = true;
208
chk_restore_grub2.set_tooltip_markup(grub_msg);
209
hbox_grub.add(chk_restore_grub2);
211
chk_restore_grub2.toggled.connect(()=>{
212
cmb_boot_device.sensitive = chk_restore_grub2.active;
216
cmb_boot_device = new ComboBox ();
217
cmb_boot_device.hexpand = true;
218
hbox_grub.add(cmb_boot_device);
220
CellRendererText cell_dev_margin = new CellRendererText ();
221
cell_dev_margin.text = "";
222
cmb_boot_device.pack_start (cell_dev_margin, false);
224
CellRendererPixbuf cell_dev_icon = new CellRendererPixbuf ();
225
cell_dev_icon.stock_id = Stock.HARDDISK;
226
cmb_boot_device.pack_start (cell_dev_icon, false);
228
CellRendererText cell_device_grub = new CellRendererText();
229
cmb_boot_device.pack_start(cell_device_grub, false );
230
cmb_boot_device.set_cell_data_func (cell_device_grub, cell_device_grub_render);
232
//Exclude tab ---------------------------------------------
235
lbl_exclude = new Label (_("Advanced"));
238
vbox_exclude = new Box(Gtk.Orientation.VERTICAL, 6);
239
vbox_exclude.margin = 6;
240
notebook.append_page (vbox_exclude, lbl_exclude);
242
//toolbar_exclude ---------------------------------------------------
245
toolbar_exclude = new Gtk.Toolbar ();
246
toolbar_exclude.toolbar_style = ToolbarStyle.BOTH_HORIZ;
247
vbox_exclude.add(toolbar_exclude);
249
string png_exclude = App.share_folder + "/timeshift/images/item-gray.png";
250
string png_include = App.share_folder + "/timeshift/images/item-blue.png";
253
btn_exclude = new Gtk.MenuToolButton(null,"");
254
toolbar_exclude.add(btn_exclude);
256
btn_exclude.is_important = true;
257
btn_exclude.label = _("Exclude");
258
btn_exclude.set_tooltip_text (_("Exclude"));
259
btn_exclude.set_icon_widget(new Gtk.Image.from_file (png_exclude));
262
btn_include = new Gtk.MenuToolButton(null,"");
263
toolbar_exclude.add(btn_include);
265
btn_include.is_important = true;
266
btn_include.label = _("Include");
267
btn_include.set_tooltip_text (_("Include"));
268
btn_include.set_icon_widget(new Gtk.Image.from_file (png_include));
271
btn_remove = new Gtk.ToolButton.from_stock(Gtk.Stock.REMOVE);
272
toolbar_exclude.add(btn_remove);
274
btn_remove.is_important = true;
275
btn_remove.label = _("Remove");
276
btn_remove.set_tooltip_text (_("Remove selected items"));
278
btn_remove.clicked.connect (btn_remove_clicked);
281
btn_warning = new Gtk.ToolButton.from_stock(Gtk.Stock.DIALOG_WARNING);
282
toolbar_exclude.add(btn_warning);
284
btn_warning.is_important = true;
285
btn_warning.label = _("Warning");
286
btn_warning.set_tooltip_text (_("Warning"));
288
btn_warning.clicked.connect (btn_warning_clicked);
291
var separator = new Gtk.SeparatorToolItem();
292
separator.set_draw (false);
293
separator.set_expand (true);
294
toolbar_exclude.add(separator);
296
//btn_reset_exclude_list
297
btn_reset_exclude_list = new Gtk.ToolButton.from_stock(Gtk.Stock.REFRESH);
298
toolbar_exclude.add(btn_reset_exclude_list);
300
btn_reset_exclude_list.is_important = false;
301
btn_reset_exclude_list.label = _("Reset");
302
btn_reset_exclude_list.set_tooltip_text (_("Reset this list to default state"));
304
btn_reset_exclude_list.clicked.connect (btn_reset_exclude_list_clicked);
306
//menu --------------------------------------------------
309
menu_exclude = new Gtk.Menu();
310
btn_exclude.set_menu(menu_exclude);
312
//menu_exclude_add_file
313
menu_exclude_add_file = new ImageMenuItem.with_label ("");
314
menu_exclude_add_file.label = _("Exclude File(s)");
315
menu_exclude_add_file.set_image(new Gtk.Image.from_file (png_exclude));
316
menu_exclude.append(menu_exclude_add_file);
318
menu_exclude_add_file.activate.connect (menu_exclude_add_files_clicked);
320
//menu_exclude_add_folder
321
menu_exclude_add_folder = new ImageMenuItem.with_label ("");
322
menu_exclude_add_folder.label = _("Exclude Directory");
323
menu_exclude_add_folder.set_image(new Gtk.Image.from_file (png_exclude));
324
menu_exclude.append(menu_exclude_add_folder);
326
menu_exclude_add_folder.activate.connect (menu_exclude_add_folder_clicked);
328
//menu_exclude_add_folder_contents
329
menu_exclude_add_folder_contents = new ImageMenuItem.with_label ("");
330
menu_exclude_add_folder_contents.label = _("Exclude Directory Contents");
331
menu_exclude_add_folder_contents.set_image(new Gtk.Image.from_file (png_exclude));
332
menu_exclude.append(menu_exclude_add_folder_contents);
334
menu_exclude_add_folder_contents.activate.connect (menu_exclude_add_folder_contents_clicked);
337
menu_include = new Gtk.Menu();
338
btn_include.set_menu(menu_include);
340
//menu_include_add_file
341
menu_include_add_file = new ImageMenuItem.with_label ("");
342
menu_include_add_file.label = _("Include File(s)");
343
menu_include_add_file.set_image(new Gtk.Image.from_file (png_include));
344
menu_include.append(menu_include_add_file);
346
menu_include_add_file.activate.connect (menu_include_add_files_clicked);
348
//menu_include_add_folder
349
menu_include_add_folder = new ImageMenuItem.with_label ("");
350
menu_include_add_folder.label = _("Include Directory");
351
menu_include_add_folder.set_image(new Gtk.Image.from_file (png_include));
352
menu_include.append(menu_include_add_folder);
354
menu_include_add_folder.activate.connect (menu_include_add_folder_clicked);
356
menu_exclude.show_all();
357
menu_include.show_all();
359
//tv_exclude-----------------------------------------------
362
tv_exclude = new TreeView();
363
tv_exclude.get_selection().mode = SelectionMode.MULTIPLE;
364
tv_exclude.headers_visible = true;
365
tv_exclude.set_rules_hint (true);
366
//tv_exclude.row_activated.connect(tv_exclude_row_activated);
369
sw_exclude = new ScrolledWindow(null, null);
370
sw_exclude.set_shadow_type (ShadowType.ETCHED_IN);
371
sw_exclude.add (tv_exclude);
372
sw_exclude.expand = true;
373
vbox_exclude.add(sw_exclude);
376
col_exclude = new TreeViewColumn();
377
col_exclude.title = _("File Pattern");
378
col_exclude.expand = true;
380
CellRendererText cell_exclude_margin = new CellRendererText ();
381
cell_exclude_margin.text = "";
382
col_exclude.pack_start (cell_exclude_margin, false);
384
CellRendererPixbuf cell_exclude_icon = new CellRendererPixbuf ();
385
col_exclude.pack_start (cell_exclude_icon, false);
386
col_exclude.set_attributes(cell_exclude_icon, "pixbuf", 1);
388
CellRendererText cell_exclude_text = new CellRendererText ();
389
col_exclude.pack_start (cell_exclude_text, false);
390
col_exclude.set_cell_data_func (cell_exclude_text, cell_exclude_text_render);
391
cell_exclude_text.editable = true;
392
tv_exclude.append_column(col_exclude);
394
cell_exclude_text.edited.connect (cell_exclude_text_edited);
397
lnk_default_list = new LinkButton.with_label("",_("Some locations are excluded by default"));
398
lnk_default_list.xalign = (float) 0.0;
399
lnk_default_list.activate_link.connect(lnk_default_list_activate);
400
vbox_exclude.add(lnk_default_list);
402
//Actions ----------------------------------------------
405
hbox_action = (Box) get_action_area ();
408
btn_restore = new Button();
409
hbox_action.add(btn_restore);
411
btn_restore.set_label (" " + _("Restore"));
412
btn_restore.set_tooltip_text (_("Restore"));
413
Gtk.Image img_restore = new Image.from_stock(Gtk.Stock.GO_FORWARD, Gtk.IconSize.BUTTON);
414
btn_restore.set_image(img_restore);
415
btn_restore.clicked.connect (btn_restore_clicked);
418
btn_cancel = new Button();
419
hbox_action.add(btn_cancel);
421
btn_cancel.set_label (" " + _("Cancel"));
422
btn_cancel.set_tooltip_text (_("Cancel"));
423
Gtk.Image img_cancel = new Image.from_stock(Gtk.Stock.CANCEL, Gtk.IconSize.BUTTON);
424
btn_cancel.set_image(img_cancel);
425
btn_cancel.clicked.connect (btn_cancel_clicked);
427
//initialize -----------------------------------------
429
refresh_tv_partitions();
430
refresh_cmb_boot_device();
432
btn_reset_exclude_list_clicked();
434
chk_restore_grub2.active = true; //keep enabled always
435
chk_restore_grub2.sensitive = false; //don't allow user to disable
436
cmb_boot_device.sensitive = chk_restore_grub2.active;
440
private void cell_device_target_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
442
model.get (iter, 0, out pi, -1);
443
if ((App.root_device != null) && (pi.device == App.root_device.device)){
444
(cell as Gtk.CellRendererText).text = pi.device_name_sdaX + " (" + _("sys") + ")";
447
(cell as Gtk.CellRendererText).text = pi.device_name_sdaX;
451
private void cell_fs_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
453
model.get (iter, 0, out pi, -1);
454
(cell as Gtk.CellRendererText).text = pi.type;
457
private void cell_size_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
459
model.get (iter, 0, out pi, -1);
460
(cell as Gtk.CellRendererText).text = pi.size;
463
private void cell_used_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
465
model.get (iter, 0, out pi, -1);
466
(cell as Gtk.CellRendererText).text = pi.used;
469
private void cell_label_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
471
model.get (iter, 0, out pi, -1);
472
(cell as Gtk.CellRendererText).text = pi.label;
475
private void cell_dist_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
477
model.get (iter, 0, out pi, -1);
478
(cell as Gtk.CellRendererText).text = pi.dist_info;
481
private void cell_device_grub_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
483
model.get (iter, 0, out info, -1);
484
(cell as Gtk.CellRendererText).text = info.description;
487
private void cell_exclude_text_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
488
string pattern, color;
489
model.get (iter, 0, out pattern, 2, out color, -1);
490
(cell as Gtk.CellRendererText).text = pattern.has_prefix("+ ") ? pattern[2:pattern.length] : pattern;
491
(cell as Gtk.CellRendererText).foreground = color;
494
private void cell_exclude_text_edited (string path, string new_text) {
498
ListStore model = (ListStore) tv_exclude.model;
499
model.get_iter_from_string (out iter, path);
500
model.get (iter, 0, out entry, -1);
501
model.set (iter, 0, new_text);
505
private void refresh_cmb_boot_device(){
506
ListStore store = new ListStore(1, typeof(DeviceInfo));
511
int selected_index = -1;
512
int default_index = -1;
514
foreach(DeviceInfo di in get_block_devices()) {
515
store.append(out iter);
516
store.set (iter, 0, di);
519
if ((App.restore_target != null) && (di.device == App.restore_target.device[0:-1])){
520
selected_index = index;
524
if (selected_index == -1){
525
selected_index = default_index;
528
cmb_boot_device.set_model (store);
529
cmb_boot_device.active = selected_index;
532
private void refresh_tv_partitions(){
534
App.update_partition_list();
536
ListStore model = new ListStore(1, typeof(PartitionInfo));
538
var list = App.partition_list;
540
PartitionInfo p1 = (PartitionInfo) a;
541
PartitionInfo p2 = (PartitionInfo) b;
543
return strcmp(p1.device,p2.device);
547
TreePath path_selected = null;
549
foreach(PartitionInfo pi in list) {
550
if (!pi.has_linux_filesystem()) { continue; }
552
model.append(out iter);
553
model.set (iter, 0, pi);
555
if ((App.restore_target != null) && (App.restore_target.device == pi.device)){
556
path_selected = model.get_path(iter);
560
tv_partitions.set_model (model);
561
if (path_selected != null){
562
tv_partitions.get_selection().select_path(path_selected);
564
//tv_partitions.columns_autosize ();
567
private void refresh_tv_exclude(){
568
ListStore model = new ListStore(3, typeof(string), typeof(Gdk.Pixbuf), typeof(string));
569
tv_exclude.model = model;
571
foreach(string path in temp_exclude_list){
572
tv_exclude_add_item(path);
576
private void tv_exclude_add_item(string path){
577
Gdk.Pixbuf pix_exclude = null;
578
Gdk.Pixbuf pix_include = null;
579
Gdk.Pixbuf pix_selected = null;
583
pix_exclude = new Gdk.Pixbuf.from_file (App.share_folder + "/timeshift/images/item-gray.png");
584
pix_include = new Gdk.Pixbuf.from_file (App.share_folder + "/timeshift/images/item-blue.png");
587
log_error (e.message);
591
ListStore model = (ListStore) tv_exclude.model;
592
model.append(out iter);
594
if (path.has_prefix("+ ")){
595
pix_selected = pix_include;
598
pix_selected = pix_exclude;
601
if (App.exclude_list_default.contains(path)){
602
text_color = "#0B610B";
605
text_color = "#000000";
608
model.set (iter, 0, path, 1, pix_selected, 2, text_color, -1);
610
Adjustment adj = tv_exclude.get_hadjustment();
611
adj.value = adj.upper;
614
private bool lnk_default_list_activate(){
616
msg += "<b>" + _("Exclude List") + ":</b>\n\n";
617
msg += _("Files matching the following patterns will be <i>excluded</i>") + ":\n\n";
619
foreach(string path in App.exclude_list_default){
624
msg += "<b>" + _("Home Directory") + ":</b>\n\n";
625
msg += _("Hidden files and folders are included by default since \nthey contain user-specific configuration files.") + "\n";
626
msg += _("All other files and folders are excluded.") + "\n";
628
var dialog = new Gtk.MessageDialog.with_markup(null, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, msg);
629
dialog.set_title(_("Default Entries"));
630
dialog.set_default_size (200, -1);
631
dialog.set_transient_for(this);
632
dialog.set_modal(true);
639
private bool tv_partitions_button_press_event(Gdk.EventButton event){
645
//get selected target device
646
PartitionInfo restore_target = null;
647
sel = tv_partitions.get_selection ();
648
store = (ListStore) tv_partitions.model;
649
iterExists = store.get_iter_first (out iter);
651
if (sel.iter_is_selected (iter)){
652
store.get (iter, 0, out restore_target);
655
iterExists = store.iter_next (ref iter);
657
App.restore_target = restore_target;
659
//select grub target device
660
refresh_cmb_boot_device();
666
private void menu_exclude_add_files_clicked(){
668
var list = browse_files();
670
if (list.length() > 0){
671
foreach(string path in list){
672
if (!temp_exclude_list.contains(path)){
673
temp_exclude_list.add(path);
674
tv_exclude_add_item(path);
675
App.first_snapshot_size = 0; //re-calculate
681
private void menu_exclude_add_folder_clicked(){
683
var list = browse_folder();
685
if (list.length() > 0){
686
foreach(string path in list){
690
if (!temp_exclude_list.contains(path)){
691
temp_exclude_list.add(path);
692
tv_exclude_add_item(path);
693
App.first_snapshot_size = 0; //re-calculate
699
private void menu_exclude_add_folder_contents_clicked(){
701
var list = browse_folder();
703
if (list.length() > 0){
704
foreach(string path in list){
708
if (!temp_exclude_list.contains(path)){
709
temp_exclude_list.add(path);
710
tv_exclude_add_item(path);
711
App.first_snapshot_size = 0; //re-calculate
717
private void menu_include_add_files_clicked(){
719
var list = browse_files();
721
if (list.length() > 0){
722
foreach(string path in list){
724
path = path.has_prefix("+ ") ? path : "+ " + path;
726
if (!temp_exclude_list.contains(path)){
727
temp_exclude_list.add(path);
728
tv_exclude_add_item(path);
729
App.first_snapshot_size = 0; //re-calculate
735
private void menu_include_add_folder_clicked(){
737
var list = browse_folder();
739
if (list.length() > 0){
740
foreach(string path in list){
742
path = path.has_prefix("+ ") ? path : "+ " + path;
743
path = path + "/***";
745
if (!temp_exclude_list.contains(path)){
746
temp_exclude_list.add(path);
747
tv_exclude_add_item(path);
748
App.first_snapshot_size = 0; //re-calculate
754
private SList<string> browse_files(){
755
var dialog = new Gtk.FileChooserDialog(_("Select file(s)"), this, Gtk.FileChooserAction.OPEN,
756
Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL,
757
Gtk.Stock.OPEN, Gtk.ResponseType.ACCEPT);
758
dialog.action = FileChooserAction.OPEN;
759
dialog.set_transient_for(this);
760
dialog.local_only = true;
761
dialog.set_modal (true);
762
dialog.set_select_multiple (true);
765
var list = dialog.get_filenames();
771
private SList<string> browse_folder(){
772
var dialog = new Gtk.FileChooserDialog(_("Select directory"), this, Gtk.FileChooserAction.OPEN,
773
Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL,
774
Gtk.Stock.OPEN, Gtk.ResponseType.ACCEPT);
775
dialog.action = FileChooserAction.SELECT_FOLDER;
776
dialog.local_only = true;
777
dialog.set_transient_for(this);
778
dialog.set_modal (true);
779
dialog.set_select_multiple (false);
782
var list = dialog.get_filenames();
789
private void btn_remove_clicked(){
790
TreeSelection sel = tv_exclude.get_selection ();
792
bool iterExists = tv_exclude.model.get_iter_first (out iter);
794
if (sel.iter_is_selected (iter)){
796
tv_exclude.model.get (iter, 0, out path);
797
temp_exclude_list.remove(path);
798
App.first_snapshot_size = 0; //re-calculate
800
iterExists = tv_exclude.model.iter_next (ref iter);
803
refresh_tv_exclude();
806
private void btn_warning_clicked(){
808
msg += _("Please do NOT modify this list unless you have a very good reason for doing so.") + " ";
809
msg += _("By default, any item that was included/excluded at the time of taking the snapshot will be included/excluded.") + " ";
810
msg += _("Any exclude patterns in the current exclude list will also be excluded.") + " ";
811
msg += _("To see which files are included in the snapshot use the 'Browse' button on the main window.");
813
var dialog = new Gtk.MessageDialog.with_markup(null, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, msg);
814
dialog.set_title("Warning");
815
dialog.set_default_size (200, -1);
816
dialog.set_transient_for(this);
817
dialog.set_modal(true);
822
private void btn_reset_exclude_list_clicked(){
823
//create a temp exclude list ----------------------------
825
temp_exclude_list = new Gee.ArrayList<string>();
827
//add all include/exclude items from snapshot list
828
foreach(string path in App.snapshot_to_restore.exclude_list){
829
if (!temp_exclude_list.contains(path) && !App.exclude_list_default.contains(path) && !App.exclude_list_home.contains(path)){
830
temp_exclude_list.add(path);
834
//add all exclude items from current list
835
foreach(string path in App.exclude_list_user){
836
if (!temp_exclude_list.contains(path) && !App.exclude_list_default.contains(path) && !App.exclude_list_home.contains(path)){
838
if (!path.has_prefix("+ ")){ //don't add include entries from current exclude list
839
temp_exclude_list.add(path);
844
//refresh treeview --------------------------
846
refresh_tv_exclude();
850
private void btn_restore_clicked(){
852
//Note: A successful restore will reboot the system if target device is same as system device
859
//check single target partition selected ---------------
861
sel = tv_partitions.get_selection ();
862
if (sel.count_selected_rows() != 1){
863
messagebox_show(_("Select Target Device"),_("Please select the target device from the list"), true);
867
//get selected target partition ------------------
869
PartitionInfo restore_target = null;
870
sel = tv_partitions.get_selection ();
871
store = (ListStore) tv_partitions.model;
872
iterExists = store.get_iter_first (out iter);
874
if (sel.iter_is_selected (iter)){
875
store.get (iter, 0, out restore_target);
878
iterExists = store.iter_next (ref iter);
880
App.restore_target = restore_target;
882
//save modified exclude list ----------------------
884
App.exclude_list_restore.clear();
886
//add default entries
887
foreach(string path in App.exclude_list_default){
888
if (!App.exclude_list_restore.contains(path)){
889
App.exclude_list_restore.add(path);
893
//add modified user entries
894
foreach(string path in temp_exclude_list){
895
if (!App.exclude_list_restore.contains(path) && !App.exclude_list_home.contains(path)){
896
App.exclude_list_restore.add(path);
901
foreach(string path in App.exclude_list_home){
902
if (!App.exclude_list_restore.contains(path)){
903
App.exclude_list_restore.add(path);
907
string timeshift_path = "/timeshift/*";
908
if (!App.exclude_list_restore.contains(timeshift_path)){
909
App.exclude_list_restore.add(timeshift_path);
912
//save grub install options ----------------------
914
App.reinstall_grub2 = chk_restore_grub2.active;
916
if (App.reinstall_grub2){
918
cmb_boot_device.get_active_iter (out iter);
919
TreeModel model = (TreeModel) cmb_boot_device.model;
920
model.get(iter, 0, out dev);
921
App.grub_device = dev;
924
//last option to quit - show disclaimer ------------
926
if (show_disclaimer() == Gtk.ResponseType.YES){
927
this.response(Gtk.ResponseType.OK);
930
this.response(Gtk.ResponseType.CANCEL);
934
private int show_disclaimer(){
936
msg += "<b>" + _("WARNING") + ":</b>\n\n";
937
msg += _("Files will be overwritten on the target device!") + "\n";
938
msg += _("If the restore fails for any reason and you are unable to boot the system, \nplease boot from the Ubuntu Live CD and try again.") + "\n";
940
if ((App.root_device != null) && (App.restore_target.device == App.root_device.device)){
941
msg += "\n<b>" + _("Please save your work and close all applications.") + "\n";
942
msg += _("System will reboot to complete the restore process.") + "</b>\n";
946
msg += "<b>" + _("DISCLAIMER") + ":</b>\n\n";
947
msg += _("This software comes without absolutely NO warranty and the author takes no responsibility for any damage arising from the use of this program.");
948
msg += " " + _("If these terms are not acceptable to you, please do not proceed beyond this point!") + "\n";
950
msg += "<b>" + _("Continue with restore?") + "</b>\n";
952
var dialog = new Gtk.MessageDialog.with_markup(null, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, msg);
953
dialog.set_title(_("DISCLAIMER"));
954
dialog.set_default_size (200, -1);
955
dialog.set_transient_for(this);
956
dialog.set_modal(true);
957
int response = dialog.run();
962
private void btn_cancel_clicked(){
963
this.response(Gtk.ResponseType.CANCEL);