[gnome-disk-utility] Redesign Format Dialog



commit 497bfd3b3c0d2b9693d9c629eba76ee50699d81b
Author: Kai Lüke <kailueke riseup net>
Date:   Mon Jul 24 11:52:09 2017 +0200

    Redesign Format Dialog
    
    Since the format dialog used hiding of widgets it was
    sometimes jumping around. The appearance of the passphrase
    entries were bound to a special LUKS+Ext4 mixed entry
    within a combo box. Also that apporach does not scale well
    if other filesystems should be listed for encryption.
    
    The dialog is redesinged and implemented with several pages,
    and thus adaptive to the needs of adding partitions, a new
    custom filesystem list and encryption, step for step.
    The default FS choices are still kept and shown via radio
    buttons on the format page.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=770738

 po/POTFILES.in                          |   18 +-
 src/disks/gduapplication.c              |    9 +-
 src/disks/gducreateconfirmpage.c        |  156 +++++++
 src/disks/gducreateconfirmpage.h        |   28 ++
 src/disks/gducreatediskimagedialog.c    |    1 -
 src/disks/gducreatefilesystempage.c     |  225 ++++++++++
 src/disks/gducreatefilesystempage.h     |   35 ++
 src/disks/gducreatefilesystemwidget.c   |  709 -------------------------------
 src/disks/gducreatefilesystemwidget.h   |   37 --
 src/disks/gducreateformatdialog.c       |  459 ++++++++++++++++++++
 src/disks/gducreateformatdialog.h       |   29 ++
 src/disks/gducreateotherpage.c          |  249 +++++++++++
 src/disks/gducreateotherpage.h          |   28 ++
 src/disks/gducreatepartitiondialog.c    |  444 -------------------
 src/disks/gducreatepartitiondialog.h    |   25 --
 src/disks/gducreatepartitionpage.c      |  339 +++++++++++++++
 src/disks/gducreatepartitionpage.h      |   34 ++
 src/disks/gducreatepasswordpage.c       |  151 +++++++
 src/disks/gducreatepasswordpage.h       |   27 ++
 src/disks/gduformatdiskdialog.c         |    1 -
 src/disks/gduformatvolumedialog.c       |  277 ------------
 src/disks/gduformatvolumedialog.h       |   28 --
 src/disks/gdupasswordstrengthwidget.c   |    1 +
 src/disks/gduwindow.c                   |   17 +-
 src/disks/gnome-disks.gresource.xml     |    9 +-
 src/disks/meson.build                   |   18 +-
 src/disks/ui/create-confirm-page.ui     |  146 +++++++
 src/disks/ui/create-filesystem-page.ui  |  212 +++++++++
 src/disks/ui/create-format.ui           |   57 +++
 src/disks/ui/create-other-page.ui       |   64 +++
 src/disks/ui/create-partition-dialog.ui |  286 -------------
 src/disks/ui/create-partition-page.ui   |  205 +++++++++
 src/disks/ui/create-password-page.ui    |  155 +++++++
 src/disks/ui/filesystem-create.ui       |  313 --------------
 src/disks/ui/format-volume-dialog.ui    |   85 ----
 src/disks/ui/gdu.css                    |    8 +
 36 files changed, 2653 insertions(+), 2232 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0f2344a..bf7cbe7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -11,15 +11,18 @@ src/disks/gduatasmartdialog.c
 src/disks/gdubenchmarkdialog.c
 src/disks/gduchangepassphrasedialog.c
 src/disks/gducreatediskimagedialog.c
-src/disks/gducreatefilesystemwidget.c
-src/disks/gducreatepartitiondialog.c
 src/disks/gducrypttabdialog.c
 src/disks/gdudevicetreemodel.c
 src/disks/gdudisksettingsdialog.c
 src/disks/gduestimator.c
 src/disks/gdufilesystemdialog.c
 src/disks/gduformatdiskdialog.c
-src/disks/gduformatvolumedialog.c
+src/disks/gducreateformatdialog.c
+src/disks/gducreatepartitionpage.c
+src/disks/gducreatefilesystempage.c
+src/disks/gducreateotherpage.c
+src/disks/gducreatepasswordpage.c
+src/disks/gducreateconfirmpage.c
 src/disks/gdufstabdialog.c
 src/disks/gdunewdiskimagedialog.c
 src/disks/gdupartitiondialog.c
@@ -35,8 +38,12 @@ src/disks/ui/about-dialog.ui
 src/disks/ui/app-menu.ui
 src/disks/ui/benchmark-dialog.ui
 src/disks/ui/change-passphrase-dialog.ui
+src/disks/ui/create-confirm-page.ui
 src/disks/ui/create-disk-image-dialog.ui
-src/disks/ui/create-partition-dialog.ui
+src/disks/ui/create-filesystem-page.ui
+src/disks/ui/create-other-page.ui
+src/disks/ui/create-partition-page.ui
+src/disks/ui/create-password-page.ui
 src/disks/ui/disk-settings-dialog.ui
 src/disks/ui/disks.ui
 src/disks/ui/edit-crypttab-dialog.ui
@@ -46,9 +53,8 @@ src/disks/ui/edit-fstab-dialog.ui
 src/disks/ui/edit-gpt-partition-dialog.ui
 src/disks/ui/edit-partition-dialog.ui
 src/disks/ui/erase-multiple-disks-dialog.ui
-src/disks/ui/filesystem-create.ui
 src/disks/ui/format-disk-dialog.ui
-src/disks/ui/format-volume-dialog.ui
+src/disks/ui/create-format.ui
 src/disks/ui/new-disk-image-dialog.ui
 src/disks/ui/resize-dialog.ui
 src/disks/ui/restore-disk-image-dialog.ui
diff --git a/src/disks/gduapplication.c b/src/disks/gduapplication.c
index 113f64e..5ca8657 100644
--- a/src/disks/gduapplication.c
+++ b/src/disks/gduapplication.c
@@ -17,7 +17,7 @@
 #include <unistd.h>
 
 #include "gduapplication.h"
-#include "gduformatvolumedialog.h"
+#include "gducreateformatdialog.h"
 #include "gdurestorediskimagedialog.h"
 #include "gdunewdiskimagedialog.h"
 #include "gduwindow.h"
@@ -257,14 +257,15 @@ gdu_application_command_line (GApplication            *_app,
         {
           gdu_window_select_object (app->window, object_to_select);
           if (opt_format)
-            gdu_format_volume_dialog_show (app->window, object_to_select);
+            gdu_create_format_show (app->client, GTK_WINDOW (app->window), object_to_select,
+                                    FALSE, FALSE, 0, 0, NULL, NULL);
         }
     }
   else if (opt_format)
     {
       g_application_hold (_app);
-      gdu_format_volume_dialog_show_for_xid (app->client, opt_xid, object_to_select,
-                                             (GCallback)g_application_release, _app);
+      gdu_create_format_show (app->client, NULL, object_to_select,
+                              FALSE, FALSE, 0, 0, (GCallback) g_application_release, _app);
     }
 
   if (opt_restore_disk_image != NULL)
diff --git a/src/disks/gducreateconfirmpage.c b/src/disks/gducreateconfirmpage.c
new file mode 100644
index 0000000..e93ac2e
--- /dev/null
+++ b/src/disks/gducreateconfirmpage.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "gducreateconfirmpage.h"
+
+struct _GduCreateConfirmPage
+{
+  GtkGrid parent_instance;
+};
+
+typedef struct _GduCreateConfirmPagePrivate GduCreateConfirmPagePrivate;
+
+struct _GduCreateConfirmPagePrivate
+{
+  GtkLabel *device_name_label;
+  GtkLabel *volume_name_label;
+  GtkLabel *used_label;
+  GtkLabel *used_amount_label;
+  GtkLabel *location_path_label;
+
+  UDisksClient *client;
+  UDisksObject *object;
+  UDisksBlock *block;
+};
+
+enum
+{
+  PROP_0,
+  PROP_COMPLETE
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GduCreateConfirmPage, gdu_create_confirm_page, GTK_TYPE_GRID);
+
+static void
+gdu_create_confirm_page_init (GduCreateConfirmPage *page)
+{
+  gtk_widget_init_template (GTK_WIDGET (page));
+}
+
+static void
+gdu_create_confirm_page_get_property (GObject    *object,
+                                      guint       property_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  switch (property_id)
+    {
+    case PROP_COMPLETE:
+      g_value_set_boolean (value, TRUE);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gdu_create_confirm_page_class_init (GduCreateConfirmPageClass *class)
+{
+  GObjectClass *gobject_class;
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gnome/Disks/ui/create-confirm-page.ui");
+  /* confirm page with information on current device usage */
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateConfirmPage, 
device_name_label);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateConfirmPage, 
volume_name_label);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateConfirmPage, 
used_amount_label);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateConfirmPage, used_label);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateConfirmPage, 
location_path_label);
+
+  gobject_class = G_OBJECT_CLASS (class);
+  gobject_class->get_property = gdu_create_confirm_page_get_property;
+  g_object_class_install_property (gobject_class, PROP_COMPLETE,
+                                   g_param_spec_boolean ("complete", NULL, NULL,
+                                                         TRUE,
+                                                         G_PARAM_READABLE |
+                                                         G_PARAM_STATIC_STRINGS));
+}
+
+void
+gdu_create_confirm_page_fill_confirmation (GduCreateConfirmPage *page)
+{
+  GduCreateConfirmPagePrivate *priv;
+  UDisksObjectInfo *info;
+  gint64 unused_space = -1;
+  gint64 size;
+  const gchar *s;
+  gchar *s1;
+  gchar *s2;
+
+  priv = gdu_create_confirm_page_get_instance_private (page);
+  /* gather data on current device usage for the confirmation page */
+  info = udisks_client_get_object_info (priv->client, priv->object);
+  unused_space = gdu_utils_get_unused_for_block (priv->client, priv->block);
+  /* Translators: In most cases this should not need translation unless the
+   *              separation character '—' is not appropriate. The strings come
+   *              from UDisks, first is description, second the name:
+   *              "Partition 1 of 32 GB Flash Disk – /dev/sdb1".
+   */
+  s1 = g_strdup_printf (_("%s — %s"), udisks_object_info_get_description (info),
+                                      udisks_object_info_get_name (info));
+  gtk_label_set_text (priv->device_name_label, s1);
+  g_free (s1);
+
+  s = udisks_block_get_id_label (priv->block);
+  if (s != NULL && strlen(s) > 0)
+    gtk_label_set_text (priv->volume_name_label, s);
+  else
+    gtk_label_set_text (priv->volume_name_label, udisks_block_get_id_type (priv->block));
+  size = udisks_block_get_size (priv->block);
+  if (unused_space > 0)
+    {
+      gtk_widget_show (GTK_WIDGET (priv->used_label));
+      gtk_widget_show (GTK_WIDGET (priv->used_amount_label));
+      s1 = udisks_client_get_size_for_display (priv->client, size - unused_space, FALSE, FALSE);
+      /* Translators: Disk usage in the format '3 GB (7%)', unit string comes from UDisks.
+       */
+      s2 = g_strdup_printf (_("%s (%.1f%%)"), s1, 100.0 * (size - unused_space) / size);
+      gtk_label_set_text (priv->used_amount_label, s2);
+      g_free (s1);
+      g_free (s2);
+    }
+  else
+    {
+      gtk_widget_hide (GTK_WIDGET (priv->used_label));
+      gtk_widget_hide (GTK_WIDGET (priv->used_amount_label));
+    }
+  gtk_label_set_text (priv->location_path_label, udisks_block_get_preferred_device (priv->block));
+
+  g_object_unref (info);
+}
+
+GduCreateConfirmPage *
+gdu_create_confirm_page_new (UDisksClient *client, UDisksObject *object, UDisksBlock *block)
+{
+  GduCreateConfirmPage *page;
+  GduCreateConfirmPagePrivate *priv;
+
+  page = g_object_new (GDU_TYPE_CREATE_CONFIRM_PAGE, NULL);
+  priv = gdu_create_confirm_page_get_instance_private (page);
+  priv->client = client;
+  priv->object = object;
+  priv->block = block;
+
+  return page;
+}
diff --git a/src/disks/gducreateconfirmpage.h b/src/disks/gducreateconfirmpage.h
new file mode 100644
index 0000000..008daf9
--- /dev/null
+++ b/src/disks/gducreateconfirmpage.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#ifndef __GDU_CREATE_CONFIRM_PAGE_H__
+#define __GDU_CREATE_CONFIRM_PAGE_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+#define GDU_TYPE_CREATE_CONFIRM_PAGE gdu_create_confirm_page_get_type ()
+G_DECLARE_FINAL_TYPE (GduCreateConfirmPage, gdu_create_confirm_page, GDU, CREATE_CONFIRM_PAGE, GtkGrid)
+
+GduCreateConfirmPage *gdu_create_confirm_page_new               (UDisksClient *client,
+                                                                 UDisksObject *object,
+                                                                 UDisksBlock  *block);
+
+void                  gdu_create_confirm_page_fill_confirmation (GduCreateConfirmPage *page);
+
+G_END_DECLS
+
+#endif /* __GDU_CREATE_CONFIRM_PAGE_H__ */
diff --git a/src/disks/gducreatediskimagedialog.c b/src/disks/gducreatediskimagedialog.c
index 2eac084..a22ef8c 100644
--- a/src/disks/gducreatediskimagedialog.c
+++ b/src/disks/gducreatediskimagedialog.c
@@ -27,7 +27,6 @@
 #include "gduwindow.h"
 #include "gducreatediskimagedialog.h"
 #include "gduvolumegrid.h"
