[gnome-disk-utility] Add erase option when formatting, show job progress and allow job cancelation



commit 92d6ccfa623b4d2a1b67e5f3559517a214c24d9b
Author: David Zeuthen <zeuthen gmail com>
Date:   Mon Jun 25 11:50:53 2012 -0400

    Add erase option when formatting, show job progress and allow job cancelation
    
     http://people.freedesktop.org/~david/gnome-disks-erase-overwrite-option.png
     http://people.freedesktop.org/~david/gnome-disks-long-running-operations.png
    
    Signed-off-by: David Zeuthen <zeuthen gmail com>

 data/ui/disks.ui                      |  609 +++++++++++++++++++--------------
 data/ui/filesystem-create.ui          |   74 +++--
 data/ui/format-disk-dialog.ui         |   38 ++-
 src/disks/gducreatefilesystemwidget.c |   61 ++++
 src/disks/gducreatefilesystemwidget.h |    1 +
 src/disks/gducreatepartitiondialog.c  |    5 +
 src/disks/gdudevicetreemodel.c        |    4 +-
 src/disks/gduformatdiskdialog.c       |   68 ++++-
 src/disks/gduformatvolumedialog.c     |    5 +
 src/disks/gduwindow.c                 |  221 ++++++++++++-
 10 files changed, 799 insertions(+), 287 deletions(-)
---
diff --git a/data/ui/disks.ui b/data/ui/disks.ui
index 18bd362..c636247 100644
--- a/data/ui/disks.ui
+++ b/data/ui/disks.ui
@@ -69,200 +69,6 @@
       </object>
     </child>
   </object>
-  <object class="GtkMenu" id="generic-drive-menu">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <child>
-      <object class="GtkMenuItem" id="generic-drive-menu-item-format-disk">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Format Disk...</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkSeparatorMenuItem" id="menuitem4">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-drive-menu-item-create-disk-image">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Create Disk Image...</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-drive-menu-item-restore-disk-image">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Restore Disk Image...</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-drive-menu-item-benchmark">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Benchmark Drive...</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkSeparatorMenuItem" id="menuitem5">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-drive-menu-item-view-smart">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">SMART Data and Tests...</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-drive-menu-item-disk-settings">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Drive Settings...</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkSeparatorMenuItem" id="menuitem6">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-drive-menu-item-standby-now">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Standby Now</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-drive-menu-item-resume-now">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Wake-Up from Standby</property>
-      </object>
-    </child>
-  </object>
-  <object class="GtkMenu" id="generic-menu">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <child>
-      <object class="GtkMenuItem" id="generic-menu-item-format-volume">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Format...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkSeparatorMenuItem" id="menuitem3">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-menu-item-edit-partition">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Edit Partition Type...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-menu-item-edit-label">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Edit Filesystem Label...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-menu-item-change-passphrase">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Change Passphrase...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkSeparatorMenuItem" id="menuitem2">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-menu-item-configure-fstab">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Edit Mount Options...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-menu-item-configure-crypttab">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Edit Encryption Options...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkSeparatorMenuItem" id="menuitem1">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-menu-item-create-volume-image">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Create Disk Image...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-menu-item-restore-volume-image">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Restore Disk Image...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="generic-menu-item-benchmark">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="use_action_appearance">False</property>
-        <property name="label" translatable="yes">Benchmark Volume...</property>
-      </object>
-    </child>
-  </object>
   <object class="GtkWindow" id="disks-window">
     <property name="can_focus">False</property>
     <property name="border_width">12</property>
@@ -311,6 +117,7 @@
                 <property name="icon_size">1</property>
                 <child>
                   <object class="GtkToolButton" id="device-tree-attach-disk-image-button">
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="has_tooltip">True</property>
@@ -326,6 +133,7 @@
                 </child>
                 <child>
                   <object class="GtkToolButton" id="device-tree-detach-disk-image-button">
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="has_tooltip">True</property>
@@ -417,7 +225,7 @@
                   <object class="GtkTable" id="devtab-drive-table">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="n_rows">6</property>
+                    <property name="n_rows">9</property>
                     <property name="n_columns">2</property>
                     <property name="column_spacing">10</property>
                     <child>
@@ -426,9 +234,7 @@
                         <property name="can_focus">False</property>
                         <property name="xalign">1</property>
                         <property name="label" translatable="yes">Model</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
+                        <style><class name="dim-label"/></style>
                       </object>
                       <packing>
                         <property name="top_attach">1</property>
@@ -463,10 +269,7 @@
                         <property name="can_focus">False</property>
                         <property name="xalign">1</property>
                         <property name="label" translatable="yes">Serial Number</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
-
+                        <style><class name="dim-label"/></style>
                       </object>
                       <packing>
                         <property name="top_attach">4</property>
@@ -501,9 +304,7 @@
                         <property name="can_focus">False</property>
                         <property name="xalign">1</property>
                         <property name="label" translatable="yes">World Wide Name</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
+                        <style><class name="dim-label"/></style>
                       </object>
                       <packing>
                         <property name="top_attach">5</property>
@@ -532,16 +333,13 @@
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
-
                     <child>
                       <object class="GtkLabel" id="devtab-location-label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="xalign">1</property>
                         <property name="label" translatable="yes" comments="The physical location of the drive, could be 'Connected to another seat'  or 'Bay 11 of Promise VTrak' or 'USB connector II'">Location</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
+                        <style><class name="dim-label"/></style>
                       </object>
                       <packing>
                         <property name="top_attach">6</property>
@@ -570,17 +368,13 @@
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
-
                     <child>
                       <object class="GtkLabel" id="devtab-media-label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="xalign">1</property>
                         <property name="label" translatable="yes">Media</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
-
+                        <style><class name="dim-label"/></style>
                       </object>
                       <packing>
                         <property name="top_attach">2</property>
