Implement new GtkFileSystemModel

The new model is mostly API-compatible with the old model (minimal
changes were required), but is a lot faster and has a lot of very
desirable features.
- the model does no longer support a tree, just a list of files in a
  given directory
- the storage has been moved to a GArray as opposed to a tree
- no more dependency on GtkFileSystem
- columns are managed by the creator of the model, so any number of
  nodes can be added as needed. This also makes the API more similar
  to GtkListStore.
- Values are filled on demand using a function given when creating the
  model.
- The function can decide to let the model cache returned values or
  decide to be called again the next time the value is queried.
- implements GtkTreeSortable
- _gtk_file_system_model_get_value() was added to significantly speed
  up value access, which is necessary when sorting large models.
This commit is contained in:
Benjamin Otte 2009-06-30 15:15:55 +02:00
parent 3c9a34dba3
commit 18b56b9970
3 changed files with 1387 additions and 1691 deletions

View File

@ -216,6 +216,12 @@ enum {
RECENT_MODEL_COL_NUM_COLUMNS
};
typedef enum {
GTK_FILE_SYSTEM_MODEL_INFO,
GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME,
GTK_FILE_SYSTEM_MODEL_N_COLUMNS
} GtkFileSystemModelColumns;
/* Identifiers for target types */
enum {
GTK_TREE_MODEL_ROW,
@ -6716,10 +6722,18 @@ show_and_select_files_finished_loading (GtkFolder *folder,
for (l = data->files; l; l = l->next)
{
GFile *file;
GtkTreePath *path;
GtkTreeIter iter;
file = l->data;
_gtk_file_system_model_path_do (data->impl->browse_files_model, file,
select_func, data->impl);
if (!_gtk_file_system_model_get_iter_for_file (data->impl->browse_files_model,
&iter,
file))
return;
path = gtk_tree_model_get_path (GTK_TREE_MODEL (data->impl->browse_files_model), &iter);
select_func (data->impl->browse_files_model, path, &iter, data->impl);
gtk_tree_path_free (path);
}
browse_files_center_selected_row (data->impl);
@ -6834,6 +6848,7 @@ pending_select_files_process (GtkFileChooserDefault *impl)
/* Callback used when the file system model finishes loading */
static void
browse_files_model_finished_loading_cb (GtkFileSystemModel *model,
GError *error,
GtkFileChooserDefault *impl)
{
profile_start ("start", NULL);
@ -6889,6 +6904,30 @@ stop_loading_and_clear_list_model (GtkFileChooserDefault *impl)
gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
}
static gboolean
file_system_model_set (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info,
int column,
GValue *value,
gpointer user_data)
{
switch (column)
{
case GTK_FILE_SYSTEM_MODEL_INFO:
g_value_set_object (value, info);
break;
case GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME:
if (info)
g_value_set_string (value, g_file_info_get_display_name (info));
break;
default:
g_assert_not_reached ();
}
return TRUE;
}
/* Gets rid of the old list model and creates a new one for the current folder */
static gboolean
set_list_model (GtkFileChooserDefault *impl,
@ -6903,10 +6942,15 @@ set_list_model (GtkFileChooserDefault *impl,
set_busy_cursor (impl, TRUE);
gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
impl->browse_files_model = _gtk_file_system_model_new (impl->file_system,
impl->current_folder, 0,
"standard,time,thumbnail::*",
error);
impl->browse_files_model =
_gtk_file_system_model_new (impl->current_folder,
"standard,time,thumbnail::*",
file_system_model_set,
impl,
GTK_FILE_SYSTEM_MODEL_N_COLUMNS,
G_TYPE_FILE_INFO,
G_TYPE_STRING);
if (!impl->browse_files_model)
{
set_busy_cursor (impl, FALSE);
@ -7512,12 +7556,20 @@ gtk_file_chooser_default_unselect_file (GtkFileChooser *chooser,
GFile *file)
{
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
GtkTreePath *path;
GtkTreeIter iter;
if (!impl->browse_files_model)
return;
_gtk_file_system_model_path_do (impl->browse_files_model, file,
unselect_func, impl);
if (!_gtk_file_system_model_get_iter_for_file (impl->browse_files_model,
&iter,
file))
return;
path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->browse_files_model), &iter);
unselect_func (impl->browse_files_model, path, &iter, impl);
gtk_tree_path_free (path);
}
static gboolean

File diff suppressed because it is too large Load Diff

View File

@ -34,27 +34,51 @@ typedef struct _GtkFileSystemModel GtkFileSystemModel;
GType _gtk_file_system_model_get_type (void) G_GNUC_CONST;
typedef enum {
GTK_FILE_SYSTEM_MODEL_INFO,
GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME,
GTK_FILE_SYSTEM_MODEL_N_COLUMNS
} GtkFileSystemModelColumns;
typedef gboolean (*GtkFileSystemModelGetValue) (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info,
int column,
GValue *value,
gpointer user_data);
GtkFileSystemModel *_gtk_file_system_model_new (GtkFileSystem *file_system,
GFile *root_file,
gint max_depth,
const gchar *attributes,
GError **error);
GtkFileSystemModel *_gtk_file_system_model_new (GFile * dir,
const gchar * attributes,
GtkFileSystemModelGetValue get_func,
gpointer get_data,
guint n_columns,
...);
GCancellable * _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model);
GFileInfo * _gtk_file_system_model_get_info (GtkFileSystemModel *model,
GtkTreeIter *iter);
gboolean _gtk_file_system_model_get_iter_for_file(GtkFileSystemModel *model,
GtkTreeIter *iter,
GFile *file);
GFile * _gtk_file_system_model_get_file (GtkFileSystemModel *model,
GtkTreeIter *iter);
const GValue * _gtk_file_system_model_get_value (GtkFileSystemModel *model,
GtkTreeIter * iter,
int column);
void _gtk_file_system_model_add_file (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info);
void _gtk_file_system_model_remove_file (GtkFileSystemModel *model,
GFile *file);
void _gtk_file_system_model_update_file (GtkFileSystemModel *model,
GFile *file,
GFileInfo *info,
gboolean requires_resort);
void _gtk_file_system_model_set_show_hidden (GtkFileSystemModel *model,
gboolean show_hidden);
void _gtk_file_system_model_set_show_folders (GtkFileSystemModel *model,
gboolean show_folders);
void _gtk_file_system_model_set_show_files (GtkFileSystemModel *model,
gboolean show_files);
void _gtk_file_system_model_freeze_updates (GtkFileSystemModel *model);
void _gtk_file_system_model_thaw_updates (GtkFileSystemModel *model);
void _gtk_file_system_model_clear_cache (GtkFileSystemModel *model,
int column);
typedef gboolean (*GtkFileSystemModelFilter) (GtkFileSystemModel *model,
GFile *file,
@ -65,16 +89,6 @@ void _gtk_file_system_model_set_filter (GtkFileSystemModel *model,
GtkFileSystemModelFilter filter,
gpointer user_data);
typedef void (*GtkFileSystemModelPathFunc) (GtkFileSystemModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer user_data);
void _gtk_file_system_model_path_do (GtkFileSystemModel *model,
GFile *file,
GtkFileSystemModelPathFunc func,
gpointer user_data);
void _gtk_file_system_model_add_editable (GtkFileSystemModel *model,
GtkTreeIter *iter);
void _gtk_file_system_model_remove_editable (GtkFileSystemModel *model);