[gnome-disk-utility] More multi-selection rework after designer feedback



commit 56603f3f01dd4a27f9caf3396081a06976ce33d1
Author: David Zeuthen <zeuthen gmail com>
Date:   Wed Oct 10 14:39:33 2012 -0400

    More multi-selection rework after designer feedback
    
    Thanks to Jon McCann for useful feedback.
    
    http://people.freedesktop.org/~david/gnome-disks-multi-c-1.png
    http://people.freedesktop.org/~david/gnome-disks-multi-c-2.png
    http://people.freedesktop.org/~david/gnome-disks-multi-c-3.png
    http://people.freedesktop.org/~david/gnome-disks-multi-c-4.png
    
    Signed-off-by: David Zeuthen <zeuthen gmail com>

 data/ui/disks.ui      |  240 ++++++++++++--------
 src/disks/gduwindow.c |  627 ++++++++++++++++++++++---------------------------
 2 files changed, 428 insertions(+), 439 deletions(-)
---
diff --git a/data/ui/disks.ui b/data/ui/disks.ui
index 1d79e44..9d7f923 100644
--- a/data/ui/disks.ui
+++ b/data/ui/disks.ui
@@ -87,40 +87,6 @@
       </object>
     </child>
   </object>
-  <object class="GtkMenu" id="device-tree-menu">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <child>
-      <object class="GtkMenuItem" id="device-tree-menu-item-create-raid-array">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label" translatable="yes">Create RAID Array on Selected Disks...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="device-tree-menu-item-erase-disks">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label" translatable="yes">Erase Selected Disks...</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkSeparatorMenuItem" id="menuitem5">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="device-tree-menu-item-abort-selection">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label" translatable="yes">Abort Selection</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-  </object>
   <object class="GtkWindow" id="disks-window">
     <property name="can_focus">False</property>
     <property name="border_width">12</property>
@@ -138,32 +104,7 @@
             <property name="can_focus">False</property>
             <property name="margin_right">6</property>
             <child>
-              <object class="GtkScrolledWindow" id="device-tree-scrolledwindow">
-                <property name="width_request">300</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="shadow_type">in</property>
-                <child>
-                  <object class="GtkTreeView" id="device-tree-treeview">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="headers_visible">False</property>
-                    <property name="show_expanders">False</property>
-                    <property name="level_indentation">12</property>
-                    <child internal-child="selection">
-                      <object class="GtkTreeSelection" id="treeview-selection"/>
-                    </child>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolbar" id="device-tree-add-remove-toolbar">
+              <object class="GtkToolbar" id="device-tree-selection-toolbar">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="toolbar_style">icons</property>
@@ -173,7 +114,7 @@
                   <class name="menubar"/>
                 </style>
                 <child>
-                  <object class="GtkToolItem" id="device-tree-left-toolbar-part">
+                  <object class="GtkToolItem" id="device-tree-selection-toolbar-left">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <child>
@@ -195,14 +136,48 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkToolItem" id="device-tree-center-toolbar-part">
+                  <object class="GtkToolItem" id="device-tree-selection-toolbar-center">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <child>
-                      <object class="GtkLabel" id="device-tree-toolbar-label">
+                      <object class="GtkNotebook" id="device-tree-selection-toolbar-center-notebook">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="show_tabs">False</property>
+                        <property name="show_border">False</property>
+                        <child>
+                          <object class="GtkLabel" id="label8">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">_Devices</property>
+                            <property name="use_underline">True</property>
+                            <attributes>
+                              <attribute name="weight" value="bold"/>
+                            </attributes>
+                          </object>
+                        </child>
+                        <child type="tab">
+                          <placeholder/>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="device-tree-selection-toolbar-label">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">(Select Items Above)</property>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child type="tab">
+                          <placeholder/>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                        <child type="tab">
+                          <placeholder/>
+                        </child>
                       </object>
                     </child>
                   </object>
@@ -221,7 +196,7 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkToolItem" id="device-tree-right-toolbar-part">
+                  <object class="GtkToolItem" id="device-tree-selection-toolbar-right">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <child>
@@ -229,7 +204,7 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkButton" id="device-tree-toolbar-select-button">
+                          <object class="GtkButton" id="device-tree-selection-toolbar-select-button">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
@@ -249,9 +224,8 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkMenuButton" id="device-tree-toolbar-done-button">
-                            <property name="menu">device-tree-menu</property>
-                            <property name="label" translatable="yes">Done...</property>
+                          <object class="GtkButton" id="device-tree-selection-toolbar-done-button">
+                            <property name="label" translatable="yes">Done</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
@@ -276,6 +250,34 @@
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkOverlay" id="device-tree-overlay">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkScrolledWindow" id="device-tree-scrolledwindow">
+                    <property name="width_request">300</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="shadow_type">in</property>
+                    <child>
+                      <object class="GtkTreeView" id="device-tree-treeview">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="headers_visible">False</property>
+                        <property name="show_expanders">False</property>
+                        <property name="level_indentation">12</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">1</property>
               </packing>
             </child>
@@ -1668,33 +1670,10 @@
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="newtab_vbox">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-              </object>
-              <packing>
-                <property name="position">3</property>
-              </packing>
+              <placeholder/>
             </child>
             <child type="tab">
-              <object class="GtkLabel" id="newtab_label">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label">new</property>
-              </object>
-              <packing>
-                <property name="position">3</property>
-                <property name="tab_fill">False</property>
-              </packing>
+              <placeholder/>
             </child>
             <child>
               <placeholder/>
