git: Implement the Tags pane
[anjuta.git] / libanjuta / anjuta-project.c
blob666b72bf91c6fed20e3cf2effba35743a37cbeb8
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"
24 #include <string.h>
26 /**
27 * SECTION:anjuta-project
28 * @title: Anjuta project
29 * @short_description: Anjuta project
30 * @see_also:
31 * @stability: Unstable
32 * @include: libanjuta/anjuta-project.h
34 * A project in Anjuta is represented by a tree. There are three kinds of node.
36 * A source node represents a source file. These are lead of the tree, a source
37 * node cannot have children.
39 * A target node represents an object file defined explicitely.
40 * There are different kinds of target: program, library...
41 * A target have as children all source needed to build it.
43 * A group node is used to group several target or source, it can represent
44 * a directory by example. The root node of the project is a group node
45 * representing the project directory.
47 * All these nodes are base objects. They have derived in each project backend
48 * to provide more specific information.
49 */
51 /* convenient shortcut macro the get the AnjutaProjectNode from a GNode */
52 #define NODE_DATA(node) ((node) != NULL ? (AnjutaProjectNodeData *)((node)->data) : NULL)
53 #define GROUP_DATA(node) ((node) != NULL ? (AnjutaProjectGroupData *)((node)->data) : NULL)
54 #define TARGET_DATA(node) ((node) != NULL ? (AnjutaProjectTargetData *)((node)->data) : NULL)
55 #define SOURCE_DATA(node) ((node) != NULL ? (AnjutaProjectSourceData *)((node)->data) : NULL)
58 /* Node access functions
59 *---------------------------------------------------------------------------*/
61 AnjutaProjectNode *
62 anjuta_project_node_parent(AnjutaProjectNode *node)
64 return node->parent;
67 AnjutaProjectNode *
68 anjuta_project_node_first_child(AnjutaProjectNode *node)
70 return g_node_first_child (node);
73 AnjutaProjectNode *
74 anjuta_project_node_last_child(AnjutaProjectNode *node)
76 return g_node_last_child (node);
79 AnjutaProjectNode *
80 anjuta_project_node_next_sibling (AnjutaProjectNode *node)
82 return g_node_next_sibling (node);
85 AnjutaProjectNode *
86 anjuta_project_node_prev_sibling (AnjutaProjectNode *node)
88 return g_node_prev_sibling (node);
91 AnjutaProjectNode *anjuta_project_node_nth_child (AnjutaProjectNode *node, guint n)
93 return g_node_nth_child (node, n);
96 typedef struct
98 AnjutaProjectNodeFunc func;
99 gpointer data;
100 } AnjutaProjectNodePacket;
102 static gboolean
103 anjuta_project_node_traverse_func (GNode *node, gpointer data)
105 AnjutaProjectNodePacket *pack = (AnjutaProjectNodePacket *)data;
107 pack->func ((AnjutaProjectNode *)node, pack->data);
109 return FALSE;
112 void
113 anjuta_project_node_all_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data)
115 AnjutaProjectNodePacket pack = {func, data};
117 /* POST_ORDER is important when deleting the node, children has to be
118 * deleted first */
119 g_node_traverse (node, G_POST_ORDER, G_TRAVERSE_ALL, -1, anjuta_project_node_traverse_func, &pack);
122 void
123 anjuta_project_node_children_foreach (AnjutaProjectNode *node, AnjutaProjectNodeFunc func, gpointer data)
125 g_node_children_foreach (node, G_TRAVERSE_ALL, func, data);
128 AnjutaProjectNode *
129 anjuta_project_node_append (AnjutaProjectNode *parent, AnjutaProjectNode *node)
131 return g_node_append (parent, node);
134 AnjutaProjectNode *
135 anjuta_project_node_insert_before (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node)
137 return g_node_insert_before (parent, sibling, node);
140 AnjutaProjectNode *
141 anjuta_project_node_insert_after (AnjutaProjectNode *parent, AnjutaProjectNode *sibling, AnjutaProjectNode *node)
143 return g_node_insert_after (parent, sibling, node);
146 AnjutaProjectNode *
147 anjuta_project_node_prepend (AnjutaProjectNode *parent, AnjutaProjectNode *node)
149 return g_node_prepend (parent, node);
153 AnjutaProjectNodeType
154 anjuta_project_node_type (const AnjutaProjectNode *node)
156 return node == NULL ? ANJUTA_PROJECT_UNKNOWN : NODE_DATA (node)->type;
159 gchar *
160 anjuta_project_node_get_name (const AnjutaProjectNode *node)
162 switch (NODE_DATA (node)->type)
164 case ANJUTA_PROJECT_GROUP:
165 return g_file_get_basename (GROUP_DATA (node)->directory);
166 case ANJUTA_PROJECT_TARGET:
167 return g_strdup (TARGET_DATA (node)->name);
168 case ANJUTA_PROJECT_SOURCE:
169 return g_file_get_basename (SOURCE_DATA (node)->file);
170 default:
171 return NULL;
175 gchar*
176 anjuta_project_node_get_uri (AnjutaProjectNode *node)
178 AnjutaProjectGroup *parent;
179 GFile *file;
180 gchar *uri;
182 switch (NODE_DATA (node)->type)
184 case ANJUTA_PROJECT_GROUP:
185 uri = g_file_get_uri (GROUP_DATA (node)->directory);
186 break;
187 case ANJUTA_PROJECT_TARGET:
188 parent = anjuta_project_node_parent (node);
189 file = g_file_get_child (anjuta_project_group_get_directory (parent), anjuta_project_target_get_name (node));
190 uri = g_file_get_uri (file);
191 g_object_unref (file);
192 break;
193 case ANJUTA_PROJECT_SOURCE:
194 uri = g_file_get_uri (SOURCE_DATA (node)->file);
195 break;
196 default:
197 uri = NULL;
198 break;
201 return uri;
204 GFile*
205 anjuta_project_node_get_file (AnjutaProjectNode *node)
207 AnjutaProjectGroup *parent;
208 GFile *file;
210 switch (NODE_DATA (node)->type)
212 case ANJUTA_PROJECT_GROUP:
213 file = g_object_ref (GROUP_DATA (node)->directory);
214 break;
215 case ANJUTA_PROJECT_TARGET:
216 parent = anjuta_project_node_parent (node);
217 file = g_file_get_child (anjuta_project_group_get_directory (parent), anjuta_project_target_get_name (node));
218 break;
219 case ANJUTA_PROJECT_SOURCE:
220 file = g_object_ref (SOURCE_DATA (node)->file);
221 break;
222 default:
223 file = NULL;
224 break;
227 return file;
230 /* Group access functions
231 *---------------------------------------------------------------------------*/
233 GFile*
234 anjuta_project_group_get_directory (const AnjutaProjectGroup *group)
236 return GROUP_DATA (group)->directory;
239 static gboolean
240 anjuta_project_group_compare (GNode *node, gpointer data)
242 GFile *file = *(GFile **)data;
244 if ((NODE_DATA(node)->type == ANJUTA_PROJECT_GROUP) && g_file_equal (GROUP_DATA(node)->directory, file))
246 *(AnjutaProjectNode **)data = node;
248 return TRUE;
250 else
252 return FALSE;
256 AnjutaProjectGroup *
257 anjuta_project_group_get_node_from_file (const AnjutaProjectGroup *root, GFile *directory)
259 GFile *data;
261 data = directory;
262 g_node_traverse ((GNode *)root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, anjuta_project_group_compare, &data);
264 return (data == directory) ? NULL : (AnjutaProjectNode *)data;
267 AnjutaProjectGroup *
268 anjuta_project_group_get_node_from_uri (const AnjutaProjectNode *root, const gchar *uri)
270 GFile *file = g_file_new_for_uri (uri);
271 AnjutaProjectGroup *node;
273 node = anjuta_project_group_get_node_from_file (root, file);
274 g_object_unref (file);
276 return node;
279 static gboolean
280 anjuta_project_target_compare (GNode *node, gpointer data)
282 const gchar *name = *(gchar **)data;
284 if ((NODE_DATA(node)->type == ANJUTA_PROJECT_TARGET) && (strcmp (TARGET_DATA(node)->name, name) == 0))
286 *(AnjutaProjectNode **)data = node;
288 return TRUE;
290 else
292 return FALSE;
296 AnjutaProjectTarget *
297 anjuta_project_target_get_node_from_name (const AnjutaProjectGroup *parent, const gchar *name)
299 const gchar *data;
301 data = name;
302 g_node_traverse ((GNode *)parent, G_PRE_ORDER, G_TRAVERSE_ALL, 2, anjuta_project_target_compare, &data);
304 return (data == name) ? NULL : (AnjutaProjectTarget *)data;
307 static gboolean
308 anjuta_project_source_compare (GNode *node, gpointer data)
310 GFile *file = *(GFile **)data;
312 if ((NODE_DATA(node)->type == ANJUTA_PROJECT_SOURCE) && g_file_equal (SOURCE_DATA(node)->file, file))
314 *(AnjutaProjectNode **)data = node;
316 return TRUE;
318 else
320 return FALSE;
324 AnjutaProjectSource *
325 anjuta_project_source_get_node_from_file (const AnjutaProjectNode *parent, GFile *file)
327 GFile *data;
329 data = file;
330 g_node_traverse ((GNode *)parent, G_PRE_ORDER, G_TRAVERSE_ALL, 2, anjuta_project_source_compare, &data);
332 return (data == file) ? NULL : (AnjutaProjectNode *)data;
335 AnjutaProjectSource *
336 anjuta_project_source_get_node_from_uri (const AnjutaProjectNode *parent, const gchar *uri)
338 GFile *file = g_file_new_for_uri (uri);
339 AnjutaProjectSource *node;
341 node = anjuta_project_source_get_node_from_file (parent, file);
342 g_object_unref (file);
344 return node;
347 /* Target access functions
348 *---------------------------------------------------------------------------*/
350 const gchar *
351 anjuta_project_target_get_name (const AnjutaProjectTarget *target)
353 return TARGET_DATA (target)->name;
356 AnjutaProjectTargetType
357 anjuta_project_target_type (const AnjutaProjectTarget *target)
359 return TARGET_DATA (target)->type;
362 /* Source access functions
363 *---------------------------------------------------------------------------*/
365 GFile*
366 anjuta_project_source_get_file (const AnjutaProjectSource *source)
368 return SOURCE_DATA (source)->file;
371 /* Target type functions
372 *---------------------------------------------------------------------------*/
374 const gchar *
375 anjuta_project_target_type_name (const AnjutaProjectTargetType type)
377 return type->name;
380 const gchar *
381 anjuta_project_target_type_mime (const AnjutaProjectTargetType type)
383 return type->mime_type;
386 AnjutaProjectTargetClass
387 anjuta_project_target_type_class (const AnjutaProjectTargetType type)
389 return type->base;