]> Pileus Git - ~andy/gtk/commitdiff
Replace the cell data computations
authorBenjamin Otte <otte@gnome.org>
Tue, 30 Jun 2009 20:58:55 +0000 (22:58 +0200)
committerBenjamin Otte <otte@gnome.org>
Thu, 15 Oct 2009 20:00:08 +0000 (22:00 +0200)
Previously custom functions were used to compute the data passed to the
cell renderers. Now that all this data is saved by the tree models with
compatible nodes, the usual default attribute-to-column mapping can be
used.
With this, caching of the values can happen in the tree model, which
avoids costly lookups of icons or computation of strings. Last but not
least it avoids spurious bugs that could happen when strings changed
without anyone noticing, like the mtime when a new day begins.

gtk/gtkfilechooserdefault.c

index 2d643c5a8c383f5b8a1a3006c474c4e110541e08..c5595158c275bc656f4169541cabc51c9d060c84 100644 (file)
@@ -399,26 +399,7 @@ static void remove_bookmark_button_clicked_cb (GtkButton             *button,
 static void save_folder_combo_changed_cb      (GtkComboBox           *combo,
                                               GtkFileChooserDefault *impl);
 
-static void list_icon_data_func (GtkTreeViewColumn *tree_column,
-                                GtkCellRenderer   *cell,
-                                GtkTreeModel      *tree_model,
-                                GtkTreeIter       *iter,
-                                gpointer           data);
-static void list_name_data_func (GtkTreeViewColumn *tree_column,
-                                GtkCellRenderer   *cell,
-                                GtkTreeModel      *tree_model,
-                                GtkTreeIter       *iter,
-                                gpointer           data);
-static void list_size_data_func (GtkTreeViewColumn *tree_column,
-                                GtkCellRenderer   *cell,
-                                GtkTreeModel      *tree_model,
-                                GtkTreeIter       *iter,
-                                gpointer           data);
-static void list_mtime_data_func (GtkTreeViewColumn *tree_column,
-                                 GtkCellRenderer   *cell,
-                                 GtkTreeModel      *tree_model,
-                                 GtkTreeIter       *iter,
-                                 gpointer           data);
+static void update_cell_renderer_attributes (GtkFileChooserDefault *impl);
 
 static GFileInfo       *get_list_file_info (GtkFileChooserDefault *impl,
                                            GtkTreeIter           *iter);
@@ -4658,8 +4639,6 @@ create_file_list (GtkFileChooserDefault *impl)
 
   renderer = gtk_cell_renderer_pixbuf_new ();
   gtk_tree_view_column_pack_start (impl->list_name_column, renderer, FALSE);
-  gtk_tree_view_column_set_cell_data_func (impl->list_name_column, renderer,
-                                          list_icon_data_func, impl, NULL);
 
   impl->list_name_renderer = gtk_cell_renderer_text_new ();
   g_object_set (impl->list_name_renderer,
@@ -4670,8 +4649,6 @@ create_file_list (GtkFileChooserDefault *impl)
   g_signal_connect (impl->list_name_renderer, "editing-canceled",
                    G_CALLBACK (renderer_editing_canceled_cb), impl);
   gtk_tree_view_column_pack_start (impl->list_name_column, impl->list_name_renderer, TRUE);
-  gtk_tree_view_column_set_cell_data_func (impl->list_name_column, impl->list_name_renderer,
-                                          list_name_data_func, impl, NULL);
 
   gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), impl->list_name_column);
 
@@ -4686,8 +4663,6 @@ create_file_list (GtkFileChooserDefault *impl)
                 "alignment", PANGO_ALIGN_RIGHT,
                 NULL);
   gtk_tree_view_column_pack_start (column, renderer, TRUE); /* bug: it doesn't expand */
