← Back to team overview

elementary-dev-community team mailing list archive

[Merge] lp:~elementary-dev-community/pantheon-files/fix-1086929 into lp:pantheon-files

 

Julián Unrrein has proposed merging lp:~elementary-dev-community/pantheon-files/fix-1086929 into lp:pantheon-files.

Commit message:
Make columns automatically size themselves to fit the longest item contained. Fixes bug #1086929.

Requested reviews:
  David Gomes (davidgomes)
Related bugs:
  Bug #1086929 in Files: "Autosize columns"
  https://bugs.launchpad.net/pantheon-files/+bug/1086929

For more details, see:
https://code.launchpad.net/~elementary-dev-community/pantheon-files/fix-1086929/+merge/183370

By Jeremy Wootten

Make columns automatically size themselves to fit the longest item contained. Fixes bug #1086929.

The first column can't be downsized, for now.
-- 
https://code.launchpad.net/~elementary-dev-community/pantheon-files/fix-1086929/+merge/183370
Your team elementary Developer Community is subscribed to branch lp:~elementary-dev-community/pantheon-files/fix-1086929.
=== modified file 'libcore/gof-directory-async.vala'
--- libcore/gof-directory-async.vala	2013-06-30 15:49:02 +0000
+++ libcore/gof-directory-async.vala	2013-09-01 22:36:03 +0000
@@ -1,16 +1,16 @@
-/*  
+/*
  * Copyright (C) 2011 Marlin Developers
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
@@ -29,7 +29,9 @@
     /* we're looking for particular path keywords like *\/icons* .icons ... */
     public bool uri_contain_keypath_icons;
     public int uri_keypath_size = 0;