@@ -1895,4 +1874,75 @@
       </object>
     </child>
   </object>
+  <object class="GtkWindow" id="overlay-toolbar-dummy-window">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkToolbar" id="overlay-toolbar">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <style>
+          <class name="osd"/>
+        </style>
+        <child>
+          <object class="GtkToolItem" id="overlay-toolbar-left">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkBox" id="box1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <style>
+                  <class name="linked"/>
+                </style>
+                <child>
+                  <object class="GtkButton" id="overlay-toolbar-erase-button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <child>
+                      <object class="GtkImage" id="image10">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="tooltip_text" translatable="yes">Click to select multiple disks to perform operations on</property>
+                        <property name="icon_name">edit-clear-all-symbolic</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="overlay-toolbar-create-raid-button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <child>
+                      <object class="GtkImage" id="image11">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="tooltip_text" translatable="yes">Click to select multiple disks to perform operations on</property>
+                        <property name="icon_name">list-add-symbolic</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="homogeneous">True</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
 </interface>
diff --git a/src/disks/gduwindow.c b/src/disks/gduwindow.c
index f7535f2..ebe40a9 100644
--- a/src/disks/gduwindow.c
+++ b/src/disks/gduwindow.c
@@ -40,14 +40,6 @@
 #include "gdumdraiddisksdialog.h"
 #include "gducreateraidarraydialog.h"
 