-  gtk_tree_view_column_set_cell_data_func (column, renderer,
-                                          list_size_data_func, impl, NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
   impl->list_size_column = column;
 
@@ -4699,12 +4674,11 @@ create_file_list (GtkFileChooserDefault *impl)
 
   renderer = gtk_cell_renderer_text_new ();
   gtk_tree_view_column_pack_start (column, renderer, TRUE);
-  gtk_tree_view_column_set_cell_data_func (column, renderer,
-                                          list_mtime_data_func, impl, NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
   impl->list_mtime_column = column;
   
   file_list_set_sort_column_ids (impl);
+  update_cell_renderer_attributes (impl);
 
   gtk_widget_show_all (swin);
 
@@ -5603,6 +5577,7 @@ gtk_file_chooser_default_set_property (GObject      *object,
                set_select_multiple (impl, FALSE, TRUE);
              }
            impl->action = action;
+            update_cell_renderer_attributes (impl);
            update_appearance (impl);
            settings_load (impl);
          }
@@ -10926,364 +10901,67 @@ get_list_file_info (GtkFileChooserDefault *impl,
 }
 
 static void
-list_icon_data_func (GtkTreeViewColumn *tree_column,
-                    GtkCellRenderer   *cell,
-                    GtkTreeModel      *tree_model,
-                    GtkTreeIter       *iter,
-                    gpointer           data)
+update_cell_renderer_attributes (GtkFileChooserDefault *impl)
 {
-  GtkFileChooserDefault *impl = data;
-  GtkTreeIter child_iter;
-  GdkPixbuf *pixbuf = NULL;
-  gboolean sensitive = TRUE;
-
-  profile_start ("start", NULL);
-  
-  switch (impl->operation_mode)
-    {
-    case OPERATION_MODE_SEARCH:
-      {
-        GtkTreeIter child_iter;
-        gboolean is_folder;
-
-        search_get_valid_child_iter (impl, &child_iter, iter);
-        gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
-                            MODEL_COL_PIXBUF, &pixbuf,
-                            MODEL_COL_IS_FOLDER, &is_folder,
-                            -1);
-        
-        if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-            impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
-          sensitive = is_folder;
-      }
-      break;
-
-    case OPERATION_MODE_RECENT:
-      {
-        GtkTreeIter child_iter;
-        GtkRecentInfo *info;
-        gboolean is_folder;
-
-        recent_get_valid_child_iter (impl, &child_iter, iter);
-        gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
-                            RECENT_MODEL_COL_INFO, &info,
-                            MODEL_COL_IS_FOLDER, &is_folder,
-                            -1);
-        
-        pixbuf = gtk_recent_info_get_icon (info, impl->icon_size);
-      
-        if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || 
-            impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
-          sensitive = is_folder;
-      }
-      break;
-    
-    case OPERATION_MODE_BROWSE:
-      {
-       GFileInfo *info;
-       GFile *file;
-
-        info = get_list_file_info (impl, iter);
-
-        gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
-                                                        &child_iter,
-                                                        iter);
-        file = _gtk_file_system_model_get_file (impl->browse_files_model, &child_iter);
-        if (file)
-          {
-            if (info)
-              {
-                /* FIXME: NULL GError */
-               pixbuf = _gtk_file_info_render_icon (info, GTK_WIDGET (impl), impl->icon_size);
-             }
-          }
-        else
-          {
-            /* We are on the editable row */
-            pixbuf = NULL;
-          }
-
-        if (info &&
-            (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-             impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
-          sensitive = _gtk_file_info_consider_as_directory (info);
-      }
-      break;
-    }
-    
-  g_object_set (cell,
-               "pixbuf", pixbuf,
-               "sensitive", sensitive,
-               NULL);
-    
-  if (pixbuf)
-    g_object_unref (pixbuf);
-
-  profile_end ("end", NULL);
-}
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *renderer;
+  GList *walk, *list;
+  gboolean always_sensitive;
 
