Updated Makefile.am files after make -f git.mk
[anjuta.git] / plugins / file-manager / file-model.c
blob81265a855f478d4de312afeb69f6185ed69a855d
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta
4 * Copyright (C) Johannes Schmid 2007 <jhs@gnome.org>
5 *
6 * anjuta is free software.
7 *
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)
11 * any later version.
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 <glib/gi18n.h>
27 #include <string.h>
28 #include <libanjuta/anjuta-debug.h>
29 #include <libanjuta/anjuta-plugin.h>
30 #include <libanjuta/anjuta-async-notify.h>
31 #include <gio/gio.h>
32 #include <gtk/gtk.h>
34 const gchar* BINARY_SUFFIX[] =
36 ".o",
37 ".lo",
38 ".a",
39 ".so",
40 ".pyc",
41 ".pyo",
42 NULL
45 #define ICON_SIZE 16
47 enum
49 PROP_0,
50 PROP_BASE_PATH,
51 PROP_FILTER_BINARY,
52 PROP_FILTER_HIDDEN,
53 PROP_FILTER_BACKUP,
54 PROP_FILTER_UNVERSIONED
57 enum
59 SIGNAL_DIRECTORY_EXPANDED,
60 SIGNAL_LAST
63 guint signals [SIGNAL_LAST];
65 typedef struct _FileModelPrivate FileModelPrivate;
66 typedef struct _FileModelAsyncData FileModelAsyncData;
68 struct _FileModelPrivate
70 GFile *base_path;
71 gboolean filter_binary;
72 gboolean filter_hidden;
73 gboolean filter_backup;
74 gboolean filter_unversioned;
76 GtkTreeView* view;
78 IAnjutaVcs *ivcs;
81 struct _FileModelAsyncData
83 FileModel* model;
84 GtkTreeRowReference* reference;
87 #define FILE_MODEL_GET_PRIVATE(o) \
88 (G_TYPE_INSTANCE_GET_PRIVATE((o), FILE_TYPE_MODEL, FileModelPrivate))
90 G_DEFINE_TYPE (FileModel, file_model, GTK_TYPE_TREE_STORE)
92 static gboolean
93 file_model_filter_file (FileModel* model,
94 GFileInfo* file_info)
96 FileModelPrivate* priv = FILE_MODEL_GET_PRIVATE (model);
98 if (priv->filter_hidden && g_file_info_get_is_hidden(file_info))
99 return FALSE;
100 else if (priv->filter_backup && g_file_info_get_is_backup(file_info))
101 return FALSE;
102 else if (priv->filter_binary &&
103 g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
105 int i;
106 const gchar* name = g_file_info_get_name (file_info);
107 for (i = 0; BINARY_SUFFIX[i] != NULL; i++)
109 if (g_str_has_suffix (name, BINARY_SUFFIX[i]))
111 return FALSE;
116 return TRUE;
119 static void
120 file_model_add_dummy (FileModel* model,
121 GtkTreeIter* iter)
123 GtkTreeStore* store = GTK_TREE_STORE (model);
124 GtkTreeIter dummy;
126 gtk_tree_store_append (store, &dummy, iter);
127 gtk_tree_store_set (store, &dummy,
128 COLUMN_FILENAME, _("Loading..."),
129 COLUMN_SORT, -1,
130 COLUMN_DUMMY, TRUE,
131 -1);
134 typedef struct
136 FileModel* model;
137 GtkTreeRowReference* ref;
138 } VcsData;
140 static void
141 file_model_vcs_status_callback(GFile *file,
142 AnjutaVcsStatus status,
143 gpointer user_data)
145 VcsData* data = user_data;
146 FileModelPrivate *priv = FILE_MODEL_GET_PRIVATE (data->model);
147 gchar* path = g_file_get_path (file);
149 GtkTreePath* tree_path = gtk_tree_row_reference_get_path (data->ref);
150 if (tree_path)
152 GFile* dir;
153 GFile* parent;
154 GtkTreeIter iter;
155 GtkTreeIter child;
156 GtkTreeModel* model = gtk_tree_row_reference_get_model (data->ref);
158 gtk_tree_model_get_iter (model,
159 &iter,
160 tree_path);
161 gtk_tree_model_get (model, &iter,
162 COLUMN_FILE, &dir, -1);
164 parent = g_file_get_parent (file);
166 if (gtk_tree_model_iter_children (model, &child, &iter) &&
167 g_file_equal (dir, parent))
171 GFile* child_file;
172 gboolean dummy;
173 gtk_tree_model_get (model, &child,
174 COLUMN_FILE,
175 &child_file,
176 COLUMN_DUMMY,
177 &dummy, -1);
178 if (dummy)
179 break;
180 if (file && child_file && g_file_equal (file, child_file))
182 if (priv->filter_unversioned &&
183 (status == ANJUTA_VCS_STATUS_UNVERSIONED ||
184 status == ANJUTA_VCS_STATUS_IGNORED))
186 gtk_tree_store_remove (GTK_TREE_STORE (model), &child);
188 else
190 gtk_tree_store_set (GTK_TREE_STORE (model),
191 &child,
192 COLUMN_STATUS,
193 status,
194 -1);
196 g_object_unref (child_file);
197 break;
200 while (gtk_tree_model_iter_next (model, &child));
202 gtk_tree_path_free (tree_path);
203 g_object_unref (dir);
204 g_object_unref (parent);
206 g_free(path);
209 static void
210 file_model_free_vcs_data (VcsData *data)
212 gtk_tree_row_reference_free (data->ref);
213 g_free (data);
216 static void
217 file_model_get_vcs_status (FileModel* model,
218 GtkTreeIter* iter,
219 GFile* file)
221 GtkTreePath* path = gtk_tree_model_get_path (GTK_TREE_MODEL(model),
222 iter);
223 FileModelPrivate* priv = FILE_MODEL_GET_PRIVATE(model);
225 if (priv->ivcs)
227 VcsData* data = g_new0(VcsData, 1);
228 AnjutaAsyncNotify* notify = anjuta_async_notify_new();
229 data->ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model),
230 path);
231 data->model = model;
233 g_signal_connect_swapped (G_OBJECT (notify), "finished",
234 G_CALLBACK (file_model_free_vcs_data), data);
236 ianjuta_vcs_query_status(priv->ivcs,
237 file,
238 file_model_vcs_status_callback,
239 data,
240 NULL,
241 notify,
242 NULL);
244 gtk_tree_path_free (path);
247 static void
248 file_model_update_file (FileModel* model,
249 GtkTreeIter* iter,
250 GFile* file,
251 GFileInfo* file_info,
252 gboolean add)
254 GtkTreeStore* store = GTK_TREE_STORE(model);
255 gboolean is_dir = FALSE;
256 gchar** icon_names;
257 GtkIconInfo* icon_info;
258 GIcon* icon;
259 GdkPixbuf* pixbuf = NULL;
260 gchar* display_name;
262 icon = g_file_info_get_icon(file_info);
263 if (icon)
265 g_object_get (icon, "names", &icon_names, NULL);
267 if ((icon_info = gtk_icon_theme_choose_icon (gtk_icon_theme_get_default(),
268 (const gchar **)icon_names,
269 ICON_SIZE,
270 GTK_ICON_LOOKUP_FORCE_SIZE)))
272 pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
273 gtk_icon_info_free(icon_info);
275 g_strfreev (icon_names);
278 if (g_file_info_get_file_type(file_info) == G_FILE_TYPE_DIRECTORY)
279 is_dir = TRUE;
281 display_name = g_markup_printf_escaped("%s",
282 g_file_info_get_display_name(file_info));
284 gtk_tree_store_set (store, iter,
285 COLUMN_DISPLAY, display_name,
286 COLUMN_FILENAME, display_name,
287 COLUMN_FILE, file,
288 COLUMN_PIXBUF, pixbuf,
289 COLUMN_STATUS, ANJUTA_VCS_STATUS_NONE,
290 COLUMN_IS_DIR, is_dir,
291 COLUMN_SORT, g_file_info_get_sort_order(file_info),
292 COLUMN_DUMMY, FALSE,
293 -1);
295 if (is_dir)
297 file_model_add_dummy(model, iter);
299 if (!is_dir && !add)
301 GtkTreeIter parent;
302 GFile* dir;
303 gtk_tree_model_iter_parent (GTK_TREE_MODEL (model), &parent, iter);
304 gtk_tree_model_get (GTK_TREE_MODEL (model), &parent,
305 COLUMN_FILE, &dir, -1);
306 file_model_get_vcs_status (model, &parent, dir);
307 g_object_unref (dir);
310 if (pixbuf)
311 g_object_unref (pixbuf);
312 g_free(display_name);
315 static gboolean
316 file_model_update_file_foreach_func (GtkTreeModel* model,
317 GtkTreePath* path,
318 GtkTreeIter* iter,
319 gpointer user_data)
321 GFile* file;
322 GFileInfo* info;
324 gtk_tree_model_get (model, iter,
325 COLUMN_FILE, &file, -1);
327 if (!file)
328 return FALSE;
330 info = g_file_query_info (file,
331 "standard::*",
332 G_FILE_QUERY_INFO_NONE,
333 NULL, NULL);
335 if (!info)
337 g_object_unref (file);
338 return FALSE;
341 file_model_update_file (FILE_MODEL (model),
342 iter,
343 file,
344 info,
345 FALSE);
346 g_object_unref (info);
347 g_object_unref (file);
349 /* Continue iterating */
350 return FALSE;
353 static void
354 file_model_add_file (FileModel* model,
355 GtkTreeIter* parent,
356 GFile* file,
357 GFileInfo* file_info)
359 GtkTreeIter iter;
360 GtkTreeStore* store = GTK_TREE_STORE(model);
362 if (file_model_filter_file (model, file_info))
364 gtk_tree_store_append (store, &iter, parent);
365 file_model_update_file (model, &iter, file, file_info, TRUE);
369 void file_model_update_vcs_status (FileModel* model)
371 gtk_tree_model_foreach (GTK_TREE_MODEL(model),
372 file_model_update_file_foreach_func, NULL);
375 static void
376 on_file_model_changed (GFileMonitor* monitor,
377 GFile* file,
378 GFile* other_file,
379 GFileMonitorEvent event_type,
380 gpointer data)
382 GtkTreeRowReference* reference = (GtkTreeRowReference*)data;
383 FileModel* model;
384 GtkTreeIter iter;
385 GtkTreePath* path;
386 GtkTreeIter file_iter;
387 gboolean found = FALSE;
389 /* reference could be invalid if the file has already been destroyed */
390 if (!gtk_tree_row_reference_valid(reference))
391 return;
393 model = FILE_MODEL(gtk_tree_row_reference_get_model (reference));
394 path = gtk_tree_row_reference_get_path (reference);
396 gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path);
397 gtk_tree_path_free (path);
399 if (gtk_tree_model_iter_children (GTK_TREE_MODEL(model), &file_iter, &iter))
403 GFile* model_file;
404 gtk_tree_model_get (GTK_TREE_MODEL(model), &file_iter,
405 COLUMN_FILE, &model_file, -1);
406 if (model_file && file && g_file_equal (model_file, file))
408 g_object_unref (model_file);
409 found = TRUE;
410 break;
412 g_clear_object (&model_file);
414 while (gtk_tree_model_iter_next (GTK_TREE_MODEL(model), &file_iter));
416 if (event_type == G_FILE_MONITOR_EVENT_CHANGED ||
417 event_type == G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED ||
418 event_type == G_FILE_MONITOR_EVENT_DELETED)
420 if (!found)
421 return;
424 switch (event_type)
426 case G_FILE_MONITOR_EVENT_CHANGED:
427 case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
428 case G_FILE_MONITOR_EVENT_CREATED:
430 GFileInfo* file_info;
431 file_info = g_file_query_info (file,
432 "standard::*",
433 G_FILE_QUERY_INFO_NONE,
434 NULL, NULL);
435 if (file_info)
437 if (!found)
438 file_model_add_file (model, &iter, file, file_info);
439 else
440 file_model_update_file (model, &file_iter, file, file_info, FALSE);
441 g_object_unref (file_info);
443 break;
445 case G_FILE_MONITOR_EVENT_DELETED:
447 gtk_tree_store_remove (GTK_TREE_STORE (model), &file_iter);
448 break;
450 default:
451 /* do nothing */
452 break;
456 static void
457 file_model_add_watch (FileModel* model, GtkTreePath* path)
459 GtkTreeIter iter;
460 GtkTreeRowReference* reference;
461 GFile* file;
462 GFileMonitor* monitor;
464 gtk_tree_model_get_iter (GTK_TREE_MODEL (model),
465 &iter, path);
467 gtk_tree_model_get (GTK_TREE_MODEL(model), &iter,
468 COLUMN_FILE, &file, -1);
470 reference = gtk_tree_row_reference_new (GTK_TREE_MODEL(model), path);
472 monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE,
473 NULL, NULL);
474 g_signal_connect (monitor, "changed", G_CALLBACK(on_file_model_changed),
475 reference);
477 g_object_set_data_full (G_OBJECT(file), "file-monitor", monitor, (GDestroyNotify)g_object_unref);
478 /* Reference is used by monitor, should be kept it until the monitor is destroyed */
479 g_object_set_data_full (G_OBJECT(monitor), "reference", reference, (GDestroyNotify)gtk_tree_row_reference_free);
480 g_object_unref (file);
483 static void
484 on_row_expanded_async (GObject* source_object,
485 GAsyncResult* result,
486 gpointer user_data)
488 FileModelAsyncData* data = user_data;
489 GFile* dir = G_FILE (source_object);
490 GFileEnumerator* files;
491 GError* err = NULL;
492 GtkTreeIter real_iter;
493 GtkTreeIter dummy;
494 GtkTreeRowReference* ref = data->reference;
495 GtkTreePath* path;
496 FileModel* model = data->model;
497 GFileInfo* file_info;
499 files = g_file_enumerate_children_finish (dir, result, &err);
500 path = gtk_tree_row_reference_get_path (ref);
502 if (!path)
504 gtk_tree_row_reference_free (ref);
505 g_object_unref (files);
506 return;
509 if (err)
511 DEBUG_PRINT ("GIO-Error: %s", err->message);
512 g_error_free (err);
513 // TODO: Collapse row
514 return;
517 gtk_tree_model_get_iter (GTK_TREE_MODEL(data->model), &real_iter, path);
519 while (files && (file_info = g_file_enumerator_next_file (files, NULL, NULL)))
521 GFile* file = g_file_get_child (dir, g_file_info_get_name(file_info));
522 file_model_add_file (data->model, &real_iter, file, file_info);
523 g_object_unref (file);
524 g_object_unref (file_info);
526 /* Remove dummy node */
527 gtk_tree_model_iter_children (GTK_TREE_MODEL(model), &dummy, &real_iter);
528 gtk_tree_store_remove (GTK_TREE_STORE(model), &dummy);
530 file_model_add_watch (model, path);
531 file_model_get_vcs_status (model, &real_iter, dir);
533 g_signal_emit (model, signals[SIGNAL_DIRECTORY_EXPANDED], 0, &real_iter, path);
535 gtk_tree_path_free (path);
536 gtk_tree_row_reference_free (ref);
537 g_object_unref(files);
540 static void
541 file_model_row_expanded (GtkTreeView* tree_view, GtkTreeIter* iter,
542 GtkTreePath* path, gpointer user_data)
544 GtkTreeModel* sort_model = gtk_tree_view_get_model(tree_view);
545 FileModel* model = FILE_MODEL(user_data);
546 GFile* dir;
547 GtkTreeIter real_iter;
548 GCancellable* cancel = g_cancellable_new ();
549 GtkTreePath* real_path;
551 DEBUG_PRINT ("%s", "row_expanded");
553 gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(sort_model),
554 &real_iter, iter);
556 gtk_tree_model_get(GTK_TREE_MODEL(model), &real_iter,
557 COLUMN_FILE, &dir, -1);
559 FileModelAsyncData* data = g_new0 (FileModelAsyncData, 1);
560 data->model = model;
561 real_path = gtk_tree_model_get_path (GTK_TREE_MODEL (model),
562 &real_iter);
563 data->reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (model),
564 real_path);
565 gtk_tree_path_free (real_path);
567 g_object_set_data (G_OBJECT(dir), "_cancel", cancel);
569 g_file_enumerate_children_async (dir,
570 "standard::*",
571 G_FILE_QUERY_INFO_NONE,
572 G_PRIORITY_LOW,
573 cancel,
574 on_row_expanded_async,
575 data);
576 g_object_unref (dir);
579 static void
580 file_model_row_collapsed (GtkTreeView* tree_view, GtkTreeIter* iter,
581 GtkTreePath* path, gpointer data)
583 GtkTreeModel* sort_model = gtk_tree_view_get_model(tree_view);
584 FileModel* model = FILE_MODEL(data);
585 GtkTreeIter child;
586 GtkTreeIter sort_iter;
587 GtkTreeIter real_iter;
588 GFile* dir;
589 GCancellable* cancel;
591 /* Iter might be invalid in some conditions */
592 gtk_tree_model_get_iter (sort_model, &sort_iter, path);
594 gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(sort_model),
595 &real_iter, &sort_iter);
597 gtk_tree_model_get (GTK_TREE_MODEL (model), &real_iter,
598 COLUMN_FILE, &dir, -1);
600 cancel = g_object_get_data (G_OBJECT(dir), "_cancel");
601 g_cancellable_cancel (cancel);
602 g_object_unref (cancel);
603 g_object_unref (dir);
605 while (gtk_tree_model_iter_children (GTK_TREE_MODEL(model), &child, &real_iter))
607 gtk_tree_store_remove (GTK_TREE_STORE (model), &child);
610 file_model_add_dummy (model, &real_iter);
613 static void
614 file_model_init (FileModel *object)
619 static void
620 file_model_finalize (GObject *object)
622 FileModel *model = FILE_MODEL(object);
623 FileModelPrivate* priv = FILE_MODEL_GET_PRIVATE(model);
625 g_clear_object (&priv->base_path);
626 if (priv->ivcs)
627 g_object_remove_weak_pointer (G_OBJECT (priv->ivcs), (void**)&priv->ivcs);
629 G_OBJECT_CLASS (file_model_parent_class)->finalize (object);
632 static void
633 file_model_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
635 g_return_if_fail (FILE_IS_MODEL (object));
636 FileModel* model = FILE_MODEL(object);
637 FileModelPrivate* priv = FILE_MODEL_GET_PRIVATE(model);
639 switch (prop_id)
641 case PROP_BASE_PATH:
642 g_clear_object (&priv->base_path);
643 priv->base_path = g_value_dup_object (value);
644 if (!priv->base_path)
645 priv->base_path = g_file_new_for_uri ("file:///");
646 break;
647 case PROP_FILTER_BINARY:
648 priv->filter_binary = g_value_get_boolean (value);
649 break;
650 case PROP_FILTER_HIDDEN:
651 priv->filter_hidden = g_value_get_boolean (value);
652 break;
653 case PROP_FILTER_BACKUP:
654 priv->filter_backup = g_value_get_boolean (value);
655 break;
656 case PROP_FILTER_UNVERSIONED:
657 priv->filter_unversioned = g_value_get_boolean (value);
658 break;
660 default:
661 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
662 break;
666 static void
667 file_model_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
669 g_return_if_fail (FILE_IS_MODEL (object));
670 FileModel* model = FILE_MODEL(object);
671 FileModelPrivate* priv = FILE_MODEL_GET_PRIVATE(model);
673 switch (prop_id)
675 case PROP_BASE_PATH:
676 g_value_set_object (value, priv->base_path);
677 break;
678 case PROP_FILTER_BINARY:
679 g_value_set_boolean (value, priv->filter_binary);
680 case PROP_FILTER_HIDDEN:
681 g_value_set_boolean (value, priv->filter_hidden);
682 case PROP_FILTER_BACKUP:
683 g_value_set_boolean (value, priv->filter_backup);
684 case PROP_FILTER_UNVERSIONED:
685 g_value_set_boolean (value, priv->filter_unversioned);
687 default:
688 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
689 break;
694 static void
695 file_model_class_init (FileModelClass *klass)
697 GObjectClass* object_class = G_OBJECT_CLASS (klass);
699 object_class->finalize = file_model_finalize;
700 object_class->set_property = file_model_set_property;
701 object_class->get_property = file_model_get_property;
703 g_type_class_add_private (object_class, sizeof(FileModelPrivate));
705 g_object_class_install_property (object_class,
706 PROP_BASE_PATH,
707 g_param_spec_object ("base-path",
708 _("Base Path"),
709 _("GFile representing the top-most path displayed"),
710 G_TYPE_FILE,
711 G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
712 g_object_class_install_property (object_class,
713 PROP_FILTER_BINARY,
714 g_param_spec_boolean ("filter_binary",
715 "Filter binary files",
716 "file_binary",
717 TRUE,
718 G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
720 g_object_class_install_property (object_class,
721 PROP_FILTER_HIDDEN,
722 g_param_spec_boolean ("filter_hidden",
723 "Filter hidden files",
724 "file_hidden",
725 TRUE,
726 G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
728 g_object_class_install_property (object_class,
729 PROP_FILTER_BACKUP,
730 g_param_spec_boolean ("filter_backup",
731 "Filter backup files",
732 "file_backup",
733 TRUE,
734 G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
736 g_object_class_install_property (object_class,
737 PROP_FILTER_UNVERSIONED,
738 g_param_spec_boolean ("filter_unversioned",
739 "Filter unversioned files",
740 "file_unversioned",
741 TRUE,
742 G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
744 signals[SIGNAL_DIRECTORY_EXPANDED] =
745 g_signal_new ("directory-expanded",
746 G_TYPE_FROM_CLASS (object_class),
747 G_SIGNAL_RUN_FIRST,
748 0, NULL, NULL, NULL,
749 G_TYPE_NONE, 2, GTK_TYPE_TREE_ITER, GTK_TYPE_TREE_PATH);
753 FileModel*
754 file_model_new (GtkTreeView* tree_view, GFile* base_path)
756 GObject* model =
757 g_object_new (FILE_TYPE_MODEL, "base-path", base_path, NULL);
758 GType types[N_COLUMNS] = {GDK_TYPE_PIXBUF, G_TYPE_STRING,
759 G_TYPE_STRING, G_TYPE_UINT, G_TYPE_OBJECT,
760 G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_BOOLEAN};
761 FileModelPrivate* priv = FILE_MODEL_GET_PRIVATE(model);
763 g_signal_connect (G_OBJECT (tree_view), "row-collapsed",
764 G_CALLBACK (file_model_row_collapsed), model);
765 g_signal_connect (G_OBJECT (tree_view), "row-expanded",
766 G_CALLBACK (file_model_row_expanded), model);
768 gtk_tree_store_set_column_types (GTK_TREE_STORE (model), N_COLUMNS,
769 types);
771 priv->view = tree_view;
773 return FILE_MODEL(model);
776 void
777 file_model_refresh (FileModel* model)
779 GtkTreeStore* store = GTK_TREE_STORE (model);
780 FileModelPrivate* priv = FILE_MODEL_GET_PRIVATE(model);
781 GFileInfo* base_info;
783 gtk_tree_store_clear (store);
785 base_info = g_file_query_info (priv->base_path, "standard::*",
786 G_FILE_QUERY_INFO_NONE, NULL, NULL);
788 if (!base_info)
789 return;
791 file_model_add_file (model, NULL, priv->base_path, base_info);
792 g_object_unref (base_info);
795 GFile*
796 file_model_get_file (FileModel* model, GtkTreeIter* iter)
798 GFile* file;
800 gtk_tree_model_get (GTK_TREE_MODEL (model), iter, COLUMN_FILE, &file, -1);
802 return file;
805 gchar*
806 file_model_get_filename (FileModel* model, GtkTreeIter* iter)
808 gchar* filename;
809 gtk_tree_model_get (GTK_TREE_MODEL (model), iter, COLUMN_FILENAME, &filename, -1);
811 return filename;
814 void
815 file_model_set_ivcs (FileModel* model, IAnjutaVcs *ivcs)
817 FileModelPrivate *priv = FILE_MODEL_GET_PRIVATE (model);
819 if (priv->ivcs)
820 g_object_remove_weak_pointer (G_OBJECT (priv->ivcs), (void**)&priv->ivcs);
822 priv->ivcs = ivcs;
823 if (priv->ivcs)
824 g_object_add_weak_pointer (G_OBJECT (priv->ivcs), (void**)&priv->ivcs);