2007-11-04 Johannes Schmid <jhs@gnome.org>
[anjuta-git-plugin.git] / src / anjuta.c
blob4eb58f3b80f09f6d2c4c79e471816d7fa3c057cd
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta.c
4 * Copyright (C) 2000 Naba Kumar <naba@gnome.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <string.h>
22 #include <libanjuta/anjuta-shell.h>
23 #include <libanjuta/anjuta-debug.h>
24 #include <libanjuta/anjuta-utils.h>
25 #include <libanjuta/anjuta-save-prompt.h>
26 #include <libanjuta/anjuta-plugin-manager.h>
27 #include <libanjuta/interfaces/ianjuta-file-loader.h>
28 #include <libanjuta/interfaces/ianjuta-file.h>
30 #include "anjuta.h"
32 #define ANJUTA_REMEMBERED_PLUGINS "anjuta.remembered.plugins"
33 #define ANJUTA_SESSION_SKIP_LAST "anjuta.session.skip.last"
34 #define ANJUTA_SESSION_SKIP_LAST_FILES "anjuta.session.skip.last.files"
35 #define USER_SESSION_PATH_NEW (g_build_filename (g_get_home_dir (), ".anjuta", \
36 "session", NULL))
38 #define DEFAULT_PROFILE "file://"PACKAGE_DATA_DIR"/profiles/default.profile"
39 #define USER_PROFILE_NAME "user"
41 static gchar *system_restore_session = NULL;
43 static gboolean
44 on_anjuta_delete_event (AnjutaApp *app, GdkEvent *event, gpointer data)
46 AnjutaPluginManager *plugin_manager;
47 AnjutaProfileManager *profile_manager;
48 AnjutaProfile *current_profile;
49 AnjutaSavePrompt *save_prompt;
50 gchar *remembered_plugins;
52 DEBUG_PRINT ("AnjutaApp delete event");
54 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app), NULL);
55 profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (app), NULL);
57 /* Save remembered plugins */
58 remembered_plugins =
59 anjuta_plugin_manager_get_remembered_plugins (plugin_manager);
60 anjuta_preferences_set (app->preferences,
61 ANJUTA_REMEMBERED_PLUGINS,
62 remembered_plugins);
63 g_free (remembered_plugins);
65 /* Check for unsaved data */
66 save_prompt = anjuta_save_prompt_new (GTK_WINDOW (app));
67 anjuta_shell_save_prompt (ANJUTA_SHELL (app), save_prompt, NULL);
69 if (anjuta_save_prompt_get_items_count (save_prompt) > 0)
71 switch (gtk_dialog_run (GTK_DIALOG (save_prompt)))
73 case ANJUTA_SAVE_PROMPT_RESPONSE_CANCEL:
74 gtk_widget_destroy (GTK_WIDGET (save_prompt));
75 /* Do not exit now */
76 return TRUE;
77 case ANJUTA_SAVE_PROMPT_RESPONSE_DISCARD:
78 case ANJUTA_SAVE_PROMPT_RESPONSE_SAVE_CLOSE:
79 /* exit now */
80 break;
84 /* If current active profile is "user", save current session as
85 * default session
87 current_profile = anjuta_profile_manager_get_current (profile_manager);
88 if (strcmp (anjuta_profile_get_name (current_profile), "user") == 0)
90 gchar *session_dir;
91 session_dir = USER_SESSION_PATH_NEW;
92 anjuta_shell_session_save (ANJUTA_SHELL (app), session_dir, NULL);
93 g_free (session_dir);
96 anjuta_shell_notify_exit (ANJUTA_SHELL (app), NULL);
98 gtk_widget_destroy (GTK_WIDGET (save_prompt));
100 /* Shutdown */
101 if (g_object_get_data (G_OBJECT (app), "__proper_shutdown"))
103 gtk_widget_hide (GTK_WIDGET (app));
104 anjuta_plugin_manager_unload_all_plugins
105 (anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app), NULL));
107 return FALSE;
110 static void
111 on_anjuta_destroy (GtkWidget * w, gpointer data)
113 DEBUG_PRINT ("AnjutaApp destroy event");
115 gtk_widget_hide (w);
116 gtk_main_quit ();
119 /* Saves the current anjuta session */
120 static gint
121 on_anjuta_session_save_yourself (GnomeClient * client, gint phase,
122 GnomeSaveStyle s_style, gint shutdown,
123 GnomeInteractStyle i_style, gint fast,
124 gpointer app)
126 gchar *argv[] = { "rm", "-rf", NULL};
127 const gchar *prefix;
129 DEBUG_PRINT ("Going to save session...");
131 prefix = gnome_client_get_config_prefix (client);
132 argv[2] = gnome_config_get_real_path (prefix);
133 gnome_client_set_discard_command (client, 3, argv);
135 argv[0] = "anjuta";
136 argv[1] = "--no-client";
137 gnome_client_set_restart_command (client, 2, argv);
138 gnome_client_set_restart_style (client, GNOME_RESTART_IF_RUNNING);
141 * We want to be somewhere at last to start, otherwise bonobo-activation
142 * and gnome-vfs gets screwed up at start up
144 gnome_client_set_priority (client, 80);
146 /* Save current session */
147 anjuta_shell_session_save (ANJUTA_SHELL (app), argv[2], NULL);
148 g_free (argv[2]);
150 return TRUE;
153 static gint
154 on_anjuta_session_die (GnomeClient * client, gpointer data)
156 gtk_main_quit();
157 return FALSE;
160 static void
161 on_profile_scoped (AnjutaProfileManager *profile_manager,
162 AnjutaProfile *profile, AnjutaApp *app)
164 gchar *session_dir;
165 static gboolean first_time = TRUE;
167 DEBUG_PRINT ("Profile scoped: %s", anjuta_profile_get_name (profile));
168 if (strcmp (anjuta_profile_get_name (profile), USER_PROFILE_NAME) != 0)
169 return;
171 DEBUG_PRINT ("User profile loaded; Restoring user session");
173 /* If profile scoped to "user", restore user session */
174 if (system_restore_session)
176 session_dir = system_restore_session;
177 system_restore_session = NULL;
179 else
181 session_dir = USER_SESSION_PATH_NEW;
184 if (first_time)
186 first_time = FALSE;
188 else
190 /* Clear the files list since we don't want to load them later */
191 AnjutaSession *session;
192 session = anjuta_session_new (session_dir);
193 anjuta_session_set_string_list (session, "File Loader",
194 "Files", NULL);
195 anjuta_session_sync (session);
196 g_object_unref (session);
199 /* Restore session */
200 anjuta_shell_session_load (ANJUTA_SHELL (app), session_dir, NULL);
201 g_free (session_dir);
204 static void
205 on_profile_descoped (AnjutaProfileManager *profile_manager,
206 AnjutaProfile *profile, AnjutaApp *app)
208 gchar *session_dir;
210 DEBUG_PRINT ("Profile descoped: %s", anjuta_profile_get_name (profile));
211 if (strcmp (anjuta_profile_get_name (profile), USER_PROFILE_NAME) != 0)
212 return;
214 DEBUG_PRINT ("User profile descoped; Saving user session");
216 /* If profile descoped from is "user", save user session */
217 session_dir = USER_SESSION_PATH_NEW;
219 /* Save current session */
220 anjuta_shell_session_save (ANJUTA_SHELL (app), session_dir, NULL);
221 g_free (session_dir);
224 /* This extracts the project URI saved in the session so that it could be
225 * loaded sequencially. Returned string must be freed.
227 static gchar*
228 extract_project_from_session (const gchar* session_dir)
230 AnjutaSession *session;
231 GList *node, *files, *new_files = NULL;
232 gchar *project_uri = NULL;
234 session = anjuta_session_new (session_dir);
236 files = anjuta_session_get_string_list (session, "File Loader", "Files");
237 if (!files)
238 return NULL;
240 /* Open project files first and then regular files */
241 node = files;
242 while (node)
244 gchar *uri = node->data;
245 if (uri)
247 gchar *mime_type;
248 mime_type = anjuta_util_get_uri_mime_type (uri);
249 if (mime_type && strcmp (mime_type, "application/x-anjuta") == 0)
251 g_free (project_uri);
252 project_uri = uri;
254 else
256 new_files = g_list_prepend (new_files, uri);
258 g_free (mime_type);
260 node = g_list_next (node);
262 /* anjuta_session_set_string_list (session, "File Loader", "Files", new_files);
263 anjuta_session_sync (session); */
264 g_object_unref (session);
266 if (new_files)
268 g_list_foreach (new_files, (GFunc)g_free, NULL);
269 g_list_free (new_files);
271 if (files)
272 g_list_free (files);
273 return project_uri;
276 /* FIXME: Clean this mess */
277 AnjutaApp*
278 anjuta_new (gchar *prog_name, GList *prog_args, gboolean no_splash,
279 gboolean no_session, gboolean no_files,
280 const gchar *im_file,
281 gboolean proper_shutdown, const gchar *geometry)
283 AnjutaPluginManager *plugin_manager;
284 AnjutaProfileManager *profile_manager;
285 AnjutaApp *app;
286 AnjutaStatus *status;
287 GnomeClient *client;
288 GnomeClientFlags flags;
289 AnjutaProfile *profile;
290 gchar *session_profile;
291 gchar *remembered_plugins;
292 gchar *project_file = NULL;
293 gchar *profile_name = NULL;
294 GError *error = NULL;
296 /* Initialize application */
297 app = ANJUTA_APP (anjuta_app_new ());
298 status = anjuta_shell_get_status (ANJUTA_SHELL (app), NULL);
299 anjuta_status_progress_add_ticks (status, 1);
301 if (im_file)
302 anjuta_status_set_splash (status, im_file, 100);
303 if (no_splash)
304 anjuta_status_disable_splash (status, no_splash);
306 if (proper_shutdown)
308 g_object_set_data (G_OBJECT (app), "__proper_shutdown", "1");
310 g_signal_connect (G_OBJECT (app), "delete_event",
311 G_CALLBACK (on_anjuta_delete_event), NULL);
312 g_signal_connect (G_OBJECT (app), "destroy",
313 G_CALLBACK (on_anjuta_destroy), NULL);
314 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app),
315 NULL);
316 profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (app),
317 NULL);
319 /* Restore remembered plugins */
320 remembered_plugins =
321 anjuta_preferences_get (app->preferences, ANJUTA_REMEMBERED_PLUGINS);
322 if (remembered_plugins)
323 anjuta_plugin_manager_set_remembered_plugins (plugin_manager,
324 remembered_plugins);
325 g_free (remembered_plugins);
327 /* Prepare profile */
328 profile = anjuta_profile_new (USER_PROFILE_NAME, plugin_manager);
329 anjuta_profile_add_plugins_from_xml (profile, DEFAULT_PROFILE,
330 TRUE, &error);
331 if (error)
333 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
334 g_error_free (error);
335 error = NULL;
338 /* Load user session profile */
339 profile_name = g_path_get_basename (DEFAULT_PROFILE);
340 session_profile = g_build_filename (g_get_home_dir(), ".anjuta",
341 profile_name, NULL);
342 if (g_file_test (session_profile, G_FILE_TEST_EXISTS))
344 anjuta_profile_add_plugins_from_xml (profile, session_profile,
345 FALSE, &error);
346 if (error)
348 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
349 g_error_free (error);
350 error = NULL;
353 anjuta_profile_set_sync_uri (profile, session_profile);
354 g_free (session_profile);
355 g_free (profile_name);
357 /* Load profile */
358 anjuta_profile_manager_freeze (profile_manager);
359 anjuta_profile_manager_push (profile_manager, profile, &error);
360 if (error)
362 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
363 g_error_free (error);
364 error = NULL;
367 /* Session management */
368 client = gnome_master_client();
369 gtk_signal_connect(GTK_OBJECT(client), "save_yourself",
370 GTK_SIGNAL_FUNC(on_anjuta_session_save_yourself),
371 app);
372 gtk_signal_connect(GTK_OBJECT(client), "die",
373 GTK_SIGNAL_FUNC(on_anjuta_session_die), app);
375 flags = gnome_client_get_flags(client);
377 if (flags & GNOME_CLIENT_RESTORED)
379 /* Load the last session */
380 const gchar *prefix;
381 prefix = gnome_client_get_config_prefix (client);
382 system_restore_session = gnome_config_get_real_path (prefix);
383 project_file = extract_project_from_session (system_restore_session);
385 else if (prog_args || geometry)
387 gchar *session_dir;
388 AnjutaSession *session;
389 GList *node, *files_load = NULL;
391 /* Reset default session */
392 session_dir = USER_SESSION_PATH_NEW;
394 project_file = extract_project_from_session (session_dir);
396 session = anjuta_session_new (session_dir);
397 anjuta_session_clear (session);
398 if (geometry)
399 anjuta_session_set_string (session, "Anjuta", "Geometry",
400 geometry);
402 /* Identify non-project files and set them for loading in session */
403 node = prog_args;
404 while (node)
406 const gchar *ext;
407 const gchar *filename = node->data;
409 ext = strrchr (filename, '.');
411 if (!ext ||
412 (strcmp (ext, ".anjuta") != 0 &&
413 strcmp (ext, ".prj") != 0))
415 files_load = g_list_prepend (files_load, node->data);
417 else
419 /* Pick up the first project file for loading later */
420 g_free (project_file);
421 project_file = g_strdup (filename);
423 node = g_list_next (node);
425 if (files_load)
427 anjuta_session_set_string_list (session, "File Loader", "Files",
428 files_load);
429 g_list_free (files_load);
431 anjuta_session_sync (session);
432 g_object_unref (session);
433 g_free (session_dir);
435 else
437 gchar *session_dir;
438 AnjutaSession *session;
440 /* Load user session */
441 session_dir = USER_SESSION_PATH_NEW;
443 /* If preferences is set to not load last session, clear it */
444 if (no_session ||
445 anjuta_preferences_get_int (app->preferences,
446 ANJUTA_SESSION_SKIP_LAST))
448 /* Reset default session */
449 session = anjuta_session_new (session_dir);
450 anjuta_session_clear (session);
451 g_object_unref (session);
453 /* If preferences is set to not load last project, clear it */
454 else if (no_files ||
455 anjuta_preferences_get_int (app->preferences,
456 ANJUTA_SESSION_SKIP_LAST_FILES))
458 session = anjuta_session_new (session_dir);
459 anjuta_session_set_string_list (session, "File Loader",
460 "Files", NULL);
461 anjuta_session_sync (session);
462 g_object_unref (session);
464 /* Otherwise, load session normally */
465 else
467 project_file = extract_project_from_session (session_dir);
469 g_free (session_dir);
472 /* Prepare for session save and load on profile change */
473 g_signal_connect (profile_manager, "profile-scoped",
474 G_CALLBACK (on_profile_scoped), app);
475 /* Load project file */
476 if (project_file)
478 IAnjutaFileLoader *loader;
479 loader = anjuta_shell_get_interface (ANJUTA_SHELL (app),
480 IAnjutaFileLoader, NULL);
481 ianjuta_file_loader_load (loader, project_file, FALSE, NULL);
482 g_free (project_file);
484 anjuta_profile_manager_thaw (profile_manager, &error);
486 if (error)
488 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
489 g_error_free (error);
490 error = NULL;
492 g_signal_connect (profile_manager, "profile-descoped",
493 G_CALLBACK (on_profile_descoped), app);
495 anjuta_status_progress_tick (status, NULL, _("Loaded Session..."));
496 anjuta_status_disable_splash (status, TRUE);
497 return app;