[gnome-boxes/wip/props-ui-files: 1/5] Add PropertiesSnapshots widget



commit 4d30bd9367d925b00f35ad0864102bee37dbeb71
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Tue Aug 9 21:34:05 2016 +0100

    Add PropertiesSnapshots widget
    
    This is almost identical to SnapshotsProperty but is a widget itself and
    extends PropertiesPageWidget. This will enable us to change
    IPropertiesProvider.get_properties() to return a PropertiesPageWidget
    rather than a list of Property objects in a following patch and
    ultimately to drop Property hierarchy in favour of page-specific widget
    implementation.

 src/Makefile.am               |    1 +
 src/properties-snapshots.vala |  161 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 162 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index adfc8ed..823c6ca 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -135,6 +135,7 @@ gnome_boxes_SOURCES =                               \
        properties.vala                         \
        properties-window.vala                  \
        properties-page-widget.vala             \
+       properties-snapshots.vala               \
        properties-toolbar.vala                 \
        remote-machine.vala                     \
        searchbar.vala                          \
diff --git a/src/properties-snapshots.vala b/src/properties-snapshots.vala
new file mode 100644
index 0000000..da6bdc1
--- /dev/null
+++ b/src/properties-snapshots.vala
@@ -0,0 +1,161 @@
+// This file is part of GNOME Boxes. License: LGPLv2+
+
+private class Boxes.PropertiesSnapshots: Boxes.PropertiesPageWidget {
+    private LibvirtMachine machine;
+    private Gtk.ListBox snapshot_list = new Gtk.ListBox ();
+    private Gtk.Stack stack;
+    private Gtk.Label activity_label = new Gtk.Label ("");
+    private Gtk.Stack snapshot_stack;
+    private Gtk.Label empty_label;
+    private Gtk.Box activity_box;
+    private Gtk.Box snapshot_box;
+    private string? activity {
+        set {
+            if (value == null) {
+                stack.visible_child = snapshot_box;
+            } else {
+                activity_label.label = value;
+                stack.visible_child = activity_box;
+            }
+        }
+    }
+    private ulong added_id;
+    private ulong removed_id;
+
+    public PropertiesSnapshots (LibvirtMachine machine) {
+        base (PropertiesPage.SNAPSHOTS, machine);
+
+        this.machine = machine;
+        stack = new Gtk.Stack ();
+        stack.transition_type = Gtk.StackTransitionType.CROSSFADE;
+
+        add_property (null, stack, null);
+
+        // Snapshots page
+        snapshot_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
+        snapshot_box.margin = 20;
+
+        var toolbar = new Gtk.Toolbar ();
+        toolbar.get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR);
+        toolbar.icon_size = Gtk.IconSize.MENU;
+        toolbar.valign = Gtk.Align.START;
+
+        var create_snapshot_button = new Gtk.ToolButton (null, null);
+        create_snapshot_button.clicked.connect (() => {
+            create_snapshot.begin ();
+        });
+        var icon_img = new Gtk.Image.from_icon_name ("list-add-symbolic", Gtk.IconSize.MENU);
+        create_snapshot_button.icon_widget = icon_img;
+        toolbar.add (create_snapshot_button);
+
+        snapshot_stack = new Gtk.Stack ();
+
+        snapshot_stack.transition_type = Gtk.StackTransitionType.CROSSFADE;
+        snapshot_list.selection_mode = Gtk.SelectionMode.NONE;
+        snapshot_list.set_size_request (-1, 250);
+        snapshot_list.set_sort_func (config_sort_func);
+        added_id = snapshot_list.add.connect (update_snapshot_stack_page);
+        removed_id = snapshot_list.remove.connect (update_snapshot_stack_page);
+        snapshot_stack.add (snapshot_list);
+
+        empty_label = new Gtk.Label (_("No snapshots created yet. Create one using the button below."));
+        empty_label.expand = true;
+        empty_label.halign = Gtk.Align.CENTER;
+        empty_label.valign = Gtk.Align.CENTER;
+        snapshot_stack.add (empty_label);
+
+        var snapshot_list_frame = new Gtk.Frame (null);
+        snapshot_list_frame.add (snapshot_stack);
+        snapshot_box.pack_start (snapshot_list_frame, true, true);
+        snapshot_box.pack_start (toolbar, true, true);
+        stack.add (snapshot_box);
+
+        // Activity page
+        activity_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12);
+        activity_box.valign = Gtk.Align.CENTER;
+        var activity_spinner = new Gtk.Spinner ();
+        activity_spinner.set_size_request (64, 64);
+        activity_spinner.start ();
+        activity_box.pack_start (activity_spinner, false, false);
+        activity_label.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL);
+        activity_box.pack_start (activity_label, false, false);
+        stack.add (activity_box);
+
+        SourceFunc on_flushed = () => {
+            if (added_id != 0) {
+                snapshot_list.disconnect (added_id);
+                added_id = 0;
+            }
+            if (removed_id != 0) {
+                snapshot_list.disconnect (removed_id);
+                removed_id = 0;
+            }
+
+            return false;
+        };
+        var change = new DeferredChange ("snapshots-disconnect", (owned) on_flushed);
+        add_deferred_change (change);
+
+        fetch_snapshots.begin ();
+    }
+
+    private async void fetch_snapshots () {
+        try {
+            var snapshots = yield machine.properties.get_snapshots (null);
+
+            foreach (var snapshot in snapshots) {
+                var row = new SnapshotListRow (snapshot, machine);
+                row.notify["activity-message"].connect (row_activity_changed);
+                snapshot_list.add (row);
+            }
+        } catch (GLib.Error e) {
+            warning ("Could not fetch snapshots: %s", e.message);
+        }
+
+        update_snapshot_stack_page ();
+    }
+
+    private int config_sort_func (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) {
+        try {
+            var conf1  = (row1 as SnapshotListRow).snapshot.get_config (0);
+            var conf2  = (row2 as SnapshotListRow).snapshot.get_config (0);
+            if (conf1.get_creation_time () < conf2.get_creation_time ())
+                return -1;
+            else
+                return 1;
+        } catch (GLib.Error e) {
+            warning ("Failed to fetch snapshot config: %s", e.message);
+            return 0;
+        }
+    }
+
+    private async void create_snapshot () {
+        if (machine.state == Machine.MachineState.RUNNING)
+            this.activity = _("Creating new snapshot…");
+
+        try {
+            var new_snapshot = yield machine.create_snapshot ();
+            var new_row = new SnapshotListRow (new_snapshot, machine);
+            new_row.notify["activity-message"].connect (row_activity_changed);
+            snapshot_list.add (new_row);
+        } catch (GLib.Error e) {
+            var msg = _("Failed to create snapshot of %s").printf (machine.name);
+            machine.window.notificationbar.display_error (msg);
+            warning (e.message);
+        }
+        this.activity = null;
+    }
+
+    private void row_activity_changed (GLib.Object source, GLib.ParamSpec param_spec) {
+        var row = source as SnapshotListRow;
+        this.activity = row.activity_message;
+    }
+
+    private void update_snapshot_stack_page () {
+        var num_snapshots = snapshot_list.get_children ().length ();
+        if (num_snapshots > 0)
+            snapshot_stack.visible_child = snapshot_list;
+        else
+            snapshot_stack.visible_child = empty_label;
+    }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]