[gnome-disk-utility/udisks2-port] First stab at a Create Partition dialog



commit 1e5e3790650ca634e2a048a9adc1daaeb0fdd2c1
Author: David Zeuthen <davidz redhat com>
Date:   Mon Nov 7 15:21:32 2011 -0500

    First stab at a Create Partition dialog
    
    Signed-off-by: David Zeuthen <davidz redhat com>

 data/ui/Makefile.am                       |    1 +
 data/ui/create-partition-dialog.ui        |  245 +++++++++++++++++++++++++++++
 src/palimpsest/Makefile.am                |   35 ++--
 src/palimpsest/gducreatepartitiondialog.c |  227 ++++++++++++++++++++++++++
 src/palimpsest/gducreatepartitiondialog.h |   38 +++++
 src/palimpsest/gduformatvolumedialog.c    |    2 +-
 src/palimpsest/gduvolumegrid.c            |   57 +++++++
 src/palimpsest/gduvolumegrid.h            |    2 +
 src/palimpsest/gduwindow.c                |   98 +++++++++++-
 src/palimpsest/gduwindow.h                |    3 +
 10 files changed, 687 insertions(+), 21 deletions(-)
---
diff --git a/data/ui/Makefile.am b/data/ui/Makefile.am
index f91b504..d6afa55 100644
--- a/data/ui/Makefile.am
+++ b/data/ui/Makefile.am
@@ -14,6 +14,7 @@ ui_DATA = 				\
 	unlock-device-dialog.ui		\
 	format-volume-dialog.ui		\
 	smart-dialog.ui			\
+	create-partition-dialog.ui	\
 	$(NULL)
 
 clean-local :
diff --git a/data/ui/create-partition-dialog.ui b/data/ui/create-partition-dialog.ui
new file mode 100644
index 0000000..170fd51
--- /dev/null
+++ b/data/ui/create-partition-dialog.ui
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkDialog" id="create-partition-dialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">12</property>
+    <property name="resizable">False</property>
+    <property name="modal">True</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">12</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button1">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button2">
+                <property name="label" translatable="yes">C_reate</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;big&gt;Create Partition&lt;/big&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="grid1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_left">12</property>
+                <property name="row_spacing">6</property>
+                <property name="column_spacing">10</property>
+                <child>
+                  <object class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Free Space _Following:</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">free-following-spinbutton</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Partition _Size:</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">size-spinbutton</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkScale" id="size-scale">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="adjustment">size-adjustment</property>
+                    <property name="restrict_to_fill_level">False</property>
+                    <property name="round_digits">1</property>
+                    <property name="draw_value">False</property>
+                    <property name="value_pos">bottom</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="GtkHBox" id="hbox1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkSpinButton" id="size-spinbutton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="tooltip_markup" translatable="yes">The size of the partition to create, in megabytes</property>
+                        <property name="invisible_char">â</property>
+                        <property name="activates_default">True</property>
+                        <property name="adjustment">size-adjustment</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">MB</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </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="GtkHBox" id="hbox2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkSpinButton" id="free-following-spinbutton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="tooltip_markup" translatable="yes">The free space following the partition, in megabytes</property>
+                        <property name="invisible_char">â</property>
+                        <property name="activates_default">True</property>
+                        <property name="adjustment">free-following-adjustment</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label6">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">MB</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </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>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">button1</action-widget>
+      <action-widget response="-5">button2</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkAdjustment" id="free-following-adjustment">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkAdjustment" id="size-adjustment">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+</interface>
diff --git a/src/palimpsest/Makefile.am b/src/palimpsest/Makefile.am
index fe37da6..a50bf08 100644
--- a/src/palimpsest/Makefile.am
+++ b/src/palimpsest/Makefile.am
@@ -22,23 +22,24 @@ enum_built_sources =							\
 
 BUILT_SOURCES += $(enum_built_sources)
 
