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 * @id: (transfer none):
70 * @name: (transfer none):
71 * @value: (transfer none):
72 * @native: (allow-none) (transfer none):
74 * Returns: (transfer full):
76 AnjutaProjectProperty
*
77 anjuta_project_property_new (const gchar
* id
, const gchar
*name
, AnjutaProjectValueType type
,
78 const gchar
*value
, AnjutaProjectProperty
*native
)
80 AnjutaProjectProperty
*prop
= g_slice_new0(AnjutaProjectProperty
);
81 prop
->id
= g_strdup (id
);
82 prop
->name
= g_strdup (name
);
84 prop
->value
= g_strdup (value
);
87 prop
->native
= native
;
88 prop
->flags
= native
->flags
;
89 prop
->detail
= native
->detail
;
95 AnjutaProjectProperty
*
96 anjuta_project_property_copy (AnjutaProjectProperty
*prop
)
98 return anjuta_project_property_new (prop
->id
, prop
->name
, prop
->type
,
99 prop
->value
, prop
->native
);
103 anjuta_project_property_free (AnjutaProjectProperty
*prop
)
106 g_free (prop
->value
);
107 g_slice_free (AnjutaProjectProperty
, prop
);
111 anjuta_project_property_get_type (void)
113 static GType type_id
= 0;
116 type_id
= g_boxed_type_register_static ("AnjutaProjectProperty",
117 (GBoxedCopyFunc
) anjuta_project_property_copy
,
118 (GBoxedFreeFunc
) anjuta_project_property_free
);
126 *---------------------------------------------------------------------------*/
129 /* Moving in tree functions
130 *---------------------------------------------------------------------------*/
133 * anjuta_project_node_parent:
135 * Returns: (transfer none):
138 anjuta_project_node_parent(AnjutaProjectNode
*node
)
140 g_return_val_if_fail (node
!= NULL
, NULL
);
146 * anjuta_project_node_root:
148 * Returns: (transfer none):
151 anjuta_project_node_root (AnjutaProjectNode
*node
)
153 g_return_val_if_fail (node
!= NULL
, NULL
);
155 while (node
->parent
!= NULL
)
164 * anjuta_project_node_first_child:
166 * Returns: (transfer none):
170 anjuta_project_node_first_child(AnjutaProjectNode
*node
)
172 g_return_val_if_fail (node
!= NULL
, NULL
);
174 return node
->children
;
178 * anjuta_project_node_last_child:
180 * Returns: (transfer none):
184 anjuta_project_node_last_child(AnjutaProjectNode
*node
)
186 g_return_val_if_fail (node
!= NULL
, NULL
);
188 node
= node
->children
;
197 * anjuta_project_node_next_sibling:
199 * Returns: (transfer none):
202 anjuta_project_node_next_sibling (AnjutaProjectNode
*node
)
204 g_return_val_if_fail (node
!= NULL
, NULL
);
210 * anjuta_project_node_prev_sibling:
212 * Returns: (transfer none):
215 anjuta_project_node_prev_sibling (AnjutaProjectNode
*node
)
217 g_return_val_if_fail (node
!= NULL
, NULL
);
223 * anjuta_project_node_nth_child:
225 * Returns: (transfer none):
227 AnjutaProjectNode
*anjuta_project_node_nth_child (AnjutaProjectNode
*node
, guint n
)
229 g_return_val_if_fail (node
!= NULL
, NULL
);
231 node
= node
->children
;
233 while ((n
-- > 0) && node
)
239 static AnjutaProjectNode
*
240 anjuta_project_node_post_order_traverse (AnjutaProjectNode
*node
, AnjutaProjectNodeTraverseFunc func
, gpointer data
)
242 AnjutaProjectNode
*child
;
244 child
= node
->children
;
245 while (child
!= NULL
)
247 AnjutaProjectNode
*current
;
250 child
= current
->next
;
251 current
= anjuta_project_node_post_order_traverse (current
, func
, data
);
258 return func (node
, data
) ? node
: NULL
;
261 static AnjutaProjectNode
*
262 anjuta_project_node_pre_order_traverse (AnjutaProjectNode
*node
, AnjutaProjectNodeTraverseFunc func
, gpointer data
)
264 AnjutaProjectNode
*child
;
266 if (func (node
, data
))
271 child
= node
->children
;
272 while (child
!= NULL
)
274 AnjutaProjectNode
*current
;
277 child
= current
->next
;
278 current
= anjuta_project_node_pre_order_traverse (current
, func
, data
);
290 * anjuta_project_node_traverse:
291 * @func: (scope call):
293 * Returns: (transfer none):
296 anjuta_project_node_traverse (AnjutaProjectNode
*node
, GTraverseType order
, AnjutaProjectNodeTraverseFunc func
, gpointer data
)
298 g_return_val_if_fail (node
!= NULL
, NULL
);
299 g_return_val_if_fail (func
!= NULL
, NULL
);
300 g_return_val_if_fail ((order
!= G_PRE_ORDER
) || (order
!= G_POST_ORDER
), NULL
);
305 return anjuta_project_node_pre_order_traverse (node
, func
, data
);
307 return anjuta_project_node_post_order_traverse (node
, func
, data
);
314 * anjuta_project_node_children_traverse:
315 * @func: (scope call):
317 * Returns: (transfer none):
320 anjuta_project_node_children_traverse (AnjutaProjectNode
*node
, AnjutaProjectNodeTraverseFunc func
, gpointer data
)
322 AnjutaProjectNode
*child
;
324 g_return_val_if_fail (node
!= NULL
, NULL
);
326 child
= node
->children
;
327 while (child
!= NULL
)
329 AnjutaProjectNode
*current
;
332 child
= current
->next
;
333 if (func (current
, data
))
343 anjuta_project_node_post_order_foreach (AnjutaProjectNode
*node
, AnjutaProjectNodeForeachFunc func
, gpointer data
)
345 AnjutaProjectNode
*child
;
347 child
= node
->children
;
348 while (child
!= NULL
)
350 AnjutaProjectNode
*current
;
353 child
= current
->next
;
354 anjuta_project_node_post_order_foreach (current
, func
, data
);
361 anjuta_project_node_pre_order_foreach (AnjutaProjectNode
*node
, AnjutaProjectNodeForeachFunc func
, gpointer data
)
363 AnjutaProjectNode
*child
;
367 child
= node
->children
;
368 while (child
!= NULL
)
370 AnjutaProjectNode
*current
;
373 child
= current
->next
;
374 anjuta_project_node_pre_order_foreach (current
, func
, data
);
379 * anjuta_project_node_foreach:
380 * @func: (scope call):
383 anjuta_project_node_foreach (AnjutaProjectNode
*node
, GTraverseType order
, AnjutaProjectNodeForeachFunc func
, gpointer data
)
385 g_return_if_fail (node
!= NULL
);
386 g_return_if_fail (func
!= NULL
);
387 g_return_if_fail ((order
!= G_PRE_ORDER
) || (order
!= G_POST_ORDER
));
392 anjuta_project_node_pre_order_foreach (node
, func
, data
);
395 anjuta_project_node_post_order_foreach (node
, func
, data
);
403 * anjuta_project_node_children_foreach:
404 * @func: (scope call):
407 anjuta_project_node_children_foreach (AnjutaProjectNode
*node
, AnjutaProjectNodeForeachFunc func
, gpointer data
)
409 AnjutaProjectNode
*child
;
411 g_return_if_fail (node
!= NULL
);
413 child
= node
->children
;
414 while (child
!= NULL
)
416 AnjutaProjectNode
*current
;
419 child
= current
->next
;
420 func (current
, data
);
425 * anjuta_project_node_parent_type:
427 * Returns: (transfer none):
430 anjuta_project_node_parent_type(AnjutaProjectNode
*node
, AnjutaProjectNodeType type
)
434 node
= anjuta_project_node_parent (node
);
435 if (node
== NULL
) break;
437 while (anjuta_project_node_get_node_type (node
) != type
);
444 /* Debugging functions
445 *---------------------------------------------------------------------------*/
447 static gboolean
check_node (AnjutaProjectNode
*node
, gpointer data
)
449 if (!ANJUTA_IS_PROJECT_NODE (node
)) g_critical (" Node %p of %p is not a AnjutaProjectNode", node
, data
);
450 if (node
->prev
== NULL
)
452 if ((node
->parent
!= NULL
) && (node
->parent
->children
!= node
)) g_critical (" Node %p of %p has the wrong parent", node
, data
);
456 if (node
->prev
->next
!= node
) g_critical (" Node %p of %p has the wrong predecessor", node
, data
);
457 if (node
->prev
->parent
!= node
->parent
) g_critical (" Node %p of %p has the wrong parent", node
, data
);
459 if (node
->next
!= NULL
)
461 if (node
->next
->prev
!= node
) g_critical (" Node %p of %p has the wrong successor", node
, data
);
463 if (node
->children
!= NULL
)
465 if (node
->children
->parent
!= node
) g_critical (" Node %p of %p has the wrong children", node
, data
);
472 anjuta_project_node_check (AnjutaProjectNode
*parent
)
474 AnjutaProjectNode
*node
;
476 g_message ("Check node %p", parent
);
477 node
= anjuta_project_node_traverse (parent
, G_POST_ORDER
, check_node
, parent
);
478 if (node
== NULL
) g_message (" Node %p is valid", parent
);
483 anjuta_project_node_show (AnjutaProjectNode
*node
, gint indent
)
485 g_message("%*s %p: %s", indent
, "", node
, node
!= NULL
? anjuta_project_node_get_name (node
) : NULL
);
489 anjuta_project_node_dump_child (AnjutaProjectNode
*parent
, gint indent
)
491 AnjutaProjectNode
*child
;
493 anjuta_project_node_show (parent
, indent
);
496 for (child
= anjuta_project_node_first_child (parent
); child
!= NULL
; child
= anjuta_project_node_next_sibling (child
))
498 anjuta_project_node_dump_child (child
, indent
);
503 anjuta_project_node_dump (AnjutaProjectNode
*parent
)
505 anjuta_project_node_dump_child (parent
, 0);
510 /* Adding node functions
511 *---------------------------------------------------------------------------*/
514 * anjuta_project_node_insert_before:
516 * @sibling: (allow-none) (transfer none):
517 * @node: (transfer none):
519 * Returns: (transfer none):
522 anjuta_project_node_insert_before (AnjutaProjectNode
*parent
, AnjutaProjectNode
*sibling
, AnjutaProjectNode
*node
)
524 g_return_val_if_fail (node
!= NULL
, NULL
);
525 g_return_val_if_fail (parent
!= NULL
, node
);
527 /* FIXME: Try to avoid filling parent member to allow these checks
528 g_return_val_if_fail (node->parent == NULL)
530 g_return_val_if_fail (sibling->parent == parent, node);*/
532 g_object_ref_sink (node
);
534 node
->parent
= parent
;
539 node
->prev
= sibling
->prev
;
540 node
->prev
->next
= node
;
541 node
->next
= sibling
;
542 sibling
->prev
= node
;
546 node
->parent
->children
= node
;
547 node
->next
= sibling
;
548 sibling
->prev
= node
;
553 if (parent
->children
)
555 sibling
= parent
->children
;
556 while (sibling
->next
)
557 sibling
= sibling
->next
;
558 node
->prev
= sibling
;
559 sibling
->next
= node
;
563 node
->parent
->children
= node
;
571 * anjuta_project_node_insert_after:
573 * @sibling: (allow-none) (transfer none):
574 * @node: (transfer none):
576 * Returns: (transfer none):
579 anjuta_project_node_insert_after (AnjutaProjectNode
*parent
, AnjutaProjectNode
*sibling
, AnjutaProjectNode
*node
)
581 g_return_val_if_fail (node
!= NULL
, NULL
);
582 g_return_val_if_fail (parent
!= NULL
, node
);
584 /* FIXME: Try to avoid filling parent member to allow these checks
585 g_return_val_if_fail (node->parent == NULL)
587 g_return_val_if_fail (sibling->parent == parent, node);*/
589 g_object_ref_sink (node
);
591 node
->parent
= parent
;
596 sibling
->next
->prev
= node
;
598 node
->next
= sibling
->next
;
599 node
->prev
= sibling
;
600 sibling
->next
= node
;
604 if (parent
->children
)
606 node
->next
= parent
->children
;
607 parent
->children
->prev
= node
;
609 parent
->children
= node
;
616 * anjuta_project_node_remove:
617 * @node: (transfer none):
619 * Returns: (transfer full):
622 anjuta_project_node_remove (AnjutaProjectNode
*node
)
624 g_return_val_if_fail (node
!= NULL
, NULL
);
627 node
->prev
->next
= node
->next
;
628 else if (node
->parent
)
629 node
->parent
->children
= node
->next
;
633 node
->next
->prev
= node
->prev
;
642 * anjuta_project_node_prepend:
644 * Returns: (transfer none):
647 anjuta_project_node_prepend (AnjutaProjectNode
*parent
, AnjutaProjectNode
*node
)
649 return anjuta_project_node_insert_before (parent
, parent
->children
, node
);
653 * anjuta_project_node_append:
655 * Returns: (transfer none):
658 anjuta_project_node_append (AnjutaProjectNode
*parent
, AnjutaProjectNode
*node
)
660 return anjuta_project_node_insert_before (parent
, NULL
, node
);
664 *---------------------------------------------------------------------------*/
666 AnjutaProjectNodeType
667 anjuta_project_node_get_node_type (const AnjutaProjectNode
*node
)
669 return node
== NULL
? ANJUTA_PROJECT_UNKNOWN
: (node
->type
& ANJUTA_PROJECT_TYPE_MASK
);
672 AnjutaProjectNodeType
673 anjuta_project_node_get_full_type (const AnjutaProjectNode
*node
)
675 return node
== NULL
? ANJUTA_PROJECT_UNKNOWN
: node
->type
;
679 AnjutaProjectNodeState
680 anjuta_project_node_get_state (const AnjutaProjectNode
*node
)
682 return node
== NULL
? ANJUTA_PROJECT_OK
: (node
->state
);
686 anjuta_project_node_get_name (const AnjutaProjectNode
*node
)
688 if ((node
->name
== NULL
) && (node
->file
!= NULL
))
690 ((AnjutaProjectNode
*)node
)->name
= g_file_get_basename (node
->file
);
697 * anjuta_project_node_get_file:
699 * Returns: (transfer none):
702 anjuta_project_node_get_file (const AnjutaProjectNode
*node
)
704 switch (node
->type
& ANJUTA_PROJECT_TYPE_MASK
)
706 case ANJUTA_PROJECT_OBJECT
:
707 case ANJUTA_PROJECT_TARGET
:
708 if ((node
->name
) && (node
->parent
!= NULL
) && (node
->parent
->file
!= NULL
))
710 GFile
*file
= g_file_get_child (node
->parent
->file
, node
->name
);
712 if ((node
->file
!= NULL
) && g_file_equal (node
->file
, file
))
714 /* Keep the same file */
715 g_object_unref (file
);
719 /* Parent has been updated, update file */
720 if (node
->file
!= NULL
) g_object_unref (node
->file
);
721 ((AnjutaProjectNode
*)node
)->file
= file
;
733 * anjuta_project_node_get_custom_properties:
735 * Returns: (transfer none) (element-type Anjuta.ProjectProperty):
738 anjuta_project_node_get_custom_properties (AnjutaProjectNode
*node
)
740 return node
->custom_properties
;
744 * anjuta_project_node_get_native_properties:
746 * Returns: (transfer none) (element-type Anjuta.ProjectProperty):
749 anjuta_project_node_get_native_properties (AnjutaProjectNode
*node
)
751 return node
->native_properties
;
755 find_property (gconstpointer item
, gconstpointer data
)
757 AnjutaProjectProperty
*prop_a
= (AnjutaProjectProperty
*)item
;
758 AnjutaProjectProperty
*prop_b
= (AnjutaProjectProperty
*)data
;
760 if (prop_a
->native
!= NULL
) prop_a
= prop_a
->native
;
761 if (prop_b
->native
!= NULL
) prop_b
= prop_b
->native
;
763 return prop_a
!= prop_b
;
767 * anjuta_project_node_get_property:
769 * Returns: (transfer none):
771 AnjutaProjectProperty
*
772 anjuta_project_node_get_property (AnjutaProjectNode
*node
, AnjutaProjectProperty
*property
)
776 /* Search in custom properties */
777 found
= g_list_find_custom (node
->custom_properties
, property
, find_property
);
781 /* Search in native properties */
782 found
= g_list_find_custom (node
->native_properties
, property
, find_property
);
785 return found
!= NULL
? (AnjutaProjectProperty
*)found
->data
: NULL
;
788 /* If name is specified, look for a property with the same name, useful for
790 AnjutaProjectProperty
*
791 anjuta_project_node_get_map_property (AnjutaProjectNode
*node
, AnjutaProjectProperty
*property
, const gchar
*name
)
795 /* Check if the property is already the right one */
796 if (property
->native
!= NULL
)
798 found
= g_list_find (node
->custom_properties
, property
);
801 /* Search in custom properties */
804 found
= g_list_find_custom (node
->custom_properties
, property
, find_property
);
807 while ((found
!= NULL
) && (strcmp (name
, ((AnjutaProjectProperty
*)found
->data
)->name
) != 0))
809 found
= g_list_find_custom (g_list_next (found
), property
, find_property
);
816 /* Search in native properties */
817 found
= g_list_find_custom (node
->native_properties
, property
, find_property
);
820 return found
!= NULL
? (AnjutaProjectProperty
*)found
->data
: NULL
;
824 *---------------------------------------------------------------------------*/
827 anjuta_project_node_set_state (AnjutaProjectNode
*node
, AnjutaProjectNodeState state
)
829 if (node
== NULL
) return FALSE
;
830 node
->state
|= state
;
835 anjuta_project_node_clear_state (AnjutaProjectNode
*node
, AnjutaProjectNodeState state
)
837 if (node
== NULL
) return FALSE
;
838 node
->state
&= ~state
;
843 * anjuta_project_node_insert_property:
844 * @property: (transfer full):
846 * Returns: (transfer none):
849 AnjutaProjectProperty
*
850 anjuta_project_node_insert_property (AnjutaProjectNode
*node
, AnjutaProjectProperty
*native
, AnjutaProjectProperty
*property
)
852 /* Make sure the property is native */
853 if (native
->native
!= NULL
) native
= native
->native
;
855 /* Fill missing information */
856 if (property
->name
== NULL
) property
->name
= native
->name
;
857 property
->type
= native
->type
;
858 property
->native
= native
;
859 property
->flags
= native
->flags
;
860 property
->detail
= native
->detail
;
862 /* Get properties list */
863 node
->custom_properties
= g_list_append (node
->custom_properties
, property
);
868 AnjutaProjectProperty
*
869 anjuta_project_node_remove_property (AnjutaProjectNode
*node
, AnjutaProjectProperty
*prop
)
872 AnjutaProjectProperty
*removed
= NULL
;
874 /* Search the exact property, useful for list property */
875 found
= g_list_find (node
->custom_properties
, prop
);
878 found
= g_list_find_custom (node
->custom_properties
, prop
, find_property
);
883 removed
= (AnjutaProjectProperty
*)found
->data
;
884 node
->custom_properties
= g_list_delete_link (node
->custom_properties
, found
);
885 /* If name is not owned by the property, remove it as the
886 * property can be associated with another one, having a
888 if ((removed
->native
!= NULL
) && (removed
->name
== removed
->native
->name
))
890 removed
->name
= NULL
;
899 /* Get node from file functions
900 *---------------------------------------------------------------------------*/
903 anjuta_project_group_compare (AnjutaProjectNode
*node
, gpointer data
)
905 GFile
*file
= (GFile
*)data
;
907 if (((node
->type
& ANJUTA_PROJECT_TYPE_MASK
) == ANJUTA_PROJECT_GROUP
) && g_file_equal (node
->file
, file
))
918 * anjuta_project_node_get_group_from_file:
919 * @func: (scope call):
921 * Returns: (transfer none):
924 anjuta_project_node_get_group_from_file (const AnjutaProjectNode
*root
, GFile
*directory
)
926 AnjutaProjectNode
*node
;
928 node
= anjuta_project_node_traverse ((AnjutaProjectNode
*)root
, G_PRE_ORDER
, anjuta_project_group_compare
, directory
);
934 anjuta_project_target_compare (AnjutaProjectNode
*node
, gpointer data
)
936 const gchar
*name
= (gchar
*)data
;
938 if (((node
->type
& ANJUTA_PROJECT_TYPE_MASK
) == ANJUTA_PROJECT_TARGET
) && (strcmp (node
->name
, name
) == 0))
949 anjuta_project_target_get_node_from_name (const AnjutaProjectNode
*parent
, const gchar
*name
)
951 AnjutaProjectNode
*node
;
953 node
= anjuta_project_node_traverse ((AnjutaProjectNode
*)parent
, G_PRE_ORDER
, anjuta_project_target_compare
, (gpointer
)name
);
959 anjuta_project_source_compare (AnjutaProjectNode
*node
, gpointer data
)
961 GFile
*file
= (GFile
*)data
;
963 if (((node
->type
& ANJUTA_PROJECT_TYPE_MASK
) == ANJUTA_PROJECT_SOURCE
) && g_file_equal (node
->file
, file
))
974 * anjuta_project_node_get_source_from_file:
975 * @func: (scope call):
977 * Returns: (transfer none):
980 anjuta_project_node_get_source_from_file (const AnjutaProjectNode
*parent
, GFile
*file
)
982 AnjutaProjectNode
*node
;
985 node
= anjuta_project_node_traverse ((AnjutaProjectNode
*)parent
, G_PRE_ORDER
, anjuta_project_source_compare
, (gpointer
)file
);
992 *---------------------------------------------------------------------------*/
1007 PROP_NATIVE_PROPERTIES
,
1008 PROP_CUSTOM_PROPERTIES
1012 static unsigned int anjuta_project_node_signals
[LAST_SIGNAL
] = { 0 };
1014 G_DEFINE_TYPE (AnjutaProjectNode
, anjuta_project_node
, G_TYPE_INITIALLY_UNOWNED
);
1017 anjuta_project_node_init (AnjutaProjectNode
*node
)
1021 node
->parent
= NULL
;
1022 node
->children
= NULL
;
1026 node
->native_properties
= NULL
;
1027 node
->custom_properties
= NULL
;
1033 anjuta_project_node_dispose (GObject
*object
)
1035 AnjutaProjectNode
*node
= ANJUTA_PROJECT_NODE(object
);
1037 anjuta_project_node_remove (node
);
1039 if (node
->file
!= NULL
) g_object_unref (node
->file
);
1042 while (node
->children
!= NULL
)
1044 AnjutaProjectNode
*child
;
1046 child
= anjuta_project_node_remove (node
->children
);
1047 g_object_unref (child
);
1050 G_OBJECT_CLASS (anjuta_project_node_parent_class
)->dispose (object
);
1054 anjuta_project_node_finalize (GObject
*object
)
1056 AnjutaProjectNode
*node
= ANJUTA_PROJECT_NODE(object
);
1058 if (node
->name
!= NULL
) g_free (node
->name
);
1060 G_OBJECT_CLASS (anjuta_project_node_parent_class
)->finalize (object
);
1064 anjuta_project_node_get_gobject_property (GObject
*object
,
1069 AnjutaProjectNode
*node
= ANJUTA_PROJECT_NODE(object
);
1072 g_value_set_string (value
, anjuta_project_node_get_name (node
));
1075 g_value_set_object (value
, node
->file
);
1078 g_value_set_flags (value
, anjuta_project_node_get_state (node
));
1081 g_value_set_flags (value
, anjuta_project_node_get_node_type (node
));
1083 case PROP_NATIVE_PROPERTIES
:
1084 g_value_set_pointer (value
, node
->native_properties
);
1086 case PROP_CUSTOM_PROPERTIES
:
1087 g_value_set_pointer (value
, node
->custom_properties
);
1090 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
1095 anjuta_project_node_set_gobject_property (GObject
*object
,
1097 const GValue
*value
,
1100 AnjutaProjectNode
*node
= ANJUTA_PROJECT_NODE(object
);
1103 if (node
->name
!= NULL
)
1104 g_free (node
->name
);
1105 node
->name
= g_value_dup_string (value
);
1108 if (node
->file
!= NULL
)
1109 g_object_unref (node
->file
);
1110 node
->file
= g_value_dup_object (value
);
1113 anjuta_project_node_set_state (node
, g_value_get_flags (value
));
1116 node
->type
= g_value_get_flags (value
);
1118 case PROP_NATIVE_PROPERTIES
:
1119 node
->native_properties
= g_value_get_pointer (value
);
1121 /* XXX: We may need to copy this instead */
1122 case PROP_CUSTOM_PROPERTIES
:
1123 node
->custom_properties
= g_value_get_pointer (value
);
1126 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
1131 anjuta_project_node_class_init (AnjutaProjectNodeClass
*klass
)
1133 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
1136 object_class
->finalize
= anjuta_project_node_finalize
;
1137 object_class
->dispose
= anjuta_project_node_dispose
;
1138 object_class
->get_property
= anjuta_project_node_get_gobject_property
;
1139 object_class
->set_property
= anjuta_project_node_set_gobject_property
;
1141 /*Change both signal to use marshal_VOID__POINTER_BOXED
1142 adding a AnjutaProjectNode pointer corresponding to the
1144 Such marshal doesn't exist as glib marshal, so look in the
1145 symbol db plugin how to add new marshal => done
1147 This new argument can be used in the plugin object in
1148 order to add corresponding shortcut when the project
1149 is loaded and a new node is loaded.
1150 The plugin should probably get the GFile from the
1151 AnjutaProjectNode object and then use a function
1152 in project-view.c to create the corresponding shortcut*/
1154 anjuta_project_node_signals
[UPDATED
] = g_signal_new ("updated",
1155 G_OBJECT_CLASS_TYPE (object_class
),
1157 G_STRUCT_OFFSET (AnjutaProjectNodeClass
, updated
),
1159 anjuta_cclosure_marshal_VOID__STRING_BOXED
,
1165 anjuta_project_node_signals
[LOADED
] = g_signal_new ("loaded",
1166 G_OBJECT_CLASS_TYPE (object_class
),
1168 G_STRUCT_OFFSET (AnjutaProjectNodeClass
, loaded
),
1170 anjuta_cclosure_marshal_VOID__STRING_BOXED
,
1176 pspec
= g_param_spec_flags ("type",
1179 ANJUTA_TYPE_PROJECT_NODE_TYPE
,
1181 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1182 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_TYPE
,
1185 pspec
= g_param_spec_flags ("state",
1188 ANJUTA_TYPE_PROJECT_NODE_STATE
,
1190 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1191 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_STATE
,
1194 pspec
= g_param_spec_string ("name",
1198 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1199 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_NAME
,
1202 pspec
= g_param_spec_object ("file",
1204 "The GFile for the node",
1206 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1207 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_FILE
,
1211 * AnjutaProjectNode:native-properties:
1213 * type: GLib.List<Anjuta.ProjectProperty>
1216 pspec
= g_param_spec_pointer ("native-properties",
1217 "Native properties",
1218 "The list of all possible properties",
1219 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1220 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_NATIVE_PROPERTIES
,
1223 * AnjutaProjectNode:custom-properties:
1225 * Type: GLib.List<Anjuta.ProjectProperty>
1228 pspec
= g_param_spec_pointer ("custom-properties",
1229 "Custom properties",
1230 "The list of overriden properties",
1231 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
1232 g_object_class_install_property (G_OBJECT_CLASS (klass
), PROP_CUSTOM_PROPERTIES
,
1240 *---------------------------------------------------------------------------*/
1243 *---------------------------------------------------------------------------*/
1246 anjuta_project_node_info_name (const AnjutaProjectNodeInfo
*info
)
1252 anjuta_project_node_info_mime (const AnjutaProjectNodeInfo
*info
)
1254 return info
->mime_type
;
1257 AnjutaProjectNodeType
1258 anjuta_project_node_info_type (const AnjutaProjectNodeInfo
*info
)
1264 * anjuta_project_node_info_new:
1265 * @name: (transfer none):
1266 * @mime_type: (transfer none):
1268 * Returns: (transfer full):
1270 AnjutaProjectNodeInfo
*
1271 anjuta_project_node_info_new (AnjutaProjectNodeType type
,
1273 const gchar
*mime_type
)
1275 AnjutaProjectNodeInfo
*info
= g_slice_new0 (AnjutaProjectNodeInfo
);
1277 info
->name
= g_strdup (name
);
1278 info
->mime_type
= g_strdup (mime_type
);
1283 AnjutaProjectNodeInfo
*
1284 anjuta_project_node_info_copy (AnjutaProjectNodeInfo
*info
)
1286 return anjuta_project_node_info_new (info
->type
, info
->name
, info
->mime_type
);
1289 void anjuta_project_node_info_free (AnjutaProjectNodeInfo
*info
)
1291 g_slice_free (AnjutaProjectNodeInfo
, info
);
1294 /* Implement Boxed type
1295 *---------------------------------------------------------------------------*/
1298 anjuta_project_node_info_get_type ()
1300 static GType type_id
= 0;
1303 type_id
= g_boxed_type_register_static ("AnjutaProjectNodeInfo",
1304 (GBoxedCopyFunc
) anjuta_project_node_info_copy
,
1305 (GBoxedFreeFunc
) anjuta_project_node_info_free
);