@@ -628,10 +422,7 @@
                         <property name="can_focus">False</property>
                         <property name="xalign">1</property>
                         <property name="label" translatable="yes">Size</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
-
+                        <style><class name="dim-label"/></style>
                       </object>
                       <packing>
                         <property name="top_attach">3</property>
@@ -666,9 +457,7 @@
                         <property name="can_focus">False</property>
                         <property name="xalign">1</property>
                         <property name="label" translatable="yes">Assessment</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
+                        <style><class name="dim-label"/></style>
                       </object>
                       <packing>
                         <property name="top_attach">7</property>
@@ -730,10 +519,7 @@
                                 <property name="selectable">True</property>
                                 <property name="ellipsize">end</property>
                                 <property name="single_line_mode">True</property>
-                                <style>
-                                  <class name="dim-label"/>
-                                </style>
-                             </object>
+                              </object>
                               <packing>
                                 <property name="expand">False</property>
                                 <property name="fill">True</property>
@@ -754,6 +540,8 @@
                             <property name="spacing">12</property>
                             <child>
                               <object class="GtkButton" id="devtab-drive-eject-button">
+                                <property name="use_action_appearance">False</property>
+                                <property name="related_action">devtab-action-eject</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
@@ -778,6 +566,8 @@
                             </child>
                             <child>
                               <object class="GtkButton" id="devtab-drive-generic-button">
+                                <property name="use_action_appearance">False</property>
+                                <property name="related_action">devtab-action-generic-drive</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
@@ -816,6 +606,73 @@
                         <property name="y_padding">4</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkLabel" id="devtab-drive-job-label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Pending Job</property>
+                        <style><class name="dim-label"/></style>
+                      </object>
+                      <packing>
+                        <property name="top_attach">8</property>
+                        <property name="bottom_attach">9</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                        <property name="y_padding">4</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkBox" id="devtab-drive-job-box">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkProgressBar" id="devtab-drive-job-progressbar">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="devtab-drive-job-id-label">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="devtab-drive-job-cancel-label">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">â &lt;a href="app://cancel"&gt;Cancel&lt;/a&gt;</property>
+                            <property name="use_markup">True</property>
+                            <property name="track_visited_links">False</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">8</property>
+                        <property name="bottom_attach">9</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -875,6 +732,7 @@
                                 <property name="icon_size">1</property>
                                 <child>
                                   <object class="GtkToolButton" id="toolbutton-mount">
+                                    <property name="related_action">devtab-action-mount</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="related_action">devtab-action-mount</property>
@@ -888,6 +746,7 @@
                                 </child>
                                 <child>
                                   <object class="GtkToolButton" id="toolbutton-unmount">
+                                    <property name="related_action">devtab-action-unmount</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="related_action">devtab-action-unmount</property>
@@ -901,6 +760,7 @@
                                 </child>
                                 <child>
                                   <object class="GtkToolButton" id="toolbutton-activate-swap">
+                                    <property name="related_action">devtab-action-activate-swap</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="related_action">devtab-action-activate-swap</property>
@@ -914,6 +774,7 @@
                                 </child>
                                 <child>
                                   <object class="GtkToolButton" id="toolbutton-deactivate-swap">
+                                    <property name="related_action">devtab-action-deactivate-swap</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="related_action">devtab-action-deactivate-swap</property>
@@ -927,6 +788,7 @@
                                 </child>
                                 <child>
                                   <object class="GtkToolButton" id="toolbutton-unlock">
+                                    <property name="related_action">devtab-action-unlock</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="related_action">devtab-action-unlock</property>
@@ -940,6 +802,7 @@
                                 </child>
                                 <child>
                                   <object class="GtkToolButton" id="toolbutton-lock">
+                                    <property name="related_action">devtab-action-lock</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="related_action">devtab-action-lock</property>
@@ -953,6 +816,7 @@
                                 </child>
                                 <child>
                                   <object class="GtkToolButton" id="toolbutton-partition-create">
+                                    <property name="related_action">devtab-action-partition-create</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="related_action">devtab-action-partition-create</property>
@@ -966,6 +830,7 @@
                                 </child>
                                 <child>
                                   <object class="GtkToolButton" id="toolbutton-partition-delete">
+                                    <property name="related_action">devtab-action-partition-delete</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="related_action">devtab-action-partition-delete</property>
@@ -979,6 +844,7 @@
                                 </child>
                                 <child>
                                   <object class="GtkToolButton" id="toolbutton-generic-menu">
+                                    <property name="related_action">devtab-action-generic</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
                                     <property name="related_action">devtab-action-generic</property>
@@ -1008,7 +874,7 @@
                           <object class="GtkTable" id="devtab-table">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="n_rows">7</property>
+                            <property name="n_rows">8</property>
                             <property name="n_columns">2</property>
                             <property name="column_spacing">10</property>
                             <child>
@@ -1017,9 +883,7 @@
                                 <property name="can_focus">False</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes">Size</property>
-                                <style>
-                                  <class name="dim-label"/>
-                                </style>
+                                <style><class name="dim-label"/></style>
                               </object>
                               <packing>
                                 <property name="x_options">GTK_FILL</property>
@@ -1050,9 +914,7 @@
                                 <property name="can_focus">False</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes" comments="The contents of the device, for example 'Unknown', 'FAT (32-bit version)', 'Ext4 (version 1.0)', 'Swap (version 2)'">Contents</property>
-                                <style>
-                                  <class name="dim-label"/>
-                                </style>
+                                <style><class name="dim-label"/></style>
                               </object>
                               <packing>
                                 <property name="top_attach">5</property>
@@ -1087,9 +949,7 @@
                                 <property name="can_focus">False</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes">Device</property>
-                                <style>
-                                  <class name="dim-label"/>
-                                </style>
+                                <style><class name="dim-label"/></style>
                               </object>
                               <packing>
                                 <property name="top_attach">1</property>