-palimpsest_SOURCES = 					\
-				main.c			\
-	gdu.h						\
-	gduapplication.h	gduapplication.c	\
-	gdudevicetreemodel.h	gdudevicetreemodel.c	\
-	gdutypes.h					\
-	gduutils.h		gduutils.c		\
-	gduvolumegrid.h		gduvolumegrid.c		\
-	gduwindow.h		gduwindow.c		\
-	gduatasmartdialog.h	gduatasmartdialog.c	\
-	gducrypttabdialog.h	gducrypttabdialog.c	\
-	gdufilesystemdialog.h	gdufilesystemdialog.c	\
-	gdufstabdialog.h	gdufstabdialog.c	\
-	gdupartitiondialog.h	gdupartitiondialog.c	\
-	gduunlockdialog.h	gduunlockdialog.c	\
-	gduformatvolumedialog.h	gduformatvolumedialog.c	\
-	$(enum_built_sources)				\
+palimpsest_SOURCES = 							\
+					main.c				\
+	gdu.h								\
+	gduapplication.h		gduapplication.c		\
+	gdudevicetreemodel.h		gdudevicetreemodel.c		\
+	gdutypes.h							\
+	gduutils.h			gduutils.c			\
+	gduvolumegrid.h			gduvolumegrid.c			\
+	gduwindow.h			gduwindow.c			\
+	gduatasmartdialog.h		gduatasmartdialog.c		\
+	gducrypttabdialog.h		gducrypttabdialog.c		\
+	gdufilesystemdialog.h		gdufilesystemdialog.c		\
+	gdufstabdialog.h		gdufstabdialog.c		\
+	gdupartitiondialog.h		gdupartitiondialog.c		\
+	gduunlockdialog.h		gduunlockdialog.c		\
+	gduformatvolumedialog.h		gduformatvolumedialog.c		\
+	gducreatepartitiondialog.h	gducreatepartitiondialog.c	\
+	$(enum_built_sources)						\
 	$(NULL)
 
 palimpsest_CPPFLAGS = 					\
