[gnome-disk-utility/udisks2-port] Support creating MBR partitions
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility/udisks2-port] Support creating MBR partitions
- Date: Thu, 10 Nov 2011 19:50:40 +0000 (UTC)
commit 9da2d20dd7a79c36304e36f944a2970014562b1d
Author: David Zeuthen <davidz redhat com>
Date: Thu Nov 10 14:49:11 2011 -0500
Support creating MBR partitions
... this entails properly handling a lot of edge-cases because MBR is
so crappy and comes with extended/logical partitions
http://people.freedesktop.org/~david/gdu2-dos-partition-crap.png
http://people.freedesktop.org/~david/gdu2-infobar-three-primary-and-free-space.png
http://people.freedesktop.org/~david/gdu2-infobar-mbr-four-primary-and-free-space.png
http://people.freedesktop.org/~david/gdu2-create-extended-partition.png
Signed-off-by: David Zeuthen <davidz redhat com>
data/ui/create-partition-dialog.ui | 190 ++++++++++++++++++----------
data/ui/filesystem-create.ui | 37 ++----
src/palimpsest/gducreatefilesystemwidget.c | 184 +++++++++++++++++++++++----
src/palimpsest/gducreatefilesystemwidget.h | 3 +-
src/palimpsest/gducreatepartitiondialog.c | 160 +++++++++++++++++++++---
src/palimpsest/gduformatvolumedialog.c | 4 +-
src/palimpsest/gduvolumegrid.c | 1 +
7 files changed, 442 insertions(+), 137 deletions(-)
---
diff --git a/data/ui/create-partition-dialog.ui b/data/ui/create-partition-dialog.ui
index 221f7ca..c0e7228 100644
--- a/data/ui/create-partition-dialog.ui
+++ b/data/ui/create-partition-dialog.ui
@@ -62,6 +62,78 @@
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
+ <object class="GtkBox" id="infobar-vbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkInfoBar" id="infobar-dos-error">
+ <property name="message_type">error</property>
+ <child internal-child="content_area">
+ <object class="GtkBox" id="infobar1-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="infobar1-label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes"><b>Error:</b> Cannot create a new partition. There are already four primary partitions.</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>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkInfoBar" id="infobar-dos-warning">
+ <property name="message_type">warning</property>
+ <child internal-child="content_area">
+ <object class="GtkBox" id="infobar2-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="infobar2-label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes"><b>Warning:</b> This is the last primary partition that can be created.</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>
+ </object>
+ </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">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -72,32 +144,15 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
- <object class="GtkGrid" id="grid1">
+ <object class="GtkBox" id="box2">
<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="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>
+ <property name="orientation">vertical</property>
<child>
<object class="GtkScale" id="size-scale">
<property name="visible">True</property>
@@ -105,35 +160,51 @@
<property name="hexpand">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">4</property>
- <property name="height">1</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox1">
+ <object class="GtkBox" id="box3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<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="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkSpinButton" id="size-spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="has_tooltip">True</property>
<property name="tooltip_markup" translatable="yes">The size of the partition to create, in megabytes</property>
+ <property name="tooltip_text" 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="invisible_char_set">True</property>
<property name="adjustment">size-adjustment</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
@@ -146,39 +217,25 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">24</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="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</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="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="margin_left">24</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">2</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>
@@ -194,7 +251,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">4</property>
</packing>
</child>
<child>
@@ -207,22 +264,21 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">5</property>
</packing>
</child>
</object>
<packing>
- <property name="left_attach">3</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
+ <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="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
@@ -236,7 +292,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
<child>
@@ -252,7 +308,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
</object>
diff --git a/data/ui/filesystem-create.ui b/data/ui/filesystem-create.ui
index 7ecf98e..3bd8249 100644
--- a/data/ui/filesystem-create.ui
+++ b/data/ui/filesystem-create.ui
@@ -26,29 +26,7 @@
</packing>
</child>
<child>
- <object class="GtkComboBoxText" id="type-combobox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="has_tooltip">True</property>
- <property name="tooltip_markup" translatable="yes">The kind of filesystem to create. Choose <b>Custom</b> to specify a custom filesystem type such as <i>btrfs</i>, <i>xfs</i> or <i>swap</i></property>
- <property name="tooltip_text" translatable="yes">The kind of filesystem to create. Choose Custom to specify a custom filesystem type such as btrfs, xfs or swap</property>
- <items>
- <item translatable="yes">Compatible with all systems and devices (FAT)</item>
- <item translatable="yes">Compatible with most systems (NTFS)</item>
- <item translatable="yes">Compatible with Linux systems (ext4)</item>
- <item translatable="yes">Encrypted, compatible with Linux systems (LUKS, ext4)</item>
- <item translatable="yes">Custom</item>
- </items>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
+ <object class="GtkLabel" id="name-label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
@@ -214,6 +192,19 @@
</packing>
</child>
<child>
+ <object class="GtkComboBox" id="type-combobox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="id_column">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
<placeholder/>
</child>
<child>
diff --git a/src/palimpsest/gducreatefilesystemwidget.c b/src/palimpsest/gducreatefilesystemwidget.c
index e368a93..f34c2ae 100644
--- a/src/palimpsest/gducreatefilesystemwidget.c
+++ b/src/palimpsest/gducreatefilesystemwidget.c
@@ -37,12 +37,14 @@ struct _GduCreateFilesystemWidget
{
GtkVBox parent;
- GduApplication *application;
- UDisksDrive *drive;
+ GduApplication *application;
+ UDisksDrive *drive;
+ gchar **additional_fstypes;
GtkBuilder *builder;
GtkWidget *grid;
GtkWidget *type_combobox;
+ GtkWidget *name_label;
GtkWidget *name_entry;
GtkWidget *filesystem_label;
GtkWidget *filesystem_entry;
@@ -68,12 +70,21 @@ enum
PROP_0,
PROP_APPLICATION,
PROP_DRIVE,
+ PROP_ADDITIONAL_FSTYPES,
PROP_FSTYPE,
PROP_NAME,
PROP_PASSPHRASE,
PROP_HAS_INFO
};
+enum
+{
+ MODEL_COLUMN_ID,
+ MODEL_COLUMN_MARKUP,
+ MODEL_COLUMN_SEPARATOR,
+ MODEL_N_COLUMNS,
+};
+
G_DEFINE_TYPE (GduCreateFilesystemWidget, gdu_create_filesystem_widget, GTK_TYPE_VBOX)
static void
@@ -83,6 +94,7 @@ gdu_create_filesystem_widget_finalize (GObject *object)
g_object_unref (widget->application);
g_clear_object (&widget->drive);
+ g_strfreev (widget->additional_fstypes);
g_free (widget->fstype);
g_free (widget->name);
g_free (widget->passphrase);
@@ -108,6 +120,10 @@ gdu_create_filesystem_widget_get_property (GObject *object,
g_value_set_object (value, widget->drive);
break;
+ case PROP_ADDITIONAL_FSTYPES:
+ g_value_set_boxed (value, widget->additional_fstypes);
+ break;
+
case PROP_FSTYPE:
g_value_set_string (value, widget->fstype);
break;
@@ -148,6 +164,10 @@ gdu_create_filesystem_widget_set_property (GObject *object,
widget->drive = g_value_dup_object (value);
break;
+ case PROP_ADDITIONAL_FSTYPES:
+ widget->additional_fstypes = g_value_dup_boxed (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -159,34 +179,36 @@ gdu_create_filesystem_widget_set_property (GObject *object,
static void
update (GduCreateFilesystemWidget *widget)
{
+ gboolean show_name_widgets = TRUE;
gboolean show_filesystem_widgets = FALSE;
gboolean show_passphrase_widgets = FALSE;
gboolean has_info = FALSE;
const gchar *fstype = NULL;
const gchar *name = NULL;
const gchar *passphrase = NULL;
+ const gchar *id;
name = gtk_entry_get_text (GTK_ENTRY (widget->name_entry));
passphrase = gtk_entry_get_text (GTK_ENTRY (widget->passphrase_entry));
- switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget->type_combobox)))
+ id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (widget->type_combobox));
+ if (g_strcmp0 (id, "vfat") == 0)
{
- case 0:
fstype = "vfat";
has_info = TRUE;
- break;
-
- case 1:
+ }
+ else if (g_strcmp0 (id, "ntfs") == 0)
+ {
fstype = "ntfs";
has_info = TRUE;
- break;
-
- case 2:
+ }
+ else if (g_strcmp0 (id, "ext4") == 0)
+ {
fstype = "ext4";
has_info = TRUE;
- break;
-
- case 3:
+ }
+ else if (g_strcmp0 (id, "luks+ext4") == 0)
+ {
fstype = "ext4";
/* Encrypted, compatible with Linux (LUKS + ext4) */
show_passphrase_widgets = TRUE;
@@ -198,9 +220,9 @@ update (GduCreateFilesystemWidget *widget)
has_info = TRUE;
}
}
- break;
-
- case 4:
+ }
+ else if (g_strcmp0 (id, "custom") == 0)
+ {
/* Custom */
show_filesystem_widgets = TRUE;
if (strlen (gtk_entry_get_text (GTK_ENTRY (widget->filesystem_entry))) > 0)
@@ -211,11 +233,24 @@ update (GduCreateFilesystemWidget *widget)
*/
has_info = TRUE;
}
- break;
+ }
+ else
+ {
+ /* Additional FS */
+ show_name_widgets = FALSE;
+ fstype = id;
+ has_info = TRUE;
+ }
- default:
- g_assert_not_reached ();
- break;
+ if (show_name_widgets)
+ {
+ gtk_widget_show (widget->name_label);
+ gtk_widget_show (widget->name_entry);
+ }
+ else
+ {
+ gtk_widget_hide (widget->name_label);
+ gtk_widget_hide (widget->name_entry);
}
if (show_filesystem_widgets)
@@ -305,25 +340,109 @@ is_flash (UDisksDrive *drive)
return ret;
}
+static gboolean
+separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gboolean is_separator;
+ gtk_tree_model_get (model, iter,
+ MODEL_COLUMN_SEPARATOR, &is_separator,
+ -1);
+ return is_separator;
+}
+
static void
-set_defaults (GduCreateFilesystemWidget *widget)
+populate (GduCreateFilesystemWidget *widget)
{
+ GtkListStore *model;
+ GtkCellRenderer *renderer;
+ gchar *s;
+
+ model = gtk_list_store_new (MODEL_N_COLUMNS,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN);
+ gtk_combo_box_set_model (GTK_COMBO_BOX (widget->type_combobox), GTK_TREE_MODEL (model));
+ g_object_unref (model);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget->type_combobox), renderer, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget->type_combobox), renderer,
+ "markup", MODEL_COLUMN_MARKUP,
+ NULL);
+
+ gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (widget->type_combobox),
+ separator_func,
+ widget,
+ NULL); /* GDestroyNotify */
+
+ s = g_strdup_printf ("%s <span foreground=\"#555555\" size=\"small\">(%s)</span>",
+ _("Compatible with all systems and devices"),
+ _("FAT"));
+ gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+ MODEL_COLUMN_ID, "vfat", MODEL_COLUMN_MARKUP, s, -1);
+ g_free (s);
+ s = g_strdup_printf ("%s <span foreground=\"#555555\" size=\"small\">(%s)</span>",
+ _("Compatible with most systems"),
+ _("NTFS"));
+ gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+ MODEL_COLUMN_ID, "ntfs", MODEL_COLUMN_MARKUP, s, -1);
+ g_free (s);
+ s = g_strdup_printf ("%s <span foreground=\"#555555\" size=\"small\">(%s)</span>",
+ _("Compatible with Linux systems"),
+ _("Ext4"));
+ gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+ MODEL_COLUMN_ID, "ext4", MODEL_COLUMN_MARKUP, s, -1);
+ g_free (s);
+ s = g_strdup_printf ("%s <span foreground=\"#555555\" size=\"small\">(%s)</span>",
+ _("Encrypted, compatible with Linux systems"),
+ _("LUKS + Ext4"));
+ gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+ MODEL_COLUMN_ID, "luks+ext4", MODEL_COLUMN_MARKUP, s, -1);
+ g_free (s);
+ s = g_strdup_printf ("%s <span foreground=\"#555555\" size=\"small\">(%s)</span>",
+ _("Custom"),
+ _("Enter filesystem type"));
+ gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+ MODEL_COLUMN_ID, "custom", MODEL_COLUMN_MARKUP, s, -1);
+ g_free (s);
+
+ /* Add from additional_types */
+ if (widget->additional_fstypes != NULL && widget->additional_fstypes[0] != NULL)
+ {
+ guint n;
+
+ /* separator */
+ gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+ MODEL_COLUMN_SEPARATOR, TRUE, -1);
+
+ for (n = 0; widget->additional_fstypes[n] != NULL; n += 2)
+ {
+ const gchar *fstype = widget->additional_fstypes[n];
+ const gchar *name = widget->additional_fstypes[n+1];
+ gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+ MODEL_COLUMN_ID, fstype,
+ MODEL_COLUMN_MARKUP, name, -1);
+ }
+ }
+
/* Default to FAT or NTFS for removable drives... Ext4 otherwise */
if (widget->drive != NULL && udisks_drive_get_removable (widget->drive))
{
/* default FAT for flash and disks/media smaller than 20G (assumed to be flash cards) */
if (is_flash (widget->drive) || udisks_drive_get_size (widget->drive) < 20L * 1000L*1000L*1000L)
{
- gtk_combo_box_set_active (GTK_COMBO_BOX (widget->type_combobox), 0); /* FAT */
+ gtk_combo_box_set_active_id (GTK_COMBO_BOX (widget->type_combobox), "vfat");
}
else
{
- gtk_combo_box_set_active (GTK_COMBO_BOX (widget->type_combobox), 1); /* NTFS */
+ gtk_combo_box_set_active_id (GTK_COMBO_BOX (widget->type_combobox), "ntfs");
}
}
else
{
- gtk_combo_box_set_active (GTK_COMBO_BOX (widget->type_combobox), 2); /* Ext4 */
+ gtk_combo_box_set_active_id (GTK_COMBO_BOX (widget->type_combobox), "ext4");
}
/* Translators: this is the default name for the filesystem */
@@ -357,6 +476,7 @@ gdu_create_filesystem_widget_constructed (GObject *object)
widget->grid = GTK_WIDGET (gtk_builder_get_object (widget->builder, "filesystem-create-grid"));
widget->type_combobox = GTK_WIDGET (gtk_builder_get_object (widget->builder, "type-combobox"));
g_signal_connect (widget->type_combobox, "notify::active", G_CALLBACK (on_property_changed), widget);
+ widget->name_label = GTK_WIDGET (gtk_builder_get_object (widget->builder, "name-label"));
widget->name_entry = GTK_WIDGET (gtk_builder_get_object (widget->builder, "name-entry"));
g_signal_connect (widget->name_entry, "notify::text", G_CALLBACK (on_property_changed), widget);
widget->filesystem_label = GTK_WIDGET (gtk_builder_get_object (widget->builder, "filesystem-label"));
@@ -375,7 +495,7 @@ gdu_create_filesystem_widget_constructed (GObject *object)
gtk_widget_reparent (widget->grid, GTK_WIDGET (widget));
gtk_widget_destroy (dummy_window);
- set_defaults (widget);
+ populate (widget);
update (widget);
if (G_OBJECT_CLASS (gdu_create_filesystem_widget_parent_class)->constructed != NULL)
@@ -409,6 +529,14 @@ gdu_create_filesystem_widget_class_init (GduCreateFilesystemWidgetClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_ADDITIONAL_FSTYPES,
+ g_param_spec_boxed ("additional-fstypes", NULL, NULL,
+ G_TYPE_STRV,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
g_object_class_install_property (gobject_class, PROP_FSTYPE,
g_param_spec_string ("fstype", NULL, NULL,
NULL,
@@ -440,13 +568,15 @@ gdu_create_filesystem_widget_init (GduCreateFilesystemWidget *widget)
}
GtkWidget *
-gdu_create_filesystem_widget_new (GduApplication *application,
- UDisksDrive *drive)
+gdu_create_filesystem_widget_new (GduApplication *application,
+ UDisksDrive *drive,
+ const gchar * const *additional_fstypes)
{
g_return_val_if_fail (GDU_IS_APPLICATION (application), NULL);
return GTK_WIDGET (g_object_new (GDU_TYPE_CREATE_FILESYSTEM_WIDGET,
"application", application,
"drive", drive,
+ "additional-fstypes", additional_fstypes,
NULL));
}
diff --git a/src/palimpsest/gducreatefilesystemwidget.h b/src/palimpsest/gducreatefilesystemwidget.h
index b72a641..e6bbadf 100644
--- a/src/palimpsest/gducreatefilesystemwidget.h
+++ b/src/palimpsest/gducreatefilesystemwidget.h
@@ -34,7 +34,8 @@ G_BEGIN_DECLS
GType gdu_create_filesystem_widget_get_type (void) G_GNUC_CONST;
GtkWidget* gdu_create_filesystem_widget_new (GduApplication *application,
- UDisksDrive *drive);
+ UDisksDrive *drive,
+ const gchar * const *addtional_fstypes);
const gchar *gdu_create_filesystem_widget_get_name (GduCreateFilesystemWidget *widget);
const gchar *gdu_create_filesystem_widget_get_fstype (GduCreateFilesystemWidget *widget);
const gchar *gdu_create_filesystem_widget_get_passphrase (GduCreateFilesystemWidget *widget);
diff --git a/src/palimpsest/gducreatepartitiondialog.c b/src/palimpsest/gducreatepartitiondialog.c
index 41476cc..644b19f 100644
--- a/src/palimpsest/gducreatepartitiondialog.c
+++ b/src/palimpsest/gducreatepartitiondialog.c
@@ -44,13 +44,14 @@ typedef struct
GtkBuilder *builder;
GtkWidget *dialog;
+ GtkWidget *dos_error_infobar;
+ GtkWidget *dos_warning_infobar;
GtkWidget *size_spinbutton;
GtkAdjustment *size_adjustment;
GtkAdjustment *free_following_adjustment;
GtkWidget *contents_box;
GtkWidget *create_filesystem_widget;
-
} CreatePartitionData;
static void
@@ -71,15 +72,103 @@ create_partition_data_free (CreatePartitionData *data)
g_free (data);
}
+static guint
+count_primary_dos_partitions (CreatePartitionData *data)
+{
+ GList *partitions, *l;
+ guint ret = 0;
+ partitions = udisks_client_get_partitions (gdu_window_get_client (data->window), data->table);
+ for (l = partitions; l != NULL; l = l->next)
+ {
+ UDisksPartition *partition = UDISKS_PARTITION (l->data);
+ if (!udisks_partition_get_is_contained (partition))
+ ret += 1;
+ }
+ g_list_foreach (partitions, (GFunc) g_object_unref, NULL);
+ g_list_free (partitions);
+ return ret;
+}
+
+static gboolean
+have_dos_extended (CreatePartitionData *data)
+{
+ GList *partitions, *l;
+ gboolean ret = FALSE;
+ partitions = udisks_client_get_partitions (gdu_window_get_client (data->window), data->table);
+ for (l = partitions; l != NULL; l = l->next)
+ {
+ UDisksPartition *partition = UDISKS_PARTITION (l->data);
+ if (udisks_partition_get_is_container (partition))
+ {
+ ret = TRUE;
+ break;
+ }
+ }
+ g_list_foreach (partitions, (GFunc) g_object_unref, NULL);
+ g_list_free (partitions);
+ return ret;
+}
+
+static gboolean
+is_inside_dos_extended (CreatePartitionData *data, guint64 offset)
+{
+ GList *partitions, *l;
+ gboolean ret = FALSE;
+ partitions = udisks_client_get_partitions (gdu_window_get_client (data->window), data->table);
+ for (l = partitions; l != NULL; l = l->next)
+ {
+ UDisksPartition *partition = UDISKS_PARTITION (l->data);
+ if (udisks_partition_get_is_container (partition))
+ {
+ if (offset >= udisks_partition_get_offset (partition) &&
+ offset < udisks_partition_get_offset (partition) + udisks_partition_get_size (partition))
+ {
+ ret = TRUE;
+ break;
+ }
+ }
+ }
+ g_list_foreach (partitions, (GFunc) g_object_unref, NULL);
+ g_list_free (partitions);
+ return ret;
+}
+
static void
create_partition_update (CreatePartitionData *data)
{
gboolean can_proceed = FALSE;
+ gboolean show_dos_error = FALSE;
+ gboolean show_dos_warning = FALSE;
+
+ /* MBR Partitioning sucks. So if we're trying to create a primary partition, then
+ *
+ * - Show WARNING if trying to create 4th primary partition
+ * - Show ERROR if there are already 4 primary partitions
+ */
+ if (g_strcmp0 (udisks_partition_table_get_type_ (data->table), "dos") == 0)
+ {
+ if (!is_inside_dos_extended (data, data->offset))
+ {
+ guint num_primary;
+ num_primary = count_primary_dos_partitions (data);
+ if (num_primary == 4)
+ show_dos_error = TRUE;
+ else if (num_primary == 3)
+ show_dos_warning = TRUE;
+ }
+ }
if (gtk_adjustment_get_value (data->size_adjustment) > 0 &&
gdu_create_filesystem_widget_get_has_info (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget)))
can_proceed = TRUE;
+ if (show_dos_error)
+ can_proceed = FALSE;
+
+ if (!show_dos_warning)
+ gtk_widget_set_no_show_all (data->dos_warning_infobar, TRUE);
+ if (!show_dos_error)
+ gtk_widget_set_no_show_all (data->dos_error_infobar, TRUE);
gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK, can_proceed);
}
@@ -172,23 +261,31 @@ create_partition_cb (GObject *source_object,
name = gdu_create_filesystem_widget_get_name (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
passphrase = gdu_create_filesystem_widget_get_passphrase (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
- g_variant_builder_init (&options_builder, G_VARIANT_TYPE_VARDICT);
- if (name != NULL && strlen (name) > 0)
- g_variant_builder_add (&options_builder, "{sv}", "label", g_variant_new_string (name));
- if (!(g_strcmp0 (fstype, "vfat") == 0 || g_strcmp0 (fstype, "ntfs") == 0))
+ /* Not meaningful to create a filesystem if requested to create an extended partition */
+ if (g_strcmp0 (fstype, "dos_extended") == 0)
+ {
+ create_partition_data_free (data);
+ }
+ else
{
- /* TODO: need a better way to determine if this should be TRUE */
- g_variant_builder_add (&options_builder, "{sv}", "take-ownership", g_variant_new_boolean (TRUE));
+ g_variant_builder_init (&options_builder, G_VARIANT_TYPE_VARDICT);
+ if (name != NULL && strlen (name) > 0)
+ g_variant_builder_add (&options_builder, "{sv}", "label", g_variant_new_string (name));
+ if (!(g_strcmp0 (fstype, "vfat") == 0 || g_strcmp0 (fstype, "ntfs") == 0))
+ {
+ /* TODO: need a better way to determine if this should be TRUE */
+ g_variant_builder_add (&options_builder, "{sv}", "take-ownership", g_variant_new_boolean (TRUE));
+ }
+ if (passphrase != NULL && strlen (passphrase) > 0)
+ g_variant_builder_add (&options_builder, "{sv}", "encrypt.passphrase", g_variant_new_string (passphrase));
+
+ udisks_block_call_format (partition_block,
+ fstype,
+ g_variant_builder_end (&options_builder),
+ NULL, /* GCancellable */
+ format_cb,
+ data);
}
- if (passphrase != NULL && strlen (passphrase) > 0)
- g_variant_builder_add (&options_builder, "{sv}", "encrypt.passphrase", g_variant_new_string (passphrase));
-
- udisks_block_call_format (partition_block,
- fstype,
- g_variant_builder_end (&options_builder),
- NULL, /* GCancellable */
- format_cb,
- data);
out:
g_free (created_partition_object_path);
@@ -204,6 +301,8 @@ gdu_create_partition_dialog_show (GduWindow *window,
CreatePartitionData *data;
guint64 max_size_mb;
gint response;
+ const gchar *additional_fstypes[3] = {NULL, NULL, NULL};
+ gchar dos_extended_partition_name[256];
data = g_new0 (CreatePartitionData, 1);
data->window = g_object_ref (window);
@@ -216,16 +315,33 @@ gdu_create_partition_dialog_show (GduWindow *window,
data->offset = offset;
data->max_size = max_size;
+ if (g_strcmp0 (udisks_partition_table_get_type_ (data->table), "dos") == 0)
+ {
+ if (!have_dos_extended (data))
+ {
+ snprintf (dos_extended_partition_name, sizeof dos_extended_partition_name,
+ "%s <span foreground=\"#555555\" size=\"small\">(%s)</span>",
+ _("Extended partition"),
+ _("For logical partitions"));
+ additional_fstypes[0] = "dos_extended";
+ additional_fstypes[1] = dos_extended_partition_name;
+ }
+ }
+
data->dialog = gdu_application_new_widget (gdu_window_get_application (window),
"create-partition-dialog.ui",
"create-partition-dialog",
&data->builder);
+ data->dos_error_infobar = GTK_WIDGET (gtk_builder_get_object (data->builder, "infobar-dos-error"));;
+ data->dos_warning_infobar = GTK_WIDGET (gtk_builder_get_object (data->builder, "infobar-dos-warning"));;
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"));
data->contents_box = GTK_WIDGET (gtk_builder_get_object (data->builder, "contents-box"));
- data->create_filesystem_widget = gdu_create_filesystem_widget_new (gdu_window_get_application (window), data->drive);
+ data->create_filesystem_widget = gdu_create_filesystem_widget_new (gdu_window_get_application (window),
+ data->drive,
+ additional_fstypes);
gtk_box_pack_start (GTK_BOX (data->contents_box),
data->create_filesystem_widget,
TRUE, TRUE, 0);
@@ -272,14 +388,22 @@ gdu_create_partition_dialog_show (GduWindow *window,
if (response == GTK_RESPONSE_OK)
{
guint64 size;
+ const gchar *fstype;
+ const gchar *partition_type = "";
gtk_widget_hide (data->dialog);
+ fstype = gdu_create_filesystem_widget_get_fstype (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
+ if (g_strcmp0 (fstype, "dos_extended") == 0)
+ {
+ partition_type = "0x05";
+ }
+
size = gtk_adjustment_get_value (data->size_adjustment) * 1000L * 1000L;
udisks_partition_table_call_create_partition (data->table,
data->offset,
size,
- "", /* use default type */
+ partition_type, /* use default type */
"", /* use blank partition name */
g_variant_new ("a{sv}", NULL), /* options */
NULL, /* GCancellable */
diff --git a/src/palimpsest/gduformatvolumedialog.c b/src/palimpsest/gduformatvolumedialog.c
index 8a3bead..1697082 100644
--- a/src/palimpsest/gduformatvolumedialog.c
+++ b/src/palimpsest/gduformatvolumedialog.c
@@ -123,7 +123,9 @@ gdu_format_volume_dialog_show (GduWindow *window,
&data->builder);
data->contents_box = GTK_WIDGET (gtk_builder_get_object (data->builder, "contents-box"));
- data->create_filesystem_widget = gdu_create_filesystem_widget_new (gdu_window_get_application (window), data->drive);
+ data->create_filesystem_widget = gdu_create_filesystem_widget_new (gdu_window_get_application (window),
+ data->drive,
+ NULL); /* additional_fstypes */
gtk_box_pack_start (GTK_BOX (data->contents_box),
data->create_filesystem_widget,
TRUE, TRUE, 0);
diff --git a/src/palimpsest/gduvolumegrid.c b/src/palimpsest/gduvolumegrid.c
index 96a9517..1b2ed54 100644
--- a/src/palimpsest/gduvolumegrid.c
+++ b/src/palimpsest/gduvolumegrid.c
@@ -1947,6 +1947,7 @@ grid_element_set_details (GduVolumeGrid *grid,
if (partition != NULL && udisks_partition_get_is_container (partition))
{
g_ptr_array_add (lines, g_strdup (C_("volume-grid", "Extended Partition")));
+ maybe_add_partition (grid, lines, partition);
g_ptr_array_add (lines, g_strdup (size_str));
}
else if (filesystem != NULL)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]