-/* Keep in sync with tabs in disks.ui file */
-typedef enum
-{
-  DETAILS_PAGE_NOT_SELECTED,
-  DETAILS_PAGE_NOT_IMPLEMENTED,
-  DETAILS_PAGE_DEVICE,
-} DetailsPage;
-
 struct _GduWindow
 {
   GtkApplicationWindow parent_instance;
@@ -62,21 +54,27 @@ struct _GduWindow
   GtkBuilder *builder;
   GduDeviceTreeModel *model;
 
-  DetailsPage current_page;
   UDisksObject *current_object;
 
   GtkWidget *volume_grid;
 
   GtkWidget *toolbutton_generic_menu;
 
+  GtkWidget *overlay_toolbar;
+  GtkWidget *overlay_toolbar_erase_button;
+  GtkWidget *overlay_toolbar_create_raid_button;
+
   GtkWidget *main_hpane;
   GtkWidget *details_notebook;
-  GtkWidget *device_scrolledwindow;
-  GtkWidget *device_treeview;
-  GtkWidget *device_toolbar;
-  GtkWidget *device_tree_toolbar_label;
-  GtkWidget *device_tree_toolbar_select_button;
-  GtkWidget *device_tree_toolbar_done_button;
+  GtkWidget *device_tree_overlay;
+  GtkWidget *device_tree_scrolledwindow;
+  GtkWidget *device_tree_treeview;
+  GtkWidget *device_tree_selection_toolbar;
+  GtkWidget *device_tree_selection_toolbar_center_notebook;
+  GtkWidget *device_tree_selection_toolbar_select_button;
+  GtkWidget *device_tree_selection_toolbar_done_button;
+  GtkWidget *device_tree_selection_toolbar_label;
+
   GtkWidget *devtab_drive_box;
   GtkWidget *devtab_drive_vbox;
   GtkWidget *devtab_drive_buttonbox;
@@ -160,11 +158,6 @@ struct _GduWindow
 
   /* GtkLabel instances we need to handle ::activate-link for */
   GtkWidget *devtab_volume_type_value_label;
-
-  GtkWidget *device_tree_menu;
-  GtkWidget *device_tree_menu_item_create_raid_array;
-  GtkWidget *device_tree_menu_item_erase_disks;
-  GtkWidget *device_tree_menu_item_abort_selection;
 };
 
 static const struct {
@@ -172,13 +165,19 @@ static const struct {
   const gchar *name;
 } widget_mapping[] = {
   {G_STRUCT_OFFSET (GduWindow, toolbutton_generic_menu), "toolbutton-generic-menu"},
+  {G_STRUCT_OFFSET (GduWindow, overlay_toolbar), "overlay-toolbar"},
+  {G_STRUCT_OFFSET (GduWindow, overlay_toolbar_erase_button), "overlay-toolbar-erase-button"},
+  {G_STRUCT_OFFSET (GduWindow, overlay_toolbar_create_raid_button), "overlay-toolbar-create-raid-button"},
   {G_STRUCT_OFFSET (GduWindow, main_hpane), "main-hpane"},
-  {G_STRUCT_OFFSET (GduWindow, device_scrolledwindow), "device-tree-scrolledwindow"},
-  {G_STRUCT_OFFSET (GduWindow, device_toolbar), "device-tree-add-remove-toolbar"},
-  {G_STRUCT_OFFSET (GduWindow, device_tree_toolbar_label), "device-tree-toolbar-label"},
-  {G_STRUCT_OFFSET (GduWindow, device_tree_toolbar_select_button), "device-tree-toolbar-select-button"},
-  {G_STRUCT_OFFSET (GduWindow, device_tree_toolbar_done_button), "device-tree-toolbar-done-button"},
-  {G_STRUCT_OFFSET (GduWindow, device_treeview), "device-tree-treeview"},
+  {G_STRUCT_OFFSET (GduWindow, device_tree_overlay), "device-tree-overlay"},
+  {G_STRUCT_OFFSET (GduWindow, device_tree_scrolledwindow), "device-tree-scrolledwindow"},
+  {G_STRUCT_OFFSET (GduWindow, device_tree_selection_toolbar), "device-tree-selection-toolbar"},
+  {G_STRUCT_OFFSET (GduWindow, device_tree_selection_toolbar_center_notebook), "device-tree-selection-toolbar-center-notebook"},
+  {G_STRUCT_OFFSET (GduWindow, device_tree_selection_toolbar_select_button), "device-tree-selection-toolbar-select-button"},
+  {G_STRUCT_OFFSET (GduWindow, device_tree_selection_toolbar_done_button), "device-tree-selection-toolbar-done-button"},
+  {G_STRUCT_OFFSET (GduWindow, device_tree_selection_toolbar_label), "device-tree-selection-toolbar-label"},
+
+  {G_STRUCT_OFFSET (GduWindow, device_tree_treeview), "device-tree-treeview"},
   {G_STRUCT_OFFSET (GduWindow, details_notebook), "disks-notebook"},
   {G_STRUCT_OFFSET (GduWindow, devtab_drive_table), "devtab-drive-table"},
   {G_STRUCT_OFFSET (GduWindow, devtab_drive_box), "devtab-drive-box"},
@@ -264,11 +263,6 @@ static const struct {
   /* GtkLabel instances we need to handle ::activate-link for */
   {G_STRUCT_OFFSET (GduWindow, devtab_volume_type_value_label), "devtab-volume-type-value-label"},
 
-  {G_STRUCT_OFFSET (GduWindow, device_tree_menu), "device-tree-menu"},
-  {G_STRUCT_OFFSET (GduWindow, device_tree_menu_item_create_raid_array), "device-tree-menu-item-create-raid-array"},
-  {G_STRUCT_OFFSET (GduWindow, device_tree_menu_item_erase_disks), "device-tree-menu-item-erase-disks"},
-  {G_STRUCT_OFFSET (GduWindow, device_tree_menu_item_abort_selection), "device-tree-menu-item-abort-selection"},
-
   {0, NULL}
 };
 
@@ -346,9 +340,7 @@ static void generic_menu_position_func (GtkMenu       *menu,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static void setup_device_page (GduWindow *window, UDisksObject *object);
-static void update_device_page (GduWindow *window, ShowFlags *show_flags);
-static void teardown_device_page (GduWindow *window);
+static void update_all (GduWindow *window);
 
 static void on_volume_grid_changed (GduVolumeGrid  *grid,
                                     gpointer        user_data);
@@ -420,15 +412,6 @@ static gboolean on_activate_link (GtkLabel    *label,
                                   const gchar *uri,
                                   gpointer     user_data);
 
-static void on_device_tree_menu_item_create_raid_array (GtkMenuItem *menu_item,
-                                                        gpointer   user_data);
-
-static void on_device_tree_menu_item_erase_disks (GtkMenuItem *menu_item,
-                                                  gpointer   user_data);
-
-static void on_device_tree_menu_item_abort_selection (GtkMenuItem *menu_item,
-                                                      gpointer   user_data);
-
 G_DEFINE_TYPE (GduWindow, gdu_window, GTK_TYPE_APPLICATION_WINDOW);
 
 static void
@@ -444,10 +427,6 @@ gdu_window_finalize (GObject *object)
 {
   GduWindow *window = GDU_WINDOW (object);
 
-  gtk_window_remove_mnemonic (GTK_WINDOW (window),
-                              'd',
-                              window->device_treeview);
-
   g_signal_handlers_disconnect_by_func (window->client,
                                         G_CALLBACK (on_client_changed),
                                         window);
@@ -492,14 +471,9 @@ on_row_inserted (GtkTreeModel *tree_model,
                  gpointer      user_data)
 {
   GduWindow *window = GDU_WINDOW (user_data);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (window->device_treeview));
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (window->device_tree_treeview));
 }
 
-static void select_details_page (GduWindow       *window,
-                                 UDisksObject    *object,
-                                 DetailsPage      page,
-                                 ShowFlags       *show_flags);
-
 static void
 update_for_show_flags (GduWindow *window,
                        ShowFlags *show_flags)
@@ -582,21 +556,20 @@ update_for_show_flags (GduWindow *window,
 }
 
 static gboolean
-set_selected_object (GduWindow    *window,
-                     UDisksObject *object)
+select_object (GduWindow    *window,
+               UDisksObject *object)
 {
   gboolean ret = FALSE;
-  ShowFlags show_flags = {0};
   GtkTreeIter iter;
 
   if (object != NULL && gdu_device_tree_model_get_iter_for_object (window->model, object, &iter))
     {
       GtkTreePath *path;
       GtkTreeSelection *tree_selection;
-      tree_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->device_treeview));
+      tree_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->device_tree_treeview));
       gtk_tree_selection_select_iter (tree_selection, &iter);
       path = gtk_tree_model_get_path (GTK_TREE_MODEL (window->model), &iter);