-static void
-list_name_data_func (GtkTreeViewColumn *tree_column,
-                    GtkCellRenderer   *cell,
-                    GtkTreeModel      *tree_model,
-                    GtkTreeIter       *iter,
-                    gpointer           data)
-{
-  GtkFileChooserDefault *impl = data;
-  GFileInfo *info;
-  gboolean sensitive = TRUE;
+  always_sensitive = impl->action != GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
+                     impl->action != GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
 
-  if (impl->operation_mode == OPERATION_MODE_SEARCH)
+  /* name */
+  column = gtk_tree_view_get_column (GTK_TREE_VIEW (impl->browse_files_tree_view), 0);
+  list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
+  for (walk = list; walk; walk = walk->next)
     {
-      GtkTreeIter child_iter;
-      gchar *display_name;
-      gboolean is_folder;
-
-      search_get_valid_child_iter (impl, &child_iter, iter);
-      gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
-                          MODEL_COL_NAME, &display_name,
-                          MODEL_COL_IS_FOLDER, &is_folder,
-                         -1);
-
-      if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-          impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
+      renderer = walk->data;
+      if (GTK_IS_CELL_RENDERER_PIXBUF (renderer))
         {
-          sensitive = is_folder;
+          gtk_tree_view_column_set_attributes (column, renderer, 
+                                               "pixbuf", MODEL_COL_PIXBUF,
+                                               NULL);
         }
-
-      g_object_set (cell,
-                   "text", display_name,
-                   "sensitive", sensitive,
-                   "ellipsize", PANGO_ELLIPSIZE_END,
-                   NULL);
-      
-      return;
-    }
-
-  if (impl->operation_mode == OPERATION_MODE_RECENT)
-    {
-      GtkTreeIter child_iter;
-      GtkRecentInfo *recent_info;
-      gchar *display_name;
-      gboolean is_folder;
-
-      recent_get_valid_child_iter (impl, &child_iter, iter);
-      gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
-                          RECENT_MODEL_COL_INFO, &recent_info,
-                          MODEL_COL_IS_FOLDER, &is_folder,
-                          -1);
-      
-      display_name = gtk_recent_info_get_short_name (recent_info);
-
-      if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-          impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
+      else
         {
-          sensitive = is_folder;
+          gtk_tree_view_column_set_attributes (column, renderer, 
+                                               "text", MODEL_COL_NAME,
+                                               "ellipsize", MODEL_COL_ELLIPSIZE,
+                                               NULL);
         }