-    
+    public string longest_file_name = ""; //for auto-sizing Miller columns
+    public bool track_longest_name;
+
     public enum State {
         NOT_LOADED,
         LOADING,
@@ -38,14 +40,14 @@
     public State state = State.NOT_LOADED;
 
     public HashTable<GLib.File,GOF.File> file_hash;
-    
+
     public uint files_count = 0;
-    
+
     public bool permission_denied = false;
 
     private Cancellable cancellable;
     private FileMonitor? monitor = null;
-    
+
     private List<GOF.File>? sorted_dirs = null;
 
     /* signals */
@@ -77,7 +79,7 @@
         file = GOF.File.get (location);
         file.exists = true;
         cancellable = new Cancellable ();
-        
+        track_longest_name = false;
         //query_info_async (file, file_info_available);
         if (file.info == null)
             file.query_update ();
@@ -110,8 +112,8 @@
         if (is_last) {
             Async dir = (Async) object;
             debug ("Async toggle_ref_notify %s", dir.file.uri);
-         
-            if (!dir.removed_from_cache) 
+
+            if (!dir.removed_from_cache)
                 dir.remove_dir_from_cache ();
             dir.remove_toggle_ref ((ToggleNotify) toggle_ref_notify);
         }
@@ -145,9 +147,10 @@
     public void load ()
     {
         cancellable.reset ();
+        longest_file_name = "";
         if (state != State.LOADED) {
             /* clear directory info if it's not fully loaded */
-            if (state == State.LOADING) 
+            if (state == State.LOADING)
                 clear_directory_info ();
             if (!file.is_mounted) {
                 mount_mountable.begin ();
@@ -160,7 +163,7 @@
             list_directory.begin (location);
             try {
                 monitor = location.monitor_directory (0);
-                monitor.changed.connect (directory_changed);  
+                monitor.changed.connect (directory_changed);
             } catch (IOError e) {
                 if (!(e is IOError.NOT_MOUNTED)) {
                     warning ("directory monitor failed: %s %s", e.message, file.uri);
@@ -173,32 +176,45 @@
             /* send again the info_available signal for reused directories */
             if (file.info != null)
                 file.info_available ();
-                
+
             bool show_hidden = Preferences.get_default ().pref_show_hidden_files;
             foreach (GOF.File gof in file_hash.get_values ()) {
-                if (gof.info != null && (!gof.is_hidden || show_hidden))
+                if (gof.info != null && (!gof.is_hidden || show_hidden)) {
+                    if (track_longest_name)
+                        update_longest_file_name (gof);
                     file_loaded (gof);
+                }
             }
             done_loading ();
         }
     }
 
-    public void load_hiddens () 
+    private void update_longest_file_name (GOF.File gof)
+    {
+        if (longest_file_name.length < gof.basename.length)
+            longest_file_name = gof.basename;
+    }
+
+    public void load_hiddens ()
     {
         if (state != State.LOADED) {
             load ();
         } else {
-            foreach (GOF.File gof in file_hash.get_values ()) {
-                if (gof != null  && gof.info != null && gof.is_hidden)
+             foreach (GOF.File gof in file_hash.get_values ()) {
+                if (gof != null  && gof.info != null && gof.is_hidden) {
+                    if (track_longest_name)
+                        update_longest_file_name (gof);
                     file_loaded (gof);
+                }
             }
         }
+        done_loading ();
     }
 
-    public void update_desktop_files () 
+    public void update_desktop_files ()
     {
         foreach (GOF.File gof in file_hash.get_values ()) {
-            if (gof != null && gof.info != null 
+            if (gof != null && gof.info != null
                 && (!gof.is_hidden || Preferences.get_default ().pref_show_hidden_files)
                 && gof.is_desktop)
                 gof.update_desktop_file ();
@@ -242,6 +258,7 @@
                 if (files == null)
                     break;
 
+                bool show_hidden =  Preferences.get_default ().pref_show_hidden_files;
                 foreach (var file_info in files)
                 {
                     GLib.File loc = location.get_child ((string) file_info.get_name());
@@ -255,14 +272,18 @@
                     //debug ("file: %s", gof.name);
 
                     add_to_hash_cache (gof);
-                    if (!gof.is_hidden || Preferences.get_default ().pref_show_hidden_files)
+
+                    if (!gof.is_hidden || show_hidden) {
+                        if (track_longest_name)
+                            update_longest_file_name (gof);
                         file_loaded (gof);
-
+                    }
                     //mutex.lock ();
                     files_count++;
                     //mutex.unlock ();
                 }
             }
+
             file.exists = true;
             state = State.LOADED;
         } catch (Error err) {
@@ -294,8 +315,8 @@
 
     private async void query_info_async (GOF.File gof, func_query_info? f = null) {
         try {
-            gof.info = yield gof.location.query_info_async (gio_attrs, 
-                                                            FileQueryInfoFlags.NONE, 
+            gof.info = yield gof.location.query_info_async (gio_attrs,
+                                                            FileQueryInfoFlags.NONE,
                                                             Priority.DEFAULT);
             if (f != null)
                 f (gof);
@@ -329,8 +350,13 @@
             /* add to sorted_dirs */
             sorted_dirs.insert_sorted (gof, GOF.File.compare_by_display_name);
         }
+
+        if (track_longest_name && gof.basename.length > longest_file_name.length) {
+            longest_file_name = gof.basename;
+            done_loading ();
+        }
     }
-    
+
     private void file_info_available (GOF.File gof) {
         gof.update ();
         gof.info_available ();
@@ -353,6 +379,9 @@
             sorted_dirs.remove (gof);
         }
         gof.remove_from_caches ();
+        if (track_longest_name && gof.basename.length == longest_file_name.length) {
+            load ();
+        }
     }
 
     private struct fchanges {
@@ -362,7 +391,7 @@
     private List <fchanges?> list_fchanges = null;
     private uint list_fchanges_count = 0;
     /* number of monitored changes to store after that simply reload the dir */
-    private const uint FCHANGES_MAX = 20; 
+    private const uint FCHANGES_MAX = 20;
 
     private void directory_changed (GLib.File _file, GLib.File? other_file, FileMonitorEvent event)
     {
@@ -393,7 +422,7 @@
             //message ("file added %s", _file.get_uri ());
             //notify_file_added (gof);
             MarlinFile.changes_queue_file_added (_file);
-            break;            
+            break;
         case FileMonitorEvent.DELETED:
             //message ("file deleted %s", _file.get_uri ());
             //notify_file_removed (gof);
@@ -424,7 +453,7 @@
                     foreach (var fchange in list_fchanges)
                         real_directory_changed (fchange.file, null, fchange.event);
                 }
-            } 
+            }
             list_fchanges_count = 0;
             list_fchanges = null;
         }
@@ -435,8 +464,8 @@
         foreach (var loc in files) {
             GOF.File gof = GOF.File.get (loc);
             Async? dir = cache_lookup (gof.directory);
-            
-            if (dir != null) 
+
+            if (dir != null)
                 dir.notify_file_changed (gof);
         }
     }
@@ -446,8 +475,8 @@
         foreach (var loc in files) {
             GOF.File gof = GOF.File.get (loc);
             Async? dir = cache_lookup (gof.directory);
-            
-            if (dir != null) 
+
+            if (dir != null)
                 dir.notify_file_added (gof);
         }
     }
@@ -457,7 +486,7 @@
         foreach (var loc in files) {
             GOF.File gof = GOF.File.get (loc);
             Async? dir = cache_lookup (gof.directory);
-            
+
             if (dir != null) {
                 //message ("notify removed %s", gof.uri);
                 dir.notify_file_removed (gof);
@@ -480,7 +509,7 @@
     {
         return from_gfile (gof.get_target_location ());
     }
-    
+
     public static Async? cache_lookup (GLib.File *file)
     {
         Async? cached_dir = null;
@@ -488,7 +517,7 @@
         if (directory_cache == null) {
             directory_cache = new HashTable<GLib.File,GOF.Directory.Async> (GLib.file_hash, GLib.file_equal);
         }
-       
+
         if (directory_cache != null)
             cached_dir = directory_cache.lookup (file);
         if (cached_dir != null) {
@@ -513,14 +542,14 @@
     {
         /* we got to increment the dir ref to remove the toggle_ref */
         this.ref ();
-        
+
         removed_from_cache = true;
         return directory_cache.remove (location);
     }
-    
+
     public bool purge_dir_from_cache () {
         var removed = remove_dir_from_cache ();
-        
+
         /* We have to remove the dir's subfolders from cache too */
         if (removed) {
             foreach (var gfile in file_hash.get_keys ()) {
@@ -529,15 +558,15 @@
                     dir.remove_dir_from_cache ();
             }
         }
-        
+
         return removed;
     }
-    
+
     public bool has_parent ()
     {
         return (file.directory != null);
     }
-    
+
     public GLib.File get_parent ()
     {
         return file.directory;
@@ -549,7 +578,7 @@
 
         if (file_hash != null)
             file_hash_count = file_hash.size ();
-        
+
         //debug ("is_empty hash sizes file: %u", file_hash_count);
         if (state == State.LOADED && file_hash_count == 0)
             return true;
@@ -566,7 +595,7 @@
 
         foreach (var gof in file_hash.get_values()) {
             if (gof.info != null && !gof.is_hidden && gof.is_folder ())
-                sorted_dirs.prepend (gof); 
+                sorted_dirs.prepend (gof);
         }
         sorted_dirs.sort (GOF.File.compare_by_display_name);
 
@@ -600,12 +629,13 @@
         }
         thumbs_loaded ();
         thumbs_thread_runing = false;
-        
+
         this.unref ();
         return null;
     }
 
-    private int icon_size;
+    public int icon_size;
+
     public void threaded_load_thumbnails (int size)
     {
         try {
@@ -641,7 +671,7 @@
             timeout_thumbsq = Timeout.add (40, queue_thumbs_timeout_cb);
         }
     }
-   
+
     private Regex regex_num_size = null;
 
     private void get_keypath_size ()

=== modified file 'src/View/ViewContainer.vala'
--- src/View/ViewContainer.vala	2013-06-14 23:37:29 +0000
+++ src/View/ViewContainer.vala	2013-09-01 22:36:03 +0000
@@ -204,8 +204,10 @@
                         select_childs.prepend (slot.directory.file.location);
                 }
             }
+            
             if (slot != null && slot.directory != null && slot.directory.file.exists) {
                 slot.directory.cancel();
+                slot.directory.track_longest_name = false;
             }
 
             if (nview == ViewMode.MILLER) {

=== modified file 'src/fm-columns-view.c'
--- src/fm-columns-view.c	2013-08-01 21:24:46 +0000
+++ src/fm-columns-view.c	2013-09-01 22:36:03 +0000
@@ -73,17 +73,17 @@
 static gboolean fm_columns_view_draw(GtkWidget* view_, cairo_t* cr, FMColumnsView* view)
 {
     g_return_val_if_fail(FM_IS_COLUMNS_VIEW(view), FALSE);
-    
+
     GOFDirectoryAsync *dir = fm_directory_view_get_current_directory (FM_DIRECTORY_VIEW (view));
 
     if (gof_directory_async_is_empty (dir))
     {
         PangoLayout* layout = gtk_widget_create_pango_layout(GTK_WIDGET(view), NULL);
-        gchar *str = g_strconcat("<span size='x-large'>", _("This folder is empty."), "</span>", NULL);
-        pango_layout_set_markup (layout, str, -1);
-
+        //gchar *str = g_strconcat("<span size='x-large'>", _("This folder is empty."), "</span>", NULL);
+        //const gchar *str = FM_DIRECTORY_VIEW (view)->empty_message;
+        pango_layout_set_markup (layout, FM_DIRECTORY_VIEW (view)->empty_message, -1);
         PangoRectangle extents;
-        /* Get hayout height and width */
+        /* Get layout height and width */
         pango_layout_get_extents(layout, NULL, &extents);
         gdouble width = pango_units_to_double(extents.width);
         gdouble height = pango_units_to_double(extents.height);
@@ -118,7 +118,7 @@
     /* don't update column if we got a drag_begin started */
     if (fm_directory_view_is_drag_pending (FM_DIRECTORY_VIEW (view)))
         return;
- 
+
     /* setup the current active slot */
     fm_directory_view_set_active_slot (FM_DIRECTORY_VIEW (view));
     fm_directory_view_notify_selection_changed (FM_DIRECTORY_VIEW (view));
@@ -148,7 +148,7 @@
 static void
 row_activated_callback (GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *path, FMColumnsView *view)
 {
-    g_message ("%s\n", G_STRFUNC);
+    g_debug ("%s\n", G_STRFUNC);
     fm_directory_view_activate_selected_items (FM_DIRECTORY_VIEW (view), MARLIN_WINDOW_OPEN_FLAG_NEW_TAB);
 }
 
@@ -156,18 +156,18 @@
 fm_columns_view_freeze_updates (FMColumnsView *view)
 {
     /* Make filename-cells editable. */
-	g_object_set (G_OBJECT (view->details->file_name_cell),
+    g_object_set (G_OBJECT (view->details->file_name_cell),
                   "editable", TRUE, NULL);
-	fm_directory_view_freeze_updates (FM_DIRECTORY_VIEW (view));
+    fm_directory_view_freeze_updates (FM_DIRECTORY_VIEW (view));
 }
 
 static void
 fm_columns_view_unfreeze_updates (FMColumnsView *view)
 {
     /*We're done editing - make the filename-cells readonly again.*/
-	g_object_set (G_OBJECT (view->details->file_name_cell),
+    g_object_set (G_OBJECT (view->details->file_name_cell),
                   "editable", FALSE, NULL);
-	fm_directory_view_unfreeze_updates (FM_DIRECTORY_VIEW (view));
+    fm_directory_view_unfreeze_updates (FM_DIRECTORY_VIEW (view));
 }
 
 static void
@@ -176,32 +176,32 @@
                                  GError *error,
                                  gpointer callback_data)
 {
-	FMColumnsView *view = FM_COLUMNS_VIEW (callback_data);
+    FMColumnsView *view = FM_COLUMNS_VIEW (callback_data);
 
     printf ("%s\n", G_STRFUNC);
-	if (view->details->renaming_file) {
-		view->details->rename_done = TRUE;
-		
-		if (error != NULL) {
+    if (view->details->renaming_file) {
+        view->details->rename_done = TRUE;
+
+        if (error != NULL) {
             marlin_dialogs_show_error (GTK_WIDGET (view), error, _("Failed to rename %s to %s"), g_file_info_get_name (file->info), view->details->original_name);
-			/* If the rename failed (or was cancelled), kill renaming_file.
-			 * We won't get a change event for the rename, so otherwise
-			 * it would stay around forever.
-			 */
+            /* If the rename failed (or was cancelled), kill renaming_file.
+             * We won't get a change event for the rename, so otherwise
+             * it would stay around forever.
+             */
             g_object_unref (view->details->renaming_file);
-		}
-	}
-	
-	g_object_unref (view);
+        }
+    }
+
+    g_object_unref (view);
 }
 
 static void
 editable_focus_out_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
 {
-	FMColumnsView *view = user_data;
+    FMColumnsView *view = user_data;
 
-	fm_columns_view_unfreeze_updates (view);
-	view->details->editable_widget = NULL;
+    fm_columns_view_unfreeze_updates (view);
+    view->details->editable_widget = NULL;
 }
 
 static void
@@ -210,17 +210,17 @@
                                   const gchar *path_str,
                                   FMColumnsView *col_view)
 {
-	GtkEntry *entry;
-
-	entry = GTK_ENTRY (editable);
-	col_view->details->editable_widget = editable;
-
-	/* Free a previously allocated original_name */
-	g_free (col_view->details->original_name);
-
-	col_view->details->original_name = g_strdup (gtk_entry_get_text (entry));
-
-	g_signal_connect (entry, "focus-out-event",
+    GtkEntry *entry;
+
+    entry = GTK_ENTRY (editable);
+    col_view->details->editable_widget = editable;
+
+    /* Free a previously allocated original_name */
+    g_free (col_view->details->original_name);
+
+    col_view->details->original_name = g_strdup (gtk_entry_get_text (entry));
+
+    g_signal_connect (entry, "focus-out-event",
                       G_CALLBACK (editable_focus_out_cb), col_view);
 }
 
@@ -228,8 +228,8 @@
 cell_renderer_editing_canceled (GtkCellRendererText *cell,
                                 FMColumnsView          *view)
 {
-	view->details->editable_widget = NULL;
-	fm_columns_view_unfreeze_updates (view);
+    view->details->editable_widget = NULL;
+    fm_columns_view_unfreeze_updates (view);
 }
 
 static void
@@ -238,43 +238,43 @@
                       const char          *new_text,
                       FMColumnsView          *view)
 {
-	GtkTreePath *path;
-	GOFFile *file;
-	GtkTreeIter iter;
+    GtkTreePath *path;
+    GOFFile *file;
+    GtkTreeIter iter;
 
     printf ("%s\n", G_STRFUNC);
-	view->details->editable_widget = NULL;
-
-	/* Don't allow a rename with an empty string. Revert to original 
-	 * without notifying the user.
-	 */
-	if (new_text[0] == '\0') {
-		fm_columns_view_unfreeze_updates (view);
-		return;
-	}
-	
-	path = gtk_tree_path_new_from_string (path_str);
-
-	gtk_tree_model_get_iter (GTK_TREE_MODEL (view->model), &iter, path);
-
-	gtk_tree_path_free (path);
-	
-	gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter,
+    view->details->editable_widget = NULL;
+
+    /* Don't allow a rename with an empty string. Revert to original
+     * without notifying the user.
+     */
+    if (new_text[0] == '\0') {
+        fm_columns_view_unfreeze_updates (view);
+        return;
+    }
+
+    path = gtk_tree_path_new_from_string (path_str);
+
+    gtk_tree_model_get_iter (GTK_TREE_MODEL (view->model), &iter, path);
+
+    gtk_tree_path_free (path);
+
+    gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter,
                         FM_LIST_MODEL_FILE_COLUMN, &file, -1);
 
-	/* Only rename if name actually changed */
-	if (strcmp (new_text, view->details->original_name) != 0) {
-		view->details->renaming_file = gof_file_ref (file);
-		view->details->rename_done = FALSE;
-		gof_file_rename (file, new_text, fm_columns_view_rename_callback, g_object_ref (view));
-
-		g_free (view->details->original_name);
-		view->details->original_name = g_strdup (new_text);
-	}
-	
-	gof_file_unref (file);
-
-	fm_columns_view_unfreeze_updates (view);
+    /* Only rename if name actually changed */
+    if (strcmp (new_text, view->details->original_name) != 0) {
+        view->details->renaming_file = gof_file_ref (file);
+        view->details->rename_done = FALSE;
+        gof_file_rename (file, new_text, fm_columns_view_rename_callback, g_object_ref (view));
+
+        g_free (view->details->original_name);
+        view->details->original_name = g_strdup (new_text);
+    }
+
+    gof_file_unref (file);
+
+    fm_columns_view_unfreeze_updates (view);
 }
 
 static void
@@ -282,35 +282,35 @@
                                      GOFFile *file,
                                      gboolean select_all)
 {
-	FMColumnsView *col_view;
-	GtkTreeIter iter;
-	GtkTreePath *path;
-	gint start_offset, end_offset;
-
-	col_view = FM_COLUMNS_VIEW (view);
-
-    g_message ("%s", G_STRFUNC);
-	/* Select all if we are in renaming mode already */
-	if (col_view->details->file_name_column && col_view->details->editable_widget) {
-		gtk_editable_select_region (GTK_EDITABLE (col_view->details->editable_widget),
+    FMColumnsView *col_view;
+    GtkTreeIter iter;
+    GtkTreePath *path;
+    gint start_offset, end_offset;
+
+    col_view = FM_COLUMNS_VIEW (view);
+
+    g_debug ("%s", G_STRFUNC);
+    /* Select all if we are in renaming mode already */
+    if (col_view->details->file_name_column && col_view->details->editable_widget) {
+        gtk_editable_select_region (GTK_EDITABLE (col_view->details->editable_widget),
                                     0, -1);
-		return;
-	}
-
-	if (!fm_list_model_get_first_iter_for_file (col_view->model, file, &iter)) {
-		return;
-	}
-
-	/* Freeze updates to the view to prevent losing rename focus when the tree view updates */
-	fm_columns_view_freeze_updates (col_view);
-
-	path = gtk_tree_model_get_path (GTK_TREE_MODEL (col_view->model), &iter);
-
-	gtk_tree_view_scroll_to_cell (col_view->tree, NULL,
+        return;
+    }
+
+    if (!fm_list_model_get_first_iter_for_file (col_view->model, file, &iter)) {
+        return;
+    }
+
+    /* Freeze updates to the view to prevent losing rename focus when the tree view updates */
+    fm_columns_view_freeze_updates (col_view);
+
+    path = gtk_tree_model_get_path (GTK_TREE_MODEL (col_view->model), &iter);
+
+    gtk_tree_view_scroll_to_cell (col_view->tree, NULL,
                                   col_view->details->file_name_column,
                                   TRUE, 0.0, 0.0);
-	/* set cursor also triggers editing-started, where we save the editable widget */
-	/*gtk_tree_view_set_cursor (col_view->tree, path,
+    /* set cursor also triggers editing-started, where we save the editable widget */
+    /*gtk_tree_view_set_cursor (col_view->tree, path,
                               col_view->details->file_name_column, TRUE);*/
     /* sound like set_cursor is not enought to trigger editing-started, we use cursor_on_cell instead */
     gtk_tree_view_set_cursor_on_cell (col_view->tree, path,
@@ -318,15 +318,15 @@
                                       (GtkCellRenderer *) col_view->details->file_name_cell,
                                       TRUE);
 
-	if (col_view->details->editable_widget != NULL) {
-		eel_filename_get_rename_region (col_view->details->original_name,
+    if (col_view->details->editable_widget != NULL) {
+        eel_filename_get_rename_region (col_view->details->original_name,
                                         &start_offset, &end_offset);
 
-		gtk_editable_select_region (GTK_EDITABLE (col_view->details->editable_widget),
+        gtk_editable_select_region (GTK_EDITABLE (col_view->details->editable_widget),
                                     start_offset, end_offset);
-	}
+    }
 
-	gtk_tree_path_free (path);
+    gtk_tree_path_free (path);
 }
 
 static void fm_columns_view_select_all(FMDirectoryView *view)
@@ -460,17 +460,17 @@
     GtkTreeSelection    *selection;
     GtkTreePath         *path;
 
-    g_message ("%s", G_STRFUNC);
+    g_debug ("%s", G_STRFUNC);
     if (view->details->pressed_button == event->button && view->details->pressed_button != -1)
     {
         view->details->updates_frozen = FALSE;
         selection = gtk_tree_view_get_selection (tree_view);
         list_selection_changed_callback (selection, view);
-        
+
         /* reset the pressed_button state */
         view->details->pressed_button = -1;
     }
-    
+
 
     return TRUE;
 }
@@ -684,7 +684,7 @@
 }
 
 static void
-fm_columns_view_set_cursor (FMDirectoryView *view, GtkTreePath *path, 
+fm_columns_view_set_cursor (FMDirectoryView *view, GtkTreePath *path,
                             gboolean start_editing, gboolean select)
 {
     FMColumnsView *cols_view = FM_COLUMNS_VIEW (view);
@@ -692,12 +692,12 @@
 
     /* the treeview select the path by default. */
     g_signal_handlers_block_by_func (selection, list_selection_changed_callback, cols_view);
-    gtk_tree_view_set_cursor_on_cell (cols_view->tree, path, 
+    gtk_tree_view_set_cursor_on_cell (cols_view->tree, path,
                                       cols_view->details->file_name_column,
                                       (GtkCellRenderer *) cols_view->details->file_name_cell,
                                       start_editing);
 
-    if (!select) 
+    if (!select)
         gtk_tree_selection_unselect_path (selection, path);
     g_signal_handlers_unblock_by_func (selection, list_selection_changed_callback, cols_view);
 }
@@ -724,7 +724,7 @@
 }
 
 static gboolean
-fm_columns_view_get_visible_range (FMDirectoryView *view, 
+fm_columns_view_get_visible_range (FMDirectoryView *view,
                                    GtkTreePath     **start_path,
                                    GtkTreePath     **end_path)
 
@@ -738,7 +738,7 @@
 fm_columns_view_zoom_normal (FMDirectoryView *view)
 {
     MarlinZoomLevel     zoom;
-    
+
     zoom = g_settings_get_enum (marlin_column_view_settings, "default-zoom-level");
     g_settings_set_enum (marlin_column_view_settings, "zoom-level", zoom);
 }
@@ -755,7 +755,7 @@
         gof_file_list_free (view->details->selection);
 
     g_free (view->details);
-    G_OBJECT_CLASS (fm_columns_view_parent_class)->finalize (object); 
+    G_OBJECT_CLASS (fm_columns_view_parent_class)->finalize (object);
 }
 
 static void
@@ -767,8 +767,8 @@
     create_and_set_up_tree_view (view);
 
     //fm_columns_view_click_policy_changed (FM_DIRECTORY_VIEW (view));
-    
-    g_settings_bind (marlin_column_view_settings, "zoom-level", 
+
+    g_settings_bind (marlin_column_view_settings, "zoom-level",
                      view, "zoom-level", 0);
 }
 
@@ -780,7 +780,7 @@
     gint xpad, ypad;
 
     gtk_cell_renderer_get_padding (view->icon_renderer, &xpad, &ypad);
-    gtk_cell_renderer_set_fixed_size (view->icon_renderer, 
+    gtk_cell_renderer_set_fixed_size (view->icon_renderer,
                                       marlin_zoom_level_to_icon_size (view->zoom_level) + 2 * xpad,
                                       marlin_zoom_level_to_icon_size (view->zoom_level) + 2 * ypad);
     gtk_tree_view_columns_autosize (FM_COLUMNS_VIEW (view)->tree);
@@ -801,7 +801,7 @@
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
-    }   
+    }
 }
 
 static void
@@ -818,7 +818,7 @@
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
-    }   
+    }
 }
 #endif
 
@@ -835,7 +835,7 @@
     fm_directory_view_class = FM_DIRECTORY_VIEW_CLASS (klass);
 
     fm_directory_view_class->sync_selection = fm_columns_view_sync_selection;
-    fm_directory_view_class->get_selection = fm_columns_view_get_selection; 
+    fm_directory_view_class->get_selection = fm_columns_view_get_selection;
     fm_directory_view_class->get_selection_for_file_transfer = fm_columns_view_get_selection_for_file_transfer;
     fm_directory_view_class->get_selected_paths = fm_columns_view_get_selected_paths;
     fm_directory_view_class->select_path = fm_columns_view_select_path;

=== modified file 'src/fm-directory-view.c'
--- src/fm-directory-view.c	2013-08-01 21:24:46 +0000
+++ src/fm-directory-view.c	2013-09-01 22:36:03 +0000
@@ -118,7 +118,7 @@
     guint               thumbnail_source_id;
     gboolean            thumbnailing_scheduled;
 
-    /* Tree path for restoring the selection after selecting and 
+    /* Tree path for restoring the selection after selecting and
      * deleting an item */
     GtkTreePath     *selection_before_delete;
     GOFFile         *newly_folder_added;
@@ -229,15 +229,14 @@
 };
 
 static gpointer _g_object_ref0 (gpointer self) {
-	return self ? g_object_ref (self) : NULL;
+    return self ? g_object_ref (self) : NULL;
 }
 
-
 void fm_directory_view_colorize_selection (FMDirectoryView *view, int ncolor)
 {
     g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
     g_return_if_fail (tags != NULL);
-        
+
     marlin_view_tags_set_color (tags, view, ncolor, NULL, NULL);
 }
 
@@ -266,7 +265,7 @@
 static void
 file_changed_callback (GOFDirectoryAsync *directory, GOFFile *file, FMDirectoryView *view)
 {
-    /*if (!file->exists) 
+    /*if (!file->exists)
         return;*/
     g_return_if_fail (file != NULL);
     g_return_if_fail (file->exists);
@@ -280,7 +279,7 @@
 static void
 file_deleted_callback (GOFDirectoryAsync *directory, GOFFile *file, FMDirectoryView *view)
 {
-    g_debug ("%s %s", G_STRFUNC, file->uri); 
+    g_debug ("%s %s", G_STRFUNC, file->uri);
     fm_list_model_remove_file (view->model, file, directory);
     /* Remove from gof-directory-async cache */
     if (gof_file_is_folder (file)) {
@@ -291,7 +290,7 @@
                 g_debug ("Remove from gof-directory-async cache %s\n", file->uri);
             g_object_unref (dir);
         }
-            
+
         if (view->details->slot->mwcols) {
             /* if in miller view mode, remove any views of subdirectories of deleted directory */
             gtk_container_foreach (GTK_CONTAINER (view->details->slot->mwcols->active_slot->colpane), (GtkCallback) gtk_widget_destroy, NULL);
@@ -312,12 +311,17 @@
     }
     else
         dir_action_set_sensitive (view, "Select All", TRUE);
-            
+
     MarlinZoomLevel zoom;
     g_object_get (view, "zoom-level", &zoom, NULL);
     int size = marlin_zoom_level_to_icon_size (zoom);
     gof_directory_async_threaded_load_thumbnails (view->details->slot->directory, size);
     //g_signal_emit (view, signals[DIRECTORY_LOADED], 0, directory);
+    /* If in Miller view, autosize the column */
+    if (view->details->slot->ready_to_autosize)
+        autosize_slot (view->details->slot);
+    else
+        view->details->slot->ready_to_autosize = TRUE;
 }
 
 static void
@@ -352,11 +356,11 @@
         gof_directory_async_load_hiddens (directory);
         g_signal_handlers_disconnect_by_func (directory, file_loaded_callback, view);
     } else {
-        /* while the model is cleared and re-loaded we do not want the view to update */ 
+        /* while the model is cleared and re-loaded we do not want the view to update */
         g_signal_handlers_block_by_func (view->model, fm_directory_view_row_deleted, view);
         g_signal_handlers_block_by_func (view->model, fm_directory_view_restore_selection, view);
         view->updates_frozen = TRUE;
-        
+
         /* clear the model */
         fm_list_model_clear (view->model);
 
@@ -365,7 +369,7 @@
         gof_directory_async_load (directory);
         g_signal_handlers_disconnect_by_func (directory, file_loaded_callback, view);
 
-        /* re-instate signals and unfreeze view */ 
+        /* re-instate signals and unfreeze view */
         g_signal_handlers_unblock_by_func (view->model, fm_directory_view_row_deleted, view);
         g_signal_handlers_unblock_by_func (view->model, fm_directory_view_restore_selection, view);
         view->updates_frozen = FALSE;
@@ -384,24 +388,24 @@
 static void
 fm_directory_view_connect_directory_handlers (FMDirectoryView *view, GOFDirectoryAsync *directory)
 {
-    g_signal_connect (directory, "file_loaded", 
+    g_signal_connect (directory, "file_loaded",
                       G_CALLBACK (file_loaded_callback), view);
-    g_signal_connect (directory, "file_added", 
+    g_signal_connect (directory, "file_added",
                       G_CALLBACK (file_added_callback), view);
-    g_signal_connect (directory, "file_changed", 
+    g_signal_connect (directory, "file_changed",
                       G_CALLBACK (file_changed_callback), view);
-    g_signal_connect (directory, "file_deleted", 
+    g_signal_connect (directory, "file_deleted",
                       G_CALLBACK (file_deleted_callback), view);
-    g_signal_connect (directory, "done_loading", 
+    g_signal_connect (directory, "done_loading",
                       G_CALLBACK (directory_done_loading_callback), view);
-    g_signal_connect (directory, "thumbs_loaded", 
+    g_signal_connect (directory, "thumbs_loaded",
                       G_CALLBACK (directory_thumbs_loaded_callback), view);
-    g_signal_connect (directory, "icon_changed", 
+    g_signal_connect (directory, "icon_changed",
                       G_CALLBACK (icon_changed_callback), view);
 }
 
 static void
-fm_directory_view_disconnect_directory_handlers (FMDirectoryView *view, 
+fm_directory_view_disconnect_directory_handlers (FMDirectoryView *view,
                                                  GOFDirectoryAsync *directory)
 {
     /*g_signal_handlers_disconnect_by_func (directory, file_loaded_callback, view);*/
@@ -433,7 +437,7 @@
 
     if (!fm_directory_view_get_loading (view)) {
         g_object_get (view, "zoom-level", &zoom, NULL);
-        gof_directory_async_queue_load_thumbnails (view->details->slot->directory, 
+        gof_directory_async_queue_load_thumbnails (view->details->slot->directory,
                                                    marlin_zoom_level_to_icon_size (zoom));
     }
 }
@@ -488,20 +492,25 @@
     /* setup the list model */
     g_signal_connect (view->model, "row-deleted", G_CALLBACK (fm_directory_view_row_deleted), view);
     g_signal_connect_after (view->model, "row-deleted", G_CALLBACK (fm_directory_view_restore_selection), view);
-    
+
     g_signal_connect (view->model, "sort_column_changed", G_CALLBACK (sort_column_changed_callback), view);
 
     /* connect to size allocation signals for generating thumbnail requests */
     g_signal_connect_after (G_OBJECT (view), "size-allocate",
                             G_CALLBACK (fm_directory_view_size_allocate), NULL);
 
-    g_signal_connect (G_OBJECT (view), "notify::zoom-level", 
+    g_signal_connect (G_OBJECT (view), "notify::zoom-level",
                       G_CALLBACK (zoom_level_changed), NULL);
 
     view->details->dir_action_group = NULL;
     view->details->dir_merge_id = 0;
     view->details->open_with_action_group = NULL;
     view->details->open_with_merge_id = 0;
+    view->empty_message = g_strconcat ("<span size='x-large'>",
+                                        _("This folder is empty."),
+                                        "</span>",
+                                        NULL);
+
 }
 
 static GObject*
@@ -626,12 +635,12 @@
     /* release the context menu references */
     if (view->details->menu_selection) {
         gpointer old_menuitems = g_object_get_data(G_OBJECT (view->details->menu_selection), "other_selection");
-        g_list_free_full (old_menuitems, (GDestroyNotify) gtk_widget_destroy); 
-        g_object_set_data (G_OBJECT (view->details->menu_selection), "other_selection", NULL); 
+        g_list_free_full (old_menuitems, (GDestroyNotify) gtk_widget_destroy);
+        g_object_set_data (G_OBJECT (view->details->menu_selection), "other_selection", NULL);
     }
 
     g_free (view->details->previewer);
-    
+
     if (view->details->newly_folder_added)
         g_object_unref (view->details->newly_folder_added);
 
@@ -672,12 +681,12 @@
     g_signal_emit_by_name (slot->ctab, "path-changed", location);
 }
 
-/* TODO remove screen if we don't create any new windows 
+/* TODO remove screen if we don't create any new windows
 ** (check if we have to) */
 static void
-fm_directory_view_activate_single_file (FMDirectoryView *view, 
-                                        GOFFile *file, 
-                                        GdkScreen *screen, 
+fm_directory_view_activate_single_file (FMDirectoryView *view,
+                                        GOFFile *file,
+                                        GdkScreen *screen,
                                         MarlinViewWindowOpenFlags flags)
 {
     GFile *location;
@@ -686,7 +695,7 @@
     location = gof_file_get_target_location (file);
 
     //g_message ("%s %s %s", G_STRFUNC, file->uri, g_file_get_uri(location));
-    if (gof_file_is_folder (file)) 
+    if (gof_file_is_folder (file))
     {
         switch (flags) {
         case MARLIN_WINDOW_OPEN_FLAG_NEW_TAB:
@@ -758,7 +767,7 @@
     }
 
     selection = fm_directory_view_get_selection (view);
-    /* FIXME only grab the first selection item as gloobus-preview is unable to handle 
+    /* FIXME only grab the first selection item as gloobus-preview is unable to handle
        multiple selection */
     if (selection != NULL) {
         file = selection->data;
@@ -777,34 +786,34 @@
     }
 }
 
-void 
+void
 fm_directory_view_zoom_normal (FMDirectoryView *view)
 {
     (*FM_DIRECTORY_VIEW_GET_CLASS (view)->zoom_normal) (view);
 }
 
-void 
+void
 fm_directory_view_zoom_in (FMDirectoryView *view)
 {
     MarlinZoomLevel zoom;
 
     g_object_get (view, "zoom-level", &zoom, NULL);
     zoom++;
-    if (zoom >= MARLIN_ZOOM_LEVEL_SMALLEST 
+    if (zoom >= MARLIN_ZOOM_LEVEL_SMALLEST
         && zoom <= MARLIN_ZOOM_LEVEL_LARGEST)
     {
         g_object_set (G_OBJECT (view), "zoom-level", zoom, NULL);
     }
 }
 
-void 
+void
 fm_directory_view_zoom_out (FMDirectoryView *view)
 {
     MarlinZoomLevel zoom;
 
     g_object_get (view, "zoom-level", &zoom, NULL);
     zoom--;
-    if (zoom >= MARLIN_ZOOM_LEVEL_SMALLEST 
+    if (zoom >= MARLIN_ZOOM_LEVEL_SMALLEST
         && zoom <= MARLIN_ZOOM_LEVEL_LARGEST)
     {
         g_object_set (view, "zoom-level", zoom, NULL);
@@ -816,7 +825,7 @@
                                        GdkEventScroll *event)
 {
     gdouble total_delta_y = 0;
-	gdouble delta_x, delta_y;
+    gdouble delta_x, delta_y;
 
     if (event->state & GDK_CONTROL_MASK) {
         switch (event->direction) {
@@ -846,7 +855,7 @@
                 total_delta_y = 0;
                 /* emulate scroll up */
                 fm_directory_view_zoom_in (directory_view);
-                return TRUE;				
+                return TRUE;
             } else {
                 /* eat event */
                 return TRUE;
@@ -1013,7 +1022,7 @@
         //printf ("%s path %s\n", G_STRFUNC, gtk_tree_path_to_string (path));
         /* determine the file for the path */
         file = fm_list_model_file_for_path (view->model, path);
-        
+
         /* If file == NULL, it means that the path in question is a blank path,
          * which can only exist under an expanded empty folder.
          * In this case, we set the destination target to that folder. */
@@ -1143,13 +1152,13 @@
         /* determine the file for the drop position */
         file = fm_directory_view_get_drop_file (view, x, y, NULL);
         g_debug ("%s XdndDirectSave0 %s", G_STRFUNC, file->uri);
-        
+
         if (G_LIKELY (file != NULL))
         {
             /* determine the file name from the DnD source window */
-            if (gdk_property_get (gdk_drag_context_get_source_window (context), 
+            if (gdk_property_get (gdk_drag_context_get_source_window (context),
                                   gdk_atom_intern_static_string ("XdndDirectSave0"),
-                                  gdk_atom_intern_static_string ("text/plain"), 
+                                  gdk_atom_intern_static_string ("text/plain"),
                                   0, 1024, FALSE, NULL, NULL,
                                   &prop_len, &prop_text) && prop_text != NULL)
             {
@@ -1191,7 +1200,7 @@
             /* release the file reference */
             g_object_unref (G_OBJECT (file));
         }
-        
+
         /* if uri == NULL, we didn't set the property */
         if (G_UNLIKELY (uri == NULL))
             return FALSE;
@@ -1650,7 +1659,7 @@
     return TRUE;
 }
 
-static gboolean 
+static gboolean
 is_selection_contain_only_folders (GList *selection)
 {
     GOFFile *file;
@@ -1695,7 +1704,7 @@
 }
 
 static void
-dir_action_set_visible_sensitive (FMDirectoryView *view, const gchar *action_name, 
+dir_action_set_visible_sensitive (FMDirectoryView *view, const gchar *action_name,
                                   gboolean visible, gboolean sensitive)
 {
     GtkAction *action;
@@ -1802,7 +1811,7 @@
 
 static void
 add_application_to_open_with_menu (FMDirectoryView *view,
-                                   GAppInfo *application, 
+                                   GAppInfo *application,
                                    GList *files,
                                    int index,
                                    const char *menu_placeholder,
@@ -1846,7 +1855,7 @@
 
     g_signal_connect_data (action, "activate",
                            G_CALLBACK (open_with_launch_application_callback),
-                           launch_parameters, 
+                           launch_parameters,
                            (GClosureNotify)application_launch_parameters_free, 0);
 
     gtk_action_group_add_action (view->details->open_with_action_group,
@@ -1895,11 +1904,11 @@
     for (l=apps; l != NULL; l=l->next) {
         app = (GAppInfo *) l->data;
         id1 = g_app_info_get_id (app);
-        if (id1 != NULL && id2 != NULL 
-            && strcmp (id1, id2) == 0) 
+        if (id1 != NULL && id2 != NULL
+            && strcmp (id1, id2) == 0)
         {
-			g_object_unref (app);
-            apps = g_list_delete_link (apps, l); 
+            g_object_unref (app);
+            apps = g_list_delete_link (apps, l);
         }
     }
 
@@ -1925,7 +1934,7 @@
     selection = fm_directory_view_get_selection (view);
     selection_count = g_list_length (selection);
     file = GOF_FILE (selection->data);
-    
+
     if (file == NULL) {
         update_menus_empty_selection (view);
         return;
@@ -1988,7 +1997,7 @@
     /* Only force displaying the icon if it is an application icon */
     gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), app_icon != NULL);
 
-    if (app_icon == NULL) 
+    if (app_icon == NULL)
         app_icon = g_themed_icon_new (GTK_STOCK_OPEN);
 
     gtk_action_set_gicon (action, app_icon);
@@ -2006,7 +2015,7 @@
     g_free (mnemonic);
 
     /* OpenAlternate label update */
-    if (selection_count > 1) 
+    if (selection_count > 1)
         mnemonic = g_strdup_printf (_("Open in %'d New _Windows"), selection_count);
     else
         mnemonic = NULL;
@@ -2022,8 +2031,8 @@
 
     /* if there s no default app then there s no common possible type to get other applications.
     checking the first file is enought to determine if we have a full directory selection
-    as the only possible common type for a directory is a directory. 
-    We don't want File Managers applications list in the open with menu for a directory(ies) 
+    as the only possible common type for a directory is a directory.
+    We don't want File Managers applications list in the open with menu for a directory(ies)
     selection */
     if (view->details->open_with_apps != NULL) {
         g_list_free_full (view->details->open_with_apps, g_object_unref);
@@ -2032,16 +2041,16 @@
     if (view->details->default_app != NULL && !gof_file_is_folder (file))
         view->details->open_with_apps = marlin_mime_get_applications_for_files (selection);
     /* we need to remove the default app from open with menu */
-    if (view->details->default_app != NULL && !gof_file_is_executable (file)) 
+    if (view->details->default_app != NULL && !gof_file_is_executable (file))
         view->details->open_with_apps = filter_default_app (view->details->open_with_apps, view->details->default_app);
     for (l = view->details->open_with_apps, index=0; l != NULL && index <10; l=l->next, index++) {
-        add_application_to_open_with_menu (view, 
-                                           l->data, 
+        add_application_to_open_with_menu (view,
+                                           l->data,
                                            selection,
                                            index,
                                            menu_path, popup_path);
     }
-    
+
     if (selection_count == 1 && !gof_file_is_folder (file))
         dir_action_set_visible (view, "OtherApplication", TRUE);
 }
@@ -2203,7 +2212,7 @@
     g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
     g_return_if_fail (view->model == model);
 
-    g_message ("%s", G_STRFUNC);
+    g_debug ("%s", G_STRFUNC);
     /* Get tree paths of selected files */
     selected_paths = (*FM_DIRECTORY_VIEW_GET_CLASS (view)->get_selected_paths) (view);
 
@@ -2220,7 +2229,7 @@
     /* Create a copy the path (we're not allowed to modify it in this handler) */
     path_copy = gtk_tree_path_copy (path);
 
-    /* Remember the selected path so that it can be restored after the row has 
+    /* Remember the selected path so that it can be restored after the row has
      * been removed. If the first row is removed, select the first row after the
      * removal, if any other row is removed, select the row before that one */
     gtk_tree_path_prev (path_copy);
@@ -2238,8 +2247,8 @@
     g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
     g_return_if_fail (view->model == model);
 
-    g_message ("%s", G_STRFUNC);
-    /* Check if there was only one file selected before the row was deleted. The 
+    g_debug ("%s", G_STRFUNC);
+    /* Check if there was only one file selected before the row was deleted. The
      * path is set by thunar_standard_view_row_deleted() if this is the case */
     if (G_LIKELY (view->details->selection_before_delete != NULL))
     {
@@ -2257,11 +2266,11 @@
     }
 }
 
-void 
+void
 fm_directory_view_select_first_for_empty_selection (FMDirectoryView *view)
 {
     g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
-    
+
     GList *selection = fm_directory_view_get_selection (view);
 
     if (!selection) {
@@ -2273,7 +2282,7 @@
 }
 
 #if 0
-void 
+void
 fm_directory_view_select_gof_file (FMDirectoryView *view, GOFFile *file)
 {
     GtkTreeIter iter;
@@ -2282,7 +2291,7 @@
     g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
 
     if (!fm_list_model_get_first_iter_for_file (view->model, file, &iter))
-		return;
+        return;
 
     path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->model), &iter);
     (*FM_DIRECTORY_VIEW_GET_CLASS (view)->set_cursor) (view, path, FALSE, TRUE);
@@ -2290,7 +2299,7 @@
 }
 #endif
 
-void 
+void
 fm_directory_view_select_glib_files (FMDirectoryView *view, GList *files)
 {
     GList *l;
@@ -2326,10 +2335,10 @@
     error = NULL;
     res = g_file_set_attributes_finish (G_FILE (source_object), result, NULL, &error);
 
-	if (error != NULL) {
+    if (error != NULL) {
         g_critical ("%s error, %s", G_STRFUNC, error->message);
-		g_error_free (error);
-	}
+        g_error_free (error);
+    }
 }
 
 static void
@@ -2354,7 +2363,7 @@
     current_dir->file->sort_column_id = sort_column_id;
     current_dir->file->sort_order = sort_order;
     location = g_object_ref (current_dir->location);
-    g_file_set_attributes_async (location, info, 0, G_PRIORITY_DEFAULT, NULL, 
+    g_file_set_attributes_async (location, info, 0, G_PRIORITY_DEFAULT, NULL,
                                  set_metadata_callback, NULL);
     g_object_unref (location);
     g_object_unref (info);
@@ -2395,7 +2404,7 @@
     return view->details->slot->directory;
 }
 
-static int 
+static int
 fm_directory_view_get_uri_keypath_size (FMDirectoryView *view)
 {
     GOFDirectoryAsync *dir = fm_directory_view_get_current_directory (view);
@@ -2436,8 +2445,8 @@
     fm_directory_view_cancel_thumbnailing (view);
 
     /* schedule the timeout handler */
-    view->details->thumbnail_source_id = 
-        g_timeout_add (175, (GSourceFunc) fm_directory_view_request_thumbnails, 
+    view->details->thumbnail_source_id =
+        g_timeout_add (175, (GSourceFunc) fm_directory_view_request_thumbnails,
                        view);
 }
 
@@ -2481,7 +2490,7 @@
                 /* only ask thumbnails once per file */
                 if (file->flags == 0) {
                     files = g_list_prepend (files, g_object_ref (file));
-                } 
+                }
 
                 g_object_unref (file);
             }
@@ -2682,12 +2691,12 @@
 
     locations = g_list_reverse (locations);
 
-    if (locations != NULL) { 
+    if (locations != NULL) {
         marlin_file_operations_trash_or_delete (locations,
                                                 GTK_WINDOW (view->details->window),
                                                 (MarlinDeleteCallback) trash_or_delete_done_cb,
                                                 view);
-    } 
+    }
     else
         return;
 
@@ -2709,8 +2718,8 @@
             trash_or_delete_files (view, selection, TRUE);
             gof_file_list_free (selection);
             view->details->selection_was_removed = TRUE;
-        } 
-        else 
+        }
+        else
             return;
     }
 }
@@ -2829,13 +2838,13 @@
 
         slot = GOF_WINDOW_SLOT (g_value_get_object (value));
         window = marlin_view_view_container_get_window (MARLIN_VIEW_VIEW_CONTAINER(slot->ctab));
-        
+
         view->details->slot = g_object_ref(slot);
         view->details->window = window;
 
         g_signal_handlers_block_by_func (view->model, sort_column_changed_callback, view);
-        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (view->model), 
-                                              slot->directory->file->sort_column_id, 
+        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (view->model),
+                                              slot->directory->file->sort_column_id,
                                               slot->directory->file->sort_order);
         g_signal_handlers_unblock_by_func (view->model, sort_column_changed_callback, view);
 
@@ -2844,15 +2853,15 @@
                                  G_CALLBACK (show_hidden_files_changed), view, 0);
         g_signal_connect_object (gof_preferences_get_default (), "notify::interpret-desktop-files",
                                  G_CALLBACK (show_desktop_files_changed), view, 0);
-        
-        
+
+
         fm_directory_view_connect_directory_handlers (view, slot->directory);
-        
-        g_signal_connect_object (view->details->slot, "active", 
+
+        g_signal_connect_object (view->details->slot, "active",
                                  G_CALLBACK (slot_active), view, 0);
-        g_signal_connect_object (view->details->slot, "inactive", 
+        g_signal_connect_object (view->details->slot, "inactive",
                                  G_CALLBACK (slot_inactive), view, 0);
-    
+
 
         break;
     case PROP_ZOOM_LEVEL:
@@ -2972,7 +2981,7 @@
 GtkUIManager *
 fm_directory_view_get_ui_manager (FMDirectoryView *view)
 {
-    if (view->details->window == NULL) 
+    if (view->details->window == NULL)
         return NULL;
 
     return MARLIN_VIEW_WINDOW (view->details->window)->ui;
@@ -2998,14 +3007,14 @@
 }
 
 void
-fm_directory_view_notify_item_hovered (FMDirectoryView *view, GtkTreePath *path) 
+fm_directory_view_notify_item_hovered (FMDirectoryView *view, GtkTreePath *path)
 {
     GOFFile *file = NULL;
 
-    if (path != NULL) 
+    if (path != NULL)
         file = fm_list_model_file_for_path (view->model, path);
     g_signal_emit_by_name (MARLIN_VIEW_WINDOW (view->details->window), "item_hovered", file);
-    if (file != NULL) 
+    if (file != NULL)
         g_object_unref (file);
 }
 
@@ -3018,12 +3027,12 @@
     view->details->selection_was_removed = FALSE;
     if (!gtk_widget_get_realized (GTK_WIDGET (view)))
         return;
-  	if (view->updates_frozen)
+    if (view->updates_frozen)
         return;
     /* when we're in column view ignore selection changed from other slot than the active one */
-    if (view->details->slot->mwcols && 
+    if (view->details->slot->mwcols != NULL &&
         view->details->slot->mwcols->active_slot != view->details->slot)
-        return;
+            return;
 
     //g_message ("%s %s", G_STRFUNC, view->details->slot->directory->file->uri);
     selection = fm_directory_view_get_selection (view);
@@ -3036,9 +3045,9 @@
 {
     fm_directory_view_notify_selection_changed (view);
 
-    /* We could optimize this by redrawing only the old and the new  
+    /* We could optimize this by redrawing only the old and the new
      * clipboard selection by emitting row-changed on the model but the icon view
-     * handle this situation very badly by recomputing all the layout. 
+     * handle this situation very badly by recomputing all the layout.
      */
     gtk_widget_queue_draw (GTK_WIDGET (view));
 }
@@ -3046,7 +3055,7 @@
 void
 fm_directory_view_set_active_slot (FMDirectoryView *view)
 {
-    g_warning ("%s %s %s", G_STRFUNC, 
+    g_warning ("%s %s %s", G_STRFUNC,
                view->details->slot->mwcols->active_slot->directory->file->uri,
                view->details->slot->directory->file->uri
                );
@@ -3108,7 +3117,7 @@
     g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
 
     view->updates_frozen = TRUE;
-    
+
     /* disable clipboard actions */
     dir_action_set_sensitive (view, "Cut", FALSE);
     dir_action_set_sensitive (view, "Copy", FALSE);
@@ -3119,7 +3128,7 @@
     /* TODO remove this blocker */
     /* block thumbnails request on size allocate */
     g_signal_handlers_block_by_func (view, fm_directory_view_size_allocate, NULL);
-    
+
     /* block clipboard change trigerring update_menus */
     g_signal_handlers_block_by_func (view, fm_directory_view_clipboard_changed, NULL);
 
@@ -3139,7 +3148,7 @@
 
     /* unblock thumbnails request on size allocate */
     g_signal_handlers_unblock_by_func (view, fm_directory_view_size_allocate, NULL);
-    
+
     /* unblock clipboard change trigerring update_menus */
     g_signal_handlers_unblock_by_func (view, fm_directory_view_clipboard_changed, NULL);
 
@@ -3255,7 +3264,7 @@
 static void
 check_newly_file_added_callback (GOFDirectoryAsync *directory, GOFFile *file, FMDirectoryView *view)
 {
-    if (file->is_directory && g_file_equal (file->location, view->details->newly_folder_added->location)) 
+    if (file->is_directory && g_file_equal (file->location, view->details->newly_folder_added->location))
     {
         g_signal_handlers_disconnect_by_func (directory,
                                               G_CALLBACK (check_newly_file_added_callback),
@@ -3267,7 +3276,7 @@
 #endif
 
 static gboolean
-rename_file_callback (FMDirectoryView *view) 
+rename_file_callback (FMDirectoryView *view)
 {
     rename_file (view, view->details->newly_folder_added);
     g_object_unref (view->details->newly_folder_added);
@@ -3285,9 +3294,9 @@
         g_object_unref (view->details->newly_folder_added);
     view->details->newly_folder_added = gof_file_get (new_folder);
 
-    /*g_signal_connect_data (view->details->slot->directory, 
-                           "file_added", 
-                           G_CALLBACK (check_newly_file_added_callback), 
+    /*g_signal_connect_data (view->details->slot->directory,
+                           "file_added",
+                           G_CALLBACK (check_newly_file_added_callback),
                            g_object_ref (view),
                            (GClosureNotify)g_object_unref,
                            G_CONNECT_AFTER);*/
@@ -3326,7 +3335,7 @@
                             GOFFile *source)
 {
     //GdkPoint *pos;
-	/*NewFolderData *data;
+    /*NewFolderData *data;
     char *source_uri;*/
     char *current_dir_uri;
 
@@ -3351,10 +3360,10 @@
     g_return_if_fail (nautilus_file_is_local (source));
 g_return_if_fail (nautilus_file_is_local (source));
     //pos = context_menu_to_file_operation_position (directory_view);
-	data = setup_new_folder_data (directory_view);
-	source_uri = nautilus_file_get_uri (source);
+    data = setup_new_folder_data (directory_view);
+    source_uri = nautilus_file_get_uri (source);
 
-	marlin_file_operations_new_file_from_template (GTK_WIDGET (directory_view),
+    marlin_file_operations_new_file_from_template (GTK_WIDGET (directory_view),
                                                    pos,
                                                    parent_uri != NULL ? parent_uri : container_uri,
                                                    NULL,
@@ -3421,17 +3430,17 @@
     g_assert (selection != NULL);
 
     file = GOF_FILE (selection->data);
-	gof_file_ref (file);
+    gof_file_ref (file);
 
-	dialog = gtk_app_chooser_dialog_new (GTK_WINDOW (view->details->window), 0, file->location);
+    dialog = gtk_app_chooser_dialog_new (GTK_WINDOW (view->details->window), 0, file->location);
     GtkWidget *check_default = gtk_check_button_new_with_label(_("Set as default"));
     gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), check_default, FALSE, FALSE, 0);
-	gtk_widget_show_all (dialog);
+    gtk_widget_show_all (dialog);
 
     int response = gtk_dialog_run (GTK_DIALOG (dialog));
     if(response == GTK_RESPONSE_OK)
     {
-	    app = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (GTK_DIALOG (dialog)));
+        app = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (GTK_DIALOG (dialog)));
         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_default)))
         {
             GError* error = NULL;
@@ -3441,14 +3450,14 @@
                 g_clear_error (&error);
             }
         }
-        
+
         gof_files_launch_with (selection,
                                eel_gtk_widget_get_screen (GTK_WIDGET (view)),
                                app);
     }
 
     gtk_widget_destroy (GTK_WIDGET (dialog));
-	gof_file_unref (file);
+    gof_file_unref (file);
 }
 
 static void
@@ -3457,7 +3466,7 @@
     g_assert (FM_IS_DIRECTORY_VIEW (view));
 
     GList *selection = fm_directory_view_get_selection (view);
-    
+
     if (selection != NULL) {
         /* The reference counts of the selection list's members are incremented,
          * so that the members aren't freed by the properties window. */
@@ -3534,11 +3543,11 @@
         /* tooltip */                  N_("Delete each selected item, without moving to the Trash"),
         G_CALLBACK (action_delete_callback) },
     /* name, stock id */         { "Restore From Trash", NULL,
-        /* label, accelerator */       N_("_Restore"), NULL, 
+        /* label, accelerator */       N_("_Restore"), NULL,
         NULL,
         G_CALLBACK (action_restore_from_trash_callback) },
     /* name, stock id */         { "Select All", NULL,
-        /* label, accelerator */       N_("Select All"), "<control>A", 
+        /* label, accelerator */       N_("Select All"), "<control>A",
         NULL,
         G_CALLBACK (action_select_all) },
     /* name, stock id */         { "Properties", GTK_STOCK_PROPERTIES,
@@ -3554,7 +3563,7 @@
 {
     GtkUIManager *ui_manager;
 
-    if (view->details->window == NULL) 
+    if (view->details->window == NULL)
         return;
     if (view->details->dir_action_group == NULL)
         return;
@@ -3638,7 +3647,7 @@
     /* we have to make sure that we add our custom widget once in the menu */
     static gboolean selection_menu_builded = FALSE;
 
-    if (!selection_menu_builded) 
+    if (!selection_menu_builded)
     {
         GtkWidget *item;
 

=== modified file 'src/fm-directory-view.h'
--- src/fm-directory-view.h	2013-02-08 00:58:30 +0000
+++ src/fm-directory-view.h	2013-09-01 22:36:03 +0000
@@ -19,8 +19,8 @@
  * Boston, MA 02111-1307, USA.
  *
  * Authors: Ettore Perazzoli
- * 	    Darin Adler <darin@xxxxxxxxxxxxx>
- * 	    John Sullivan <sullivan@xxxxxxxxx>
+ *       Darin Adler <darin@xxxxxxxxxxxxx>
+ *       John Sullivan <sullivan@xxxxxxxxx>
  *          Pavel Cisler <pavel@xxxxxxxxx>
  */
 
@@ -65,7 +65,7 @@
     GtkCellRenderer         *name_renderer;
     MarlinZoomLevel         zoom_level;
     gboolean                updates_frozen;
-
+    const gchar* empty_message;
     FMDirectoryViewDetails  *details;
 };
 
@@ -75,24 +75,24 @@
     /* The 'clear' signal is emitted to empty the view of its contents.
      * It must be replaced by each subclass.
      */
-    //	void 	(* clear) 		 (FMDirectoryView *view);
+    //    void      (* clear)            (FMDirectoryView *view);
 
     /* The 'begin_file_changes' signal is emitted before a set of files
-     * are added to the view. It can be replaced by a subclass to do any 
+     * are added to the view. It can be replaced by a subclass to do any
      * necessary preparation for a set of new files. The default
      * implementation does nothing.
      */
-    //void 	(* begin_file_changes) (FMDirectoryView *view);
+    //void     (* begin_file_changes) (FMDirectoryView *view);
 
     /* The 'add_file' signal is emitted to add one file to the view.
      * It must be replaced by each subclass.
      */
-    void    (* add_file) 		 (FMDirectoryView *view, 
+    void    (* add_file)            (FMDirectoryView *view,
                                           GOFFile *file,
                                           GOFDirectoryAsync *directory);
-    void    (* directory_loaded) (FMDirectoryView *view, 
+    void    (* directory_loaded) (FMDirectoryView *view,
                                           GOFDirectoryAsync *directory);
-    void    (* sync_selection)	         (FMDirectoryView *view);
+    void    (* sync_selection)              (FMDirectoryView *view);
 
 
 #if 0
@@ -100,29 +100,29 @@
      * including the file being removed.
      * It must be replaced by each subclass.
      */
-    void 	(* file_changed)         (FMDirectoryView *view, 
+    void  (* file_changed)         (FMDirectoryView *view,
                                           GOFFile *file,
                                           GOFDirectoryAsync *directory);
 
     /* The 'end_file_changes' signal is emitted after a set of files
-     * are added to the view. It can be replaced by a subclass to do any 
+     * are added to the view. It can be replaced by a subclass to do any
      * necessary cleanup (typically, cleanup for code in begin_file_changes).
      * The default implementation does nothing.
      */
-    //void 	(* end_file_changes)    (FMDirectoryView *view);
+    //void     (* end_file_changes)    (FMDirectoryView *view);
 
-    //void    (* flush_added_files)	 (FMDirectoryView *view);
+    //void    (* flush_added_files)      (FMDirectoryView *view);
 
     /* The 'begin_loading' signal is emitted before any of the contents
-     * of a directory are added to the view. It can be replaced by a 
+     * of a directory are added to the view. It can be replaced by a
      * subclass to do any necessary preparation to start dealing with a
      * new directory. The default implementation does nothing.
      */
-    void 	(* begin_loading) 	 (FMDirectoryView *view);
+    void  (* begin_loading)    (FMDirectoryView *view);
 
     /* The 'end_loading' signal is emitted after all of the contents
-     * of a directory are added to the view. It can be replaced by a 
-     * subclass to do any necessary clean-up. The default implementation 
+     * of a directory are added to the view. It can be replaced by a
+     * subclass to do any necessary clean-up. The default implementation
      * does nothing.
      *
      * If all_files_seen is true, the handler may assume that
@@ -132,12 +132,12 @@
      * Otherwise, end_loading was emitted due to cancellation,
      * which usually means that not all files are available.
      */
-    void 	(* end_loading) 	 (FMDirectoryView *view,
+    void  (* end_loading)      (FMDirectoryView *view,
                                           gboolean all_files_seen);
 
     /* The 'load_error' signal is emitted when the directory model
      * reports an error in the process of monitoring the directory's
-     * contents.  The load error indicates that the process of 
+     * contents.  The load error indicates that the process of
      * loading the contents has ended, but the directory is still
      * being monitored. The default implementation handles common
      * load failures like ACCESS_DENIED.
@@ -147,11 +147,11 @@
 
     /* Function pointers that don't have corresponding signals */
 
-    /* reset_to_defaults is a function pointer that subclasses must 
+    /* reset_to_defaults is a function pointer that subclasses must
      * override to set sort order, zoom level, etc to match default
-     * values. 
+     * values.
      */
-    void     (* reset_to_defaults)	         (FMDirectoryView *view);
+    void     (* reset_to_defaults)          (FMDirectoryView *view);
 #endif
 
     /* get_selection is not a signal; it is just a function pointer for
@@ -159,7 +159,7 @@
      * with a function that returns a newly-allocated GList of
      * GOFFile pointers.
      */
-    GList *	(* get_selection) 	 	(FMDirectoryView *view);
+    GList *    (* get_selection)        (FMDirectoryView *view);
 
     /* get_selection_for_file_transfer  is a function pointer for
      * subclasses to replace (override). Subclasses must replace it
@@ -168,11 +168,11 @@
      * that any files in the selection that also has a parent folder
      * in the selection is not included.
      */
-    GList *	(* get_selection_for_file_transfer)(FMDirectoryView *view);
+    GList *    (* get_selection_for_file_transfer)(FMDirectoryView *view);
 
     /* Returns the list of currently selected GtkTreePath's, where
      * both the list and the items are owned by the caller. */
-    GList *	(* get_selected_paths)  (FMDirectoryView *view);
+    GList *    (* get_selected_paths)  (FMDirectoryView *view);
 
     /* Selects the given item */
     void    (*select_path)          (FMDirectoryView *view, GtkTreePath *path);
@@ -192,19 +192,19 @@
 #if 0
     /* select_all is a function pointer that subclasses must override to
      * select all of the items in the view */
-    void     (* select_all)	         	(FMDirectoryView *view);
+    void     (* select_all)             (FMDirectoryView *view);
 
     /* set_selection is a function pointer that subclasses must
      * override to select the specified items (and unselect all
      * others). The argument is a list of GOFFiles. */
 
-    void     (* set_selection)	 	(FMDirectoryView *view, 
+    void     (* set_selection)          (FMDirectoryView *view,
                                          GList *selection);
-    
+
     /* invert_selection is a function pointer that subclasses must
      * override to invert selection. */
 
-    void     (* invert_selection)	 	(FMDirectoryView *view);        					 
+    void     (* invert_selection)       (FMDirectoryView *view);
 
     /* Return an array of locations of selected icons in their view. */
     //GArray * (* get_selected_icon_locations) (FMDirectoryView *view);
@@ -213,12 +213,12 @@
 
     /* bump_zoom_level is a function pointer that subclasses must override
      * to change the zoom level of an object. */
-    /*void    (* bump_zoom_level)      	(FMDirectoryView *view,
+    /*void    (* bump_zoom_level)       (FMDirectoryView *view,
       int zoom_increment);*/
 
     /* zoom_to_level is a function pointer that subclasses must override
      * to set the zoom level of an object to the specified level. */
-    /*void    (* zoom_to_level) 		(FMDirectoryView *view, 
+    /*void    (* zoom_to_level)         (FMDirectoryView *view,
       NautilusZoomLevel level);*/
 
     //NautilusZoomLevel (* get_zoom_level)    (FMDirectoryView *view);
@@ -229,39 +229,39 @@
 
     /* can_zoom_in is a function pointer that subclasses must override to
      * return whether the view is at maximum size (furthest-in zoom level) */
-    //gboolean (* can_zoom_in)	 	(FMDirectoryView *view);
+    //gboolean (* can_zoom_in)          (FMDirectoryView *view);
 
     /* can_zoom_out is a function pointer that subclasses must override to
      * return whether the view is at minimum size (furthest-out zoom level) */
-    //gboolean (* can_zoom_out)	 	(FMDirectoryView *view);
+    //gboolean (* can_zoom_out)         (FMDirectoryView *view);
 
     /* reveal_selection is a function pointer that subclasses may
      * override to make sure the selected items are sufficiently
      * apparent to the user (e.g., scrolled into view). By default,
      * this does nothing.
      */
-    void     (* reveal_selection)	 	(FMDirectoryView *view);
+    void     (* reveal_selection)       (FMDirectoryView *view);
 
     /* get_background is a function pointer that subclasses must
      * override to return the EelBackground for this view.
      */
-    //GtkWidget * (* get_background_widget)	(FMDirectoryView *view);
+    //GtkWidget * (* get_background_widget)  (FMDirectoryView *view);
 #endif
 
     /* merge_menus is a function pointer that subclasses can override to
      * add their own menu items to the window's menu bar.
      * If overridden, subclasses must call parent class's function.
      */
-    void    (* merge_menus)         	(FMDirectoryView *view);
-    void    (* unmerge_menus)         	(FMDirectoryView *view);
+    void    (* merge_menus)             (FMDirectoryView *view);
+    void    (* unmerge_menus)           (FMDirectoryView *view);
 
 #if 0
     /* update_menus is a function pointer that subclasses can override to
      * update the sensitivity or wording of menu items in the menu bar.
-     * It is called (at least) whenever the selection changes. If overridden, 
+     * It is called (at least) whenever the selection changes. If overridden,
      * subclasses must call parent class's function.
      */
-    //void    (* update_menus)         	(FMDirectoryView *view);
+    //void    (* update_menus)          (FMDirectoryView *view);
 
     /* sort_files is a function pointer that subclasses can override
      * to provide a sorting order to determine which files should be
@@ -276,7 +276,7 @@
      * be displayed with each file. By default, all emblems returned by
      * GOFFile are displayed.
      */
-    //char ** (* get_emblem_names_to_exclude)	(FMDirectoryView *view);
+    //char ** (* get_emblem_names_to_exclude)     (FMDirectoryView *view);
 
     /* file_limit_reached is a function pointer that subclasses may
      * override to control what happens when a directory is loaded
@@ -285,21 +285,21 @@
      * display when the user explicitly tried to visit a location that
      * they would think of as a normal directory.
      */
-    //void (* file_limit_reached)		(FMDirectoryView *view);
+    //void (* file_limit_reached)       (FMDirectoryView *view);
 
     /* supports_properties is a function pointer that subclasses may
      * override to control whether the "Show Properties" menu item
-     * should be enabled for selected items. The default implementation 
+     * should be enabled for selected items. The default implementation
      * returns TRUE.
      */
-    //gboolean (* supports_properties)	(FMDirectoryView *view);
+    //gboolean (* supports_properties)  (FMDirectoryView *view);
 
     /* supports_zooming is a function pointer that subclasses may
      * override to control whether or not the zooming control and
      * menu items should be enabled. The default implementation
      * returns TRUE.
      */
-    //gboolean (* supports_zooming)		(FMDirectoryView *view);
+    //gboolean (* supports_zooming)          (FMDirectoryView *view);
 
     /* using_manual_layout is a function pointer that subclasses may
      * override to control whether or not items can be freely positioned
@@ -314,7 +314,7 @@
      * default implementation checks the permissions of the
      * directory.
      */
-    gboolean (* is_read_only)	        (FMDirectoryView *view);
+    gboolean (* is_read_only)         (FMDirectoryView *view);
 
     /* is_empty is a function pointer that subclasses must
      * override to report whether the view contains any items.
@@ -327,13 +327,13 @@
      * user has write permissions for the viewed directory, and whether
      * the viewed directory is in the trash.
      */
-    gboolean (* supports_creating_files)	(FMDirectoryView *view);
+    gboolean (* supports_creating_files)     (FMDirectoryView *view);
 
     /* accepts_dragged_files is a function pointer that subclasses may
      * override to control whether or not files can be dropped in this
      * location. The default implementation returns TRUE.
      */
-    //gboolean (* accepts_dragged_files)	(FMDirectoryView *view);
+    //gboolean (* accepts_dragged_files)     (FMDirectoryView *view);
 
     /*gboolean (* can_rename_file)            (FMDirectoryView *view,
       GOFFile *file);*/
@@ -341,12 +341,12 @@
     /* select_all specifies whether the whole filename should be selected
      * or only its basename (i.e. everything except the extension)
      * */
-    void	 (* start_renaming_file)        (FMDirectoryView *view,
+    void   (* start_renaming_file)        (FMDirectoryView *view,
                                              GOFFile *file,
                                              gboolean select_all);
 #if 0
-    /*gboolean (* file_still_belongs)		(FMDirectoryView *view,
-      GOFFile	 *file,
+    /*gboolean (* file_still_belongs)        (FMDirectoryView *view,
+      GOFFile   *file,
       GOFDirectoryAsync *directory);
       */
 
@@ -360,17 +360,17 @@
       GdkPoint
      *position);*/
 
-    /* Preference change callbacks, overriden by icon and list views. 
+    /* Preference change callbacks, overriden by icon and list views.
      * Icon and list views respond by synchronizing to the new preference
      * values and forcing an update if appropriate.
      */
-    /*void	(* text_attribute_names_changed)   (FMDirectoryView *view);
-      void	(* embedded_text_policy_changed)   (FMDirectoryView *view);
-      void	(* image_display_policy_changed)   (FMDirectoryView *view);
-      void	(* click_policy_changed)	   (FMDirectoryView *view);
-      void	(* sort_directories_first_changed) (FMDirectoryView *view);
+    /*void     (* text_attribute_names_changed)   (FMDirectoryView *view);
+      void     (* embedded_text_policy_changed)   (FMDirectoryView *view);
+      void     (* image_display_policy_changed)   (FMDirectoryView *view);
+      void     (* click_policy_changed)    (FMDirectoryView *view);
+      void     (* sort_directories_first_changed) (FMDirectoryView *view);
 
-      void	(* emblems_changed)                (FMDirectoryView *view);
+      void     (* emblems_changed)                (FMDirectoryView *view);
 
       void    (* set_is_active)                  (FMDirectoryView *view,
       gboolean

=== modified file 'src/gof-window-slot.c'
--- src/gof-window-slot.c	2013-06-27 19:34:48 +0000
+++ src/gof-window-slot.c	2013-09-01 22:36:03 +0000
@@ -46,12 +46,13 @@
 {
     slot->content_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     slot->width = 0;
+    slot->ready_to_autosize = FALSE;
     GOF_ABSTRACT_SLOT (slot)->extra_location_widgets = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
     gtk_box_pack_start (GTK_BOX (slot->content_box), GOF_ABSTRACT_SLOT(slot)->extra_location_widgets, FALSE, FALSE, 0);
 }
 
 static void
-real_active (GOFWindowSlot *slot) 
+real_active (GOFWindowSlot *slot)
 {
     marlin_view_view_container_refresh_slot_info (MARLIN_VIEW_VIEW_CONTAINER (slot->ctab));
 }
@@ -60,22 +61,22 @@
 gof_window_slot_class_init (GOFWindowSlotClass *class)
 {
     signals[ACTIVE] =
-	g_signal_new ("active",
-		      G_TYPE_FROM_CLASS (class),
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GOFWindowSlotClass, active),
-		      NULL, NULL,
-		      g_cclosure_marshal_VOID__VOID,
-		      G_TYPE_NONE, 0);
+    g_signal_new ("active",
+              G_TYPE_FROM_CLASS (class),
+              G_SIGNAL_RUN_LAST,
+              G_STRUCT_OFFSET (GOFWindowSlotClass, active),
+              NULL, NULL,
+              g_cclosure_marshal_VOID__VOID,
+              G_TYPE_NONE, 0);
 
     signals[INACTIVE] =
-	g_signal_new ("inactive",
-		      G_TYPE_FROM_CLASS (class),
-		      G_SIGNAL_RUN_LAST,
-		      G_STRUCT_OFFSET (GOFWindowSlotClass, inactive),
-		      NULL, NULL,
-		      g_cclosure_marshal_VOID__VOID,
-		      G_TYPE_NONE, 0);
+    g_signal_new ("inactive",
+              G_TYPE_FROM_CLASS (class),
+              G_SIGNAL_RUN_LAST,
+              G_STRUCT_OFFSET (GOFWindowSlotClass, inactive),
+              NULL, NULL,
+              g_cclosure_marshal_VOID__VOID,
+              G_TYPE_NONE, 0);
 
     G_OBJECT_CLASS (class)->finalize = gof_window_slot_finalize;
     class->active = real_active;
@@ -87,10 +88,12 @@
     GOFWindowSlot *slot = GOF_WINDOW_SLOT (object);
 
     //load_dir_async_cancel(slot->directory);
-    g_debug ("%s %s\n", G_STRFUNC, slot->directory->file->uri);
+    g_debug ("%s %s finalizing\n", G_STRFUNC, slot->directory->file->uri);
     //g_warning ("%s %s %u\n", G_STRFUNC, slot->directory->file->uri, G_OBJECT (slot->directory)->ref_count);
+    g_signal_handlers_disconnect_by_data (slot->directory, slot);
     g_object_unref(slot->directory);
     g_object_unref(slot->location);
+
     G_OBJECT_CLASS (parent_class)->finalize (object);
     /* avoid a warning in vala code: slot is freed in ViewContainer */
     //slot = NULL;
@@ -100,7 +103,7 @@
 update_total_width (GtkWidget *widget, GtkAllocation *allocation, void *data)
 {
     GOFWindowSlot* slot = data;
-    
+
     if (slot->mwcols->total_width != 0 && slot->width != allocation->width) {
         slot->mwcols->total_width += allocation->width - slot->width;
         slot->width = allocation->width;
@@ -114,11 +117,11 @@
     GtkWidget *hpane = GTK_WIDGET (granite_widgets_thin_paned_new (GTK_ORIENTATION_HORIZONTAL));
     gtk_widget_set_hexpand(hpane, TRUE);
     gtk_widget_show (hpane);
-    
+
     gtk_container_add(GTK_CONTAINER (slot->colpane), hpane);
     gtk_widget_show_all(slot->colpane);
-    
-    GtkWidget *box1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);    
+
+    GtkWidget *box1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
     gtk_widget_show_all (box1);
 
     slot->colpane = box1;
@@ -131,6 +134,69 @@
 
     gtk_paned_pack1 (GTK_PANED (hpane), column, FALSE, FALSE);
     gtk_paned_pack2 (GTK_PANED (hpane), box1, TRUE, FALSE);
+
+    /* If the directory finished loading before slot was ready then autosize the slot now.
+    * Otherwise the slot will be autosized by the directory_done_loading callback
+    * This is necessary because the directory loads faster from the cache than from disk
+    * On first use the directory loads from disk and we reach here before the directory
+    * has finished loading.
+    * On subsequent uses, the directory loads from cache before the slot is ready.
+    * Whichever finishes first sets slot->ready_to_autosize = TRUE
+    * Whichever finds slot->ready_to_autosize = TRUE does the autosizing.
+    */
+
+    if (slot->ready_to_autosize)
+        autosize_slot (slot);
+    else {
+        slot->ready_to_autosize = TRUE;
+    }
+}
+
+void autosize_slot (GOFWindowSlot *slot)
+{
+    g_return_if_fail (GOF_IS_WINDOW_SLOT (slot));
+    g_return_if_fail (slot->view_box != NULL);
+    g_return_if_fail (GTK_IS_WIDGET (slot->view_box));
+    g_return_if_fail (GOF_DIRECTORY_IS_ASYNC (slot->directory));
+    g_return_if_fail (slot->mwcols != NULL);
+
+    PangoLayout* layout = gtk_widget_create_pango_layout (GTK_WIDGET (slot->view_box), NULL);
+
+    if (gof_directory_async_is_empty (slot->directory))
+        pango_layout_set_markup (layout, FM_DIRECTORY_VIEW (slot->view_box)->empty_message, -1);
+    else
+        pango_layout_set_markup (layout,
+                                g_markup_escape_text (slot->directory->longest_file_name, -1),
+                                 -1);
+
+    PangoRectangle extents;
+    pango_layout_get_extents (layout, NULL, &extents);
+
+    gint column_width = (int) pango_units_to_double(extents.width)
+                        + 2 * slot->directory->icon_size
+                        + 2 * slot->mwcols->handle_size
+                        + 12;
+
+    gint min_width = slot->mwcols->preferred_column_width / 2;
+
+    if (column_width < min_width)
+        column_width = min_width;
+    else {
+        //TODO make max_width a setting
+        gint max_width = 2 * slot->mwcols->preferred_column_width;
+        if (column_width > max_width)
+            column_width = max_width;
+    }
+
+    if (slot->slot_number == 0)
+        gtk_widget_set_size_request (gtk_paned_get_child1 (GTK_PANED (slot->hpane)), column_width, -1);
+    else
+        gtk_paned_set_position (GTK_PANED (slot->hpane), column_width);
+    slot->width = column_width;
+
+    gtk_widget_show_all (slot->mwcols->colpane);
+    gtk_widget_queue_draw (slot->mwcols->colpane);
+
 }
 
 void
@@ -139,10 +205,10 @@
     gint current_slot_position = 0;
     gint i;
     GList* list_slot = slot->mwcols->slot;
-   
+
     g_return_if_fail (slot->colpane != NULL);
     gtk_container_foreach (GTK_CONTAINER (slot->colpane), (GtkCallback)gtk_widget_destroy, NULL);
-    
+
     current_slot_position = g_list_index(slot->mwcols->slot, slot);
     if(current_slot_position == -1) {
         g_warning ("Can't find the slot you are viewing, this should *not* happen.");
@@ -157,9 +223,11 @@
         g_list_free (slot->mwcols->slot);
         slot->mwcols->slot = l;
     }
-    slot->mwcols->total_width += slot->mwcols->preferred_column_width + 100;
-    gtk_widget_set_size_request (slot->mwcols->colpane, slot->mwcols->total_width, -1);    
+
     marlin_window_columns_add (slot->mwcols, location);
+
+    slot->mwcols->total_width += slot->width + 100;
+    gtk_widget_set_size_request (slot->mwcols->colpane, slot->mwcols->total_width, -1);
 }
 
 GOFWindowSlot *
@@ -191,8 +259,10 @@
     slot->view_box = GTK_WIDGET (g_object_new (FM_TYPE_ICON_VIEW,
                                                "window-slot", slot, NULL));
     gtk_box_pack_start(GTK_BOX (slot->content_box), slot->view_box, TRUE, TRUE, 0);
-    
+
     marlin_view_view_container_set_content ((MarlinViewViewContainer *) slot->ctab, slot->content_box);
+
+    slot->directory->track_longest_name = FALSE;
     gof_directory_async_load (slot->directory);
 }
 
@@ -207,6 +277,8 @@
                                                "window-slot", slot, NULL));
     gtk_box_pack_start (GTK_BOX (slot->content_box), slot->view_box, TRUE, TRUE, 0);
     marlin_view_view_container_set_content ((MarlinViewViewContainer *) slot->ctab, slot->content_box);
+
+    slot->directory->track_longest_name = FALSE;
     gof_directory_async_load (slot->directory);
 }
 
@@ -224,6 +296,7 @@
 {
     slot->view_box = GTK_WIDGET (g_object_new (FM_TYPE_COLUMNS_VIEW,
                                                "window-slot", slot, NULL));
+    slot->directory->track_longest_name = TRUE;
     gof_directory_async_load (slot->directory);
 }
 
@@ -233,8 +306,10 @@
 {
     g_return_if_fail (GOF_IS_WINDOW_SLOT (slot));
 
-    if (slot->mwcols)
+    if (slot->mwcols != NULL) {
         marlin_window_columns_active_slot (slot->mwcols, slot);
+        autosize_slot (slot);
+    }
 }
 
 void

=== modified file 'src/gof-window-slot.h'
--- src/gof-window-slot.h	2013-06-27 19:34:48 +0000
+++ src/gof-window-slot.h	2013-09-01 22:36:03 +0000
@@ -25,9 +25,9 @@
 #include "marlincore.h"
 #include "marlin-window-columns.h"
 
-#define GOF_TYPE_WINDOW_SLOT	 (gof_window_slot_get_type())
+#define GOF_TYPE_WINDOW_SLOT     (gof_window_slot_get_type())
 #define GOF_WINDOW_SLOT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GOF_TYPE_WINDOW_SLOT, GOFWindowSlotClass))
-#define GOF_WINDOW_SLOT(obj)	 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOF_TYPE_WINDOW_SLOT, GOFWindowSlot))
+#define GOF_WINDOW_SLOT(obj)     (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOF_TYPE_WINDOW_SLOT, GOFWindowSlot))
 #define GOF_IS_WINDOW_SLOT(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOF_TYPE_WINDOW_SLOT))
 #define GOF_IS_WINDOW_SLOT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GOF_TYPE_WINDOW_SLOT))
 #define GOF_WINDOW_SLOT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GOF_TYPE_WINDOW_SLOT, GOFWindowSlotClass))
@@ -55,6 +55,8 @@
 
     MarlinWindowColumns *mwcols;
     guint width;
+    guint slot_number;
+    gboolean ready_to_autosize;
 };
 
 struct GOFWindowSlotClass {
@@ -81,5 +83,6 @@
 
 void            gof_window_slot_freeze_updates (GOFWindowSlot *slot);
 void            gof_window_slot_unfreeze_updates (GOFWindowSlot *slot);
+void            autosize_slot (GOFWindowSlot *slot);
 
 #endif /* GOF_WINDOW_SLOT_H */

=== modified file 'src/marlin-window-columns.c'
--- src/marlin-window-columns.c	2013-07-05 18:20:51 +0000
+++ src/marlin-window-columns.c	2013-09-01 22:36:03 +0000
@@ -110,6 +110,7 @@
     GOFWindowSlot *slot = mwcols->active_slot;
 
     gof_window_slot_make_column_view (slot);
+    slot->slot_number = 0;
 
     mwcols->colpane = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
     slot->colpane = mwcols->colpane;
@@ -133,6 +134,7 @@
 
     marlin_view_view_container_set_content ((MarlinViewViewContainer *) mwcols->ctab, mwcols->content_box);
 
+
     /* store pane handle size*/
     gtk_widget_style_get (GTK_WIDGET (slot->hpane), "handle-size", &mwcols->handle_size, NULL);
 
@@ -156,7 +158,9 @@
 marlin_window_columns_add (MarlinWindowColumns *mwcols, GFile *location)
 {
     GOFWindowSlot *slot = gof_window_slot_new (location, mwcols->ctab);
+    slot->width = mwcols->preferred_column_width;
     gof_window_slot_make_column_view (slot);
+    slot->slot_number = mwcols->active_slot->slot_number +1;
     slot->mwcols = mwcols;
     slot->colpane = mwcols->active_slot->colpane;
     gof_window_column_add (slot, slot->view_box);


Follow ups