public class MyApp.Window : Gtk.ApplicationWindow{ string laoutput; bool upol; public bool process_line (IOChannel channel, IOCondition condition, string stream_name, out string x, out bool y) { if (condition == IOCondition.HUP) { print ("%s: The fd has been closed.\n", stream_name); return false; } try { string line; channel.read_line (out line, null, null); print ("%s: %s", stream_name, line); x = line; y = true; } catch (IOChannelError e) { print ("%s: IOChannelError: %s\n", stream_name, e.message); return false; } catch (ConvertError e) { print ("%s: ConvertError: %s\n", stream_name, e.message); return false; } return true; } public Window(Nostalgia application){ Object( application: application ); } construct{ bool ssnap=false; var actualstack = new Gtk.Stack(); actualstack.expand = true; var createstack = new Gtk.Stack(); createstack.expand = true; var memc = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); var memr = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); var cr1 = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); var progresscr = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); //memr.add(new Gtk.Label("Restore")); actualstack.add_titled(memc, "memc", "Create"); actualstack.add_titled(memr, "memr", "Restore"); createstack.add_titled(cr1, "cr1", "Backup Options"); createstack.add_titled(progresscr, "progresscr", "Snapshot Progress" ); actualstack.set_transition_type(Gtk.StackTransitionType.SLIDE_UP_DOWN); actualstack.set_transition_duration(750); createstack.set_transition_type(Gtk.StackTransitionType.SLIDE_UP_DOWN); createstack.set_transition_duration(750); //memc.set_column_homogeneous(true); //memc.set_row_homogeneous(true); //BACKUP MENU INTERFACE var label1 = new Gtk.Label("Back up all your files and memories, For when you need them the most"); label1.set_use_markup(true); memc.pack_start(label1, true, true, 50); //memc.pack_start(new Gtk.Image.from_icon_name("liveusb-creator", Gtk.IconSize.DIALOG), false, false, 0); memc.pack_start(new Gtk.Label("Nostalgia makes incremental snapshots, that means: ✔ Only the first snapshot contains the full file system ✔ All snapshots after the first only document changes ✔ It takes up significantly less space compared to full system snapshots ✔ You can hold lots of backups on a drive"), true, false, 0); var button1 = new Gtk.Button.with_label("Create memory"); var blue_color = new Gdk.RGBA(); blue_color.parse("#0860F2"); var green_color = new Gdk.RGBA(); green_color.parse("#59C837"); button1.override_background_color(Gtk.StateFlags.NORMAL, green_color); var gridfb = new Gtk.Grid(); gridfb.attach(button1, 1, 1); button1.clicked.connect (() => { createstack.set_visible_child(cr1); print("Create Button Pressed \n"); remove(actualstack); add(createstack); createstack.set_visible_child(cr1); var crtitlebar = new MyApp.HeaderBar(createstack); set_titlebar(crtitlebar); show_all(); }); gridfb.attach(new Gtk.Label(""), 2, 1); gridfb.attach(new Gtk.Label(""), 0, 1); gridfb.set_column_homogeneous(true); gridfb.set_row_homogeneous(true); //var img1 = new Gtk.Image.from_icon_name("liveusb-creator", Gtk.IconSize.DIALOG); //memc.pack_start(img1, false, false, 30); memc.pack_start(gridfb, true, true, 60); var label1r = new Gtk.Label("For when the worst happens, I'm here to get you back online"); label1r.set_use_markup(true); memr.pack_start(label1r, true, true, 50); memr.pack_start(new Gtk.Label("You can use this option to restore your lost files and configurations from any of your backups. Keep in mind restoring your entire system using this tool may take a while, so please be patient and let us get your system back and running"), true, false, 0); var button1r = new Gtk.Button.with_label("Restore Memory"); button1r.override_background_color(Gtk.StateFlags.NORMAL, blue_color); var gridfbr = new Gtk.Grid(); gridfbr.attach(button1r, 1, 1); gridfbr.attach(new Gtk.Label(""), 0, 1); gridfbr.attach(new Gtk.Label(""), 2, 1); gridfbr.set_column_homogeneous(true); gridfbr.set_row_homogeneous(true); memr.pack_start(gridfbr, true, true, 60); //CREATESTACK STUFF cr1.pack_start(new Gtk.Label(""), false, false, 100); var cr11 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0); //cr11.expand = true; cr11.pack_start(new Gtk.Label(""), true, true, 40); var cr1label = new Gtk.Label("Select your backup drive:"); cr1label.set_use_markup(true); cr11.pack_start(cr1label, true, true, 10); var crloc1 = new Gtk.FileChooserButton("Set location", Gtk.FileChooserAction.SELECT_FOLDER); cr11.pack_start(crloc1, true, true, 0); cr11.pack_start(new Gtk.Label(""), true, true, 10); cr1.pack_start(cr11, false, false, 0); cr1.pack_start(new Gtk.Label(""), false, false, 15); var cr12 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0); var crbackbutton = new Gtk.Button.with_label("↩ Go back"); crbackbutton.clicked.connect (() => { if (!ssnap){ print("Menu Button Pressed \n"); remove(createstack); add(actualstack); var hmtitlebar = new MyApp.HeaderBar(actualstack); set_titlebar(hmtitlebar); show_all(); string x; //Process.spawn_command_line_sync("lsblk", out x); //print(x); } }); cr12.pack_start(crbackbutton, false, false, 10); var packhome = new Gtk.Switch(); packhome.set_state(true); var cr14 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0); cr14.pack_start(new Gtk.Label(""), true, true, 10); var packhomela = new Gtk.Label("Include home folder in backup:"); packhomela.set_use_markup(true); cr14.pack_start(packhomela, false, false, 10); cr14.pack_start(packhome, false, false, 10); cr14.pack_start(new Gtk.Label(""), true, true, 10); cr1.pack_start(cr14, false, false, 0); var finbutcr = new Gtk.Button.with_label("✔ Make snapshot"); finbutcr.override_background_color(Gtk.StateFlags.NORMAL, green_color); cr12.pack_end(finbutcr, false, false, 10); finbutcr.clicked.connect (() => { if(!ssnap){ print(crloc1.get_filename()); string loc = crloc1.get_filename(); print("\n"); if (crloc1.get_filename() == null){ var ibl = new Gtk.Dialog.with_buttons("Invaild backup location", this, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.USE_HEADER_BAR, null); var iblca = ibl.get_content_area(); iblca.add(new Gtk.Label(" ")); iblca.add(new Gtk.Label(" Make sure the folder you picked is mounted and exists ")); iblca.add(new Gtk.Label(" ")); ibl.show_all(); }else{ ssnap=true; createstack.set_visible_child(progresscr); string isfile; Process.spawn_command_line_sync("file " + crloc1.get_filename() + "/nostalgia.file", out isfile); string isft = crloc1.get_filename() + "/nostalgia.file: empty "; print(isfile); print(isft); var lbl = new Gtk.TextView(); lbl.set_wrap_mode (Gtk.WrapMode.WORD); lbl.set_monospace(true); var lblScroll = new Gtk.ScrolledWindow(null, null); lblScroll.add(lbl); lblScroll.set_max_content_height(100); progresscr.pack_start(lblScroll); //The length will never be the same if the file is not found if(isfile.char_count() != isft.char_count()){ print("\n root backup \n"); string testx; //Process.spawn_command_line_sync("bash command", out testx); progresscr.pack_start(new Gtk.Label(testx)); //print(testx); progresscr.pack_start(new Gtk.Label("This seems to be your first nostalgia backup on this harddrive, so it will take a while"), false, false, 10); show_all(); } string[] spawn_env1 = Environ.get(); Pid rpid; int otcr; int dum; bool lop=true; string[] backup_command = {"/usr/bin/rsync", "-av", "/home/ioachim/Music", "/home/ioachim/Music2", "--no-i-r", "--info=progress2", null}; var ChildProcessBackup = new Subprocess.newv(backup_command, SubprocessFlags.STDOUT_PIPE); ChildProcessBackup.wait_check_async.begin(null, (obj, res) => { try{ ChildProcessBackup.wait_check_async.end(res); print("\n\n-------SUCCESFULL------\n\n"); ssnap = false; createstack.set_visible_child(cr1); Notify.init("Nostalgia"); var notification = new Notify.Notification("Nostalgia", "Your snapshot is ready", "deja-dup"); notification.set_timeout(0); notification.show(); }catch(Error err){ print("\n\n------ERROR!!!------\n%s\n\n", err.message); } }); var OutputPipeBackup = ChildProcessBackup.get_stdout_pipe(); update_label_from_istream.begin(OutputPipeBackup, lbl); } } }); cr1.pack_end(cr12, false, false, 10); add(actualstack); var headerbar = new MyApp.HeaderBar(actualstack); set_titlebar(headerbar); window_position = Gtk.WindowPosition.CENTER; window_position = Gtk.WindowPosition.CENTER; set_default_size(800, 600); set_resizable(false); show_all(); print("Hey, thanks for choosing nostalgia! \n"); print("If you're looking at the debug output most probably you're having some trouble with this program, so feel free to email me at [ioachim.radu@protonmail.com] and I'll see if I can help \n"); } } async void update_label_from_istream (InputStream istream, Gtk.TextView label) { try { var dis = new DataInputStream (istream); var line = yield dis.read_line_async (); while (line != null) { label.buffer.text += line + "\n"; line = yield dis.read_line_async (); } } catch (Error err) {} }