-#include "gducreatefilesystemwidget.h"
 #include "gduestimator.h"
 #include "gdulocaljob.h"
 
diff --git a/src/disks/gducreatefilesystempage.c b/src/disks/gducreatefilesystempage.c
new file mode 100644
index 0000000..f7ce643
--- /dev/null
+++ b/src/disks/gducreatefilesystempage.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "gducreatefilesystempage.h"
+
+struct _GduCreateFilesystemPage
+{
+  GtkGrid parent_instance;
+};
+
+typedef struct _GduCreateFilesystemPagePrivate GduCreateFilesystemPagePrivate;
+
+struct _GduCreateFilesystemPagePrivate
+{
+  GtkEntry *name_entry;
+  GtkSwitch *erase_switch;
+  GtkRadioButton *internal_radiobutton;
+  GtkCheckButton *internal_encrypt_checkbutton;
+  GtkRadioButton *windows_radiobutton;
+  GtkRadioButton *all_radiobutton;
+  GtkRadioButton *other_radiobutton;
+
+  gboolean complete;
+};
+
+enum
+{
+  PROP_0,
+  PROP_COMPLETE
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GduCreateFilesystemPage, gdu_create_filesystem_page, GTK_TYPE_GRID);
+
+static void
+gdu_create_filesystem_page_init (GduCreateFilesystemPage *page)
+{
+  gtk_widget_init_template (GTK_WIDGET (page));
+}
+
+static void
+gdu_create_filesystem_page_get_property (GObject    *object,
+                                         guint       property_id,
+                                         GValue     *value,
+                                         GParamSpec *pspec)
+{
+  GduCreateFilesystemPage *page = GDU_CREATE_FILESYSTEM_PAGE (object);
+  GduCreateFilesystemPagePrivate *priv;
+
+  priv = gdu_create_filesystem_page_get_instance_private (page);
+
+  switch (property_id)
+    {
+    case PROP_COMPLETE:
+      g_value_set_boolean (value, priv->complete);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gdu_create_filesystem_page_class_init (GduCreateFilesystemPageClass *class)
+{
+  GObjectClass *gobject_class;
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gnome/Disks/ui/create-filesystem-page.ui");
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateFilesystemPage, 
name_entry);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateFilesystemPage, 
erase_switch);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateFilesystemPage, 
internal_radiobutton);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateFilesystemPage, 
internal_encrypt_checkbutton);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateFilesystemPage, 
windows_radiobutton);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateFilesystemPage, 
all_radiobutton);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateFilesystemPage, 
other_radiobutton);
+
+  gobject_class = G_OBJECT_CLASS (class);
+  gobject_class->get_property = gdu_create_filesystem_page_get_property;
+  g_object_class_install_property (gobject_class, PROP_COMPLETE,
+                                   g_param_spec_boolean ("complete", NULL, NULL,
+                                                         FALSE,
+                                                         G_PARAM_READABLE |
+                                                         G_PARAM_STATIC_STRINGS));
+}
+
+const gchar *
+gdu_create_filesystem_page_get_name (GduCreateFilesystemPage *page)
+{
+  GduCreateFilesystemPagePrivate *priv;
+
+  priv = gdu_create_filesystem_page_get_instance_private (page);
+
+  return gtk_entry_get_text (priv->name_entry);
+}
+
+gboolean
+gdu_create_filesystem_page_is_other (GduCreateFilesystemPage *page)
+{
+  GduCreateFilesystemPagePrivate *priv;
+
+  priv = gdu_create_filesystem_page_get_instance_private (page);
+
+  return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->other_radiobutton));
+}
+
+const gchar *
+gdu_create_filesystem_page_get_fs (GduCreateFilesystemPage *page)
+{
+  GduCreateFilesystemPagePrivate *priv;
+
+  priv = gdu_create_filesystem_page_get_instance_private (page);
+
+  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->internal_radiobutton)))
+    return "ext4";
+  else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->windows_radiobutton)))
+    return "ntfs";
+  else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->all_radiobutton)))
+    return "vfat";
+  else
+    return NULL;
+}
+
+gboolean
+gdu_create_filesystem_page_is_encrypted (GduCreateFilesystemPage *page)
+{
+  GduCreateFilesystemPagePrivate *priv;
+
+  priv = gdu_create_filesystem_page_get_instance_private (page);
+
+  return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->internal_radiobutton)) &&
+         gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->internal_encrypt_checkbutton));
+}
+
+const gchar *
+gdu_create_filesystem_page_get_erase (GduCreateFilesystemPage *page)
+{
+  GduCreateFilesystemPagePrivate *priv;
+
+  priv = gdu_create_filesystem_page_get_instance_private (page);
+
+  if (gtk_switch_get_active (priv->erase_switch))
+    return "zero";
+  else /* TODO: "ata-secure-erase", "ata-secure-erase-enhanced" */
+    return NULL;
+}
+
+static void
+on_fs_name_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
+{
+  GduCreateFilesystemPage *page = GDU_CREATE_FILESYSTEM_PAGE (user_data);
+  GduCreateFilesystemPagePrivate *priv;
+
+  priv = gdu_create_filesystem_page_get_instance_private (page);
+
+  priv->complete = gtk_entry_get_text_length (priv->name_entry) > 0; /* require a label */
+  g_object_notify (G_OBJECT (page), "complete");
+
+  _gtk_entry_buffer_truncate_bytes (gtk_entry_get_buffer (priv->name_entry),
+                                    gdu_utils_get_max_label_length (gdu_create_filesystem_page_get_fs 
(page)));
+}
+
+static void
+on_fs_type_changed (GtkToggleButton *object, gpointer user_data)
+{
+  GduCreateFilesystemPage *page = GDU_CREATE_FILESYSTEM_PAGE (user_data);
+  GduCreateFilesystemPagePrivate *priv;
+
+  priv = gdu_create_filesystem_page_get_instance_private (page);
+
+  _gtk_entry_buffer_truncate_bytes (gtk_entry_get_buffer (priv->name_entry),
+                                    gdu_utils_get_max_label_length (gdu_create_filesystem_page_get_fs 
(page)));
+  g_object_notify (G_OBJECT (page), "complete");
+}
+
+GduCreateFilesystemPage *
+gdu_create_filesystem_page_new (gboolean show_custom, UDisksDrive *drive)
+{
+  GduCreateFilesystemPage *page;
+  GduCreateFilesystemPagePrivate *priv;
+
+  page = g_object_new (GDU_TYPE_CREATE_FILESYSTEM_PAGE, NULL);
+  priv = gdu_create_filesystem_page_get_instance_private (page);
+  g_signal_connect (priv->name_entry, "notify::text", G_CALLBACK (on_fs_name_changed), page);
+  g_signal_connect (priv->internal_encrypt_checkbutton, "toggled", G_CALLBACK (on_fs_type_changed), page);
+  g_signal_connect (priv->internal_radiobutton, "toggled", G_CALLBACK (on_fs_type_changed), page);
+  g_signal_connect (priv->windows_radiobutton, "toggled", G_CALLBACK (on_fs_type_changed), page);
+  g_signal_connect (priv->all_radiobutton, "toggled", G_CALLBACK (on_fs_type_changed), page);
+  g_signal_connect (priv->other_radiobutton, "toggled", G_CALLBACK (on_fs_type_changed), page);
+
+  g_object_bind_property (priv->internal_radiobutton, "active", priv->internal_encrypt_checkbutton, 
"sensitive", G_BINDING_SYNC_CREATE);
+
+  if (!show_custom)
+    gtk_widget_hide (GTK_WIDGET (priv->other_radiobutton));
+
+  /* Default to FAT or NTFS for removable drives... */
+  if (drive != NULL && udisks_drive_get_removable (drive))
+    {
+      /* default FAT for flash and disks/media smaller than 20G (assumed to be flash cards) */
+      if (gdu_utils_is_flash (drive) ||
+          udisks_drive_get_size (drive) < 20UL * 1000UL*1000UL*1000UL ||
+          !gdu_utils_is_ntfs_available ()
+          )
+        {
+          gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->all_radiobutton), TRUE);
+        }
+      else
+        {
+          gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->windows_radiobutton), TRUE);
+        }
+    }
+
+  gtk_widget_set_sensitive (GTK_WIDGET (priv->windows_radiobutton), gdu_utils_is_ntfs_available ());
+
+  return page;
+}
diff --git a/src/disks/gducreatefilesystempage.h b/src/disks/gducreatefilesystempage.h
new file mode 100644
index 0000000..3dfd29d
--- /dev/null
+++ b/src/disks/gducreatefilesystempage.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#ifndef __GDU_CREATE_FILESYSTEM_PAGE_H__
+#define __GDU_CREATE_FILESYSTEM_PAGE_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+#define GDU_TYPE_CREATE_FILESYSTEM_PAGE gdu_create_filesystem_page_get_type ()
+G_DECLARE_FINAL_TYPE (GduCreateFilesystemPage, gdu_create_filesystem_page, GDU, CREATE_FILESYSTEM_PAGE, 
GtkGrid)
+
+GduCreateFilesystemPage *gdu_create_filesystem_page_new          (gboolean      show_custom,
+                                                                  UDisksDrive  *drive);
+
+const gchar *            gdu_create_filesystem_page_get_name     (GduCreateFilesystemPage *page);
+
+const gchar *            gdu_create_filesystem_page_get_fs       (GduCreateFilesystemPage *page);
+
+gboolean                 gdu_create_filesystem_page_is_other     (GduCreateFilesystemPage *page);
+
+gboolean                 gdu_create_filesystem_page_is_encrypted (GduCreateFilesystemPage *page);
+
+const gchar *            gdu_create_filesystem_page_get_erase    (GduCreateFilesystemPage *page);
+
+G_END_DECLS
+
+#endif /* __GDU_CREATE_FILESYSTEM_PAGE_H__ */
diff --git a/src/disks/gducreateformatdialog.c b/src/disks/gducreateformatdialog.c
new file mode 100644
index 0000000..6077db1
--- /dev/null
+++ b/src/disks/gducreateformatdialog.c
@@ -0,0 +1,459 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2013 Red Hat, Inc.
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: David Zeuthen <zeuthen gmail com>, Kai Lüke <kailueke riseup net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "gduapplication.h"
+#include "gduwindow.h"
+#include "gducreateformatdialog.h"
+#include "gducreatepartitionpage.h"
+#include "gducreatefilesystempage.h"
+#include "gducreateotherpage.h"
+#include "gducreatepasswordpage.h"
+#include "gducreateconfirmpage.h"
+#include "gduvolumegrid.h"
+
+#define PARTITION_PAGE "partition"
+#define FORMAT_PAGE "format"
+#define OTHER_PAGE "other"
+#define PASSWORD_PAGE "password"
+#define CONFIRM_PAGE "confirm"
+
+typedef struct
+{
+  GtkWindow *parent_window;
+  UDisksObject *object;
+  UDisksBlock *block;
+  UDisksDrive *drive;
+  UDisksPartitionTable *table;
+  UDisksClient *client;
+
+  GtkBuilder *builder;
+  GtkDialog *dialog;
+  GtkStack *stack;
+  GtkButton *back;
+  GtkButton *forward;
+  const gchar *current; /* page names */
+  const gchar *prev;
+  const gchar *next;
+  gboolean add_partition; /* mode: format vs add partition and format */
+  guint64 add_partition_offset;
+  guint64 add_partition_maxsize;
+
+  GduCreatePartitionPage *partition_page;    /* create partition page */
+  GduCreateFilesystemPage *filesystem_page;  /* main format page */
+  GduCreateOtherPage *other_page;            /* custom filesystem page */
+  GduCreatePasswordPage *password_page;      /* set password page */
+  GduCreateConfirmPage *confirm_page;        /* confirm format page */
+
+  GCallback finished_cb;
+  gpointer  cb_data;
+} CreateFormatData;
+
+static void
+create_format_data_free (CreateFormatData *data)
+{
+  if (data->finished_cb)
+    ((GDestroyNotify) data->finished_cb) (data->cb_data);
+  g_clear_object (&data->parent_window);
+  g_object_unref (data->object);
+  g_object_unref (data->block);
+  g_clear_object (&data->drive);
+  if (data->dialog != NULL)
+    {
+      gtk_widget_hide (GTK_WIDGET (data->dialog));
+      gtk_widget_destroy (GTK_WIDGET (data->dialog));
+    }
+  if (data->builder != NULL)
+    g_object_unref (data->builder);
+  g_free (data);
+}
+
+static const gchar *
+get_filesystem (CreateFormatData *data)
+{
+  if (data->add_partition && gdu_create_partition_page_is_extended (data->partition_page))
+    return "dos_extended";
+  else if (gdu_create_filesystem_page_get_fs (data->filesystem_page) != NULL)
+    return gdu_create_filesystem_page_get_fs (data->filesystem_page);
+  else
+    return gdu_create_other_page_get_fs (data->other_page);
+}
+
+static gboolean
+get_encrypt (CreateFormatData *data)
+{
+  return gdu_create_filesystem_page_is_encrypted (data->filesystem_page) ||
+         (gdu_create_filesystem_page_is_other (data->filesystem_page) &&
+          gdu_create_other_page_is_encrypted (data->other_page));
+}
+
+static void
+update_dialog (GtkWidget *widget, GParamSpec *child_property, CreateFormatData *data)
+{
+  GValue title = G_VALUE_INIT;
+  gboolean complete = FALSE;
+  GtkWidget *child;
+  gpointer page = NULL;
+
+  g_value_init (&title, G_TYPE_STRING);
+  child = gtk_stack_get_child_by_name (data->stack, data->current);
+  gtk_container_child_get_property (GTK_CONTAINER (data->stack), child, "title", &title);
+
+  gtk_window_set_title (GTK_WINDOW (data->dialog), g_value_get_string (&title));
+  data->prev = NULL;
+  data->next = CONFIRM_PAGE;
+
+  if (data->add_partition)
+    data->next = NULL;
+
+  if (g_strcmp0 (data->current, PARTITION_PAGE) == 0)
+    {
+      page = data->partition_page;
+      data->next = FORMAT_PAGE;
+      if (gdu_create_partition_page_is_extended (data->partition_page))
+        data->next = NULL;
+    }
+  else if (g_strcmp0 (data->current, FORMAT_PAGE) == 0)
+    {
+      page = data->filesystem_page;
+      if (data->add_partition)
+        data->prev = PARTITION_PAGE;
+
+      if (gdu_create_filesystem_page_is_other (data->filesystem_page))
+        data->next = OTHER_PAGE;
+
+      if (gdu_create_filesystem_page_is_encrypted (data->filesystem_page))
+        data->next = PASSWORD_PAGE;
+    }
+  else if (g_strcmp0 (data->current, OTHER_PAGE) == 0)
+    {
+      page = data->other_page;
+      data->prev = FORMAT_PAGE;
+
+      if (gdu_create_other_page_is_encrypted (data->other_page))
+        data->next = PASSWORD_PAGE;
+    }
+  else if (g_strcmp0 (data->current, PASSWORD_PAGE) == 0)
+    {
+      page = data->password_page;
+      if (gdu_create_filesystem_page_is_encrypted (data->filesystem_page))
+        data->prev = FORMAT_PAGE;
+      else if (gdu_create_filesystem_page_is_other (data->filesystem_page) &&
+               gdu_create_other_page_is_encrypted (data->other_page))
+        data->prev = OTHER_PAGE;
+    }
+  else if (g_strcmp0 (data->current, CONFIRM_PAGE) == 0)
+    {
+      page = data->confirm_page;
+      data->next = NULL;
+
+      if (gdu_create_filesystem_page_is_encrypted (data->filesystem_page) ||
+          (gdu_create_filesystem_page_is_other (data->filesystem_page) &&
+           gdu_create_other_page_is_encrypted (data->other_page)))
+        data->prev = PASSWORD_PAGE;
+      else if (gdu_create_filesystem_page_is_other (data->filesystem_page))
+        data->prev = OTHER_PAGE;
+      else
+        data->prev = FORMAT_PAGE;
+
+      gdu_create_confirm_page_fill_confirmation (data->confirm_page);
+    }
+
+  if (data->prev == NULL)
+    gtk_button_set_label (data->back, _("_Cancel"));
+  else
+    gtk_button_set_label (data->back, _("_Previous"));
+
+  if (data->next == NULL)
+    {
+      if (data->add_partition)
+        {
+          gtk_button_set_label (data->forward, _("Cre_ate"));
+          gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (data->forward)),
+                                       "suggested-action");
+        }
+      else
+        {
+          gtk_button_set_label (data->forward, _("Form_at"));
+          gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (data->forward)),
+                                       "destructive-action");
+        }
+    }
+  else
+    {
+      gtk_button_set_label (data->forward, _("N_ext"));
+      gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (data->forward)),
+                                      "suggested-action");
+      gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (data->forward)),
+                                      "destructive-action");
+    }
+
+  g_object_get (page, "complete", &complete, NULL);
+  gtk_widget_set_sensitive (GTK_WIDGET (data->forward), complete);
+  gtk_stack_set_visible_child (data->stack, child);
+}
+
+static void
+cancel_cb (GtkDialog *dialog, CreateFormatData *data)
+{
+  create_format_data_free (data);
+}
+
+static void
+format_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+  CreateFormatData *data = user_data;
+  GError *error;
+
+  error = NULL;
+  if (!udisks_block_call_format_finish (UDISKS_BLOCK (source_object), res, &error))
+    {
+      gdu_utils_show_error (GTK_WINDOW (data->parent_window), _("Error formatting volume"), error);
+      g_error_free (error);
+    }
+  create_format_data_free (data);
+}
+
+static void
+ensure_unused_cb (UDisksClient *client, GAsyncResult *res, CreateFormatData *data)
+{
+  GVariantBuilder options_builder;
+  const gchar *fs_type;
+  const gchar *erase_type;
+
+  if (!gdu_utils_ensure_unused_finish (client, res, NULL))
+    {
+      create_format_data_free (data);
+      return;
+    }
+
+  fs_type = get_filesystem (data);
+  erase_type = gdu_create_filesystem_page_get_erase (data->filesystem_page);
+
+  g_variant_builder_init (&options_builder, G_VARIANT_TYPE_VARDICT);
+  if (g_strcmp0 (fs_type, "empty") != 0)
+    g_variant_builder_add (&options_builder, "{sv}", "label",
+                           g_variant_new_string (gdu_create_filesystem_page_get_name 
(data->filesystem_page)));
+
+  if (g_strcmp0 (fs_type, "vfat") != 0 && g_strcmp0 (fs_type, "ntfs") != 0 && g_strcmp0 (fs_type, "exfat") 
!= 0)
+    {
+      g_variant_builder_add (&options_builder, "{sv}", "take-ownership", g_variant_new_boolean (TRUE));
+    }
+
+  if (get_encrypt (data))
+    g_variant_builder_add (&options_builder, "{sv}", "encrypt.passphrase",
+                           g_variant_new_string (gdu_create_password_page_get_password 
(data->password_page)));
+
+  if (erase_type != NULL)
+    g_variant_builder_add (&options_builder, "{sv}", "erase", g_variant_new_string (erase_type));
+
+  g_variant_builder_add (&options_builder, "{sv}", "update-partition-type", g_variant_new_boolean (TRUE));
+
+  udisks_block_call_format (data->block,
+                            fs_type,
+                            g_variant_builder_end (&options_builder),
+                            NULL, /* GCancellable */
+                            format_cb,
+                            data);
+}
+
+void
+finish_cb (GtkDialog *assistant, gint response_id, CreateFormatData *data);
+
+static void
+create_partition_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+  CreateFormatData *data = user_data;
+  GError *error;
+  gchar *created_partition_object_path = NULL;
+  UDisksObject *partition_object = NULL;
+  UDisksBlock *partition_block;
+
+  error = NULL;
+  if (!udisks_partition_table_call_create_partition_finish (UDISKS_PARTITION_TABLE (source_object),
+                                                            &created_partition_object_path,
+                                                            res,
+                                                            &error))
+    {
+      gdu_utils_show_error (GTK_WINDOW (data->parent_window), _("Error creating partition"), error);
+      g_error_free (error);
+      create_format_data_free (data);
+      return;
+    }
+
+  udisks_client_settle (data->client);
+
+  partition_object = udisks_client_get_object (data->client, created_partition_object_path);
+  g_free (created_partition_object_path);
+  gdu_window_select_object (GDU_WINDOW (data->parent_window), partition_object);
+
+  partition_block = udisks_object_get_block (partition_object);
+  if (partition_block == NULL)
+    {
+      g_warning ("Created partition has no block interface");
+      create_format_data_free (data);
+      g_clear_object (&partition_object);
+      return;
+    }
+
+  /* Create a filesystem now on partition if not an extended partition */
+  if (g_strcmp0 (get_filesystem (data), "dos_extended") != 0)
+    {
+      data->add_partition = FALSE;
+      g_object_unref (data->block);
+      data->block = partition_block;
+      g_object_unref (data->object);
+      data->object = partition_object;
+      finish_cb (data->dialog, GTK_RESPONSE_APPLY, data);
+    }
+}
+
+void
+finish_cb (GtkDialog *dialog, gint response_id, CreateFormatData *data) /* the assistant is done */
+{
+  guint64 size;
+  const gchar *partition_type = "";
+
+  if (response_id != GTK_RESPONSE_APPLY)
+    {
+      /* step back or cancel */
+      if (data->prev != NULL)
+        {
+          data->current = data->prev;
+          update_dialog (NULL, NULL, data);
+        }
+      else
+        cancel_cb (dialog, data);
+      return;
+    }
+
+  /* step to next page */
+  if (data->next != NULL)
+    {
+      data->current = data->next;
+      update_dialog (NULL, NULL, data);
+      return;
+    }
+
+  if (g_strcmp0 (get_filesystem (data), "dos_extended") == 0)
+    {
+      partition_type = "0x05";
+    }
+
+  if (data->add_partition)
+    {
+      size = gdu_create_partition_page_get_size (data->partition_page);
+      udisks_partition_table_call_create_partition (data->table,
+                                                    data->add_partition_offset,
+                                                    size,
+                                                    partition_type, /* use default type */
+                                                    "", /* use blank partition name */
+                                                    g_variant_new ("a{sv}", NULL), /* options */
+                                                    NULL, /* GCancellable */
+                                                    create_partition_cb,
+                                                    data);
+    }
+  else
+    {
+      /* ensure the volume is unused (e.g. unmounted) before formatting it... */
+      gdu_utils_ensure_unused (data->client,
+                               GTK_WINDOW (data->parent_window),
+                               data->object,
+                               (GAsyncReadyCallback) ensure_unused_cb,
+                               NULL, /* GCancellable */
+                               data);
+    }
+
+  gtk_widget_hide (GTK_WIDGET (data->dialog));
+}
+
+void
+gdu_create_format_show (UDisksClient *client,
+                        GtkWindow    *parent_window,
+                        UDisksObject *object,
+                        gboolean      show_custom,  /* e.g. hide custom format page from nautilus */
+                        gboolean      add_partition, /* format vs add partition and format */
+                        guint64       add_partition_offset,
+                        guint64       add_partition_maxsize,
+                        GCallback     finished_cb,
+                        gpointer      cb_data)
+{
+  GduApplication *app;
+  CreateFormatData *data;
+
+  app = GDU_APPLICATION (g_application_get_default ());
+  data = g_new0 (CreateFormatData, 1);
+  data->finished_cb = finished_cb;
+  data->cb_data = cb_data;
+  data->client = client;
+  data->parent_window = (parent_window != NULL) ? g_object_ref (parent_window) : NULL;
+  data->object = g_object_ref (object);
+  data->block = udisks_object_get_block (object);
+  g_assert (data->block != NULL);
+  data->drive = udisks_client_get_drive_for_block (client, data->block);
+  data->table = udisks_object_get_partition_table (object);
+
+  data->dialog = GTK_DIALOG (gdu_application_new_widget (app,
+                                                         "create-format.ui",
+                                                         "create-format",
+                                                         &data->builder));
+  data->stack = GTK_STACK (gtk_builder_get_object (data->builder, "pages-stack"));
+
+  data->add_partition = add_partition;
+  data->add_partition_offset = add_partition_offset;
+  data->add_partition_maxsize = add_partition_maxsize;
+
+  if (data->add_partition)
+    {
+      data->partition_page = gdu_create_partition_page_new (data->client, data->table,
+                                                            add_partition_maxsize, add_partition_offset);
+      gtk_stack_add_titled (data->stack, GTK_WIDGET (data->partition_page), PARTITION_PAGE, _("Create 
Partition"));
+      g_signal_connect (data->partition_page, "notify::complete", G_CALLBACK (update_dialog), data);
+    }
+  else
+    {
+      data->partition_page = NULL;
+    }
+
+  data->filesystem_page = gdu_create_filesystem_page_new (show_custom, data->drive);
+  gtk_stack_add_titled (data->stack, GTK_WIDGET (data->filesystem_page), FORMAT_PAGE, _("Format Volume"));
+  g_signal_connect (data->filesystem_page, "notify::complete", G_CALLBACK (update_dialog), data);
+  data->other_page = gdu_create_other_page_new (data->client);
+  gtk_stack_add_titled (data->stack, GTK_WIDGET (data->other_page), OTHER_PAGE, _("Custom Format"));
+  g_signal_connect (data->other_page, "notify::complete", G_CALLBACK (update_dialog), data);
+  data->password_page = gdu_create_password_page_new ();
+  gtk_stack_add_titled (data->stack, GTK_WIDGET (data->password_page), PASSWORD_PAGE, _("Set Password"));
+  g_signal_connect (data->password_page, "notify::complete", G_CALLBACK (update_dialog), data);
+  data->confirm_page = gdu_create_confirm_page_new (data->client, data->object, data->block);
+  gtk_stack_add_titled (data->stack, GTK_WIDGET (data->confirm_page), CONFIRM_PAGE, _("Confirm Details"));
+
+  data->back = GTK_BUTTON (gtk_dialog_add_button (data->dialog, _("_Cancel"), GTK_RESPONSE_CANCEL));
+  data->forward = GTK_BUTTON (gtk_dialog_add_button (data->dialog, _("_Format"), GTK_RESPONSE_APPLY));
+  gtk_widget_grab_default (GTK_WIDGET (data->forward));
+
+  g_signal_connect (data->dialog, "close", G_CALLBACK (cancel_cb), data);
+  g_signal_connect (data->dialog, "response", G_CALLBACK (finish_cb), data);
+
+  if (add_partition)
+    data->current = PARTITION_PAGE;
+  else
+    data->current = FORMAT_PAGE;
+
+  if (parent_window != NULL)
+    {
+      gtk_window_set_transient_for (GTK_WINDOW (data->dialog), parent_window);
+    }
+
+  update_dialog (NULL, NULL, data);
+  gtk_widget_show (GTK_WIDGET (data->dialog));
+}
diff --git a/src/disks/gducreateformatdialog.h b/src/disks/gducreateformatdialog.h
new file mode 100644
index 0000000..c3864aa
--- /dev/null
+++ b/src/disks/gducreateformatdialog.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#ifndef __GDU_CREATE_FORMAT_DIALOG_H__
+#define __GDU_CREATE_FORMAT_DIALOG_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+void gdu_create_format_show (UDisksClient *client,
+                             GtkWindow    *parent_window,
+                             UDisksObject *object,
+                             gboolean      show_custom,
+                             gboolean      add_partition,
+                             guint64       add_partition_offset,
+                             guint64       add_partition_maxsize,
+                             GCallback     finished_cb,
+                             gpointer      cb_data);
+
+G_END_DECLS
+
+#endif /* __GDU_CREATE_FORMAT_DIALOG_H__ */
diff --git a/src/disks/gducreateotherpage.c b/src/disks/gducreateotherpage.c
new file mode 100644
index 0000000..83557da
--- /dev/null
+++ b/src/disks/gducreateotherpage.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "gducreateotherpage.h"
+
+struct _GduCreateOtherPage
+{
+  GtkBox parent_instance;
+};
+
+typedef struct _GduCreateOtherPagePrivate GduCreateOtherPagePrivate;
+
+struct _GduCreateOtherPagePrivate
+{
+  GtkBox *other_fs_box;
+  GtkCheckButton *other_encrypt_checkbutton;
+
+  UDisksClient *client;
+  const gchar *other_fs_type;
+  GtkRadioButton *prev_other_fs_radio;
+  gint current_index;
+};
+
+enum
+{
+  PROP_0,
+  PROP_COMPLETE
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GduCreateOtherPage, gdu_create_other_page, GTK_TYPE_BOX);
+
+static void
+gdu_create_other_page_init (GduCreateOtherPage *page)
+{
+  gtk_widget_init_template (GTK_WIDGET (page));
+}
+
+static void
+gdu_create_other_page_get_property (GObject    *object,
+                                    guint       property_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  switch (property_id)
+    {
+    case PROP_COMPLETE:
+      g_value_set_boolean (value, TRUE);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gdu_create_other_page_class_init (GduCreateOtherPageClass *class)
+{
+  GObjectClass *gobject_class;
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gnome/Disks/ui/create-other-page.ui");
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateOtherPage, other_fs_box);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreateOtherPage, 
other_encrypt_checkbutton);
+
+  gobject_class = G_OBJECT_CLASS (class);
+  gobject_class->get_property = gdu_create_other_page_get_property;
+  g_object_class_install_property (gobject_class, PROP_COMPLETE,
+                                   g_param_spec_boolean ("complete", NULL, NULL,
+                                                         TRUE,
+                                                         G_PARAM_READABLE |
+                                                         G_PARAM_STATIC_STRINGS));
+}
+
+static void
+row_adder (GduCreateOtherPage *page, gboolean tested, gboolean available, gchar *util);
+
+const gchar *
+gdu_create_other_page_get_fs (GduCreateOtherPage *page)
+{
+  GduCreateOtherPagePrivate *priv;
+
+  priv = gdu_create_other_page_get_instance_private (page);
+
+  return priv->other_fs_type;
+}
+
+gboolean
+gdu_create_other_page_is_encrypted (GduCreateOtherPage *page)
+{
+  GduCreateOtherPagePrivate *priv;
+
+  priv = gdu_create_other_page_get_instance_private (page);
+
+  return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->other_encrypt_checkbutton));
+}
+
+static const gchar *other_fs[] = {
+  "xfs", "swap", "btrfs", "f2fs", "exfat", "udf", "empty", NULL
+};
+
+static const gchar *
+get_fs_description (const gchar *fs_type)
+{
+  if (g_strcmp0 (fs_type, "xfs") == 0)
+    return _("XFS – Linux Filesystem");
+  else if (g_strcmp0 (fs_type, "swap") == 0)
+    return _("Linux Swap Partition");
+  else if (g_strcmp0 (fs_type, "btrfs") == 0)
+    return _("Btrfs – Copy-on-write Linux Filesystem, for snapshots");
+  else if (g_strcmp0 (fs_type, "f2fs") == 0)
+    return _("F2FS – Flash Storage Linux Filesystem");
+  else if (g_strcmp0 (fs_type, "exfat") == 0)
+    return _("exFAT – Flash Storage Windows Filesystem, used on SDXC cards");
+  else if (g_strcmp0 (fs_type, "udf") == 0)
+    return _("UDF – Universal Disk Format, for removable devices on many systems");
+  else if (g_strcmp0 (fs_type, "empty") == 0)
+    return _("No Filesystem");
+  else
+    return fs_type;
+}
+
+static void
+on_other_fs_selected (GtkToggleButton *object, GduCreateOtherPage *page)
+{
+  GduCreateOtherPagePrivate *priv;
+
+  priv = gdu_create_other_page_get_instance_private (page);
+
+  priv->other_fs_type = g_object_get_data (G_OBJECT (object), "id");
+}
+
+#ifdef HAVE_UDISKS2_7_2
+static void
+can_format_cb (UDisksManager *manager,
+               GAsyncResult  *res,
+               gpointer       user_data)
+{
+  GVariant *out_available;
+  GError *error = NULL;
+  gboolean available = FALSE;
+  gchar *util = NULL;
+
+  if (!udisks_manager_call_can_format_finish (manager, &out_available, res, &error))
+    {
+      available = FALSE;
+      g_clear_error (&error);
+    }
+  else
+    {
+      g_variant_get (out_available, "(bs)", &available, &util);
+      g_variant_unref (out_available);
+    }
+
+  row_adder (user_data, TRUE, available, util);
+  g_free (util);
+}
+#endif
+
+static void
+row_adder (GduCreateOtherPage *page, gboolean tested, gboolean available, gchar *missing_util)
+{
+  GSList *group = NULL;
+  GduCreateOtherPagePrivate *priv;
+  const gchar *id;
+
+  priv = gdu_create_other_page_get_instance_private (page);
+  id = other_fs[priv->current_index];
+
+  if (id == NULL)
+    {
+      gtk_widget_show_all (GTK_WIDGET (priv->other_fs_box));
+      return;
+    }
+
+#ifdef HAVE_UDISKS2_7_2
+   if (!tested)
+    {
+      udisks_manager_call_can_format (udisks_client_get_manager (priv->client), id,
+                                      NULL, (GAsyncReadyCallback) can_format_cb, page);
+      return;
+    }
+#endif
+
+  if (priv->prev_other_fs_radio != NULL)
+    group = gtk_radio_button_get_group (priv->prev_other_fs_radio);
+
+  priv->prev_other_fs_radio = GTK_RADIO_BUTTON (gtk_radio_button_new_with_label (group, get_fs_description 
(id)));
+  gtk_box_pack_start (GTK_BOX (priv->other_fs_box), GTK_WIDGET (priv->prev_other_fs_radio), TRUE, TRUE, 0);
+  g_signal_connect (priv->prev_other_fs_radio, "toggled", G_CALLBACK (on_other_fs_selected), page);
+  g_object_set_data_full (G_OBJECT (priv->prev_other_fs_radio), "id", g_strdup (id), g_free);
+
+  if (!available)
+    {
+      gchar *s;
+
+      gtk_widget_set_sensitive (GTK_WIDGET (priv->prev_other_fs_radio), FALSE);
+      s = g_strdup_printf (_("The utility %s is missing."), missing_util);
+      gtk_widget_set_tooltip_text (GTK_WIDGET (priv->prev_other_fs_radio), s);
+
+      g_free (s);
+    }
+
+  if (priv->other_fs_type == NULL && available)
+    {
+      priv->other_fs_type = id;
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->prev_other_fs_radio), TRUE);
+    }
+
+  priv->current_index++;
+  row_adder (page, FALSE, TRUE, NULL);
+}
+
+static void
+on_fs_type_changed (GtkToggleButton *object, gpointer user_data)
+{
+  GduCreateOtherPage *page = GDU_CREATE_OTHER_PAGE (user_data);
+
+  g_object_notify (G_OBJECT (page), "complete");
+}
+
+
+GduCreateOtherPage *
+gdu_create_other_page_new (UDisksClient *client)
+{
+  GduCreateOtherPage *page;
+  GduCreateOtherPagePrivate *priv;
+
+  page = g_object_new (GDU_TYPE_CREATE_OTHER_PAGE, NULL);
+  priv = gdu_create_other_page_get_instance_private (page);
+  priv->client = client;
+  g_signal_connect (priv->other_encrypt_checkbutton, "toggled", G_CALLBACK (on_fs_type_changed), page);
+
+  /* custom format page content is empty on loading */
+  priv->other_fs_type = NULL;
+  priv->current_index = 0;
+  row_adder (page, FALSE, TRUE, NULL);
+
+  return page;
+}
diff --git a/src/disks/gducreateotherpage.h b/src/disks/gducreateotherpage.h
new file mode 100644
index 0000000..eeb576d
--- /dev/null
+++ b/src/disks/gducreateotherpage.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#ifndef __GDU_CREATE_OTHER_PAGE_H__
+#define __GDU_CREATE_OTHER_PAGE_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+#define GDU_TYPE_CREATE_OTHER_PAGE gdu_create_other_page_get_type ()
+G_DECLARE_FINAL_TYPE (GduCreateOtherPage, gdu_create_other_page, GDU, CREATE_OTHER_PAGE, GtkBox)
+
+GduCreateOtherPage *gdu_create_other_page_new          (UDisksClient *client);
+
+gboolean            gdu_create_other_page_is_encrypted (GduCreateOtherPage *page);
+
+const gchar *       gdu_create_other_page_get_fs       (GduCreateOtherPage *page);
+
+G_END_DECLS
+
+#endif /* __GDU_CREATE_OTHER_PAGE_H__ */
diff --git a/src/disks/gducreatepartitionpage.c b/src/disks/gducreatepartitionpage.c
new file mode 100644
index 0000000..1a4ed1a
--- /dev/null
+++ b/src/disks/gducreatepartitionpage.c
@@ -0,0 +1,339 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2013 Red Hat, Inc.
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: David Zeuthen <zeuthen gmail com>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <math.h>
+
+#include "gducreatepartitionpage.h"
+
+struct _GduCreatePartitionPage
+{
+  GtkBox parent_instance;
+};
+
+typedef struct _GduCreatePartitionPagePrivate GduCreatePartitionPagePrivate;
+
+struct _GduCreatePartitionPagePrivate
+{
+  GtkWidget *infobar_vbox;
+  GtkWidget *dos_error_infobar;
+  GtkWidget *dos_warning_infobar;
+  GtkWidget *size_spinbutton;
+  GtkWidget *free_following_spinbutton;
+  GtkAdjustment *size_adjustment;
+  GtkAdjustment *free_following_adjustment;
+  GtkWidget *size_unit_combobox;
+  GtkWidget *size_unit_following_label;
+  GtkCheckButton *part_dos_extended_checkbutton;
+
+  UDisksClient *client;
+  UDisksPartitionTable *table;
+  guint64 max_size;
+  guint64 offset;
+  gint cur_unit_num;
+  gboolean complete;
+};
+
+enum
+{
+  PROP_0,
+  PROP_COMPLETE
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GduCreatePartitionPage, gdu_create_partition_page, GTK_TYPE_BOX);
+
+static void
+gdu_create_partition_page_init (GduCreatePartitionPage *page)
+{
+  gtk_widget_init_template (GTK_WIDGET (page));
+}
+
+static void
+gdu_create_partition_page_get_property (GObject    *object,
+                                        guint       property_id,
+                                        GValue     *value,
+                                        GParamSpec *pspec)
+{
+  GduCreatePartitionPage *page = GDU_CREATE_PARTITION_PAGE (object);
+  GduCreatePartitionPagePrivate *priv;
+
+  priv = gdu_create_partition_page_get_instance_private (page);
+
+  switch (property_id)
+    {
+    case PROP_COMPLETE:
+      g_value_set_boolean (value, priv->complete);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gdu_create_partition_page_class_init (GduCreatePartitionPageClass *class)
+{
+  GObjectClass *gobject_class;
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gnome/Disks/ui/create-partition-page.ui");
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePartitionPage, 
infobar_vbox);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePartitionPage, 
size_spinbutton);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePartitionPage, 
free_following_spinbutton);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePartitionPage, 
size_adjustment);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePartitionPage, 
free_following_adjustment);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePartitionPage, 
size_unit_combobox);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePartitionPage, 
size_unit_following_label);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePartitionPage, 
part_dos_extended_checkbutton);
+
+  gobject_class = G_OBJECT_CLASS (class);
+  gobject_class->get_property = gdu_create_partition_page_get_property;
+  g_object_class_install_property (gobject_class, PROP_COMPLETE,
+                                   g_param_spec_boolean ("complete", NULL, NULL,
+                                                         FALSE,
+                                                         G_PARAM_READABLE |
+                                                         G_PARAM_STATIC_STRINGS));
+}
+
+gboolean
+gdu_create_partition_page_is_extended (GduCreatePartitionPage *page)
+{
+  GduCreatePartitionPagePrivate *priv;
+
+  priv = gdu_create_partition_page_get_instance_private (page);
+
+  return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->part_dos_extended_checkbutton));
+}
+
+guint64
+gdu_create_partition_page_get_size (GduCreatePartitionPage *page)
+{
+  GduCreatePartitionPagePrivate *priv;
+
+  priv = gdu_create_partition_page_get_instance_private (page);
+
+  return gtk_adjustment_get_value (priv->size_adjustment) * unit_sizes[priv->cur_unit_num];
+}
+
+guint64
+gdu_create_partition_page_get_offset (GduCreatePartitionPage *page)
+{
+  GduCreatePartitionPagePrivate *priv;
+
+  priv = gdu_create_partition_page_get_instance_private (page);
+
+  return priv->offset;
+}
+
+static void
+create_partition_update (GduCreatePartitionPage *page)
+{
+  GduCreatePartitionPagePrivate *priv;
+  gboolean can_proceed = FALSE;
+  gboolean show_dos_error = FALSE;
+  gboolean show_dos_warning = FALSE;
+  gchar *s;
+
+  priv = gdu_create_partition_page_get_instance_private (page);
+
+  /* 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_ (priv->table), "dos") == 0)
+    {
+      if (!gdu_utils_is_inside_dos_extended (priv->client, priv->table, priv->offset))
+        {
+          guint num_primary;
+          num_primary = gdu_utils_count_primary_dos_partitions (priv->client, priv->table);
+          if (num_primary == 4)
+            show_dos_error = TRUE;
+          else if (num_primary == 3)
+            show_dos_warning = TRUE;
+        }
+    }
+
+  if (gtk_adjustment_get_value (priv->size_adjustment) > 0 && !show_dos_error)
+    can_proceed = TRUE;
+
+  priv->complete = can_proceed;
+  g_object_notify (G_OBJECT (page), "complete");
+
+  gtk_widget_set_visible (priv->dos_warning_infobar, show_dos_warning);
+  gtk_widget_set_visible (priv->dos_error_infobar, show_dos_error);
+
+  s = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (priv->size_unit_combobox));
+  gtk_label_set_text (GTK_LABEL (priv->size_unit_following_label), s);
+  g_free (s);
+}
+
+static void
+create_partition_property_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
+{
+  GduCreatePartitionPage *page = GDU_CREATE_PARTITION_PAGE (user_data);
+
+  create_partition_update (page);
+}
+
+static void
+set_unit_num (GduCreatePartitionPage *page, gint unit_num)
+{
+  GduCreatePartitionPagePrivate *priv;
+  gdouble unit_size;
+  gdouble value;
+  gdouble value_units;
+  gdouble max_size_units;
+  gint num_digits;
+
+  priv = gdu_create_partition_page_get_instance_private (page);
+
+  g_assert (unit_num < NUM_UNITS);
+
+  gtk_combo_box_set_active (GTK_COMBO_BOX (priv->size_unit_combobox), unit_num);
+
+  if (priv->cur_unit_num == -1)
+    {
+      value = priv->max_size;
+    }
+  else
+    {
+      value = gtk_adjustment_get_value (priv->size_adjustment) * ((gdouble) unit_sizes[priv->cur_unit_num]);
+    }
+
+  unit_size = unit_sizes[unit_num];
+  value_units = value / unit_size;
+  max_size_units = ((gdouble) priv->max_size) / unit_size;
+
+  /* show at least three digits in the spin buttons */
+  num_digits = 3.0 - ceil (log10 (max_size_units));
+  if (num_digits < 0)
+    num_digits = 0;
+
+  g_object_freeze_notify (G_OBJECT (priv->size_adjustment));
+  g_object_freeze_notify (G_OBJECT (priv->free_following_adjustment));
+
+  priv->cur_unit_num = unit_num;
+
+  gtk_adjustment_configure (priv->size_adjustment,
+                            value_units,
+                            0.0,                    /* lower */
+                            max_size_units,         /* upper */
+                            1,                      /* step increment */
+                            100,                    /* page increment */
+                            0.0);                   /* page_size */
+  gtk_adjustment_configure (priv->free_following_adjustment,
+                            max_size_units - value_units,
+                            0.0,                    /* lower */
+                            max_size_units,         /* upper */
+                            1,                      /* step increment */
+                            100,                    /* page increment */
+                            0.0);                   /* page_size */
+
+  gtk_spin_button_set_digits (GTK_SPIN_BUTTON (priv->size_spinbutton), num_digits);
+  gtk_spin_button_set_digits (GTK_SPIN_BUTTON (priv->free_following_spinbutton), num_digits);
+
+  gtk_adjustment_set_value (priv->size_adjustment, value_units);
+  gtk_adjustment_set_value (priv->free_following_adjustment, max_size_units - value_units);
+
+  g_object_thaw_notify (G_OBJECT (priv->size_adjustment));
+  g_object_thaw_notify (G_OBJECT (priv->free_following_adjustment));
+}
+
+static void
+create_partition_populate (GduCreatePartitionPage *page)
+{
+  GduCreatePartitionPagePrivate *priv;
+
+  priv = gdu_create_partition_page_get_instance_private (page);
+
+  set_unit_num (page, gdu_utils_get_default_unit (priv->max_size));
+}
+
+static void
+on_size_unit_combobox_changed (GtkComboBox *combobox, GduCreatePartitionPage *page)
+{
+  GduCreatePartitionPagePrivate *priv;
+  gint unit_num;
+
+  priv = gdu_create_partition_page_get_instance_private (page);
+
+  unit_num = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->size_unit_combobox));
+  set_unit_num (page, unit_num);
+
+  create_partition_update (page);
+}
+
+static gboolean
+size_binding_func (GBinding *binding, const GValue *source_value, GValue *target_value, gpointer user_data)
+{
+  GduCreatePartitionPage *page = GDU_CREATE_PARTITION_PAGE (user_data);
+  GduCreatePartitionPagePrivate *priv;
+  gdouble max_size_units;
+
+  priv = gdu_create_partition_page_get_instance_private (page);
+
+  max_size_units = ((gdouble) priv->max_size) / unit_sizes[priv->cur_unit_num];
+  g_value_set_double (target_value, max_size_units - g_value_get_double (source_value));
+
+  return TRUE;
+}
+
+static void
+on_part_type_changed (GtkToggleButton *object, gpointer user_data)
+{
+  GduCreatePartitionPage *page = GDU_CREATE_PARTITION_PAGE (user_data);
+
+  g_object_notify (G_OBJECT (page), "complete");
+}
+
+GduCreatePartitionPage *
+gdu_create_partition_page_new (UDisksClient *client, UDisksPartitionTable *table,
+                               guint64 max_size, guint64 offset)
+{
+  GduCreatePartitionPage *page;
+  GduCreatePartitionPagePrivate *priv;
+
+  page = g_object_new (GDU_TYPE_CREATE_PARTITION_PAGE, NULL);
+  priv = gdu_create_partition_page_get_instance_private (page);
+  priv->client = client;
+  priv->table = table;
+  priv->max_size = max_size;
+  priv->offset = offset;
+  priv->cur_unit_num = -1;
+
+  if (g_strcmp0 (udisks_partition_table_get_type_ (priv->table), "dos") != 0 ||
+      gdu_utils_have_dos_extended (priv->client, priv->table))
+    {
+      /* hide if already present or GPT */
+      gtk_widget_hide (GTK_WIDGET (priv->part_dos_extended_checkbutton));
+    }
+
+  priv->dos_error_infobar = gdu_utils_create_info_bar (GTK_MESSAGE_ERROR,
+                                                       _("Cannot create a new partition. There are already 
four primary partitions."),
+                                                       NULL);
+  gtk_box_pack_start (GTK_BOX (priv->infobar_vbox), priv->dos_error_infobar, TRUE, TRUE, 0);
+  priv->dos_warning_infobar = gdu_utils_create_info_bar (GTK_MESSAGE_WARNING,
+                                                         _("This is the last primary partition that can be 
created."),
+                                                         NULL);
+  gtk_box_pack_start (GTK_BOX (priv->infobar_vbox), priv->dos_warning_infobar, TRUE, TRUE, 0);
+  g_signal_connect (priv->size_adjustment, "notify::value", G_CALLBACK (create_partition_property_changed), 
page);
+  g_signal_connect (priv->size_unit_combobox, "changed", G_CALLBACK (on_size_unit_combobox_changed), page);
+
+  g_signal_connect (priv->part_dos_extended_checkbutton, "toggled", G_CALLBACK (on_part_type_changed), page);
+
+  create_partition_populate (page);
+  create_partition_update (page);
+
+  g_object_bind_property_full (priv->size_adjustment, "value", priv->free_following_adjustment, "value",
+                               G_BINDING_BIDIRECTIONAL, size_binding_func, size_binding_func, page, NULL);
+
+  return page;
+}
diff --git a/src/disks/gducreatepartitionpage.h b/src/disks/gducreatepartitionpage.h
new file mode 100644
index 0000000..2b97544
--- /dev/null
+++ b/src/disks/gducreatepartitionpage.h
@@ -0,0 +1,34 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#ifndef __GDU_CREATE_PARTITION_PAGE_H__
+#define __GDU_CREATE_PARTITION_PAGE_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+#define GDU_TYPE_CREATE_PARTITION_PAGE gdu_create_partition_page_get_type ()
+G_DECLARE_FINAL_TYPE (GduCreatePartitionPage, gdu_create_partition_page, GDU, CREATE_PARTITION_PAGE, GtkBox)
+
+GduCreatePartitionPage *gdu_create_partition_page_new         (UDisksClient         *client,
+                                                               UDisksPartitionTable *table,
+                                                               guint64               max_size,
+                                                               guint64               offset);
+
+gboolean                gdu_create_partition_page_is_extended (GduCreatePartitionPage *page);
+
+guint64                 gdu_create_partition_page_get_size    (GduCreatePartitionPage *page);
+
+guint64                 gdu_create_partition_page_get_offset  (GduCreatePartitionPage *page);
+
+G_END_DECLS
+
+#endif /* __GDU_CREATE_PARTITION_PAGE_H__ */
diff --git a/src/disks/gducreatepasswordpage.c b/src/disks/gducreatepasswordpage.c
new file mode 100644
index 0000000..af91565
--- /dev/null
+++ b/src/disks/gducreatepasswordpage.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "gducreatepasswordpage.h"
+#include "gdupasswordstrengthwidget.h"
+
+struct _GduCreatePasswordPage
+{
+  GtkGrid parent_instance;
+};
+
+typedef struct _GduCreatePasswordPagePrivate GduCreatePasswordPagePrivate;
+
+struct _GduCreatePasswordPagePrivate
+{
+  GtkEntry *password_entry;
+  GtkEntry *confirm_password_entry;
+  GtkCheckButton *show_password_checkbutton;
+  GtkBox *password_strength_box;
+  GtkWidget *password_strengh_widget;
+
+  gboolean complete;
+};
+
+enum
+{
+  PROP_0,
+  PROP_COMPLETE
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GduCreatePasswordPage, gdu_create_password_page, GTK_TYPE_GRID);
+
+static void
+gdu_create_password_page_init (GduCreatePasswordPage *page)
+{
+  gtk_widget_init_template (GTK_WIDGET (page));
+}
+
+static void
+gdu_create_password_page_get_property (GObject    *object,
+                                       guint       property_id,
+                                       GValue     *value,
+                                       GParamSpec *pspec)
+{
+  GduCreatePasswordPage *page = GDU_CREATE_PASSWORD_PAGE (object);
+  GduCreatePasswordPagePrivate *priv;
+
+  priv = gdu_create_password_page_get_instance_private (page);
+
+  switch (property_id)
+    {
+    case PROP_COMPLETE:
+      g_value_set_boolean (value, priv->complete);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gdu_create_password_page_class_init (GduCreatePasswordPageClass *class)
+{
+  GObjectClass *gobject_class;
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gnome/Disks/ui/create-password-page.ui");
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePasswordPage, 
password_strength_box);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePasswordPage, 
password_entry);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePasswordPage, 
confirm_password_entry);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), GduCreatePasswordPage, 
show_password_checkbutton);
+
+  gobject_class = G_OBJECT_CLASS (class);
+  gobject_class->get_property = gdu_create_password_page_get_property;
+  g_object_class_install_property (gobject_class, PROP_COMPLETE,
+                                   g_param_spec_boolean ("complete", NULL, NULL,
+                                                         FALSE,
+                                                         G_PARAM_READABLE |
+                                                         G_PARAM_STATIC_STRINGS));
+}
+
+const gchar *
+gdu_create_password_page_get_password (GduCreatePasswordPage *page)
+{
+  GduCreatePasswordPagePrivate *priv;
+
+  priv = gdu_create_password_page_get_instance_private (page);
+
+  return gtk_entry_get_text (priv->password_entry);
+}
+
+static void
+on_password_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
+{
+  GduCreatePasswordPage *page = GDU_CREATE_PASSWORD_PAGE (user_data);
+  GduCreatePasswordPagePrivate *priv;
+  gboolean can_proceed = FALSE;
+
+  priv = gdu_create_password_page_get_instance_private (page);
+
+  gtk_entry_set_icon_from_icon_name (priv->confirm_password_entry, GTK_ENTRY_ICON_SECONDARY, NULL);
+  gtk_entry_set_icon_tooltip_text (priv->confirm_password_entry, GTK_ENTRY_ICON_SECONDARY, NULL);
+
+  if (gtk_entry_get_text_length (priv->password_entry) > 0)
+    {
+      if (g_strcmp0 (gtk_entry_get_text (priv->password_entry),
+                     gtk_entry_get_text (priv->confirm_password_entry)) == 0)
+        {
+          can_proceed = TRUE;
+        }
+      else if (gtk_entry_get_text_length (priv->confirm_password_entry) > 0)
+        {
+          gtk_entry_set_icon_from_icon_name (priv->confirm_password_entry, GTK_ENTRY_ICON_SECONDARY, 
"dialog-warning-symbolic");
+          gtk_entry_set_icon_tooltip_text (priv->confirm_password_entry, GTK_ENTRY_ICON_SECONDARY, _("The 
passwords do not match"));
+        }
+    }
+
+  gdu_password_strength_widget_set_password (GDU_PASSWORD_STRENGTH_WIDGET (priv->password_strengh_widget),
+                                             gtk_entry_get_text (priv->password_entry));
+
+  priv->complete = can_proceed;
+  g_object_notify (G_OBJECT (page), "complete");
+}
+
+GduCreatePasswordPage *
+gdu_create_password_page_new (void)
+{
+  GduCreatePasswordPage *page;
+  GduCreatePasswordPagePrivate *priv;
+
+  page = g_object_new (GDU_TYPE_CREATE_PASSWORD_PAGE, NULL);
+  priv = gdu_create_password_page_get_instance_private (page);
+  g_signal_connect (priv->password_entry, "notify::text", G_CALLBACK (on_password_changed), page);
+  g_signal_connect (priv->confirm_password_entry, "notify::text", G_CALLBACK (on_password_changed), page);
+  g_object_bind_property (priv->show_password_checkbutton, "active", priv->password_entry, "visibility", 
G_BINDING_SYNC_CREATE);
+  g_object_bind_property (priv->show_password_checkbutton, "active", priv->confirm_password_entry, 
"visibility", G_BINDING_SYNC_CREATE);
+  priv->password_strengh_widget = gdu_password_strength_widget_new ();
+  gtk_box_pack_start (priv->password_strength_box, priv->password_strengh_widget, TRUE, TRUE, 0);
+
+  return page;
+}
diff --git a/src/disks/gducreatepasswordpage.h b/src/disks/gducreatepasswordpage.h
new file mode 100644
index 0000000..f60ef33
--- /dev/null
+++ b/src/disks/gducreatepasswordpage.h
@@ -0,0 +1,27 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2017 Kai Lüke
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: Kai Lüke <kailueke riseup net>
+ */
+
+#ifndef __GDU_CREATE_PASSWORD_PAGE_H__
+#define __GDU_CREATE_PASSWORD_PAGE_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+#define GDU_TYPE_CREATE_PASSWORD_PAGE gdu_create_password_page_get_type ()
+G_DECLARE_FINAL_TYPE (GduCreatePasswordPage, gdu_create_password_page, GDU, CREATE_PASSWORD_PAGE, GtkGrid)
+
+GduCreatePasswordPage *gdu_create_password_page_new          (void);
+
+const gchar *          gdu_create_password_page_get_password (GduCreatePasswordPage *page);
+
+G_END_DECLS
+
+#endif /* __GDU_CREATE_PASSWORD_PAGE_H__ */
diff --git a/src/disks/gduformatdiskdialog.c b/src/disks/gduformatdiskdialog.c
index 32fce3d..dfac028 100644
--- a/src/disks/gduformatdiskdialog.c
+++ b/src/disks/gduformatdiskdialog.c
@@ -15,7 +15,6 @@
 #include "gduwindow.h"
 #include "gduformatdiskdialog.h"
 #include "gduvolumegrid.h"
-#include "gducreatefilesystemwidget.h"
 
 /* ---------------------------------------------------------------------------------------------------- */
 
diff --git a/src/disks/gdupasswordstrengthwidget.c b/src/disks/gdupasswordstrengthwidget.c
index 6f4138c..8a1a3b7 100644
--- a/src/disks/gdupasswordstrengthwidget.c
+++ b/src/disks/gdupasswordstrengthwidget.c
@@ -195,6 +195,7 @@ gdu_password_strength_widget_constructed (GObject *object)
 
   widget->notebook = gtk_notebook_new ();
   gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget->notebook), FALSE);