-      gtk_tree_view_set_cursor (GTK_TREE_VIEW (window->device_treeview),
+      gtk_tree_view_set_cursor (GTK_TREE_VIEW (window->device_tree_treeview),
                                 path,
                                 NULL,
                                 FALSE);
@@ -616,7 +589,7 @@ set_selected_object (GduWindow    *window,
           mdraid_object = udisks_client_peek_object (window->client, udisks_block_get_mdraid (block));
           if (mdraid_object != NULL)
             {
-              set_selected_object (window, mdraid_object);
+              select_object (window, mdraid_object);
               goto out;
             }
         }
@@ -627,25 +600,15 @@ set_selected_object (GduWindow    *window,
       goto out;
     }
 
-  if (object != NULL)
+  if (window->current_object != object)
     {
-      if (udisks_object_peek_drive (object) != NULL ||
-          udisks_object_peek_block (object) != NULL ||
-          udisks_object_peek_mdraid (object) != NULL)
-        {
-          select_details_page (window, object, DETAILS_PAGE_DEVICE, &show_flags);
-        }
-      else
-        {
-          g_warning ("no page for object %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
-          select_details_page (window, NULL, DETAILS_PAGE_NOT_IMPLEMENTED, &show_flags);
-        }
+      if (window->current_object != NULL)
+        g_object_unref (window->current_object);
+      window->current_object = object != NULL ? g_object_ref (object) : NULL;
     }
-  else
-    {
-      select_details_page (window, NULL, DETAILS_PAGE_NOT_SELECTED, &show_flags);
-    }
-  update_for_show_flags (window, &show_flags);
+
+  update_all (window);
+
  out:
   return ret;
 }
@@ -674,7 +637,7 @@ ensure_something_selected (GduWindow *window)
                           &object);
   if (object != NULL)
     {
-      set_selected_object (window, object);
+      select_object (window, object);
       g_object_unref (object);
     }
 }
@@ -695,12 +658,12 @@ on_tree_selection_changed (GtkTreeSelection *tree_selection,
                           GDU_DEVICE_TREE_MODEL_COLUMN_OBJECT,
                           &object,
                           -1);
-      set_selected_object (window, object);
+      select_object (window, object);
       g_object_unref (object);
     }
   else
     {
-      set_selected_object (window, NULL);
+      select_object (window, NULL);
       ensure_something_selected (window);
     }
 }
@@ -807,7 +770,7 @@ loop_setup_cb (UDisksManager  *manager,
       udisks_client_settle (data->window->client);
 
       object = udisks_client_get_object (data->window->client, out_loop_device_object_path);
-      set_selected_object (data->window, object);
+      select_object (data->window, object);
       g_object_unref (object);
       g_free (out_loop_device_object_path);
     }
@@ -891,113 +854,59 @@ gdu_window_show_attach_disk_image (GduWindow *window)
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-device_tree_toolbar_update_label (GduWindow *window)
-{
-  GList *selected;
-  GList *l;
-  guint num_disks = 0;
-  guint64 total_size = 0;
-  gchar *s, *s2;
-
-  selected = gdu_device_tree_model_get_selected (window->model);
-  for (l = selected; l != NULL; l = l->next)
-    {
-      UDisksObject *object = UDISKS_OBJECT (l->data);
-      UDisksDrive *drive = NULL;
-      UDisksBlock *block = NULL;
-      UDisksMDRaid *mdraid = NULL;
-
-      drive = udisks_object_peek_drive (object);
-      block = udisks_object_peek_block (object);
-      mdraid = udisks_object_peek_mdraid (object);
-
-      if (drive != NULL)
-        {
-          total_size += udisks_drive_get_size (drive);
-          num_disks++;
-        }
-      else if (block != NULL)
-        {
-          total_size += udisks_block_get_size (block);
-          num_disks++;
-        }
-      else if (mdraid != NULL)
-        {
-          total_size += udisks_mdraid_get_size (mdraid);
-          num_disks++;
-        }
-      else
-        {
-          g_warning ("unhandled object of with path %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
-        }
-    }
-  g_list_free_full (selected, g_object_unref);
-
-  if (num_disks == 0)
-    {
-      /* Translators: Shown in the device tree toolbar when no disks are selected but
-       *              multiple selection is active.
-       */
-      s = g_strdup (C_("multi-disk-menu", "Select Disks Above"));
-    }
-  else
-    {
-      s2 = udisks_client_get_size_for_display (window->client, total_size, FALSE, FALSE);
-      /* Translators: Shown in the device tree toolbar when N>=1 disks are selected.
-       *              The %d is the number of disks selected (e.g. 4).
-       *              The %s is a string with the combined size (e.g. '42.0 GB').
-       */
-      s = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
-                                        "%d Disk Selected (%s)",
-                                        "%d Disks Selected (%s)",
-                                        num_disks),
-                              num_disks, s2);
-      g_free (s2);
-    }
-  gtk_label_set_text (GTK_LABEL (window->device_tree_toolbar_label), s);
-  g_free (s);
-}
-
-static void
-device_tree_toolbar_select_done_toggle (GduWindow *window,
-                                        gboolean   set_clicked)
+device_tree_selection_toolbar_select_done_toggle (GduWindow *window,
+                                                  gboolean   set_clicked)
 {
   GtkStyleContext *context;
 
-  context = gtk_widget_get_style_context (window->device_toolbar);
+  context = gtk_widget_get_style_context (window->device_tree_selection_toolbar);
   if (set_clicked)
     {
       window->in_selection_mode = TRUE;
-      gtk_widget_set_visible (GTK_WIDGET (window->device_tree_toolbar_select_button), FALSE);
-      gtk_widget_set_visible (GTK_WIDGET (window->device_tree_toolbar_done_button), TRUE);
+      gtk_widget_set_visible (GTK_WIDGET (window->device_tree_selection_toolbar_select_button), FALSE);
+      gtk_widget_set_visible (GTK_WIDGET (window->device_tree_selection_toolbar_done_button), TRUE);
+      gtk_notebook_set_current_page (GTK_NOTEBOOK (window->device_tree_selection_toolbar_center_notebook), 1);
       gtk_style_context_add_class (context, "selection-mode");
       gdu_device_tree_model_clear_selected (window->model);
-      device_tree_toolbar_update_label (window);
     }
   else
     {
       window->in_selection_mode = FALSE;
-      gtk_widget_set_visible (GTK_WIDGET (window->device_tree_toolbar_select_button), TRUE);
-      gtk_widget_set_visible (GTK_WIDGET (window->device_tree_toolbar_done_button), FALSE);
-      gtk_label_set_markup (GTK_LABEL (window->device_tree_toolbar_label), "");
+      gtk_widget_set_visible (GTK_WIDGET (window->device_tree_selection_toolbar_select_button), TRUE);
+      gtk_widget_set_visible (GTK_WIDGET (window->device_tree_selection_toolbar_done_button), FALSE);
+      gtk_notebook_set_current_page (GTK_NOTEBOOK (window->device_tree_selection_toolbar_center_notebook), 0);
       gtk_style_context_remove_class (context, "selection-mode");
-      gtk_label_set_markup_with_mnemonic (GTK_LABEL (window->device_tree_toolbar_label), "");
     }
+  update_all (window);
 
   gtk_tree_view_column_set_visible (window->selection_column, window->in_selection_mode);
 
 }
 