@@ -1124,9 +984,7 @@
                                 <property name="can_focus">False</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes">In Use</property>
-                                <style>
-                                  <class name="dim-label"/>
-                                </style>
+                                <style><class name="dim-label"/></style>
                               </object>
                               <packing>
                                 <property name="top_attach">6</property>
@@ -1155,16 +1013,13 @@
                                 <property name="y_padding">4</property>
                               </packing>
                             </child>
-
                             <child>
                               <object class="GtkLabel" id="devtab-loop-autoclear-label">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes">Auto-clear</property>
-                                <style>
-                                  <class name="dim-label"/>
-                                </style>
+                                <style><class name="dim-label"/></style>
                               </object>
                               <packing>
                                 <property name="top_attach">4</property>
@@ -1201,16 +1056,13 @@
                                 <property name="y_options"></property>
                               </packing>
                             </child>
-
                             <child>
                               <object class="GtkLabel" id="devtab-partition-label">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes">Partition Type</property>
-                                <style>
-                                  <class name="dim-label"/>
-                                </style>
+                                <style><class name="dim-label"/></style>
                               </object>
                               <packing>
                                 <property name="top_attach">3</property>
@@ -1245,9 +1097,7 @@
                                 <property name="can_focus">False</property>
                                 <property name="xalign">1</property>
                                 <property name="label" translatable="yes" comments="The filename or URI of the file that is used as backing store for the loop device.">Backing File</property>
-                                <style>
-                                  <class name="dim-label"/>
-                                </style>
+                                <style><class name="dim-label"/></style>
                               </object>
                               <packing>
                                 <property name="top_attach">2</property>
@@ -1276,6 +1126,73 @@
                                 <property name="y_padding">4</property>
                               </packing>
                             </child>
+                            <child>
+                              <object class="GtkLabel" id="devtab-job-label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">1</property>
+                                <property name="label" translatable="yes">Pending Job</property>
+                                <style><class name="dim-label"/></style>
+                              </object>
+                              <packing>
+                                <property name="top_attach">7</property>
+                                <property name="bottom_attach">8</property>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                                <property name="y_padding">4</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="devtab-job-box">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">6</property>
+                                <child>
+                                  <object class="GtkProgressBar" id="devtab-job-progressbar">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="devtab-job-id-label">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="devtab-job-cancel-label">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="label" translatable="yes">â &lt;a href="app://cancel"&gt;Cancel&lt;/a&gt;</property>
+                                    <property name="use_markup">True</property>
+                                    <property name="track_visited_links">False</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">2</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">7</property>
+                                <property name="bottom_attach">8</property>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
                           </object>
                           <packing>
                             <property name="expand">False</property>
@@ -1352,4 +1269,198 @@
       </object>
     </child>
   </object>
+  <object class="GtkMenu" id="generic-drive-menu">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkMenuItem" id="generic-drive-menu-item-format-disk">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Format Disk...</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSeparatorMenuItem" id="menuitem4">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-drive-menu-item-create-disk-image">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Create Disk Image...</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-drive-menu-item-restore-disk-image">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Restore Disk Image...</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-drive-menu-item-benchmark">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Benchmark Drive...</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSeparatorMenuItem" id="menuitem5">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-drive-menu-item-view-smart">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">SMART Data and Tests...</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-drive-menu-item-disk-settings">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Drive Settings...</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSeparatorMenuItem" id="menuitem6">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-drive-menu-item-standby-now">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Standby Now</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-drive-menu-item-resume-now">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Wake-Up from Standby</property>
+      </object>
+    </child>
+  </object>
+  <object class="GtkMenu" id="generic-menu">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkMenuItem" id="generic-menu-item-format-volume">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Format...</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSeparatorMenuItem" id="menuitem3">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-menu-item-edit-partition">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Edit Partition Type...</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-menu-item-edit-label">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Edit Filesystem Label...</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-menu-item-change-passphrase">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Change Passphrase...</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSeparatorMenuItem" id="menuitem2">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-menu-item-configure-fstab">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Edit Mount Options...</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-menu-item-configure-crypttab">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Edit Encryption Options...</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSeparatorMenuItem" id="menuitem1">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-menu-item-create-volume-image">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Create Disk Image...</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-menu-item-restore-volume-image">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Restore Disk Image...</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="generic-menu-item-benchmark">
+        <property name="use_action_appearance">False</property>
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Benchmark Volume...</property>
+      </object>
+    </child>
+  </object>
 </interface>
diff --git a/data/ui/filesystem-create.ui b/data/ui/filesystem-create.ui
index fcaec1e..1325cda 100644
--- a/data/ui/filesystem-create.ui
+++ b/data/ui/filesystem-create.ui
@@ -17,13 +17,11 @@
             <property name="label" translatable="yes">_Type</property>
             <property name="use_underline">True</property>
             <property name="mnemonic_widget">type-combobox</property>
-            <style>
-              <class name="dim-label"/>
-            </style>
+            <style><class name="dim-label"/></style>
           </object>
           <packing>
             <property name="left_attach">0</property>
-            <property name="top_attach">0</property>
+            <property name="top_attach">1</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -36,13 +34,11 @@
             <property name="label" translatable="yes">_Name</property>
             <property name="use_underline">True</property>
             <property name="mnemonic_widget">name-entry</property>
-            <style>
-              <class name="dim-label"/>
-            </style>
+            <style><class name="dim-label"/></style>
           </object>
           <packing>
             <property name="left_attach">0</property>
-            <property name="top_attach">1</property>
+            <property name="top_attach">2</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -61,7 +57,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="top_attach">1</property>
+            <property name="top_attach">2</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -75,13 +71,11 @@
             <property name="label" translatable="yes">F_ilesystem</property>
             <property name="use_underline">True</property>
             <property name="mnemonic_widget">filesystem-entry</property>