+  gtk_notebook_set_show_border (GTK_NOTEBOOK (widget->notebook), FALSE);
   gtk_box_pack_start (GTK_BOX (widget), widget->notebook, FALSE, TRUE, 0);
 
   for (n = 0; n < G_N_ELEMENTS (hint_labels); n++)
diff --git a/src/disks/gduwindow.c b/src/disks/gduwindow.c
index 7f80dd0..8d2c1a4 100644
--- a/src/disks/gduwindow.c
+++ b/src/disks/gduwindow.c
@@ -30,8 +30,7 @@
 #include "gdufilesystemdialog.h"
 #include "gdupartitiondialog.h"
 #include "gduunlockdialog.h"
-#include "gduformatvolumedialog.h"
-#include "gducreatepartitiondialog.h"
+#include "gducreateformatdialog.h"
 #include "gduformatdiskdialog.h"
 #include "gducreatediskimagedialog.h"
 #include "gdurestorediskimagedialog.h"
@@ -3422,7 +3421,7 @@ on_generic_menu_item_format_volume (GtkMenuItem *menu_item,
 
   object = gdu_volume_grid_get_selected_device (GDU_VOLUME_GRID (window->volume_grid));
   g_assert (object != NULL);
-  gdu_format_volume_dialog_show (window, object);
+  gdu_create_format_show (gdu_window_get_client (window), GTK_WINDOW (window), object, TRUE, FALSE, 0, 0, 
NULL, NULL);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -3878,10 +3877,14 @@ on_partition_create_tool_button_clicked (GtkToolButton *button, gpointer user_da
 
   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)));
