]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkfilechooserdefault.c
docs: fix typo in gtkbuildable
[~andy/gtk] / gtk / gtkfilechooserdefault.c
index 280e49102cd44b690d9a0e2f761023ad5c7df3a7..19fff36accb9c38aa226b7f7f1d0d1137f4b7e35 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
@@ -41,7 +39,7 @@
 #include "gtkfilesystem.h"
 #include "gtkfilesystemmodel.h"
 #include "gtkframe.h"
-#include "gtkpaned.h"
+#include "gtkgrid.h"
 #include "gtkiconfactory.h"
 #include "gtkicontheme.h"
 #include "gtkimage.h"
@@ -51,6 +49,7 @@
 #include "gtkmarshalers.h"
 #include "gtkmessagedialog.h"
 #include "gtkmountoperation.h"
+#include "gtkpaned.h"
 #include "gtkpathbar.h"
 #include "gtkprivate.h"
 #include "gtkradiobutton.h"
 #include "gtkrecentmanager.h"
 #include "gtkscrolledwindow.h"
 #include "gtkseparatormenuitem.h"
+#include "gtksettings.h"
 #include "gtksizegroup.h"
 #include "gtksizerequest.h"
 #include "gtkstock.h"
-#include "gtkgrid.h"
 #include "gtktoolbar.h"
 #include "gtktoolbutton.h"
 #include "gtktooltip.h"
