[gnome-boxes/wip/ui-files: 3/3] Move UnattendedInstaller UI setup to a .ui file
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes/wip/ui-files: 3/3] Move UnattendedInstaller UI setup to a .ui file
- Date: Wed, 18 Dec 2013 21:47:59 +0000 (UTC)
commit 2eac8d93e1ef4af9610bdba7fe2d76994e2a3c56
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Wed Dec 18 20:32:01 2013 +0000
Move UnattendedInstaller UI setup to a .ui file
data/gnome-boxes.gresource.xml | 1 +
data/ui/unattended-installer.ui | 223 ++++++++++++++++++++++++++++++++++++
po/POTFILES.in | 1 +
src/installer-media.vala | 2 +-
src/unattended-installer.vala | 241 ++++++++++++++-------------------------
src/util-app.vala | 10 ++
src/wizard.vala | 14 +-
7 files changed, 327 insertions(+), 165 deletions(-)
---
diff --git a/data/gnome-boxes.gresource.xml b/data/gnome-boxes.gresource.xml
index 00d5144..da0b345 100644
--- a/data/gnome-boxes.gresource.xml
+++ b/data/gnome-boxes.gresource.xml
@@ -5,5 +5,6 @@
<file>icons/boxes-arrow.svg</file>
<file>icons/boxes-dark.png</file>
<file>icons/boxes-gray.png</file>
+ <file preprocess="xml-stripblanks">ui/unattended-installer.ui</file>
</gresource>
</gresources>
diff --git a/data/ui/unattended-installer.ui b/data/ui/unattended-installer.ui
new file mode 100644
index 0000000..ef58393
--- /dev/null
+++ b/data/ui/unattended-installer.ui
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.9 -->
+
+ <object class="GtkBox" id="setup-vbox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">30</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <child>
+ <object class="GtkLabel" id="setup-label">
+ <property name="label" translatable="yes">Choose express install to automatically preconfigure the
box with optimal settings.</property>
+ <property name="visible">True</property>
+ <property name="wrap">True</property>
+ <property name="halign">start</property>
+ <property name="width-chars">30</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="setup-hbox">
+ <property name="visible">True</property>
+ <property name="valign">start</property>
+ <property name="margin">24</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">0</property>
+ <child>
+ <object class="GtkGrid" id="setup-grid">
+ <property name="visible">True</property>
+ <property name="column-homogeneous">False</property>
+ <property name="row-homogeneous">False</property>
+ <property name="column-spacing">0</property>
+ <property name="row-spacing">0</property>
+
+ <!-- First row -->
+ <child>
+ <object class="GtkLabel" id="express-label">
+ <!-- Translators: 'Express Install' means that the new box installation will be fully
automated, the
+ user won't be asked anything while it's performed. -->
+ <property name="label" translatable="yes">Express Install</property>
+ <property name="visible">True</property>
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="margin-right">10</property>
+ <property name="margin-bottom">15</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSwitch" id="express-toggle">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="margin-bottom">15</property>
+ <signal name="notify::active" handler="boxes_unattended_installer_on_express_toggled"/>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+
+ <!-- 2nd row (while user avatar spans over 2 rows) -->
+ <child>
+ <object class="GtkImage" id="user-avatar">
+ <property name="visible">True</property>
+ <property name="icon-name">avatar-default</property>
+ <property name="icon-size">0</property>
+ <property name="pixel-size">64</property>
+ <property name="margin-right">15</property>
+ <property name="valign">center</property>
+ <property name="halign">center</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ <property name="width">1</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="username-label">
+ <property name="label" translatable="yes">Username</property>
+ <property name="visible">True</property>
+ <property name="halign">end</property>
+ <property name="valign">baseline</property>
+ <property name="margin-right">10</property>
+ <property name="margin-bottom">10</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="username-entry">
+ <property name="visible">True</property>
+ <property name="visibility">True</property>
+ <property name="halign">fill</property>
+ <property name="valign">baseline</property>
+ <property name="margin-bottom">10</property>
+ <signal name="activate" handler="boxes_unattended_installer_on_username_entry_activated"/>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+
+ <!-- 3rd row -->
+ <child>
+ <object class="GtkLabel" id="password-label">
+ <property name="label" translatable="yes">Password</property>
+ <property name="visible">True</property>
+ <property name="halign">end</property>
+ <property name="valign">baseline</property>
+ <property name="margin-right">10</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="password-notebook">
+ <property name="visible">True</property>
+ <property name="show-tabs">False</property>
+ <property name="show-border">False</property>
+ <property name="halign">fill</property>
+ <property name="valign">center</property>
+ <child>
+ <object class="GtkButton" id="password-button">
+ <property name="label" translatable="yes">_Add Password</property>
+ <property name="visible">True</property>
+ <property name="use-underline">True</property>
+ <property name="valign">baseline</property>
+ <signal name="clicked" handler="boxes_unattended_installer_on_password_button_clicked"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="password-entry">
+ <property name="text"></property>
+ <property name="visible">True</property>
+ <property name="visibility">False</property>
+ <signal name="focus-out-event"
handler="boxes_unattended_installer_on_password_entry_focus_out"/>
+ <signal name="activate"
handler="boxes_unattended_installer_on_password_entry_activated"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+
+ <!-- 4th row -->
+ <child>
+ <object class="GtkLabel" id="product-key-label">
+ <property name="visible">False</property>
+ <property name="label" translatable="yes">Product Key</property>
+ <property name="margin-top">15</property>
+ <property name="margin-right">10</property>
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="product-key-entry">
+ <property name="visible">False</property>
+ <property name="visibility">True</property>
+ <property name="halign">fill</property>
+ <property name="valign">center</property>
+ <property name="margin-top">15</property>
+ <style>
+ <class name="boxes-product-key-entry"/>
+ </style>
+ <signal name="activate" handler="boxes_unattended_installer_on_key_entry_activated"/>
+ <signal name="insert-text" handler="boxes_unattended_installer_on_key_text_inserted"/>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 081ef60..eb19e9e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -34,3 +34,4 @@ src/vm-importer.vala
src/vnc-display.vala
src/wizard-source.vala
src/wizard.vala
+[type: gettext/glade]data/ui/unattended-installer.ui
diff --git a/src/installer-media.vala b/src/installer-media.vala
index af3b205..f638669 100644
--- a/src/installer-media.vala
+++ b/src/installer-media.vala
@@ -99,7 +99,7 @@ private class Boxes.InstallerMedia : GLib.Object {
eject_cdrom_media (domain);
}
- public virtual void populate_setup_vbox (Gtk.Box setup_vbox) {}
+ public virtual void populate_setup_box (Gtk.Box setup_box) {}
public virtual GLib.List<Pair<string,string>> get_vm_properties () {
var properties = new GLib.List<Pair<string,string>> ();
diff --git a/src/unattended-installer.vala b/src/unattended-installer.vala
index d7abaac..3325454 100644
--- a/src/unattended-installer.vala
+++ b/src/unattended-installer.vala
@@ -73,13 +73,10 @@ private class Boxes.UnattendedInstaller: InstallerMedia {
private GLib.List<UnattendedFile> secondary_unattended_files;
private UnattendedAvatarFile avatar_file;
- private Gtk.Grid setup_grid;
- private int setup_grid_n_rows;
-
- private Gtk.Label setup_label;
- private Gtk.Box setup_hbox;
+ private Gtk.Box setup_vbox;
private Gtk.Switch express_toggle;
private Gtk.Entry username_entry;
+ private Gtk.Notebook password_notebook;
private Gtk.Entry password_entry;
private Gtk.Entry key_entry;
@@ -282,13 +279,12 @@ private class Boxes.UnattendedInstaller: InstallerMedia {
base.setup_post_install_domain_config (domain);
}
- public override void populate_setup_vbox (Gtk.Box setup_vbox) {
- foreach (var child in setup_vbox.get_children ())
- setup_vbox.remove (child);
+ public override void populate_setup_box (Gtk.Box setup_box) {
+ foreach (var child in setup_box.get_children ())
+ setup_box.remove (child);
- setup_vbox.pack_start (setup_label, false, false);
- setup_vbox.pack_start (setup_hbox, false, false);
- setup_vbox.show_all ();
+ setup_box.add (setup_vbox);
+ setup_box.show ();
}
public override GLib.List<Pair> get_vm_properties () {
@@ -362,144 +358,89 @@ private class Boxes.UnattendedInstaller: InstallerMedia {
}
private void setup_ui () {
- setup_label = new Gtk.Label (_("Choose express install to automatically preconfigure the box with
optimal settings."));
- setup_label.wrap = true;
- setup_label.width_chars = 30;
- setup_label.halign = Gtk.Align.START;
- setup_hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
- setup_hbox.valign = Gtk.Align.START;
- setup_hbox.margin = 24;
-
- setup_grid = new Gtk.Grid ();
- setup_hbox.pack_start (setup_grid, false, false);
- setup_grid.column_spacing = 0;
- setup_grid.column_homogeneous = false;
- setup_grid.row_spacing = 0;
- setup_grid.row_homogeneous = true;
-
- // First row
- // Translators: 'Express Install' means that the new box installation will be fully automated, the
user
- // won't be asked anything while it's performed.
- var express_label = new Gtk.Label (_("Express Install"));
- express_label.margin_right = 10;
- express_label.margin_bottom = 15;
- express_label.halign = Gtk.Align.END;
- express_label.valign = Gtk.Align.CENTER;
- setup_grid.attach (express_label, 0, 0, 2, 1);
-
- express_toggle = new Gtk.Switch ();
+ var builder = load_ui ("unattended-installer.ui");
+
+ setup_vbox = builder.get_object ("setup-vbox") as Gtk.Box;
+
+ express_toggle = builder.get_object ("express-toggle") as Gtk.Switch;
express_toggle.active = !os_media.live;
- express_toggle.margin_bottom = 15;
- express_toggle.halign = Gtk.Align.START;
- express_toggle.valign = Gtk.Align.CENTER;
- express_toggle.notify["active"].connect (() => { notify_property ("ready-to-create"); });
- setup_grid.attach (express_toggle, 2, 0, 1, 1);
- setup_grid_n_rows++;
-
- // 2nd row (while user avatar spans over 2 rows)
- var avatar = new Gtk.Image.from_icon_name ("avatar-default", 0);
- avatar.pixel_size = 64;
- avatar.margin_right = 15;
- avatar.valign = Gtk.Align.CENTER;
- avatar.halign = Gtk.Align.CENTER;
- setup_grid.attach (avatar, 0, 1, 1, 2);
- avatar.show_all ();
+
+ var avatar = builder.get_object ("user-avatar") as Gtk.Image;
fetch_user_avatar.begin (avatar);
- var label = new Gtk.Label (_("Username"));
- label.margin_right = 10;
- label.margin_bottom = 10;
- label.halign = Gtk.Align.END;
- label.valign = Gtk.Align.BASELINE;
- setup_grid.attach (label, 1, 1, 1, 1);
- username_entry = create_input_entry (Environment.get_user_name ());
- username_entry.margin_bottom = 10;
- username_entry.halign = Gtk.Align.FILL;
- username_entry.valign = Gtk.Align.BASELINE;
- username_entry.activate.connect (() => {
- if (ready_for_express)
- user_wants_to_create ();
- else if (username != "" && product_key_format != null)
- key_entry.grab_focus (); // If username is provided, must be product key thats still not
provided
- });
+ username_entry = builder.get_object ("username-entry") as Gtk.Entry;
+ username_entry.text = Environment.get_user_name ();
- setup_grid.attach (username_entry, 2, 1, 1, 1);
- setup_grid_n_rows++;
-
- // 3rd row
- label = new Gtk.Label (_("Password"));
- label.margin_right = 10;
- label.halign = Gtk.Align.END;
- label.valign = Gtk.Align.BASELINE;
- setup_grid.attach (label, 1, 2, 1, 1);
-
- var notebook = new Gtk.Notebook ();
- notebook.show_tabs = false;
- notebook.show_border = false;
- notebook.halign = Gtk.Align.FILL;
- notebook.valign = Gtk.Align.CENTER;
- var button = new Gtk.Button.with_mnemonic (_("_Add Password"));
- button.visible = true;
- button.valign = Gtk.Align.BASELINE;
- notebook.append_page (button);
- password_entry = create_input_entry ("", false, false);
- notebook.append_page (password_entry);
- button.clicked.connect (() => {
- notebook.next_page ();
- password_entry.grab_focus ();
- });
- password_entry.focus_out_event.connect (() => {
- if (password_entry.text_length == 0)
- notebook.prev_page ();
- return false;
- });
- password_entry.activate.connect (() => {
- if (ready_for_express)
- user_wants_to_create ();
- else if (username == "")
- username_entry.grab_focus ();
- else if (product_key_format != null)
- key_entry.grab_focus ();
- });
- setup_grid.attach (notebook, 2, 2, 1, 1);
- setup_grid_n_rows++;
+ password_notebook = builder.get_object ("password-notebook") as Gtk.Notebook;
+ password_entry = builder.get_object ("password-entry") as Gtk.Entry;
- foreach (var child in setup_grid.get_children ())
- if ((child != express_label) && (child != express_toggle))
+ key_entry = builder.get_object ("product-key-entry") as Gtk.Entry;
+ if (product_key_format != null) {
+ var label = builder.get_object ("product-key-label") as Gtk.Label;
+ label.visible = true;
+
+ key_entry.visible = true;
+ key_entry.width_chars = product_key_format.length;
+ key_entry.max_length = product_key_format.length;
+ }
+
+ var setup_grid = builder.get_object ("setup-grid") as Gtk.Grid;
+ foreach (var child in setup_grid.get_children ()) {
+ var buildable = (child as Gtk.Buildable);
+
+ if ((buildable.get_name () != "express-label") && (buildable.get_name () != "express-toggle"))
express_toggle.bind_property ("active", child, "sensitive", BindingFlags.SYNC_CREATE);
+ }
- if (product_key_format == null)
- return;
+ builder.connect_signals (this);
+ }
- label = new Gtk.Label (_("Product Key"));
- label.margin_top = 15;
- label.margin_right = 10;
- label.halign = Gtk.Align.END;
- label.valign = Gtk.Align.CENTER;
- setup_grid.attach (label, 0, setup_grid_n_rows, 2, 1);
- express_toggle.bind_property ("active", label, "sensitive", 0);
-
- key_entry = create_input_entry ("");
- key_entry.width_chars = product_key_format.length;
- key_entry.max_length = product_key_format.length;
- key_entry.margin_top = 15;
- key_entry.halign = Gtk.Align.FILL;
- key_entry.valign = Gtk.Align.CENTER;
- key_entry.get_style_context ().add_class ("boxes-product-key-entry");
- setup_grid.attach (key_entry, 2, setup_grid_n_rows, 1, 1);
- express_toggle.bind_property ("active", key_entry, "sensitive", 0);
- key_entry.activate.connect (() => {
- if (ready_for_express)
- user_wants_to_create ();
- else if (key_entry.text_length == product_key_format.length)
- username_entry.grab_focus (); // If product key is provided, must be username thats still
not provided.
- });
- setup_grid_n_rows++;
+ [CCode (instance_pos = -1)]
+ protected void on_express_toggled () {
+ notify_property ("ready-to-create");
+ }
+
+ [CCode (instance_pos = -1)]
+ protected void on_username_entry_activated () {
+ if (ready_for_express)
+ user_wants_to_create ();
+ else if (username != "" && product_key_format != null)
+ key_entry.grab_focus (); // If username is provided, must be product key thats still not provided
+ }
+
+ [CCode (instance_pos = -1)]
+ protected void on_password_button_clicked () {
+ password_notebook.next_page ();
+ password_entry.grab_focus ();
+ }
+
+ [CCode (instance_pos = -1)]
+ protected bool on_password_entry_focus_out () {
+ if (password_entry.text_length == 0)
+ password_notebook.prev_page ();
+ return false;
+ }
+
+ [CCode (instance_pos = -1)]
+ protected void on_password_entry_activated () {
+ if (ready_for_express)
+ user_wants_to_create ();
+ else if (username == "")
+ username_entry.grab_focus ();
+ else if (product_key_format != null)
+ key_entry.grab_focus ();
+ }
- key_inserted_id = key_entry.insert_text.connect (on_key_text_inserted);
+ [CCode (instance_pos = -1)]
+ protected void on_key_entry_activated (Gtk.Entry key_entry) {
+ if (ready_for_express)
+ user_wants_to_create ();
+ else if (key_entry.text_length == product_key_format.length)
+ username_entry.grab_focus (); // If product key is provided, must be username thats still not
provided.
}
- private void on_key_text_inserted (string text, int text_length, ref int position) {
+ [CCode (instance_pos = -1)]
+ protected void on_key_text_inserted (Gtk.Entry key_entry, string text, int text_length, ref int
position) {
var result = "";
for (uint i = 0, j = position; i < text_length && j < product_key_format.length; ) {
@@ -604,20 +545,6 @@ private class Boxes.UnattendedInstaller: InstallerMedia {
secondary_unattended_files.append (file);
}
- private Gtk.Entry create_input_entry (string text, bool mandatory = true, bool visibility = true) {
- var entry = new Gtk.Entry ();
- entry.visibility = visibility;
- entry.visible = true;
- entry.text = text;
-
- if (mandatory)
- entry.notify["text"].connect (() => {
- notify_property ("ready-to-create");
- });
-
- return entry;
- }
-
private async void create_disk_image (Cancellable? cancellable) throws GLib.Error {
var template_path = get_unattended ("disk.img");
var template_file = File.new_for_path (template_path);
diff --git a/src/util-app.vala b/src/util-app.vala
index 2c33f1d..1be7111 100644
--- a/src/util-app.vala
+++ b/src/util-app.vala
@@ -20,6 +20,16 @@ namespace Boxes {
return new Gdk.Pixbuf.from_resource ("/org/gnome/Boxes/icons/" + asset);
}
+ public Gtk.Builder load_ui (string ui) {
+ var builder = new Gtk.Builder ();
+ try {
+ builder.add_from_resource ("/org/gnome/Boxes/ui/".concat (ui, null));
+ } catch (GLib.Error e) {
+ error ("Failed to load UI file '%s': %s", ui, e.message);
+ }
+ return builder;
+ }
+
public Clutter.Color gdk_rgba_to_clutter_color (Gdk.RGBA gdk_rgba) {
Clutter.Color color = {
(uint8) (gdk_rgba.red * 255).clamp (0, 255),
diff --git a/src/wizard.vala b/src/wizard.vala
index 90aedf2..30d7fec 100644
--- a/src/wizard.vala
+++ b/src/wizard.vala
@@ -28,7 +28,7 @@ private class Boxes.Wizard: Boxes.UI {
private Gtk.ProgressBar prep_progress;
private Gtk.Label prep_media_label;
private Gtk.Label prep_status_label;
- private Gtk.Box setup_vbox;
+ private Gtk.Box setup_box;
private Gtk.Label review_label;
private Gtk.Box nokvm_box;
private Gtk.Image installer_image;
@@ -348,7 +348,7 @@ private class Boxes.Wizard: Boxes.UI {
vm_creator.install_media.bind_property ("ready-to-create",
continue_button, "sensitive",
BindingFlags.SYNC_CREATE);
- vm_creator.install_media.populate_setup_vbox (setup_vbox);
+ vm_creator.install_media.populate_setup_box (setup_box);
vm_creator.install_media.user_wants_to_create.connect (() => {
if (vm_creator.install_media.ready_to_create)
page = page + 1;
@@ -624,11 +624,11 @@ private class Boxes.Wizard: Boxes.UI {
vbox.show_all ();
/* Setup */
- setup_vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 30);
- setup_vbox.valign = Gtk.Align.CENTER;
- setup_vbox.halign = Gtk.Align.CENTER;
- add_step (setup_vbox, _("Setup"), WizardPage.SETUP);
- setup_vbox.show_all ();
+ setup_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
+ setup_box.valign = Gtk.Align.CENTER;
+ setup_box.halign = Gtk.Align.CENTER;
+ add_step (setup_box, _("Setup"), WizardPage.SETUP);
+ setup_box.show_all ();
/* Review */
vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]