+  gdu_create_format_show (window->client,
+                          GTK_WINDOW (window),
+                          object,
+                          TRUE,
+                          TRUE,
+                          gdu_volume_grid_get_selected_offset (GDU_VOLUME_GRID (window->volume_grid)),
+                          gdu_volume_grid_get_selected_size (GDU_VOLUME_GRID (window->volume_grid)),
+                          NULL, NULL);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/disks/gnome-disks.gresource.xml b/src/disks/gnome-disks.gresource.xml
index 17dbfc9..759f4c2 100644
--- a/src/disks/gnome-disks.gresource.xml
+++ b/src/disks/gnome-disks.gresource.xml
@@ -5,8 +5,12 @@
     <file preprocess="xml-stripblanks">ui/app-menu.ui</file>
     <file preprocess="xml-stripblanks">ui/benchmark-dialog.ui</file>
     <file preprocess="xml-stripblanks">ui/change-passphrase-dialog.ui</file>
+    <file preprocess="xml-stripblanks">ui/create-confirm-page.ui</file>
     <file preprocess="xml-stripblanks">ui/create-disk-image-dialog.ui</file>
-    <file preprocess="xml-stripblanks">ui/create-partition-dialog.ui</file>
+    <file preprocess="xml-stripblanks">ui/create-filesystem-page.ui</file>
+    <file preprocess="xml-stripblanks">ui/create-other-page.ui</file>
+    <file preprocess="xml-stripblanks">ui/create-partition-page.ui</file>
+    <file preprocess="xml-stripblanks">ui/create-password-page.ui</file>
     <file preprocess="xml-stripblanks">ui/disk-settings-dialog.ui</file>
     <file preprocess="xml-stripblanks">ui/disks.ui</file>
     <file preprocess="xml-stripblanks">ui/edit-crypttab-dialog.ui</file>
