1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Johannes Schmid 2007 <jhs@gnome.org>
6 * anjuta is free software.
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
13 * anjuta is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with anjuta. If not, write to:
20 * The Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA.
25 #include "file-model.h"
26 #include <gdl/gdl-icons.h>
27 #include <glib/gi18n.h>
30 #include <libgnomevfs/gnome-vfs.h>
32 #define DIRECTORY_MIME_TYPE "x-directory/normal"
33 #define DIRECTORY_OPEN "x-directory/open"
42 typedef struct _FileModelPrivate FileModelPrivate
;
44 struct _FileModelPrivate
53 typedef struct _FileModelIdleExpand FileModelIdleExpand
;
54 struct _FileModelIdleExpand
62 #define FILE_MODEL_GET_PRIVATE(o) \
63 (G_TYPE_INSTANCE_GET_PRIVATE((o), FILE_TYPE_MODEL, FileModelPrivate))
65 G_DEFINE_TYPE (FileModel
, file_model
, GTK_TYPE_TREE_STORE
);
68 file_model_cancel_expand_idle(FileModel
* model
)
70 FileModelPrivate
* priv
= FILE_MODEL_GET_PRIVATE(model
);
72 if (priv
->expand_idle_id
)
74 GSource
* source
= g_main_context_find_source_by_id (g_main_context_default(),
75 priv
->expand_idle_id
);
76 g_source_destroy (source
);
77 priv
->expand_idle_id
= 0;
82 file_model_add_dummy (FileModel
* model
,
85 FileModelPrivate
* priv
=
86 FILE_MODEL_GET_PRIVATE (model
);
87 GtkTreeStore
* store
= GTK_TREE_STORE (model
);
90 gtk_tree_store_append (store
, &dummy
, iter
);
91 gtk_tree_store_set (store
, &dummy
,
92 COLUMN_FILENAME
, _("Loading..."),
97 file_model_expand_idle (gpointer data
)
99 FileModelIdleExpand
* expand
= (FileModelIdleExpand
*) data
;
100 FileModel
* model
= expand
->model
;
101 FileModelPrivate
* priv
= FILE_MODEL_GET_PRIVATE (model
);
102 GtkTreeStore
* store
= GTK_TREE_STORE (model
);
105 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(model
), &parent
, expand
->path
))
109 GList
* file
= expand
->files
;
110 GnomeVFSFileInfo
* info
= (GnomeVFSFileInfo
*) file
->data
;
111 GtkTreeIter new_iter
;
113 gboolean directory
= FALSE
;
115 /* Set pointer to the next element */
116 expand
->files
= g_list_next (file
);
118 /* Ignore hidden files */
119 if (g_str_has_prefix (info
->name
, "."))
124 /* Create file entry in tree */
125 const gchar
* mime_type
= gnome_vfs_file_info_get_mime_type (info
);
126 gchar
* uri
= g_build_filename (expand
->uri
, info
->name
, NULL
);
128 pixbuf
= gdl_icons_get_mime_icon (priv
->icons
, mime_type
);
130 gtk_tree_store_append (store
, &new_iter
, &parent
);
132 if (g_str_equal (mime_type
, DIRECTORY_MIME_TYPE
))
134 file_model_add_dummy (model
, &new_iter
);
138 gtk_tree_store_set (store
, &new_iter
,
139 COLUMN_FILENAME
, info
->name
,
141 COLUMN_PIXBUF
, pixbuf
,
142 COLUMN_IS_DIR
, directory
,
150 gnome_vfs_file_info_list_free (expand
->files
);
151 gtk_tree_model_iter_children (GTK_TREE_MODEL(model
), &dummy
, &parent
);
152 gtk_tree_store_remove (store
, &dummy
);
154 g_free (expand
->uri
);
156 priv
->expand_idle_id
= 0;
163 file_model_sort (gconstpointer a
, gconstpointer b
)
165 GnomeVFSFileInfo
* info_a
= (GnomeVFSFileInfo
*) a
;
166 GnomeVFSFileInfo
* info_b
= (GnomeVFSFileInfo
*) b
;
167 gboolean dir_a
= (info_a
->type
== GNOME_VFS_FILE_TYPE_DIRECTORY
);
168 gboolean dir_b
= (info_b
->type
== GNOME_VFS_FILE_TYPE_DIRECTORY
);
172 return strcasecmp (info_a
->name
, info_b
->name
);
187 file_model_row_expanded (GtkTreeView
* tree_view
, GtkTreeIter
* iter
,
190 FileModel
* model
= FILE_MODEL(gtk_tree_view_get_model(tree_view
));
191 FileModelPrivate
* priv
= FILE_MODEL_GET_PRIVATE (model
);
195 gtk_tree_model_get (GTK_TREE_MODEL(model
), iter
, COLUMN_URI
, &uri
, -1);
197 if (gnome_vfs_directory_list_load (&files
, uri
,
198 GNOME_VFS_FILE_INFO_GET_MIME_TYPE
) ==
201 files
= g_list_sort (files
, file_model_sort
);
202 FileModelIdleExpand
* expand
= g_new0 (FileModelIdleExpand
, 1);
203 expand
->files
= files
;
204 expand
->path
= gtk_tree_model_get_path (GTK_TREE_MODEL (model
), iter
);
205 expand
->model
= model
;
208 priv
->expand_idle_id
= g_idle_add_full (G_PRIORITY_HIGH_IDLE
,
209 (GSourceFunc
) file_model_expand_idle
,
211 (GDestroyNotify
) g_free
);
213 gtk_tree_store_set (GTK_TREE_STORE (model
), iter
,
215 gdl_icons_get_mime_icon (priv
->icons
, DIRECTORY_OPEN
),
222 file_model_row_collapsed (GtkTreeView
* tree_view
, GtkTreeIter
* iter
,
225 FileModel
* model
= FILE_MODEL(gtk_tree_view_get_model(tree_view
));
226 FileModelPrivate
* priv
= FILE_MODEL_GET_PRIVATE (model
);
229 while (gtk_tree_model_iter_children (GTK_TREE_MODEL(model
), &child
, iter
))
231 gtk_tree_store_remove (GTK_TREE_STORE (model
), &child
);
233 file_model_add_dummy (model
, iter
);
234 gtk_tree_store_set (GTK_TREE_STORE (model
), iter
,
236 gdl_icons_get_folder_icon (priv
->icons
),
241 file_model_init (FileModel
*object
)
243 FileModel
* model
= FILE_MODEL(object
);
244 FileModelPrivate
* priv
= FILE_MODEL_GET_PRIVATE (model
);
246 priv
->icons
= gdl_icons_new(ICON_SIZE
);
250 file_model_finalize (GObject
*object
)
252 FileModel
* model
= FILE_MODEL(object
);
253 FileModelPrivate
* priv
= FILE_MODEL_GET_PRIVATE(model
);
255 g_object_unref (G_OBJECT(priv
->icons
));
256 G_OBJECT_CLASS (file_model_parent_class
)->finalize (object
);
260 file_model_set_property (GObject
*object
, guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
262 g_return_if_fail (FILE_IS_MODEL (object
));
263 FileModel
* model
= FILE_MODEL(object
);
264 FileModelPrivate
* priv
= FILE_MODEL_GET_PRIVATE(model
);
269 g_free (priv
->base_uri
);
270 priv
->base_uri
= g_strdup (g_value_get_string (value
));
273 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
279 file_model_get_property (GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
281 g_return_if_fail (FILE_IS_MODEL (object
));
282 FileModel
* model
= FILE_MODEL(object
);
283 FileModelPrivate
* priv
= FILE_MODEL_GET_PRIVATE(model
);
288 g_value_set_string (value
, priv
->base_uri
);
291 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
297 file_model_class_init (FileModelClass
*klass
)
299 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
300 GtkTreeStoreClass
* parent_class
= GTK_TREE_STORE_CLASS (klass
);
302 object_class
->finalize
= file_model_finalize
;
303 object_class
->set_property
= file_model_set_property
;
304 object_class
->get_property
= file_model_get_property
;
306 g_type_class_add_private (object_class
, sizeof(FileModelPrivate
));
308 g_object_class_install_property (object_class
,
310 g_param_spec_string ("base_uri",
314 G_PARAM_READABLE
| G_PARAM_WRITABLE
| G_PARAM_CONSTRUCT
));
319 file_model_new (GtkTreeView
* tree_view
, const gchar
* base_uri
)
322 g_object_new (FILE_TYPE_MODEL
, "base_uri", base_uri
, NULL
);
323 GType types
[N_COLUMNS
] = {GDK_TYPE_PIXBUF
, G_TYPE_STRING
, G_TYPE_STRING
,
326 g_signal_connect (G_OBJECT (tree_view
), "row-collapsed",
327 G_CALLBACK (file_model_row_collapsed
), model
);
328 g_signal_connect (G_OBJECT (tree_view
), "row-expanded",
329 G_CALLBACK (file_model_row_expanded
), model
);
331 gtk_tree_store_set_column_types (GTK_TREE_STORE (model
), N_COLUMNS
,
334 return FILE_MODEL(model
);
338 file_model_refresh (FileModel
* model
)
340 GtkTreeStore
* store
= GTK_TREE_STORE (model
);
342 FileModelPrivate
* priv
= FILE_MODEL_GET_PRIVATE(model
);
344 gchar
* path
= gnome_vfs_get_local_path_from_uri (priv
->base_uri
);
345 gchar
* basename
= g_path_get_basename (path
);
346 GdkPixbuf
* pixbuf
= gdl_icons_get_folder_icon (priv
->icons
);
348 file_model_cancel_expand_idle(model
);
350 gtk_tree_store_clear (store
);
351 gtk_tree_store_append (store
, &iter
, NULL
);
353 gtk_tree_store_set (store
, &iter
,
354 COLUMN_FILENAME
, basename
,
355 COLUMN_URI
, priv
->base_uri
,
356 COLUMN_PIXBUF
, pixbuf
,
362 file_model_add_dummy (model
, &iter
);
366 file_model_get_uri (FileModel
* model
, GtkTreeIter
* iter
)
369 gtk_tree_model_get (GTK_TREE_MODEL (model
), iter
, COLUMN_URI
, &uri
, -1);
375 file_model_get_filename (FileModel
* model
, GtkTreeIter
* iter
)
378 gtk_tree_model_get (GTK_TREE_MODEL (model
), iter
, COLUMN_FILENAME
, &filename
, -1);