1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Sébastien Granjoux 2009 <seb.sfo@free.fr>
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "anjuta-project.h"
22 #include "anjuta-debug.h"
23 #include "anjuta-marshal.h"
24 #include "anjuta-enum-types.h"
29 * SECTION:anjuta-project
30 * @title: Anjuta project
31 * @short_description: Anjuta project
33 * @stability: Unstable
34 * @include: libanjuta/anjuta-project.h
36 * A project in Anjuta is represented by a tree. There are six kinds of node.
38 * The root node is the parent of all other nodes, it can implement
39 * IAnjutaProject interface and represent the project itself but it is not
42 * A module node represents a module in autotools project, it is a group of
45 * A package node represents a package in autotools project, it is library.
47 * A group node is used to group several target or source, it can represent
48 * a directory by example.
50 * A target node represents an object file defined explicitely.
51 * There are different kinds of target: program, library...
52 * A target have as children all source needed to build it.
54 * A source node represents a source file. These are lead of the tree, a source
55 * node cannot have children.
57 * All these nodes are base objects. They have derived in each project backend
58 * to provide more specific information.
62 *---------------------------------------------------------------------------*/
64 /* Implement Boxed type
65 *---------------------------------------------------------------------------*/
68 * anjuta_project_property_new:
69 * @value: (transfer none): Value
70 * @name: (allow-none) (transfer none): Optional name used by map properties
71 * @user_data: (allow-none) (transfer full): Optional user data
73 * Returns: (transfer full):
75 AnjutaProjectProperty
*
76 anjuta_project_property_new (const gchar
*value
,
80 AnjutaProjectProperty
*prop
= g_slice_new0(AnjutaProjectProperty
);
82 prop
->value
= g_strdup (value
);
83 prop
->name
= name
!= NULL
? g_strdup (name
) : NULL
;
84 prop
->user_data
= user_data
;
90 AnjutaProjectProperty
*
91 anjuta_project_property_copy (AnjutaProjectProperty
*prop
)
93 return anjuta_project_property_new (prop
->value
, prop
->name
, prop
->user_data
);
97 anjuta_project_property_free (AnjutaProjectProperty
*prop
)
101 g_slice_free (AnjutaProjectProperty
, prop
);
105 anjuta_project_property_get_type (void)
107 static GType type_id
= 0;
110 type_id
= g_boxed_type_register_static ("AnjutaProjectProperty",
111 (GBoxedCopyFunc
) anjuta_project_property_copy
,
112 (GBoxedFreeFunc
) anjuta_project_property_free
);
117 /* Node properties information
118 *---------------------------------------------------------------------------*/
120 /* Implement Boxed type
121 *---------------------------------------------------------------------------*/
124 * anjuta_project_property_info_new:
125 * @id: (transfer none): Property identifier
126 * @name: (transfer none): Translatable property name
127 * @type: Property value type
128 * @flags: Property flags
129 * @description: (transfer none): Property description
130 * @default_value: (transfer full): Default property value
131 * @user_data: (allow-none) (transfer full): Optional user data
133 * Returns: (transfer full):
135 AnjutaProjectPropertyInfo
*
136 anjuta_project_property_info_new (const gchar
*id
,
138 AnjutaProjectValueType type
,
139 AnjutaProjectPropertyFlags flags
,
140 const gchar
*description
,
141 AnjutaProjectProperty
*default_value
,
144 AnjutaProjectPropertyInfo
*info
= g_slice_new0(AnjutaProjectPropertyInfo
);
146 info
->id
= g_strdup (id
);
147 info
->name
= g_strdup (name
);
150 info
->description
= g_strdup (description
);
151 info
->default_value
= default_value
;
152 info
->user_data
= user_data
;
154 info
->default_value
->info
= info
;
159 AnjutaProjectPropertyInfo
*
160 anjuta_project_property_info_copy (AnjutaProjectPropertyInfo
*info
)
162 return anjuta_project_property_info_new (info
->id
, info
->name
, info
->type
,
163 info
->flags
, info
->description
,
164 info
->default_value
, info
->user_data
);
168 anjuta_project_property_info_free (AnjutaProjectPropertyInfo
*info
)
172 g_free (info
->description
);
173 anjuta_project_property_free (info
->default_value
);
174 g_slice_free (AnjutaProjectPropertyInfo
, info
);
178 anjuta_project_property_info_get_type (void)
180 static GType type_id
= 0;
183 type_id
= g_boxed_type_register_static ("AnjutaProjectPropertyInfo",
184 (GBoxedCopyFunc
) anjuta_project_property_info_copy
,
185 (GBoxedFreeFunc
) anjuta_project_property_info_free
);
191 *---------------------------------------------------------------------------*/
194 /* Moving in tree functions
195 *---------------------------------------------------------------------------*/
198 * anjuta_project_node_parent:
200 * Returns: (transfer none):
203 anjuta_project_node_parent(AnjutaProjectNode
*node
)
205 g_return_val_if_fail (node
!= NULL
, NULL
);
211 * anjuta_project_node_root:
213 * Returns: (transfer none):
216 anjuta_project_node_root (AnjutaProjectNode
*node
)
218 g_return_val_if_fail (node
!= NULL
, NULL
);
220 while (node
->parent
!= NULL
)
229 * anjuta_project_node_first_child:
231 * Returns: (transfer none):
235 anjuta_project_node_first_child(AnjutaProjectNode
*node
)
237 g_return_val_if_fail (node
!= NULL
, NULL
);
239 return node
->children
;
243 * anjuta_project_node_last_child:
245 * Returns: (transfer none):
249 anjuta_project_node_last_child(AnjutaProjectNode
*node
)
251 g_return_val_if_fail (node
!= NULL
, NULL
);
253 node
= node
->children
;
262 * anjuta_project_node_next_sibling:
264 * Returns: (transfer none):
267 anjuta_project_node_next_sibling (AnjutaProjectNode
*node
)
269 g_return_val_if_fail (node
!= NULL
, NULL
);
275 * anjuta_project_node_prev_sibling:
277 * Returns: (transfer none):
280 anjuta_project_node_prev_sibling (AnjutaProjectNode
*node
)
282 g_return_val_if_fail (node
!= NULL
, NULL
);
288 * anjuta_project_node_nth_child:
290 * Returns: (transfer none):
292 AnjutaProjectNode
*anjuta_project_node_nth_child (AnjutaProjectNode
*node
, guint n
)
294 g_return_val_if_fail (node
!= NULL
, NULL
);
296 node
= node
->children
;
298 while ((n
-- > 0) && node
)
304 static AnjutaProjectNode
*
305 anjuta_project_node_post_order_traverse (AnjutaProjectNode
*node
, AnjutaProjectNodeTraverseFunc func
, gpointer data
)
307 AnjutaProjectNode
*child
;
309 child
= node
->children
;
310 while (child
!= NULL
)
312 AnjutaProjectNode
*current
;
315 child
= current
->next
;
316 current
= anjuta_project_node_post_order_traverse (current
, func
, data
);
323 return func (node
, data
) ? node
: NULL
;
326 static AnjutaProjectNode
*
327 anjuta_project_node_pre_order_traverse (AnjutaProjectNode
*node
, AnjutaProjectNodeTraverseFunc func
, gpointer data
)
329 AnjutaProjectNode
*child
;
331 if (func (node
, data
))
336 child
= node
->children
;
337 while (child
!= NULL
)
339 AnjutaProjectNode
*current
;
342 child
= current
->next
;
343 current
= anjuta_project_node_pre_order_traverse (current
, func
, data
);
355 * anjuta_project_node_traverse:
356 * @func: (scope call):
358 * Returns: (transfer none):
361 anjuta_project_node_traverse (AnjutaProjectNode
*node
, GTraverseType order
, AnjutaProjectNodeTraverseFunc func
, gpointer data
)
363 g_return_val_if_fail (node
!= NULL
, NULL
);
364 g_return_val_if_fail (func
!= NULL
, NULL
);
365 g_return_val_if_fail ((order
!= G_PRE_ORDER
) || (order
!= G_POST_ORDER
), NULL
);
370 return anjuta_project_node_pre_order_traverse (node
, func
, data
);
372 return anjuta_project_node_post_order_traverse (node
, func
, data
);
379 * anjuta_project_node_children_traverse:
380 * @func: (scope call):
382 * Returns: (transfer none):
385 anjuta_project_node_children_traverse (AnjutaProjectNode
*node
, AnjutaProjectNodeTraverseFunc func
, gpointer data
)
387 AnjutaProjectNode
*child
;
389 g_return_val_if_fail (node
!= NULL
, NULL
);
391 child
= node
->children
;
392 while (child
!= NULL
)
394 AnjutaProjectNode
*current
;
397 child
= current
->next
;
398 if (func (current
, data
))
408 anjuta_project_node_post_order_foreach (AnjutaProjectNode
*node
, AnjutaProjectNodeForeachFunc func
, gpointer data
)
410 AnjutaProjectNode
*child
;
412 child
= node
->children
;
413 while (child
!= NULL
)
415 AnjutaProjectNode
*current
;
418 child
= current
->next
;
419 anjuta_project_node_post_order_foreach (current
, func
, data
);
426 anjuta_project_node_pre_order_foreach (AnjutaProjectNode
*node
, AnjutaProjectNodeForeachFunc func
, gpointer data
)
428 AnjutaProjectNode
*child
;
432 child
= node
->children
;
433 while (child
!= NULL
)
435 AnjutaProjectNode
*current
;
438 child
= current
->next
;
439 anjuta_project_node_pre_order_foreach (current
, func
, data
);
444 * anjuta_project_node_foreach:
445 * @func: (scope call):
448 anjuta_project_node_foreach (AnjutaProjectNode
*node
, GTraverseType order
, AnjutaProjectNodeForeachFunc func
, gpointer data
)
450 g_return_if_fail (node
!= NULL
);
451 g_return_if_fail (func
!= NULL
);
452 g_return_if_fail ((order
!= G_PRE_ORDER
) || (order
!= G_POST_ORDER
));
457 anjuta_project_node_pre_order_foreach (node
, func
, data
);
460 anjuta_project_node_post_order_foreach (node
, func
, data
);
468 * anjuta_project_node_children_foreach:
469 * @func: (scope call):
472 anjuta_project_node_children_foreach (AnjutaProjectNode
*node
, AnjutaProjectNodeForeachFunc func
, gpointer data
)
474 AnjutaProjectNode
*child
;
476 g_return_if_fail (node
!= NULL
);
478 child
= node
->children
;
479 while (child
!= NULL
)
481 AnjutaProjectNode
*current
;
484 child
= current
->next
;
485 func (current
, data
);
490 * anjuta_project_node_parent_type:
492 * Returns: (transfer none):
495 anjuta_project_node_parent_type(AnjutaProjectNode
*node
, AnjutaProjectNodeType type
)
499 node
= anjuta_project_node_parent (node
);
500 if (node
== NULL
) break;
502 while (anjuta_project_node_get_node_type (node
) != type
);
509 /* Debugging functions
510 *---------------------------------------------------------------------------*/
512 static gboolean
check_node (AnjutaProjectNode
*node
, gpointer data
)
514 if (!ANJUTA_IS_PROJECT_NODE (node
)) g_critical (" Node %p of %p is not a AnjutaProjectNode", node
, data
);
515 if (node
->prev
== NULL
)
517 if ((node
->parent
!= NULL
) && (node
->parent
->children
!= node
)) g_critical (" Node %p of %p has the wrong parent", node
, data
);
521 if (node
->prev
->next
!= node
) g_critical (" Node %p of %p has the wrong predecessor", node
, data
);
522 if (node
->prev
->parent
!= node
->parent
) g_critical (" Node %p of %p has the wrong parent", node
, data
);
524 if (node
->next
!= NULL
)
526 if (node
->next
->prev
!= node
) g_critical (" Node %p of %p has the wrong successor", node
, data
);
528 if (node
->children
!= NULL
)
530 if (node
->children
->parent
!= node
) g_critical (" Node %p of %p has the wrong children", node
, data
);
537 anjuta_project_node_check (AnjutaProjectNode
*parent
)
539 AnjutaProjectNode
*node
;
541 g_message ("Check node %p", parent
);
542 node
= anjuta_project_node_traverse (parent
, G_POST_ORDER
, check_node
, parent
);
543 if (node
== NULL
) g_message (" Node %p is valid", parent
);
548 anjuta_project_node_show (AnjutaProjectNode
*node
, gint indent
)
550 g_message("%*s %p: %s", indent
, "", node
, node
!= NULL
? anjuta_project_node_get_name (node
) : NULL
);
554 anjuta_project_node_dump_child (AnjutaProjectNode
*parent
, gint indent
)
556 AnjutaProjectNode
*child
;
558 anjuta_project_node_show (parent
, indent
);
561 for (child
= anjuta_project_node_first_child (parent
); child
!= NULL
; child
= anjuta_project_node_next_sibling (child
))
563 anjuta_project_node_dump_child (child
, indent
);
568 anjuta_project_node_dump (AnjutaProjectNode
*parent
)
570 anjuta_project_node_dump_child (parent
, 0);
575 /* Adding node functions
576 *---------------------------------------------------------------------------*/
579 * anjuta_project_node_insert_before:
581 * @sibling: (allow-none) (transfer none):
582 * @node: (transfer none):
584 * Returns: (transfer none):
587 anjuta_project_node_insert_before (AnjutaProjectNode
*parent
, AnjutaProjectNode
*sibling
, AnjutaProjectNode
*node
)
589 g_return_val_if_fail (node
!= NULL
, NULL
);
590 g_return_val_if_fail (parent
!= NULL
, node
);
592 /* FIXME: Try to avoid filling parent member to allow these checks
593 g_return_val_if_fail (node->parent == NULL)
595 g_return_val_if_fail (sibling->parent == parent, node);*/
597 g_object_ref_sink (node
);
599 node
->parent
= parent
;
604 node
->prev
= sibling
->prev
;
605 node
->prev
->next
= node
;
606 node
->next
= sibling
;
607 sibling
->prev
= node
;
611 node
->parent
->children
= node
;
612 node
->next
= sibling
;
613 sibling
->prev
= node
;
618 if (parent
->children
)
620 sibling
= parent
->children
;
621 while (sibling
->next
)
622 sibling
= sibling
->next
;
623 node
->prev
= sibling
;
624 sibling
->next
= node
;
628 node
->parent
->children
= node
;
636 * anjuta_project_node_insert_after:
638 * @sibling: (allow-none) (transfer none):
639 * @node: (transfer none):
641 * Returns: (transfer none):
644 anjuta_project_node_insert_after (AnjutaProjectNode
*parent
, AnjutaProjectNode
*sibling
, AnjutaProjectNode
*node
)
646 g_return_val_if_fail (node
!= NULL
, NULL
);
647 g_return_val_if_fail (parent
!= NULL
, node
);
649 /* FIXME: Try to avoid filling parent member to allow these checks
650 g_return_val_if_fail (node->parent == NULL)
652 g_return_val_if_fail (sibling->parent == parent, node);*/
654 g_object_ref_sink (node
);
656 node
->parent
= parent
;
661 sibling
->next
->prev
= node
;
663 node
->next
= sibling
->next
;
664 node
->prev
= sibling
;
665 sibling
->next
= node
;
669 if (parent
->children
)
671 node
->next
= parent
->children
;
672 parent
->children
->prev
= node
;
674 parent
->children
= node
;
681 * anjuta_project_node_remove:
682 * @node: (transfer none):
684 * Returns: (transfer full):
687 anjuta_project_node_remove (AnjutaProjectNode
*node
)
689 g_return_val_if_fail (node
!= NULL
, NULL
);
692 node
->prev
->next
= node
->next
;
693 else if (node
->parent
)
694 node
->parent
->children
= node
->next
;
698 node
->next
->prev
= node
->prev
;
707 * anjuta_project_node_prepend:
709 * Returns: (transfer none):
712 anjuta_project_node_prepend (AnjutaProjectNode
*parent
, AnjutaProjectNode
*node
)
714 return anjuta_project_node_insert_before (parent
, parent
->children
, node
);
718 * anjuta_project_node_append:
720 * Returns: (transfer none):
723 anjuta_project_node_append (AnjutaProjectNode
*parent
, AnjutaProjectNode
*node
)
725 return anjuta_project_node_insert_before (parent
, NULL
, node
);
729 *---------------------------------------------------------------------------*/
731 AnjutaProjectNodeType
732 anjuta_project_node_get_node_type (const AnjutaProjectNode
*node
)
734 return node
== NULL
? ANJUTA_PROJECT_UNKNOWN
: (node
->type
& ANJUTA_PROJECT_TYPE_MASK
);
737 AnjutaProjectNodeType
738 anjuta_project_node_get_full_type (const AnjutaProjectNode
*node
)
740 return node
== NULL
? ANJUTA_PROJECT_UNKNOWN
: node
->type
;
744 AnjutaProjectNodeState
745 anjuta_project_node_get_state (const AnjutaProjectNode
*node
)
747 return node
== NULL
? ANJUTA_PROJECT_OK
: (node
->state
);
751 anjuta_project_node_get_name (const AnjutaProjectNode
*node
)
753 if ((node
->name
== NULL
) && (node
->file
!= NULL
))
755 ((AnjutaProjectNode
*)node
)->name
= g_file_get_basename (node
->file
);
762 * anjuta_project_node_get_file:
764 * Returns: (transfer none):
767 anjuta_project_node_get_file (const AnjutaProjectNode
*node
)
769 switch (node
->type
& ANJUTA_PROJECT_TYPE_MASK
)
771 case ANJUTA_PROJECT_OBJECT
:
772 case ANJUTA_PROJECT_TARGET
:
773 if ((node
->name
) && (node
->parent
!= NULL
) && (node
->parent
->file
!= NULL
))
775 GFile
*file
= g_file_get_child (node
->parent
->file
, node
->name
);
777 if ((node
->file
!= NULL
) && g_file_equal (node
->file
, file
))
779 /* Keep the same file */
780 g_object_unref (file
);
784 /* Parent has been updated, update file */
785 if (node
->file
!= NULL
) g_object_unref (node
->file
);
786 ((AnjutaProjectNode
*)node
)->file
= file
;
798 * anjuta_project_node_get_properties_info:
800 * Returns: (transfer none) (element-type Anjuta.ProjectPropertyInfo):
803 anjuta_project_node_get_properties_info (AnjutaProjectNode
*node
)
805 return node
->properties_info
;
809 * anjuta_project_node_get_properties:
811 * Returns: (transfer none) (element-type Anjuta.ProjectProperty):
814 anjuta_project_node_get_properties (AnjutaProjectNode
*node
)
816 return node
->properties
;
820 find_property_info (gconstpointer item
, gconstpointer data
)
822 AnjutaProjectPropertyInfo
*info
= (AnjutaProjectPropertyInfo
*)item
;
823 const gchar
*id
= (const gchar
*)data
;
825 return strcmp (info
->id
, id
);
829 * anjuta_project_node_get_property_info:
830 * @node: (transfer none):
831 * @id: (transfer none): Property identifier
833 * Returns: (transfer none):
835 AnjutaProjectPropertyInfo
*
836 anjuta_project_node_get_property_info (AnjutaProjectNode
*node
,
841 /* Find property info */
842 found
= g_list_find_custom (node
->properties_info
, id
, find_property_info
);
844 return found
!= NULL
? (AnjutaProjectPropertyInfo
*)found
->data
: NULL
;
848 find_property (gconstpointer item
, gconstpointer data
)
850 AnjutaProjectProperty
*prop
= (AnjutaProjectProperty
*)item
;
851 AnjutaProjectPropertyInfo
*info
= (AnjutaProjectPropertyInfo
*)data
;
853 return prop
->info
!= info
;
857 * anjuta_project_node_get_property:
858 * @node: (transfer none):
859 * @id: (transfer none): Property identifier
861 * Returns: (transfer none):
863 AnjutaProjectProperty
*
864 anjuta_project_node_get_property (AnjutaProjectNode
*node
, const gchar
*id
)
866 AnjutaProjectPropertyInfo
*info
;
867 AnjutaProjectProperty
*prop
= NULL
;
869 /* Find property info */
870 info
= anjuta_project_node_get_property_info (node
, id
);
875 /* Get default property */
876 prop
= info
->default_value
;
878 /* Find custom property */
879 found
= g_list_find_custom (node
->properties
, info
, find_property
);
882 prop
= (AnjutaProjectProperty
*)found
->data
;
889 /* If name is specified, look for a property with the same name, useful for
891 AnjutaProjectProperty
*
892 anjuta_project_node_get_map_property (AnjutaProjectNode
*node
, const gchar
*id
, const gchar
*name
)
894 AnjutaProjectPropertyInfo
*info
;
895 AnjutaProjectProperty
*prop
= NULL
;
897 /* Find property info */
898 info
= anjuta_project_node_get_property_info (node
, id
);
903 /* Get default property */
904 prop
= info
->default_value
;
907 found
= node
->properties
;
910 found
= g_list_find_custom (found
, info
, find_property
);
913 prop
= (AnjutaProjectProperty
*)found
->data
;
914 if ((info
->type
!= ANJUTA_PROJECT_PROPERTY_MAP
) || (g_strcmp0 (prop
->name
, name
) == 0)) break;
916 found
= g_list_next (found
);
919 while (found
!= NULL
);
926 *---------------------------------------------------------------------------*/
929 anjuta_project_node_set_state (AnjutaProjectNode
*node
, AnjutaProjectNodeState state
)
931 if (node
== NULL
) return FALSE
;
932 node
->state
|= state
;
937 anjuta_project_node_clear_state (AnjutaProjectNode
*node
, AnjutaProjectNodeState state
)
939 if (node
== NULL
) return FALSE
;
940 node
->state
&= ~state
;
945 * anjuta_project_node_insert_property_info:
946 * @node: (transfer none):
947 * @info: (transfer none):
949 * Returns: (transfer none):
952 AnjutaProjectPropertyInfo
*
953 anjuta_project_node_insert_property_info (AnjutaProjectNode
*node
,
954 AnjutaProjectPropertyInfo
*info
)
956 node
->properties_info
= g_list_append (node
->properties_info
, info
);
962 * anjuta_project_node_insert_property:
963 * @node: (transfer none):
964 * @info: (transfer none):
965 * @property: (transfer full):
967 * Returns: (transfer none):
970 AnjutaProjectProperty
*
971 anjuta_project_node_insert_property (AnjutaProjectNode
*node
, AnjutaProjectPropertyInfo
*info
, AnjutaProjectProperty
*property
)
973 /* Make sure the property is native */
974 property
->info
= info
;
976 /* Add in properties list */
977 node
->properties
= g_list_append (node
->properties
, property
);
982 AnjutaProjectProperty
*
983 anjuta_project_node_remove_property (AnjutaProjectNode
*node
, AnjutaProjectProperty
*prop
)
985 /* Search the exact property, useful for list property */
986 if (prop
!= prop
->info
->default_value
)
988 node
->properties
= g_list_remove (node
->properties
, prop
);
995 /* Get node from file functions
996 *---------------------------------------------------------------------------*/
999 anjuta_project_group_compare (AnjutaProjectNode
*node
, gpointer data
)
1001 GFile
*file
= (GFile
*)data
;
1003 if (((node
->type
& ANJUTA_PROJECT_TYPE_MASK
) == ANJUTA_PROJECT_GROUP
) && g_file_equal (node
->file
, file
))
1014 * anjuta_project_node_get_group_from_file:
1015 * @root: the root node
1016 * @directory: Directory to search in
1018 * Returns: (transfer none):
1021 anjuta_project_node_get_group_from_file (const AnjutaProjectNode
*root
, GFile
*directory
)
1023 AnjutaProjectNode
*node
;
1025 node
= anjuta_project_node_traverse ((AnjutaProjectNode
*)root
, G_PRE_ORDER
, anjuta_project_group_compare
, directory
);
1031 anjuta_project_target_compare (AnjutaProjectNode
*node
, gpointer data
)
1033 const gchar
*name
= (gchar
*)data
;
1035 if (((node
->type
& ANJUTA_PROJECT_TYPE_MASK
) == ANJUTA_PROJECT_TARGET
) && (strcmp (node
->name
, name
) == 0))
1046 anjuta_project_target_get_node_from_name (const AnjutaProjectNode
*parent
, const gchar
*name
)
1048 AnjutaProjectNode
*node
;
1050 node
= anjuta_project_node_traverse ((AnjutaProjectNode
*)parent
, G_PRE_ORDER
, anjuta_project_target_compare
, (gpointer
)name
);
1056 anjuta_project_source_compare (AnjutaProjectNode
*node
, gpointer data
)
1058 GFile
*file
= (GFile
*)data
;
1060 if (((node
->type
& ANJUTA_PROJECT_TYPE_MASK
) == ANJUTA_PROJECT_SOURCE
) && g_file_equal (node
->file
, file
))
1071 * anjuta_project_node_get_source_from_file:
1072 * @parent: the parent node
1073 * @file: The file to query the source for
1075 * Returns: (transfer none):
1078 anjuta_project_node_get_source_from_file (const AnjutaProjectNode
*parent
, GFile
*file
)
1080 AnjutaProjectNode
*node
;
1083 node
= anjuta_project_node_traverse ((AnjutaProjectNode
*)parent
, G_PRE_ORDER
, anjuta_project_source_compare
, (gpointer
)file
);
1089 /* Implement GObject
1090 *---------------------------------------------------------------------------*/
1108 static unsigned int anjuta_project_node_signals
[LAST_SIGNAL
] = { 0 };
1110 G_DEFINE_TYPE (AnjutaProjectNode
, anjuta_project_node
, G_TYPE_INITIALLY_UNOWNED
);
1113 anjuta_project_node_init (AnjutaProjectNode
*node
)
1117 node
->parent
= NULL
;
1118 node
->children
= NULL
;
1122 node
->properties
= NULL
;
1123 node
->properties_info
= NULL
;
1129 anjuta_project_node_dispose (GObject
*object
)
1131 AnjutaProjectNode
*node
= ANJUTA_PROJECT_NODE(object
);
1133 anjuta_project_node_remove (node
);
1135 if (node
->file
!= NULL
) g_object_unref (node
->file
);
1138 while (node
->children
!= NULL
)
1140 AnjutaProjectNode
*child
;
1142 child
= anjuta_project_node_remove (node
->children
);
1143 g_object_unref (child
);
1146 G_OBJECT_CLASS (anjuta_project_node_parent_class
)->dispose (object
);
1150 anjuta_project_node_finalize (GObject
*object
)
1152 AnjutaProjectNode
*node
= ANJUTA_PROJECT_NODE(object
);
1154 if (node
->name
!= NULL
) g_free (node
->name
);
1156 g_list_free_full (node
->properties
, (GDestroyNotify
) anjuta_project_property_free
);
1157 node
->properties
= NULL
;
1159 g_list_free (node
->properties_info
);
1160 node
->properties_info
= NULL
;
1162 G_OBJECT_CLASS (anjuta_project_node_parent_class
)->finalize (object
);
1166 anjuta_project_node_get_gobject_property (GObject
*object
,
1171 AnjutaProjectNode
*node
= ANJUTA_PROJECT_NODE(object
);
1174 g_value_set_string (value
, anjuta_project_node_get_name (node
));
1177 g_value_set_object (value
, node
->file
);
1180 g_value_set_flags (value
, anjuta_project_node_get_state (node
));
1183 g_value_set_flags (value
, anjuta_project_node_get_node_type (node
));
1186 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
1191 anjuta_project_node_set_gobject_property (GObject
*object
,
1193 const GValue
*value
,
1196 AnjutaProjectNode
*node
= ANJUTA_PROJECT_NODE(object
);
1199 if (node
->name
!= NULL
)
1200 g_free (node
->name
);
1201 node
->name
= g_value_dup_string (value
);
1204 if (node
->file
!= NULL
)
1205 g_object_unref (node
->file
);
1206 node
->file
= g_value_dup_object (value
);
1209 anjuta_project_node_set_state (node
, g_value_get_flags (value
));
1212 node
->type
= g_value_get_flags (value
);
1215 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
1220 anjuta_project_node_class_init (AnjutaProjectNodeClass
*klass
)
1222 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
1225 object_class
->finalize
= anjuta_project_node_finalize
;
1226 object_class
->dispose
= anjuta_project_node_dispose
;
1227 object_class
->get_property
= anjuta_project_node_get_gobject_property
;
1228 object_class
->set_property
= anjuta_project_node_set_gobject_property
;
1230 /*Change both signal to use marshal_VOID__POINTER_BOXED
1231 adding a AnjutaProjectNode pointer corresponding to the
1233 Such marshal doesn't exist as glib marshal, so look in the
1234 symbol db plugin how to add new marshal => done
1236 This new argument can be used in the plugin object in
1237 order to add corresponding shortcut when the project
1238 is loaded and a new node is loaded.
1239 The plugin should probably get the GFile from the
1240 AnjutaProjectNode object and then use a function
1241 in project-view.c to create the corresponding shortcut*/
1243 anjuta_project_node_signals
[UPDATED
] = g_signal_new ("updated",
1244 G_OBJECT_CLASS_TYPE (object_class
),
1246 G_STRUCT_OFFSET (AnjutaProjectNodeClass
, updated
),
1248 anjuta_cclosure_marshal_VOID__STRING_BOXED
,
1254 anjuta_project_node_signals
[LOADED
] = g_signal_new ("loaded",
1255 G_OBJECT_CLASS_TYPE (object_class
),
1257 G_STRUCT_OFFSET (AnjutaProjectNodeClass
, loaded
),
1259 anjuta_cclosure_marshal_VOID__STRING_BOXED
,
1265 pspec
= g_param_spec_flags ("type",
1268 ANJUTA_TYPE_PROJECT_NODE_TYPE
,
1270 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1271 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_TYPE
,
1274 pspec
= g_param_spec_flags ("state",
1277 ANJUTA_TYPE_PROJECT_NODE_STATE
,
1279 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1280 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_STATE
,
1283 pspec
= g_param_spec_string ("name",
1287 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1288 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_NAME
,
1291 pspec
= g_param_spec_object ("file",
1293 "The GFile for the node",
1295 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1296 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_FILE
,
1304 *---------------------------------------------------------------------------*/
1307 *---------------------------------------------------------------------------*/
1310 anjuta_project_node_info_name (const AnjutaProjectNodeInfo
*info
)
1316 anjuta_project_node_info_mime (const AnjutaProjectNodeInfo
*info
)
1318 return info
->mime_type
;
1321 AnjutaProjectNodeType
1322 anjuta_project_node_info_type (const AnjutaProjectNodeInfo
*info
)
1328 anjuta_project_node_info_property_help_id (const AnjutaProjectNodeInfo
*info
)
1330 return info
->property_help_id
;
1334 * anjuta_project_node_info_new:
1335 * @name: (transfer none):
1336 * @mime_type: (transfer none):
1338 * Returns: (transfer full):
1340 AnjutaProjectNodeInfo
*
1341 anjuta_project_node_info_new (AnjutaProjectNodeType type
,
1343 const gchar
*mime_type
)
1345 AnjutaProjectNodeInfo
*info
= g_slice_new0 (AnjutaProjectNodeInfo
);
1347 info
->name
= g_strdup (name
);
1348 info
->mime_type
= g_strdup (mime_type
);
1353 AnjutaProjectNodeInfo
*
1354 anjuta_project_node_info_copy (AnjutaProjectNodeInfo
*info
)
1356 return anjuta_project_node_info_new (info
->type
, info
->name
, info
->mime_type
);
1359 void anjuta_project_node_info_free (AnjutaProjectNodeInfo
*info
)
1361 g_slice_free (AnjutaProjectNodeInfo
, info
);
1364 /* Implement Boxed type
1365 *---------------------------------------------------------------------------*/
1368 anjuta_project_node_info_get_type ()
1370 static GType type_id
= 0;
1373 type_id
= g_boxed_type_register_static ("AnjutaProjectNodeInfo",
1374 (GBoxedCopyFunc
) anjuta_project_node_info_copy
,
1375 (GBoxedFreeFunc
) anjuta_project_node_info_free
);