@@ -207,6 +206,7 @@ enum {
   MODEL_COL_FILE,
   MODEL_COL_NAME_COLLATED,
   MODEL_COL_IS_FOLDER,
+  MODEL_COL_IS_SENSITIVE,
   MODEL_COL_PIXBUF,
   MODEL_COL_SIZE_TEXT,
   MODEL_COL_MTIME_TEXT,
@@ -223,6 +223,7 @@ enum {
        G_TYPE_FILE,              /* MODEL_COL_FILE */          \
        G_TYPE_STRING,            /* MODEL_COL_NAME_COLLATED */ \
        G_TYPE_BOOLEAN,           /* MODEL_COL_IS_FOLDER */     \
+       G_TYPE_BOOLEAN,           /* MODEL_COL_IS_SENSITIVE */  \
        GDK_TYPE_PIXBUF,          /* MODEL_COL_PIXBUF */        \
        G_TYPE_STRING,            /* MODEL_COL_SIZE_TEXT */     \
        G_TYPE_STRING,            /* MODEL_COL_MTIME_TEXT */    \
@@ -263,6 +264,7 @@ typedef enum {
 #define SETTINGS_KEY_SORT_ORDER          "sort-order"
 #define SETTINGS_KEY_WINDOW_POSITION     "window-position"
 #define SETTINGS_KEY_WINDOW_SIZE         "window-size"
+#define SETTINGS_KEY_SIDEBAR_WIDTH       "sidebar-width"
 
 static void gtk_file_chooser_default_iface_init       (GtkFileChooserIface        *iface);
 static void gtk_file_chooser_embed_default_iface_init (GtkFileChooserEmbedIface   *iface);
@@ -453,6 +455,8 @@ typedef struct {
 
 static void shortcuts_pane_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface);
 
+GType _shortcuts_pane_model_filter_get_type (void);
+
 G_DEFINE_TYPE_WITH_CODE (ShortcutsPaneModelFilter,
                         _shortcuts_pane_model_filter,
                         GTK_TYPE_TREE_MODEL_FILTER,
@@ -820,8 +824,7 @@ shortcuts_free (GtkFileChooserDefault *impl)
 static void
 pending_select_files_free (GtkFileChooserDefault *impl)
 {
-  g_slist_foreach (impl->pending_select_files, (GFunc) g_object_unref, NULL);
-  g_slist_free (impl->pending_select_files);
+  g_slist_free_full (impl->pending_select_files, g_object_unref);
   impl->pending_select_files = NULL;
 }
 
@@ -2249,7 +2252,7 @@ add_idle_while_impl_is_alive (GtkFileChooserDefault *impl, GCallback callback)
 static gboolean
 edited_idle_cb (GtkFileChooserDefault *impl)
 {
-  GDK_THREADS_ENTER ();
+  gdk_threads_enter ();
   
   g_source_destroy (impl->edited_idle);
   impl->edited_idle = NULL;
@@ -2287,7 +2290,7 @@ edited_idle_cb (GtkFileChooserDefault *impl)
       impl->edited_new_text = NULL;
     }
 
-  GDK_THREADS_LEAVE ();
+  gdk_threads_leave ();
 
   return FALSE;
 }
@@ -3383,7 +3386,7 @@ shortcuts_build_popup_menu (GtkFileChooserDefault *impl)
   gtk_widget_show (item);
   gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_shortcuts_popup_menu), item);
 
-  item = gtk_menu_item_new_with_label (_("Rename..."));
+  item = gtk_menu_item_new_with_label (_("Rename"));
   impl->browse_shortcuts_popup_menu_rename_item = item;
   g_signal_connect (item, "activate",
                    G_CALLBACK (rename_shortcut_cb), impl);
@@ -3862,7 +3865,7 @@ copy_file_clear_cb (GtkClipboard *clipboard,
   g_slist_free (selected_files);
 }
 
-/* Callback used when the "Copy file's location" menu item is activated */
+/* Callback used when the "Copy files location" menu item is activated */
 static void
 copy_file_location_cb (GtkMenuItem           *item,
                        GtkFileChooserDefault *impl)
@@ -4104,7 +4107,7 @@ file_list_drag_motion_cb (GtkWidget             *widget,
   return TRUE;
 }
 
-/* Sensitizes the "Copy file's location" context menu item if there is actually
+/* Sensitizes the "Copy files location" context menu item if there is actually
  * a selection active.
  */
 static void
@@ -4173,7 +4176,7 @@ file_list_build_popup_menu (GtkFileChooserDefault *impl)
   impl->browse_files_popup_menu_visit_file_item                = file_list_add_image_menu_item (impl, GTK_STOCK_DIRECTORY, _("_Visit this file"),
                                                                                         G_CALLBACK (visit_file_cb));
 
-  impl->browse_files_popup_menu_copy_file_location_item        = file_list_add_image_menu_item (impl, GTK_STOCK_COPY, _("_Copy file's location"),
+  impl->browse_files_popup_menu_copy_file_location_item        = file_list_add_image_menu_item (impl, GTK_STOCK_COPY, _("_Copy files location"),
                                                                                         G_CALLBACK (copy_file_location_cb));
 
   impl->browse_files_popup_menu_add_shortcut_item      = file_list_add_image_menu_item (impl, GTK_STOCK_ADD, _("_Add to Bookmarks"),
@@ -5055,7 +5058,7 @@ browse_widgets_create (GtkFileChooserDefault *impl)
 
   /* Paned widget */
 
-  hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
+  hpaned = impl->browse_widgets_hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
   gtk_widget_show (hpaned);
   gtk_box_pack_start (GTK_BOX (impl->browse_widgets_box), hpaned, TRUE, TRUE, 0);
 
@@ -5063,7 +5066,6 @@ browse_widgets_create (GtkFileChooserDefault *impl)
   gtk_paned_pack1 (GTK_PANED (hpaned), widget, FALSE, FALSE);
   widget = file_pane_create (impl, size_group);
   gtk_paned_pack2 (GTK_PANED (hpaned), widget, TRUE, FALSE);
-  gtk_paned_set_position (GTK_PANED (hpaned), 148);
   g_object_unref (size_group);
 }
 
@@ -5197,7 +5199,7 @@ set_select_multiple (GtkFileChooserDefault *impl,
   if (select_multiple == impl->select_multiple)
     return;
 
-  mode = select_multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_BROWSE;
+  mode = select_multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE;
 
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
   gtk_tree_selection_set_mode (selection, mode);
@@ -6035,6 +6037,7 @@ settings_load (GtkFileChooserDefault *impl)
   gboolean show_size_column;
   gint sort_column;
   GtkSortType sort_order;
+  gint sidebar_width;
 
   settings_ensure (impl);
 
@@ -6043,6 +6046,7 @@ settings_load (GtkFileChooserDefault *impl)
   show_size_column = g_settings_get_boolean (impl->settings, SETTINGS_KEY_SHOW_SIZE_COLUMN);
   sort_column = g_settings_get_enum (impl->settings, SETTINGS_KEY_SORT_COLUMN);
   sort_order = g_settings_get_enum (impl->settings, SETTINGS_KEY_SORT_ORDER);
+  sidebar_width = g_settings_get_int (impl->settings, SETTINGS_KEY_SIDEBAR_WIDTH);
 
   location_mode_set (impl, location_mode, TRUE);
 
@@ -6057,6 +6061,8 @@ settings_load (GtkFileChooserDefault *impl)
    * created yet.  The individual functions that create and set the models will
    * call set_sort_column() themselves.
    */
+
+  gtk_paned_set_position (GTK_PANED (impl->browse_widgets_hpaned), sidebar_width);
 }
 
 static void
@@ -6104,6 +6110,8 @@ settings_save (GtkFileChooserDefault *impl)
   g_settings_set_boolean (impl->settings, SETTINGS_KEY_SHOW_SIZE_COLUMN, impl->show_size_column);
   g_settings_set_enum (impl->settings, SETTINGS_KEY_SORT_COLUMN, impl->sort_column);
   g_settings_set_enum (impl->settings, SETTINGS_KEY_SORT_ORDER, impl->sort_order);
+  g_settings_set_int (impl->settings, SETTINGS_KEY_SIDEBAR_WIDTH,
+                     gtk_paned_get_position (GTK_PANED (impl->browse_widgets_hpaned)));
 
   save_dialog_geometry (impl);
 
@@ -6204,13 +6212,6 @@ gtk_file_chooser_default_unmap (GtkWidget *widget)
   GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->unmap (widget);
 }
 
-static void
-install_list_model_filter (GtkFileChooserDefault *impl)
-{
-  _gtk_file_system_model_set_filter (impl->browse_files_model,
-                                     impl->current_filter);
-}
-
 #define COMPARE_DIRECTORIES                                                                                   \
   GtkFileChooserDefault *impl = user_data;                                                                    \
   GtkFileSystemModel *fs_model = GTK_FILE_SYSTEM_MODEL (model);                                                \
@@ -6786,14 +6787,14 @@ file_system_model_got_thumbnail (GObject *object, GAsyncResult *res, gpointer da
   if (queried == NULL)
     return;
 
-  GDK_THREADS_ENTER ();
+  gdk_threads_enter ();
 
   /* now we know model is valid */
 
   /* file was deleted */
   if (!_gtk_file_system_model_get_iter_for_file (model, &iter, file))
     {
-      GDK_THREADS_LEAVE ();
+      gdk_threads_leave ();
       return;
     }
 
@@ -6803,11 +6804,11 @@ file_system_model_got_thumbnail (GObject *object, GAsyncResult *res, gpointer da
   copy_attribute (info, queried, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED);
   copy_attribute (info, queried, G_FILE_ATTRIBUTE_STANDARD_ICON);
 
-  _gtk_file_system_model_update_file (model, file, info, FALSE);
+  _gtk_file_system_model_update_file (model, file, info);
 
   g_object_unref (info);
 
-  GDK_THREADS_LEAVE ();
+  gdk_threads_leave ();
 }
 
 static gboolean
@@ -6840,6 +6841,34 @@ file_system_model_set (GtkFileSystemModel *model,
     case MODEL_COL_IS_FOLDER:
       g_value_set_boolean (value, info == NULL || _gtk_file_info_consider_as_directory (info));
       break;
+    case MODEL_COL_IS_SENSITIVE:
+      if (info)
+        {
+          gboolean sensitive = TRUE;
+
+          if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
+               || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
+            {
+              sensitive = TRUE; /* for file modes... */
+            }
+          else if (!_gtk_file_info_consider_as_directory (info))
+            {
+              sensitive = FALSE; /* for folder modes, files are not sensitive... */
+            }
+          else
+            {
+             /* ... and for folder modes, folders are sensitive only if the filter says so */
+              GtkTreeIter iter;
+              if (!_gtk_file_system_model_get_iter_for_file (model, &iter, file))
+                g_assert_not_reached ();
+              sensitive = !_gtk_file_system_model_iter_is_filtered_out (model, &iter);
+            }
+
+          g_value_set_boolean (value, sensitive);
+        }
+      else
+        g_value_set_boolean (value, TRUE);
+      break;
     case MODEL_COL_PIXBUF:
       if (info)
         {
@@ -6963,7 +6992,7 @@ set_list_model (GtkFileChooserDefault *impl,
   g_signal_connect (impl->browse_files_model, "finished-loading",
                    G_CALLBACK (browse_files_model_finished_loading_cb), impl);
 
-  install_list_model_filter (impl);
+  _gtk_file_system_model_set_filter (impl->browse_files_model, impl->current_filter);
 
   profile_end ("end", NULL);
 
@@ -7534,16 +7563,19 @@ maybe_select (GtkTreeModel *model,
 {
   GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
   GtkTreeSelection *selection;
+  gboolean is_sensitive;
   gboolean is_folder;
   
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
   
   gtk_tree_model_get (model, iter,
                       MODEL_COL_IS_FOLDER, &is_folder,
+                      MODEL_COL_IS_SENSITIVE, &is_sensitive,
                       -1);
 
-  if ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ||
-      (!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN))
+  if (is_sensitive &&
+      ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ||
+       (!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)))
     gtk_tree_selection_select_iter (selection, iter);
   else
     gtk_tree_selection_unselect_iter (selection, iter);
@@ -7952,6 +7984,9 @@ add_shortcut_get_info_cb (GCancellable *cancellable,
 
   shortcuts_insert_file (data->impl, pos, SHORTCUT_TYPE_FILE, NULL, data->file, NULL, FALSE, SHORTCUTS_SHORTCUTS);
 
+  /* need to call shortcuts_add_bookmarks to flush out any duplicates bug #577806 */
+  shortcuts_add_bookmarks (data->impl);
+
 out:
   g_object_unref (data->impl);
   g_object_unref (data->file);
@@ -8152,7 +8187,7 @@ find_good_size_from_style (GtkWidget *widget,
 {
   GtkStyleContext *context;
   GtkStateFlags state;
-  int font_size;
+  double font_size;
   GdkScreen *screen;
   double resolution;
 
@@ -8169,8 +8204,8 @@ find_good_size_from_style (GtkWidget *widget,
   else
     resolution = 96.0; /* wheeee */
 
-  font_size = pango_font_description_get_size (gtk_style_context_get_font (context, state));
-  font_size = PANGO_PIXELS (font_size) * resolution / 72.0;
+  gtk_style_context_get (context, state, "font-size", &font_size, NULL);
+  font_size = font_size * resolution / 72.0 + 0.5;
 
   *width = font_size * NUM_CHARS;
   *height = font_size * NUM_LINES;
@@ -9309,7 +9344,7 @@ search_entry_activate_cb (GtkEntry *entry,
 static gboolean
 focus_entry_idle_cb (GtkFileChooserDefault *impl)
 {
-  GDK_THREADS_ENTER ();
+  gdk_threads_enter ();
   
   g_source_destroy (impl->focus_entry_idle);
   impl->focus_entry_idle = NULL;
@@ -9317,7 +9352,7 @@ focus_entry_idle_cb (GtkFileChooserDefault *impl)
   if (impl->search_entry)
     gtk_widget_grab_focus (impl->search_entry);
 
-  GDK_THREADS_LEAVE ();
+  gdk_threads_leave ();
 
   return FALSE;
 }
@@ -9657,13 +9692,22 @@ set_current_filter (GtkFileChooserDefault *impl,
                                  filter_index);
 
       if (impl->browse_files_model)
-       install_list_model_filter (impl);
+        {
+          _gtk_file_system_model_set_filter (impl->browse_files_model, impl->current_filter);
+          _gtk_file_system_model_clear_cache (impl->browse_files_model, MODEL_COL_IS_SENSITIVE);
+        }
 
       if (impl->search_model)
-        _gtk_file_system_model_set_filter (impl->search_model, filter);
+        {
+          _gtk_file_system_model_set_filter (impl->search_model, filter);
+          _gtk_file_system_model_clear_cache (impl->search_model, MODEL_COL_IS_SENSITIVE);
+        }
 
       if (impl->recent_model)
-        _gtk_file_system_model_set_filter (impl->recent_model, filter);
+        {
+          _gtk_file_system_model_set_filter (impl->recent_model, filter);
+          _gtk_file_system_model_clear_cache (impl->recent_model, MODEL_COL_IS_SENSITIVE);
+        }
 
       g_object_notify (G_OBJECT (impl), "filter");
     }
@@ -10054,14 +10098,16 @@ list_select_func  (GtkTreeSelection  *selection,
       impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
     {
       GtkTreeIter iter;
+      gboolean is_sensitive;
       gboolean is_folder;
 
       if (!gtk_tree_model_get_iter (model, &iter, path))
         return FALSE;
       gtk_tree_model_get (model, &iter,
+                          MODEL_COL_IS_SENSITIVE, &is_sensitive,
                           MODEL_COL_IS_FOLDER, &is_folder,
                           -1);
-      if (!is_folder)
+      if (!is_sensitive || !is_folder)
         return FALSE;
     }
     
@@ -10112,6 +10158,7 @@ list_row_activated (GtkTreeView           *tree_view,
   GtkTreeIter iter;
   GtkTreeModel *model;
   gboolean is_folder;
+  gboolean is_sensitive;
 
   model = gtk_tree_view_get_model (tree_view);
 
@@ -10121,9 +10168,10 @@ list_row_activated (GtkTreeView           *tree_view,
   gtk_tree_model_get (model, &iter,
                       MODEL_COL_FILE, &file,
                       MODEL_COL_IS_FOLDER, &is_folder,
+                      MODEL_COL_IS_SENSITIVE, &is_sensitive,
                       -1);
         
-  if (is_folder && file)
+  if (is_sensitive && is_folder && file)
     {
       change_folder_and_display_error (impl, file, FALSE);
       goto out;
@@ -10166,10 +10214,6 @@ update_cell_renderer_attributes (GtkFileChooserDefault *impl)
   GtkTreeViewColumn *column;
   GtkCellRenderer *renderer;
   GList *walk, *list;
-  gboolean always_sensitive;
-
-  always_sensitive = impl->action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
-                     impl->action != GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
 
   /* Keep the following column numbers in sync with create_file_list() */
 
@@ -10192,10 +10236,8 @@ update_cell_renderer_attributes (GtkFileChooserDefault *impl)
                                                "ellipsize", MODEL_COL_ELLIPSIZE,
                                                NULL);
         }
-      if (always_sensitive)
-        g_object_set (renderer, "sensitive", TRUE, NULL);
-      else
-        gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_FOLDER);
+
+      gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_SENSITIVE);
     }
   g_list_free (list);
 
@@ -10206,10 +10248,8 @@ update_cell_renderer_attributes (GtkFileChooserDefault *impl)
   gtk_tree_view_column_set_attributes (column, renderer, 
                                        "text", MODEL_COL_SIZE_TEXT,
                                        NULL);
-  if (always_sensitive)
-    g_object_set (renderer, "sensitive", TRUE, NULL);
-  else
-    gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_FOLDER);
+
+  gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_SENSITIVE);
   g_list_free (list);
 
   /* mtime */
@@ -10219,10 +10259,7 @@ update_cell_renderer_attributes (GtkFileChooserDefault *impl)
   gtk_tree_view_column_set_attributes (column, renderer, 
                                        "text", MODEL_COL_MTIME_TEXT,
                                        NULL);
-  if (always_sensitive)
-    g_object_set (renderer, "sensitive", TRUE, NULL);
-  else
-    gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_FOLDER);
+  gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_SENSITIVE);
   g_list_free (list);
 }