-            <style>
-              <class name="dim-label"/>
-            </style>
+            <style><class name="dim-label"/></style>
           </object>
           <packing>
             <property name="left_attach">0</property>
-            <property name="top_attach">2</property>
+            <property name="top_attach">3</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -101,7 +95,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="top_attach">2</property>
+            <property name="top_attach">3</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -115,13 +109,11 @@
             <property name="label" translatable="yes">_Passphrase</property>
             <property name="use_underline">True</property>
             <property name="mnemonic_widget">passphrase-entry</property>
-            <style>
-              <class name="dim-label"/>
-            </style>
+            <style><class name="dim-label"/></style>
           </object>
           <packing>
             <property name="left_attach">0</property>
-            <property name="top_attach">3</property>
+            <property name="top_attach">4</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -135,13 +127,11 @@
             <property name="label" translatable="yes">C_onfirm Passphrase</property>
             <property name="use_underline">True</property>
             <property name="mnemonic_widget">confirm-passphrase-entry</property>
-            <style>
-              <class name="dim-label"/>
-            </style>
+            <style><class name="dim-label"/></style>
           </object>
           <packing>
             <property name="left_attach">0</property>
-            <property name="top_attach">4</property>
+            <property name="top_attach">5</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -162,7 +152,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="top_attach">3</property>
+            <property name="top_attach">4</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -183,7 +173,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="top_attach">4</property>
+            <property name="top_attach">5</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -197,7 +187,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="top_attach">0</property>
+            <property name="top_attach">1</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -205,6 +195,7 @@
         <child>
           <object class="GtkCheckButton" id="show-passphrase-checkbutton">
             <property name="label" translatable="yes">Sho_w Passphrases</property>
+            <property name="use_action_appearance">False</property>
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="receives_default">False</property>
@@ -219,7 +210,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="top_attach">6</property>
+            <property name="top_attach">7</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -235,7 +226,7 @@
           </object>
           <packing>
             <property name="left_attach">1</property>
-            <property name="top_attach">5</property>
+            <property name="top_attach">6</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>
@@ -247,7 +238,34 @@
           <placeholder/>
         </child>
         <child>
-          <placeholder/>
+          <object class="GtkLabel" id="label1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Erase</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">erase-combobox</property>
+            <style><class name="dim-label"/></style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="erase-combobox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="id_column">0</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
         </child>
       </object>
     </child>
diff --git a/data/ui/format-disk-dialog.ui b/data/ui/format-disk-dialog.ui
index aa44d78..e698374 100644
--- a/data/ui/format-disk-dialog.ui
+++ b/data/ui/format-disk-dialog.ui
@@ -20,6 +20,7 @@
             <child>
               <object class="GtkButton" id="button1">
                 <property name="label">gtk-cancel</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -35,6 +36,7 @@
             <child>
               <object class="GtkButton" id="button2">
                 <property name="label" translatable="yes">_Format...</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
@@ -91,7 +93,7 @@
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
-                    <property name="top_attach">0</property>
+                    <property name="top_attach">1</property>
                     <property name="width">1</property>
                     <property name="height">1</property>
                   </packing>
@@ -104,12 +106,40 @@
                     <property name="label" translatable="yes">_Partitioning</property>
                     <property name="use_underline">True</property>
                     <property name="mnemonic_widget">type-combobox</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
+                    <style><class name="dim-label"/></style>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">_Erase</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">erase-combobox</property>
+                    <style><class name="dim-label"/></style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBox" id="erase-combobox">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="id_column">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
                     <property name="top_attach">0</property>
                     <property name="width">1</property>
                     <property name="height">1</property>
diff --git a/src/disks/gducreatefilesystemwidget.c b/src/disks/gducreatefilesystemwidget.c
index 523a70e..1b4f646 100644
--- a/src/disks/gducreatefilesystemwidget.c
+++ b/src/disks/gducreatefilesystemwidget.c
@@ -44,6 +44,7 @@ struct _GduCreateFilesystemWidget
 
   GtkBuilder *builder;
   GtkWidget *grid;
+  GtkWidget *erase_combobox;
   GtkWidget *type_combobox;
   GtkWidget *name_label;
   GtkWidget *name_entry;
@@ -366,6 +367,9 @@ populate (GduCreateFilesystemWidget *widget)
   GtkCellRenderer *renderer;
   gchar *s;
 
+  /* ---------------------------------------------------------------------------------------------------- */
+  /* type combobox */
+
   model = gtk_list_store_new (MODEL_N_COLUMNS,
                               G_TYPE_STRING,
                               G_TYPE_STRING,
@@ -468,6 +472,47 @@ populate (GduCreateFilesystemWidget *widget)
                           widget->confirm_passphrase_entry,
                           "visibility",
                           G_BINDING_SYNC_CREATE);
+
+  /* ---------------------------------------------------------------------------------------------------- */
+  /* erase combobox */
+
+  model = gtk_list_store_new (MODEL_N_COLUMNS,
+                              G_TYPE_STRING,
+                              G_TYPE_STRING,
+                              G_TYPE_BOOLEAN);
+  gtk_combo_box_set_model (GTK_COMBO_BOX (widget->erase_combobox), GTK_TREE_MODEL (model));
+  g_object_unref (model);
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget->erase_combobox), renderer, FALSE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget->erase_combobox), renderer,
+                                  "markup", MODEL_COLUMN_MARKUP,
+                                  NULL);
+
+  gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (widget->erase_combobox),
+                                        separator_func,
+                                        widget,
+                                        NULL); /* GDestroyNotify */
+
+  /* Quick */
+  s = g_strdup_printf ("%s <span size=\"small\">(%s)</span>",
+                       _("Don't overwrite existing data"),
+                       _("Quick"));
+  gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+                                     MODEL_COLUMN_ID, "", MODEL_COLUMN_MARKUP, s, -1);
+  g_free (s);
+
+  /* Full */
+  s = g_strdup_printf ("%s <span size=\"small\">(%s)</span>",
+                       _("Overwrite existing data with zeroes"),
+                       _("Slow"));
+  gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+                                     MODEL_COLUMN_ID, "zero", MODEL_COLUMN_MARKUP, s, -1);
+  g_free (s);
+
+  /* TODO: include 7-pass and 35-pass (DoD 5220-22 M) */
+
+  gtk_combo_box_set_active_id (GTK_COMBO_BOX (widget->erase_combobox), "");
 }
 
 static void
