Implement viewing files at any revision.
[anjuta-git-plugin.git] / src / anjuta.c
blob650ee4bb803f9166459c5946a7dc984b510cd8ca
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 (anjuta_util_get_user_cache_file_path ("session/", NULL))
37 #define DEFAULT_PROFILE "file://"PACKAGE_DATA_DIR"/profiles/default.profile"
38 #define USER_PROFILE_NAME "user"
40 static gchar *system_restore_session = NULL;
42 static gboolean
43 on_anjuta_delete_event (AnjutaApp *app, GdkEvent *event, gpointer data)
45 AnjutaPluginManager *plugin_manager;
46 AnjutaProfileManager *profile_manager;
47 AnjutaProfile *current_profile;
48 AnjutaSavePrompt *save_prompt;
49 gchar *remembered_plugins;
51 DEBUG_PRINT ("AnjutaApp delete event");
53 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app), NULL);
54 profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (app), NULL);
56 /* Save remembered plugins */
57 remembered_plugins =
58 anjuta_plugin_manager_get_remembered_plugins (plugin_manager);
59 anjuta_preferences_set (app->preferences,
60 ANJUTA_REMEMBERED_PLUGINS,
61 remembered_plugins);
62 g_free (remembered_plugins);
64 /* Check for unsaved data */
65 save_prompt = anjuta_save_prompt_new (GTK_WINDOW (app));
66 anjuta_shell_save_prompt (ANJUTA_SHELL (app), save_prompt, NULL);
68 if (anjuta_save_prompt_get_items_count (save_prompt) > 0)
70 switch (gtk_dialog_run (GTK_DIALOG (save_prompt)))
72 case ANJUTA_SAVE_PROMPT_RESPONSE_CANCEL:
73 gtk_widget_destroy (GTK_WIDGET (save_prompt));
74 /* Do not exit now */
75 return TRUE;
76 case ANJUTA_SAVE_PROMPT_RESPONSE_DISCARD:
77 case ANJUTA_SAVE_PROMPT_RESPONSE_SAVE_CLOSE:
78 /* exit now */
79 break;
83 /* If current active profile is "user", save current session as
84 * default session
86 current_profile = anjuta_profile_manager_get_current (profile_manager);
87 if (strcmp (anjuta_profile_get_name (current_profile), "user") == 0)
89 gchar *session_dir;
90 session_dir = USER_SESSION_PATH_NEW;
91 anjuta_shell_session_save (ANJUTA_SHELL (app), session_dir, NULL);
92 g_free (session_dir);
95 anjuta_shell_notify_exit (ANJUTA_SHELL (app), NULL);
97 gtk_widget_destroy (GTK_WIDGET (save_prompt));
99 /* Shutdown */
100 if (g_object_get_data (G_OBJECT (app), "__proper_shutdown"))
102 gtk_widget_hide (GTK_WIDGET (app));
103 anjuta_plugin_manager_unload_all_plugins
104 (anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app), NULL));
106 return FALSE;
109 static void
110 on_anjuta_destroy (GtkWidget * w, gpointer data)
112 DEBUG_PRINT ("AnjutaApp destroy event");
114 gtk_widget_hide (w);
115 gtk_main_quit ();
118 /* Saves the current anjuta session */
119 static gint
120 on_anjuta_session_save_yourself (GnomeClient * client, gint phase,
121 GnomeSaveStyle s_style, gint shutdown,
122 GnomeInteractStyle i_style, gint fast,
123 gpointer app)
125 gchar *argv[] = { "rm", "-rf", NULL};
126 const gchar *prefix;
128 DEBUG_PRINT ("Going to save session...");
130 prefix = gnome_client_get_config_prefix (client);
131 argv[2] = gnome_config_get_real_path (prefix);
132 gnome_client_set_discard_command (client, 3, argv);
134 argv[0] = "anjuta";
135 argv[1] = "--no-client";
136 gnome_client_set_restart_command (client, 2, argv);
137 gnome_client_set_restart_style (client, GNOME_RESTART_IF_RUNNING);
140 * We want to be somewhere at last to start, otherwise bonobo-activation
141 * and gnome-vfs gets screwed up at start up
143 gnome_client_set_priority (client, 80);
145 /* Save current session */
146 anjuta_shell_session_save (ANJUTA_SHELL (app), argv[2], NULL);
147 g_free (argv[2]);
149 return TRUE;
152 static gint
153 on_anjuta_session_die (GnomeClient * client, gpointer data)
155 gtk_main_quit();
156 return FALSE;
159 static void
160 on_profile_scoped (AnjutaProfileManager *profile_manager,
161 AnjutaProfile *profile, AnjutaApp *app)
163 gchar *session_dir;
164 static gboolean first_time = TRUE;
166 DEBUG_PRINT ("Profile scoped: %s", anjuta_profile_get_name (profile));
167 if (strcmp (anjuta_profile_get_name (profile), USER_PROFILE_NAME) != 0)
168 return;
170 DEBUG_PRINT ("User profile loaded; Restoring user session");
172 /* If profile scoped to "user", restore user session */
173 if (system_restore_session)
175 session_dir = system_restore_session;
176 system_restore_session = NULL;
178 else
180 session_dir = USER_SESSION_PATH_NEW;
183 if (first_time)
185 first_time = FALSE;
187 else
189 /* Clear the files list since we don't want to load them later */
190 AnjutaSession *session;
191 session = anjuta_session_new (session_dir);
192 anjuta_session_set_string_list (session, "File Loader",
193 "Files", NULL);
194 anjuta_session_sync (session);
195 g_object_unref (session);
198 /* Restore session */
199 anjuta_shell_session_load (ANJUTA_SHELL (app), session_dir, NULL);
200 g_free (session_dir);
203 static void
204 on_profile_descoped (AnjutaProfileManager *profile_manager,
205 AnjutaProfile *profile, AnjutaApp *app)
207 gchar *session_dir;
209 DEBUG_PRINT ("Profile descoped: %s", anjuta_profile_get_name (profile));
210 if (strcmp (anjuta_profile_get_name (profile), USER_PROFILE_NAME) != 0)
211 return;
213 DEBUG_PRINT ("User profile descoped; Saving user session");
215 /* If profile descoped from is "user", save user session */
216 session_dir = USER_SESSION_PATH_NEW;
218 /* Save current session */
219 anjuta_shell_session_save (ANJUTA_SHELL (app), session_dir, NULL);
220 g_free (session_dir);
223 /* This extracts the project URI saved in the session so that it could be
224 * loaded sequencially. Returned string must be freed.
226 static gchar*
227 extract_project_from_session (const gchar* session_dir)
229 AnjutaSession *session;
230 GList *node, *files, *new_files = NULL;
231 gchar *project_uri = NULL;
233 session = anjuta_session_new (session_dir);
235 files = anjuta_session_get_string_list (session, "File Loader", "Files");
236 if (!files)
237 return NULL;
239 /* Open project files first and then regular files */
240 node = files;
241 while (node)
243 gchar *uri = node->data;
244 if (uri)
246 gchar *mime_type;
247 mime_type = anjuta_util_get_uri_mime_type (uri);
248 if (mime_type && strcmp (mime_type, "application/x-anjuta") == 0)
250 g_free (project_uri);
251 project_uri = uri;
253 else
255 new_files = g_list_prepend (new_files, uri);
257 g_free (mime_type);
259 node = g_list_next (node);
261 /* anjuta_session_set_string_list (session, "File Loader", "Files", new_files);
262 anjuta_session_sync (session); */
263 g_object_unref (session);
265 if (new_files)
267 g_list_foreach (new_files, (GFunc)g_free, NULL);
268 g_list_free (new_files);
270 if (files)
271 g_list_free (files);
272 return project_uri;
275 /* FIXME: Clean this mess */
276 AnjutaApp*
277 anjuta_new (gchar *prog_name, GList *prog_args, gboolean no_splash,
278 gboolean no_session, gboolean no_files,
279 const gchar *im_file,
280 gboolean proper_shutdown, const gchar *geometry)
282 AnjutaPluginManager *plugin_manager;
283 AnjutaProfileManager *profile_manager;
284 AnjutaApp *app;
285 AnjutaStatus *status;
286 GnomeClient *client;
287 GnomeClientFlags flags;
288 AnjutaProfile *profile;
289 gchar *session_profile;
290 gchar *remembered_plugins;
291 gchar *project_file = NULL;
292 gchar *profile_name = NULL;
293 GError *error = NULL;
295 /* Initialize application */
296 app = ANJUTA_APP (anjuta_app_new ());
297 status = anjuta_shell_get_status (ANJUTA_SHELL (app), NULL);
298 anjuta_status_progress_add_ticks (status, 1);
300 if (im_file)
301 anjuta_status_set_splash (status, im_file, 100);
302 if (no_splash)
303 anjuta_status_disable_splash (status, no_splash);
305 if (proper_shutdown)
307 g_object_set_data (G_OBJECT (app), "__proper_shutdown", "1");
309 g_signal_connect (G_OBJECT (app), "delete_event",
310 G_CALLBACK (on_anjuta_delete_event), NULL);
311 g_signal_connect (G_OBJECT (app), "destroy",
312 G_CALLBACK (on_anjuta_destroy), NULL);
313 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app),
314 NULL);
315 profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (app),
316 NULL);
318 /* Restore remembered plugins */
319 remembered_plugins =
320 anjuta_preferences_get (app->preferences, ANJUTA_REMEMBERED_PLUGINS);
321 if (remembered_plugins)
322 anjuta_plugin_manager_set_remembered_plugins (plugin_manager,
323 remembered_plugins);
324 g_free (remembered_plugins);
326 /* Prepare profile */
327 profile = anjuta_profile_new (USER_PROFILE_NAME, plugin_manager);
328 anjuta_profile_add_plugins_from_xml (profile, DEFAULT_PROFILE,
329 TRUE, &error);
330 if (error)
332 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
333 g_error_free (error);
334 error = NULL;
337 /* Load user session profile */
338 profile_name = g_path_get_basename (DEFAULT_PROFILE);
339 session_profile = anjuta_util_get_user_cache_file_path (profile_name, NULL);
340 if (g_file_test (session_profile, G_FILE_TEST_EXISTS))
342 anjuta_profile_add_plugins_from_xml (profile, session_profile,
343 FALSE, &error);
344 if (error)
346 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
347 g_error_free (error);
348 error = NULL;
351 anjuta_profile_set_sync_uri (profile, session_profile);
352 g_free (session_profile);
353 g_free (profile_name);
355 /* Load profile */
356 anjuta_profile_manager_freeze (profile_manager);
357 anjuta_profile_manager_push (profile_manager, profile, &error);
358 if (error)
360 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
361 g_error_free (error);
362 error = NULL;
365 /* Session management */
366 client = gnome_master_client();
367 gtk_signal_connect(GTK_OBJECT(client), "save_yourself",
368 GTK_SIGNAL_FUNC(on_anjuta_session_save_yourself),
369 app);
370 gtk_signal_connect(GTK_OBJECT(client), "die",
371 GTK_SIGNAL_FUNC(on_anjuta_session_die), app);
373 flags = gnome_client_get_flags(client);
375 if (flags & GNOME_CLIENT_RESTORED)
377 /* Load the last session */
378 const gchar *prefix;
379 prefix = gnome_client_get_config_prefix (client);
380 system_restore_session = gnome_config_get_real_path (prefix);
381 project_file = extract_project_from_session (system_restore_session);
383 else if (prog_args || geometry)
385 gchar *session_dir;
386 AnjutaSession *session;
387 GList *node, *files_load = NULL;
389 /* Reset default session */
390 session_dir = USER_SESSION_PATH_NEW;
392 project_file = extract_project_from_session (session_dir);
394 session = anjuta_session_new (session_dir);
395 anjuta_session_clear (session);
396 if (geometry)
397 anjuta_session_set_string (session, "Anjuta", "Geometry",
398 geometry);
400 /* Identify non-project files and set them for loading in session */
401 node = prog_args;
402 while (node)
404 const gchar *ext;
405 const gchar *filename = node->data;
407 ext = strrchr (filename, '.');
409 if (!ext ||
410 (strcmp (ext, ".anjuta") != 0 &&
411 strcmp (ext, ".prj") != 0))
413 files_load = g_list_prepend (files_load, node->data);
415 else
417 /* Pick up the first project file for loading later */
418 g_free (project_file);
419 project_file = g_strdup (filename);
421 node = g_list_next (node);
423 if (files_load)
425 anjuta_session_set_string_list (session, "File Loader", "Files",
426 files_load);
427 g_list_free (files_load);
429 anjuta_session_sync (session);
430 g_object_unref (session);
431 g_free (session_dir);
433 else
435 gchar *session_dir;
436 AnjutaSession *session;
438 /* Load user session */
439 session_dir = USER_SESSION_PATH_NEW;
441 /* If preferences is set to not load last session, clear it */
442 if (no_session ||
443 anjuta_preferences_get_int (app->preferences,
444 ANJUTA_SESSION_SKIP_LAST))
446 /* Reset default session */
447 session = anjuta_session_new (session_dir);
448 anjuta_session_clear (session);
449 g_object_unref (session);
451 /* If preferences is set to not load last project, clear it */
452 else if (no_files ||
453 anjuta_preferences_get_int (app->preferences,
454 ANJUTA_SESSION_SKIP_LAST_FILES))
456 session = anjuta_session_new (session_dir);
457 anjuta_session_set_string_list (session, "File Loader",
458 "Files", NULL);
459 anjuta_session_sync (session);
460 g_object_unref (session);
462 /* Otherwise, load session normally */
463 else
465 project_file = extract_project_from_session (session_dir);
467 g_free (session_dir);
470 /* Prepare for session save and load on profile change */
471 g_signal_connect (profile_manager, "profile-scoped",
472 G_CALLBACK (on_profile_scoped), app);
473 /* Load project file */
474 if (project_file)
476 GFile* file = g_file_new_for_uri (project_file);
477 IAnjutaFileLoader *loader;
478 loader = anjuta_shell_get_interface (ANJUTA_SHELL (app),
479 IAnjutaFileLoader, NULL);
480 ianjuta_file_loader_load (loader, file, FALSE, NULL);
481 g_free (project_file);
482 g_object_unref (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;