+/* ---------------------------------------------------------------------------------------------------- */
+
 static void
-on_device_tree_toolbar_select_button_clicked (GtkButton *button,
-                                              gpointer   user_data)
+on_device_tree_selection_toolbar_select_button_clicked (GtkButton *button,
+                                                        gpointer   user_data)
 {
   GduWindow *window = GDU_WINDOW (user_data);
-  device_tree_toolbar_select_done_toggle (window, TRUE);
+  device_tree_selection_toolbar_select_done_toggle (window, TRUE);
+  update_all (window);
+}
+
+
+static void
+on_device_tree_selection_toolbar_done_button_clicked (GtkButton *button,
+                                                      gpointer   user_data)
+{
+  GduWindow *window = GDU_WINDOW (user_data);
+  device_tree_selection_toolbar_select_done_toggle (window, FALSE);
+  update_all (window);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+#if 0
 static void
 on_device_tree_menu_item_erase_disks (GtkMenuItem *menu_item,
                                       gpointer   user_data)
@@ -1013,14 +922,7 @@ on_device_tree_menu_item_create_raid_array (GtkMenuItem *menu_item,
   GduWindow *window = GDU_WINDOW (user_data);
   gdu_create_raid_array_dialog_show (window);
 }
-
-static void
-on_device_tree_menu_item_abort_selection (GtkMenuItem *menu_item,
-                                          gpointer   user_data)
-{
-  GduWindow *window = GDU_WINDOW (user_data);
-  device_tree_toolbar_select_done_toggle (window, FALSE);
-}
+#endif
 
 /* ---------------------------------------------------------------------------------------------------- */
 
@@ -1075,14 +977,14 @@ gdu_window_select_object (GduWindow    *window,
               drive_object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (drive));
               if (drive_object != NULL)
                 {
-                  if (!set_selected_object (window, drive_object))
+                  if (!select_object (window, drive_object))
                     goto out;
                   ret = TRUE;
                 }
             }
           else
             {
-              if (!set_selected_object (window, object))
+              if (!select_object (window, object))
                 goto out;
               ret = TRUE;
             }
@@ -1162,7 +1064,7 @@ on_constructed_in_idle (gpointer user_data)
   GduWindow *window = GDU_WINDOW (user_data);
   /* select something sensible */
   ensure_something_selected (window);
-  device_tree_toolbar_select_done_toggle (window, FALSE);
+  device_tree_selection_toolbar_select_done_toggle (window, FALSE);
   return FALSE; /* remove source */
 }
 
@@ -1246,12 +1148,32 @@ on_selected_toggled (GtkCellRendererToggle *renderer,
 
   gdu_device_tree_model_toggle_selected (window->model, &iter);
 
-  device_tree_toolbar_update_label (window);
+  update_all (window);
 
  out:
   ;
 }
 
+static gboolean
+device_tree_overlay_on_get_child_position (GtkOverlay   *overlay,
+                                           GtkWidget    *widget,
+                                           GdkRectangle *allocation,
+                                           gpointer      user_data)
+{
+  //GduWindow *window = GDU_WINDOW (user_data);
+  gint border = 16;
+  gint height = 56;
+
+  /* TODO: choose height so we get square buttons */
+
+  allocation->x = border;
+  allocation->y = gtk_widget_get_allocated_height (GTK_WIDGET (overlay)) - height - border;
+  allocation->width = gtk_widget_get_allocated_width (GTK_WIDGET (overlay)) - 2 * border;
+  allocation->height = height;
+
+  return TRUE; /* allocation was filled in */
+}
+
 static void
 gdu_window_constructed (GObject *object)
 {
@@ -1285,6 +1207,14 @@ gdu_window_constructed (GObject *object)
   gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
   gtk_container_set_border_width (GTK_CONTAINER (window), 12);
 
+  /* detach overlay toolbar and attach it to the right place - see also update_for_multi_selection() */
+  gtk_widget_unparent (window->overlay_toolbar);
+  gtk_overlay_add_overlay (GTK_OVERLAY (window->device_tree_overlay), window->overlay_toolbar);
+  g_signal_connect (window->device_tree_overlay,
+                    "get-child-position",
+                    G_CALLBACK (device_tree_overlay_on_get_child_position),
+                    window);
+
   /* hide all children in the devtab list, otherwise the dialog is going to be huge by default */
   children = gtk_container_get_children (GTK_CONTAINER (window->devtab_drive_table));
   for (l = children; l != NULL; l = l->next)
@@ -1303,20 +1233,15 @@ gdu_window_constructed (GObject *object)
   gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->details_notebook), FALSE);
   gtk_notebook_set_show_border (GTK_NOTEBOOK (window->details_notebook), FALSE);
 
