Updated files for 2.91.90 release
[anjuta.git] / libanjuta / anjuta-project.c
blob38f64ccb20b1130eb6a0e0080d24cd26216d1e5d
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta-project.c
4 * Copyright (C) Sébastien Granjoux 2009 <seb.sfo@free.fr>
5 *
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"
26 #include <string.h>
28 /**
29 * SECTION:anjuta-project
30 * @title: Anjuta project
31 * @short_description: Anjuta project
32 * @see_also:
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
40 * mandatory.
42 * A module node represents a module in autotools project, it is a group of
43 * packages.
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.
59 */
61 /* Node properties
62 *---------------------------------------------------------------------------*/
64 /* Implement Boxed type
65 *---------------------------------------------------------------------------*/
67 /**
68 * anjuta_project_property_new:
69 * name: (transfer none):
70 * value: (transfer none):
71 * native: (allow-none) (transfer none):
73 * Returns: (transfer full):
75 AnjutaProjectProperty *
76 anjuta_project_property_new (const gchar *name, AnjutaProjectValueType type,
77 const gchar *value, AnjutaProjectProperty *native)
79 AnjutaProjectProperty *prop = g_slice_new0(AnjutaProjectProperty);
80 prop->name = g_strdup (name);
81 prop->type = type;
82 prop->value = g_strdup (value);
83 prop->native = native;
84 prop->flags = native->flags;
85 prop->detail = native->detail;
87 return prop;
90 AnjutaProjectProperty *
91 anjuta_project_property_copy (AnjutaProjectProperty *prop)
93 return anjuta_project_property_new (prop->name, prop->type,
94 prop->value, prop->native);
97 void
98 anjuta_project_property_free (AnjutaProjectProperty *prop)
100 g_free (prop->name);
101 g_free (prop->value);
102 g_slice_free (AnjutaProjectProperty, prop);
105 GType
106 anjuta_project_property_get_type (void)
108 static GType type_id = 0;
110 if (!type_id)
111 type_id = g_boxed_type_register_static ("AnjutaProjectProperty",
112 (GBoxedCopyFunc) anjuta_project_property_copy,
113 (GBoxedFreeFunc) anjuta_project_property_free);
115 return type_id;
120 /* Node
121 *---------------------------------------------------------------------------*/
124 /* Moving in tree functions
125 *---------------------------------------------------------------------------*/
127 AnjutaProjectNode *
128 anjuta_project_node_parent(AnjutaProjectNode *node)
130 g_return_val_if_fail (node != NULL, NULL);
132 return node->parent;
135 AnjutaProjectNode *
136 anjuta_project_node_root (AnjutaProjectNode *node)
138 g_return_val_if_fail (node != NULL, NULL);
140 while (node->parent != NULL)
142 node = node->parent;
145 return node;
148 AnjutaProjectNode *
149 anjuta_project_node_first_child(AnjutaProjectNode *node)
151 g_return_val_if_fail (node != NULL, NULL);
153 return node->children;
156 AnjutaProjectNode *
157 anjuta_project_node_last_child(AnjutaProjectNode *node)
159 g_return_val_if_fail (node != NULL, NULL);
161 node = node->children;
162 if (node)
163 while (node->next)
164 node = node->next;
166 return node;
169 AnjutaProjectNode *
170 anjuta_project_node_next_sibling (AnjutaProjectNode *node)
172 g_return_val_if_fail (node != NULL, NULL);
174 return node->next;
177 AnjutaProjectNode *
178 anjuta_project_node_prev_sibling (AnjutaProjectNode *node)
180 g_return_val_if_fail (node != NULL, NULL);
182 return node->prev;
185 AnjutaProjectNode *anjuta_project_node_nth_child (AnjutaProjectNode *node, guint n)
187 g_return_val_if_fail (node != NULL, NULL);
189 node = node->children;
190 if (node)
191 while ((n-- > 0) && node)
192 node = node->next;
194 return node;
197 static AnjutaProjectNode *
198 anjuta_project_node_post_order_traverse (AnjutaProjectNode *node, AnjutaProjectNodeTraverseFunc func, gpointer data)
200 AnjutaProjectNode *child;
202 child = node->children;
203 while (child != NULL)
205 AnjutaProjectNode *current;
207 current = child;
208 child = current->next;
209 current = anjuta_project_node_post_order_traverse (current, func, data);
210 if (current != NULL)
212 return current;
216 return func (node, data) ? node : NULL;
219 static AnjutaProjectNode *
220 anjuta_project_node_pre_order_traverse (AnjutaProjectNode *node, AnjutaProjectNodeTraverseFunc func, gpointer data)
222 AnjutaProjectNode *child;
224 if (func (node, data))
226 return node;
229 child = node->children;
230 while (child != NULL)
232 AnjutaProjectNode *current;
234 current = child;
235 child = current->next;
236 current = anjuta_project_node_pre_order_traverse (current, func, data);
237 if (current != NULL)
239 return current;
243 return NULL;
247 AnjutaProjectNode *
248 anjuta_project_node_traverse (AnjutaProjectNode *node, GTraverseType order, AnjutaProjectNodeTraverseFunc func, gpointer data)
250 g_return_val_if_fail (node != NULL, NULL);
251 g_return_val_if_fail (func != NULL, NULL);
252 g_return_val_if_fail ((order != G_PRE_ORDER) || (order != G_POST_ORDER), NULL);
254 switch (order)
256 case G_PRE_ORDER:
257 return anjuta_project_node_pre_order_traverse (node, func, data);
258 case G_POST_ORDER:
259 return anjuta_project_node_post_order_traverse (node, func, data);
260 default:
261 return NULL;
265 AnjutaProjectNode *
266 anjuta_project_node_children_traverse (AnjutaProjectNode *node, AnjutaProjectNodeTraverseFunc func, gpointer data)
268 AnjutaProjectNode *child;
270 g_return_val_if_fail (node != NULL, NULL);
272 child = node->children;
273 while (child != NULL)
275 AnjutaProjectNode *current;
277 current = child;
278 child = current->next;
279 if (func (current, data))
281 return current;
285 return NULL;
288 static void
289 anjuta_project_node_post_order_foreach (AnjutaProjectNode *node, AnjutaProjectNodeForeachFunc func, gpointer data)
291 AnjutaProjectNode *child;
293 child = node->children;
294 while (child != NULL)
296 AnjutaProjectNode *current;
298 current = child;
299 child = current->next;
300 anjuta_project_node_post_order_foreach (current, func, data);
303 func (node, data);
306 static void
307 anjuta_project_node_pre_order_foreach (AnjutaProjectNode *node, AnjutaProjectNodeForeachFunc func, gpointer data)
309 AnjutaProjectNode *child;
311 func (node, data);
313 child = node->children;
314 while (child != NULL)
316 AnjutaProjectNode *current;
318 current = child;
319 child = current->next;
320 anjuta_project_node_pre_order_foreach (current, func, data);
325 void
326 anjuta_project_node_foreach (AnjutaProjectNode *node, GTraverseType order, AnjutaProjectNodeForeachFunc func, gpointer data)
328 g_return_if_fail (node != NULL);
329 g_return_if_fail (func != NULL);
330 g_return_if_fail ((order != G_PRE_ORDER) || (order != G_POST_ORDER));
332 switch (order)
334 case G_PRE_ORDER:
335 anjuta_project_node_pre_order_foreach (node, func, data);
336 break;
337 case G_POST_ORDER:
338 anjuta_project_node_post_order_foreach (node, func, data);
339 break;
340 default:
341 break;
345 void
346 anjuta_project_node_children_foreach (AnjutaProjectNode *node, AnjutaProjectNodeForeachFunc func, gpointer data)
348 AnjutaProjectNode *child;
350 g_return_if_fail (node != NULL);
352 child = node->children;
353 while (child != NULL)
355 AnjutaProjectNode *current;
357 current = child;
358 child = current->next;
359 func (current, data);
364 /* Debugging functions
365 *---------------------------------------------------------------------------*/
367 static gboolean check_node (AnjutaProjectNode *node, gpointer data)
369 if (!ANJUTA_IS_PROJECT_NODE (node)) g_critical (" Node %p of %p is not a AnjutaProjectNode", node, data);
370 if (node->prev == NULL)
372 if ((node->parent != NULL) && (node->parent->children != node)) g_critical (" Node %p of %p has the wrong parent", node, data);
374 else
376 if (node->prev->next != node) g_critical (" Node %p of %p has the wrong predecessor", node, data);
377 if (node->prev->parent != node->parent) g_critical (" Node %p of %p has the wrong parent", node, data);
379 if (node->next != NULL)
381 if (node->next->prev != node) g_critical (" Node %p of %p has the wrong successor", node, data);
383 if (node->children != NULL)
385 if (node->children->parent != node) g_critical (" Node %p of %p has the wrong children", node, data);
388 return FALSE;
391 void
392 anjuta_project_node_check (AnjutaProjectNode *parent)
394 AnjutaProjectNode *node;
396 g_message ("Check node %p", parent);
397 node = anjuta_project_node_traverse (parent, G_POST_ORDER, check_node, parent);
398 if (node == NULL) g_message (" Node %p is valid", parent);
402 static void
403 anjuta_project_node_show (AnjutaProjectNode *node, gint indent)
405 g_message("%*s %p: %s", indent, "", node, node != NULL ? anjuta_project_node_get_name (node) : NULL);
408 static void
409 anjuta_project_node_dump_child (AnjutaProjectNode *parent, gint indent)
411 AnjutaProjectNode *child;
413 anjuta_project_node_show (parent, indent);
414 indent += 4;
416 for (child = anjuta_project_node_first_child (parent); child != NULL; child = anjuta_project_node_next_sibling (child))
418 anjuta_project_node_dump_child (child, indent);
422 void
423 anjuta_project_node_dump (AnjutaProjectNode *parent)
425 anjuta_project_node_dump_child (parent, 0);
430 /* Adding node functions
431 *---------------------------------------------------------------------------*/
434 * anjuta_project_node_insert_before:
435 * @parent:
436 * @sibling: (allow-none) (transfer none):
437 * @node: (transfer none):
439 * Returns: (transfer none):
441 AnjutaProjectNode *
442 anjuta_project_node_insert_before (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node)
444 g_return_val_if_fail (node != NULL, NULL);
445 g_return_val_if_fail (parent != NULL, node);
447 /* FIXME: Try to avoid filling parent member to allow these checks
448 g_return_val_if_fail (node->parent == NULL)
449 if (sibling)
450 g_return_val_if_fail (sibling->parent == parent, node);*/
452 g_object_ref_sink (node);
454 node->parent = parent;
455 if (sibling)
457 if (sibling->prev)
459 node->prev = sibling->prev;
460 node->prev->next = node;
461 node->next = sibling;
462 sibling->prev = node;
464 else
466 node->parent->children = node;
467 node->next = sibling;
468 sibling->prev = node;
471 else
473 if (parent->children)
475 sibling = parent->children;
476 while (sibling->next)
477 sibling = sibling->next;
478 node->prev = sibling;
479 sibling->next = node;
481 else
483 node->parent->children = node;
487 return node;
491 * anjuta_project_node_insert_after:
492 * @parent:
493 * @sibling: (allow-none) (transfer none):
494 * @node: (transfer none):
496 * Returns: (transfer none):
498 AnjutaProjectNode *
499 anjuta_project_node_insert_after (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node)
501 g_return_val_if_fail (node != NULL, NULL);
502 g_return_val_if_fail (parent != NULL, node);
504 /* FIXME: Try to avoid filling parent member to allow these checks
505 g_return_val_if_fail (node->parent == NULL)
506 if (sibling)
507 g_return_val_if_fail (sibling->parent == parent, node);*/
509 g_object_ref_sink (node);
511 node->parent = parent;
512 if (sibling)
514 if (sibling->next)
516 sibling->next->prev = node;
518 node->next = sibling->next;
519 node->prev = sibling;
520 sibling->next = node;
522 else
524 if (parent->children)
526 node->next = parent->children;
527 parent->children->prev = node;
529 parent->children = node;
532 return node;
536 * anjuta_project_node_remove:
537 * @parent:
538 * @sibling: (allow-none) (transfer none):
539 * @node: (transfer none):
541 * Returns: (transfer full):
543 AnjutaProjectNode *
544 anjuta_project_node_remove (AnjutaProjectNode *node)
546 g_return_val_if_fail (node != NULL, NULL);
548 if (node->prev)
549 node->prev->next = node->next;
550 else if (node->parent)
551 node->parent->children = node->next;
552 node->parent = NULL;
553 if (node->next)
555 node->next->prev = node->prev;
556 node->next = NULL;
558 node->prev = NULL;
560 return node;
563 AnjutaProjectNode *
564 anjuta_project_node_prepend (AnjutaProjectNode *parent, AnjutaProjectNode *node)
566 return anjuta_project_node_insert_before (parent, parent->children, node);
569 AnjutaProjectNode *
570 anjuta_project_node_append (AnjutaProjectNode *parent, AnjutaProjectNode *node)
572 return anjuta_project_node_insert_before (parent, NULL, node);
575 /* Access functions
576 *---------------------------------------------------------------------------*/
578 AnjutaProjectNodeType
579 anjuta_project_node_get_node_type (const AnjutaProjectNode *node)
581 return node == NULL ? ANJUTA_PROJECT_UNKNOWN : (node->type & ANJUTA_PROJECT_TYPE_MASK);
584 AnjutaProjectNodeType
585 anjuta_project_node_get_full_type (const AnjutaProjectNode *node)
587 return node == NULL ? ANJUTA_PROJECT_UNKNOWN : node->type;
591 AnjutaProjectNodeState
592 anjuta_project_node_get_state (const AnjutaProjectNode *node)
594 return node == NULL ? ANJUTA_PROJECT_OK : (node->state);
597 const gchar *
598 anjuta_project_node_get_name (const AnjutaProjectNode *node)
600 if ((node->name == NULL) && (node->file != NULL))
602 ((AnjutaProjectNode *)node)->name = g_file_get_basename (node->file);
605 return node->name;
608 GFile*
609 anjuta_project_node_get_file (const AnjutaProjectNode *node)
611 switch (node->type & ANJUTA_PROJECT_TYPE_MASK)
613 case ANJUTA_PROJECT_TARGET:
614 if ((node->name) && (node->parent != NULL) && (node->parent->file != NULL))
616 GFile *file = g_file_get_child (node->parent->file, node->name);
618 if ((node->file != NULL) && g_file_equal (node->file, file))
620 /* Keep the same file */
621 g_object_unref (file);
623 else
625 /* Parent has been updated, update file */
626 if (node->file != NULL) g_object_unref (node->file);
627 ((AnjutaProjectNode *)node)->file = file;
630 break;
631 default:
632 break;
635 return node->file;
638 GList *
639 anjuta_project_node_get_custom_properties (AnjutaProjectNode *node)
641 return node->custom_properties;
644 GList *
645 anjuta_project_node_get_native_properties (AnjutaProjectNode *node)
647 return node->native_properties;
650 static gint
651 find_property (gconstpointer item, gconstpointer data)
653 AnjutaProjectProperty *prop_a = (AnjutaProjectProperty *)item;
654 AnjutaProjectProperty *prop_b = (AnjutaProjectProperty *)data;
656 if (prop_a->native != NULL) prop_a = prop_a->native;
657 if (prop_b->native != NULL) prop_b = prop_b->native;
659 return prop_a != prop_b;
662 AnjutaProjectProperty *
663 anjuta_project_node_get_property (AnjutaProjectNode *node, AnjutaProjectProperty *property)
665 GList *found;
667 /* Search in custom properties */
668 found = g_list_find_custom (node->custom_properties, property, find_property);
670 if (found == NULL)
672 /* Search in native properties */
673 found = g_list_find_custom (node->native_properties, property, find_property);
676 return found != NULL ? (AnjutaProjectProperty *)found->data : NULL;
680 /* Set functions
681 *---------------------------------------------------------------------------*/
683 gboolean
684 anjuta_project_node_set_state (AnjutaProjectNode *node, AnjutaProjectNodeState state)
686 if (node == NULL) return FALSE;
687 node->state |= state;
688 return TRUE;
691 gboolean
692 anjuta_project_node_clear_state (AnjutaProjectNode *node, AnjutaProjectNodeState state)
694 if (node == NULL) return FALSE;
695 node->state &= ~state;
696 return TRUE;
699 AnjutaProjectProperty *
700 anjuta_project_node_insert_property (AnjutaProjectNode *node, AnjutaProjectProperty *native, AnjutaProjectProperty *property)
702 /* Make sure the property is native */
703 if (native->native != NULL) native = native->native;
705 /* Fill missing information */
706 if (property->name == NULL) property->name = native->name;
707 property->type = native->type;
708 property->native = native;
709 property->flags = native->flags;
710 property->detail = native->detail;
712 /* Get properties list */
713 node->custom_properties = g_list_append (node->custom_properties, property);
715 return property;
718 AnjutaProjectProperty *
719 anjuta_project_node_remove_property (AnjutaProjectNode *node, AnjutaProjectProperty *prop)
721 GList *found;
722 AnjutaProjectProperty *removed = NULL;
724 /* Search the exact property, useful for list property */
725 found = g_list_find (node->custom_properties, prop);
726 if (found == NULL)
728 found = g_list_find_custom (node->custom_properties, prop, find_property);
731 if (found != NULL)
733 removed = (AnjutaProjectProperty *)found->data;
734 node->custom_properties = g_list_delete_link (node->custom_properties, found);
735 /* If name is not owned by the property, remove it as the
736 * property can be associated with another one, having a
737 * different name */
738 if ((removed->native != NULL) && (removed->name == removed->native->name))
740 removed->name = NULL;
745 return removed;
749 /* Get node from file functions
750 *---------------------------------------------------------------------------*/
752 static gboolean
753 anjuta_project_group_compare (AnjutaProjectNode *node, gpointer data)
755 GFile *file = (GFile *)data;
757 if (((node->type & ANJUTA_PROJECT_TYPE_MASK) == ANJUTA_PROJECT_GROUP) && g_file_equal (node->file, file))
759 return TRUE;
761 else
763 return FALSE;
767 AnjutaProjectNode *
768 anjuta_project_group_get_node_from_file (const AnjutaProjectNode *root, GFile *directory)
770 AnjutaProjectNode *node;
772 node = anjuta_project_node_traverse ((AnjutaProjectNode *)root, G_PRE_ORDER, anjuta_project_group_compare, directory);
774 return node;
777 static gboolean
778 anjuta_project_target_compare (AnjutaProjectNode *node, gpointer data)
780 const gchar *name = (gchar *)data;
782 if (((node->type & ANJUTA_PROJECT_TYPE_MASK) == ANJUTA_PROJECT_TARGET) && (strcmp (node->name, name) == 0))
784 return TRUE;
786 else
788 return FALSE;
792 AnjutaProjectNode *
793 anjuta_project_target_get_node_from_name (const AnjutaProjectNode *parent, const gchar *name)
795 AnjutaProjectNode *node;
797 node = anjuta_project_node_traverse ((AnjutaProjectNode *)parent, G_PRE_ORDER, anjuta_project_target_compare, (gpointer)name);
799 return node;
802 static gboolean
803 anjuta_project_source_compare (AnjutaProjectNode *node, gpointer data)
805 GFile *file = (GFile *)data;
807 if (((node->type & ANJUTA_PROJECT_TYPE_MASK) == ANJUTA_PROJECT_SOURCE) && g_file_equal (node->file, file))
809 return TRUE;
811 else
813 return FALSE;
817 AnjutaProjectNode *
818 anjuta_project_source_get_node_from_file (const AnjutaProjectNode *parent, GFile *file)
820 AnjutaProjectNode *node;
823 node = anjuta_project_node_traverse ((AnjutaProjectNode *)parent, G_PRE_ORDER, anjuta_project_source_compare, (gpointer)file);
825 return node;
829 /* Implement GObject
830 *---------------------------------------------------------------------------*/
832 enum
834 UPDATED,
835 LOADED,
836 LAST_SIGNAL
839 enum {
840 PROP_NONE,
841 PROP_NAME,
842 PROP_FILE,
843 PROP_STATE,
844 PROP_TYPE,
845 PROP_NATIVE_PROPERTIES,
846 PROP_CUSTOM_PROPERTIES
850 static unsigned int anjuta_project_node_signals[LAST_SIGNAL] = { 0 };
852 G_DEFINE_TYPE (AnjutaProjectNode, anjuta_project_node, G_TYPE_INITIALLY_UNOWNED);
854 static void
855 anjuta_project_node_init (AnjutaProjectNode *node)
857 node->next = NULL;
858 node->prev = NULL;
859 node->parent = NULL;
860 node->children = NULL;
862 node->type = 0;
863 node->state = 0;
864 node->native_properties = NULL;
865 node->custom_properties = NULL;
866 node->file = NULL;
867 node->name = NULL;
870 static void
871 anjuta_project_node_dispose (GObject *object)
873 AnjutaProjectNode *node = ANJUTA_PROJECT_NODE(object);
875 anjuta_project_node_remove (node);
877 if (node->file != NULL) g_object_unref (node->file);
878 node->file = NULL;
880 while (node->children != NULL)
882 AnjutaProjectNode *child;
884 child = anjuta_project_node_remove (node->children);
885 g_object_unref (child);
888 G_OBJECT_CLASS (anjuta_project_node_parent_class)->dispose (object);
891 static void
892 anjuta_project_node_finalize (GObject *object)
894 AnjutaProjectNode *node = ANJUTA_PROJECT_NODE(object);
896 if (node->name != NULL) g_free (node->name);
898 G_OBJECT_CLASS (anjuta_project_node_parent_class)->finalize (object);
901 static void
902 anjuta_project_node_get_gobject_property (GObject *object,
903 guint prop_id,
904 GValue *value,
905 GParamSpec *pspec)
907 AnjutaProjectNode *node = ANJUTA_PROJECT_NODE(object);
908 switch (prop_id) {
909 case PROP_NAME:
910 g_value_set_string (value, anjuta_project_node_get_name (node));
911 break;
912 case PROP_FILE:
913 g_value_set_object (value, node->file);
914 break;
915 case PROP_STATE:
916 g_value_set_flags (value, anjuta_project_node_get_state (node));
917 break;
918 case PROP_TYPE:
919 g_value_set_flags (value, anjuta_project_node_get_node_type (node));
920 break;
921 case PROP_NATIVE_PROPERTIES:
922 g_value_set_pointer (value, node->native_properties);
923 break;
924 case PROP_CUSTOM_PROPERTIES:
925 g_value_set_pointer (value, node->custom_properties);
926 break;
927 default:
928 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
932 static void
933 anjuta_project_node_set_gobject_property (GObject *object,
934 guint prop_id,
935 const GValue *value,
936 GParamSpec *pspec)
938 AnjutaProjectNode *node = ANJUTA_PROJECT_NODE(object);
939 switch (prop_id) {
940 case PROP_NAME:
941 if (node->name != NULL)
942 g_free (node->name);
943 node->name = g_value_dup_string (value);
944 break;
945 case PROP_FILE:
946 if (node->file != NULL)
947 g_object_unref (node->file);
948 node->file = g_value_dup_object (value);
949 break;
950 case PROP_STATE:
951 anjuta_project_node_set_state (node, g_value_get_flags (value));
952 break;
953 case PROP_TYPE:
954 node->type = g_value_get_flags (value);
955 break;
956 case PROP_NATIVE_PROPERTIES:
957 node->native_properties = g_value_get_pointer (value);
958 break;
959 /* XXX: We may need to copy this instead */
960 case PROP_CUSTOM_PROPERTIES:
961 node->custom_properties = g_value_get_pointer (value);
962 break;
963 default:
964 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
968 static void
969 anjuta_project_node_class_init (AnjutaProjectNodeClass *klass)
971 GObjectClass* object_class = G_OBJECT_CLASS (klass);
972 GParamSpec* pspec;
974 object_class->finalize = anjuta_project_node_finalize;
975 object_class->dispose = anjuta_project_node_dispose;
976 object_class->get_property = anjuta_project_node_get_gobject_property;
977 object_class->set_property = anjuta_project_node_set_gobject_property;
979 /*Change both signal to use marshal_VOID__POINTER_BOXED
980 adding a AnjutaProjectNode pointer corresponding to the
981 loaded node => done
982 Such marshal doesn't exist as glib marshal, so look in the
983 symbol db plugin how to add new marshal => done
984 ToDo :
985 This new argument can be used in the plugin object in
986 order to add corresponding shortcut when the project
987 is loaded and a new node is loaded.
988 The plugin should probably get the GFile from the
989 AnjutaProjectNode object and then use a function
990 in project-view.c to create the corresponding shortcut*/
992 anjuta_project_node_signals[UPDATED] = g_signal_new ("updated",
993 G_OBJECT_CLASS_TYPE (object_class),
994 G_SIGNAL_RUN_LAST,
995 G_STRUCT_OFFSET (AnjutaProjectNodeClass, updated),
996 NULL, NULL,
997 anjuta_cclosure_marshal_VOID__STRING_BOXED,
998 G_TYPE_NONE,
1000 G_TYPE_POINTER,
1001 G_TYPE_ERROR);
1003 anjuta_project_node_signals[LOADED] = g_signal_new ("loaded",
1004 G_OBJECT_CLASS_TYPE (object_class),
1005 G_SIGNAL_RUN_LAST,
1006 G_STRUCT_OFFSET (AnjutaProjectNodeClass, loaded),
1007 NULL, NULL,
1008 anjuta_cclosure_marshal_VOID__STRING_BOXED,
1009 G_TYPE_NONE,
1011 G_TYPE_POINTER,
1012 G_TYPE_ERROR);
1014 pspec = g_param_spec_flags ("type",
1015 "Type",
1016 "Node type",
1017 ANJUTA_TYPE_PROJECT_NODE_TYPE,
1019 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1020 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TYPE,
1021 pspec);
1023 pspec = g_param_spec_flags ("state",
1024 "State",
1025 "Node state",
1026 ANJUTA_TYPE_PROJECT_NODE_STATE,
1028 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1029 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_STATE,
1030 pspec);
1032 pspec = g_param_spec_string ("name",
1033 "Name",
1034 "Node name",
1036 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1037 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_NAME,
1038 pspec);
1040 pspec = g_param_spec_object ("file",
1041 "File",
1042 "The GFile for the node",
1043 G_TYPE_FILE,
1044 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1045 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FILE,
1046 pspec);
1049 * AnjutaProjectNode:native-properties:
1051 * type: GLib.List<Anjuta.ProjectProperty>
1052 * Transfer: none
1054 pspec = g_param_spec_pointer ("native-properties",
1055 "Native properties",
1056 "The list of all possible properties",
1057 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1058 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_NATIVE_PROPERTIES,
1059 pspec);
1061 * AnjutaProjectNode:custom-properties:
1063 * Type: GLib.List<Anjuta.ProjectProperty>
1064 * Transfer: none
1066 pspec = g_param_spec_pointer ("custom-properties",
1067 "Custom properties",
1068 "The list of overriden properties",
1069 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
1070 g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CUSTOM_PROPERTIES,
1071 pspec);
1077 /* Node information
1078 *---------------------------------------------------------------------------*/
1080 /* Public functions
1081 *---------------------------------------------------------------------------*/
1083 const gchar *
1084 anjuta_project_node_info_name (const AnjutaProjectNodeInfo *info)
1086 return info->name;
1089 const gchar *
1090 anjuta_project_node_info_mime (const AnjutaProjectNodeInfo *info)
1092 return info->mime_type;
1095 AnjutaProjectNodeType
1096 anjuta_project_node_info_type (const AnjutaProjectNodeInfo *info)
1098 return info->type;
1102 * anjuta_project_node_info_new:
1103 * name: (transfer none):
1104 * mime_type: (transfer none):
1106 * Returns: (transfer full):
1108 AnjutaProjectNodeInfo *
1109 anjuta_project_node_info_new (AnjutaProjectNodeType type,
1110 const gchar *name,
1111 const gchar *mime_type)
1113 AnjutaProjectNodeInfo *info = g_slice_new0 (AnjutaProjectNodeInfo);
1114 info->type = type;
1115 info->name = g_strdup (name);
1116 info->mime_type = g_strdup (mime_type);
1118 return info;
1121 AnjutaProjectNodeInfo *
1122 anjuta_project_node_info_copy (AnjutaProjectNodeInfo *info)
1124 return anjuta_project_node_info_new (info->type, info->name, info->mime_type);
1127 void anjuta_project_node_info_free (AnjutaProjectNodeInfo *info)
1129 g_slice_free (AnjutaProjectNodeInfo, info);
1132 /* Implement Boxed type
1133 *---------------------------------------------------------------------------*/
1135 GType
1136 anjuta_project_node_info_get_type ()
1138 static GType type_id = 0;
1140 if (!type_id)
1141 type_id = g_boxed_type_register_static ("AnjutaProjectNodeInfo",
1142 (GBoxedCopyFunc) anjuta_project_node_info_copy,
1143 (GBoxedFreeFunc) anjuta_project_node_info_free);
1145 return type_id;