-
-      g_object_set (cell,
-                    "text", display_name,
-                    "sensitive", sensitive,
-                    "ellipsize", PANGO_ELLIPSIZE_END,
-                    NULL);
-
-      g_free (display_name);
-
-      return;
-    }
-
-  info = get_list_file_info (impl, iter);
-  sensitive = TRUE;
-
-  if (!info)
-    {
-      g_object_set (cell,
-                   "text", DEFAULT_NEW_FOLDER_NAME,
-                   "sensitive", TRUE,
-                   "ellipsize", PANGO_ELLIPSIZE_NONE,
-                   NULL);
-
-      return;
-    }
-
-
-  if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-      impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
-    {
-      sensitive = _gtk_file_info_consider_as_directory (info);
-    }
-
-  g_object_set (cell,
-               "text", g_file_info_get_display_name (info),
-               "sensitive", sensitive,
-               "ellipsize", PANGO_ELLIPSIZE_END,
-               NULL);
-}
-
-static void
-list_size_data_func (GtkTreeViewColumn *tree_column,
-                    GtkCellRenderer   *cell,
-                    GtkTreeModel      *tree_model,
-                    GtkTreeIter       *iter,
-                    gpointer           data)
-{
-  GtkFileChooserDefault *impl = data;
-  GFileInfo *info;
-  goffset size;
-  gchar *str;
-  gboolean sensitive = TRUE;
-
-  if (impl->operation_mode == OPERATION_MODE_RECENT)
-    return;
-
-  if (impl->operation_mode == OPERATION_MODE_SEARCH)
-    {
-      GtkTreeIter child_iter;
-      gboolean is_folder = FALSE;
-
-      search_get_valid_child_iter (impl, &child_iter, iter);
-      gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
-                          MODEL_COL_SIZE, &size,
-                          MODEL_COL_IS_FOLDER, &is_folder,
-                         -1);
-
-      if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-          impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
-        sensitive = is_folder ? TRUE : FALSE;
-
-      if (!is_folder)
-        str = g_format_size_for_display (size);
-      else
-        str = NULL;
-
-      g_object_set (cell,
-                    "text", str,
-                    "sensitive", sensitive,
-                    NULL);
-
-      g_free (str);
-
-      return;
-    }
-
-  info = get_list_file_info (impl, iter);
-
-  if (!info || _gtk_file_info_consider_as_directory (info))
-    {
-      g_object_set (cell,
-                   "text", NULL,
-                   "sensitive", sensitive,
-                   NULL);
-      return;
-    }
-
-  size = g_file_info_get_size (info);
-  str = g_format_size_for_display (size);
-
-  if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-      impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
-    sensitive = FALSE;
-
-  g_object_set (cell,
-               "text", str,
-               "sensitive", sensitive,
-               NULL);
-
-  g_free (str);
-}
-
-/* Tree column data callback for the file list; fetches the mtime of a file */
-static void
-list_mtime_data_func (GtkTreeViewColumn *tree_column,
-                  GtkCellRenderer   *cell,
-                     GtkTreeModel      *tree_model,
-                     GtkTreeIter       *iter,
-                     gpointer           data)
-{
-  GtkFileChooserDefault *impl;
-  GTimeVal timeval = { 0, };
-  time_t time_mtime;
-  gchar *date_str = NULL;
-  gboolean sensitive = TRUE;
-#ifdef G_OS_WIN32
-  const char *locale, *dot = NULL;
-  gint64 codepage = -1;
-  char charset[20];
-#endif
-
-  impl = data;
-
-  if (impl->operation_mode == OPERATION_MODE_SEARCH)
-    {
-      GtkTreeIter child_iter;
-      guint64 mtime;
-      gboolean is_folder;
-
-      search_get_valid_child_iter (impl, &child_iter, iter);
-      gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
-                          MODEL_COL_MTIME, &mtime,
-                          MODEL_COL_IS_FOLDER, &is_folder,
-                         -1);
-
-      time_mtime = (time_t) mtime;
-
-      if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-          impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
-        sensitive = is_folder;
-    }
-  else if (impl->operation_mode == OPERATION_MODE_RECENT)
-    {
-      GtkTreeIter child_iter;
-      GtkRecentInfo *info;
-      gboolean is_folder;
-
-      recent_get_valid_child_iter (impl, &child_iter, iter);
-      gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
-                          RECENT_MODEL_COL_INFO, &info,
-                          MODEL_COL_IS_FOLDER, &is_folder,
-                          -1);
-
-      if (info)
-        time_mtime = gtk_recent_info_get_modified (info);
+      if (always_sensitive)
+        g_object_set (renderer, "sensitive", TRUE, NULL);
       else
-        time_mtime = 0;
-
-      if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-          impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
-        sensitive = is_folder;
-    }
+        gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_FOLDER);
+    }
+  g_list_free (list);
+
+  /* size */
+  column = gtk_tree_view_get_column (GTK_TREE_VIEW (impl->browse_files_tree_view), 1);
+  list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
+  renderer = list->data;
+  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
-    {
-      GFileInfo *info;
-
-      info = get_list_file_info (impl, iter);
-      if (!info)
-       {
-         g_object_set (cell,
-                       "text", "",
-                       "sensitive", TRUE,
-                       NULL);
-         return;
-       }
-
-      g_file_info_get_modification_time (info, &timeval);
-      time_mtime = timeval.tv_sec;
-
-      if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
-         impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
-       sensitive = _gtk_file_info_consider_as_directory (info);
-    }
-
-  if (G_UNLIKELY (time_mtime == 0))
-    date_str = g_strdup (_("Unknown"));
+    gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_FOLDER);
+  g_list_free (list);
+
+  /* mtime */
+  column = gtk_tree_view_get_column (GTK_TREE_VIEW (impl->browse_files_tree_view), 2);
+  list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
+  renderer = list->data;
+  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
-    date_str = my_g_format_time_for_display (time_mtime);
-
-  g_object_set (cell,
-               "text", date_str,
-               "sensitive", sensitive,
-               NULL);
-  g_free (date_str);
+    gtk_tree_view_column_add_attribute (column, renderer, "sensitive", MODEL_COL_IS_FOLDER);
+  g_list_free (list);
 }
 
 GtkWidget *