-  context = gtk_widget_get_style_context (window->device_scrolledwindow);
-  gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
-  context = gtk_widget_get_style_context (window->device_toolbar);
-  gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
+  context = gtk_widget_get_style_context (window->device_tree_scrolledwindow);
   gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+  context = gtk_widget_get_style_context (window->device_tree_selection_toolbar);
+  //gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
+  gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
 
   window->model = gdu_device_tree_model_new (window->client);
 
-  /* set up mnemonic */
-  gtk_window_add_mnemonic (GTK_WINDOW (window),
-                           'd',
-                           window->device_treeview);
-
-  gtk_tree_view_set_model (GTK_TREE_VIEW (window->device_treeview), GTK_TREE_MODEL (window->model));
+  gtk_tree_view_set_model (GTK_TREE_VIEW (window->device_tree_treeview), GTK_TREE_MODEL (window->model));
   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (window->model),
                                         GDU_DEVICE_TREE_MODEL_COLUMN_SORT_KEY,
                                         GTK_SORT_ASCENDING);
@@ -1327,7 +1252,7 @@ gdu_window_constructed (GObject *object)
                                    NULL, /* user_data */
                                    NULL); /* GDestroyNotify */
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->device_treeview));
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->device_tree_treeview));
   gtk_tree_selection_set_select_function (selection, dont_select_headings, NULL, NULL);
   g_signal_connect (selection,
                     "changed",
@@ -1338,7 +1263,7 @@ gdu_window_constructed (GObject *object)
 
   column = gtk_tree_view_column_new ();
   gtk_tree_view_column_set_expand (column, TRUE);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (window->device_treeview), column);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (window->device_tree_treeview), column);
 
   renderer = gtk_cell_renderer_text_new ();
   gtk_tree_view_column_pack_start (column, renderer, FALSE);
@@ -1394,7 +1319,7 @@ gdu_window_constructed (GObject *object)
   /* -------------------- */
 
   column = gtk_tree_view_column_new ();
-  gtk_tree_view_append_column (GTK_TREE_VIEW (window->device_treeview), column);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (window->device_tree_treeview), column);
   renderer = gtk_cell_renderer_toggle_new ();
   //g_object_set (G_OBJECT (renderer), "indicator-size", 20, NULL);
   gtk_tree_view_column_pack_start (column, renderer, FALSE);
@@ -1416,7 +1341,7 @@ gdu_window_constructed (GObject *object)
                     "row-inserted",
                     G_CALLBACK (on_row_inserted),
                     window);
-  gtk_tree_view_expand_all (GTK_TREE_VIEW (window->device_treeview));
+  gtk_tree_view_expand_all (GTK_TREE_VIEW (window->device_tree_treeview));
 
   g_signal_connect (window->client,
                     "changed",
@@ -1441,9 +1366,13 @@ gdu_window_constructed (GObject *object)
   gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
 
   /* main toolbar */
-  g_signal_connect (window->device_tree_toolbar_select_button,
+  g_signal_connect (window->device_tree_selection_toolbar_select_button,
+                    "clicked",
+                    G_CALLBACK (on_device_tree_selection_toolbar_select_button_clicked),
+                    window);
+  g_signal_connect (window->device_tree_selection_toolbar_done_button,
                     "clicked",
-                    G_CALLBACK (on_device_tree_toolbar_select_button_clicked),
+                    G_CALLBACK (on_device_tree_selection_toolbar_done_button_clicked),
                     window);
 
   /* actions */
@@ -1602,20 +1531,6 @@ gdu_window_constructed (GObject *object)
                     G_CALLBACK (on_activate_link),
                     window);
 
-  /* device-tree add menu */
-  g_signal_connect (window->device_tree_menu_item_create_raid_array,
-                    "activate",
-                    G_CALLBACK (on_device_tree_menu_item_create_raid_array),
-                    window);
-  g_signal_connect (window->device_tree_menu_item_erase_disks,
-                    "activate",
-                    G_CALLBACK (on_device_tree_menu_item_erase_disks),
-                    window);
-  g_signal_connect (window->device_tree_menu_item_abort_selection,
-                    "activate",
-                    G_CALLBACK (on_device_tree_menu_item_abort_selection),
-                    window);
-
   g_idle_add (on_constructed_in_idle, g_object_ref (window));
 }
 
@@ -1735,28 +1650,6 @@ gdu_window_get_client (GduWindow *window)
   return window->client;
 }
 
