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
using TeeJee.FileSystem;
30
using TeeJee.JsonHelper;
31
using TeeJee.ProcessHelper;
32
using TeeJee.GtkHelper;
36
public class SettingsWindow : Gtk.Dialog{
37
private Box vbox_main;
38
private Notebook notebook;
41
private Label lbl_schedule;
42
private Box vbox_schedule;
43
private CheckButton chk_schedule;
44
private TreeView tv_schedule;
45
private ScrolledWindow sw_schedule;
46
private TreeViewColumn col_sched_enable;
47
private TreeViewColumn col_sched_level;
48
private TreeViewColumn col_sched_desc;
51
private Label lbl_auto_remove;
52
private Box vbox_auto_remove;
53
private TreeView tv_remove;
54
private ScrolledWindow sw_remove;
55
private TreeViewColumn col_remove_rule;
56
private TreeViewColumn col_remove_limit;
57
private TreeViewColumn col_remove_units;
60
private Label lbl_exclude;
61
private Box vbox_exclude;
62
private LinkButton lnk_default_list;
63
private TreeView tv_exclude;
64
private ScrolledWindow sw_exclude;
65
private TreeViewColumn col_exclude;
66
private Toolbar toolbar_exclude;
67
private ToolButton btn_remove;
68
private ToolButton btn_warning;
69
private ToolButton btn_reset_exclude_list;
71
private MenuToolButton btn_exclude;
72
private Gtk.Menu menu_exclude;
73
private ImageMenuItem menu_exclude_add_file;
74
private ImageMenuItem menu_exclude_add_folder;
75
private ImageMenuItem menu_exclude_add_folder_contents;
77
private MenuToolButton btn_include;
78
private Gtk.Menu menu_include;
79
private ImageMenuItem menu_include_add_file;
80
private ImageMenuItem menu_include_add_folder;
83
private Button btn_save;
84
private Button btn_cancel;
86
private Gee.ArrayList<string> temp_exclude_list;
88
public SettingsWindow () {
89
this.deletable = false;
90
this.title = _("Settings");
91
this.window_position = WindowPosition.CENTER_ON_PARENT;
92
this.set_destroy_with_parent (true);
93
this.set_modal (true);
94
this.set_default_size (450, 450);
95
this.icon = get_app_icon(16);
98
vbox_main = get_content_area ();
101
notebook = new Notebook ();
102
notebook.margin = 12;
103
vbox_main.pack_start (notebook, true, true, 0);
105
//schedule tab ---------------------------------------------
108
lbl_schedule = new Label (_("Schedule"));
111
vbox_schedule = new Box (Gtk.Orientation.VERTICAL, 6);
112
vbox_schedule.margin = 6;
113
notebook.append_page (vbox_schedule, lbl_schedule);
115
//automatic snapshots ------------------------------
118
chk_schedule = new Gtk.CheckButton.with_label(_("Create scheduled/automatic snapshots"));
119
chk_schedule.active = App.is_scheduled;
120
vbox_schedule.pack_start(chk_schedule,false,false,0);
122
chk_schedule.notify["active"].connect(chk_schedule_changed);
124
//tv_schedule -----------------------------------------------
127
tv_schedule = new TreeView();
128
tv_schedule.get_selection().mode = SelectionMode.MULTIPLE;
129
tv_schedule.set_rules_hint (true);
132
sw_schedule = new ScrolledWindow(null, null);
133
sw_schedule.set_shadow_type (ShadowType.ETCHED_IN);
134
sw_schedule.add (tv_schedule);
135
sw_schedule.expand = true;
136
vbox_schedule.add(sw_schedule);
139
col_sched_enable = new TreeViewColumn();
140
col_sched_enable.title = " " + _("Enable") + " ";
141
CellRendererToggle cell_sched_enable = new CellRendererToggle ();
142
cell_sched_enable.activatable = true;
143
cell_sched_enable.toggled.connect (cell_sched_enable_toggled);
144
col_sched_enable.pack_start (cell_sched_enable, false);
145
col_sched_enable.set_cell_data_func (cell_sched_enable, cell_sched_enable_render);
146
tv_schedule.append_column(col_sched_enable);
149
col_sched_level = new TreeViewColumn();
150
col_sched_level.title = " " + _("Backup Level") + " ";
151
CellRendererText cell_sched_level = new CellRendererText ();
152
col_sched_level.pack_start (cell_sched_level, false);
153
col_sched_level.set_cell_data_func (cell_sched_level, cell_sched_level_render);
154
tv_schedule.append_column(col_sched_level);
157
col_sched_desc = new TreeViewColumn();
158
col_sched_desc.title = " " + _("Description") + " ";
159
col_sched_desc.expand = true;
160
CellRendererText cell_sched_desc = new CellRendererText ();
161
col_sched_desc.pack_start (cell_sched_desc, false);
162
col_sched_desc.set_cell_data_func (cell_sched_desc, cell_sched_desc_render);
163
tv_schedule.append_column(col_sched_desc);
165
//auto-remove tab ------------------------------------------------------
168
lbl_auto_remove = new Label (_("Auto-Remove"));
171
vbox_auto_remove = new Box(Gtk.Orientation.VERTICAL, 6);
172
vbox_auto_remove.margin = 6;
173
notebook.append_page (vbox_auto_remove, lbl_auto_remove);
175
//lbl_auto_remove_msg
176
Label lbl_auto_remove_msg = new Label (_("Snapshots matching following rules will be removed automatically"));
177
lbl_auto_remove_msg.xalign = (float) 0.0;
178
vbox_auto_remove.add(lbl_auto_remove_msg);
181
tv_remove = new TreeView();
182
tv_remove.get_selection().mode = SelectionMode.MULTIPLE;
183
tv_remove.set_rules_hint (true);
186
sw_remove = new ScrolledWindow(null, null);
187
sw_remove.set_shadow_type (ShadowType.ETCHED_IN);
188
sw_remove.add (tv_remove);
189
sw_remove.expand = true;
190
vbox_auto_remove.add(sw_remove);
193
col_remove_rule = new TreeViewColumn();
194
col_remove_rule.title = " " + _("Rule") + " ";
195
CellRendererText cell_remove_rule = new CellRendererText ();
196
col_remove_rule.pack_start (cell_remove_rule, false);
197
col_remove_rule.set_cell_data_func (cell_remove_rule, cell_remove_rule_render);
198
tv_remove.append_column(col_remove_rule);
201
col_remove_limit = new TreeViewColumn();
202
col_remove_limit.title = " " + _("Limit") + " ";
203
CellRendererText cell_remove_limit = new CellRendererText ();
204
cell_remove_limit.xalign = (float) 0.5;
205
cell_remove_limit.editable = true;
206
cell_remove_limit.edited.connect (cell_remove_limit_edited);
207
col_remove_limit.pack_start (cell_remove_limit, false);
208
col_remove_limit.set_cell_data_func (cell_remove_limit, cell_remove_limit_render);
209
tv_remove.append_column(col_remove_limit);
212
col_remove_units = new TreeViewColumn();
213
col_remove_units.title = "";
214
CellRendererText cell_remove_units = new CellRendererText ();
215
col_remove_units.pack_start (cell_remove_units, false);
216
col_remove_units.set_cell_data_func (cell_remove_units, cell_remove_units_render);
217
tv_remove.append_column(col_remove_units);
219
tv_schedule.sensitive = chk_schedule.active;
221
//Exclude tab ---------------------------------------------
224
lbl_exclude = new Label (_("Advanced"));
227
vbox_exclude = new Box(Gtk.Orientation.VERTICAL, 6);
228
vbox_exclude.margin = 6;
229
notebook.append_page (vbox_exclude, lbl_exclude);
231
//toolbar_exclude ---------------------------------------------------
234
toolbar_exclude = new Gtk.Toolbar ();
235
toolbar_exclude.toolbar_style = ToolbarStyle.BOTH_HORIZ;
236
//toolbar_exclude.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR);
237
//toolbar.set_size_request(-1,48);
238
vbox_exclude.add(toolbar_exclude);
240
string png_exclude = App.share_folder + "/timeshift/images/item-gray.png";
241
string png_include = App.share_folder + "/timeshift/images/item-blue.png";
244
btn_exclude = new Gtk.MenuToolButton(null,"");
245
toolbar_exclude.add(btn_exclude);
247
btn_exclude.is_important = true;
248
btn_exclude.label = _("Exclude");
249
btn_exclude.set_tooltip_text (_("Exclude"));
250
btn_exclude.set_icon_widget(new Gtk.Image.from_file (png_exclude));
253
btn_include = new Gtk.MenuToolButton(null,"");
254
toolbar_exclude.add(btn_include);
256
btn_include.is_important = true;
257
btn_include.label = _("Include");
258
btn_include.set_tooltip_text (_("Include"));
259
btn_include.set_icon_widget(new Gtk.Image.from_file (png_include));
262
btn_remove = new Gtk.ToolButton.from_stock("gtk-remove");
263
toolbar_exclude.add(btn_remove);
265
btn_remove.is_important = true;
266
btn_remove.label = _("Remove");
267
btn_remove.set_tooltip_text (_("Remove selected items"));
269
btn_remove.clicked.connect (btn_remove_clicked);
272
btn_warning = new Gtk.ToolButton.from_stock("gtk-dialog-warning");
273
toolbar_exclude.add(btn_warning);
275
btn_warning.is_important = true;
276
btn_warning.label = _("Warning");
277
btn_warning.set_tooltip_text (_("Warning"));
279
btn_warning.clicked.connect (btn_warning_clicked);
282
var separator = new Gtk.SeparatorToolItem();
283
separator.set_draw (false);
284
separator.set_expand (true);
285
toolbar_exclude.add(separator);
287
//btn_reset_exclude_list
288
btn_reset_exclude_list = new Gtk.ToolButton.from_stock("gtk-refresh");
289
toolbar_exclude.add(btn_reset_exclude_list);
291
btn_reset_exclude_list.is_important = false;
292
btn_reset_exclude_list.label = _("Reset");
293
btn_reset_exclude_list.set_tooltip_text (_("Clear the list"));
295
btn_reset_exclude_list.clicked.connect (btn_reset_exclude_list_clicked);
298
menu_exclude = new Gtk.Menu();
299
btn_exclude.set_menu(menu_exclude);
301
//menu_exclude_add_file
302
menu_exclude_add_file = new ImageMenuItem.with_label ("");
303
menu_exclude_add_file.label = _("Exclude File(s)");
304
menu_exclude_add_file.set_image(new Gtk.Image.from_file (png_exclude));
305
menu_exclude.append(menu_exclude_add_file);
307
menu_exclude_add_file.activate.connect (menu_exclude_add_files_clicked);
309
//menu_exclude_add_folder
310
menu_exclude_add_folder = new ImageMenuItem.with_label ("");
311
menu_exclude_add_folder.label = _("Exclude Directory");
312
menu_exclude_add_folder.set_image(new Gtk.Image.from_file (png_exclude));
313
menu_exclude.append(menu_exclude_add_folder);
315
menu_exclude_add_folder.activate.connect (menu_exclude_add_folder_clicked);
317
//menu_exclude_add_folder_contents
318
menu_exclude_add_folder_contents = new ImageMenuItem.with_label ("");
319
menu_exclude_add_folder_contents.label = _("Exclude Directory Contents");
320
menu_exclude_add_folder_contents.set_image(new Gtk.Image.from_file (png_exclude));
321
menu_exclude.append(menu_exclude_add_folder_contents);
323
menu_exclude_add_folder_contents.activate.connect (menu_exclude_add_folder_contents_clicked);
326
menu_include = new Gtk.Menu();
327
btn_include.set_menu(menu_include);
329
//menu_include_add_file
330
menu_include_add_file = new ImageMenuItem.with_label ("");
331
menu_include_add_file.label = _("Include File(s)");
332
menu_include_add_file.set_image(new Gtk.Image.from_file (png_include));
333
menu_include.append(menu_include_add_file);
335
menu_include_add_file.activate.connect (menu_include_add_files_clicked);
337
//menu_include_add_folder
338
menu_include_add_folder = new ImageMenuItem.with_label ("");
339
menu_include_add_folder.label = _("Include Directory");
340
menu_include_add_folder.set_image(new Gtk.Image.from_file (png_include));
341
menu_include.append(menu_include_add_folder);
343
menu_include_add_folder.activate.connect (menu_include_add_folder_clicked);
345
menu_exclude.show_all();
346
menu_include.show_all();
348
//tv_exclude-----------------------------------------------
351
tv_exclude = new TreeView();
352
tv_exclude.get_selection().mode = SelectionMode.MULTIPLE;
353
tv_exclude.headers_visible = true;
354
tv_exclude.set_rules_hint (true);
355
//tv_exclude.row_activated.connect(tv_exclude_row_activated);
358
sw_exclude = new ScrolledWindow(null, null);
359
sw_exclude.set_shadow_type (ShadowType.ETCHED_IN);
360
sw_exclude.add (tv_exclude);
361
sw_exclude.expand = true;
362
vbox_exclude.add(sw_exclude);
365
col_exclude = new TreeViewColumn();
366
col_exclude.title = _("File Pattern");
367
col_exclude.expand = true;
369
CellRendererText cell_exclude_margin = new CellRendererText ();
370
cell_exclude_margin.text = "";
371
col_exclude.pack_start (cell_exclude_margin, false);
373
CellRendererPixbuf cell_exclude_icon = new CellRendererPixbuf ();
374
col_exclude.pack_start (cell_exclude_icon, false);
375
col_exclude.set_attributes(cell_exclude_icon, "pixbuf", 1);
377
CellRendererText cell_exclude_text = new CellRendererText ();
378
col_exclude.pack_start (cell_exclude_text, false);
379
col_exclude.set_cell_data_func (cell_exclude_text, cell_exclude_text_render);
380
cell_exclude_text.editable = true;
381
tv_exclude.append_column(col_exclude);
383
cell_exclude_text.edited.connect (cell_exclude_text_edited);
386
lnk_default_list = new LinkButton.with_label("",_("Some locations are excluded by default"));
387
lnk_default_list.xalign = (float) 0.0;
388
lnk_default_list.activate_link.connect(lnk_default_list_activate);
389
vbox_exclude.add(lnk_default_list);
391
//initialize ------------------
393
temp_exclude_list = new Gee.ArrayList<string>();
395
foreach(string path in App.exclude_list_user){
396
if (!temp_exclude_list.contains(path)){
397
temp_exclude_list.add(path);
401
refresh_tv_exclude();
402
refresh_tv_schedule();
405
// Actions ----------------------------------------------
407
var vbox_action = get_action_area();
408
vbox_action.margin = 12;
409
vbox_action.margin_top = 0;
412
btn_save = (Button) add_button ("gtk-save", Gtk.ResponseType.ACCEPT);
413
btn_save.clicked.connect (btn_save_clicked);
416
btn_cancel = (Button) add_button ("gtk-cancel", Gtk.ResponseType.CANCEL);
417
btn_cancel.clicked.connect (btn_cancel_clicked);
421
private void cell_sched_enable_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
423
model.get (iter, 0, out val, -1);
424
(cell as Gtk.CellRendererToggle).active = val;
427
private void cell_sched_level_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
429
model.get (iter, 1, out val, -1);
430
(cell as Gtk.CellRendererText).text = val;
433
private void cell_sched_desc_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
435
model.get (iter, 2, out val, -1);
436
(cell as Gtk.CellRendererText).text = val;
439
private void cell_remove_rule_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
441
model.get (iter, 0, out val, -1);
442
(cell as Gtk.CellRendererText).markup = val;
445
private void cell_remove_limit_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
448
model.get (iter, 1, out val, 2, out units, -1);
449
(cell as Gtk.CellRendererText).text = (units == "GB") ? "%.0f".printf(val/1024.0) : val.to_string();
450
(cell as Gtk.CellRendererText).background = "#F2F5A9";
453
private void cell_remove_units_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
455
model.get (iter, 2, out val, -1);
456
(cell as Gtk.CellRendererText).text = val;
459
private void cell_sched_enable_toggled (string path){
461
var model = (Gtk.ListStore)tv_schedule.model;
465
model.get_iter_from_string (out iter, path);
466
model.get (iter, 0, out enabled, 2, out count,-1);
467
model.set (iter, 0, !enabled);
469
//update switch_auto_backups
470
bool atleast_one_enabled = false;
471
for(int k = 0; k<5; k++){
472
model.get_iter_from_string (out iter, k.to_string());
473
model.get (iter, 0, out enabled, -1);
475
atleast_one_enabled = true;
480
chk_schedule.active = atleast_one_enabled;
483
private void cell_remove_limit_edited (string path, string new_text) {
488
var model = (Gtk.ListStore)tv_remove.model;
489
model.get_iter_from_string (out iter, path);
490
model.get (iter, 2, out units,-1);
491
count = int.parse(new_text);
493
count = count * 1024;
495
model.set (iter, 1, count);
498
private void cell_exclude_text_render (CellLayout cell_layout, CellRenderer cell, TreeModel model, TreeIter iter){
500
model.get (iter, 0, out pattern, -1);
501
(cell as Gtk.CellRendererText).text = pattern.has_prefix("+ ") ? pattern[2:pattern.length] : pattern;
504
private void cell_exclude_text_edited (string path, string new_text) {
509
var model = (Gtk.ListStore) tv_exclude.model;
510
model.get_iter_from_string (out iter, path);
511
model.get (iter, 0, out old_pattern, -1);
513
if (old_pattern.has_prefix("+ ")){
514
new_pattern = "+ " + new_text;
517
new_pattern = new_text;
519
model.set (iter, 0, new_pattern);
521
int index = temp_exclude_list.index_of(old_pattern);
522
temp_exclude_list.insert(index, new_pattern);
523
temp_exclude_list.remove(old_pattern);
526
private void refresh_tv_schedule(){
528
var model = new Gtk.ListStore(3, typeof(bool), typeof(string), typeof(string));
531
model.append(out iter);
532
model.set (iter, 0, App.schedule_monthly);
533
model.set (iter, 1, _("Monthly"));
534
model.set (iter, 2, _("Create one snapshot every month"));
536
model.append(out iter);
537
model.set (iter, 0, App.schedule_weekly);
538
model.set (iter, 1, _("Weekly"));
539
model.set (iter, 2, _("Create one snapshot every week"));
541
model.append(out iter);
542
model.set (iter, 0, App.schedule_daily);
543
model.set (iter, 1, _("Daily"));
544
model.set (iter, 2, _("Create one snapshot every day"));
546
model.append(out iter);
547
model.set (iter, 0, App.schedule_hourly);
548
model.set (iter, 1, _("Hourly"));
549
model.set (iter, 2, _("Create one snapshot every hour"));
551
model.append(out iter);
552
model.set (iter, 0, App.schedule_boot);
553
model.set (iter, 1, _("Boot"));
554
model.set (iter, 2, _("Create one snapshot every boot"));
556
tv_schedule.set_model (model);
557
tv_schedule.columns_autosize ();
560
private void refresh_tv_remove(){
562
var model = new Gtk.ListStore(3, typeof(string), typeof(int), typeof(string));
564
string span = "<span foreground=\"#2E2E2E\">";
565
if (chk_schedule.active){
566
span = "<span foreground=\"blue\">";
573
model.append(out iter);
574
model.set (iter, 0, span + _("Monthly") + "</span> " + _("snapshots older than"));
575
model.set (iter, 1, App.count_monthly);
576
model.set (iter, 2, "months");
578
model.append(out iter);
579
model.set (iter, 0, span + _("Weekly") + "</span> " + _("snapshots older than"));
580
model.set (iter, 1, App.count_weekly);
581
model.set (iter, 2, "weeks");
583
model.append(out iter);
584
model.set (iter, 0, span + _("Daily") + "</span> " + _("snapshots older than"));
585
model.set (iter, 1, App.count_daily);
586
model.set (iter, 2, "days");
588
model.append(out iter);
589
model.set (iter, 0, span + _("Hourly") + "</span> " + _("snapshots older than"));
590
model.set (iter, 1, App.count_hourly);
591
model.set (iter, 2, "hours");
593
model.append(out iter);
594
model.set (iter, 0, span + _("Boot") + "</span> " + _("snapshots older than"));
595
model.set (iter, 1, App.count_boot);
596
model.set (iter, 2, "reboots");
598
model.append(out iter);
599
model.set (iter, 0, _("All snapshots older than"));
600
model.set (iter, 1, App.retain_snapshots_max_days);
601
model.set (iter, 2, "days");
603
model.append(out iter);
604
model.set (iter, 0, _("When free space less than"));
605
model.set (iter, 1, ((int) (App.minimum_free_disk_space / GB)));
606
model.set (iter, 2, "GB");
608
tv_remove.set_model (model);
609
//tv_remove.columns_autosize ();
612
private void refresh_tv_exclude(){
613
var model = new Gtk.ListStore(2, typeof(string), typeof(Gdk.Pixbuf));
614
tv_exclude.model = model;
616
foreach(string path in temp_exclude_list){
617
tv_exclude_add_item(path);
621
private void tv_exclude_add_item(string path){
622
Gdk.Pixbuf pix_exclude = null;
623
Gdk.Pixbuf pix_include = null;
624
Gdk.Pixbuf pix_selected = null;
627
pix_exclude = new Gdk.Pixbuf.from_file (App.share_folder + "/timeshift/images/item-gray.png");
628
pix_include = new Gdk.Pixbuf.from_file (App.share_folder + "/timeshift/images/item-blue.png");
631
log_error (e.message);
635
var model = (Gtk.ListStore) tv_exclude.model;
636
model.append(out iter);
638
if (path.has_prefix("+ ")){
639
pix_selected = pix_include;
642
pix_selected = pix_exclude;
645
model.set (iter, 0, path, 1, pix_selected, -1);
647
Adjustment adj = tv_exclude.get_hadjustment();
648
adj.value = adj.upper;
652
private void chk_schedule_changed(){
653
tv_schedule.sensitive = chk_schedule.active;
655
if (chk_schedule.active){
657
bool atleast_one_enabled = App.schedule_boot
658
|| App.schedule_hourly
659
|| App.schedule_daily
660
|| App.schedule_weekly
661
|| App.schedule_monthly;
663
if(!atleast_one_enabled){
665
var store = (Gtk.ListStore) tv_schedule.model;
669
bool iterExists = store.get_iter_first (out iter);
671
store.get (iter, 0, out enabled,-1);
674
store.set (iter, 0, true);
677
iterExists = store.iter_next (ref iter);
682
tv_schedule.get_selection().unselect_all();
683
tv_remove.get_selection().unselect_all();
686
refresh_tv_remove(); //refresh the item colors
689
private bool lnk_default_list_activate(){
690
//show message window -----------------
691
var dialog = new ExcludeMessageWindow();
692
dialog.set_transient_for (this);
700
private void menu_exclude_add_files_clicked(){
702
var list = browse_files();
704
if (list.length() > 0){
705
foreach(string path in list){
706
if (!temp_exclude_list.contains(path)){
707
temp_exclude_list.add(path);
708
tv_exclude_add_item(path);
709
App.first_snapshot_size = 0; //re-calculate
715
private void menu_exclude_add_folder_clicked(){
717
var list = browse_folder();
719
if (list.length() > 0){
720
foreach(string path in list){
724
if (!temp_exclude_list.contains(path)){
725
temp_exclude_list.add(path);
726
tv_exclude_add_item(path);
727
App.first_snapshot_size = 0; //re-calculate
733
private void menu_exclude_add_folder_contents_clicked(){
735
var list = browse_folder();
737
if (list.length() > 0){
738
foreach(string path in list){
742
if (!temp_exclude_list.contains(path)){
743
temp_exclude_list.add(path);
744
tv_exclude_add_item(path);
745
App.first_snapshot_size = 0; //re-calculate
751
private void menu_include_add_files_clicked(){
753
var list = browse_files();
755
if (list.length() > 0){
756
foreach(string path in list){
758
path = path.has_prefix("+ ") ? path : "+ " + path;
760
if (!temp_exclude_list.contains(path)){
761
temp_exclude_list.add(path);
762
tv_exclude_add_item(path);
763
App.first_snapshot_size = 0; //re-calculate
769
private void menu_include_add_folder_clicked(){
771
var list = browse_folder();
773
if (list.length() > 0){
774
foreach(string path in list){
776
path = path.has_prefix("+ ") ? path : "+ " + path;
777
path = path + "/***";
779
if (!temp_exclude_list.contains(path)){
780
temp_exclude_list.add(path);
781
tv_exclude_add_item(path);
782
App.first_snapshot_size = 0; //re-calculate
788
private SList<string> browse_files(){
789
var dialog = new Gtk.FileChooserDialog(_("Select file(s)"), this, Gtk.FileChooserAction.OPEN,
790
"gtk-cancel", Gtk.ResponseType.CANCEL,
791
"gtk-open", Gtk.ResponseType.ACCEPT);
792
dialog.action = FileChooserAction.OPEN;
793
dialog.set_transient_for(this);
794
dialog.local_only = true;
795
dialog.set_modal (true);
796
dialog.set_select_multiple (true);
799
var list = dialog.get_filenames();
805
private SList<string> browse_folder(){
806
var dialog = new Gtk.FileChooserDialog(_("Select directory"), this, Gtk.FileChooserAction.OPEN,
807
"gtk-cancel", Gtk.ResponseType.CANCEL,
808
"gtk-open", Gtk.ResponseType.ACCEPT);
809
dialog.action = FileChooserAction.SELECT_FOLDER;
810
dialog.local_only = true;
811
dialog.set_transient_for(this);
812
dialog.set_modal (true);
813
dialog.set_select_multiple (false);
816
var list = dialog.get_filenames();
823
private void btn_remove_clicked(){
824
TreeSelection sel = tv_exclude.get_selection ();
826
bool iterExists = tv_exclude.model.get_iter_first (out iter);
828
if (sel.iter_is_selected (iter)){
830
tv_exclude.model.get (iter, 0, out path);
831
temp_exclude_list.remove(path);
832
App.first_snapshot_size = 0; //re-calculate
834
iterExists = tv_exclude.model.iter_next (ref iter);
837
refresh_tv_exclude();
840
private void btn_warning_clicked(){
842
msg += _("Documents, music and other folders in your home directory are excluded by default.") + " ";
843
msg += _("Please do NOT include these folders in your snapshot unless you have a very good reason for doing so.") + " ";
844
msg += _("If you include any specific folders then these folders will get overwritten with previous contents when you restore a snapshot.");
846
var dialog = new Gtk.MessageDialog.with_markup(null, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, msg);
847
dialog.set_title("Warning");
848
dialog.set_default_size (200, -1);
849
dialog.set_transient_for(this);
850
dialog.set_modal(true);
855
private void btn_reset_exclude_list_clicked(){
856
//create a temp exclude list ----------------------------
858
temp_exclude_list = new Gee.ArrayList<string>();
860
//refresh treeview --------------------------
862
refresh_tv_exclude();
866
private void btn_save_clicked(){
867
tv_schedule_save_changes();
868
tv_remove_save_changes();
869
tv_exclude_save_changes();
871
App.save_app_config();
872
App.cron_job_update();
877
private void tv_schedule_save_changes(){
879
TreeModel store = tv_schedule.model;
883
bool iterExists = store.get_iter_first (out iter);
887
store.get (iter, 0, out enabled,-1);
891
App.schedule_monthly = enabled;
894
App.schedule_weekly = enabled;
897
App.schedule_daily = enabled;
900
App.schedule_hourly = enabled;
903
App.schedule_boot = enabled;
906
iterExists = store.iter_next (ref iter);
909
if (!App.live_system()){
910
App.is_scheduled = chk_schedule.active;
914
private void tv_remove_save_changes(){
916
TreeModel store = tv_remove.model;
920
bool iterExists = store.get_iter_first (out iter);
924
store.get (iter, 1, out count, -1);
928
App.count_monthly = count;
931
App.count_weekly = count;
934
App.count_daily = count;
937
App.count_hourly = count;
940
App.count_boot = count;
943
App.retain_snapshots_max_days = count;
946
App.minimum_free_disk_space = count * 1000;
949
iterExists = store.iter_next (ref iter);
953
private void tv_exclude_save_changes(){
954
App.exclude_list_user.clear();
955
foreach(string path in temp_exclude_list){
956
if (!App.exclude_list_user.contains(path) && !App.exclude_list_default.contains(path) && !App.exclude_list_home.contains(path)){
957
App.exclude_list_user.add(path);
962
private void btn_cancel_clicked(){