diff --git a/src/palimpsest/gducreatepartitiondialog.c b/src/palimpsest/gducreatepartitiondialog.c
new file mode 100644
index 0000000..33da57d
--- /dev/null
+++ b/src/palimpsest/gducreatepartitiondialog.c
@@ -0,0 +1,227 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "gduapplication.h"
+#include "gduwindow.h"
+#include "gducreatepartitiondialog.h"
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+
+typedef struct
+{
+  GduWindow *window;
+  UDisksObject *object;
+  UDisksBlock *block;
+  UDisksPartitionTable *table;
+  UDisksDrive *drive;
+  guint64 offset;
+  guint64 max_size;
+
+  GtkBuilder *builder;
+  GtkWidget *dialog;
+  GtkWidget *size_spinbutton;
+  GtkAdjustment *size_adjustment;
+  GtkAdjustment *free_following_adjustment;
+
+} CreatePartitionData;
+
+static void
+create_partition_data_free (CreatePartitionData *data)
+{
+  g_object_unref (data->window);
+  g_object_unref (data->object);
+  g_object_unref (data->block);
+  g_object_unref (data->table);
+  g_clear_object (&data->drive);
+  if (data->dialog != NULL)
+    {
+      gtk_widget_hide (data->dialog);
+      gtk_widget_destroy (data->dialog);
+    }
+  if (data->builder != NULL)
+    g_object_unref (data->builder);
+  g_free (data);
+}
+
+static void
+create_partition_update (CreatePartitionData *data)
+{
+  gboolean can_proceed = FALSE;
+
+  if (gtk_adjustment_get_value (data->size_adjustment) > 0)
+    can_proceed = TRUE;
+
+  gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK, can_proceed);
+}
+
+static void
+create_partition_property_changed (GObject     *object,
+                                   GParamSpec  *pspec,
+                                   gpointer     user_data)
+{
+  CreatePartitionData *data = user_data;
+  create_partition_update (data);
+}
+
+static void
+create_partition_populate (CreatePartitionData *data)
+{
+}
+
+static gboolean
+size_binding_func (GBinding     *binding,
+                   const GValue *source_value,
+                   GValue       *target_value,
+                   gpointer      user_data)
+{
+  CreatePartitionData *data = user_data;
+  g_value_set_double (target_value, data->max_size / (1000*1000) - g_value_get_double (source_value));
+  return TRUE;
+}
+
+
+static void
+create_partition_cb (GObject      *source_object,
+                     GAsyncResult *res,
+                     gpointer      user_data)
+{
+  CreatePartitionData *data = user_data;
+  GError *error;
+  gchar *created_partition_object_path;
+
+  error = NULL;
+  if (!udisks_partition_table_call_create_partition_finish (UDISKS_PARTITION_TABLE (source_object),
+                                                            &created_partition_object_path,
+                                                            res,
+                                                            &error))
+    {
+      gdu_window_show_error (data->window, _("Error creating partition"), error);
+      g_error_free (error);
+    }
+  else
+    {
+      UDisksObject *object;
+
+      udisks_client_settle (gdu_window_get_client (data->window));
+
+      object = udisks_client_get_object (gdu_window_get_client (data->window),
+                                         created_partition_object_path);
+      gdu_window_select_object (data->window, object);
+      g_object_unref (object);
+      g_free (created_partition_object_path);
+    }
+  create_partition_data_free (data);
+}
+
+void
+gdu_create_partition_dialog_show (GduWindow    *window,
+                                  UDisksObject *object,
+                                  guint64       offset,
+                                  guint64       max_size)
+{
+  CreatePartitionData *data;
+  guint64 max_size_mb;
+  gint response;
+
+  data = g_new0 (CreatePartitionData, 1);
+  data->window = g_object_ref (window);
+  data->object = g_object_ref (object);
+  data->block = udisks_object_get_block (object);
+  g_assert (data->block != NULL);
+  data->table = udisks_object_get_partition_table (object);
+  g_assert (data->table != NULL);
+  data->drive = udisks_client_get_drive_for_block (gdu_window_get_client (window), data->block);
+  data->offset = offset;
+  data->max_size = max_size;
+
+  data->dialog = gdu_application_new_widget (gdu_window_get_application (window),
+                                             "create-partition-dialog.ui",
+                                             "create-partition-dialog",
+                                             &data->builder);
+  data->size_spinbutton = GTK_WIDGET (gtk_builder_get_object (data->builder, "size-spinbutton"));
+  data->size_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (data->builder, "size-adjustment"));
+  g_signal_connect (data->size_adjustment, "notify::value", G_CALLBACK (create_partition_property_changed), data);
+  data->free_following_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (data->builder, "free-following-adjustment"));
+
+  /* The adjustments count MB, not bytes */
+  max_size_mb = max_size / (1000L*1000L);
+  gtk_adjustment_configure (data->size_adjustment,
+                            max_size_mb,
+                            0.0,                    /* lower */
+                            max_size_mb,            /* upper */
+                            100,                    /* step increment */
+                            1000,                   /* page increment */
+                            0.0);                   /* page_size */
+  gtk_adjustment_configure (data->free_following_adjustment,
+                            0,
+                            0.0,                    /* lower */
+                            max_size_mb,            /* upper */
+                            100,                    /* step increment */
+                            1000,                   /* page increment */
+                            0.0);                   /* page_size */
+
+  g_object_bind_property_full (data->size_adjustment,
+                               "value",
+                               data->free_following_adjustment,
+                               "value",
+                               G_BINDING_BIDIRECTIONAL,
+                               size_binding_func,
+                               size_binding_func,
+                               data,
+                               NULL);
+
+  gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (window));
+  gtk_dialog_set_default_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK);
+
+  create_partition_populate (data);
+  create_partition_update (data);
+
+  gtk_widget_show_all (data->dialog);
+  gtk_widget_grab_focus (data->size_spinbutton);
+
+  response = gtk_dialog_run (GTK_DIALOG (data->dialog));
+  if (response == GTK_RESPONSE_OK)
+    {
+      guint64 size;
+
+      gtk_widget_hide (data->dialog);
+
+      size = gtk_adjustment_get_value (data->size_adjustment) * 1000L * 1000L;
+      udisks_partition_table_call_create_partition (data->table,
+                                                    data->offset,
+                                                    size,
+                                                    "", /* use default type */
+                                                    "", /* use blank partition name */
+                                                    g_variant_new ("a{sv}", NULL), /* options */
+                                                    NULL, /* GCancellable */
+                                                    create_partition_cb,
+                                                    data);
+      return;
+    }
+
+  create_partition_data_free (data);
+}
diff --git a/src/palimpsest/gducreatepartitiondialog.h b/src/palimpsest/gducreatepartitiondialog.h
new file mode 100644
index 0000000..170f38b
--- /dev/null
+++ b/src/palimpsest/gducreatepartitiondialog.h
@@ -0,0 +1,38 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#ifndef __GDU_CREATE_PARTITION_DIALOG_H__
+#define __GDU_CREATE_PARTITION_DIALOG_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+void     gdu_create_partition_dialog_show (GduWindow    *window,
+                                           UDisksObject *object,
+                                           guint64       offset,
+                                           guint64       max_size);
+
+G_END_DECLS
+
+#endif /* __GDU_CREATE_PARTITION_DIALOG_H__ */
diff --git a/src/palimpsest/gduformatvolumedialog.c b/src/palimpsest/gduformatvolumedialog.c
index a86a74c..c4df199 100644
--- a/src/palimpsest/gduformatvolumedialog.c
+++ b/src/palimpsest/gduformatvolumedialog.c
@@ -225,7 +225,7 @@ format_cb (GObject      *source_object,
                                         res,
                                         &error))
     {
-      gdu_window_show_error (data->window, _("Error setting partition flags"), error);
+      gdu_window_show_error (data->window, _("Error formatting volume"), error);
       g_error_free (error);
     }
   format_volume_data_free (data);