-static void
-teardown_details_page (GduWindow    *window,
-                       UDisksObject *object,
-                       DetailsPage   page)
-{
-  //g_debug ("teardown for %s, page %d",
-  //       object != NULL ? g_dbus_object_get_object_path (object) : "<none>",
-  //         page);
-  switch (page)
-    {
-    case DETAILS_PAGE_NOT_SELECTED:
-      break;
-
-    case DETAILS_PAGE_NOT_IMPLEMENTED:
-      break;
-
-    case DETAILS_PAGE_DEVICE:
-      teardown_device_page (window);
-      break;
-    }
-}
-
 typedef enum
 {
   SET_MARKUP_FLAGS_NONE = 0,
@@ -1873,85 +1766,47 @@ block_compare_on_preferred (UDisksObject *a,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static void
-setup_details_page (GduWindow     *window,
-                    UDisksObject  *object,
-                    DetailsPage    page)
-{
-  //g_debug ("setup for %s, page %d",
-  //         object != NULL ? g_dbus_object_get_object_path (object) : "<none>",
-  //         page);
-
-  switch (page)
-    {
-    case DETAILS_PAGE_NOT_SELECTED:
-      break;
-
-    case DETAILS_PAGE_NOT_IMPLEMENTED:
-      break;
-
-    case DETAILS_PAGE_DEVICE:
-      setup_device_page (window, object);
-      break;
-    }
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
+static void update_device_page (GduWindow *window, ShowFlags *show_flags);
+static void update_for_multi_selection (GduWindow *window, ShowFlags *show_flags);
 
-static void
-update_details_page (GduWindow      *window,
-                     DetailsPage     page,
-                     ShowFlags      *show_flags)
+/* Keep in sync with tabs in disks.ui file */
+typedef enum
 {
-  ;
-  //g_debug ("update for %s, page %d",
-  //         object != NULL ? g_dbus_object_get_object_path (object) : "<none>",
-  //         page);
-
-  switch (page)
-    {
-    case DETAILS_PAGE_NOT_SELECTED:
-      break;
-
-    case DETAILS_PAGE_NOT_IMPLEMENTED:
-      break;
-
-    case DETAILS_PAGE_DEVICE:
-      update_device_page (window, show_flags);
-      break;
-    }
-}
+  DETAILS_PAGE_NOT_SELECTED,
+  DETAILS_PAGE_NOT_IMPLEMENTED,
+  DETAILS_PAGE_DEVICE,
+} DetailsPage;
 
 static void
-select_details_page (GduWindow      *window,
-                     UDisksObject   *object,
-                     DetailsPage     page,
-                     ShowFlags      *show_flags)
+update_all (GduWindow *window)
 {
-  teardown_details_page (window,
-                         window->current_object,
-                         window->current_page);
+  ShowFlags show_flags = {0};
+  DetailsPage page = DETAILS_PAGE_NOT_IMPLEMENTED;
 
-  window->current_page = page;
+  /* figure out page to display */
   if (window->current_object != NULL)
-    g_object_unref (window->current_object);
-  window->current_object = object != NULL ? g_object_ref (object) : NULL;
+    {
+      if (udisks_object_peek_drive (window->current_object) != NULL ||
+          udisks_object_peek_block (window->current_object) != NULL ||
+          udisks_object_peek_mdraid (window->current_object) != NULL)
+        {
+          page = DETAILS_PAGE_DEVICE;
+        }
+    }
+  else
+    {
+      page = DETAILS_PAGE_NOT_SELECTED;
+    }
 
+  if (page == DETAILS_PAGE_NOT_IMPLEMENTED)
+    {
+      g_warning ("no page for object %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (window->current_object)));
+    }
   gtk_notebook_set_current_page (GTK_NOTEBOOK (window->details_notebook), page);
 
-  setup_details_page (window,
-                      window->current_object,
-                      window->current_page);
-
-  update_details_page (window, window->current_page, show_flags);
-}
+  update_for_multi_selection (window, &show_flags);
 
-static void
-update_all (GduWindow     *window)
-{
-  ShowFlags show_flags = {0};
-
-  switch (window->current_page)
+  switch (page)
     {
     case DETAILS_PAGE_NOT_SELECTED:
       /* Nothing to update */
@@ -1962,10 +1817,10 @@ update_all (GduWindow     *window)
       break;
 
     case DETAILS_PAGE_DEVICE:
-      update_details_page (window, window->current_page, &show_flags);
-      update_for_show_flags (window, &show_flags);
+      update_device_page (window, &show_flags);
       break;
     }
+  update_for_show_flags (window, &show_flags);
 }
 
 static void
@@ -1988,48 +1843,6 @@ on_volume_grid_changed (GduVolumeGrid  *grid,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static void
-setup_device_page (GduWindow     *window,
-                   UDisksObject  *object)
-{
-  UDisksDrive *drive;
-  UDisksMDRaid *mdraid;
-  UDisksBlock *block;
-
-  drive = udisks_object_peek_drive (object);
-  mdraid = udisks_object_peek_mdraid (object);
-  block = udisks_object_peek_block (object);
-
-  if (drive != NULL)
-    {
-      GList *blocks;
-
-      /* TODO: for multipath, ensure e.g. mpathk is before sda, sdb */
-      blocks = get_top_level_blocks_for_drive (window, g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
-      blocks = g_list_sort (blocks, (GCompareFunc) block_compare_on_preferred);
-
-      if (blocks != NULL)
-        gdu_volume_grid_set_block_object (GDU_VOLUME_GRID (window->volume_grid), blocks->data);
-      else
-        gdu_volume_grid_set_block_object (GDU_VOLUME_GRID (window->volume_grid), NULL);
-
-      g_list_foreach (blocks, (GFunc) g_object_unref, NULL);
-      g_list_free (blocks);
-    }
-  else if (mdraid != NULL)
-    {
-      /* happens in update_device_page_for_mdraid as the /dev/md* device can come and go */
-    }
-  else if (block != NULL)
-    {
-      gdu_volume_grid_set_block_object (GDU_VOLUME_GRID (window->volume_grid), object);
-    }
-  else
-    {
-      g_assert_not_reached ();
-    }
-}
-
 static gchar *
 get_device_file_for_display (UDisksBlock *block)
 {
@@ -3401,6 +3214,49 @@ update_device_page_for_free_space (GduWindow          *window,
   g_free (s);
 }
 
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+device_page_ensure_grid (GduWindow *window)
+{
+  UDisksDrive *drive;
+  UDisksMDRaid *mdraid;
+  UDisksBlock *block;
+
+  drive = udisks_object_peek_drive (window->current_object);
+  mdraid = udisks_object_peek_mdraid (window->current_object);
+  block = udisks_object_peek_block (window->current_object);
+
+  if (drive != NULL)
+    {
+      GList *blocks;
+
+      /* TODO: for multipath, ensure e.g. mpathk is before sda, sdb */
+      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)
+        gdu_volume_grid_set_block_object (GDU_VOLUME_GRID (window->volume_grid), blocks->data);
+      else
+        gdu_volume_grid_set_block_object (GDU_VOLUME_GRID (window->volume_grid), NULL);
+
+      g_list_foreach (blocks, (GFunc) g_object_unref, NULL);
+      g_list_free (blocks);
+    }
+  else if (mdraid != NULL)
+    {
+      /* happens in update_device_page_for_mdraid as the /dev/md* device can come and go */
+    }
+  else if (block != NULL)
+    {
+      gdu_volume_grid_set_block_object (GDU_VOLUME_GRID (window->volume_grid), window->current_object);
+    }
+  else
+    {
+      g_assert_not_reached ();
+    }
+}
+
 static void
 update_device_page (GduWindow      *window,
                     ShowFlags      *show_flags)
@@ -3435,6 +3291,9 @@ update_device_page (GduWindow      *window,
   gtk_widget_hide (GTK_WIDGET (window->generic_drive_menu_item_mdraid_sep_1));
   gtk_widget_hide (GTK_WIDGET (window->generic_drive_menu_item_mdraid_disks));
 
+  /* ensure grid is set to the right volumes */
+  device_page_ensure_grid (window);
+
   /* always show the generic toolbar item */
   gtk_action_set_visible (GTK_ACTION (gtk_builder_get_object (window->builder,
                                                               "devtab-action-generic")), TRUE);
@@ -3500,12 +3359,6 @@ update_device_page (GduWindow      *window,
   g_clear_object (&loop);
 }
 
-static void
-teardown_device_page (GduWindow *window)
-{
-  gdu_volume_grid_set_block_object (GDU_VOLUME_GRID (window->volume_grid), NULL);
-}
-
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
@@ -4478,10 +4331,96 @@ on_activate_link (GtkLabel    *label,
       UDisksObject *object = udisks_client_peek_object (window->client, uri + strlen ("x-udisks://"));
       if (object != NULL)
         {
-          set_selected_object (window, object);
+          select_object (window, object);
           handled = TRUE;
         }
     }
 
   return handled;
 }
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_for_multi_selection (GduWindow *window, ShowFlags *show_flags)
+{
+  GList *selected;
+  GList *l;
+  guint num_disks = 0;
+  guint64 total_size = 0;
+  gchar *s, *s2;
+
+  selected = gdu_device_tree_model_get_selected (window->model);
+  for (l = selected; l != NULL; l = l->next)
+    {
+      UDisksObject *object = UDISKS_OBJECT (l->data);
+      UDisksDrive *drive = NULL;
+      UDisksBlock *block = NULL;
+      UDisksMDRaid *mdraid = NULL;
+
+      drive = udisks_object_peek_drive (object);
+      block = udisks_object_peek_block (object);
+      mdraid = udisks_object_peek_mdraid (object);
+
+      if (drive != NULL)
+        {
+          total_size += udisks_drive_get_size (drive);
+          num_disks++;
+        }
+      else if (block != NULL)
+        {
+          total_size += udisks_block_get_size (block);
+          num_disks++;
+        }
+      else if (mdraid != NULL)
+        {
+          total_size += udisks_mdraid_get_size (mdraid);
+          num_disks++;
+        }
+      else
+        {
+          g_warning ("unhandled object of with path %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+        }
+    }
+  g_list_free_full (selected, g_object_unref);
+
+  if (num_disks == 0)
+    {
+      /* Translators: Shown when no devices are selected but multiple selection is active.
+       */
+      s = g_strdup (C_("multi-disk-menu", "No Devices Selected"));
+    }
+  else
+    {
+      s2 = udisks_client_get_size_for_display (window->client, total_size, FALSE, FALSE);
+      /* Translators: Shown when N>=1 devices are selected.
+       *              The %d is the number of disks selected (e.g. 4).
+       *              The %s is a string with the combined size (e.g. '42.0 GB').
+       */
+      s = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
+                                        "%d Device Selected (%s)",
+                                        "%d Devices Selected (%s)",
+                                        num_disks),
+                              num_disks, s2);
+      g_free (s2);
+    }
+  gtk_label_set_text (GTK_LABEL (window->device_tree_selection_toolbar_label), s);
+  g_free (s);
+
+  /* visibility - TODO: use ShowFlags instead */
+  if (window->in_selection_mode && num_disks > 0)
+    {
+      gtk_widget_show (window->overlay_toolbar);
+      gtk_widget_show (window->overlay_toolbar_erase_button);
+      if (num_disks > 1)
+        gtk_widget_show (window->overlay_toolbar_create_raid_button);
+      else
+        gtk_widget_hide (window->overlay_toolbar_create_raid_button);
+    }
+  else
+    {
+      gtk_widget_hide (window->overlay_toolbar);
+    }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */



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