1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
4 * Copyright (C) 2009 Sébastien Granjoux
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
27 #include "mk-project.h"
30 #include "mk-project-private.h"
32 #include <libanjuta/interfaces/ianjuta-project.h>
33 #include <libanjuta/anjuta-debug.h>
34 #include <libanjuta/anjuta-utils.h>
35 #include <libanjuta/anjuta-pkg-config.h>
43 #include <sys/types.h>
45 #include <glib/gi18n.h>
48 #include "mk-scanner.h"
51 #define UNIMPLEMENTED G_STMT_START { g_warning (G_STRLOC": unimplemented"); } G_STMT_END
53 /* Constant strings for parsing perl script error output */
54 #define ERROR_PREFIX "ERROR("
55 #define WARNING_PREFIX "WARNING("
56 #define MESSAGE_DELIMITER ": "
58 static const gchar
*valid_makefiles
[] = {"GNUmakefile", "makefile", "Makefile", NULL
};
62 *---------------------------------------------------------------------------*/
64 static MkpNodeInfo MkpNodeInformation
[] = {
65 {{ANJUTA_PROJECT_GROUP
,
70 {{ANJUTA_PROJECT_SOURCE
,
75 {{ANJUTA_PROJECT_TARGET
,
80 {{ANJUTA_PROJECT_UNKNOWN
,
87 /* ----- Standard GObject types and variables ----- */
94 static GObject
*parent_class
;
97 *---------------------------------------------------------------------------*/
101 error_set (GError
**error
, gint code
, const gchar
*message
)
104 if (*error
!= NULL
) {
107 /* error already created, just change the code
108 * and prepend the string */
109 (*error
)->code
= code
;
110 tmp
= (*error
)->message
;
111 (*error
)->message
= g_strconcat (message
, "\n\n", tmp
, NULL
);
115 *error
= g_error_new_literal (IANJUTA_PROJECT_ERROR
,
123 /* Work even if file is not a descendant of parent */
125 get_relative_path (GFile
*parent
, GFile
*file
)
129 relative
= g_file_get_relative_path (parent
, file
);
130 if (relative
== NULL
)
132 if (g_file_equal (parent
, file
))
134 relative
= g_strdup ("");
138 GFile
*grand_parent
= g_file_get_parent (parent
);
140 gchar
*grand_relative
;
145 for (level
= 1; !g_file_has_prefix (file
, grand_parent
); level
++)
147 GFile
*next
= g_file_get_parent (grand_parent
);
149 g_object_unref (grand_parent
);
153 grand_relative
= g_file_get_relative_path (grand_parent
, file
);
154 g_object_unref (grand_parent
);
156 len
= strlen (grand_relative
);
157 relative
= g_new (gchar
, len
+ level
* 3 + 1);
159 for (; level
; level
--)
161 memcpy(ptr
, ".." G_DIR_SEPARATOR_S
, 3);
164 memcpy (ptr
, grand_relative
, len
+ 1);
165 g_free (grand_relative
);
173 file_type (GFile
*file
, const gchar
*filename
)
179 child
= filename
!= NULL
? g_file_get_child (file
, filename
) : g_object_ref (file
);
181 //g_message ("check file %s", g_file_get_path (child));
183 info
= g_file_query_info (child
,
184 G_FILE_ATTRIBUTE_STANDARD_TYPE
,
185 G_FILE_QUERY_INFO_NONE
,
190 type
= g_file_info_get_file_type (info
);
191 g_object_unref (info
);
195 type
= G_FILE_TYPE_UNKNOWN
;
198 g_object_unref (child
);
204 *---------------------------------------------------------------------------*/
206 static AnjutaProjectNode
*
207 mkp_group_new (GFile
*file
)
209 MkpGroup
*group
= g_object_new (MKP_TYPE_GROUP
, NULL
);;
210 group
->base
.file
= g_object_ref (file
);
212 group
->base
.type
= ANJUTA_PROJECT_GROUP
;
213 group
->base
.properties
= NULL
;
214 group
->base
.properties_info
= NULL
;
215 group
->base
.name
= NULL
;
216 group
->base
.state
= 0;
219 return ANJUTA_PROJECT_NODE(group
);
223 mkp_group_class_init (MkpGroupClass
*klass
)
229 mkp_group_init (MkpGroup
*obj
)
234 G_DEFINE_TYPE (MkpGroup
, mkp_group
, ANJUTA_TYPE_PROJECT_NODE
);
237 *---------------------------------------------------------------------------*/
240 mkp_target_add_token (MkpTarget
*target
, AnjutaToken
*token
)
242 target
->tokens
= g_list_prepend (target
->tokens
, token
);
247 mkp_target_get_token (MkpTarget
*target
)
249 return target
->tokens
;
253 mkp_target_new (const gchar
*name
, AnjutaProjectNodeType type
)
255 MkpTarget
*target
= NULL
;
257 target
= g_object_new (MKP_TYPE_TARGET
, NULL
);
258 target
->base
.name
= g_strdup (name
);
259 target
->base
.type
= ANJUTA_PROJECT_TARGET
;
260 target
->base
.state
= 0;
262 return ANJUTA_PROJECT_NODE(target
);
266 mkp_target_class_init (MkpTargetClass
*klass
)
272 mkp_target_init (MkpTarget
*obj
)
277 G_DEFINE_TYPE (MkpTarget
, mkp_target
, ANJUTA_TYPE_PROJECT_NODE
);
280 *---------------------------------------------------------------------------*/
283 mkp_object_new (const gchar
*name
)
285 MkpObject
*node
= NULL
;
287 node
= g_object_new (MKP_TYPE_OBJECT
, NULL
);
288 node
->base
.name
= g_strdup (name
);
289 node
->base
.type
= ANJUTA_PROJECT_OBJECT
;
290 node
->base
.state
= 0;
292 return ANJUTA_PROJECT_NODE(node
);
296 mkp_object_class_init (MkpObjectClass
*klass
)
302 mkp_object_init (MkpObject
*obj
)
307 G_DEFINE_TYPE (MkpObject
, mkp_object
, ANJUTA_TYPE_PROJECT_NODE
);
311 *---------------------------------------------------------------------------*/
314 mkp_source_new (GFile
*file
)
316 MkpSource
*source
= NULL
;
318 source
= g_object_new (MKP_TYPE_SOURCE
, NULL
);
319 source
->base
.file
= g_object_ref (file
);
320 source
->base
.type
= ANJUTA_PROJECT_SOURCE
;
321 source
->base
.properties
= NULL
;
322 source
->base
.properties_info
= NULL
;
323 source
->base
.name
= NULL
;
324 source
->base
.state
= 0;
326 return ANJUTA_PROJECT_NODE (source
);
330 mkp_source_class_init (MkpSourceClass
*klass
)
336 mkp_source_init (MkpSource
*obj
)
341 G_DEFINE_TYPE (MkpSource
, mkp_source
, ANJUTA_TYPE_PROJECT_NODE
);
344 * File monitoring support --------------------------------
345 * FIXME: review these
348 monitor_cb (GFileMonitor
*monitor
,
351 GFileMonitorEvent event_type
,
354 MkpProject
*project
= data
;
356 g_return_if_fail (project
!= NULL
&& MKP_IS_PROJECT (project
));
358 switch (event_type
) {
359 case G_FILE_MONITOR_EVENT_CHANGED
:
360 case G_FILE_MONITOR_EVENT_CREATED
:
361 g_signal_emit_by_name (G_OBJECT (project
), "file-changed", data
);
370 monitor_add (MkpProject
*project
, GFile
*file
)
372 GFileMonitor
*monitor
= NULL
;
374 g_return_if_fail (project
!= NULL
);
375 g_return_if_fail (project
->monitors
!= NULL
);
380 monitor
= g_hash_table_lookup (project
->monitors
, file
);
384 /* FIXME clarify if uri is uri, path or both */
385 exists
= g_file_query_exists (file
, NULL
);
388 monitor
= g_file_monitor_file (file
,
394 g_signal_connect (G_OBJECT (monitor
),
396 G_CALLBACK (monitor_cb
),
398 g_hash_table_insert (project
->monitors
,
407 monitors_remove (MkpProject
*project
)
409 g_return_if_fail (project
!= NULL
);
411 if (project
->monitors
)
412 g_hash_table_destroy (project
->monitors
);
413 project
->monitors
= NULL
;
417 files_hash_foreach_monitor (gpointer key
,
421 GFile
*makefile
= (GFile
*)key
;
422 MkpProject
*project
= user_data
;
424 monitor_add (project
, makefile
);
428 monitors_setup (MkpProject
*project
)
430 g_return_if_fail (project
!= NULL
);
432 monitors_remove (project
);
434 /* setup monitors hash */
435 project
->monitors
= g_hash_table_new_full (g_direct_hash
, g_direct_equal
, NULL
,
436 (GDestroyNotify
) g_file_monitor_cancel
);
439 g_hash_table_foreach (project
->files
, files_hash_foreach_monitor
, project
);
444 * ---------------- Data structures managment
447 static AnjutaProjectNode
*
448 project_node_new (MkpProject
*project
, AnjutaProjectNode
*parent
, AnjutaProjectNodeType type
, GFile
*file
, const gchar
*name
, GError
**error
)
450 AnjutaProjectNode
*node
= NULL
;
452 switch (type
& ANJUTA_PROJECT_TYPE_MASK
) {
453 case ANJUTA_PROJECT_ROOT
:
454 case ANJUTA_PROJECT_GROUP
:
455 node
= ANJUTA_PROJECT_NODE (mkp_group_new (file
));
457 case ANJUTA_PROJECT_TARGET
:
458 node
= ANJUTA_PROJECT_NODE (mkp_target_new (name
, 0));
460 case ANJUTA_PROJECT_SOURCE
:
461 node
= ANJUTA_PROJECT_NODE (mkp_source_new (file
));
464 g_assert_not_reached ();
467 if (node
!= NULL
) node
->type
= type
;
472 static AnjutaProjectNode
*
473 project_load_makefile (MkpProject
*project
, GFile
*file
, MkpGroup
*parent
, GError
**error
)
477 AnjutaTokenFile
*tfile
;
483 DEBUG_PRINT ("Parse: %s", g_file_get_uri (file
));
484 tfile
= anjuta_token_file_new (file
);
485 g_hash_table_insert (project
->files
, g_object_ref (file
), g_object_ref (tfile
));
486 arg
= anjuta_token_file_load (tfile
, NULL
);
487 scanner
= mkp_scanner_new (project
);
488 parse
= mkp_scanner_parse_token (scanner
, arg
, &err
);
490 mkp_scanner_free (scanner
);
495 g_set_error_literal (error
, IANJUTA_PROJECT_ERROR
,
496 IANJUTA_PROJECT_ERROR_PROJECT_MALFORMED
,
502 g_set_error (error
, IANJUTA_PROJECT_ERROR
,
503 IANJUTA_PROJECT_ERROR_PROJECT_MALFORMED
,
505 _("Unable to parse make file"));
512 mkp_project_enumerate_targets (project
, ANJUTA_PROJECT_NODE(parent
));
514 return ANJUTA_PROJECT_NODE(parent
);
517 /* Project access functions
518 *---------------------------------------------------------------------------*/
521 mkp_project_get_root (MkpProject
*project
)
523 return MKP_PROJECT(project
);
527 mkp_project_get_node_info (MkpProject
*project
, GError
**error
)
529 static GList
*info_list
= NULL
;
531 if (info_list
== NULL
)
535 for (node
= MkpNodeInformation
; node
->base
.type
!= 0; node
++)
537 info_list
= g_list_prepend (info_list
, node
);
540 info_list
= g_list_reverse (info_list
);
547 mkp_project_get_token_location (MkpProject
*project
, AnjutaTokenFileLocation
*location
, AnjutaToken
*token
)
553 g_hash_table_iter_init (&iter
, project
->files
);
554 while (g_hash_table_iter_next (&iter
, &key
, &value
))
556 if (anjuta_token_file_get_token_location ((AnjutaTokenFile
*)value
, location
, token
))
565 /* Variable access functions
566 *---------------------------------------------------------------------------*/
569 mkp_variable_get_name (MkpVariable
*variable
)
571 return variable
->name
;
575 mkp_variable_evaluate (MkpVariable
*variable
, MkpProject
*project
)
577 return anjuta_token_evaluate (variable
->value
);
581 mkp_variable_new (gchar
*name
, AnjutaTokenType assign
, AnjutaToken
*value
)
583 MkpVariable
*variable
= NULL
;
585 g_return_val_if_fail (name
!= NULL
, NULL
);
587 variable
= g_slice_new0(MkpVariable
);
588 variable
->name
= g_strdup (name
);
589 variable
->assign
= assign
;
590 variable
->value
= value
;
596 mkp_variable_free (MkpVariable
*variable
)
598 g_free (variable
->name
);
600 g_slice_free (MkpVariable
, variable
);
604 *---------------------------------------------------------------------------*/
607 mkp_project_update_variable (MkpProject
*project
, AnjutaToken
*variable
)
611 MakeTokenType assign
= 0;
612 AnjutaToken
*value
= NULL
;
614 //fprintf(stdout, "update variable");
615 //anjuta_token_dump (variable);
617 arg
= anjuta_token_first_item (variable
);
618 name
= g_strstrip (anjuta_token_evaluate (arg
));
619 arg
= anjuta_token_next_item (arg
);
621 //g_message ("new variable %s", name);
622 switch (anjuta_token_get_type (arg
))
625 case MK_TOKEN_IMMEDIATE_EQUAL
:
626 case MK_TOKEN_CONDITIONAL_EQUAL
:
627 case MK_TOKEN_APPEND
:
628 assign
= anjuta_token_get_type (arg
);
634 value
= anjuta_token_next_item (arg
);
640 //g_message ("assign %d name %s value %s\n", assign, name, anjuta_token_evaluate (value));
641 var
= (MkpVariable
*)g_hash_table_lookup (project
->variables
, name
);
644 var
->assign
= assign
;
649 var
= mkp_variable_new (name
, assign
, value
);
650 g_hash_table_insert (project
->variables
, var
->name
, var
);
655 //g_message ("update variable %s", name);
657 if (name
) g_free (name
);
661 mkp_project_get_variable_token (MkpProject
*project
, AnjutaToken
*variable
)
668 length
= anjuta_token_get_length (variable
);
669 string
= anjuta_token_get_string (variable
);
670 if ((length
== 0) || (string
== NULL
)) return NULL
;
672 if (string
[1] == '(')
674 name
= g_strndup (string
+ 2, length
- 3);
678 name
= g_strndup (string
+ 1, 1);
680 var
= g_hash_table_lookup (project
->variables
, name
);
683 return var
!= NULL
? var
->value
: NULL
;
686 static AnjutaProjectNode
*
687 mkp_project_load_root (MkpProject
*project
, AnjutaProjectNode
*node
, GError
**error
)
690 GFile
*make_file
= NULL
;
691 const gchar
**makefile
;
694 /* Unload current project */
695 root_file
= g_object_ref (anjuta_project_node_get_file (node
));
696 mkp_project_unload (project
);
697 project
->root_file
= root_file
;
698 DEBUG_PRINT ("reload project %p root file %p", project
, project
->root_file
);
700 /* shortcut hash tables */
701 project
->groups
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
702 project
->files
= g_hash_table_new_full (g_file_hash
, (GEqualFunc
)g_file_equal
, g_object_unref
, g_object_unref
);
703 project
->variables
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
, (GDestroyNotify
)mkp_variable_free
);
705 /* Initialize rules data */
706 mkp_project_init_rules (project
);
708 /* Initialize list styles */
709 project
->space_list
= anjuta_token_style_new (NULL
, " ", "\n", NULL
, 0);
710 project
->arg_list
= anjuta_token_style_new (NULL
, ", ", ",\n ", ")", 0);
713 for (makefile
= valid_makefiles
; *makefile
!= NULL
; makefile
++)
715 if (file_type (root_file
, *makefile
) == G_FILE_TYPE_REGULAR
)
717 make_file
= g_file_get_child (root_file
, *makefile
);
721 if (make_file
== NULL
)
723 g_set_error (error
, IANJUTA_PROJECT_ERROR
,
724 IANJUTA_PROJECT_ERROR_DOESNT_EXIST
,
725 _("Project doesn't exist or invalid path"));
731 group
= MKP_GROUP(mkp_group_new (root_file
));
732 anjuta_project_node_append (node
, ANJUTA_PROJECT_NODE(group
));
733 g_hash_table_insert (project
->groups
, g_file_get_uri (root_file
), group
);
736 /* Parse make file */
737 project_load_makefile (project
, make_file
, group
, error
);
738 g_object_unref (make_file
);
740 monitors_setup (project
);
746 mkp_project_load_node (MkpProject
*project
, AnjutaProjectNode
*node
, GError
**error
)
748 switch (anjuta_project_node_get_node_type (node
))
750 case ANJUTA_PROJECT_ROOT
:
752 DEBUG_PRINT("*** Loading project: %p root file: %p\n", project
, project
->root_file
);
753 return mkp_project_load_root (project
, node
, error
);
754 case ANJUTA_PROJECT_GROUP
:
756 return project_load_makefile (project
, node
->file
, MKP_GROUP(node
), error
);
763 mkp_project_reload (MkpProject
*project
, GError
**error
)
767 const gchar
**makefile
;
771 /* Unload current project */
772 root_file
= g_object_ref (project
->root_file
);
773 mkp_project_unload (project
);
774 project
->root_file
= root_file
;
775 DEBUG_PRINT ("reload project %p root file %p", project
, project
->root_file
);
777 /* shortcut hash tables */
778 project
->groups
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
779 project
->files
= g_hash_table_new_full (g_file_hash
, (GEqualFunc
)g_file_equal
, g_object_unref
, g_object_unref
);
780 project
->variables
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
, (GDestroyNotify
)mkp_variable_free
);
782 /* Initialize rules data */
783 mkp_project_init_rules (project
);
785 /* Initialize list styles */
786 project
->space_list
= anjuta_token_style_new (NULL
, " ", "\n", NULL
, 0);
787 project
->arg_list
= anjuta_token_style_new (NULL
, ", ", ",\n ", ")", 0);
790 for (makefile
= valid_makefiles
; *makefile
!= NULL
; makefile
++)
792 if (file_type (root_file
, *makefile
) == G_FILE_TYPE_REGULAR
)
794 make_file
= g_file_get_child (root_file
, *makefile
);
798 if (make_file
== NULL
)
800 g_set_error (error
, IANJUTA_PROJECT_ERROR
,
801 IANJUTA_PROJECT_ERROR_DOESNT_EXIST
,
802 _("Project doesn't exist or invalid path"));
808 group
= MKP_GROUP(mkp_group_new (root_file
));
809 anjuta_project_node_append (ANJUTA_PROJECT_NODE(project
), ANJUTA_PROJECT_NODE(group
));
810 g_hash_table_insert (project
->groups
, g_file_get_uri (root_file
), group
);
812 /* Parse make file */
813 project_load_makefile (project
, make_file
, group
, error
);
814 g_object_unref (make_file
);
816 monitors_setup (project
);
823 mkp_project_load (MkpProject
*project
,
827 g_return_val_if_fail (directory
!= NULL
, FALSE
);
829 return mkp_project_load_root (project
, ANJUTA_PROJECT_NODE(project
), error
) != NULL
;
833 mkp_project_unload (MkpProject
*project
)
835 AnjutaProjectNode
*node
;
837 monitors_remove (project
);
840 if (project
->root_file
) g_object_unref (project
->root_file
);
841 project
->root_file
= NULL
;
843 /* Remove all children */
844 while ((node
= anjuta_project_node_first_child (ANJUTA_PROJECT_NODE (project
))) != NULL
)
846 g_object_unref (node
);
849 /* shortcut hash tables */
850 if (project
->groups
) g_hash_table_destroy (project
->groups
);
851 project
->groups
= NULL
;
852 if (project
->files
) g_hash_table_destroy (project
->files
);
853 project
->files
= NULL
;
854 if (project
->variables
) g_hash_table_destroy (project
->variables
);
855 project
->variables
= NULL
;
857 mkp_project_free_rules (project
);
860 if (project
->space_list
) anjuta_token_style_free (project
->space_list
);
861 if (project
->arg_list
) anjuta_token_style_free (project
->arg_list
);
865 mkp_project_probe (GFile
*directory
,
871 dir
= (file_type (directory
, NULL
) == G_FILE_TYPE_DIRECTORY
);
874 g_set_error (error
, IANJUTA_PROJECT_ERROR
,
875 IANJUTA_PROJECT_ERROR_DOESNT_EXIST
,
876 _("Project doesn't exist or invalid path"));
882 const gchar
**makefile
;
884 /* Look for makefiles */
886 for (makefile
= valid_makefiles
; *makefile
!= NULL
; makefile
++)
888 if (file_type (directory
, *makefile
) == G_FILE_TYPE_REGULAR
)
896 return probe
? IANJUTA_PROJECT_PROBE_MAKE_FILES
: 0;
900 mkp_project_save (MkpProject
*project
, GError
**error
)
906 g_return_val_if_fail (project
!= NULL
, FALSE
);
908 g_hash_table_iter_init (&iter
, project
->files
);
909 while (g_hash_table_iter_next (&iter
, &key
, &value
))
911 GError
*error
= NULL
;
912 AnjutaTokenFile
*tfile
= (AnjutaTokenFile
*)value
;
913 anjuta_token_file_save (tfile
, &error
);
920 mkp_project_move (MkpProject
*project
, const gchar
*path
)
922 GFile
*old_root_file
;
928 AnjutaTokenFile
*tfile
;
929 GHashTable
* old_hash
;
931 /* Change project root directory */
932 old_root_file
= project
->root_file
;
933 project
->root_file
= g_file_new_for_path (path
);
935 /* Change project root directory in groups */
936 old_hash
= project
->groups
;
937 project
->groups
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
938 g_hash_table_iter_init (&iter
, old_hash
);
939 while (g_hash_table_iter_next (&iter
, &key
, &value
))
941 MkpGroup
*group
= (MkpGroup
*)value
;
943 relative
= get_relative_path (old_root_file
, group
->base
.file
);
944 new_file
= g_file_resolve_relative_path (project
->root_file
, relative
);
946 g_object_unref (group
->base
.file
);
947 group
->base
.file
= new_file
;
949 g_hash_table_insert (project
->groups
, g_file_get_uri (new_file
), group
);
951 g_hash_table_destroy (old_hash
);
953 /* Change all files */
954 old_hash
= project
->files
;
955 project
->files
= g_hash_table_new_full (g_file_hash
, (GEqualFunc
)g_file_equal
, g_object_unref
, g_object_unref
);
956 g_hash_table_iter_init (&iter
, old_hash
);
957 while (g_hash_table_iter_next (&iter
, &key
, (gpointer
*)&tfile
))
959 relative
= get_relative_path (old_root_file
, anjuta_token_file_get_file (tfile
));
960 new_file
= g_file_resolve_relative_path (project
->root_file
, relative
);
962 anjuta_token_file_move (tfile
, new_file
);
964 g_hash_table_insert (project
->files
, new_file
, tfile
);
965 g_object_unref (key
);
967 g_hash_table_steal_all (old_hash
);
968 g_hash_table_destroy (old_hash
);
970 g_object_unref (old_root_file
);
976 mkp_project_new (GFile
*file
, GError
**error
)
980 project
= MKP_PROJECT (g_object_new (MKP_TYPE_PROJECT
, NULL
));
981 project
->parent
.file
= (file
!= NULL
) ? g_file_dup (file
) : NULL
;
982 project
->parent
.type
= ANJUTA_PROJECT_ROOT
;
988 mkp_project_is_loaded (MkpProject
*project
)
990 return project
->loading
== 0;
994 /* Implement IAnjutaProject
995 *---------------------------------------------------------------------------*/
998 iproject_load_node (IAnjutaProject
*obj
, AnjutaProjectNode
*node
, GError
**err
)
1000 if (node
== NULL
) node
= ANJUTA_PROJECT_NODE (obj
);
1003 if (mkp_project_load_node (MKP_PROJECT (obj
), node
, err
) != NULL
) {
1004 (MKP_PROJECT(obj
))->loading
--;
1005 g_signal_emit_by_name (MKP_PROJECT(obj
), "node-loaded", node
, err
);
1014 iproject_save_node (IAnjutaProject
*obj
, AnjutaProjectNode
*node
, GError
**err
)
1016 return mkp_project_save (MKP_PROJECT(node
), err
);
1019 static AnjutaProjectProperty
*
1020 iproject_set_property (IAnjutaProject
*obj
, AnjutaProjectNode
*node
, const gchar
*id
, const gchar
*name
, const gchar
*value
, GError
**error
)
1022 g_set_error (error
, IANJUTA_PROJECT_ERROR
,
1023 IANJUTA_PROJECT_ERROR_NOT_SUPPORTED
,
1024 _("Project doesn't allow to set properties"));
1030 iproject_remove_property (IAnjutaProject
*obj
, AnjutaProjectNode
*node
, const gchar
*id
, const gchar
*name
, GError
**error
)
1032 g_set_error (error
, IANJUTA_PROJECT_ERROR
,
1033 IANJUTA_PROJECT_ERROR_NOT_SUPPORTED
,
1034 _("Project doesn't allow to set properties"));
1040 iproject_get_node_info (IAnjutaProject
*obj
, GError
**err
)
1042 return mkp_project_get_node_info (MKP_PROJECT (obj
), err
);
1045 static AnjutaProjectNode
*
1046 iproject_get_root (IAnjutaProject
*obj
, GError
**err
)
1048 return ANJUTA_PROJECT_NODE(mkp_project_get_root (MKP_PROJECT(obj
)));
1052 iproject_is_loaded (IAnjutaProject
*obj
, GError
**err
)
1054 return mkp_project_is_loaded (MKP_PROJECT (obj
));
1058 iproject_remove_node (IAnjutaProject
*obj
, AnjutaProjectNode
*node
, GError
**err
)
1060 anjuta_project_node_set_state (node
, ANJUTA_PROJECT_REMOVED
);
1061 g_signal_emit_by_name (obj
, "node-modified", node
, NULL
);
1066 static AnjutaProjectNode
*
1067 iproject_add_node_before (IAnjutaProject
*obj
, AnjutaProjectNode
*parent
, AnjutaProjectNode
*sibling
, AnjutaProjectNodeType type
, GFile
*file
, const gchar
*name
, GError
**error
)
1069 AnjutaProjectNode
*node
;
1071 node
= project_node_new (MKP_PROJECT (obj
), parent
, type
, file
, name
, error
);
1072 anjuta_project_node_set_state (node
, ANJUTA_PROJECT_MODIFIED
);
1073 anjuta_project_node_insert_before (parent
, sibling
, node
);
1075 g_signal_emit_by_name (obj
, "node-changed", node
, NULL
);
1080 static AnjutaProjectNode
*
1081 iproject_add_node_after (IAnjutaProject
*obj
, AnjutaProjectNode
*parent
, AnjutaProjectNode
*sibling
, AnjutaProjectNodeType type
, GFile
*file
, const gchar
*name
, GError
**error
)
1083 AnjutaProjectNode
*node
;
1085 node
= project_node_new (MKP_PROJECT (obj
), parent
, type
, file
, name
, error
);
1086 anjuta_project_node_set_state (node
, ANJUTA_PROJECT_MODIFIED
);
1087 anjuta_project_node_insert_after (parent
, sibling
, node
);
1089 g_signal_emit_by_name (obj
, "node-modified", node
, NULL
);
1095 iproject_iface_init(IAnjutaProjectIface
* iface
)
1097 iface
->load_node
= iproject_load_node
;
1098 iface
->save_node
= iproject_save_node
;
1099 iface
->set_property
= iproject_set_property
;
1100 iface
->remove_property
= iproject_remove_property
;
1101 iface
->get_node_info
= iproject_get_node_info
;
1102 iface
->get_root
= iproject_get_root
;
1104 iface
->is_loaded
= iproject_is_loaded
;
1106 iface
->remove_node
= iproject_remove_node
;
1108 iface
->add_node_before
= iproject_add_node_before
;
1109 iface
->add_node_after
= iproject_add_node_after
;
1113 /* GObject implementation
1114 *---------------------------------------------------------------------------*/
1117 mkp_project_dispose (GObject
*object
)
1119 g_return_if_fail (MKP_IS_PROJECT (object
));
1121 mkp_project_unload (MKP_PROJECT (object
));
1123 G_OBJECT_CLASS (parent_class
)->dispose (object
);
1127 mkp_project_instance_init (MkpProject
*project
)
1129 g_return_if_fail (project
!= NULL
);
1130 g_return_if_fail (MKP_IS_PROJECT (project
));
1133 project
->root_file
= NULL
;
1134 project
->suffix
= NULL
;
1135 project
->rules
= NULL
;
1137 project
->space_list
= NULL
;
1138 project
->arg_list
= NULL
;
1142 mkp_project_class_init (MkpProjectClass
*klass
)
1144 GObjectClass
*object_class
;
1146 parent_class
= g_type_class_peek_parent (klass
);
1148 object_class
= G_OBJECT_CLASS (klass
);
1149 object_class
->dispose
= mkp_project_dispose
;
1153 ANJUTA_TYPE_BEGIN(MkpProject
, mkp_project
, ANJUTA_TYPE_PROJECT_NODE
);
1154 ANJUTA_TYPE_ADD_INTERFACE(iproject
, IANJUTA_TYPE_PROJECT
);