@@ -481,6 +526,8 @@ gdu_create_filesystem_widget_constructed (GObject *object)
                                                          "filesystem-create-dummywindow",
                                                          &widget->builder));
   widget->grid = GTK_WIDGET (gtk_builder_get_object (widget->builder, "filesystem-create-grid"));
+  widget->erase_combobox = GTK_WIDGET (gtk_builder_get_object (widget->builder, "erase-combobox"));
+  g_signal_connect (widget->erase_combobox, "notify::active", G_CALLBACK (on_property_changed), widget);
   widget->type_combobox = GTK_WIDGET (gtk_builder_get_object (widget->builder, "type-combobox"));
   g_signal_connect (widget->type_combobox, "notify::active", G_CALLBACK (on_property_changed), widget);
   widget->name_label = GTK_WIDGET (gtk_builder_get_object (widget->builder, "name-label"));
@@ -601,6 +648,20 @@ gdu_create_filesystem_widget_get_name (GduCreateFilesystemWidget *widget)
 }
 
 const gchar *
+gdu_create_filesystem_widget_get_erase (GduCreateFilesystemWidget *widget)
+{
+  const gchar *ret;
+
+  g_return_val_if_fail (GDU_IS_CREATE_FILESYSTEM_WIDGET (widget), NULL);
+
+  ret = gtk_combo_box_get_active_id (GTK_COMBO_BOX (widget->erase_combobox));
+  if (g_strcmp0 (ret, "") == 0)
+    ret = NULL;
+
+  return ret;
+}
+
+const gchar *
 gdu_create_filesystem_widget_get_fstype (GduCreateFilesystemWidget *widget)
 {
   g_return_val_if_fail (GDU_IS_CREATE_FILESYSTEM_WIDGET (widget), NULL);
diff --git a/src/disks/gducreatefilesystemwidget.h b/src/disks/gducreatefilesystemwidget.h
index e6bbadf..b1d07a0 100644
--- a/src/disks/gducreatefilesystemwidget.h
+++ b/src/disks/gducreatefilesystemwidget.h
@@ -37,6 +37,7 @@ GtkWidget*   gdu_create_filesystem_widget_new            (GduApplication
                                                           UDisksDrive               *drive,
                                                           const gchar * const       *addtional_fstypes);
 const gchar *gdu_create_filesystem_widget_get_name       (GduCreateFilesystemWidget *widget);
+const gchar *gdu_create_filesystem_widget_get_erase      (GduCreateFilesystemWidget *widget);
 const gchar *gdu_create_filesystem_widget_get_fstype     (GduCreateFilesystemWidget *widget);
 const gchar *gdu_create_filesystem_widget_get_passphrase (GduCreateFilesystemWidget *widget);
 gboolean     gdu_create_filesystem_widget_get_has_info   (GduCreateFilesystemWidget *widget);
diff --git a/src/disks/gducreatepartitiondialog.c b/src/disks/gducreatepartitiondialog.c
index 2016e94..b45f92e 100644
--- a/src/disks/gducreatepartitiondialog.c
+++ b/src/disks/gducreatepartitiondialog.c
@@ -229,6 +229,7 @@ create_partition_cb (GObject      *source_object,
   UDisksObject *partition_object = NULL;
   UDisksBlock *partition_block;
   GVariantBuilder options_builder;
+  const gchar *erase;
   const gchar *fstype;
   const gchar *name;
   const gchar *passphrase;
@@ -259,6 +260,7 @@ create_partition_cb (GObject      *source_object,
       goto out;
     }
 
+  erase = gdu_create_filesystem_widget_get_erase (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
   fstype = gdu_create_filesystem_widget_get_fstype (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
   name = gdu_create_filesystem_widget_get_name (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
   passphrase = gdu_create_filesystem_widget_get_passphrase (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
@@ -281,6 +283,9 @@ create_partition_cb (GObject      *source_object,
       if (passphrase != NULL && strlen (passphrase) > 0)
         g_variant_builder_add (&options_builder, "{sv}", "encrypt.passphrase", g_variant_new_string (passphrase));
 
+      if (erase != NULL)
+        g_variant_builder_add (&options_builder, "{sv}", "erase", g_variant_new_string (erase));
+
       udisks_block_call_format (partition_block,
                                 fstype,
                                 g_variant_builder_end (&options_builder),
diff --git a/src/disks/gdudevicetreemodel.c b/src/disks/gdudevicetreemodel.c
index 6784050..7de3547 100644
--- a/src/disks/gdudevicetreemodel.c
+++ b/src/disks/gdudevicetreemodel.c
@@ -396,8 +396,8 @@ gdu_device_tree_model_constructed (GObject *object)
   types[4] = G_TYPE_STRING;
   types[5] = G_TYPE_DBUS_OBJECT;
   types[6] = G_TYPE_BOOLEAN;
-  types[7] = G_TYPE_BOOLEAN;
-  types[8] = G_TYPE_UINT;
+  types[7] = G_TYPE_UINT;
+  types[8] = G_TYPE_BOOLEAN;
   types[9] = G_TYPE_BOOLEAN;
   G_STATIC_ASSERT (10 == GDU_DEVICE_TREE_MODEL_N_COLUMNS);
   gtk_tree_store_set_column_types (GTK_TREE_STORE (model),
diff --git a/src/disks/gduformatdiskdialog.c b/src/disks/gduformatdiskdialog.c
index ae2869e..138162e 100644
--- a/src/disks/gduformatdiskdialog.c
+++ b/src/disks/gduformatdiskdialog.c
@@ -51,6 +51,7 @@ typedef struct
   GtkBuilder *builder;
   GtkWidget *dialog;
   GtkWidget *type_combobox;
+  GtkWidget *erase_combobox;
 } FormatDiskData;
 
 static void
@@ -101,7 +102,55 @@ separator_func (GtkTreeModel *model,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-format_disk_populate (FormatDiskData *data)
+populate_erase_combobox (FormatDiskData *data)
+{
+  GtkListStore *model;
+  GtkCellRenderer *renderer;
+  gchar *s;
+
+  model = gtk_list_store_new (MODEL_N_COLUMNS,
+                              G_TYPE_STRING,
+                              G_TYPE_STRING,
+                              G_TYPE_BOOLEAN);
+  gtk_combo_box_set_model (GTK_COMBO_BOX (data->erase_combobox), GTK_TREE_MODEL (model));
+  g_object_unref (model);
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (data->erase_combobox), renderer, FALSE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (data->erase_combobox), renderer,
+                                  "markup", MODEL_COLUMN_MARKUP,
+                                  NULL);
+
+  gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (data->erase_combobox),
+                                        separator_func,
+                                        data,
+                                        NULL); /* GDestroyNotify */
+
+  /* Quick */
+  s = g_strdup_printf ("%s <span size=\"small\">(%s)</span>",
+                       _("Don't overwrite existing data"),
+                       _("Quick"));
+  gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+                                     MODEL_COLUMN_ID, "", MODEL_COLUMN_MARKUP, s, -1);
+  g_free (s);
+
+  /* Full */
+  s = g_strdup_printf ("%s <span size=\"small\">(%s)</span>",
+                       _("Overwrite existing data with zeroes"),
+                       _("Slow"));
+  gtk_list_store_insert_with_values (model, NULL /* out_iter */, G_MAXINT, /* position */
+                                     MODEL_COLUMN_ID, "zero", MODEL_COLUMN_MARKUP, s, -1);
+  g_free (s);
+
+  /* TODO: include 7-pass and 35-pass (DoD 5220-22 M) */
+
+  /* TODO: include ATA SECURE ERASE */
+
+  gtk_combo_box_set_active_id (GTK_COMBO_BOX (data->erase_combobox), "");
+}
+
+static void
+populate_partitioning_combobox (FormatDiskData *data)
 {
   GtkListStore *model;
   GtkCellRenderer *renderer;
@@ -168,6 +217,13 @@ format_disk_populate (FormatDiskData *data)
     }
 }
 
+static void
+format_disk_populate (FormatDiskData *data)
+{
+  populate_erase_combobox (data);
+  populate_partitioning_combobox (data);
+}
+
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
@@ -208,6 +264,7 @@ gdu_format_disk_dialog_show (GduWindow    *window,
                                                          "format-disk-dialog",
                                                          &data->builder));
   data->type_combobox = GTK_WIDGET (gtk_builder_get_object (data->builder, "type-combobox"));
+  data->erase_combobox = GTK_WIDGET (gtk_builder_get_object (data->builder, "erase-combobox"));
   g_signal_connect (data->type_combobox, "notify::active", G_CALLBACK (on_property_changed), data);
 
   gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (window));
@@ -223,6 +280,8 @@ gdu_format_disk_dialog_show (GduWindow    *window,
   if (response == GTK_RESPONSE_OK)
     {
       const gchar *partition_table_type;
+      const gchar *erase_type;
+      GVariantBuilder options_builder;
 
       partition_table_type = gtk_combo_box_get_active_id (GTK_COMBO_BOX (data->type_combobox));
 
@@ -233,9 +292,14 @@ gdu_format_disk_dialog_show (GduWindow    *window,
                                          _("_Format")))
         goto out;
 
+      erase_type = gtk_combo_box_get_active_id (GTK_COMBO_BOX (data->erase_combobox));
+
+      g_variant_builder_init (&options_builder, G_VARIANT_TYPE_VARDICT);
+      if (strlen (erase_type) > 0)
+        g_variant_builder_add (&options_builder, "{sv}", "erase", g_variant_new_string (erase_type));
       udisks_block_call_format (data->block,
                                 partition_table_type,
-                                g_variant_new ("a{sv}", NULL), /* options */
+                                g_variant_builder_end (&options_builder),
                                 NULL, /* GCancellable */
                                 format_cb,
                                 data);
diff --git a/src/disks/gduformatvolumedialog.c b/src/disks/gduformatvolumedialog.c
index 4f0d2f5..f77d13c 100644
--- a/src/disks/gduformatvolumedialog.c
+++ b/src/disks/gduformatvolumedialog.c
@@ -144,10 +144,12 @@ gdu_format_volume_dialog_show (GduWindow    *window,
   if (response == GTK_RESPONSE_OK)
     {
       GVariantBuilder options_builder;
+      const gchar *erase;
       const gchar *fstype;
       const gchar *name;
       const gchar *passphrase;
 
+      erase = gdu_create_filesystem_widget_get_erase (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
       fstype = gdu_create_filesystem_widget_get_fstype (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
       name = gdu_create_filesystem_widget_get_name (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
       passphrase = gdu_create_filesystem_widget_get_passphrase (GDU_CREATE_FILESYSTEM_WIDGET (data->create_filesystem_widget));
@@ -170,6 +172,9 @@ gdu_format_volume_dialog_show (GduWindow    *window,
       if (passphrase != NULL && strlen (passphrase) > 0)
         g_variant_builder_add (&options_builder, "{sv}", "encrypt.passphrase", g_variant_new_string (passphrase));
 
+      if (erase != NULL)
+        g_variant_builder_add (&options_builder, "{sv}", "erase", g_variant_new_string (erase));
+
       udisks_block_call_format (data->block,
                                 fstype,
                                 g_variant_builder_end (&options_builder),
diff --git a/src/disks/gduwindow.c b/src/disks/gduwindow.c
index f1a394c..567b65b 100644
--- a/src/disks/gduwindow.c
+++ b/src/disks/gduwindow.c
@@ -91,6 +91,8 @@ struct _GduWindow
   GtkWidget *devtab_drive_name_label;
   GtkWidget *devtab_drive_devices_label;
   GtkWidget *devtab_drive_image;
+  GtkWidget *devtab_drive_job_cancel_label;
+  GtkWidget *devtab_job_cancel_label;
   GtkWidget *devtab_table;
   GtkWidget *devtab_drive_table;
   GtkWidget *devtab_grid_hbox;
@@ -152,6 +154,8 @@ static const struct {
   {G_STRUCT_OFFSET (GduWindow, devtab_drive_name_label), "devtab-drive-name-label"},
   {G_STRUCT_OFFSET (GduWindow, devtab_drive_devices_label), "devtab-drive-devices-label"},
   {G_STRUCT_OFFSET (GduWindow, devtab_drive_image), "devtab-drive-image"},
+  {G_STRUCT_OFFSET (GduWindow, devtab_drive_job_cancel_label), "devtab-drive-job-cancel-label"},
+  {G_STRUCT_OFFSET (GduWindow, devtab_job_cancel_label), "devtab-job-cancel-label"},
   {G_STRUCT_OFFSET (GduWindow, devtab_table), "devtab-table"},
   {G_STRUCT_OFFSET (GduWindow, devtab_grid_hbox), "devtab-grid-hbox"},
   {G_STRUCT_OFFSET (GduWindow, devtab_volumes_label), "devtab-volumes-label"},
@@ -308,6 +312,14 @@ static void on_devtab_loop_autoclear_switch_notify_active (GObject    *object,
                                                            GParamSpec *pspec,
                                                            gpointer    user_data);
 
+static void on_drive_job_cancel_label_activate_link (GtkLabel     *label,
+                                                     const gchar  *uri,
+                                                     gpointer      user_data);
+
+static void on_job_cancel_label_activate_link (GtkLabel     *label,
+                                               const gchar  *uri,
+                                               gpointer      user_data);
+
 G_DEFINE_TYPE (GduWindow, gdu_window, GTK_TYPE_APPLICATION_WINDOW);
 
 static void
@@ -1223,6 +1235,18 @@ gdu_window_constructed (GObject *object)
                     G_CALLBACK (on_devtab_loop_autoclear_switch_notify_active),
                     window);
 
+  /* cancel-button for drive job */
+  g_signal_connect (window->devtab_drive_job_cancel_label,
+                    "activate-link",
+                    G_CALLBACK (on_drive_job_cancel_label_activate_link),
+                    window);
+
+  /* cancel-button for job */
+  g_signal_connect (window->devtab_job_cancel_label,
+                    "activate-link",
+                    G_CALLBACK (on_job_cancel_label_activate_link),
+                    window);
+
   g_idle_add (on_constructed_in_idle, g_object_ref (window));
 }
 
@@ -1672,6 +1696,7 @@ update_device_page_for_drive (GduWindow      *window,
   UDisksDriveAta *ata;
   const gchar *our_seat;
   const gchar *serial;
+  GList *jobs;
 
   //g_debug ("In update_device_page_for_drive() - selected=%s",
   //         object != NULL ? g_dbus_object_get_object_path (object) : "<nothing>");
@@ -1872,6 +1897,55 @@ update_device_page_for_drive (GduWindow      *window,
                   SET_MARKUP_FLAGS_HYPHEN_IF_EMPTY);
     }
 
+  jobs = udisks_client_get_jobs_for_object (window->client, object);
+  /* if there are no jobs on the drive, look at the first block object if it's partitioned
+   * (because: if it's not partitioned, we'll see the job in Volumes below so no need to show it here)
+   */
+  if (jobs == NULL && blocks != NULL)
+    {
+      UDisksObject *block_object = UDISKS_OBJECT (blocks->data);
+      if (udisks_object_peek_partition_table (object) != NULL)
+        {
+          jobs = udisks_client_get_jobs_for_object (window->client, block_object);
+        }
+    }
+  if (jobs == NULL)
+    {
+      gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-drive-job-label")));
+      gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-drive-job-box")));
+    }
+  else
+    {
+      UDisksJob *job = UDISKS_JOB (jobs->data);
+      GtkWidget *label;
+      GtkWidget *progress_bar;
+      gchar *desc;
+
+      gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-drive-job-label")));
+      gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-drive-job-box")));
+
+      label = GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-drive-job-id-label"));
+      progress_bar = GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-drive-job-progressbar"));
+      desc = udisks_client_get_job_description (window->client, job);
+      if (udisks_job_get_progress_valid (job))
+        {
+          gdouble progress = udisks_job_get_progress (job);
+          gtk_widget_show (progress_bar);
+          gtk_widget_hide (label);
+          gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), progress);
+          gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (progress_bar), TRUE);
+          gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress_bar), desc);
+        }
+      else
+        {
+          gtk_widget_hide (progress_bar);
+          gtk_widget_show (label);
+          gtk_label_set_text (GTK_LABEL (label), desc);
+        }
+      g_free (desc);
+    }
+  g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
+  g_list_free (jobs);
 
   if (udisks_drive_get_ejectable (drive))
     {
@@ -1941,6 +2015,7 @@ update_device_page_for_block (GduWindow          *window,
   gchar *s;
   UDisksObject *drive_object;
   UDisksDrive *drive = NULL;
+  GList *jobs;
 
   read_only = udisks_block_get_read_only (block);
   partition = udisks_object_peek_partition (object);
@@ -2190,6 +2265,46 @@ update_device_page_for_block (GduWindow          *window,
       *show_flags |= SHOW_FLAGS_POPUP_MENU_CONFIGURE_CRYPTTAB;
       *show_flags |= SHOW_FLAGS_POPUP_MENU_CHANGE_PASSPHRASE;
     }
+
+
+  jobs = udisks_client_get_jobs_for_object (window->client, object);
+  if (jobs == NULL)
+    {
+      gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-job-label")));
+      gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-job-box")));
+    }
+  else
+    {
+      UDisksJob *job = UDISKS_JOB (jobs->data);
+      GtkWidget *label;
+      GtkWidget *progress_bar;
+      gchar *desc;
+
+      gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-job-label")));
+      gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-job-box")));
+
+      label = GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-job-id-label"));
+      progress_bar = GTK_WIDGET (gtk_builder_get_object (window->builder, "devtab-job-progressbar"));
+      desc = udisks_client_get_job_description (window->client, job);
+      if (udisks_job_get_progress_valid (job))
+        {
+          gdouble progress = udisks_job_get_progress (job);
+          gtk_widget_show (progress_bar);
+          gtk_widget_hide (label);
+          gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), progress);
+          gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (progress_bar), TRUE);
+          gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress_bar), desc);
+        }
+      else
+        {
+          gtk_widget_hide (progress_bar);
+          gtk_widget_show (label);
+          gtk_label_set_text (GTK_LABEL (label), desc);
+        }
+      g_free (desc);
+    }
+  g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
+  g_list_free (jobs);
 }
 
 static void
@@ -2380,9 +2495,11 @@ gdu_window_show_error (GduWindow   *window,
 
   /* Never show an error if it's because the user dismissed the
    * authentication dialog himself
+   *
+   * ... or if the user cancelled the operation
    */
-  if (error->domain == UDISKS_ERROR &&
-      error->code == UDISKS_ERROR_NOT_AUTHORIZED_DISMISSED)
+  if ((error->domain == UDISKS_ERROR && error->code == UDISKS_ERROR_NOT_AUTHORIZED_DISMISSED) ||
+      (error->domain == UDISKS_ERROR && error->code == UDISKS_ERROR_CANCELLED))
     goto no_dialog;
 
   fixed_up_error = g_error_copy (error);
@@ -3133,3 +3250,103 @@ on_devtab_loop_autoclear_switch_notify_active (GObject    *gobject,
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
+
+static void
+drive_job_cancel_cb (UDisksJob       *job,
+                     GAsyncResult    *res,
+                     gpointer         user_data)
+{
+  GduWindow *window = GDU_WINDOW (user_data);
+  GError *error = NULL;
+
+  if (!udisks_job_call_cancel_finish (job, res, &error))
+    {
+      gdu_window_show_error (window,
+                             _("Error canceling job"),
+                             error);
+      g_error_free (error);
+    }
+  g_object_unref (window);
+}
+
+static void
+on_drive_job_cancel_label_activate_link (GtkLabel     *label,
+                                         const gchar  *uri,
+                                         gpointer      user_data)
+{
+  GduWindow *window = GDU_WINDOW (user_data);
+  GList *jobs;
+
+  jobs = udisks_client_get_jobs_for_object (window->client, window->current_object);
+  /* if there are no jobs on the drive, look at the first block object */
+  if (jobs == NULL)
+    {
+      GList *blocks;
+      blocks = get_top_level_blocks_for_drive (window, g_dbus_object_get_object_path (G_DBUS_OBJECT (window->current_object)));
+      blocks = g_list_sort (blocks, (GCompareFunc) block_compare_on_preferred);
+      if (blocks != NULL)
+        {
+          UDisksObject *block_object = UDISKS_OBJECT (blocks->data);
+          jobs = udisks_client_get_jobs_for_object (window->client, block_object);
+        }
+      g_list_foreach (blocks, (GFunc) g_object_unref, NULL);
+      g_list_free (blocks);
+    }
+  if (jobs != NULL)
+    {
+      UDisksJob *job = UDISKS_JOB (jobs->data);
+      udisks_job_call_cancel (job,
+                              g_variant_new ("a{sv}", NULL), /* options */
+                              NULL, /* cancellable */
+                              (GAsyncReadyCallback) drive_job_cancel_cb,
+                              g_object_ref (window));
+    }
+  g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
+  g_list_free (jobs);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+job_cancel_cb (UDisksJob       *job,
+               GAsyncResult    *res,
+               gpointer         user_data)
+{
+  GduWindow *window = GDU_WINDOW (user_data);
+  GError *error = NULL;
+
+  if (!udisks_job_call_cancel_finish (job, res, &error))
+    {
+      gdu_window_show_error (window,
+                             _("Error canceling job"),
+                             error);
+      g_error_free (error);
+    }
+  g_object_unref (window);
+}
+
+static void
+on_job_cancel_label_activate_link (GtkLabel     *label,
+                                   const gchar  *uri,
+                                   gpointer      user_data)
+{
+  GduWindow *window = GDU_WINDOW (user_data);
+  GList *jobs;
+  UDisksObject *object;
+
+  object = gdu_volume_grid_get_selected_device (GDU_VOLUME_GRID (window->volume_grid));
+  g_assert (object != NULL);
+
+  jobs = udisks_client_get_jobs_for_object (window->client, object);
+  if (jobs != NULL)
+    {
+      UDisksJob *job = UDISKS_JOB (jobs->data);
+      udisks_job_call_cancel (job,
+                              g_variant_new ("a{sv}", NULL), /* options */
+                              NULL, /* cancellable */
+                              (GAsyncReadyCallback) job_cancel_cb,
+                              g_object_ref (window));
+    }
+  g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
+  g_list_free (jobs);
+}



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