From 20c8fd0a445471aaf428e702dd05f4869cc822d2 Mon Sep 17 00:00:00 2001 From: ygerlach <100762533+ygerlach@users.noreply.github.com> Date: Mon, 29 Dec 2025 10:49:56 +0100 Subject: [PATCH] make Tags an enum --- src/Core/Main.vala | 139 +++++++++++++-------------------- src/Core/Snapshot.vala | 37 ++++----- src/Core/SnapshotRepo.vala | 75 ++++++++---------- src/Core/Tags.vala | 117 +++++++++++++++++++++++++++ src/Gtk/MainWindow.vala | 4 +- src/Gtk/ScheduleBox.vala | 71 +++++------------ src/Gtk/SetupWizardWindow.vala | 14 +--- src/meson.build | 1 + 8 files changed, 248 insertions(+), 210 deletions(-) create mode 100644 src/Core/Tags.vala diff --git a/src/Core/Main.vala b/src/Core/Main.vala index 28f5bc2c..d4788434 100644 --- a/src/Core/Main.vala +++ b/src/Core/Main.vala @@ -84,11 +84,10 @@ public class Main : GLib.Object{ public LinuxDistro current_distro; public bool mirror_system = false; - public bool schedule_monthly = false; - public bool schedule_weekly = false; - public bool schedule_daily = false; - public bool schedule_hourly = false; - public bool schedule_boot = false; + // tags that are scheduled + public Tags schedule = 0; + + // planned snapshots per tag public int count_monthly = 2; public int count_weekly = 3; public int count_daily = 5; @@ -184,7 +183,7 @@ public class Main : GLib.Object{ } public Main(string[] args, bool gui_mode){ - + this.mount_point_app = "/run/timeshift/%d".printf(Posix.getpid()); dir_create(this.mount_point_app); @@ -1056,9 +1055,7 @@ public class Main : GLib.Object{ public bool scheduled{ get{ - return !live_system() - && (schedule_boot || schedule_hourly || schedule_daily || - schedule_weekly || schedule_monthly); + return !live_system() && (schedule > 0); } } @@ -1127,7 +1124,7 @@ public class Main : GLib.Object{ // ondemand if (is_ondemand){ - bool ok = create_snapshot_for_tag ("ondemand",now); + bool ok = create_snapshot_for_tag (Tags.OnDemand,now); if(!ok){ return false; } @@ -1136,16 +1133,16 @@ public class Main : GLib.Object{ } } else if (scheduled){ - Snapshot last_snapshot_boot = repo.get_latest_snapshot("boot", sys_uuid); - Snapshot last_snapshot_hourly = repo.get_latest_snapshot("hourly", sys_uuid); - Snapshot last_snapshot_daily = repo.get_latest_snapshot("daily", sys_uuid); - Snapshot last_snapshot_weekly = repo.get_latest_snapshot("weekly", sys_uuid); - Snapshot last_snapshot_monthly = repo.get_latest_snapshot("monthly", sys_uuid); + Snapshot last_snapshot_boot = repo.get_latest_snapshot(Tags.Boot, sys_uuid); + Snapshot last_snapshot_hourly = repo.get_latest_snapshot(Tags.Hourly, sys_uuid); + Snapshot last_snapshot_daily = repo.get_latest_snapshot(Tags.Daily, sys_uuid); + Snapshot last_snapshot_weekly = repo.get_latest_snapshot(Tags.Weekly, sys_uuid); + Snapshot last_snapshot_monthly = repo.get_latest_snapshot(Tags.Monthly, sys_uuid); DateTime dt_sys_boot = now.add_seconds((-1) * get_system_uptime_seconds()); bool take_new = false; - if (schedule_boot){ + if (Tags.Boot in App.schedule){ log_msg(_("Boot snapshots are enabled")); @@ -1164,7 +1161,7 @@ public class Main : GLib.Object{ } if (take_new){ - status = create_snapshot_for_tag ("boot",now); + status = create_snapshot_for_tag (Tags.Boot,now); if(!status){ log_error(_("Boot snapshot failed!")); return false; @@ -1176,7 +1173,7 @@ public class Main : GLib.Object{ } } - if (schedule_hourly){ + if (Tags.Hourly in App.schedule){ log_msg(_("Hourly snapshots are enabled")); @@ -1195,7 +1192,7 @@ public class Main : GLib.Object{ } if (take_new){ - status = create_snapshot_for_tag ("hourly",now); + status = create_snapshot_for_tag (Tags.Hourly,now); if(!status){ log_error(_("Hourly snapshot failed!")); return false; @@ -1207,7 +1204,7 @@ public class Main : GLib.Object{ } } - if (schedule_daily){ + if (Tags.Daily in App.schedule){ log_msg(_("Daily snapshots are enabled")); @@ -1226,7 +1223,7 @@ public class Main : GLib.Object{ } if (take_new){ - status = create_snapshot_for_tag ("daily",now); + status = create_snapshot_for_tag (Tags.Daily,now); if(!status){ log_error(_("Daily snapshot failed!")); return false; @@ -1238,7 +1235,7 @@ public class Main : GLib.Object{ } } - if (schedule_weekly){ + if (Tags.Weekly in App.schedule){ log_msg(_("Weekly snapshots are enabled")); @@ -1257,7 +1254,7 @@ public class Main : GLib.Object{ } if (take_new){ - status = create_snapshot_for_tag ("weekly",now); + status = create_snapshot_for_tag (Tags.Weekly,now); if(!status){ log_error(_("Weekly snapshot failed!")); return false; @@ -1269,7 +1266,7 @@ public class Main : GLib.Object{ } } - if (schedule_monthly){ + if (Tags.Monthly in App.schedule){ log_msg(_("Monthly snapshot are enabled")); @@ -1288,7 +1285,7 @@ public class Main : GLib.Object{ } if (take_new){ - status = create_snapshot_for_tag ("monthly",now); + status = create_snapshot_for_tag (Tags.Monthly,now); if(!status){ log_error(_("Monthly snapshot failed!")); return false; @@ -1328,7 +1325,7 @@ public class Main : GLib.Object{ return status; } - private bool create_snapshot_for_tag(string tag, DateTime dt_created){ + private bool create_snapshot_for_tag(Tags tag, DateTime dt_created){ log_debug("Main: backup_and_rotate()"); @@ -1344,20 +1341,17 @@ public class Main : GLib.Object{ DateTime dt_filter = null; - if (tag != "ondemand"){ + if (tag != Tags.OnDemand){ switch(tag){ - case "boot": + case Tags.Boot: dt_filter = dt_sys_boot; break; - case "hourly": - case "daily": - case "weekly": - case "monthly": + case Tags.Hourly: + case Tags.Daily: + case Tags.Weekly: + case Tags.Monthly: dt_filter = now.add_hours(-1).add_seconds(59); break; - default: - log_error(_("Unknown snapshot type") + ": %s".printf(tag)); - return false; } // find a recent backup that can be used @@ -1374,7 +1368,7 @@ public class Main : GLib.Object{ // tag the backup backup_to_rotate.add_tag(tag); - var message = _("Tagged snapshot") + " '%s': %s".printf(backup_to_rotate.name, tag); + var message = _("Tagged snapshot") + " '%s': %s".printf(backup_to_rotate.name, tag.localized_name()); log_msg(message); return true; @@ -1448,7 +1442,7 @@ public class Main : GLib.Object{ OSDNotify.notify_send("TimeShift", message, 10000, "low"); if (new_snapshot != null){ - message = _("Tagged snapshot") + " '%s': %s".printf(new_snapshot.name, tag); + message = _("Tagged snapshot") + " '%s': %s".printf(new_snapshot.name, tag.localized_name()); log_msg(message); } @@ -1506,7 +1500,7 @@ public class Main : GLib.Object{ // get latest snapshot to link if not set ------- if (snapshot_to_link == null){ - snapshot_to_link = repo.get_latest_snapshot("", sys_uuid); + snapshot_to_link = repo.get_latest_snapshot(0, sys_uuid); } string link_from_path = ""; @@ -1555,7 +1549,7 @@ public class Main : GLib.Object{ return total_size; } - private Snapshot? create_snapshot_with_rsync(string tag, DateTime dt_created){ + private Snapshot? create_snapshot_with_rsync(Tags tag, DateTime dt_created){ log_msg(string.nfill(78, '-')); if (first_snapshot_size == 0){ @@ -1619,7 +1613,7 @@ public class Main : GLib.Object{ // get latest snapshot to link if not set ------- if (snapshot_to_link == null){ - snapshot_to_link = repo.get_latest_snapshot("", sys_uuid); + snapshot_to_link = repo.get_latest_snapshot(0, sys_uuid); } string link_from_path = ""; @@ -1687,7 +1681,7 @@ public class Main : GLib.Object{ return null; } - string initial_tags = (tag == "ondemand") ? "" : tag; + string initial_tags = (tag == Tags.OnDemand) ? "" : tag.name(); // write control file // this step is redundant - just in case if app crashes while parsing log file in next step @@ -1716,7 +1710,7 @@ public class Main : GLib.Object{ return snapshot; } - private Snapshot? create_snapshot_with_btrfs(string tag, DateTime dt_created){ + private Snapshot? create_snapshot_with_btrfs(Tags tag, DateTime dt_created){ log_msg(_("Creating new backup...") + "(BTRFS)"); @@ -1788,7 +1782,7 @@ public class Main : GLib.Object{ snapshot_path = path_combine(repo.mount_paths["@"], "timeshift-btrfs/snapshots/%s".printf(snapshot_name)); - string initial_tags = (tag == "ondemand") ? "" : tag; + string initial_tags = (tag == Tags.OnDemand) ? "" : tag.name(); // write control file var snapshot = Snapshot.write_control_file( @@ -1830,50 +1824,25 @@ public class Main : GLib.Object{ // add tags passed on commandline for both --check and --create foreach(string tag in cmd_tags.split(",")){ - switch(tag.strip().up()){ - case "O": - snapshot.add_tag("ondemand"); - break; - case "B": - snapshot.add_tag("boot"); - break; - case "H": - snapshot.add_tag("hourly"); - break; - case "D": - snapshot.add_tag("daily"); - break; - case "W": - snapshot.add_tag("weekly"); - break; - case "M": - snapshot.add_tag("monthly"); - break; + Tags? parsed = Tags.parse(tag); + if(parsed != null) { + snapshot.add_tag(parsed); } } // add tag as ondemand if no other tag is specified - if (snapshot.tags.size == 0){ - snapshot.add_tag("ondemand"); + if (snapshot.tags == 0){ + snapshot.add_tag(Tags.OnDemand); } } public void validate_cmd_tags(){ foreach(string tag in cmd_tags.split(",")){ - switch(tag.strip().up()){ - case "O": - case "B": - case "H": - case "D": - case "W": - case "M": - break; - default: + if(Tags.parse(tag) == null) { log_error(_("Unknown value specified for option --tags") + " (%s).".printf(tag)); log_error(_("Expected values: O, B, H, D, W, M")); exit_app(1); - break; } } } @@ -3363,11 +3332,11 @@ public class Main : GLib.Object{ config.set_string_member("include_btrfs_home_for_restore", include_btrfs_home_for_restore.to_string()); config.set_string_member("stop_cron_emails", stop_cron_emails.to_string()); - config.set_string_member("schedule_monthly", schedule_monthly.to_string()); - config.set_string_member("schedule_weekly", schedule_weekly.to_string()); - config.set_string_member("schedule_daily", schedule_daily.to_string()); - config.set_string_member("schedule_hourly", schedule_hourly.to_string()); - config.set_string_member("schedule_boot", schedule_boot.to_string()); + config.set_string_member("schedule_monthly", (Tags.Monthly in App.schedule).to_string()); + config.set_string_member("schedule_weekly", (Tags.Weekly in App.schedule).to_string()); + config.set_string_member("schedule_daily", (Tags.Daily in App.schedule).to_string()); + config.set_string_member("schedule_hourly", (Tags.Hourly in App.schedule).to_string()); + config.set_string_member("schedule_boot", (Tags.Boot in App.schedule).to_string()); config.set_string_member("count_monthly", count_monthly.to_string()); config.set_string_member("count_weekly", count_weekly.to_string()); @@ -3480,11 +3449,11 @@ public class Main : GLib.Object{ backup_uuid = json_get_string(config,"backup_device_uuid", backup_uuid); backup_parent_uuid = json_get_string(config,"parent_device_uuid", backup_parent_uuid); - this.schedule_monthly = json_get_bool(config,"schedule_monthly",schedule_monthly); - this.schedule_weekly = json_get_bool(config,"schedule_weekly",schedule_weekly); - this.schedule_daily = json_get_bool(config,"schedule_daily",schedule_daily); - this.schedule_hourly = json_get_bool(config,"schedule_hourly",schedule_hourly); - this.schedule_boot = json_get_bool(config,"schedule_boot",schedule_boot); + Tags.set_value(ref this.schedule, Tags.Monthly, json_get_bool(config,"schedule_monthly", Tags.Monthly in schedule)); + Tags.set_value(ref this.schedule, Tags.Weekly, json_get_bool(config,"schedule_weekly", Tags.Weekly in schedule)); + Tags.set_value(ref this.schedule, Tags.Daily, json_get_bool(config,"schedule_daily", Tags.Daily in schedule)); + Tags.set_value(ref this.schedule, Tags.Hourly, json_get_bool(config,"schedule_hourly", Tags.Hourly in schedule)); + Tags.set_value(ref this.schedule, Tags.Boot, json_get_bool(config,"schedule_boot", Tags.Boot in schedule)); this.count_monthly = json_get_int(config,"count_monthly",count_monthly); this.count_weekly = json_get_int(config,"count_weekly",count_weekly); @@ -4331,7 +4300,7 @@ public class Main : GLib.Object{ CronTab.add_script_file("timeshift-hourly", "d", "0 * * * * root timeshift --check --scripted", stop_cron_emails); //boot - if (schedule_boot){ + if (Tags.Boot in App.schedule){ CronTab.add_script_file("timeshift-boot", "d", "@reboot root sleep 10m && timeshift --create --scripted --tags B", stop_cron_emails); } else{ diff --git a/src/Core/Snapshot.vala b/src/Core/Snapshot.vala index 4898925c..f4ec3c3c 100644 --- a/src/Core/Snapshot.vala +++ b/src/Core/Snapshot.vala @@ -41,7 +41,7 @@ public class Snapshot : GLib.Object{ public string app_version = ""; public string description = ""; public int64 file_count = 0; - public Gee.ArrayList tags; + public Tags tags; public Gee.ArrayList exclude_list; public Gee.HashMap subvolumes; public Gee.ArrayList fstab_list; @@ -73,7 +73,7 @@ public class Snapshot : GLib.Object{ repo = _repo; date = new DateTime.from_unix_utc(0); - tags = new Gee.ArrayList(); + tags = 0; exclude_list = new Gee.ArrayList(); fstab_list = new Gee.ArrayList(); delete_file_task = new DeleteFileTask(); @@ -139,17 +139,15 @@ public class Snapshot : GLib.Object{ public string taglist{ owned get{ string str = ""; - foreach(string tag in tags){ - str += " " + tag; + foreach(Tags? tag in tags) { + str += " " + tag.name(); } return str.strip(); } set{ - tags.clear(); + this.tags = 0; foreach(string tag in value.split(" ")){ - if (!tags.contains(tag.strip())){ - tags.add(tag.strip()); - } + this.tags |= Tags.parse(tag); } } } @@ -157,32 +155,29 @@ public class Snapshot : GLib.Object{ public string taglist_short{ owned get{ string str = ""; - foreach(string tag in tags){ - str += " " + tag.replace("ondemand","O").replace("boot","B").replace("hourly","H").replace("daily","D").replace("weekly","W").replace("monthly","M"); + foreach(Tags? tag in this.tags){ + str += " " + tag.letter().to_string(); } return str.strip(); } } - public void add_tag(string tag){ - - if (!tags.contains(tag.strip())){ - tags.add(tag.strip()); + public void add_tag(Tags tag){ + if (!(tag in this.tags)){ + this.tags |= tag; update_control_file(); } } - public void remove_tag(string tag){ - - if (tags.contains(tag.strip())){ - tags.remove(tag.strip()); + public void remove_tag(Tags tag){ + if (tag in this.tags){ + this.tags ^= tag; update_control_file(); } } - public bool has_tag(string tag){ - - return tags.contains(tag.strip()); + public bool has_tag(Tags tag){ + return tag in this.tags; } // control files diff --git a/src/Core/SnapshotRepo.vala b/src/Core/SnapshotRepo.vala index 5be72936..dc5b798e 100644 --- a/src/Core/SnapshotRepo.vala +++ b/src/Core/SnapshotRepo.vala @@ -373,30 +373,27 @@ public class SnapshotRepo : GLib.Object{ // get tagged snapshots ---------------------------------- - public Gee.ArrayList get_snapshots_by_tag(string tag = ""){ + public Gee.ArrayList get_snapshots_by_tag(Tags tag = 0){ - var list = new Gee.ArrayList(); + var list = new Gee.ArrayList(); foreach(Snapshot bak in snapshots){ - if (bak.valid && (tag.length == 0) || bak.has_tag(tag)){ + if (bak.valid && (tag == 0) || bak.has_tag(tag)){ list.add(bak); } } - list.sort((a,b) => { - Snapshot t1 = (Snapshot) a; - Snapshot t2 = (Snapshot) b; - return (t1.date.compare(t2.date)); - }); + list.sort((a, b) => + a.date.compare(b.date) + ); return list; } - public Snapshot? get_latest_snapshot(string tag, string sys_uuid){ - - var list = get_snapshots_by_tag(tag); + public Snapshot? get_latest_snapshot(Tags tag, string sys_uuid){ + Gee.ArrayList list = get_snapshots_by_tag(tag); for(int i = list.size - 1; i >= 0; i--){ - var bak = list[i]; + Snapshot bak = list[i]; if (bak.sys_uuid == sys_uuid){ return bak; } @@ -405,12 +402,11 @@ public class SnapshotRepo : GLib.Object{ return null; } - public Snapshot? get_oldest_snapshot(string tag, string sys_uuid){ - - var list = get_snapshots_by_tag(tag); + public Snapshot? get_oldest_snapshot(Tags tag, string sys_uuid){ + Gee.ArrayList list = get_snapshots_by_tag(tag); for(int i = 0; i < list.size; i++){ - var bak = list[i]; + Snapshot bak = list[i]; if (bak.sys_uuid == sys_uuid){ return bak; } @@ -622,45 +618,46 @@ public class SnapshotRepo : GLib.Object{ last_snapshot_failed_space = false; DateTime now = new DateTime.now_local(); DateTime dt_limit; - int count_limit; // remove tags from older backups - boot --------------- - var list = get_snapshots_by_tag("boot"); + Gee.ArrayList list = get_snapshots_by_tag(Tags.Boot); if (list.size > App.count_boot){ log_msg(_("Maximum backups exceeded for backup level") + " '%s'".printf("boot")); while (list.size > App.count_boot){ - list[0].remove_tag("boot"); + list[0].remove_tag(Tags.Boot); log_msg(_("Snapshot") + " '%s' ".printf(list[0].name) + _("un-tagged") + " '%s'".printf("boot")); - list = get_snapshots_by_tag("boot"); + list = get_snapshots_by_tag(Tags.Boot); } } // remove tags from older backups - hourly, daily, weekly, monthly --------- - string[] levels = { "hourly","daily","weekly","monthly" }; + Tags levels = Tags.Hourly | Tags.Daily | Tags.Weekly | Tags.Monthly; - foreach(string level in levels){ + foreach(Tags? level in levels){ list = get_snapshots_by_tag(level); if (list.size == 0) { continue; } + int count_limit; + switch (level){ - case "hourly": + case Tags.Hourly: dt_limit = now.add_hours(-1 * App.count_hourly); count_limit = App.count_hourly; break; - case "daily": + case Tags.Daily: dt_limit = now.add_days(-1 * App.count_daily); count_limit = App.count_daily; break; - case "weekly": + case Tags.Weekly: dt_limit = now.add_weeks(-1 * App.count_weekly); count_limit = App.count_weekly; break; - case "monthly": + case Tags.Monthly: dt_limit = now.add_months(-1 * App.count_monthly); count_limit = App.count_monthly; break; @@ -670,12 +667,11 @@ public class SnapshotRepo : GLib.Object{ break; } - if (list.size > count_limit){ + int snaps_count = list.size; + if (snaps_count > count_limit){ - log_msg(_("Maximum backups exceeded for backup level") + " '%s'".printf(level)); + log_msg(_("Maximum backups exceeded for backup level") + " '%s'".printf(level.name())); - int snaps_count = list.size; - foreach(var snap in list){ if (snap.description.strip().length > 0){ continue; } // don't delete snapshots with comments @@ -685,7 +681,7 @@ public class SnapshotRepo : GLib.Object{ snap.remove_tag(level); snaps_count--; - log_msg(_("Snapshot") + " '%s' ".printf(list[0].name) + _("un-tagged") + " '%s'".printf(level)); + log_msg(_("Snapshot") + " '%s' ".printf(list[0].name) + _("un-tagged") + " '%s'".printf(level.name())); } } } @@ -760,8 +756,9 @@ public class SnapshotRepo : GLib.Object{ bool show_msg = true; + // delete untagged snapshots foreach(Snapshot bak in snapshots){ - if (bak.tags.size == 0){ + if (bak.tags == 0){ if (show_msg){ log_msg("%s (%s):".printf(_("Removing snapshots"), _("un-tagged"))); @@ -901,17 +898,13 @@ public class SnapshotRepo : GLib.Object{ // symlinks ---------------------------------------- public void create_symlinks(){ - cleanup_symlink_dir("boot"); - cleanup_symlink_dir("hourly"); - cleanup_symlink_dir("daily"); - cleanup_symlink_dir("weekly"); - cleanup_symlink_dir("monthly"); - cleanup_symlink_dir("ondemand"); - + foreach(Tags? tag in Tags.All) { + cleanup_symlink_dir(tag.name()); + } foreach(Snapshot bak in snapshots){ - foreach(string tag in bak.tags) { - string linkTarget = "%s-%s/%s".printf(snapshots_path, tag, bak.name); + foreach(Tags? tag in bak.tags) { + string linkTarget = "%s-%s/%s".printf(snapshots_path, tag.name(), bak.name); string linkValue = "../snapshots/" + bak.name; try { File f = File.new_for_path(linkTarget); diff --git a/src/Core/Tags.vala b/src/Core/Tags.vala new file mode 100644 index 00000000..7c0856f0 --- /dev/null +++ b/src/Core/Tags.vala @@ -0,0 +1,117 @@ + +[Flags] +public enum Tags { + + Boot, + Hourly, + Daily, + Weekly, + Monthly, + OnDemand, + + First = Boot, + Last = OnDemand, + Timed = Boot | Hourly | Daily | Weekly | Monthly, + All = Timed | OnDemand; + + /** + A lowercase short name + */ + public string name() { + switch(this) { + case Boot: return "boot"; + case Hourly: return "hourly"; + case Daily: return "daily"; + case Weekly: return "weekly"; + case Monthly: return "monthly"; + case OnDemand: return "ondemand"; + } + + assert_not_reached(); + } + + /** + A lowercase short name + */ + public string localized_name() { + switch(this) { + case Boot: return _("Boot"); + case Hourly: return _("Hourly"); + case Daily: return _("Daily"); + case Weekly: return _("Weekly"); + case Monthly: return _("Monthly"); + case OnDemand: return _("Ondemand"); + } + + assert_not_reached(); + } + + /** + A single uppercase letter + */ + public char letter() { + switch(this) { + case Boot: return 'B'; + case Hourly: return 'H'; + case Daily: return 'D'; + case Weekly: return 'W'; + case Monthly: return 'M'; + case OnDemand: return 'O'; + } + + assert_not_reached(); + } + + public static Tags? parse(string input) { + switch(input.strip().down().get(0)) { + case 'b': return Boot; + case 'h': return Hourly; + case 'd': return Daily; + case 'w': return Weekly; + case 'm': return Monthly; + case 'o': return OnDemand; + } + return null; + } + + public static void set_value(ref Tags tags, Tags value, bool setit) { + if(setit) { + tags |= value; + } else { + tags &= ~ value; + } + } + + public TagsIterator iterator() { + return new TagsIterator(this); + } +} + +public class TagsIterator { + private Tags value; + private Tags pos = Tags.First; + + public TagsIterator(Tags value) { + this.value = value; + } + + public bool next() { + for(Tags t = this.pos; t <= Tags.Last; t <<= 1) { + if(t in this.value) { + return true; + } + } + return false; + } + + public Tags? next_value() { + for(; this.pos <= Tags.Last; this.pos <<= 1) { + if(this.pos in this.value) { + Tags copy = this.pos; + this.pos <<= 1; + return copy; + } + } + return null; + } +} diff --git a/src/Gtk/MainWindow.vala b/src/Gtk/MainWindow.vala index cd127b1d..ece1cf01 100644 --- a/src/Gtk/MainWindow.vala +++ b/src/Gtk/MainWindow.vala @@ -934,9 +934,9 @@ class MainWindow : Gtk.Window{ if (App.repo.has_snapshots()){ string sys_uuid = (App.sys_root == null) ? "" : App.sys_root.uuid; - var last_snapshot = App.repo.get_latest_snapshot("", sys_uuid); + var last_snapshot = App.repo.get_latest_snapshot(0, sys_uuid); last_snapshot_date = (last_snapshot == null) ? null : last_snapshot.date; - var oldest_snapshot = App.repo.get_oldest_snapshot("", sys_uuid); + var oldest_snapshot = App.repo.get_oldest_snapshot(0, sys_uuid); oldest_snapshot_date = (oldest_snapshot == null) ? null : oldest_snapshot.date; } diff --git a/src/Gtk/ScheduleBox.vala b/src/Gtk/ScheduleBox.vala index 39f33fcc..ea013591 100644 --- a/src/Gtk/ScheduleBox.vala +++ b/src/Gtk/ScheduleBox.vala @@ -61,15 +61,7 @@ class ScheduleBox : Gtk.Box{ // monthly - add_schedule_option(this, _("Monthly"), _("Create one per month"), out chk_m, out spin_m); - - chk_m.active = App.schedule_monthly; - chk_m.toggled.connect(()=>{ - App.schedule_monthly = chk_m.active; - //spin_m.sensitive = chk_m.active; - chk_cron.sensitive = App.scheduled; - update_statusbar(); - }); + add_schedule_option(this, Tags.Monthly, _("Create one per month"), out chk_m, out spin_m); spin_m.set_value(App.count_monthly); //spin_m.sensitive = chk_m.active; @@ -79,15 +71,7 @@ class ScheduleBox : Gtk.Box{ // weekly - add_schedule_option(this, _("Weekly"), _("Create one per week"), out chk_w, out spin_w); - - chk_w.active = App.schedule_weekly; - chk_w.toggled.connect(()=>{ - App.schedule_weekly = chk_w.active; - //spin_w.sensitive = chk_w.active; - chk_cron.sensitive = App.scheduled; - update_statusbar(); - }); + add_schedule_option(this, Tags.Weekly, _("Create one per week"), out chk_w, out spin_w); spin_w.set_value(App.count_weekly); //spin_w.sensitive = chk_w.active; @@ -97,15 +81,7 @@ class ScheduleBox : Gtk.Box{ // daily - add_schedule_option(this, _("Daily"), _("Create one per day"), out chk_d, out spin_d); - - chk_d.active = App.schedule_daily; - chk_d.toggled.connect(()=>{ - App.schedule_daily = chk_d.active; - //spin_d.sensitive = chk_d.active; - chk_cron.sensitive = App.scheduled; - update_statusbar(); - }); + add_schedule_option(this, Tags.Daily, _("Create one per day"), out chk_d, out spin_d); spin_d.set_value(App.count_daily); //spin_d.sensitive = chk_d.active; @@ -115,15 +91,7 @@ class ScheduleBox : Gtk.Box{ // hourly - add_schedule_option(this, _("Hourly"), _("Create one per hour"), out chk_h, out spin_h); - - chk_h.active = App.schedule_hourly; - chk_h.toggled.connect(()=>{ - App.schedule_hourly = chk_h.active; - //spin_h.sensitive = chk_h.active; - chk_cron.sensitive = App.scheduled; - update_statusbar(); - }); + add_schedule_option(this, Tags.Hourly, _("Create one per hour"), out chk_h, out spin_h); spin_h.set_value(App.count_hourly); //spin_h.sensitive = chk_h.active; @@ -133,15 +101,7 @@ class ScheduleBox : Gtk.Box{ // boot - add_schedule_option(this, _("Boot"), _("Create one per boot"), out chk_b, out spin_b); - - chk_b.active = App.schedule_boot; - chk_b.toggled.connect(()=>{ - App.schedule_boot = chk_b.active; - //spin_b.sensitive = chk_b.active; - chk_cron.sensitive = App.scheduled; - update_statusbar(); - }); + add_schedule_option(this, Tags.Boot, _("Create one per boot"), out chk_b, out spin_b); spin_b.set_value(App.count_boot); //spin_b.sensitive = chk_b.active; @@ -260,7 +220,7 @@ class ScheduleBox : Gtk.Box{ } private void add_schedule_option( - Gtk.Box box, string period, string period_desc, + Gtk.Box box, Tags period, string period_desc, out Gtk.CheckButton chk, out Gtk.SpinButton spin){ var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 6); @@ -275,9 +235,21 @@ class ScheduleBox : Gtk.Box{ sg_count = new Gtk.SizeGroup(Gtk.SizeGroupMode.HORIZONTAL); } - var txt = "%s".printf(period); - chk = add_checkbox(hbox, txt); + var txt = "%s".printf(period.localized_name()); + Gtk.CheckButton check = add_checkbox(hbox, txt); + chk = check; sg_title.add_widget(chk); + + check.active = period in App.schedule; + check.toggled.connect(()=>{ + if(check.active) { + App.schedule |= period; // add + } else { + App.schedule &= ~ period; // remove + } + chk_cron.sensitive = App.scheduled; + update_statusbar(); + }); var tt = _("Number of snapshots to keep.\nOlder snapshots will be removed once this limit is exceeded."); var label = add_label(hbox, " " + _("Keep")); @@ -296,8 +268,7 @@ class ScheduleBox : Gtk.Box{ public void update_statusbar(){ - if (App.schedule_monthly || App.schedule_weekly || App.schedule_daily - || App.schedule_hourly || App.schedule_boot){ + if (App.scheduled){ img_shield.surface = IconManager.lookup_surface(IconManager.SHIELD_HIGH, IconManager.SHIELD_ICON_SIZE, img_shield.scale_factor); diff --git a/src/Gtk/SetupWizardWindow.vala b/src/Gtk/SetupWizardWindow.vala index 6056c087..9cf50ffb 100644 --- a/src/Gtk/SetupWizardWindow.vala +++ b/src/Gtk/SetupWizardWindow.vala @@ -78,12 +78,8 @@ class SetupWizardWindow : Gtk.Window{ this.resize(def_width, def_height); if (App.first_run && !schedule_accepted){ - App.schedule_boot = false; - App.schedule_hourly = false; - App.schedule_daily = true; // set - log_debug("Setting schedule_daily for first run"); - App.schedule_weekly = false; - App.schedule_monthly = false; + App.schedule = Tags.Daily; + log_debug("Setting schedule Daily for first run"); } // add notebook @@ -150,11 +146,7 @@ class SetupWizardWindow : Gtk.Window{ private bool on_delete_event(Gdk.EventAny event){ if (App.first_run && !schedule_accepted){ - App.schedule_boot = false; - App.schedule_hourly = false; - App.schedule_daily = false; // unset - App.schedule_weekly = false; - App.schedule_monthly = false; + App.schedule = 0; } save_changes(); diff --git a/src/meson.build b/src/meson.build index def2ce5d..a37f3929 100644 --- a/src/meson.build +++ b/src/meson.build @@ -21,6 +21,7 @@ sources_core = files([ 'Core/Snapshot.vala', 'Core/SnapshotRepo.vala', 'Core/Subvolume.vala', + 'Core/Tags.vala', ]) sources_utility = files([