@@ -16,9 +20,8 @@
     <file preprocess="xml-stripblanks">ui/edit-gpt-partition-dialog.ui</file>
     <file preprocess="xml-stripblanks">ui/edit-partition-dialog.ui</file>
     <file preprocess="xml-stripblanks">ui/erase-multiple-disks-dialog.ui</file>
-    <file preprocess="xml-stripblanks">ui/filesystem-create.ui</file>
     <file preprocess="xml-stripblanks">ui/format-disk-dialog.ui</file>
-    <file preprocess="xml-stripblanks">ui/format-volume-dialog.ui</file>
+    <file preprocess="xml-stripblanks">ui/create-format.ui</file>
     <file preprocess="xml-stripblanks">ui/new-disk-image-dialog.ui</file>
     <file preprocess="xml-stripblanks">ui/resize-dialog.ui</file>
     <file preprocess="xml-stripblanks">ui/restore-disk-image-dialog.ui</file>
diff --git a/src/disks/meson.build b/src/disks/meson.build
index 5238163..a495474 100644
--- a/src/disks/meson.build
+++ b/src/disks/meson.build
@@ -7,9 +7,13 @@ sources = files(
   'gduatasmartdialog.c',
   'gdubenchmarkdialog.c',
   'gduchangepassphrasedialog.c',
+  'gducreateconfirmpage.c',
   'gducreatediskimagedialog.c',
-  'gducreatefilesystemwidget.c',
-  'gducreatepartitiondialog.c',
+  'gducreatefilesystempage.c',
+  'gducreateformatdialog.c',
+  'gducreateotherpage.c',
+  'gducreatepartitionpage.c',
+  'gducreatepasswordpage.c',
   'gducrypttabdialog.c',
   'gdudevicetreemodel.c',
   'gdudisksettingsdialog.c',
@@ -17,7 +21,6 @@ sources = files(
   'gduestimator.c',
   'gdufilesystemdialog.c',
   'gduformatdiskdialog.c',
-  'gduformatvolumedialog.c',
   'gdufstabdialog.c',
   'gdulocaljob.c',
   'gdunewdiskimagedialog.c',
@@ -40,8 +43,13 @@ resource_data = files(
   'ui/app-menu.ui',
   'ui/benchmark-dialog.ui',
   'ui/change-passphrase-dialog.ui',
+  'ui/create-confirm-page.ui',
   'ui/create-disk-image-dialog.ui',
-  'ui/create-partition-dialog.ui',
+  'ui/create-filesystem-page.ui',
+  'ui/create-format.ui',
+  'ui/create-other-page.ui',
+  'ui/create-partition-page.ui',
+  'ui/create-password-page.ui',
   'ui/disk-settings-dialog.ui',
   'ui/disks.ui',
   'ui/edit-crypttab-dialog.ui',
@@ -51,9 +59,7 @@ resource_data = files(
   'ui/edit-fstab-dialog.ui',
   'ui/edit-partition-dialog.ui',
   'ui/erase-multiple-disks-dialog.ui',
-  'ui/filesystem-create.ui',
   'ui/format-disk-dialog.ui',
-  'ui/format-volume-dialog.ui',
   'ui/gdu.css',
   'ui/new-disk-image-dialog.ui',
   'ui/resize-dialog.ui',
diff --git a/src/disks/ui/create-confirm-page.ui b/src/disks/ui/create-confirm-page.ui
new file mode 100644
index 0000000..509f57c
--- /dev/null
+++ b/src/disks/ui/create-confirm-page.ui
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <template class="GduCreateConfirmPage" parent="GtkGrid">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_top">40</property>
+    <property name="row_spacing">10</property>
+    <property name="column_spacing">10</property>
+    <child>
+      <object class="GtkLabel" id="warning_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_bottom">10</property>
+        <property name="hexpand">True</property>
+        <property name="label" translatable="yes">Warning: all data on the volume will be lost</property>
+        <style>
+          <class name="warning-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+        <property name="width">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="confirm_info_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_bottom">50</property>
+        <property name="label" translatable="yes">Confirm the details of the current volume before 
proceeding.</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+        <property name="width">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="device_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="label" translatable="yes">Device</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="device_name_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="volume_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="label" translatable="yes">Volume</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">3</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="volume_name_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">3</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="used_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="label" translatable="yes">Used</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">4</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="location_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="label" translatable="yes">Location</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">5</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="used_amount_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">4</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="location_path_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">5</property>
+      </packing>
+    </child>
+  </template>
+</interface>
diff --git a/src/disks/ui/create-filesystem-page.ui b/src/disks/ui/create-filesystem-page.ui
new file mode 100644
index 0000000..aaf674a
--- /dev/null
+++ b/src/disks/ui/create-filesystem-page.ui
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <template class="GduCreateFilesystemPage" parent="GtkGrid">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_left">40</property>
+    <property name="margin_right">40</property>
+    <property name="margin_top">40</property>
+    <property name="margin_bottom">40</property>
+    <property name="row_spacing">8</property>
+    <property name="column_spacing">16</property>
+    <child>
+      <object class="GtkLabel" id="name_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="label" translatable="yes">Volume _Name</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">name_entry</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="name_entry">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="has_tooltip">True</property>
+        <property name="tooltip_text" translatable="yes">The name to use for the filesystem. This is useful 
if you want to refer to the device via a symlink in the /dev/disk/by-label directory.</property>
+        <property name="activates_default">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="name_description_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="margin_bottom">20</property>
+        <property name="label" translatable="yes">For example: "Angela's Files" or "Backup".</property>
+        <style>
+          <class name="dim-label"/>
+          <class name="explanation-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkSwitch" id="erase_switch">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="halign">start</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="erase_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="label" translatable="yes">_Erase</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">erase_switch</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="erase_description_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="margin_bottom">20</property>
+        <property name="label" translatable="yes">Overwrites existing data, but takes longer.</property>
+        <style>
+          <class name="dim-label"/>
+          <class name="explanation-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">3</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="type_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="label" translatable="yes">Type</property>
+        <property name="mnemonic_widget">internal_radiobutton</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">4</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkRadioButton" id="internal_radiobutton">
+        <property name="label" translatable="yes">_Internal disk for use with Linux systems only 
(Ext4)</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="halign">start</property>
+        <property name="use_underline">True</property>
+        <property name="active">True</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">4</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkCheckButton" id="internal_encrypt_checkbutton">
+        <property name="label" translatable="yes">_Password protect volume (LUKS)</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="halign">start</property>
+        <property name="margin_left">18</property>
+        <property name="use_underline">True</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">5</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkRadioButton" id="windows_radiobutton">
+        <property name="label" translatable="yes">For use with _Windows (NTFS)</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="halign">start</property>
+        <property name="use_underline">True</property>
+        <property name="draw_indicator">True</property>
+        <property name="group">internal_radiobutton</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">6</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkRadioButton" id="all_radiobutton">
+        <property name="label" translatable="yes">For use with all _systems and devices (FAT)</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="halign">start</property>
+        <property name="use_underline">True</property>
+        <property name="draw_indicator">True</property>
+        <property name="group">internal_radiobutton</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">7</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkRadioButton" id="other_radiobutton">
+        <property name="label" translatable="yes">_Other</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="halign">start</property>
+        <property name="use_underline">True</property>
+        <property name="draw_indicator">True</property>
+        <property name="group">internal_radiobutton</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">8</property>
+      </packing>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+  </template>
+</interface>
diff --git a/src/disks/ui/create-format.ui b/src/disks/ui/create-format.ui
new file mode 100644
index 0000000..52c83c9
--- /dev/null
+++ b/src/disks/ui/create-format.ui
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkDialog" id="create-format">
+    <property name="width_request">600</property>
+    <property name="can_focus">False</property>
+    <property name="resizable">False</property>
+    <property name="modal">True</property>
+    <property name="use-header-bar">1</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <property name="border_width">0</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkStack" id="pages-stack">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="transition_type">crossfade</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="titlebar">
+      <placeholder/>
+    </child>
+  </object>
+</interface>
diff --git a/src/disks/ui/create-other-page.ui b/src/disks/ui/create-other-page.ui
new file mode 100644
index 0000000..502be5c
--- /dev/null
+++ b/src/disks/ui/create-other-page.ui
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <template class="GduCreateOtherPage" parent="GtkBox">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_left">40</property>
+    <property name="margin_right">40</property>
+    <property name="margin_top">40</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkLabel" id="other_explain_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_bottom">25</property>
+        <property name="label" translatable="yes">In case that the default options do not fit your needs 
select one of the following filesystems. Be aware of the technical differences and do research about your use 
case.</property>
+        <property name="wrap">True</property>
+        <property name="max_width_chars">40</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkBox" id="other_fs_box">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">20</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkCheckButton" id="other_encrypt_checkbutton">
+        <property name="label" translatable="yes">_Password protect volume (LUKS)</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="halign">end</property>
+        <property name="margin_top">2</property>
+        <property name="margin_bottom">20</property>
+        <property name="use_underline">True</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="pack_type">end</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+  </template>
+</interface>
diff --git a/src/disks/ui/create-partition-page.ui b/src/disks/ui/create-partition-page.ui
new file mode 100644
index 0000000..534671e
--- /dev/null
+++ b/src/disks/ui/create-partition-page.ui
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <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>
+  <template class="GduCreatePartitionPage" parent="GtkBox">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="orientation">vertical</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>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkBox" id="box2">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">40</property>
+        <property name="margin_right">40</property>
+        <property name="margin_top">40</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">20</property>
+        <child>
+          <object class="GtkScale" id="size_scale">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="adjustment">size_adjustment</property>
+            <property name="restrict_to_fill_level">False</property>
+            <property name="draw_value">False</property>
+            <property name="value_pos">bottom</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="size_number_grid">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="row_spacing">6</property>
+            <property name="column_spacing">6</property>
+            <property name="baseline_row">1</property>
+            <child>
+              <object class="GtkLabel" id="label3">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="hexpand">True</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">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_text" translatable="yes">The size of the partition to 
create</property>
+                <property name="activates_default">True</property>
+                <property name="text" translatable="yes">0</property>
+                <property name="adjustment">size_adjustment</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkComboBoxText" id="size_unit_combobox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">start</property>
+                <property name="hexpand">True</property>
+                <property name="active">2</property>
+                <items>
+                  <item translatable="yes">bytes</item>
+                  <item translatable="yes">kB</item>
+                  <item translatable="yes">MB</item>
+                  <item translatable="yes">GB</item>
+                  <item translatable="yes">TB</item>
+                  <item translatable="yes">PB</item>
+                  <item translatable="yes">KiB</item>
+                  <item translatable="yes">MiB</item>
+                  <item translatable="yes">GiB</item>
+                  <item translatable="yes">TiB</item>
+                  <item translatable="yes">PiB</item>
+                </items>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="top_attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label4">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="hexpand">True</property>
+                <property name="label" translatable="yes">Free Space _Following</property>
+                <property name="use_underline">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSpinButton" id="free_following_spinbutton">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="has_tooltip">True</property>
+                <property name="tooltip_text" translatable="yes">The free space following the 
partition</property>
+                <property name="activates_default">True</property>
+                <property name="text" translatable="yes">0</property>
+                <property name="adjustment">free_following_adjustment</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="size_unit_following_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">start</property>
+                <property name="hexpand">True</property>
+                <property name="label">MB</property>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="top_attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="part_dos_extended_checkbutton">
+                <property name="label" translatable="yes">Extended Partition</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="tooltip_text" translatable="yes">Extended Partitions can contain Logical 
Partitions</property>
+                <property name="halign">start</property>
+                <property name="draw_indicator">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">2</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+  </template>
+</interface>
diff --git a/src/disks/ui/create-password-page.ui b/src/disks/ui/create-password-page.ui
new file mode 100644
index 0000000..d9abcbd
--- /dev/null
+++ b/src/disks/ui/create-password-page.ui
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <template class="GduCreatePasswordPage" parent="GtkGrid">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_left">40</property>
+    <property name="margin_right">40</property>
+    <property name="margin_top">40</property>
+    <property name="row_spacing">10</property>
+    <property name="column_spacing">15</property>
+    <child>
+      <object class="GtkLabel" id="password_description_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_bottom">30</property>
+        <property name="label" translatable="yes">Data stored in the volume will only be accessible with the 
correct password. Be careful not to forget it.</property>
+        <property name="wrap">True</property>
+        <property name="max_width_chars">55</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+        <property name="width">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="password_label ">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="margin_left">40</property>
+        <property name="label" translatable="yes">_Password</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">password_entry</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="confirm_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="label" translatable="yes">_Confirm</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">confirm_password_entry</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">4</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="password_entry">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="no_show_all">True</property>
+        <property name="has_tooltip">True</property>
+        <property name="tooltip_text" translatable="yes">Enter passphrase used to protect the data</property>
+        <property name="margin_right">20</property>
+        <property name="hexpand">True</property>
+        <property name="visibility">False</property>
+        <property name="invisible_char">●</property>
+        <property name="activates_default">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="confirm_password_entry">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="no_show_all">True</property>
+        <property name="has_tooltip">True</property>
+        <property name="tooltip_text" translatable="yes">Confirm passphrase entered above</property>
+        <property name="margin_right">20</property>
+        <property name="hexpand">True</property>
+        <property name="visibility">False</property>
+        <property name="invisible_char">●</property>
+        <property name="activates_default">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">4</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkCheckButton" id="show_password_checkbutton">
+        <property name="label" translatable="yes">Sh_ow Password</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="no_show_all">True</property>
+        <property name="has_tooltip">True</property>
+        <property name="tooltip_text" translatable="yes">Check this box to see the passphrases entered 
above</property>
+        <property name="halign">start</property>
+        <property name="valign">start</property>
+        <property name="use_underline">True</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">5</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkBox" id="password_strength_box">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="no_show_all">True</property>
+        <property name="margin_right">20</property>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="strength_hint_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="margin_right">20</property>
+        <property name="margin_bottom">30</property>
+        <property name="label" translatable="yes">Mix uppercase and lowercase and try to use a number or 
two.</property>
+        <style>
+          <class name="dim-label"/>
+          <class name="explanation-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">3</property>
+      </packing>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+  </template>
+</interface>
diff --git a/src/disks/ui/gdu.css b/src/disks/ui/gdu.css
index f3a482e..2308e9e 100644
--- a/src/disks/ui/gdu.css
+++ b/src/disks/ui/gdu.css
@@ -38,3 +38,11 @@
 .partition-scale contents trough {
        margin-left: -2px;
 }
+
+.explanation-label {
+       font-size: small;
+}
+
+.warning-label {
+       font-size: x-large;
+}


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