diff --git a/src/palimpsest/gduvolumegrid.c b/src/palimpsest/gduvolumegrid.c
index 83756e5..96a9517 100644
--- a/src/palimpsest/gduvolumegrid.c
+++ b/src/palimpsest/gduvolumegrid.c
@@ -2099,6 +2099,63 @@ gdu_volume_grid_includes_object (GduVolumeGrid   *grid,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+static GridElement *
+find_element_for_object_list (GList         *elements,
+                              UDisksObject  *object)
+{
+  GridElement *ret = NULL;
+  GList *l;
+
+  for (l = elements; l != NULL; l = l->next)
+    {
+      GridElement *e = l->data;
+      if (e->object == object)
+        {
+          ret = e;
+          goto out;
+        }
+      ret = find_element_for_object_list (e->embedded_elements, object);
+      if (ret != NULL)
+        goto out;
+    }
+ out:
+  return ret;
+}
+
+static GridElement *
+find_element_for_object (GduVolumeGrid *grid,
+                         UDisksObject  *object)
+{
+  return find_element_for_object_list (grid->elements, object);
+}
+
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+gboolean
+gdu_volume_grid_select_object (GduVolumeGrid   *grid,
+                               UDisksObject    *block_object)
+{
+  gboolean ret = FALSE;
+  GridElement *elem;
+
+  g_return_val_if_fail (GDU_IS_VOLUME_GRID (grid), FALSE);
+  g_return_val_if_fail (G_IS_DBUS_OBJECT (block_object), FALSE);
+
+  elem = find_element_for_object (grid, block_object);
+  if (elem != NULL)
+    {
+      grid->selected = elem;
+      grid->focused = elem;
+      ret = TRUE;
+      g_signal_emit (grid, signals[CHANGED_SIGNAL], 0);
+      gtk_widget_queue_draw (GTK_WIDGET (grid));
+    }
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 static void
 on_client_changed (UDisksClient   *client,
                    gpointer        user_data)
diff --git a/src/palimpsest/gduvolumegrid.h b/src/palimpsest/gduvolumegrid.h
index 544561d..f94623a 100644
--- a/src/palimpsest/gduvolumegrid.h
+++ b/src/palimpsest/gduvolumegrid.h
@@ -46,6 +46,8 @@ void                      gdu_volume_grid_set_container_icon    (GduVolumeGrid
 
 gboolean                  gdu_volume_grid_includes_object       (GduVolumeGrid       *grid,
                                                                  UDisksObject        *object);
+gboolean                  gdu_volume_grid_select_object         (GduVolumeGrid       *grid,
+                                                                 UDisksObject        *block_object);
 
 GduVolumeGridElementType  gdu_volume_grid_get_selected_type     (GduVolumeGrid       *grid);
 UDisksObject             *gdu_volume_grid_get_selected_device   (GduVolumeGrid       *grid);
diff --git a/src/palimpsest/gduwindow.c b/src/palimpsest/gduwindow.c
index ef77c15..89dbb7f 100644
--- a/src/palimpsest/gduwindow.c
+++ b/src/palimpsest/gduwindow.c
@@ -44,6 +44,7 @@
 #include "gdupartitiondialog.h"
 #include "gduunlockdialog.h"
 #include "gduformatvolumedialog.h"
+#include "gducreatepartitiondialog.h"
 
 /* Keep in sync with tabs in palimpsest.ui file */
 typedef enum
@@ -327,10 +328,11 @@ update_for_show_flags (GduWindow *window,
   /* TODO: don't show the button bringing up the popup menu if it has no items */
 }
 
-static void
+static gboolean
 set_selected_object (GduWindow    *window,
                      UDisksObject *object)
 {
+  gboolean ret = FALSE;
   ShowFlags show_flags;
   GtkTreeIter iter;
 
@@ -346,6 +348,14 @@ set_selected_object (GduWindow    *window,
                                 NULL,
                                 FALSE);
       gtk_tree_path_free (path);
+      ret = TRUE;
+    }
+  else
+    {
+      if (object != NULL)
+        g_warning ("Cannot display object with object path %s",
+                   g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+      goto out;
     }
 
   show_flags = SHOW_FLAGS_NONE;
@@ -367,6 +377,8 @@ set_selected_object (GduWindow    *window,
       select_details_page (window, NULL, DETAILS_PAGE_NOT_SELECTED, &show_flags);
     }
   update_for_show_flags (window, show_flags);
+ out:
+  return ret;
 }
 
 static gboolean
@@ -618,6 +630,79 @@ on_device_tree_attach_disk_image_button_clicked (GtkToolButton *button,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+gboolean
+gdu_window_select_object (GduWindow    *window,
+                          UDisksObject *object)
+{
+  gboolean ret = FALSE;
+  UDisksPartition *partition;
+  UDisksPartitionTable *table = NULL;
+  UDisksDrive *drive = NULL;
+
+  partition = udisks_object_peek_partition (object);
+
+  /* if it's a partition, first select the object with the partition table */
+  if (partition != NULL)
+    {
+      UDisksObject *table_object = NULL;
+
+      table = udisks_client_get_partition_table (window->client, partition);
+      if (table == NULL)
+        goto out;
+      table_object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (table));
+      if (table_object == NULL)
+        goto out;
+
+      if (gdu_window_select_object (window, table_object))
+        {
+          /* then select the partition */
+          if (!gdu_volume_grid_select_object (GDU_VOLUME_GRID (window->volume_grid), object))
+            {
+              g_warning ("Error selecting partition %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+            }
+          else
+            {
+              ret = TRUE;
+            }
+        }
+    }
+  else
+    {
+      UDisksBlock *block;
+
+      block = udisks_object_peek_block (object);
+      if (block != NULL)
+        {
+          /* OK, if not a partition, either select the drive (if available) or the block device itself */
+          drive = udisks_client_get_drive_for_block (window->client, block);
+          if (drive != NULL)
+            {
+              UDisksObject *drive_object = NULL;
+              drive_object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (drive));
+              if (drive_object != NULL)
+                {
+                  if (!set_selected_object (window, drive_object))
+                    goto out;
+                  ret = TRUE;
+                }
+            }
+          else
+            {
+              if (!set_selected_object (window, object))
+                goto out;
+              ret = TRUE;
+            }
+        }
+    }
+
+ out:
+  g_clear_object (&drive);
+  g_clear_object (&table);
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 
 static void
 init_css (GduWindow *window)
@@ -2259,8 +2344,15 @@ static void
 on_devtab_action_partition_create_activated (GtkAction *action,
                                              gpointer   user_data)
 {
-  // GduWindow *window = GDU_WINDOW (user_data);
-  g_debug ("%s: TODO", G_STRFUNC);
+  GduWindow *window = GDU_WINDOW (user_data);
+  UDisksObject *object;
+
+  object = gdu_volume_grid_get_block_object (GDU_VOLUME_GRID (window->volume_grid));
+  g_assert (object != NULL);
+  gdu_create_partition_dialog_show (window,
+                                    object,
+                                    gdu_volume_grid_get_selected_offset (GDU_VOLUME_GRID (window->volume_grid)),
+                                    gdu_volume_grid_get_selected_size (GDU_VOLUME_GRID (window->volume_grid)));
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/palimpsest/gduwindow.h b/src/palimpsest/gduwindow.h
index 38d060e..778d213 100644
--- a/src/palimpsest/gduwindow.h
+++ b/src/palimpsest/gduwindow.h
@@ -47,6 +47,9 @@ gboolean        gdu_window_show_confirmation (GduWindow   *window,
                                               const gchar *secondary_message,
                                               const gchar *affirmative_verb);
 
+gboolean        gdu_window_select_object     (GduWindow    *window,
+                                              UDisksObject *object);
+
 
 G_END_DECLS
 



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