1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 * Copyright (C) 2002 Dave Camp
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
20 * Authors: Dave Camp <dave@ximian.com>
21 * Gustavo Giráldez <gustavo.giraldez@gmx.net>
29 #include <glib-object.h>
31 #include <glib/gi18n.h>
36 #include "project-util.h"
37 #include "project-model.h"
40 struct _GbfProjectModelPrivate
{
41 AnjutaPmProject
*proj
;
42 gulong project_updated_handler
;
44 GtkTreeRowReference
*root
;
45 GtkTreeRowReference
*root_group
;
48 gboolean default_shortcut
; /* Add shortcut for each primary node */
57 /* Function prototypes ------------- */
59 static void gbf_project_model_class_init (GbfProjectModelClass
*klass
);
60 static void gbf_project_model_instance_init (GbfProjectModel
*tree
);
62 static void load_project (GbfProjectModel
*model
,
63 AnjutaPmProject
*proj
);
64 static void insert_empty_node (GbfProjectModel
*model
);
65 static void unload_project (GbfProjectModel
*model
);
67 static gint
default_sort_func (GtkTreeModel
*model
,
72 static GtkTreeStoreClass
*parent_class
= NULL
;
75 /* Implementation ---------------- */
77 /* Helper functions */
79 /* Type & interfaces initialization */
82 gbf_project_model_class_init_trampoline (gpointer klass
,
85 parent_class
= g_type_class_ref (GTK_TYPE_TREE_STORE
);
86 gbf_project_model_class_init (klass
);
90 gbf_project_model_get_type (void)
92 static GType object_type
= 0;
93 if (object_type
== 0) {
94 static const GTypeInfo object_info
= {
95 sizeof (GbfProjectModelClass
),
97 NULL
, /* base_finalize */
98 gbf_project_model_class_init_trampoline
,
99 NULL
, /* class_finalize */
100 NULL
, /* class_data */
101 sizeof (GbfProjectModel
),
103 (GInstanceInitFunc
) gbf_project_model_instance_init
106 object_type
= g_type_register_static (
107 GTK_TYPE_TREE_STORE
, "GbfProjectModel",
114 get_property (GObject
*object
,
119 GbfProjectModel
*model
= GBF_PROJECT_MODEL (object
);
123 g_value_set_pointer (value
, model
->priv
->proj
);
126 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
132 set_property (GObject
*object
,
137 GbfProjectModel
*model
= GBF_PROJECT_MODEL (object
);
141 gbf_project_model_set_project (model
, g_value_get_pointer (value
));
144 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
150 dispose (GObject
*obj
)
152 GbfProjectModel
*model
= GBF_PROJECT_MODEL (obj
);
154 if (model
->priv
->proj
) {
155 unload_project (model
);
158 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
162 finalize (GObject
*obj
)
164 GbfProjectModel
*model
= GBF_PROJECT_MODEL (obj
);
166 g_free (model
->priv
);
168 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
172 gbf_project_model_class_init (GbfProjectModelClass
*klass
)
174 parent_class
= g_type_class_peek_parent (klass
);
176 G_OBJECT_CLASS (klass
)->dispose
= dispose
;
177 G_OBJECT_CLASS (klass
)->finalize
= finalize
;
178 G_OBJECT_CLASS (klass
)->get_property
= get_property
;
179 G_OBJECT_CLASS (klass
)->set_property
= set_property
;
181 g_object_class_install_property
182 (G_OBJECT_CLASS (klass
), PROP_PROJECT
,
183 g_param_spec_pointer ("project",
185 _("GbfProject Object"),
190 gbf_project_model_instance_init (GbfProjectModel
*model
)
192 static GType types
[GBF_PROJECT_MODEL_NUM_COLUMNS
];
194 types
[GBF_PROJECT_MODEL_COLUMN_DATA
] = G_TYPE_POINTER
;
196 gtk_tree_store_set_column_types (GTK_TREE_STORE (model
),
197 GBF_PROJECT_MODEL_NUM_COLUMNS
,
200 model
->priv
= g_new0 (GbfProjectModelPrivate
, 1);
201 model
->priv
->default_shortcut
= TRUE
;
203 /* sorting function */
204 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model
),
207 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model
),
208 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID
,
211 insert_empty_node (model
);
214 /* Model data functions ------------ */
216 /* Remove node without checking its shortcuts */
218 gbf_project_model_remove_children (GbfProjectModel
*model
, GtkTreeIter
*iter
)
224 /* Free all children */
225 valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &child
, iter
);
228 valid
= gbf_project_model_remove_children (model
, &child
);
230 /* Free children node */
231 gtk_tree_model_get (GTK_TREE_MODEL (model
), &child
,
232 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
,
234 valid
= gtk_tree_store_remove (GTK_TREE_STORE (model
), &child
);
235 if (data
!= NULL
) gbf_tree_data_free (data
);
242 gbf_project_model_invalidate_children (GbfProjectModel
*model
, GtkTreeIter
*iter
)
248 /* Mark all children as invalid */
249 valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &child
, iter
);
252 valid
= gbf_project_model_invalidate_children (model
, &child
);
254 /* Invalidate children node */
255 gtk_tree_model_get (GTK_TREE_MODEL (model
), &child
,
256 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
,
258 gbf_tree_data_invalidate (data
);
260 valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &child
);
267 gbf_project_model_remove_invalid_shortcut (GbfProjectModel
*model
, GtkTreeIter
*iter
)
273 /* Get all shortcut */
274 valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &child
, iter
);
277 gtk_tree_model_get (GTK_TREE_MODEL (model
), &child
,
278 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
,
280 /* Shortcuts are always at the beginning */
281 if (data
->type
!= GBF_TREE_NODE_SHORTCUT
) break;
283 if (data
->shortcut
->type
== GBF_TREE_NODE_INVALID
)
285 gbf_project_model_remove_children (model
, &child
);
286 valid
= gtk_tree_store_remove (GTK_TREE_STORE (model
), &child
);
287 if (data
!= NULL
) gbf_tree_data_free (data
);
291 gbf_project_model_remove_invalid_shortcut (model
, &child
);
292 valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &child
);
300 *---------------------------------------------------------------------------*/
303 sort_by_name (GtkTreeModel
*model
,
308 GbfTreeData
*data_a
, *data_b
;
310 gtk_tree_model_get (model
, iter_a
,
311 GBF_PROJECT_MODEL_COLUMN_DATA
, &data_a
,
313 gtk_tree_model_get (model
, iter_b
,
314 GBF_PROJECT_MODEL_COLUMN_DATA
, &data_b
,
317 return strcmp (data_a
->name
, data_b
->name
);
322 gbf_project_model_merge (GtkTreeModel
*model
,
326 GtkTreeIterCompareFunc compare_func
,
332 if (gtk_tree_model_get_iter (model
, &left
, begin
) &&
333 gtk_tree_model_get_iter (model
, &right
, half
))
339 /* Get number of elements in both list */
340 ll
= (gtk_tree_path_get_indices_with_depth (half
, &depth
)[depth
- 1]
341 - gtk_tree_path_get_indices_with_depth (begin
, &depth
)[depth
- 1]);
342 lr
= (gtk_tree_path_get_indices_with_depth (end
, &depth
)[depth
- 1]
343 - gtk_tree_path_get_indices_with_depth (half
, &depth
)[depth
- 1]);
347 if (compare_func (model
, &left
, &right
, user_data
) <= 0)
349 gtk_tree_model_iter_next (model
, &left
);
357 gtk_tree_model_iter_next (model
, &right
);
359 gtk_tree_store_move_before (GTK_TREE_STORE (model
), &iter
, &left
);
365 /* sort using merge sort */
367 gbf_project_model_sort (GtkTreeModel
*model
,
370 GtkTreeIterCompareFunc compare_func
,
376 /* Empty list are sorted */
377 if (gtk_tree_path_compare (begin
, end
) >= 0)
382 /* Split the list in two */
383 half
= gtk_tree_path_copy (begin
);
384 gtk_tree_path_up (half
);
385 gtk_tree_path_append_index (half
, (gtk_tree_path_get_indices_with_depth (begin
, &depth
)[depth
-1] +
386 gtk_tree_path_get_indices_with_depth (end
, &depth
)[depth
- 1]) / 2);
388 /* List with a single element are sorted too */
389 if (gtk_tree_path_compare (begin
, half
) < 0)
391 gbf_project_model_sort (model
, begin
, half
, compare_func
, user_data
);
392 gbf_project_model_sort (model
, half
, end
, compare_func
, user_data
);
393 gbf_project_model_merge (model
, begin
, half
, end
, compare_func
, user_data
);
396 gtk_tree_path_free (half
);
401 *---------------------------------------------------------------------------*/
404 gbf_project_model_remove (GbfProjectModel
*model
, GtkTreeIter
*iter
)
410 /* Check if node is not a shortcut. In this case we need to remove
411 * all shortcuts first. */
412 gtk_tree_model_get (GTK_TREE_MODEL (model
), iter
,
413 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
,
415 if (data
->type
!= GBF_TREE_NODE_SHORTCUT
)
417 /* Mark all nodes those will be removed */
418 gbf_project_model_invalidate_children (model
, iter
);
419 gbf_tree_data_invalidate (data
);
421 gbf_project_model_remove_invalid_shortcut (model
, NULL
);
424 /* Free all children */
425 valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &child
, iter
);
428 valid
= gbf_project_model_remove_children (model
, &child
);
431 /* Free parent node */
432 valid
= gtk_tree_store_remove (GTK_TREE_STORE (model
), iter
);
433 if (data
!= NULL
) gbf_tree_data_free (data
);
440 gbf_project_model_clear (GbfProjectModel
*model
)
445 valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &child
, NULL
);
448 valid
= gbf_project_model_remove (model
, &child
);
453 default_sort_func (GtkTreeModel
*model
,
458 GbfTreeData
*data_a
, *data_b
;
460 gboolean unsorted_a
, unsorted_b
;
462 gtk_tree_model_get (model
, iter_a
,
463 GBF_PROJECT_MODEL_COLUMN_DATA
, &data_a
,
465 gtk_tree_model_get (model
, iter_b
,
466 GBF_PROJECT_MODEL_COLUMN_DATA
, &data_b
,
469 unsorted_a
= (data_a
->type
== GBF_TREE_NODE_SHORTCUT
) || (data_a
->type
== GBF_TREE_NODE_UNKNOWN
) || (data_a
->is_shortcut
);
470 unsorted_b
= (data_b
->type
== GBF_TREE_NODE_SHORTCUT
) || (data_b
->type
== GBF_TREE_NODE_UNKNOWN
) || (data_b
->is_shortcut
);
471 if (unsorted_a
&& unsorted_b
) {
475 /* special case: the order of shortcuts is
476 * user customizable */
477 for (valid
= gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model
), &iter
);
479 valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &iter
))
483 gtk_tree_model_get (model
, &iter
,
484 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
,
486 if (data
== data_a
) {
491 else if (data
== data_b
) {
498 } else if (unsorted_a
&& !unsorted_b
) {
501 } else if (!unsorted_a
&& unsorted_b
) {
504 } else if (data_a
->type
== data_b
->type
) {
505 retval
= strcmp (data_a
->name
, data_b
->name
);
508 /* assume a->b and check for the opposite cases */
510 retval
= data_a
->type
< data_b
->type
? -1 : 1;
517 gbf_project_model_add_target_shortcut (GbfProjectModel
*model
,
518 GtkTreeIter
*shortcut
,
520 GtkTreePath
*before_path
,
523 AnjutaProjectNode
*node
;
524 GtkTreeIter iter
, sibling
;
525 GtkTreePath
*root_path
;
527 AnjutaProjectNode
*parent
;
528 gboolean valid
= FALSE
;
533 if (expanded
!= NULL
) *expanded
= FALSE
;
535 root_path
= gbf_project_model_get_project_root (model
);
536 if ((before_path
== NULL
) && (target
->type
!= GBF_TREE_NODE_SHORTCUT
))
538 /* Check is a proxy node is not already existing. It is used to
539 * save the shortcut order */
541 for (valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &iter
, NULL
);
543 valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &iter
))
547 /* Look for current node */
548 gtk_tree_model_get (GTK_TREE_MODEL (model
), &iter
,
549 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
,
552 if (((data
->type
== GBF_TREE_NODE_UNKNOWN
) || (data
->type
== GBF_TREE_NODE_SHORTCUT
)) && (g_strcmp0 (target
->name
, data
->name
) == 0))
554 /* Find already existing node and replace it */
555 if (expanded
!= NULL
) *expanded
= data
->expanded
;
556 gbf_tree_data_free (data
);
558 data
= gbf_tree_data_new_shortcut (target
);
559 gtk_tree_store_set (GTK_TREE_STORE (model
), &iter
,
560 GBF_PROJECT_MODEL_COLUMN_DATA
, data
,
568 /* check before_path */
569 if ((before_path
== NULL
) ||
570 gtk_tree_path_get_depth (before_path
) > 1 ||
571 gtk_tree_path_compare (before_path
, root_path
) > 0)
573 before_path
= root_path
;
576 /* get the tree iter for the row before which to insert the shortcut */
577 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model
), &sibling
, before_path
)) {
578 gtk_tree_path_free (root_path
);
582 if (target
->type
!= GBF_TREE_NODE_SHORTCUT
)
584 data
= gbf_tree_data_new_shortcut (target
);
590 gtk_tree_store_insert_before (GTK_TREE_STORE (model
), &iter
, NULL
, &sibling
);
591 gtk_tree_store_set (GTK_TREE_STORE (model
), &iter
,
592 GBF_PROJECT_MODEL_COLUMN_DATA
, data
,
597 parent
= gbf_tree_data_get_node (target
);
598 for (node
= anjuta_project_node_first_child (parent
); node
; node
= anjuta_project_node_next_sibling (node
))
599 gbf_project_model_add_node (model
, node
, &iter
, 0);
601 gtk_tree_path_free (root_path
);
603 if (shortcut
) *shortcut
= iter
;
607 gbf_project_model_move_target_shortcut (GbfProjectModel
*model
,
609 GbfTreeData
*shortcut
,
610 GtkTreePath
*before_path
)
612 AnjutaProjectNode
*node
;
614 GtkTreePath
*root_path
;
615 GtkTreePath
*src_path
;
616 AnjutaProjectNode
*parent
;
621 root_path
= gbf_project_model_get_project_root (model
);
623 /* check before_path */
625 gtk_tree_path_get_depth (before_path
) > 1)
627 /* Missing destination path, use root path */
628 before_path
= root_path
;
630 else if (gtk_tree_path_compare (before_path
, root_path
) > 0)
632 /* Destination path outside shortcut are, remove shortcut */
633 gbf_project_model_remove (model
, iter
);
634 gtk_tree_path_free (root_path
);
639 /* get the tree iter for the row before which to insert the shortcut */
640 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model
), &sibling
, before_path
)) {
641 gtk_tree_path_free (root_path
);
645 src_path
= gtk_tree_model_get_path (GTK_TREE_MODEL (model
), iter
);
646 if (gtk_tree_path_compare (src_path
, before_path
) != 0)
648 gtk_tree_store_remove (GTK_TREE_STORE (model
), iter
);
649 gtk_tree_store_insert_before (GTK_TREE_STORE (model
), iter
, NULL
, &sibling
);
650 gtk_tree_store_set (GTK_TREE_STORE (model
), iter
,
651 GBF_PROJECT_MODEL_COLUMN_DATA
, shortcut
,
655 parent
= gbf_tree_data_get_node (shortcut
->shortcut
);
656 for (node
= anjuta_project_node_first_child (parent
); node
; node
= anjuta_project_node_next_sibling (node
))
657 gbf_project_model_add_node (model
, node
, iter
, 0);
661 gtk_tree_path_free (src_path
);
662 gtk_tree_path_free (root_path
);
667 gbf_project_model_add_node (GbfProjectModel
*model
,
668 AnjutaProjectNode
*node
,
670 AnjutaProjectNodeType only_type
)
673 GbfTreeData
*data
= NULL
;
674 AnjutaProjectNode
*child
;
675 AnjutaProjectNodeType child_types
[] = {ANJUTA_PROJECT_GROUP
,
676 ANJUTA_PROJECT_TARGET
,
677 ANJUTA_PROJECT_SOURCE
,
678 ANJUTA_PROJECT_MODULE
,
679 ANJUTA_PROJECT_PACKAGE
,
681 AnjutaProjectNodeType
*type
;
683 if (node
== NULL
) return;
686 if (anjuta_project_node_get_full_type (node
) & ANJUTA_PROJECT_FRAME
) return;
688 if ((only_type
== 0) || (anjuta_project_node_get_node_type (node
) == only_type
))
690 if (anjuta_project_node_get_node_type (node
) != ANJUTA_PROJECT_OBJECT
)
692 data
= gbf_tree_data_new_node (node
);
693 gtk_tree_store_append (GTK_TREE_STORE (model
), &iter
, parent
);
694 gtk_tree_store_set (GTK_TREE_STORE (model
), &iter
,
695 GBF_PROJECT_MODEL_COLUMN_DATA
, data
,
705 for (type
= child_types
; *type
!= 0; type
++)
707 for (child
= anjuta_project_node_first_child (node
); child
!= NULL
; child
= anjuta_project_node_next_sibling (child
))
709 gbf_project_model_add_node (model
, child
, &iter
, *type
);
713 /* Add shortcut if needed */
714 if ((data
!= NULL
) &&
715 model
->priv
->default_shortcut
&&
716 (anjuta_project_node_get_node_type (node
) == ANJUTA_PROJECT_TARGET
) &&
717 (anjuta_project_node_get_full_type (node
) & ANJUTA_PROJECT_PRIMARY
))
719 gbf_project_model_add_target_shortcut (model
, NULL
, data
, NULL
, NULL
);
722 else if (anjuta_project_node_get_node_type (node
) == ANJUTA_PROJECT_OBJECT
)
724 /* Add only children */
725 for (child
= anjuta_project_node_first_child (node
); child
!= NULL
; child
= anjuta_project_node_next_sibling (child
))
727 gbf_project_model_add_node (model
, child
, parent
, only_type
);
733 load_project (GbfProjectModel
*model
, AnjutaPmProject
*proj
)
735 model
->priv
->proj
= proj
;
738 gbf_project_model_add_node (model
, anjuta_pm_project_get_root (proj
), NULL
, 0);
742 insert_empty_node (GbfProjectModel
*model
)
745 GbfTreeData
*empty_node
;
747 empty_node
= gbf_tree_data_new_string (_("No project loaded"));
749 gtk_tree_store_append (GTK_TREE_STORE (model
), &iter
, NULL
);
750 gtk_tree_store_set (GTK_TREE_STORE (model
), &iter
,
751 GBF_PROJECT_MODEL_COLUMN_DATA
, empty_node
,
756 unload_project (GbfProjectModel
*model
)
758 if (model
->priv
->proj
) {
759 gtk_tree_row_reference_free (model
->priv
->root
);
760 model
->priv
->root
= NULL
;
762 gbf_project_model_clear (model
);
764 g_list_free (model
->priv
->shortcuts
);
765 model
->priv
->shortcuts
= NULL
;
767 //g_signal_handler_disconnect (anjuta_pm_project_get_project (model->priv->proj),
768 // model->priv->project_updated_handler);
769 //model->priv->project_updated_handler = 0;
770 model
->priv
->proj
= NULL
;
772 insert_empty_node (model
);
777 recursive_find_tree_data (GtkTreeModel
*model
,
782 gboolean retval
= FALSE
;
788 GbfTreeData
*tmp_data
;
790 gtk_tree_model_get (model
, &tmp
,
791 GBF_PROJECT_MODEL_COLUMN_DATA
, &tmp_data
, -1);
792 if (gbf_tree_data_equal (tmp_data
, data
))
798 if (gtk_tree_model_iter_children (model
, &child
, &tmp
)) {
799 if (recursive_find_tree_data (model
, &child
, data
)) {
805 } while (!retval
&& gtk_tree_model_iter_next (model
, &tmp
));
811 gbf_project_model_find_tree_data (GbfProjectModel
*model
,
815 GtkTreeIter tmp_iter
;
816 gboolean retval
= FALSE
;
818 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model
), &tmp_iter
)) {
819 if (recursive_find_tree_data (GTK_TREE_MODEL (model
), &tmp_iter
, data
)) {
828 /* Can return shortcut node if exist */
830 gbf_project_model_find_file (GbfProjectModel
*model
,
833 GbfTreeNodeType type
,
839 /* Search for direct children */
840 for (valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &iter
, parent
); valid
== TRUE
; valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &iter
))
844 gtk_tree_model_get (GTK_TREE_MODEL (model
), &iter
,
845 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
, -1);
847 if (gbf_tree_data_equal_file (data
, type
, file
))
854 /* Search for children of children */
857 for (valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &iter
, parent
); valid
== TRUE
; valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &iter
))
859 if (gbf_project_model_find_file (model
, found
, &iter
, type
, file
)) break;
867 gbf_project_model_find_node (GbfProjectModel
*model
,
870 AnjutaProjectNode
*node
)
875 /* Search for direct children */
876 for (valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &iter
, parent
); valid
== TRUE
; valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &iter
))
880 gtk_tree_model_get (GTK_TREE_MODEL (model
), &iter
,
881 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
, -1);
883 if (node
== gbf_tree_data_get_node (data
))
890 /* Search for children of children */
893 for (valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &iter
, parent
); valid
== TRUE
; valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &iter
))
895 if (gbf_project_model_find_node (model
, found
, &iter
, node
)) break;
902 /* Can return shortcut node if exist */
904 gbf_project_model_find_child_name (GbfProjectModel
*model
,
912 /* Search for direct children only */
913 for (valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &iter
, parent
); valid
== TRUE
; valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &iter
))
917 gtk_tree_model_get (GTK_TREE_MODEL (model
), &iter
,
918 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
, -1);
920 if (gbf_tree_data_equal_name (data
, name
))
931 gbf_project_model_new (AnjutaPmProject
*project
)
933 return GBF_PROJECT_MODEL (g_object_new (GBF_TYPE_PROJECT_MODEL
,
939 gbf_project_model_set_project (GbfProjectModel
*model
, AnjutaPmProject
*project
)
941 g_return_if_fail (model
!= NULL
&& GBF_IS_PROJECT_MODEL (model
));
943 if (model
->priv
->proj
!= project
)
945 //unload_project (model);
947 /* project can be NULL */
949 load_project (model
, project
);
954 gbf_project_model_get_project (GbfProjectModel
*model
)
956 g_return_val_if_fail (model
!= NULL
&& GBF_IS_PROJECT_MODEL (model
), NULL
);
958 return model
->priv
->proj
;
962 gbf_project_model_get_project_root (GbfProjectModel
*model
)
964 GtkTreePath
*path
= NULL
;
966 g_return_val_if_fail (GBF_IS_PROJECT_MODEL (model
), NULL
);
968 if (model
->priv
->root
== NULL
)
973 /* Search root group */
974 for (valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &iter
, NULL
); valid
; valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &iter
))
978 gtk_tree_model_get (GTK_TREE_MODEL (model
), &iter
,
979 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
,
982 if (data
->type
== GBF_TREE_NODE_ROOT
)
984 path
= gtk_tree_model_get_path (GTK_TREE_MODEL (model
), &iter
);
985 model
->priv
->root
= gtk_tree_row_reference_new (GTK_TREE_MODEL (model
), path
);
991 path
= gtk_tree_row_reference_get_path (model
->priv
->root
);
998 gbf_project_model_get_node (GbfProjectModel
*model
,
1001 GbfTreeData
*data
= NULL
;
1003 gtk_tree_model_get (GTK_TREE_MODEL (model
), iter
,
1004 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
,
1007 return gbf_tree_data_get_node (data
);
1011 gbf_project_model_set_default_shortcut (GbfProjectModel
*model
,
1014 model
->priv
->default_shortcut
= enable
;
1018 gbf_project_model_sort_shortcuts (GbfProjectModel
*model
)
1022 /* Get all shortcut */
1023 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (model
), &iter
, NULL
))
1029 begin
= gtk_tree_model_get_path (GTK_TREE_MODEL (model
), &iter
);
1034 gtk_tree_model_get (GTK_TREE_MODEL (model
), &iter
,
1035 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
,
1038 /* Shortcuts are always at the beginning */
1039 if (data
->type
!= GBF_TREE_NODE_SHORTCUT
) break;
1041 valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (model
), &iter
);
1047 end
= gtk_tree_model_get_path (GTK_TREE_MODEL (model
), &iter
);
1048 gbf_project_model_sort (GTK_TREE_MODEL (model
), begin
, end
, sort_by_name
, NULL
);
1049 gtk_tree_path_free (begin
);
1050 gtk_tree_path_free (end
);