glade: Fix make file some files were not installed
[anjuta.git] / plugins / project-manager / plugin.c
blob058e8b0ae808e36d38b32c0d778603069779a0dd
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) 2000 Naba Kumar
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (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
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <config.h>
22 #include <libanjuta/interfaces/ianjuta-file.h>
23 #include <libanjuta/interfaces/ianjuta-file-savable.h>
24 #include <libanjuta/interfaces/ianjuta-file-loader.h>
25 #include <libanjuta/interfaces/ianjuta-project-manager.h>
26 #include <libanjuta/interfaces/ianjuta-document-manager.h>
27 #include <libanjuta/interfaces/ianjuta-file-manager.h>
28 #include <libanjuta/interfaces/ianjuta-builder.h>
29 #include <libanjuta/interfaces/ianjuta-project-backend.h>
30 #include <libanjuta/interfaces/ianjuta-project.h>
31 #include <libanjuta/anjuta-profile-manager.h>
32 #include <libanjuta/anjuta-debug.h>
33 #include <libanjuta/anjuta-status.h>
34 #include <libanjuta/anjuta-project.h>
36 #include "project-util.h"
37 #include "dialogs.h"
38 #include "project-chooser.h"
40 #include "plugin.h"
42 #define UI_FILE PACKAGE_DATA_DIR "/ui/anjuta-project-manager.xml"
43 #define PREFS_GLADE PACKAGE_DATA_DIR "/glade/anjuta-project-manager-plugin.ui"
44 #define ICON_FILE "anjuta-project-manager-plugin-48.png"
45 #define DEFAULT_PROFILE "file://"PACKAGE_DATA_DIR "/profiles/default.profile"
46 #define PROJECT_PROFILE_NAME "project"
48 #define INT_TO_GBOOLEAN(i) ((i) ? TRUE : FALSE)
50 typedef struct _PmPropertiesDialogInfo PmPropertiesDialogInfo;
52 typedef enum _PmPropertiesType
54 PM_PROJECT_PROPERTIES,
55 PM_TARGET_PROPERTIES,
56 PM_GROUP_PROPERTIES
57 } PmPropertiesType;
59 struct _PmPropertiesDialogInfo
61 PmPropertiesType type;
62 AnjutaProjectNode* id;
63 GtkWidget* dialog;
66 static gpointer parent_class;
68 static gboolean file_is_inside_project (ProjectManagerPlugin *plugin,
69 GFile *uri);
70 static void project_manager_plugin_close (ProjectManagerPlugin *plugin);
72 static void
73 update_title (ProjectManagerPlugin* plugin, const gchar *project_uri)
75 AnjutaStatus *status;
76 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
77 if (project_uri)
79 GFileInfo *file_info;
80 GFile *file;
82 file = g_file_new_for_uri (project_uri);
83 file_info = g_file_query_info (file,
84 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
85 G_FILE_QUERY_INFO_NONE,
86 NULL,
87 NULL);
88 if (file_info)
90 gchar *dispname;
91 gchar *ext;
93 dispname = g_strdup (
94 g_file_info_get_display_name (file_info));
95 ext = strrchr (dispname, '.');
96 if (ext)
97 *ext = '\0';
98 anjuta_status_set_title (status, dispname);
99 g_free (dispname);
100 g_object_unref (file_info);
103 g_object_unref (file);
105 else
107 anjuta_status_set_title (status, NULL);
111 static gchar*
112 get_session_dir (ProjectManagerPlugin *plugin)
114 gchar *session_dir = NULL;
115 gchar *local_dir;
117 g_return_val_if_fail (plugin->project_root_uri, NULL);
119 local_dir = anjuta_util_get_local_path_from_uri (plugin->project_root_uri);
120 if (local_dir)
122 session_dir = g_build_filename (local_dir, ".anjuta", "session",
123 NULL);
125 g_free (local_dir);
127 return session_dir;
130 static void
131 project_manager_save_session (ProjectManagerPlugin *plugin)
133 gchar *session_dir;
134 session_dir = get_session_dir (plugin);
135 g_return_if_fail (session_dir != NULL);
137 plugin->session_by_me = TRUE;
138 anjuta_shell_session_save (ANJUTA_PLUGIN (plugin)->shell,
139 session_dir, NULL);
140 plugin->session_by_me = FALSE;
141 g_free (session_dir);
144 static void
145 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
146 AnjutaSession *session, ProjectManagerPlugin *plugin)
148 GList *list;
150 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
151 return;
154 * When a project session is being saved (session_by_me == TRUE),
155 * we should not save the current project uri, because project
156 * sessions are loaded when the project has already been loaded.
158 if (plugin->project_file && !plugin->session_by_me)
160 list = anjuta_session_get_string_list (session,
161 "File Loader",
162 "Files");
163 list = g_list_append (list, anjuta_session_get_relative_uri_from_file (session, plugin->project_file, NULL));
164 anjuta_session_set_string_list (session, "File Loader",
165 "Files", list);
166 g_list_foreach (list, (GFunc)g_free, NULL);
167 g_list_free (list);
170 /* Save shortcuts */
171 list = gbf_project_view_get_shortcut_list (plugin->view);
172 if (list != NULL)
174 anjuta_session_set_string_list (session, "Project Manager", "Shortcut", list);
175 g_list_foreach (list, (GFunc)g_free, NULL);
176 g_list_free (list);
179 /* Save expanded node */
180 list = gbf_project_view_get_expanded_list (GBF_PROJECT_VIEW (plugin->view));
181 if (list != NULL)
183 anjuta_session_set_string_list (session, "Project Manager", "Expand", list);
184 g_list_foreach (list, (GFunc)g_free, NULL);
185 g_list_free (list);
190 static void
191 on_session_load (AnjutaShell *shell, AnjutaSessionPhase phase, AnjutaSession *session, ProjectManagerPlugin *plugin)
193 GList *list;
195 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
196 return;
198 list = anjuta_session_get_string_list (session, "Project Manager", "Shortcut");
199 gbf_project_view_set_shortcut_list (GBF_PROJECT_VIEW (plugin->view), list);
200 g_list_foreach (list, (GFunc)g_free, NULL);
201 g_list_free (list);
203 list = anjuta_session_get_string_list (session, "Project Manager", "Expand");
204 gbf_project_view_set_expanded_list (GBF_PROJECT_VIEW (plugin->view), list);
205 g_list_foreach (list, (GFunc)g_free, NULL);
206 g_list_free (list);
209 static void
210 on_shell_exiting (AnjutaShell *shell, ProjectManagerPlugin *plugin)
212 if (plugin->project_file)
214 /* Also make sure we save the project session also */
215 project_manager_save_session (plugin);
219 static gboolean
220 on_close_project_idle (gpointer plugin)
222 project_manager_plugin_close (ANJUTA_PLUGIN_PROJECT_MANAGER (plugin));
223 ANJUTA_PLUGIN_PROJECT_MANAGER(plugin)->close_project_idle = -1;
225 return FALSE;
228 static void
229 on_close_project (GtkAction *action, ProjectManagerPlugin *plugin)
231 if (plugin->project_file)
232 plugin->close_project_idle = g_idle_add (on_close_project_idle, plugin);
235 static GList *
236 find_missing_files (GList *pre, GList *post)
238 GHashTable *hash;
239 GList *ret = NULL;
240 GList *node;
242 hash = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
243 node = pre;
244 while (node)
246 g_hash_table_insert (hash, node->data, node->data);
247 node = g_list_next (node);
250 node = post;
251 while (node)
253 if (g_hash_table_lookup (hash, node->data) == NULL)
254 ret = g_list_prepend (ret, node->data);
255 node = g_list_next (node);
257 g_hash_table_destroy (hash);
258 return g_list_reverse (ret);
261 static void
262 update_operation_emit_signals (ProjectManagerPlugin *plugin, GList *pre,
263 GList *post)
265 GList *missing_files, *node;
267 missing_files = find_missing_files (pre, post);
268 node = missing_files;
269 while (node)
271 DEBUG_PRINT ("URI added emitting: %s", (char*)node->data);
272 g_signal_emit_by_name (G_OBJECT (plugin), "element_added",
273 node->data);
274 node = g_list_next (node);
276 g_list_free (missing_files);
278 missing_files = find_missing_files (post, pre);
279 node = missing_files;
280 while (node)
282 DEBUG_PRINT ("URI removed emitting: %s", (char*)node->data);
283 g_signal_emit_by_name (G_OBJECT (plugin), "element_removed",
284 node->data);
285 node = g_list_next (node);
287 g_list_free (missing_files);
290 static void
291 update_operation_end (ProjectManagerPlugin *plugin, gboolean emit_signal)
293 if (emit_signal)
295 if (plugin->pre_update_sources)
297 GList *post_update_sources =
298 ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
299 ANJUTA_PROJECT_SOURCE,
300 NULL);
301 update_operation_emit_signals (plugin, plugin->pre_update_sources,
302 post_update_sources);
303 if (post_update_sources)
305 g_list_foreach (post_update_sources, (GFunc)g_object_unref, NULL);
306 g_list_free (post_update_sources);
309 if (plugin->pre_update_targets)
311 GList *post_update_targets =
312 ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
313 ANJUTA_PROJECT_TARGET,
314 NULL);
315 update_operation_emit_signals (plugin, plugin->pre_update_targets,
316 post_update_targets);
317 if (post_update_targets)
319 g_list_foreach (post_update_targets, (GFunc)g_object_unref, NULL);
320 g_list_free (post_update_targets);
323 if (plugin->pre_update_groups)
325 GList *post_update_groups =
326 ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
327 ANJUTA_PROJECT_GROUP,
328 NULL);
329 update_operation_emit_signals (plugin, plugin->pre_update_groups,
330 post_update_groups);
331 if (post_update_groups)
333 g_list_foreach (post_update_groups, (GFunc)g_object_unref, NULL);
334 g_list_free (post_update_groups);
338 if (plugin->pre_update_sources)
340 g_list_foreach (plugin->pre_update_sources, (GFunc)g_object_unref, NULL);
341 g_list_free (plugin->pre_update_sources);
342 plugin->pre_update_sources = NULL;
344 if (plugin->pre_update_targets)
346 g_list_foreach (plugin->pre_update_targets, (GFunc)g_object_unref, NULL);
347 g_list_free (plugin->pre_update_targets);
348 plugin->pre_update_targets = NULL;
350 if (plugin->pre_update_groups)
352 g_list_foreach (plugin->pre_update_groups, (GFunc)g_object_unref, NULL);
353 g_list_free (plugin->pre_update_groups);
354 plugin->pre_update_groups = NULL;
358 static void
359 update_operation_begin (ProjectManagerPlugin *plugin)
361 update_operation_end (plugin, FALSE);
362 plugin->pre_update_sources =
363 ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
364 ANJUTA_PROJECT_SOURCE,
365 NULL);
366 plugin->pre_update_targets =
367 ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
368 ANJUTA_PROJECT_TARGET,
369 NULL);
370 plugin->pre_update_groups =
371 ianjuta_project_manager_get_elements (IANJUTA_PROJECT_MANAGER (plugin),
372 ANJUTA_PROJECT_GROUP,
373 NULL);
376 GtkWindow*
377 get_plugin_parent_window (ProjectManagerPlugin *plugin)
379 GtkWindow *win;
380 GtkWidget *toplevel;
382 toplevel = gtk_widget_get_toplevel (plugin->scrolledwindow);
383 if (toplevel && GTK_IS_WINDOW (toplevel))
384 win = GTK_WINDOW (toplevel);
385 else
386 win = GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell);
387 return win;
391 /* GUI callbacks
392 *---------------------------------------------------------------------------*/
394 static gboolean
395 on_refresh_idle (gpointer user_data)
397 ProjectManagerPlugin *plugin;
398 AnjutaStatus *status;
399 GError *err = NULL;
401 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (user_data);
403 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
404 anjuta_status_push (status, _("Refreshing symbol tree…"));
405 anjuta_status_busy_push (status);
407 anjuta_pm_project_refresh (plugin->project, &err);
408 if (err)
410 anjuta_util_dialog_error (get_plugin_parent_window (plugin),
411 _("Failed to refresh project: %s"),
412 err->message);
413 g_error_free (err);
415 anjuta_status_busy_pop (status);
416 anjuta_status_pop (status);
417 return FALSE;
420 static void
421 on_refresh (GtkAction *action, ProjectManagerPlugin *plugin)
423 g_idle_add (on_refresh_idle, plugin);
426 static void
427 on_properties (GtkAction *action, ProjectManagerPlugin *plugin)
429 GtkTreeIter selected;
430 gboolean found;
432 found = gbf_project_view_get_first_selected (plugin->view, &selected) != NULL;
434 anjuta_pm_project_show_properties_dialog (plugin, found ? &selected : NULL);
437 static void
438 on_new_group (GtkAction *action, ProjectManagerPlugin *plugin)
440 GFile *group;
441 GFile *default_group = NULL;
443 if (plugin->current_editor_uri)
445 gchar *uri = g_path_get_dirname (plugin->current_editor_uri);
446 default_group = g_file_new_for_uri (uri);
447 g_free (uri);
450 group =
451 ianjuta_project_manager_add_group (IANJUTA_PROJECT_MANAGER (plugin),
452 "", default_group,
453 NULL);
454 if (group != NULL) g_object_unref (group);
455 if (default_group != NULL) g_object_unref (default_group);
458 static void
459 on_new_package (GtkAction *action, ProjectManagerPlugin *plugin)
461 GtkTreeIter selected_module;
462 GList *new_module;
463 GbfTreeData *data;
465 update_operation_begin (plugin);
466 data = gbf_project_view_get_first_selected (plugin->view, &selected_module);
468 new_module = anjuta_pm_project_new_package (plugin,
469 get_plugin_parent_window (plugin),
470 data == NULL ? NULL : &selected_module, NULL);
471 g_list_free (new_module);
472 update_operation_end (plugin, TRUE);
475 static void
476 on_add_module (GtkAction *action, ProjectManagerPlugin *plugin)
478 GtkTreeIter selected_target;
479 GList *new_modules;
480 GbfTreeData *data;
482 update_operation_begin (plugin);
483 data = gbf_project_view_get_first_selected (plugin->view, &selected_target);
485 new_modules = anjuta_pm_project_new_module (plugin,
486 get_plugin_parent_window (plugin),
487 data == NULL ? NULL : &selected_target, NULL);
488 g_list_free (new_modules);
489 update_operation_end (plugin, TRUE);
492 static void
493 on_new_target (GtkAction *action, ProjectManagerPlugin *plugin)
495 GFile *target;
496 GFile *default_group = NULL;
498 if (plugin->current_editor_uri)
500 gchar *uri = g_path_get_dirname (plugin->current_editor_uri);
501 default_group = g_file_new_for_uri (uri);
502 g_free (uri);
505 target =
506 ianjuta_project_manager_add_target (IANJUTA_PROJECT_MANAGER (plugin),
507 "", default_group,
508 NULL);
510 if (target != NULL) g_object_unref (target);
511 if (default_group != NULL) g_object_unref (default_group);
514 static void
515 on_add_source (GtkAction *action, ProjectManagerPlugin *plugin)
517 GList *new_sources;
518 GFile *default_source = NULL;
519 GtkTreeIter selected;
520 gboolean found;
522 if (plugin->current_editor_uri)
524 default_source = g_file_new_for_uri (plugin->current_editor_uri);
526 found = gbf_project_view_get_first_selected (plugin->view, &selected) != NULL;
527 update_operation_begin (plugin);
528 new_sources = anjuta_pm_add_source_dialog (plugin,
529 get_plugin_parent_window (plugin),
530 found ? &selected : NULL,
531 default_source);
532 update_operation_end (plugin, TRUE);
533 g_list_free (new_sources);
534 if (default_source) g_object_unref (default_source);
537 static void
538 on_popup_properties (GtkAction *action, ProjectManagerPlugin *plugin)
540 GtkTreeIter selected;
541 gboolean found;
543 /* FIXME: Perhaps it would be better to open a dialog for each
544 * selected node ? */
545 found = gbf_project_view_get_first_selected (plugin->view, &selected) != NULL;
547 anjuta_pm_project_show_properties_dialog (plugin, found ? &selected : NULL);
550 static void
551 on_popup_sort_shortcuts (GtkAction *action, ProjectManagerPlugin *plugin)
553 gbf_project_view_sort_shortcuts (plugin->view);
556 static void
557 on_popup_new_package (GtkAction *action, ProjectManagerPlugin *plugin)
559 GtkTreeIter selected_module;
560 GList *packages;
562 update_operation_begin (plugin);
563 gbf_project_view_get_first_selected (plugin->view, &selected_module);
565 packages = anjuta_pm_project_new_package (plugin,
566 get_plugin_parent_window (plugin),
567 &selected_module, NULL);
568 update_operation_end (plugin, TRUE);
571 static void
572 on_popup_add_module (GtkAction *action, ProjectManagerPlugin *plugin)
574 GtkTreeIter selected_target;
575 GList *new_modules;
577 update_operation_begin (plugin);
578 gbf_project_view_get_first_selected (plugin->view, &selected_target);
580 new_modules = anjuta_pm_project_new_module (plugin,
581 get_plugin_parent_window (plugin),
582 &selected_target, NULL);
583 g_list_free (new_modules);
584 update_operation_end (plugin, TRUE);
587 static void
588 on_popup_new_group (GtkAction *action, ProjectManagerPlugin *plugin)
590 GtkTreeIter selected_group;
591 AnjutaProjectNode *new_group;
593 update_operation_begin (plugin);
594 gbf_project_view_get_first_selected (plugin->view, &selected_group);
596 new_group = anjuta_pm_project_new_group (plugin,
597 get_plugin_parent_window (plugin),
598 &selected_group, NULL);
599 update_operation_end (plugin, TRUE);
602 static void
603 on_popup_new_target (GtkAction *action, ProjectManagerPlugin *plugin)
605 GtkTreeIter selected_group;
606 AnjutaProjectNode *new_target;
608 update_operation_begin (plugin);
609 gbf_project_view_get_first_selected (plugin->view, &selected_group);
611 new_target = anjuta_pm_project_new_target (plugin,
612 get_plugin_parent_window (plugin),
613 &selected_group, NULL);
615 update_operation_end (plugin, TRUE);
618 static void
619 on_popup_add_source (GtkAction *action, ProjectManagerPlugin *plugin)
621 GList *new_sources;
622 GFile *default_source = NULL;
623 GtkTreeIter selected;
624 gboolean found;
626 if (plugin->current_editor_uri)
628 default_source = g_file_new_for_uri (plugin->current_editor_uri);
630 found = gbf_project_view_get_first_selected (plugin->view, &selected) != NULL;
631 update_operation_begin (plugin);
632 new_sources = anjuta_pm_add_source_dialog (plugin,
633 get_plugin_parent_window (plugin),
634 found ? &selected : NULL,
635 default_source);
637 update_operation_end (plugin, TRUE);
638 g_list_free (new_sources);
639 if (default_source) g_object_unref (default_source);
642 static gboolean
643 confirm_removal (ProjectManagerPlugin *plugin, GList *selected)
645 gboolean answer;
646 GString* mesg;
647 GList *item;
648 GbfTreeNodeType type;
649 gboolean group = FALSE;
650 gboolean remove_group_file = FALSE;
651 gboolean source = FALSE;
652 gboolean remove_source_file = FALSE;
654 g_return_val_if_fail (selected != NULL, FALSE);
656 type = ((GbfTreeData *)selected->data)->type;
657 for (item = g_list_first (selected); item != NULL; item = g_list_next (item))
659 GbfTreeData *data = (GbfTreeData *)item->data;
660 AnjutaProjectNode *node;
662 if (data->type == GBF_TREE_NODE_GROUP)
664 group = TRUE;
665 node = gbf_tree_data_get_node (data);
666 remove_group_file = anjuta_project_node_get_state (node) & ANJUTA_PROJECT_REMOVE_FILE;
668 if (data->type == GBF_TREE_NODE_SOURCE)
670 source = TRUE;
671 node = gbf_tree_data_get_node (data);
672 remove_source_file = anjuta_project_node_get_state (node) & ANJUTA_PROJECT_REMOVE_FILE;
674 if (type != data->type) type = GBF_TREE_NODE_UNKNOWN;
677 switch (type)
679 case GBF_TREE_NODE_GROUP:
680 mesg = g_string_new (_("Are you sure you want to remove the following group from the project?\n\n"));
681 break;
682 case GBF_TREE_NODE_TARGET:
683 mesg = g_string_new (_("Are you sure you want to remove the following target from the project?\n\n"));
684 break;
685 case GBF_TREE_NODE_SOURCE:
686 mesg = g_string_new (_("Are you sure you want to remove the following source file from the project?\n\n"));
687 break;
688 case GBF_TREE_NODE_PACKAGE:
689 mesg = g_string_new (_("Are you sure you want to remove the following package from the project?\n\n"));
690 break;
691 case GBF_TREE_NODE_MODULE:
692 mesg = g_string_new (_("Are you sure you want to remove the following module from the project?\n\n"));
693 break;
694 case GBF_TREE_NODE_UNKNOWN:
695 mesg = g_string_new (_("Are you sure you want to remove the following elements from the project?\n\n"));
696 break;
697 case GBF_TREE_NODE_SHORTCUT:
698 /* Remove shortcut without confirmation */
699 return TRUE;
700 default:
701 g_warn_if_reached ();
702 return FALSE;
705 for (item = g_list_first (selected); item != NULL; item = g_list_next (item))
707 GbfTreeData *data = (GbfTreeData *)item->data;
709 switch (data->type)
711 case GBF_TREE_NODE_GROUP:
712 g_string_append_printf (mesg, _("Group: %s\n"), data->name);
713 break;
714 case GBF_TREE_NODE_TARGET:
715 g_string_append_printf (mesg, _("Target: %s\n"), data->name);
716 break;
717 case GBF_TREE_NODE_SOURCE:
718 g_string_append_printf (mesg, _("Source: %s\n"), data->name);
719 break;
720 case GBF_TREE_NODE_SHORTCUT:
721 g_string_append_printf (mesg, _("Shortcut: %s\n"), data->name);
722 return TRUE;
723 case GBF_TREE_NODE_MODULE:
724 g_string_append_printf (mesg, _("Module: %s\n"), data->name);
725 break;
726 case GBF_TREE_NODE_PACKAGE:
727 g_string_append_printf (mesg, _("Package: %s\n"), data->name);
728 break;
729 default:
730 g_warn_if_reached ();
731 return FALSE;
735 if (group || source)
737 g_string_append (mesg, "\n");
738 if (remove_group_file)
739 g_string_append (mesg, _("The group will be deleted from the file system."));
740 else if (group)
741 g_string_append (mesg, _("The group will not be deleted from the file system."));
742 if (remove_source_file)
743 g_string_append (mesg, _("The source file will be deleted from the file system."));
744 else if (source)
745 g_string_append (mesg, _("The source file will not be deleted from the file system."));
748 answer =
749 anjuta_util_dialog_boolean_question (get_plugin_parent_window (plugin),
750 mesg->str, _("Confirm remove"));
751 g_string_free (mesg, TRUE);
753 return answer;
756 static void
757 on_popup_remove (GtkAction *action, ProjectManagerPlugin *plugin)
759 GList *selected;
761 selected = gbf_project_view_get_all_selected (plugin->view);
763 if (selected != NULL)
765 if (confirm_removal (plugin, selected))
767 GError *err = NULL;
768 GList *item;
769 gboolean update = FALSE;
771 for (item = g_list_first (selected); item != NULL; item = g_list_next (item))
773 GbfTreeData *data = (GbfTreeData *)(item->data);
774 AnjutaProjectNode *node;
776 switch (data->type)
778 case GBF_TREE_NODE_GROUP:
779 case GBF_TREE_NODE_TARGET:
780 case GBF_TREE_NODE_SOURCE:
781 case GBF_TREE_NODE_MODULE:
782 case GBF_TREE_NODE_PACKAGE:
783 node = gbf_tree_data_get_node (data);
784 if (node != NULL)
786 if (!update) update_operation_begin (plugin);
787 anjuta_pm_project_remove (plugin->project, node, &err);
788 if (err)
790 const gchar *name;
792 update_operation_end (plugin, TRUE);
793 update = FALSE;
794 name = anjuta_project_node_get_name (node);
795 anjuta_util_dialog_error (get_plugin_parent_window (plugin),
796 _("Failed to remove '%s':\n%s"),
797 name, err->message);
798 g_error_free (err);
801 break;
802 case GBF_TREE_NODE_SHORTCUT:
803 gbf_project_view_remove_data (plugin->view, data, NULL);
804 break;
805 default:
806 break;
809 if (update) update_operation_end (plugin, TRUE);
811 g_list_free (selected);
815 static void
816 on_popup_add_to_project (GtkAction *action, ProjectManagerPlugin *plugin)
818 GtkWindow *win;
819 GFile *file;
820 GFileInfo *file_info;
821 GFile *parent_directory;
822 gchar *filename;
823 GError *error = NULL;
825 win = get_plugin_parent_window (plugin);
827 file = g_file_new_for_uri (plugin->fm_current_uri);
828 file_info = g_file_query_info (file,
829 G_FILE_ATTRIBUTE_STANDARD_TYPE,
830 G_FILE_QUERY_INFO_NONE,
831 NULL,
832 &error);
833 if (file_info != NULL)
835 parent_directory = g_file_get_parent (file);
837 filename = g_file_get_basename (file);
838 if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
840 GFile *new_file =
841 ianjuta_project_manager_add_group (IANJUTA_PROJECT_MANAGER (plugin),
842 filename, parent_directory,
843 NULL);
844 g_object_unref (new_file);
846 else
848 GFile *new_file =
849 ianjuta_project_manager_add_source (IANJUTA_PROJECT_MANAGER
850 (plugin),
851 plugin->fm_current_uri,
852 parent_directory,
853 NULL);
854 g_object_unref (new_file);
856 g_object_unref (file_info);
857 g_free (filename);
858 g_object_unref (parent_directory);
860 else
862 anjuta_util_dialog_error (win, _("Failed to retrieve URI info of %s: %s"),
863 plugin->fm_current_uri, error->message);
864 g_error_free (error);
868 static void
869 on_node_activated (GtkWidget *widget, AnjutaProjectNode *node,
870 ProjectManagerPlugin *plugin)
872 IAnjutaFileLoader *loader;
874 switch (anjuta_project_node_get_node_type (node))
876 case ANJUTA_PROJECT_GROUP:
877 case ANJUTA_PROJECT_ROOT:
878 case ANJUTA_PROJECT_TARGET:
879 case ANJUTA_PROJECT_MODULE:
880 case ANJUTA_PROJECT_PACKAGE:
881 on_popup_properties (NULL, plugin);
882 break;
883 case ANJUTA_PROJECT_SOURCE:
884 loader = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
885 IAnjutaFileLoader, NULL);
886 if (loader)
887 ianjuta_file_loader_load (loader, anjuta_project_node_get_file (node), FALSE, NULL);
888 break;
889 default:
890 break;
894 static GtkActionEntry pm_actions[] =
897 "ActionMenuProject", NULL,
898 N_("_Project"), NULL, NULL, NULL
901 "ActionProjectNewFolder", GTK_STOCK_ADD,
902 N_("New _Folder…"), NULL, N_("Add a new folder to the project"),
903 G_CALLBACK (on_new_group)
906 "ActionProjectNewTarget", GTK_STOCK_ADD,
907 N_("New _Target…"), NULL, N_("Add a new target to the project"),
908 G_CALLBACK (on_new_target)
911 "ActionProjectAddSource", GTK_STOCK_ADD,
912 N_("Add _Source File…"), NULL, N_("Add a source file to a target"),
913 G_CALLBACK (on_add_source)
916 "ActionProjectAddLibrary", GTK_STOCK_ADD,
917 N_("Add _Library…"), NULL, N_("Add a module to a target"),
918 G_CALLBACK (on_add_module)
921 "ActionProjectNewLibrary", GTK_STOCK_ADD,
922 N_("New _Library…"), NULL, N_("Add a new package to the project"),
923 G_CALLBACK (on_new_package)
926 "ActionProjectProperties", GTK_STOCK_PROPERTIES,
927 N_("_Properties"), NULL, N_("Project properties"),
928 G_CALLBACK (on_properties)
931 "ActionFileCloseProject", NULL,
932 N_("Close Pro_ject"), NULL, N_("Close project"),
933 G_CALLBACK (on_close_project)
937 static GtkActionEntry popup_actions[] =
940 "ActionPopupProjectNewFolder", GTK_STOCK_ADD,
941 N_("New _Folder"), NULL, N_("Add a new folder to the project"),
942 G_CALLBACK (on_popup_new_group)
945 "ActionPopupProjectNewTarget", GTK_STOCK_ADD,
946 N_("New _Target"), NULL, N_("Add a new target to the project"),
947 G_CALLBACK (on_popup_new_target)
950 "ActionPopupProjectAddSource", GTK_STOCK_ADD,
951 N_("Add _Source File"), NULL, N_("Add a source file to a target"),
952 G_CALLBACK (on_popup_add_source)
955 "ActionPopupProjectAddLibrary", GTK_STOCK_ADD,
956 N_("Add _Library"), NULL, N_("Add a library to a target"),
957 G_CALLBACK (on_popup_add_module)
960 "ActionPopupProjectNewLibrary", GTK_STOCK_ADD,
961 N_("New _Library"), NULL, N_("Add a new library to the project"),
962 G_CALLBACK (on_popup_new_package)
965 "ActionPopupProjectAddToProject", GTK_STOCK_ADD,
966 N_("_Add to Project"), NULL, N_("Add a source file to a target"),
967 G_CALLBACK (on_popup_add_to_project)
970 "ActionPopupProjectProperties", GTK_STOCK_PROPERTIES,
971 N_("_Properties"), NULL, N_("Properties of group/target/source"),
972 G_CALLBACK (on_popup_properties)
975 "ActionPopupProjectRemove", GTK_STOCK_REMOVE,
976 N_("Re_move"), NULL, N_("Remove from project"),
977 G_CALLBACK (on_popup_remove)
980 "ActionPopupProjectSortShortcut", GTK_STOCK_SORT_ASCENDING,
981 N_("_Sort"), NULL, N_("Sort shortcuts"),
982 G_CALLBACK (on_popup_sort_shortcuts)
986 static void
987 update_ui (ProjectManagerPlugin *plugin)
989 AnjutaUI *ui;
990 gint j;
991 gint caps;
992 gint main_caps;
993 gint popup_caps;
995 /* Close project is always here */
996 main_caps = 0x101;
997 popup_caps = 0x100;
999 /* Check for supported node */
1000 caps = anjuta_pm_project_get_capabilities (plugin->project);
1001 if (caps != 0)
1003 if (caps & ANJUTA_PROJECT_CAN_ADD_GROUP)
1005 main_caps |= 0x2;
1006 popup_caps |= 0x21;
1008 if (caps & ANJUTA_PROJECT_CAN_ADD_TARGET)
1010 main_caps |= 0x4;
1011 popup_caps |= 0x2;
1013 if (caps & ANJUTA_PROJECT_CAN_ADD_SOURCE)
1015 main_caps |= 0x8;
1016 popup_caps |= 0x24;
1018 if (caps & ANJUTA_PROJECT_CAN_ADD_MODULE)
1020 main_caps |= 0x10;
1021 popup_caps |= 0x8;
1023 if (caps & ANJUTA_PROJECT_CAN_ADD_PACKAGE)
1025 main_caps |= 0x20;
1026 popup_caps |= 0x10;
1028 /* Keep remove if a project is opened */
1029 popup_caps |= 0x080;
1031 /* Keep properties and refresh if a project is opened */
1032 main_caps |= 0x0C0;
1033 /* Keep properties and remove if a project is opened */
1034 popup_caps |= 0x040;
1036 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
1038 /* Main menu */
1039 for (j = 0; j < G_N_ELEMENTS (pm_actions); j++)
1041 GtkAction *action;
1043 action = anjuta_ui_get_action (ui, "ActionGroupProjectManager",
1044 pm_actions[j].name);
1045 g_object_set (G_OBJECT (action), "visible", INT_TO_GBOOLEAN (main_caps & 0x1), NULL);
1046 main_caps >>= 1;
1049 /* Popup menu */
1050 for (j = 0; j < G_N_ELEMENTS (popup_actions); j++)
1052 GtkAction *action;
1054 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1055 popup_actions[j].name);
1056 g_object_set (G_OBJECT (action), "visible", INT_TO_GBOOLEAN (popup_caps & 0x1), NULL);
1057 popup_caps >>= 1;
1061 static void
1062 on_treeview_selection_changed (GtkTreeSelection *sel,
1063 ProjectManagerPlugin *plugin)
1065 AnjutaUI *ui;
1066 GtkAction *action;
1067 AnjutaProjectNode *node;
1068 gint state = 0;
1069 GFile *selected_file;
1070 GbfTreeData *data;
1072 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
1073 node = gbf_project_view_find_selected (plugin->view,
1074 ANJUTA_PROJECT_UNKNOWN);
1075 data = gbf_project_view_get_first_selected (plugin->view, NULL);
1077 if (node != NULL)
1079 AnjutaProjectNode *parent;
1081 state = anjuta_project_node_get_state (node);
1082 /* Allow to select a sibling instead of a parent node */
1083 parent = anjuta_project_node_parent (node);
1084 if (parent != NULL)
1086 state |= anjuta_project_node_get_state (parent);
1090 /* Popup menu */
1091 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1092 "ActionPopupProjectNewFolder");
1093 g_object_set (G_OBJECT (action), "sensitive", INT_TO_GBOOLEAN (state & ANJUTA_PROJECT_CAN_ADD_GROUP), NULL);
1094 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1095 "ActionPopupProjectNewTarget");
1096 g_object_set (G_OBJECT (action), "sensitive", INT_TO_GBOOLEAN (state & ANJUTA_PROJECT_CAN_ADD_TARGET), NULL);
1097 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1098 "ActionPopupProjectAddSource");
1099 g_object_set (G_OBJECT (action), "sensitive", INT_TO_GBOOLEAN (state & ANJUTA_PROJECT_CAN_ADD_SOURCE), NULL);
1100 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1101 "ActionPopupProjectAddLibrary");
1102 g_object_set (G_OBJECT (action), "sensitive", INT_TO_GBOOLEAN (state & ANJUTA_PROJECT_CAN_ADD_MODULE), NULL);
1103 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1104 "ActionPopupProjectNewLibrary");
1105 g_object_set (G_OBJECT (action), "sensitive", INT_TO_GBOOLEAN (state & ANJUTA_PROJECT_CAN_ADD_PACKAGE), NULL);
1106 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1107 "ActionPopupProjectRemove");
1108 g_object_set (G_OBJECT (action), "sensitive", INT_TO_GBOOLEAN (state & ANJUTA_PROJECT_CAN_REMOVE), NULL);
1109 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1110 "ActionPopupProjectSortShortcut");
1111 g_object_set (G_OBJECT (action), "sensitive", (data != NULL) && (data->type == GBF_TREE_NODE_SHORTCUT), NULL);
1113 selected_file = node != NULL ? anjuta_project_node_get_file (node) : NULL;
1114 if (selected_file)
1116 GValue *value;
1117 gchar *uri = g_file_get_uri (selected_file);
1119 value = g_new0 (GValue, 1);
1120 g_value_init (value, G_TYPE_STRING);
1121 g_value_set_string (value, uri);
1122 anjuta_shell_add_value (ANJUTA_PLUGIN(plugin)->shell,
1123 IANJUTA_PROJECT_MANAGER_CURRENT_URI,
1124 value, NULL);
1125 g_signal_emit_by_name (G_OBJECT (plugin), "element_selected",
1126 selected_file);
1127 g_free (uri);
1128 } else {
1129 anjuta_shell_remove_value (ANJUTA_PLUGIN(plugin)->shell,
1130 IANJUTA_PROJECT_MANAGER_CURRENT_URI, NULL);
1134 static gboolean
1135 on_treeview_popup_menu (GtkWidget *widget,
1136 ProjectManagerPlugin *plugin)
1138 AnjutaUI *ui;
1139 GtkWidget *popup;
1141 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
1142 popup = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui), "/PopupProjectManager");
1143 g_return_val_if_fail (GTK_IS_WIDGET (popup), FALSE);
1145 gtk_menu_popup (GTK_MENU (popup),
1146 NULL, NULL, NULL, NULL,
1148 gtk_get_current_event_time());
1150 return TRUE;
1153 static gboolean
1154 on_treeview_button_press_event (GtkWidget *widget,
1155 GdkEventButton *event,
1156 ProjectManagerPlugin *plugin)
1158 if (event->button == 3)
1160 GtkTreePath *path;
1161 GtkTreeSelection *selection;
1162 AnjutaUI *ui;
1163 GtkWidget *popup;
1165 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget),
1166 event->x,event->y, &path, NULL, NULL, NULL))
1167 return FALSE;
1169 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW (widget));
1170 if (!gtk_tree_selection_path_is_selected(selection, path))
1172 gtk_tree_selection_unselect_all(selection);
1173 gtk_tree_selection_select_path(selection, path);
1174 gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget),
1175 path, NULL, FALSE);
1177 gtk_tree_path_free (path);
1179 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
1180 popup = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui), "/PopupProjectManager");
1181 g_return_val_if_fail (GTK_IS_WIDGET (popup), FALSE);
1183 gtk_menu_popup (GTK_MENU (popup),
1184 NULL, NULL, NULL, NULL,
1185 ((GdkEventButton *) event)->button,
1186 ((GdkEventButton *) event)->time);
1188 return TRUE;
1191 return FALSE;
1195 *---------------------------------------------------------------------------*/
1197 static void
1198 register_stock_icons (AnjutaPlugin *plugin)
1200 static gboolean registered = FALSE;
1202 if (registered)
1203 return;
1204 registered = TRUE;
1206 /* Register stock icons */
1207 BEGIN_REGISTER_ICON(plugin);
1208 REGISTER_ICON (ICON_FILE,
1209 "project-manager-plugin-icon");
1210 END_REGISTER_ICON;
1213 static void
1214 value_added_fm_current_file (AnjutaPlugin *plugin, const char *name,
1215 const GValue *value, gpointer data)
1217 AnjutaUI *ui;
1218 GtkAction *action;
1219 gchar *uri;
1220 ProjectManagerPlugin *pm_plugin;
1222 GFile* file = g_value_get_object (value);
1223 uri = g_file_get_uri (file);
1225 pm_plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (plugin);
1226 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1228 if (pm_plugin->fm_current_uri)
1229 g_free (pm_plugin->fm_current_uri);
1230 pm_plugin->fm_current_uri = g_strdup (uri);
1232 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1233 "ActionPopupProjectAddToProject");
1234 g_object_set (G_OBJECT (action), "sensitive", TRUE, NULL);
1235 g_free (uri);
1238 static void
1239 value_removed_fm_current_file (AnjutaPlugin *plugin,
1240 const char *name, gpointer data)
1242 AnjutaUI *ui;
1243 GtkAction *action;
1244 ProjectManagerPlugin *pm_plugin;
1246 pm_plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (plugin);
1248 if (pm_plugin->fm_current_uri)
1249 g_free (pm_plugin->fm_current_uri);
1250 pm_plugin->fm_current_uri = NULL;
1252 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1253 action = anjuta_ui_get_action (ui, "ActionGroupProjectManagerPopup",
1254 "ActionPopupProjectAddToProject");
1255 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
1258 static void
1259 value_added_current_editor (AnjutaPlugin *plugin, const char *name,
1260 const GValue *value, gpointer data)
1262 GObject *editor;
1263 ProjectManagerPlugin *pm_plugin;
1264 GFile* file;
1266 editor = g_value_get_object (value);
1267 if (!IANJUTA_IS_EDITOR(editor))
1268 return;
1270 pm_plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (plugin);
1272 if (pm_plugin->current_editor_uri)
1273 g_free (pm_plugin->current_editor_uri);
1274 file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
1275 if (file)
1277 pm_plugin->current_editor_uri = g_file_get_uri (file);
1278 g_object_unref (file);
1280 else
1281 pm_plugin->current_editor_uri = NULL;
1285 static void
1286 value_removed_current_editor (AnjutaPlugin *plugin,
1287 const char *name, gpointer data)
1289 ProjectManagerPlugin *pm_plugin;
1291 pm_plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (plugin);
1293 if (pm_plugin->current_editor_uri)
1294 g_free (pm_plugin->current_editor_uri);
1295 pm_plugin->current_editor_uri = NULL;
1298 static void
1299 on_project_loaded (AnjutaPmProject *project, GtkTreeIter *parent, gboolean complete, GError *error, ProjectManagerPlugin *plugin)
1301 AnjutaStatus *status;
1302 gchar *dirname;
1304 dirname = anjuta_util_get_local_path_from_uri (plugin->project_root_uri);
1305 status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
1306 if (error)
1308 if (complete)
1310 GtkWidget *toplevel;
1311 GtkWindow *win;
1313 toplevel = gtk_widget_get_toplevel (plugin->scrolledwindow);
1314 if (toplevel && GTK_IS_WINDOW (toplevel))
1315 win = GTK_WINDOW (toplevel);
1316 else
1317 win = GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell);
1319 anjuta_util_dialog_error (win, _("Failed to parse project (the project is opened, but there will be no project view) %s: %s\n"
1320 ""),
1321 dirname, error->message);
1325 if (complete)
1327 gchar *basename = g_path_get_basename (dirname);
1329 anjuta_status_progress_tick (status, NULL, _("Update project view…"));
1330 update_ui (plugin);
1331 anjuta_shell_present_widget (ANJUTA_PLUGIN (plugin)->shell,
1332 plugin->scrolledwindow,
1333 NULL);
1334 anjuta_status_set_default (status, _("Project"), basename);
1335 g_free (basename);
1337 if (plugin->busy)
1339 anjuta_status_pop (status);
1340 anjuta_status_busy_pop (status);
1341 plugin->busy = FALSE;
1344 /* Emit loaded signal for other plugins */
1345 g_signal_emit_by_name (G_OBJECT (plugin), "project_loaded", error);
1349 g_free (dirname);
1352 static void
1353 project_manager_load_gbf (ProjectManagerPlugin *pm_plugin)
1355 AnjutaStatus *status;
1356 gchar *dirname;
1357 GFile *dirfile;
1358 gchar *basename;
1359 const gchar *root_uri;
1360 GError *error = NULL;
1362 root_uri = pm_plugin->project_root_uri;
1364 dirname = anjuta_util_get_local_path_from_uri (root_uri);
1365 dirfile = g_file_new_for_uri (root_uri);
1367 g_return_if_fail (dirname != NULL);
1369 status = anjuta_shell_get_status (ANJUTA_PLUGIN (pm_plugin)->shell, NULL);
1370 anjuta_status_progress_add_ticks (status, 1);
1371 basename = g_path_get_basename (dirname);
1372 anjuta_status_push (status, _("Loading project: %s"), basename);
1373 anjuta_status_busy_push (status);
1374 pm_plugin->busy = TRUE;
1376 anjuta_pm_project_unload (pm_plugin->project, NULL);
1378 DEBUG_PRINT ("loading project %s\n\n", dirname);
1379 anjuta_pm_project_load (pm_plugin->project, dirfile, &error);
1380 update_ui (pm_plugin);
1382 g_free (basename);
1383 g_free (dirname);
1384 g_object_unref (dirfile);
1387 static void
1388 project_manager_unload_gbf (ProjectManagerPlugin *pm_plugin)
1390 AnjutaStatus *status;
1392 if (anjuta_pm_project_is_open (pm_plugin->project))
1394 IAnjutaDocumentManager *docman;
1396 /* Close files that belong to this project (that are saved) */
1397 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (pm_plugin)->shell,
1398 IAnjutaDocumentManager, NULL);
1399 if (docman)
1401 GList *to_remove = NULL;
1402 GList *editors;
1403 GList *node;
1405 editors =
1406 ianjuta_document_manager_get_doc_widgets (docman, NULL);
1407 node = editors;
1408 while (node)
1410 if (!IANJUTA_IS_EDITOR(node->data))
1412 node = g_list_next(node);
1413 continue;
1415 GFile* editor_file = ianjuta_file_get_file (IANJUTA_FILE (node->data), NULL);
1416 gchar *editor_uri = g_file_get_uri (editor_file);
1417 g_object_unref (editor_file);
1420 /* Only remove if it does not have unsaved data */
1421 if (editor_uri && (!IANJUTA_IS_FILE_SAVABLE (node->data) ||
1422 !ianjuta_file_savable_is_dirty
1423 (IANJUTA_FILE_SAVABLE (node->data),
1424 NULL)))
1426 if (strncmp (editor_uri, pm_plugin->project_root_uri,
1427 strlen (pm_plugin->project_root_uri)) == 0 &&
1428 editor_uri[strlen (pm_plugin->project_root_uri)] == '/')
1430 to_remove = g_list_prepend (to_remove, node->data);
1433 g_free (editor_uri);
1434 node = g_list_next (node);
1436 node = to_remove;
1437 while (node)
1439 ianjuta_document_manager_remove_document (docman,
1440 IANJUTA_DOCUMENT (node->data),
1441 FALSE,
1442 NULL);
1443 node = g_list_next (node);
1445 if (editors)
1446 g_list_free (editors);
1447 if (to_remove)
1448 g_list_free (to_remove);
1451 /* Release project */
1452 anjuta_pm_project_unload (pm_plugin->project, NULL);
1453 update_ui (pm_plugin);
1454 status = anjuta_shell_get_status (ANJUTA_PLUGIN (pm_plugin)->shell,
1455 NULL);
1456 anjuta_status_set_default (status, _("Project"), NULL);
1460 static void
1461 on_profile_scoped (AnjutaProfileManager *profile_manager,
1462 AnjutaProfile *profile, ProjectManagerPlugin *plugin)
1464 gchar *session_dir;
1465 DEBUG_PRINT ("Profile scoped: %s", anjuta_profile_get_name (profile));
1466 if (strcmp (anjuta_profile_get_name (profile), PROJECT_PROFILE_NAME) != 0)
1467 return;
1469 DEBUG_PRINT ("%s", "Project profile loaded; Restoring project session");
1471 /* Load gbf project */
1472 project_manager_load_gbf (plugin);
1475 update_title (plugin, plugin->project_root_uri);
1477 /* If profile scoped to "project", restore project session */
1478 session_dir = get_session_dir (plugin);
1479 g_return_if_fail (session_dir != NULL);
1482 * If there is a session load already in progress (that is this
1483 * project is being opened in session restoration), our session
1484 * load would be ignored. Good thing.
1486 plugin->session_by_me = TRUE;
1487 anjuta_shell_session_load (ANJUTA_PLUGIN (plugin)->shell,
1488 session_dir, NULL);
1489 plugin->session_by_me = FALSE;
1490 g_free (session_dir);
1493 static void
1494 on_profile_descoped (AnjutaProfileManager *profile_manager,
1495 AnjutaProfile *profile, ProjectManagerPlugin *plugin)
1497 DEBUG_PRINT ("Profile descoped: %s", anjuta_profile_get_name (profile));
1499 if (strcmp (anjuta_profile_get_name (profile), PROJECT_PROFILE_NAME) != 0)
1500 return;
1502 DEBUG_PRINT ("%s", "Project profile descoped; Saving project session");
1504 /* Save current project session */
1505 g_return_if_fail (plugin->project_root_uri != NULL);
1507 /* Save project session */
1508 project_manager_save_session (plugin);
1510 /* Close current project */
1511 project_manager_unload_gbf (plugin);
1513 g_free (plugin->project_root_uri);
1514 if (plugin->project_file) g_object_unref (plugin->project_file);
1515 plugin->project_file = NULL;
1516 plugin->project_root_uri = NULL;
1518 update_title (ANJUTA_PLUGIN_PROJECT_MANAGER (plugin), NULL);
1519 anjuta_shell_remove_value (ANJUTA_PLUGIN (plugin)->shell,
1520 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI, NULL);
1523 static void
1524 project_manager_plugin_close (ProjectManagerPlugin *plugin)
1526 AnjutaProfileManager *profile_manager;
1527 GError *error = NULL;
1529 /* Remove project profile */
1530 profile_manager =
1531 anjuta_shell_get_profile_manager (ANJUTA_PLUGIN (plugin)->shell, NULL);
1532 anjuta_profile_manager_pop (profile_manager, PROJECT_PROFILE_NAME, &error);
1533 if (error)
1535 anjuta_util_dialog_error (get_plugin_parent_window (plugin),
1536 _("Error closing project: %s"),
1537 error->message);
1538 g_error_free (error);
1542 static gboolean
1543 project_manager_plugin_activate_plugin (AnjutaPlugin *plugin)
1545 AnjutaProfileManager *profile_manager;
1546 GtkWidget *scrolled_window;
1547 GtkWidget *view;
1548 static gboolean initialized = FALSE;
1549 GtkTreeSelection *selection;
1550 /* GladeXML *gxml; */
1551 ProjectManagerPlugin *pm_plugin;
1553 DEBUG_PRINT ("ProjectManagerPlugin: Activating Project Manager plugin %p…", plugin);
1555 if (!initialized)
1556 register_stock_icons (plugin);
1558 pm_plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (plugin);
1559 pm_plugin->ui = anjuta_shell_get_ui (plugin->shell, NULL);
1560 pm_plugin->prefs = anjuta_shell_get_preferences (plugin->shell, NULL);
1562 /* Create project */
1563 pm_plugin->project = anjuta_pm_project_new (plugin);
1565 /* create model & view and bind them */
1566 view = gbf_project_view_new ();
1568 /* Add project to view */
1569 gbf_project_view_set_project (GBF_PROJECT_VIEW (view), pm_plugin->project);
1570 g_signal_connect (view, "node-loaded", G_CALLBACK (on_project_loaded), plugin);
1572 /*gtk_tree_view_set_model (GTK_TREE_VIEW (view),
1573 GTK_TREE_MODEL (anjuta_pm_project_get_model (pm_plugin->project)));*/
1575 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
1576 gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
1577 g_signal_connect (view, "node-selected",
1578 G_CALLBACK (on_node_activated), plugin);
1579 g_signal_connect (selection, "changed",
1580 G_CALLBACK (on_treeview_selection_changed), plugin);
1581 g_signal_connect (view, "button-press-event",
1582 G_CALLBACK (on_treeview_button_press_event), plugin);
1583 g_signal_connect (view, "popup-menu",
1584 G_CALLBACK (on_treeview_popup_menu), plugin);
1586 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1587 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
1588 GTK_POLICY_AUTOMATIC,
1589 GTK_POLICY_AUTOMATIC);
1590 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
1591 GTK_SHADOW_IN);
1592 gtk_container_add (GTK_CONTAINER (scrolled_window), view);
1593 gtk_widget_show (view);
1594 gtk_widget_show (scrolled_window);
1596 pm_plugin->scrolledwindow = scrolled_window;
1597 pm_plugin->view = GBF_PROJECT_VIEW (view);
1599 /* Action groups */
1600 pm_plugin->pm_action_group =
1601 anjuta_ui_add_action_group_entries (pm_plugin->ui,
1602 "ActionGroupProjectManager",
1603 _("Project manager actions"),
1604 pm_actions,
1605 G_N_ELEMENTS(pm_actions),
1606 GETTEXT_PACKAGE, TRUE,
1607 plugin);
1608 pm_plugin->popup_action_group =
1609 anjuta_ui_add_action_group_entries (pm_plugin->ui,
1610 "ActionGroupProjectManagerPopup",
1611 _("Project manager popup actions"),
1612 popup_actions,
1613 G_N_ELEMENTS (popup_actions),
1614 GETTEXT_PACKAGE, TRUE,
1615 plugin);
1616 /* Merge UI */
1617 pm_plugin->merge_id =
1618 anjuta_ui_merge (pm_plugin->ui, UI_FILE);
1620 update_ui (pm_plugin);
1622 /* Added widget in shell */
1623 anjuta_shell_add_widget (plugin->shell, pm_plugin->scrolledwindow,
1624 "AnjutaProjectManager", _("Project"),
1625 "project-manager-plugin-icon",
1626 ANJUTA_SHELL_PLACEMENT_LEFT, NULL);
1627 #if 0
1628 /* Add preferences page */
1629 gxml = glade_xml_new (PREFS_GLADE, "dialog.project.manager", NULL);
1631 anjuta_preferences_add_page (pm_plugin->prefs,
1632 gxml, "Project Manager", ICON_FILE);
1633 preferences_changed(pm_plugin->prefs, pm_plugin);
1634 g_object_unref (G_OBJECT (gxml));
1635 #endif
1637 /* Add watches */
1638 pm_plugin->fm_watch_id =
1639 anjuta_plugin_add_watch (plugin, IANJUTA_FILE_MANAGER_SELECTED_FILE,
1640 value_added_fm_current_file,
1641 value_removed_fm_current_file, NULL);
1642 pm_plugin->editor_watch_id =
1643 anjuta_plugin_add_watch (plugin, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
1644 value_added_current_editor,
1645 value_removed_current_editor, NULL);
1646 /* Connect to save session */
1647 g_signal_connect (G_OBJECT (plugin->shell), "save_session",
1648 G_CALLBACK (on_session_save), plugin);
1649 g_signal_connect (G_OBJECT (plugin->shell), "load_session",
1650 G_CALLBACK (on_session_load), plugin);
1651 g_signal_connect (G_OBJECT (plugin->shell), "exiting",
1652 G_CALLBACK (on_shell_exiting), plugin);
1653 profile_manager = anjuta_shell_get_profile_manager (plugin->shell, NULL);
1655 /* Connect to profile scoping */
1656 g_signal_connect (profile_manager, "profile-scoped",
1657 G_CALLBACK (on_profile_scoped), plugin);
1658 g_signal_connect (profile_manager, "profile-descoped",
1659 G_CALLBACK (on_profile_descoped), plugin);
1660 return TRUE;
1663 static gboolean
1664 project_manager_plugin_deactivate_plugin (AnjutaPlugin *plugin)
1666 AnjutaProfileManager *profile_manager;
1667 ProjectManagerPlugin *pm_plugin;
1668 pm_plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (plugin);
1670 DEBUG_PRINT ("ProjectManagerPlugin: Deactivate Project Manager plugin…");
1671 if (pm_plugin->close_project_idle > -1)
1673 g_source_remove (pm_plugin->close_project_idle);
1676 /* Close project if it's open */
1677 if (pm_plugin->project_root_uri)
1678 project_manager_plugin_close (pm_plugin);
1680 profile_manager = anjuta_shell_get_profile_manager (plugin->shell, NULL);
1682 /* Disconnect signals */
1683 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1684 G_CALLBACK (on_session_save),
1685 plugin);
1686 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1687 G_CALLBACK (on_session_load),
1688 plugin);
1689 g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->shell),
1690 G_CALLBACK (on_shell_exiting),
1691 plugin);
1692 g_signal_handlers_disconnect_by_func (G_OBJECT (profile_manager),
1693 G_CALLBACK (on_profile_descoped),
1694 plugin);
1695 g_signal_handlers_disconnect_by_func (G_OBJECT (profile_manager),
1696 G_CALLBACK (on_profile_scoped),
1697 plugin);
1698 /* Remove watches */
1699 anjuta_plugin_remove_watch (plugin, pm_plugin->fm_watch_id, TRUE);
1700 anjuta_plugin_remove_watch (plugin, pm_plugin->editor_watch_id, TRUE);
1702 /* Widget is removed from the shell when destroyed */
1703 gtk_widget_destroy (pm_plugin->scrolledwindow);
1705 anjuta_ui_unmerge (pm_plugin->ui, pm_plugin->merge_id);
1706 anjuta_ui_remove_action_group (pm_plugin->ui, pm_plugin->pm_action_group);
1707 anjuta_ui_remove_action_group (pm_plugin->ui,
1708 pm_plugin->popup_action_group);
1710 /* Remove shortcuts list */
1711 g_list_foreach (pm_plugin->shortcuts, (GFunc)g_free, NULL);
1712 g_list_free (pm_plugin->shortcuts);
1713 pm_plugin->shortcuts = NULL;
1715 /* Destroy project */
1716 anjuta_pm_project_free (pm_plugin->project);
1718 return TRUE;
1721 static void
1722 project_manager_plugin_finalize (GObject *obj)
1724 /* FIXME: */
1725 G_OBJECT_CLASS (parent_class)->finalize (obj);
1728 static void
1729 project_manager_plugin_dispose (GObject *obj)
1731 /* FIXME: */
1732 G_OBJECT_CLASS (parent_class)->dispose (obj);
1735 static void
1736 project_manager_plugin_instance_init (GObject *obj)
1738 ProjectManagerPlugin *plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (obj);
1739 plugin->scrolledwindow = NULL;
1740 plugin->project = NULL;
1741 plugin->view = NULL;
1742 plugin->pre_update_sources = NULL;
1743 plugin->pre_update_targets = NULL;
1744 plugin->pre_update_groups = NULL;
1745 plugin->project_root_uri = NULL;
1746 plugin->project_file = NULL;
1747 plugin->fm_current_uri = NULL;
1748 plugin->current_editor_uri = NULL;
1749 plugin->session_by_me = FALSE;
1750 plugin->close_project_idle = -1;
1751 plugin->shortcuts = NULL;
1754 static void
1755 project_manager_plugin_class_init (GObjectClass *klass)
1757 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1759 parent_class = g_type_class_peek_parent (klass);
1761 plugin_class->activate = project_manager_plugin_activate_plugin;
1762 plugin_class->deactivate = project_manager_plugin_deactivate_plugin;
1763 klass->dispose = project_manager_plugin_finalize;
1764 klass->dispose = project_manager_plugin_dispose;
1767 /* IAnjutaProjectManager implementation */
1769 static gboolean
1770 file_is_inside_project (ProjectManagerPlugin *plugin, GFile *file)
1772 gchar *uri = g_file_get_uri (file);
1773 gboolean inside = FALSE;
1775 if (plugin->project_root_uri == NULL)
1777 /* No project open */
1778 return FALSE;
1781 if (strncmp (uri, plugin->project_root_uri,
1782 strlen (plugin->project_root_uri)) == 0)
1784 g_free (uri);
1785 return TRUE;
1788 if (uri[0] == '/')
1790 const gchar *project_root_path = strchr (plugin->project_root_uri, ':');
1791 if (project_root_path)
1792 project_root_path += 3;
1793 else
1794 project_root_path = plugin->project_root_uri;
1795 inside = strncmp (uri, project_root_path,
1796 strlen (project_root_path)) == 0;
1798 g_free (uri);
1800 return inside;
1803 static GFile*
1804 get_element_file_from_node (ProjectManagerPlugin *plugin, AnjutaProjectNode *node, const gchar *root)
1806 const gchar *project_root = NULL;
1807 GFile *file = NULL;
1809 if (!node)
1810 return NULL;
1812 anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell,
1813 root, G_TYPE_STRING,
1814 &project_root, NULL);
1815 if (project_root == NULL)
1817 /* Perhaps missing build URI, use project URI instead */
1818 anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell,
1819 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
1820 G_TYPE_STRING,
1821 &project_root,
1822 NULL);
1825 file = g_object_ref (anjuta_project_node_get_file (node));
1827 if ((file != NULL) && (project_root != NULL))
1829 gchar *rel_path;
1831 rel_path = g_file_get_relative_path (anjuta_project_node_get_file (anjuta_pm_project_get_root (plugin->project)), file);
1833 if (rel_path)
1835 GFile *node_file = NULL;
1836 GFile *root_file = NULL;
1837 root_file = g_file_new_for_uri (project_root);
1838 node_file = g_file_get_child (root_file, rel_path);
1839 g_object_unref (root_file);
1840 g_object_unref (file);
1842 file = node_file;
1843 g_free (rel_path);
1847 return file;
1850 static GtkTreeIter*
1851 get_tree_iter_from_file (ProjectManagerPlugin *plugin, GtkTreeIter* iter, GFile *file, GbfTreeNodeType type)
1853 gboolean found;
1855 found = gbf_project_view_find_file (plugin->view, iter, file, type);
1857 return found ? iter : NULL;
1860 static gboolean
1861 project_node_compare (AnjutaProjectNode *node, gpointer data)
1863 GFile *file = (GFile *)data;
1865 switch (anjuta_project_node_get_node_type (node))
1867 case ANJUTA_PROJECT_GROUP:
1868 case ANJUTA_PROJECT_SOURCE:
1869 case ANJUTA_PROJECT_OBJECT:
1870 case ANJUTA_PROJECT_TARGET:
1871 return g_file_equal (anjuta_project_node_get_file (node), file);
1872 default:
1873 return FALSE;
1877 static AnjutaProjectNode *
1878 get_node_from_file (const AnjutaProjectNode *root, GFile *file)
1880 AnjutaProjectNode *node;
1882 node = anjuta_project_node_traverse ((AnjutaProjectNode *)root, G_PRE_ORDER, project_node_compare, file);
1884 return node;
1887 static AnjutaProjectNodeType
1888 get_element_type (ProjectManagerPlugin *plugin, GFile *element)
1890 AnjutaProjectNode *node;
1892 node = gbf_project_view_get_node_from_file (plugin->view, ANJUTA_PROJECT_UNKNOWN, element);
1894 return node == NULL ? ANJUTA_PROJECT_UNKNOWN : anjuta_project_node_get_node_type (node);
1897 static GList*
1898 iproject_manager_get_children (IAnjutaProjectManager *project_manager,
1899 GFile *parent,
1900 gint children_type,
1901 GError **err)
1903 ProjectManagerPlugin *plugin;
1904 GList *children = NULL;
1906 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), NULL);
1908 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
1909 if (plugin->project != NULL)
1911 AnjutaProjectNode *root;
1913 root = anjuta_pm_project_get_root (plugin->project);
1914 if (root != NULL)
1916 /* Get parent */
1917 if (parent != NULL) root = get_node_from_file (root, parent);
1918 if (root != NULL)
1920 /* Get all nodes */
1921 GList *node;
1922 GHashTable *included_hash;
1924 children = gbf_project_util_node_all (root, children_type);
1926 /* Replace all nodes by their corresponding file and remove duplicate */
1927 included_hash = g_hash_table_new ((GHashFunc)g_file_hash, (GEqualFunc)g_file_equal);
1928 node = g_list_first (children);
1929 while (node != NULL)
1931 GFile *file;
1933 if (anjuta_project_node_get_node_type (ANJUTA_PROJECT_NODE (node->data)) == ANJUTA_PROJECT_TARGET)
1935 /* Take care of different build directory */
1936 file = get_element_file_from_node (plugin, ANJUTA_PROJECT_NODE (node->data), IANJUTA_BUILDER_ROOT_URI);
1938 else
1940 file = g_object_ref (anjuta_project_node_get_file (ANJUTA_PROJECT_NODE (node->data)));
1943 if (g_hash_table_lookup (included_hash, file) != NULL)
1945 /* Already included, remove */
1946 GList *next = g_list_next (node);
1948 children = g_list_delete_link (children, node);
1949 g_object_unref (file);
1950 node = next;
1952 else
1954 /* Keep in the list */
1955 g_hash_table_replace (included_hash, file, file);
1957 node->data = file;
1958 node = g_list_next (node);
1961 g_hash_table_destroy (included_hash);
1966 return children;
1969 static GList*
1970 iproject_manager_get_elements (IAnjutaProjectManager *project_manager,
1971 AnjutaProjectNodeType element_type,
1972 GError **err)
1974 return ianjuta_project_manager_get_children (project_manager, NULL, element_type, err);
1977 static AnjutaProjectNodeType
1978 iproject_manager_get_target_type (IAnjutaProjectManager *project_manager,
1979 GFile *target_file,
1980 GError **err)
1982 ProjectManagerPlugin *plugin;
1984 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager),
1985 ANJUTA_PROJECT_UNKNOWN);
1987 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
1989 /* Check that file belongs to the project */
1990 if ((plugin->project != NULL) && file_is_inside_project (plugin, target_file))
1992 AnjutaProjectNode *node;
1994 node = anjuta_pm_project_get_root (plugin->project);
1995 if (node != NULL)
1997 node = get_node_from_file (node, target_file);
1998 if (node != NULL) return anjuta_project_node_get_node_type (node);
2002 return ANJUTA_PROJECT_UNKNOWN;
2004 static GList*
2005 iproject_manager_get_targets (IAnjutaProjectManager *project_manager,
2006 AnjutaProjectNodeType target_type,
2007 GError **err)
2009 GList *targets, *node;
2010 ProjectManagerPlugin *plugin;
2012 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), NULL);
2014 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2016 /* Get all targets */
2017 targets = gbf_project_util_node_all (anjuta_pm_project_get_root (plugin->project), target_type);
2019 /* Replace all targets by their corresponding URI */
2020 for (node = g_list_first (targets); node != NULL; node = g_list_next (node))
2022 node->data = get_element_file_from_node (plugin, node->data, IANJUTA_BUILDER_ROOT_URI);
2025 return targets;
2028 static GFile*
2029 iproject_manager_get_parent (IAnjutaProjectManager *project_manager,
2030 GFile *element,
2031 GError **err)
2033 ProjectManagerPlugin *plugin;
2034 GFile *file = NULL;
2036 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), NULL);
2038 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2039 if (plugin->project != NULL)
2041 AnjutaProjectNode *node;
2043 node = anjuta_pm_project_get_root (plugin->project);
2044 if (node != NULL)
2046 node = get_node_from_file (node, element);
2047 if (node != NULL) node = anjuta_project_node_parent (node);
2048 if (node != NULL)
2050 file = anjuta_project_node_get_file (node);
2051 if (file != NULL) g_object_ref (file);
2056 return file;
2059 static GFile*
2060 iproject_manager_get_selected (IAnjutaProjectManager *project_manager,
2061 GError **err)
2063 AnjutaProjectNode *node;
2064 ProjectManagerPlugin *plugin;
2066 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), NULL);
2068 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2069 if (!anjuta_pm_project_is_open (plugin->project)) return NULL;
2071 node = gbf_project_view_find_selected (plugin->view,
2072 ANJUTA_PROJECT_SOURCE);
2073 if (node && anjuta_project_node_get_node_type (node) == ANJUTA_PROJECT_SOURCE)
2075 return g_object_ref (anjuta_project_node_get_file (node));
2078 node = gbf_project_view_find_selected (plugin->view,
2079 ANJUTA_PROJECT_TARGET);
2080 if (node && anjuta_project_node_get_node_type (node) == ANJUTA_PROJECT_TARGET)
2082 return get_element_file_from_node (plugin, node, IANJUTA_BUILDER_ROOT_URI);
2085 node = gbf_project_view_find_selected (plugin->view,
2086 ANJUTA_PROJECT_GROUP);
2087 if (node && anjuta_project_node_get_node_type (node) == GBF_TREE_NODE_GROUP)
2089 return g_object_ref (anjuta_project_node_get_file (node));
2092 return NULL;
2095 static guint
2096 iproject_manager_get_capabilities (IAnjutaProjectManager *project_manager,
2097 GError **err)
2099 ProjectManagerPlugin *plugin;
2101 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), 0);
2103 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2104 return anjuta_pm_project_get_capabilities (plugin->project);
2107 static GFile*
2108 iproject_manager_add_source (IAnjutaProjectManager *project_manager,
2109 const gchar *source_uri_to_add,
2110 GFile *default_target_file,
2111 GError **err)
2113 ProjectManagerPlugin *plugin;
2114 GtkTreeIter target_iter;
2115 GtkTreeIter *iter = NULL;
2116 AnjutaProjectNode *source_id;
2117 GFile* source;
2119 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
2121 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2123 update_operation_begin (plugin);
2124 if (default_target_file != NULL)
2126 iter = get_tree_iter_from_file (plugin, &target_iter, default_target_file, GBF_TREE_NODE_TARGET);
2128 source_id = anjuta_pm_project_new_source (plugin,
2129 get_plugin_parent_window (plugin),
2130 iter,
2131 source_uri_to_add);
2132 update_operation_end (plugin, TRUE);
2134 source = get_element_file_from_node(plugin, source_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
2136 return source;
2139 static GFile*
2140 iproject_manager_add_source_quiet (IAnjutaProjectManager *project_manager,
2141 const gchar *source_uri_to_add,
2142 GFile *location_file,
2143 GError **err)
2145 ProjectManagerPlugin *plugin;
2146 AnjutaProjectNode *source_id;
2147 AnjutaProjectNode *target = NULL;
2149 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
2151 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2153 target = gbf_project_view_get_node_from_file (plugin->view, ANJUTA_PROJECT_UNKNOWN, location_file);
2154 if (target != NULL)
2156 update_operation_begin (plugin);
2157 source_id = anjuta_pm_project_add_source (plugin->project,
2158 target,
2159 NULL,
2160 source_uri_to_add,
2161 err);
2162 update_operation_end (plugin, TRUE);
2164 return get_element_file_from_node (plugin, source_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
2166 else
2168 return NULL;
2172 static GList*
2173 iproject_manager_add_source_multi (IAnjutaProjectManager *project_manager,
2174 GList *source_add_uris,
2175 GFile *default_target_file,
2176 GError **err)
2178 ProjectManagerPlugin *plugin;
2179 GtkTreeIter target_iter;
2180 GtkTreeIter *iter = NULL;
2181 GList* source_ids;
2182 GList* source_files = NULL;
2184 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
2186 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2188 update_operation_begin (plugin);
2189 if (default_target_file != NULL)
2191 iter = get_tree_iter_from_file (plugin, &target_iter, default_target_file, GBF_TREE_NODE_TARGET);
2194 source_ids = anjuta_pm_project_new_multiple_source (plugin,
2195 get_plugin_parent_window (plugin),
2196 iter,
2197 source_add_uris);
2198 update_operation_end (plugin, TRUE);
2200 while (source_ids)
2202 source_files = g_list_append (source_files,
2203 get_element_file_from_node (plugin,
2204 source_ids->data,
2205 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI));
2206 source_ids = g_list_delete_link (source_ids, source_ids);
2209 return source_files;
2212 static GFile*
2213 iproject_manager_add_target (IAnjutaProjectManager *project_manager,
2214 const gchar *target_name_to_add,
2215 GFile *default_group_file,
2216 GError **err)
2218 ProjectManagerPlugin *plugin;
2219 GtkTreeIter group_iter;
2220 GtkTreeIter *iter = NULL;
2221 GFile *target = NULL;
2222 AnjutaProjectNode *target_id;
2224 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
2226 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2228 if (default_group_file != NULL)
2230 iter = get_tree_iter_from_file (plugin, &group_iter, default_group_file, GBF_TREE_NODE_GROUP);
2233 update_operation_begin (plugin);
2234 target_id = anjuta_pm_project_new_target (plugin,
2235 get_plugin_parent_window (plugin),
2236 iter,
2237 target_name_to_add);
2238 update_operation_end (plugin, TRUE);
2239 target = get_element_file_from_node (plugin, target_id, IANJUTA_BUILDER_ROOT_URI);
2241 return target;
2244 static GFile*
2245 iproject_manager_add_group (IAnjutaProjectManager *project_manager,
2246 const gchar *group_name_to_add,
2247 GFile *default_group_file,
2248 GError **err)
2250 ProjectManagerPlugin *plugin;
2251 GtkTreeIter group_iter;
2252 GtkTreeIter *iter = NULL;
2253 GFile *group = NULL;
2254 AnjutaProjectNode *group_id;
2256 g_return_val_if_fail (ANJUTA_IS_PLUGIN (project_manager), FALSE);
2258 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2260 if (default_group_file != NULL)
2262 iter = get_tree_iter_from_file (plugin, &group_iter, default_group_file, GBF_TREE_NODE_GROUP);
2265 update_operation_begin (plugin);
2266 group_id = anjuta_pm_project_new_group (plugin,
2267 get_plugin_parent_window (plugin),
2268 iter,
2269 group_name_to_add);
2270 update_operation_end (plugin, TRUE);
2271 group = get_element_file_from_node (plugin, group_id, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI);
2273 return group;
2276 static gboolean
2277 iproject_manager_is_open (IAnjutaProjectManager *project_manager, GError **err)
2279 ProjectManagerPlugin *plugin;
2281 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2283 return anjuta_pm_project_is_open (plugin->project);
2286 static GList*
2287 iproject_manager_get_packages (IAnjutaProjectManager *project_manager, GError **err)
2289 ProjectManagerPlugin *plugin;
2291 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2293 return anjuta_pm_project_get_packages (plugin->project);
2296 static IAnjutaProject*
2297 iproject_manager_get_current_project (IAnjutaProjectManager *project_manager, GError **err)
2299 ProjectManagerPlugin *plugin;
2301 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (G_OBJECT (project_manager));
2303 return anjuta_pm_project_get_project (plugin->project);
2306 static void
2307 iproject_manager_iface_init(IAnjutaProjectManagerIface *iface)
2309 iface->get_elements = iproject_manager_get_elements;
2310 iface->get_target_type = iproject_manager_get_target_type;
2311 iface->get_targets = iproject_manager_get_targets;
2312 iface->get_parent = iproject_manager_get_parent;
2313 iface->get_children = iproject_manager_get_children;
2314 iface->get_selected = iproject_manager_get_selected;
2315 iface->get_capabilities = iproject_manager_get_capabilities;
2316 iface->add_source = iproject_manager_add_source;
2317 iface->add_source_quiet = iproject_manager_add_source_quiet;
2318 iface->add_sources = iproject_manager_add_source_multi;
2319 iface->add_target = iproject_manager_add_target;
2320 iface->add_group = iproject_manager_add_group;
2321 iface->is_open = iproject_manager_is_open;
2322 iface->get_packages = iproject_manager_get_packages;
2323 iface->get_current_project = iproject_manager_get_current_project;
2326 static void
2327 ifile_open (IAnjutaFile *ifile, GFile* file, GError **e)
2329 AnjutaProfile *profile;
2330 AnjutaProfileManager *profile_manager;
2331 AnjutaPluginManager *plugin_manager;
2332 AnjutaStatus *status;
2333 gchar *session_profile_path, *profile_name;
2334 GFile *session_profile;
2335 GFile *default_profile;
2336 GFile *project_root;
2337 GFile *tmp;
2338 ProjectManagerPlugin *plugin;
2339 GError *error = NULL;
2341 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (ifile);
2343 /* If there is already a project loaded, load in separate anjuta window */
2344 if (plugin->project_root_uri)
2346 gchar *uri = g_file_get_uri (file);
2347 gchar *quoted_uri = g_shell_quote (uri);
2348 gchar *cmd = g_strconcat ("anjuta --no-splash --no-client ", quoted_uri, NULL);
2349 g_free (quoted_uri);
2350 anjuta_util_execute_shell (NULL, cmd);
2351 g_free (cmd);
2352 g_free (uri);
2354 return;
2357 plugin_manager =
2358 anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (ifile)->shell, NULL);
2359 profile_manager =
2360 anjuta_shell_get_profile_manager (ANJUTA_PLUGIN (ifile)->shell, NULL);
2361 status = anjuta_shell_get_status (ANJUTA_PLUGIN (ifile)->shell, NULL);
2363 anjuta_status_progress_add_ticks (status, 2);
2364 /* Prepare profile */
2365 profile = anjuta_profile_new (PROJECT_PROFILE_NAME, plugin_manager);
2367 /* System default profile */
2368 default_profile = g_file_new_for_uri (DEFAULT_PROFILE);
2369 anjuta_profile_add_plugins_from_xml (profile, default_profile,
2370 TRUE, &error);
2371 profile_name = g_file_get_basename (default_profile);
2372 g_object_unref (default_profile);
2373 if (error)
2375 g_propagate_error (e, error);
2376 g_free (profile_name);
2377 g_object_unref (profile);
2379 return;
2382 /* Project default profile */
2383 anjuta_profile_add_plugins_from_xml (profile, file, TRUE, &error);
2384 if (error)
2386 g_propagate_error (e, error);
2388 g_free (profile_name);
2389 g_object_unref (profile);
2391 return;
2394 /* Project session profile */
2395 project_root = g_file_get_parent (file);
2396 tmp = g_file_get_child (project_root, ".anjuta");
2397 session_profile = g_file_get_child (tmp, profile_name);
2398 g_object_unref (tmp);
2399 g_free (profile_name);
2401 session_profile_path = g_file_get_path (session_profile);
2402 DEBUG_PRINT ("Loading project session profile: %s", session_profile_path);
2403 if (g_file_query_exists (session_profile, NULL))
2405 anjuta_profile_add_plugins_from_xml (profile, session_profile,
2406 FALSE, &error);
2407 if (error)
2409 g_propagate_error (e, error);
2411 g_free (session_profile_path);
2412 g_object_unref (project_root);
2413 g_object_unref (profile);
2414 g_object_unref (session_profile);
2416 return;
2419 anjuta_profile_set_sync_file (profile, session_profile);
2420 g_free (session_profile_path);
2422 /* Set project uri */
2423 g_free (plugin->project_root_uri);
2424 if (plugin->project_file) g_object_unref (plugin->project_file);
2426 plugin->project_file = g_object_ref (file);
2427 plugin->project_root_uri = g_file_get_uri (project_root);
2428 g_object_unref (project_root);
2430 /* Load profile */
2431 anjuta_profile_manager_push (profile_manager, profile, &error);
2432 if (error)
2434 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (ifile)->shell),
2435 "%s", error->message);
2436 g_error_free (error);
2437 error = NULL;
2440 anjuta_status_progress_tick (status, NULL,
2441 _("Initializing Project…"));
2442 update_ui (plugin);
2444 anjuta_status_progress_tick (status, NULL, _("Project Loaded"));
2447 static GFile*
2448 ifile_get_file (IAnjutaFile *ifile, GError **e)
2450 ProjectManagerPlugin *plugin;
2452 plugin = ANJUTA_PLUGIN_PROJECT_MANAGER (ifile);
2453 if (plugin->project_root_uri)
2454 return g_file_new_for_uri (plugin->project_root_uri);
2455 else
2456 return NULL;
2459 static void
2460 ifile_iface_init(IAnjutaFileIface *iface)
2462 iface->open = ifile_open;
2463 iface->get_file = ifile_get_file;
2466 ANJUTA_PLUGIN_BEGIN (ProjectManagerPlugin, project_manager_plugin);
2467 ANJUTA_PLUGIN_ADD_INTERFACE (iproject_manager, IANJUTA_TYPE_PROJECT_MANAGER);
2468 ANJUTA_PLUGIN_ADD_INTERFACE (ifile, IANJUTA_TYPE_FILE);
2469 anjuta_pm_chooser_button_register (module);
2470 ANJUTA_PLUGIN_END;
2472 ANJUTA_SIMPLE_PLUGIN (ProjectManagerPlugin, project_manager_plugin);