project-manager: Allow hidden node in the tree view (for object node)
[anjuta.git] / plugins / project-manager / project-view.c
blob0002e3d5544aa5d6ce6b08688ac27798898f088a
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8; coding: utf-8 -*- */
2 /* project-tree.c
4 * Copyright (C) 2000 JP Rosevear
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
21 * Authors: JP Rosevear
22 * Gustavo Giráldez <gustavo.giraldez@gmx.net>
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
31 #include <glib/gi18n.h>
32 #include <gdk/gdk.h>
33 #include <gtk/gtk.h>
34 #include <gio/gio.h>
35 #include <string.h>
37 #include "tree-data.h"
38 #include "project-model.h"
39 #include "project-view.h"
40 #include "project-marshal.h"
41 #include "project-util.h"
43 #define ICON_SIZE 16
45 enum {
46 URI_ACTIVATED,
47 TARGET_SELECTED,
48 GROUP_SELECTED,
49 NODE_LOADED,
50 LAST_SIGNAL
53 static guint signals [LAST_SIGNAL] = { 0 };
55 /* Project model filter with drag and drop support
56 *---------------------------------------------------------------------------*/
58 typedef struct {
59 GtkTreeModelFilter parent;
60 } PmProjectModelFilter;
62 typedef struct {
63 GtkTreeModelFilterClass parent_class;
64 } PmProjectModelFilterClass;
66 #define PM_TYPE_PROJECT_MODEL_FILTER (pm_project_model_filter_get_type ())
67 #define PM_PROJECT_MODEL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PM_TYPE_PROJECT_MODEL_FILTER, PmProjectModelFilter))
70 static void
71 pm_project_model_filter_class_init (PmProjectModelFilterClass *class)
75 static void
76 pm_project_model_filter_init (PmProjectModelFilter *model)
80 static gboolean
81 idrag_source_row_draggable (GtkTreeDragSource *drag_source, GtkTreePath *path)
83 GtkTreeIter iter;
84 GbfTreeData *data;
85 gboolean retval = FALSE;
87 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path))
88 return FALSE;
90 gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter,
91 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
92 -1);
94 if (data->is_shortcut) {
95 /* shortcuts can be moved */
96 retval = TRUE;
98 } else if (data->type == GBF_TREE_NODE_TARGET) {
99 /* don't allow duplicate shortcuts */
100 if (data->shortcut == NULL)
101 retval = TRUE;
104 return retval;
107 static gboolean
108 idrag_source_drag_data_delete (GtkTreeDragSource *drag_source, GtkTreePath *path)
110 return FALSE;
113 static gboolean
114 idrag_dest_drag_data_received (GtkTreeDragDest *drag_dest,
115 GtkTreePath *dest,
116 GtkSelectionData *selection_data)
118 GtkTreeModel *src_model = NULL;
119 GtkTreePath *src_path = NULL;
120 GtkTreeModel *project_model;
121 gboolean retval = FALSE;
123 if (GTK_IS_TREE_MODEL_FILTER (drag_dest))
125 project_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (drag_dest));
127 else
129 project_model = GTK_TREE_MODEL (drag_dest);
131 g_return_val_if_fail (GBF_IS_PROJECT_MODEL (project_model), FALSE);
133 if (gtk_tree_get_row_drag_data (selection_data,
134 &src_model,
135 &src_path) &&
136 src_model == GTK_TREE_MODEL (project_model)) {
138 GtkTreeIter iter;
139 GbfTreeData *data = NULL;
141 if (gtk_tree_model_get_iter (src_model, &iter, src_path)) {
142 gtk_tree_model_get (src_model, &iter,
143 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
144 -1);
145 if (data != NULL)
147 GtkTreePath *child_path;
149 child_path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (drag_dest), dest);
150 if (data->type == GBF_TREE_NODE_SHORTCUT)
152 gbf_project_model_move_target_shortcut (GBF_PROJECT_MODEL (project_model),
153 &iter, data, child_path);
155 else
157 gbf_project_model_add_target_shortcut (GBF_PROJECT_MODEL (project_model),
158 NULL, data, child_path, NULL);
160 gtk_tree_path_free (child_path);
161 retval = TRUE;
166 if (src_path)
167 gtk_tree_path_free (src_path);
169 return retval;
172 static gboolean
173 idrag_dest_row_drop_possible (GtkTreeDragDest *drag_dest,
174 GtkTreePath *dest_path,
175 GtkSelectionData *selection_data)
177 GtkTreeModel *src_model;
178 GtkTreeModel *project_model;
179 GtkTreePath *src_path;
180 GtkTreeIter iter;
181 gboolean retval = FALSE;
183 //g_return_val_if_fail (GBF_IS_PROJECT_MODEL (drag_dest), FALSE);
185 if (GTK_IS_TREE_MODEL_FILTER (drag_dest))
187 project_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (drag_dest));
189 else
191 project_model = GTK_TREE_MODEL (drag_dest);
194 if (!gtk_tree_get_row_drag_data (selection_data,
195 &src_model,
196 &src_path))
198 return FALSE;
202 if (gtk_tree_model_get_iter (src_model, &iter, src_path))
204 GbfTreeData *data = NULL;
206 gtk_tree_model_get (src_model, &iter,
207 GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
209 if (data != NULL)
211 /* can only drag to ourselves and only new toplevel nodes will
212 * be created */
213 if (src_model == project_model &&
214 gtk_tree_path_get_depth (dest_path) == 1)
216 if (data->type == GBF_TREE_NODE_SHORTCUT)
218 retval = TRUE;
220 else
222 GtkTreePath *root_path;
223 GtkTreePath *child_path;
225 root_path = gbf_project_model_get_project_root (GBF_PROJECT_MODEL (project_model));
226 child_path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER (drag_dest), dest_path);
227 retval = gtk_tree_path_compare (child_path, root_path) <= 0;
228 gtk_tree_path_free (child_path);
229 gtk_tree_path_free (root_path);
234 gtk_tree_path_free (src_path);
236 return retval;
239 static void
240 pm_project_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface)
242 iface->row_draggable = idrag_source_row_draggable;
243 iface->drag_data_delete = idrag_source_drag_data_delete;
246 static void
247 pm_project_model_filter_drag_dest_iface_init (GtkTreeDragDestIface *iface)
249 iface->drag_data_received = idrag_dest_drag_data_received;
250 iface->row_drop_possible = idrag_dest_row_drop_possible;
253 static GType pm_project_model_filter_get_type (void);
255 G_DEFINE_TYPE_WITH_CODE (PmProjectModelFilter,
256 pm_project_model_filter,
257 GTK_TYPE_TREE_MODEL_FILTER,
258 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
259 pm_project_model_filter_drag_source_iface_init)
260 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_DEST,
261 pm_project_model_filter_drag_dest_iface_init));
264 static GtkTreeModel *
265 pm_project_model_filter_new (GtkTreeModel *child_model,
266 GtkTreePath *root)
268 PmProjectModelFilter *model;
270 model = g_object_new (PM_TYPE_PROJECT_MODEL_FILTER,
271 "child-model", child_model,
272 "virtual-root", root,
273 NULL);
275 return GTK_TREE_MODEL (model);
282 static void gbf_project_view_class_init (GbfProjectViewClass *klass);
283 static void gbf_project_view_init (GbfProjectView *tree);
284 static void destroy (GtkWidget *object);
286 static void set_pixbuf (GtkTreeViewColumn *tree_column,
287 GtkCellRenderer *cell,
288 GtkTreeModel *model,
289 GtkTreeIter *iter,
290 gpointer data);
291 static void set_text (GtkTreeViewColumn *tree_column,
292 GtkCellRenderer *cell,
293 GtkTreeModel *model,
294 GtkTreeIter *iter,
295 gpointer data);
298 G_DEFINE_TYPE(GbfProjectView, gbf_project_view, GTK_TYPE_TREE_VIEW);
300 static void
301 row_activated (GtkTreeView *tree_view,
302 GtkTreePath *path,
303 GtkTreeViewColumn *column)
305 GtkTreeModel *model;
306 GtkTreeIter iter;
307 GbfTreeData *data;
308 gchar *uri;
310 model = gtk_tree_view_get_model (tree_view);
312 gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
314 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
315 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
316 -1);
318 uri = gbf_tree_data_get_uri (data);
319 if (uri != NULL) {
320 g_signal_emit (G_OBJECT (tree_view),
321 signals [URI_ACTIVATED], 0,
322 uri);
325 if (data->type == GBF_TREE_NODE_TARGET) {
326 g_signal_emit (G_OBJECT (tree_view),
327 signals [TARGET_SELECTED], 0,
328 uri);
331 if (data->type == GBF_TREE_NODE_GROUP) {
332 g_signal_emit (G_OBJECT (tree_view),
333 signals [GROUP_SELECTED], 0,
334 uri);
336 g_free (uri);
339 static void on_node_loaded (AnjutaPmProject *sender, AnjutaProjectNode *node, gboolean complete, GError *error, GbfProjectView *view);
341 static void
342 dispose (GObject *object)
344 GbfProjectView *view;
346 view = GBF_PROJECT_VIEW (object);
348 if (view->filter)
350 g_object_unref (G_OBJECT (view->filter));
351 view->filter = NULL;
353 if (view->model)
355 AnjutaPmProject *old_project;
357 old_project = gbf_project_model_get_project (view->model);
358 if (old_project != NULL)
360 g_signal_handlers_disconnect_by_func (old_project, G_CALLBACK (on_node_loaded), view);
362 g_object_unref (G_OBJECT (view->model));
363 view->model = NULL;
366 G_OBJECT_CLASS (gbf_project_view_parent_class)->dispose (object);
369 static void
370 destroy (GtkWidget *object)
372 GbfProjectView *tree;
374 tree = GBF_PROJECT_VIEW (object);
376 if (GTK_WIDGET_CLASS (gbf_project_view_parent_class)->destroy)
377 (* GTK_WIDGET_CLASS (gbf_project_view_parent_class)->destroy) (object);
380 static GdkPixbuf*
381 get_icon (GFile *file)
383 const gchar** icon_names;
384 GtkIconInfo* icon_info;
385 GIcon* icon;
386 GdkPixbuf* pixbuf = NULL;
387 GFileInfo* file_info;
388 GError *error = NULL;
390 file_info = g_file_query_info (file,
391 G_FILE_ATTRIBUTE_STANDARD_ICON,
392 G_FILE_QUERY_INFO_NONE,
393 NULL,
394 &error);
396 if (file_info == NULL)
398 pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default(),
399 GTK_STOCK_MISSING_IMAGE,
400 ICON_SIZE,
401 GTK_ICON_LOOKUP_GENERIC_FALLBACK,
402 NULL);
404 else
406 icon = g_file_info_get_icon(file_info);
407 g_object_get (icon, "names", &icon_names, NULL);
408 icon_info = gtk_icon_theme_choose_icon (gtk_icon_theme_get_default(),
409 icon_names,
410 ICON_SIZE,
411 GTK_ICON_LOOKUP_GENERIC_FALLBACK);
412 pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
413 gtk_icon_info_free(icon_info);
414 g_object_unref (file_info);
417 return pixbuf;
420 static void
421 set_pixbuf (GtkTreeViewColumn *tree_column,
422 GtkCellRenderer *cell,
423 GtkTreeModel *model,
424 GtkTreeIter *iter,
425 gpointer user_data)
427 GbfTreeData *data = NULL;
428 GdkPixbuf *pixbuf = NULL;
430 gtk_tree_model_get (model, iter,
431 GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
432 g_return_if_fail (data != NULL);
433 /* FIXME: segmentation fault with shortcut when corresponding
434 * data is removed before the shortcut, so data = NULL.
435 * Perhaps we can add a GtkTreeReference to the shortcut
436 * node to remove the shortcut when the node is destroyed */
438 if ((data->type == GBF_TREE_NODE_SHORTCUT) && (data->shortcut != NULL))
440 data = data->shortcut;
442 switch (data->type) {
443 case GBF_TREE_NODE_SOURCE:
445 pixbuf = get_icon (data->source);
446 break;
448 case GBF_TREE_NODE_ROOT:
449 pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default(),
450 GTK_STOCK_OPEN,
451 ICON_SIZE,
452 GTK_ICON_LOOKUP_GENERIC_FALLBACK,
453 NULL);
454 break;
455 case GBF_TREE_NODE_GROUP:
456 pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default(),
457 GTK_STOCK_DIRECTORY,
458 ICON_SIZE,
459 GTK_ICON_LOOKUP_GENERIC_FALLBACK,
460 NULL);
461 break;
462 case GBF_TREE_NODE_TARGET:
464 pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default(),
465 GTK_STOCK_CONVERT,
466 ICON_SIZE,
467 GTK_ICON_LOOKUP_GENERIC_FALLBACK,
468 NULL);
469 break;
471 case GBF_TREE_NODE_MODULE:
473 pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default(),
474 GTK_STOCK_DND_MULTIPLE,
475 ICON_SIZE,
476 GTK_ICON_LOOKUP_GENERIC_FALLBACK,
477 NULL);
478 break;
480 case GBF_TREE_NODE_PACKAGE:
482 pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default(),
483 GTK_STOCK_DND,
484 ICON_SIZE,
485 GTK_ICON_LOOKUP_GENERIC_FALLBACK,
486 NULL);
487 break;
489 default:
490 /* Can reach this if type = GBF_TREE_NODE_SHORTCUT. It
491 * means a shortcut with the original data removed */
492 pixbuf = NULL;
495 g_object_set (GTK_CELL_RENDERER (cell), "pixbuf", pixbuf, NULL);
496 if (pixbuf)
497 g_object_unref (pixbuf);
500 static void
501 set_text (GtkTreeViewColumn *tree_column,
502 GtkCellRenderer *cell,
503 GtkTreeModel *model,
504 GtkTreeIter *iter,
505 gpointer user_data)
507 GbfTreeData *data;
509 gtk_tree_model_get (model, iter, GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
510 /* data can be NULL just after gtk_tree_store_insert before
511 calling gtk_tree_store_set */
512 g_object_set (GTK_CELL_RENDERER (cell), "text",
513 data == NULL ? "" : data->name, NULL);
516 static gboolean
517 search_equal_func (GtkTreeModel *model, gint column,
518 const gchar *key, GtkTreeIter *iter,
519 gpointer user_data)
521 GbfTreeData *data;
522 gboolean ret = TRUE;
524 gtk_tree_model_get (model, iter, GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
525 if (strncmp (data->name, key, strlen (key)) == 0)
526 ret = FALSE;
527 return ret;
530 static gboolean
531 draw (GtkWidget *widget, cairo_t *cr)
533 GtkTreeModel *view_model;
534 GtkTreeModel *model;
535 GtkTreeView *tree_view;
536 gint event_handled = FALSE;
538 if (GTK_WIDGET_CLASS (gbf_project_view_parent_class)->draw != NULL)
539 GTK_WIDGET_CLASS (gbf_project_view_parent_class)->draw (widget, cr);
541 tree_view = GTK_TREE_VIEW (widget);
542 view_model = gtk_tree_view_get_model (tree_view);
543 if (GTK_IS_TREE_MODEL_FILTER (view_model))
545 model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (view_model));
547 if (gtk_cairo_should_draw_window (cr, gtk_tree_view_get_bin_window (tree_view)) &&
548 model && GBF_IS_PROJECT_MODEL (model)) {
549 GtkTreePath *root;
550 GdkRectangle rect;
552 /* paint an horizontal ruler to separate the project
553 * tree from the target shortcuts */
555 root = gbf_project_model_get_project_root (GBF_PROJECT_MODEL (model));
556 if (root) {
557 if (view_model != model)
559 /* Convert path */
560 GtkTreePath *child_path;
562 child_path = gtk_tree_model_filter_convert_child_path_to_path (GTK_TREE_MODEL_FILTER (view_model), root);
563 gtk_tree_path_free (root);
564 root = child_path;
566 gtk_tree_view_get_background_area (
567 tree_view, root, gtk_tree_view_get_column (tree_view, 0), &rect);
568 gtk_paint_hline (gtk_widget_get_style (widget),
570 gtk_widget_get_state (widget),
571 widget,
573 rect.x, rect.x + rect.width,
574 rect.y);
575 gtk_tree_path_free (root);
579 return event_handled;
582 static void
583 gbf_project_view_class_init (GbfProjectViewClass *klass)
585 GObjectClass *g_object_class;
586 GtkWidgetClass *widget_class;
587 GtkTreeViewClass *tree_view_class;
589 g_object_class = G_OBJECT_CLASS (klass);
590 widget_class = GTK_WIDGET_CLASS (klass);
591 tree_view_class = GTK_TREE_VIEW_CLASS (klass);
593 g_object_class->dispose = dispose;
594 widget_class->destroy = destroy;
595 widget_class->draw = draw;
596 tree_view_class->row_activated = row_activated;
598 signals [URI_ACTIVATED] =
599 g_signal_new ("uri_activated",
600 GBF_TYPE_PROJECT_VIEW,
601 G_SIGNAL_RUN_LAST,
602 G_STRUCT_OFFSET (GbfProjectViewClass,
603 uri_activated),
604 NULL, NULL,
605 g_cclosure_marshal_VOID__STRING,
606 G_TYPE_NONE, 1, G_TYPE_STRING);
608 signals [TARGET_SELECTED] =
609 g_signal_new ("target_selected",
610 GBF_TYPE_PROJECT_VIEW,
611 G_SIGNAL_RUN_LAST,
612 G_STRUCT_OFFSET (GbfProjectViewClass,
613 target_selected),
614 NULL, NULL,
615 g_cclosure_marshal_VOID__POINTER,
616 G_TYPE_NONE, 1, G_TYPE_POINTER);
617 signals [GROUP_SELECTED] =
618 g_signal_new ("group_selected",
619 GBF_TYPE_PROJECT_VIEW,
620 G_SIGNAL_RUN_LAST,
621 G_STRUCT_OFFSET (GbfProjectViewClass,
622 group_selected),
623 NULL, NULL,
624 g_cclosure_marshal_VOID__POINTER,
625 G_TYPE_NONE, 1, G_TYPE_POINTER);
626 signals[NODE_LOADED] =
627 g_signal_new ("node-loaded",
628 GBF_TYPE_PROJECT_VIEW,
629 G_SIGNAL_RUN_LAST,
630 G_STRUCT_OFFSET (GbfProjectViewClass,
631 node_loaded),
632 NULL, NULL,
633 pm_cclosure_marshal_VOID__POINTER_BOOLEAN_BOXED,
634 G_TYPE_NONE, 3,
635 G_TYPE_POINTER,
636 G_TYPE_BOOLEAN,
637 G_TYPE_ERROR);
641 static gboolean
642 is_project_node_visible (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
644 GbfTreeData *data;
646 gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
647 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
648 -1);
650 return (data != NULL) && (gbf_tree_data_get_node (data) != NULL);
653 static void
654 gbf_project_view_init (GbfProjectView *tree)
656 GtkCellRenderer *renderer;
657 GtkTreeViewColumn *column;
658 static GtkTargetEntry row_targets[] = {
659 { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, 0 }
662 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree), FALSE);
663 gtk_tree_view_set_enable_search (GTK_TREE_VIEW (tree), TRUE);
664 gtk_tree_view_set_search_column (GTK_TREE_VIEW (tree), 0);
665 gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (tree),
666 search_equal_func,
667 NULL, NULL);
669 gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (tree),
670 GDK_BUTTON1_MASK,
671 row_targets,
672 G_N_ELEMENTS (row_targets),
673 GDK_ACTION_MOVE);
674 gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (tree),
675 row_targets,
676 G_N_ELEMENTS (row_targets),
677 GDK_ACTION_MOVE);
679 /* set renderer for files column. */
680 column = gtk_tree_view_column_new ();
681 renderer = gtk_cell_renderer_pixbuf_new ();
682 gtk_tree_view_column_pack_start (column, renderer, FALSE);
683 gtk_tree_view_column_set_cell_data_func (column, renderer, set_pixbuf, tree, NULL);
685 renderer = gtk_cell_renderer_text_new ();
686 gtk_tree_view_column_pack_start (column, renderer, FALSE);
687 gtk_tree_view_column_set_cell_data_func (column, renderer, set_text, tree, NULL);
689 gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
691 /* Create model */
692 tree->model = gbf_project_model_new (NULL);
693 tree->filter = GTK_TREE_MODEL_FILTER (pm_project_model_filter_new (GTK_TREE_MODEL (tree->model), NULL));
694 gtk_tree_model_filter_set_visible_func (tree->filter, is_project_node_visible, tree, NULL);
696 gtk_tree_view_set_model (GTK_TREE_VIEW (tree), GTK_TREE_MODEL (tree->filter));
699 GtkWidget *
700 gbf_project_view_new (void)
702 return GTK_WIDGET (g_object_new (GBF_TYPE_PROJECT_VIEW, NULL));
705 AnjutaProjectNode *
706 gbf_project_view_find_selected (GbfProjectView *view, AnjutaProjectNodeType type)
708 AnjutaProjectNode *node = NULL;
709 GbfTreeData *data;
711 g_return_val_if_fail (view != NULL, NULL);
712 g_return_val_if_fail (GBF_IS_PROJECT_VIEW (view), NULL);
714 data = gbf_project_view_get_first_selected (view, NULL);
715 if (data != NULL)
718 node = gbf_tree_data_get_node (data);
720 /* walk up the hierarchy searching for a node of the given type */
721 while ((node != NULL) && (type != ANJUTA_PROJECT_UNKNOWN) && (anjuta_project_node_get_node_type (node) != type))
723 node = anjuta_project_node_parent (node);
727 return node;
730 GbfTreeData *
731 gbf_project_view_get_first_selected (GbfProjectView *view, GtkTreeIter* selected)
733 GtkTreeSelection *selection;
734 GbfTreeData *data = NULL;
735 GtkTreeModel *model;
736 GList *list;
738 g_return_val_if_fail (view != NULL, NULL);
739 g_return_val_if_fail (GBF_IS_PROJECT_VIEW (view), NULL);
741 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
742 list = gtk_tree_selection_get_selected_rows(selection, &model);
743 if (list != NULL)
745 GtkTreeIter iter;
747 if (gtk_tree_model_get_iter (model, &iter, list->data))
749 if (selected)
751 if (GTK_IS_TREE_MODEL_FILTER (model))
753 GtkTreeIter child_iter;
755 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, &iter);
756 *selected = child_iter;
758 else
760 *selected = iter;
764 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
765 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
766 -1);
768 g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
769 g_list_free (list);
772 return data;
775 void
776 gbf_project_view_set_cursor_to_iter (GbfProjectView *view,
777 GtkTreeIter *selected)
779 GtkTreePath *path = NULL;
780 GtkTreeIter view_iter;
782 /* select node if we find it in the view*/
783 if ((selected != NULL) && gtk_tree_model_filter_convert_child_iter_to_iter (
784 GTK_TREE_MODEL_FILTER (view->filter), &view_iter, selected))
786 path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->filter), &view_iter);
788 else
790 /* Check if it is a shortcut */
791 if (selected !=NULL)
793 GbfTreeData *data;
795 gtk_tree_model_get (GTK_TREE_MODEL (view->model), selected,
796 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
797 -1);
799 if ((data != NULL) && (data->shortcut != NULL))
801 /* Select the corresponding node */
802 GtkTreeIter iter;
804 if (gbf_project_model_find_tree_data (view->model, &iter, data->shortcut))
806 if (gtk_tree_model_filter_convert_child_iter_to_iter (
807 GTK_TREE_MODEL_FILTER (view->filter), &view_iter, &iter))
809 path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->filter), &view_iter);
815 /* Try to select root node */
816 if (path == NULL)
818 GtkTreePath *root_path;
820 root_path = gbf_project_model_get_project_root (view->model);
821 if (root_path)
823 path = gtk_tree_model_filter_convert_child_path_to_path (
824 GTK_TREE_MODEL_FILTER (view->filter), root_path);
825 gtk_tree_path_free (root_path);
829 /* Take the first node */
830 if (path == NULL)
832 path = gtk_tree_path_new_first ();
836 if (path)
838 gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), path);
840 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
841 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view), path, NULL,
842 TRUE, 0.5, 0.0);
843 gtk_tree_path_free (path);
848 static void
849 on_each_get_data (GtkTreeModel *model,
850 GtkTreePath *path,
851 GtkTreeIter *iter,
852 gpointer user_data)
854 GList **selected = (GList **)user_data;
855 GbfTreeData *data;
857 gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
858 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
859 -1);
861 *selected = g_list_prepend (*selected, data);
864 GList *
865 gbf_project_view_get_all_selected (GbfProjectView *view)
867 GtkTreeSelection *selection;
868 GList *selected = NULL;
870 g_return_val_if_fail (view != NULL, FALSE);
871 g_return_val_if_fail (GBF_IS_PROJECT_VIEW (view), FALSE);
873 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
874 gtk_tree_selection_selected_foreach (selection, on_each_get_data, &selected);
876 return g_list_reverse (selected);
879 static void
880 on_each_get_iter (GtkTreeModel *model,
881 GtkTreePath *path,
882 GtkTreeIter *iter,
883 gpointer user_data)
885 GList **selected = (GList **)user_data;
887 *selected = g_list_prepend (*selected, gtk_tree_iter_copy (iter));
890 GList *
891 gbf_project_view_get_all_selected_iter (GbfProjectView *view)
893 GtkTreeSelection *selection;
894 GList *selected = NULL;
896 g_return_val_if_fail (view != NULL, FALSE);
897 g_return_val_if_fail (GBF_IS_PROJECT_VIEW (view), FALSE);
899 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
900 gtk_tree_selection_selected_foreach (selection, on_each_get_iter, &selected);
902 return g_list_reverse (selected);
905 static void
906 gbf_project_view_update_shortcut (GbfProjectView *view, AnjutaProjectNode *parent)
908 GtkTreeIter child;
909 gboolean valid;
911 /* Get all root node */
912 valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (view->model), &child, NULL);
914 while (valid)
916 GbfTreeData *data;
917 AnjutaProjectNode* old_node = NULL;
919 gtk_tree_model_get (GTK_TREE_MODEL (view->model), &child,
920 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
921 -1);
923 /* Shortcuts are always at the beginning */
924 if (data->type != GBF_TREE_NODE_SHORTCUT) break;
926 old_node = gbf_tree_data_get_node (data);
927 if (old_node == parent)
929 /* check children */
930 gbf_project_view_update_tree (view, parent, &child);
932 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (view->model), &child);
936 static gint
937 compare_node_name (gconstpointer a, gconstpointer b)
939 const AnjutaProjectNode *node = (const AnjutaProjectNode *)a;
940 const gchar *name = (const gchar *)b;
942 return g_strcmp0 (anjuta_project_node_get_name (node), name);
945 static GList *
946 list_visible_children (AnjutaProjectNode *parent)
948 AnjutaProjectNode *node;
949 GList *list = NULL;
951 for (node = anjuta_project_node_first_child (parent); node != NULL; node = anjuta_project_node_next_sibling (node))
953 if (anjuta_project_node_get_node_type (node) != ANJUTA_PROJECT_OBJECT)
955 list = g_list_prepend (list, node);
957 else
959 /* object node are hidden, get their children instead */
960 GList *children = list_visible_children (node);
962 children = g_list_reverse (children);
963 list = g_list_concat (children, list);
966 list = g_list_reverse (list);
968 return list;
971 void
972 gbf_project_view_update_tree (GbfProjectView *view, AnjutaProjectNode *parent, GtkTreeIter *iter)
974 GtkTreeIter child;
975 GList *node;
976 GList *nodes;
977 GbfTreeData *data = NULL;
979 /* Get all new nodes */
980 nodes = list_visible_children (parent);
982 /* walk the tree nodes */
983 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (view->model), &child, iter))
985 gboolean valid = TRUE;
987 while (valid) {
988 data = NULL;
989 AnjutaProjectNode* data_node = NULL;
991 /* Look for current node */
992 gtk_tree_model_get (GTK_TREE_MODEL (view->model), &child,
993 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
994 -1);
996 data_node = gbf_tree_data_get_node (data);
998 /* Skip shortcuts */
999 if (data->type == GBF_TREE_NODE_SHORTCUT)
1001 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (view->model), &child);
1002 continue;
1005 if (data->type == GBF_TREE_NODE_UNKNOWN)
1007 node = g_list_find_custom (nodes, data->name, compare_node_name);
1008 if (node != NULL)
1010 GtkTreePath *path;
1011 GtkTreePath *child_path;
1012 GtkTreeModelFilter *filter;
1013 gboolean expanded;
1014 gboolean shortcut;
1016 expanded = data->expanded;
1017 shortcut = data->has_shortcut;
1018 data_node = (AnjutaProjectNode *)node->data;
1019 gbf_tree_data_free (data);
1020 data = gbf_tree_data_new_node (data_node);
1021 gtk_tree_store_set (GTK_TREE_STORE (view->model), &child,
1022 GBF_PROJECT_MODEL_COLUMN_DATA, data,
1023 -1);
1025 /* Node already exist, remove it from the list */
1026 nodes = g_list_delete_link (nodes, node);
1028 /* Update shortcut */
1029 gbf_project_view_update_shortcut (view, data_node);
1031 /* update recursively */
1032 gbf_project_view_update_tree (view, data_node, &child);
1034 if (shortcut)
1036 gboolean expanded;
1037 GtkTreeIter iter;
1039 gbf_project_model_add_target_shortcut (view->model, &iter, data, NULL, &expanded);
1040 if (expanded)
1042 /* Expand shortcut */
1043 filter = GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
1044 path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->model), &iter);
1045 child_path = gtk_tree_model_filter_convert_child_path_to_path (filter, path);
1046 gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), child_path);
1047 gtk_tree_path_free (child_path);
1048 gtk_tree_path_free (path);
1051 data->expanded = expanded;
1052 if (expanded)
1054 filter = GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
1055 path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->model), &child);
1056 child_path = gtk_tree_model_filter_convert_child_path_to_path (filter, path);
1057 gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), child_path);
1058 expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), child_path);
1059 gtk_tree_path_free (child_path);
1060 gtk_tree_path_free (path);
1063 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (view->model), &child);
1065 else
1067 node = g_list_find (nodes, data_node);
1068 if (node != NULL)
1070 /* Node already exist, remove it from the list */
1071 nodes = g_list_delete_link (nodes, node);
1073 /* Update shortcut */
1074 gbf_project_view_update_shortcut (view, data_node);
1076 /* update recursively */
1077 gbf_project_view_update_tree (view, data_node, &child);
1079 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (view->model), &child);
1081 else
1083 /* Node has been deleted */
1084 valid = gbf_project_model_remove (view->model, &child);
1090 /* add the remaining sources, targets and groups */
1091 for (node = nodes; node; node = node->next)
1093 gbf_project_model_add_node (view->model, node->data, iter, 0);
1096 /* Expand parent, needed if the parent hasn't any children when it was created */
1097 if (iter != NULL)
1099 /* Check parent data */
1100 gtk_tree_model_get (GTK_TREE_MODEL (view->model), iter,
1101 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
1102 -1);
1103 if (data->expanded)
1105 GtkTreePath *path;
1106 GtkTreePath *child_path;
1107 GtkTreeModelFilter *filter;
1109 filter = GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
1110 path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->model), iter);
1111 child_path = gtk_tree_model_filter_convert_child_path_to_path (filter, path);
1112 gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), child_path);
1113 gtk_tree_path_free (child_path);
1114 gtk_tree_path_free (path);
1115 data->expanded = FALSE;
1120 /* Shorcuts functions
1121 *---------------------------------------------------------------------------*/
1123 void
1124 gbf_project_view_sort_shortcuts (GbfProjectView *view)
1126 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (view->model),
1127 GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
1128 GTK_SORT_ASCENDING);
1129 gbf_project_model_sort_shortcuts (view->model);
1130 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (view->model),
1131 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
1132 GTK_SORT_ASCENDING);
1136 GList *
1137 gbf_project_view_get_shortcut_list (GbfProjectView *view)
1139 GList *list = NULL;
1140 GtkTreeModel* model;
1141 gboolean valid;
1142 GtkTreeIter iter;
1144 model = GTK_TREE_MODEL (view->model);
1145 if (model != NULL)
1147 for (valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, NULL);
1148 valid == TRUE;
1149 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter))
1151 GbfTreeData *data;
1152 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
1153 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
1154 -1);
1156 if ((data->type == GBF_TREE_NODE_SHORTCUT) && (data->shortcut != NULL))
1158 GtkTreeIter iter;
1160 if (gbf_project_model_find_tree_data (view->model, &iter, data->shortcut))
1162 GString *str;
1163 GtkTreeIter child;
1165 str = g_string_new (NULL);
1168 GbfTreeData *data;
1170 child = iter;
1171 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
1172 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
1173 -1);
1175 if (data->node != NULL)
1177 if (str->len != 0) g_string_prepend (str, "//");
1178 g_string_prepend (str, anjuta_project_node_get_name (data->node));
1181 while (gtk_tree_model_iter_parent (model, &iter, &child));
1182 list = g_list_prepend (list, str->str);
1183 g_string_free (str, FALSE);
1187 list = g_list_reverse (list);
1190 return list;
1193 static void
1194 save_expanded_node (GtkTreeView *view, GtkTreePath *path, gpointer user_data)
1196 GList **list = (GList **)user_data;
1197 GtkTreeModel *model;
1198 GtkTreeIter iter;
1200 model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
1202 if (gtk_tree_model_get_iter (model, &iter, path))
1204 GString *str;
1205 GtkTreeIter child;
1207 str = g_string_new (NULL);
1210 GbfTreeData *data;
1212 child = iter;
1213 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
1214 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
1215 -1);
1217 if (data->node != NULL)
1219 if (str->len != 0) g_string_prepend (str, "//");
1220 g_string_prepend (str, anjuta_project_node_get_name (data->node));
1223 while (gtk_tree_model_iter_parent (model, &iter, &child));
1225 *list = g_list_prepend (*list, str->str);
1226 g_string_free (str, FALSE);
1230 GList *
1231 gbf_project_view_get_expanded_list (GbfProjectView *view)
1233 GList *list = NULL;
1235 gtk_tree_view_map_expanded_rows (GTK_TREE_VIEW (view), save_expanded_node, &list);
1236 list = g_list_reverse (list);
1238 return list;
1241 void
1242 gbf_project_view_remove_all_shortcut (GbfProjectView* view)
1244 GtkTreeModel* model;
1245 gboolean valid;
1246 GtkTreeIter iter;
1248 model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
1250 /* Remove all current shortcuts */
1251 for (valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, NULL);
1252 valid == TRUE;)
1254 GbfTreeData *data;
1256 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
1257 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
1258 -1);
1260 if (data->type == GBF_TREE_NODE_SHORTCUT)
1262 valid = gbf_project_model_remove (GBF_PROJECT_MODEL (model), &iter);
1264 else
1266 /* No more shortcut */
1267 break;
1272 void
1273 gbf_project_view_set_shortcut_list (GbfProjectView *view, GList *shortcuts)
1275 GList *item;
1277 gbf_project_model_set_default_shortcut (view->model, shortcuts == NULL);
1279 for (item = g_list_first (shortcuts); item != NULL; item = g_list_next (item))
1281 gchar *name = (gchar *)item->data;
1282 gchar *end;
1283 GtkTreeIter iter;
1284 GtkTreeIter *parent = NULL;
1288 end = strstr (name, "/" "/"); /* Avoid troubles with auto indent */
1289 if (end != NULL) *end = '\0';
1290 if (*name != '\0')
1292 if (!gbf_project_model_find_child_name (view->model, &iter, parent, name))
1294 GbfTreeData *data;
1296 /* Create proxy node */
1297 data = gbf_tree_data_new_proxy (name, FALSE);
1298 gtk_tree_store_append (GTK_TREE_STORE (view->model), &iter, parent);
1299 gtk_tree_store_set (GTK_TREE_STORE (view->model), &iter,
1300 GBF_PROJECT_MODEL_COLUMN_DATA, data,
1301 -1);
1302 if (end == NULL)
1304 data->has_shortcut = TRUE;
1306 /* Create another proxy at root level to keep shortcut order */
1307 data = gbf_tree_data_new_proxy (name, FALSE);
1308 gtk_tree_store_append (GTK_TREE_STORE (view->model), &iter, NULL);
1309 gtk_tree_store_set (GTK_TREE_STORE (view->model), &iter,
1310 GBF_PROJECT_MODEL_COLUMN_DATA, data,
1311 -1);
1314 else
1316 GbfTreeData *data;
1318 gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter,
1319 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
1320 -1);
1321 if (end == NULL) data->has_shortcut = TRUE;
1323 parent = &iter;
1325 if (end != NULL)
1327 *end = '/';
1328 name = end + 2;
1331 while (end != NULL);
1334 return;
1337 void
1338 gbf_project_view_set_expanded_list (GbfProjectView *view, GList *expand)
1340 GList *item;
1342 for (item = g_list_first (expand); item != NULL; item = g_list_next (item))
1344 gchar *name = (gchar *)item->data;
1345 gchar *end;
1346 GtkTreeIter iter;
1347 GtkTreeIter *parent = NULL;
1351 end = strstr (name, "/" "/"); /* Avoid troubles with auto indent */
1352 if (end != NULL) *end = '\0';
1353 if (*name != '\0')
1355 if (!gbf_project_model_find_child_name (view->model, &iter, parent, name))
1357 GbfTreeData *data;
1359 /* Create proxy node */
1360 data = gbf_tree_data_new_proxy (name, TRUE);
1361 gtk_tree_store_append (GTK_TREE_STORE (view->model), &iter, parent);
1362 gtk_tree_store_set (GTK_TREE_STORE (view->model), &iter,
1363 GBF_PROJECT_MODEL_COLUMN_DATA, data,
1364 -1);
1366 else
1368 GbfTreeData *data;
1370 gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter,
1371 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
1372 -1);
1373 data->expanded = TRUE;
1375 parent = &iter;
1377 if (end != NULL)
1379 *end = '/';
1380 name = end + 2;
1383 while (end != NULL);
1386 return;
1389 AnjutaProjectNode *
1390 gbf_project_view_get_node_from_iter (GbfProjectView *view, GtkTreeIter *iter)
1392 return gbf_project_model_get_node (view->model, iter);
1395 AnjutaProjectNode *
1396 gbf_project_view_get_node_from_file (GbfProjectView *view, AnjutaProjectNodeType type, GFile *file)
1398 GtkTreeIter iter;
1399 AnjutaProjectNode *node = NULL;
1401 if (gbf_project_model_find_file (view->model, &iter, NULL, type, file))
1404 node = gbf_project_model_get_node (view->model, &iter);
1407 return NULL;
1410 gboolean
1411 gbf_project_view_remove_data (GbfProjectView *view, GbfTreeData *data, GError **error)
1413 GtkTreeIter iter;
1415 if (gbf_project_model_find_tree_data (view->model, &iter, data))
1417 gbf_project_model_remove (view->model, &iter);
1419 return TRUE;
1421 else
1423 return FALSE;
1427 static void
1428 on_node_loaded (AnjutaPmProject *sender, AnjutaProjectNode *node, gboolean complete, GError *error, GbfProjectView *view)
1430 if (error != NULL)
1432 g_warning ("unable to load node");
1433 g_signal_emit (G_OBJECT (view), NODE_LOADED, 0, NULL, complete, error);
1435 else
1437 GtkTreeIter iter;
1438 gboolean found;
1440 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (view->model),
1441 GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
1442 GTK_SORT_ASCENDING);
1444 found = gbf_project_model_find_node (view->model, &iter, NULL, node);
1445 if (!found)
1447 if (anjuta_project_node_get_node_type (node) != ANJUTA_PROJECT_ROOT)
1449 g_critical ("Unable to find node %s", anjuta_project_node_get_name (node));
1451 else
1453 GtkTreePath *path;
1454 GtkTreePath *child_path;
1455 GtkTreeModelFilter *filter;
1457 if (!gbf_project_model_find_child_name (view->model, &iter, NULL, anjuta_project_node_get_name (node)))
1459 gbf_project_model_add_node (view->model, node, NULL, 0);
1460 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (view->model), &iter);
1462 else
1464 GbfTreeData *data;
1466 gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter,
1467 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
1468 -1);
1469 if (data->type == GBF_TREE_NODE_UNKNOWN)
1471 /* Replace with real node */
1472 GbfTreeData *new_data;
1474 new_data = gbf_tree_data_new_node (node);
1475 gtk_tree_store_set (GTK_TREE_STORE (view->model), &iter,
1476 GBF_PROJECT_MODEL_COLUMN_DATA, new_data,
1477 -1);
1478 gbf_tree_data_free (data);
1480 gbf_project_view_update_tree (view, node, &iter);
1483 /* Expand root node */
1484 path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->model), &iter);
1485 filter = GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
1486 child_path = gtk_tree_model_filter_convert_child_path_to_path (filter, path);
1487 if (child_path != NULL) gtk_tree_view_expand_row (GTK_TREE_VIEW (view), child_path, FALSE);
1488 gtk_tree_path_free (child_path);
1489 gtk_tree_path_free (path);
1492 else
1494 gbf_project_view_update_tree (view, node, &iter);
1496 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (view->model),
1497 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
1498 GTK_SORT_ASCENDING);
1500 g_signal_emit (G_OBJECT (view), signals[NODE_LOADED], 0, found ? &iter : NULL, complete, NULL);
1503 if (complete)
1505 // Add shortcut for all new primary targets
1506 gbf_project_model_set_default_shortcut (view->model, TRUE);
1511 void
1512 gbf_project_view_set_project (GbfProjectView *view, AnjutaPmProject *project)
1514 AnjutaPmProject *old_project;
1516 old_project = gbf_project_model_get_project (view->model);
1517 if (old_project != NULL)
1519 g_signal_handlers_disconnect_by_func (old_project, G_CALLBACK (on_node_loaded), view);
1522 g_signal_connect (project, "loaded", G_CALLBACK (on_node_loaded), view);
1524 gbf_project_model_set_project (view->model, project);
1527 void
1528 gbf_project_view_set_parent_view (GbfProjectView *view,
1529 GbfProjectView *parent,
1530 GtkTreePath *root)
1533 if (view->model != NULL) g_object_unref (view->model);
1534 if (view->filter != NULL) g_object_unref (view->model);
1536 view->model = g_object_ref (parent->model);
1537 view->filter = GTK_TREE_MODEL_FILTER (pm_project_model_filter_new (GTK_TREE_MODEL (view->model), root));
1538 gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (view->filter));
1541 void
1542 gbf_project_view_set_visible_func (GbfProjectView *view,
1543 GtkTreeModelFilterVisibleFunc func,
1544 gpointer data,
1545 GDestroyNotify destroy)
1547 if (func == NULL)
1549 gtk_tree_model_filter_set_visible_func (view->filter, is_project_node_visible, view, NULL);
1551 else
1553 gtk_tree_model_filter_set_visible_func (view->filter, func, data, destroy);
1555 gtk_tree_model_filter_refilter (view->filter);
1558 gboolean
1559 gbf_project_view_find_file (GbfProjectView *view, GtkTreeIter* iter, GFile *file, GbfTreeNodeType type)
1561 return gbf_project_model_find_file (view->model, iter, NULL, type, file);
1564 GbfProjectModel *
1565 gbf_project_view_get_model (GbfProjectView *view)
1567 return view->model;
1570 gboolean
1571 gbf_project_view_get_project_root (GbfProjectView *view, GtkTreeIter *iter)
1573 GtkTreeModel *model;
1574 GtkTreeModel *view_model;
1575 GtkTreePath *path;
1576 gboolean ok = FALSE;
1578 model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
1579 view_model = model;
1580 if (GTK_IS_TREE_MODEL_FILTER (model))
1582 model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (view_model));
1585 path = gbf_project_model_get_project_root (GBF_PROJECT_MODEL (model));
1586 if (path)
1588 ok = gtk_tree_model_get_iter (model, iter, path);
1589 gtk_tree_path_free (path);
1592 return ok;