anjuta: Rename AnjutaApp as AnjutaWindow
[anjuta.git] / src / anjuta.c
blob130a6d8eb8f909a120a80d05e68e4ed1e12e836a
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>
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/resources.h>
28 #include <libanjuta/interfaces/ianjuta-file-loader.h>
29 #include <libanjuta/interfaces/ianjuta-file.h>
31 #include "anjuta.h"
33 #define ANJUTA_REMEMBERED_PLUGINS "remembered-plugins"
34 #define ANJUTA_SESSION_SKIP_LAST "session-skip-last"
35 #define ANJUTA_SESSION_SKIP_LAST_FILES "session-skip-last-files"
36 #define USER_SESSION_PATH_NEW (anjuta_util_get_user_cache_file_path ("session/", NULL))
38 #define DEFAULT_PROFILE "file://"PACKAGE_DATA_DIR"/profiles/default.profile"
39 #define USER_PROFILE_NAME "user"
41 #define ANJUTA_PIXMAP_SPLASH_SCREEN "anjuta_splash.png"
43 static gchar *system_restore_session = NULL;
45 static gboolean
46 on_anjuta_delete_event (AnjutaWindow *win, GdkEvent *event, gpointer data)
48 AnjutaPluginManager *plugin_manager;
49 AnjutaProfileManager *profile_manager;
50 AnjutaProfile *current_profile;
51 AnjutaSavePrompt *save_prompt;
52 gchar *remembered_plugins;
54 DEBUG_PRINT ("%s", "AnjutaWindow delete event");
56 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (win), NULL);
57 profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (win), NULL);
59 /* Save remembered plugins */
60 remembered_plugins =
61 anjuta_plugin_manager_get_remembered_plugins (plugin_manager);
62 g_settings_set_string (win->settings,
63 ANJUTA_REMEMBERED_PLUGINS,
64 remembered_plugins);
65 g_free (remembered_plugins);
67 /* Check for unsaved data */
68 save_prompt = anjuta_save_prompt_new (GTK_WINDOW (win));
69 anjuta_shell_save_prompt (ANJUTA_SHELL (win), save_prompt, NULL);
71 if (anjuta_save_prompt_get_items_count (save_prompt) > 0)
73 switch (gtk_dialog_run (GTK_DIALOG (save_prompt)))
75 case GTK_RESPONSE_DELETE_EVENT:
76 case ANJUTA_SAVE_PROMPT_RESPONSE_CANCEL:
77 gtk_widget_destroy (GTK_WIDGET (save_prompt));
78 /* Do not exit now */
79 return TRUE;
80 case ANJUTA_SAVE_PROMPT_RESPONSE_DISCARD:
81 case ANJUTA_SAVE_PROMPT_RESPONSE_SAVE_CLOSE:
82 /* exit now */
83 break;
86 /* Wait for files to be really saved (asyncronous operation) */
87 if (win->save_count > 0)
89 g_message ("Waiting for %d file(s) to be saved!", win->save_count);
90 while (win->save_count > 0)
92 g_main_context_iteration (NULL, TRUE);
96 /* If current active profile is "user", save current session as
97 * default session
99 current_profile = anjuta_profile_manager_get_current (profile_manager);
100 if (strcmp (anjuta_profile_get_name (current_profile), "user") == 0)
102 gchar *session_dir;
103 session_dir = USER_SESSION_PATH_NEW;
104 anjuta_shell_session_save (ANJUTA_SHELL (win), session_dir, NULL);
105 g_free (session_dir);
108 anjuta_shell_notify_exit (ANJUTA_SHELL (win), NULL);
110 gtk_widget_destroy (GTK_WIDGET (save_prompt));
112 /* Shutdown */
113 if (g_object_get_data (G_OBJECT (win), "__proper_shutdown"))
115 gtk_widget_hide (GTK_WIDGET (win));
116 anjuta_plugin_manager_unload_all_plugins
117 (anjuta_shell_get_plugin_manager (ANJUTA_SHELL (win), NULL));
119 return FALSE;
122 static void
123 on_anjuta_destroy (GtkWidget * w, gpointer data)
125 DEBUG_PRINT ("%s", "AnjutaWindow destroy event");
127 gtk_widget_hide (w);
130 static void
131 on_profile_scoped (AnjutaProfileManager *profile_manager,
132 AnjutaProfile *profile, AnjutaWindow *win)
134 gchar *session_dir;
135 static gboolean first_time = TRUE;
137 DEBUG_PRINT ("Profile scoped: %s", anjuta_profile_get_name (profile));
138 if (strcmp (anjuta_profile_get_name (profile), USER_PROFILE_NAME) != 0)
139 return;
141 DEBUG_PRINT ("%s", "User profile loaded; Restoring user session");
143 /* If profile scoped to "user", restore user session */
144 if (system_restore_session)
146 session_dir = system_restore_session;
147 system_restore_session = NULL;
149 else
151 session_dir = USER_SESSION_PATH_NEW;
154 if (first_time)
156 first_time = FALSE;
158 else
160 /* Clear the files list since we don't want to load them later */
161 AnjutaSession *session;
162 session = anjuta_session_new (session_dir);
163 anjuta_session_set_string_list (session, "File Loader",
164 "Files", NULL);
165 anjuta_session_sync (session);
166 g_object_unref (session);
169 /* Restore session */
170 anjuta_shell_session_load (ANJUTA_SHELL (win), session_dir, NULL);
171 g_free (session_dir);
174 static void
175 on_profile_descoped (AnjutaProfileManager *profile_manager,
176 AnjutaProfile *profile, AnjutaWindow *win)
178 gchar *session_dir;
180 DEBUG_PRINT ("Profile descoped: %s", anjuta_profile_get_name (profile));
181 if (strcmp (anjuta_profile_get_name (profile), USER_PROFILE_NAME) != 0)
182 return;
184 DEBUG_PRINT ("%s", "User profile descoped; Saving user session");
186 /* If profile descoped from is "user", save user session */
187 session_dir = USER_SESSION_PATH_NEW;
189 /* Save current session */
190 anjuta_shell_session_save (ANJUTA_SHELL (win), session_dir, NULL);
191 g_free (session_dir);
194 /* This extracts the project URI saved in the session so that it could be
195 * loaded sequencially. Returned string must be freed.
197 static GFile*
198 extract_project_from_session (const gchar* session_dir)
200 AnjutaSession *session;
201 GList *node, *files;
202 GFile *project = NULL;
204 session = anjuta_session_new (session_dir);
206 files = anjuta_session_get_string_list (session, "File Loader", "Files");
208 /* Find project file */
209 node = files;
210 for (node = files; node != NULL; node = g_list_next (node))
212 gchar *uri = node->data;
213 if (uri)
215 if (anjuta_util_is_project_file (uri))
217 if (project != NULL) g_object_unref (project);
218 project = anjuta_session_get_file_from_relative_uri (session, uri, NULL);
220 g_free (uri);
223 g_list_free (files);
224 g_object_unref (session);
226 return project;
229 AnjutaWindow*
230 create_window (GFile **files, int n_files, gboolean no_splash,
231 gboolean no_session, gboolean no_files,
232 gboolean proper_shutdown, const gchar *geometry)
234 AnjutaPluginManager *plugin_manager;
235 AnjutaProfileManager *profile_manager;
236 AnjutaWindow *win;
237 AnjutaStatus *status;
238 AnjutaProfile *profile;
239 GFile *session_profile;
240 gchar *remembered_plugins;
241 GFile *project = NULL;
242 GFile *template = NULL;
243 gchar *profile_name = NULL;
244 gchar *im_file = NULL;
245 GError *error = NULL;
247 /* Initialize application */
248 win = ANJUTA_WINDOW (anjuta_window_new ());
249 status = anjuta_shell_get_status (ANJUTA_SHELL (win), NULL);
250 anjuta_status_progress_add_ticks (status, 1);
252 im_file = anjuta_res_get_pixmap_file (ANJUTA_PIXMAP_SPLASH_SCREEN);
254 gtk_window_set_role (GTK_WINDOW (win), "anjuta-app");
255 gtk_window_set_auto_startup_notification(TRUE);
256 gtk_window_set_default_icon_name ("anjuta");
257 gtk_window_set_auto_startup_notification(FALSE);
259 if (im_file)
261 anjuta_status_set_splash (status, im_file, 100);
262 g_free (im_file);
264 if (no_splash)
265 anjuta_status_disable_splash (status, no_splash);
267 if (proper_shutdown)
269 g_object_set_data (G_OBJECT (win), "__proper_shutdown", "1");
271 g_signal_connect (G_OBJECT (win), "delete_event",
272 G_CALLBACK (on_anjuta_delete_event), NULL);
273 g_signal_connect (G_OBJECT (win), "destroy",
274 G_CALLBACK (on_anjuta_destroy), NULL);
276 /* Setup application framework */
277 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (win),
278 NULL);
279 profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (win),
280 NULL);
282 /* Restore remembered plugins */
283 remembered_plugins =
284 g_settings_get_string (win->settings, ANJUTA_REMEMBERED_PLUGINS);
285 if (remembered_plugins)
286 anjuta_plugin_manager_set_remembered_plugins (plugin_manager,
287 remembered_plugins);
288 g_free (remembered_plugins);
290 /* Prepare profile */
291 profile = anjuta_profile_new (USER_PROFILE_NAME, plugin_manager);
292 session_profile = g_file_new_for_uri (DEFAULT_PROFILE);
293 anjuta_profile_add_plugins_from_xml (profile, session_profile,
294 TRUE, &error);
295 if (error)
297 anjuta_util_dialog_error (GTK_WINDOW (win), "%s", error->message);
298 g_error_free (error);
299 error = NULL;
301 g_object_unref (session_profile);
303 /* Load user session profile */
304 profile_name = g_path_get_basename (DEFAULT_PROFILE);
305 session_profile = anjuta_util_get_user_cache_file (profile_name, NULL);
306 if (g_file_query_exists (session_profile, NULL))
308 anjuta_profile_add_plugins_from_xml (profile, session_profile,
309 FALSE, &error);
310 if (error)
312 anjuta_util_dialog_error (GTK_WINDOW (win), "%s", error->message);
313 g_error_free (error);
314 error = NULL;
317 anjuta_profile_set_sync_file (profile, session_profile);
318 g_object_unref (session_profile);
319 g_free (profile_name);
321 /* Load profile */
322 anjuta_profile_manager_freeze (profile_manager);
323 anjuta_profile_manager_push (profile_manager, profile, &error);
324 if (error)
326 anjuta_util_dialog_error (GTK_WINDOW (win), "%s", error->message);
327 g_error_free (error);
328 error = NULL;
331 if (files || geometry)
333 gchar *session_dir;
334 AnjutaSession *session;
335 gint i;
336 GList *files_load = NULL;
338 /* Reset default session */
339 session_dir = USER_SESSION_PATH_NEW;
341 project = extract_project_from_session (session_dir);
342 template = NULL;
344 session = anjuta_session_new (session_dir);
345 anjuta_session_clear (session);
346 if (geometry)
347 anjuta_session_set_string (session, "Anjuta", "Geometry",
348 geometry);
350 /* Identify non-project files and set them for loading in session */
351 for (i = 0; i < n_files; i++)
353 gchar* file = g_file_get_path (files[i]);
354 if (!file)
355 continue;
356 if (anjuta_util_is_project_file (file))
358 /* Pick up the first project file for loading later */
359 project = files[i];
360 g_object_ref (project);
362 else if (anjuta_util_is_template_file (file))
364 template = files[i];
365 g_object_ref (template);
367 else
369 files_load = g_list_prepend (files_load, g_file_get_uri (files[i]));
372 if (files_load)
374 anjuta_session_set_string_list (session, "File Loader", "Files",
375 files_load);
376 g_list_foreach (files_load, (GFunc)g_free, NULL);
377 g_list_free (files_load);
379 anjuta_session_sync (session);
380 g_object_unref (session);
381 g_free (session_dir);
383 else
385 gchar *session_dir;
386 AnjutaSession *session;
388 /* Load user session */
389 session_dir = USER_SESSION_PATH_NEW;
391 /* If preferences is set to not load last session, clear it */
392 if (no_session ||
393 g_settings_get_boolean (win->settings,
394 ANJUTA_SESSION_SKIP_LAST))
396 /* Reset default session */
397 session = anjuta_session_new (session_dir);
398 anjuta_session_clear (session);
399 g_object_unref (session);
401 /* If preferences is set to not load last project, clear it */
402 else if (no_files ||
403 g_settings_get_boolean (win->settings,
404 ANJUTA_SESSION_SKIP_LAST_FILES))
406 session = anjuta_session_new (session_dir);
407 anjuta_session_set_string_list (session, "File Loader",
408 "Files", NULL);
409 anjuta_session_sync (session);
410 g_object_unref (session);
412 /* Otherwise, load session normally */
413 else
415 project = extract_project_from_session (session_dir);
417 g_free (session_dir);
420 /* Prepare for session save and load on profile change */
421 g_signal_connect (profile_manager, "profile-scoped",
422 G_CALLBACK (on_profile_scoped), win);
423 /* Load project file */
424 if ((project != NULL) && (template == NULL))
426 IAnjutaFileLoader *loader;
427 loader = anjuta_shell_get_interface (ANJUTA_SHELL (win),
428 IAnjutaFileLoader, NULL);
429 ianjuta_file_loader_load (loader, project, FALSE, NULL);
430 g_object_unref (project);
432 anjuta_profile_manager_thaw (profile_manager, &error);
434 if (error)
436 anjuta_util_dialog_error (GTK_WINDOW (win), "%s", error->message);
437 g_error_free (error);
438 error = NULL;
440 g_signal_connect (profile_manager, "profile-descoped",
441 G_CALLBACK (on_profile_descoped), win);
443 anjuta_status_progress_tick (status, NULL, _("Loaded Session…"));
444 anjuta_status_disable_splash (status, TRUE);
446 /* Load template file */
447 if (template != NULL)
449 IAnjutaFileLoader *loader;
450 loader = anjuta_shell_get_interface (ANJUTA_SHELL (win),
451 IAnjutaFileLoader, NULL);
452 ianjuta_file_loader_load (loader, template, FALSE, NULL);
453 g_object_unref (template);
456 return win;
459 /* Application */
461 G_DEFINE_TYPE (Anjuta, anjuta, GTK_TYPE_APPLICATION)
463 static void
464 anjuta_finalize (GObject *object)
466 G_OBJECT_CLASS (anjuta_parent_class)->finalize (object);
469 static void
470 anjuta_open (GApplication *application,
471 GFile **files,
472 gint n_files,
473 const gchar* hint)
475 int i;
476 GList* windows = gtk_application_get_windows (GTK_APPLICATION (application));
477 AnjutaWindow *win = ANJUTA_WINDOW (windows->data);
478 IAnjutaFileLoader* loader =
479 anjuta_shell_get_interface(ANJUTA_SHELL(win), IAnjutaFileLoader, NULL);
481 if (!loader)
482 return;
484 /* Identify non-project files and set them for loading in session */
485 for (i = 0; i < n_files; i++)
487 gchar* file = g_file_get_path (files[i]);
488 if (!file)
489 continue;
490 if (anjuta_util_is_project_file (file))
492 AnjutaWindow* new_win = create_window (files, n_files,
493 TRUE, TRUE, FALSE, FALSE, NULL);
494 gtk_application_add_window (GTK_APPLICATION (application),
495 GTK_WINDOW (new_win));
496 gtk_widget_show (GTK_WIDGET (new_win));
497 g_free (file);
498 return;
500 g_free (file);
503 for (i = 0; i < n_files; i++)
505 ianjuta_file_loader_load(loader, files[i], FALSE, NULL);
509 static void
510 anjuta_activate (GApplication *application)
512 /* Show first window */
513 GList* windows = gtk_application_get_windows (GTK_APPLICATION (application));
515 gtk_window_present (GTK_WINDOW (g_list_last (windows)->data));
518 static void
519 anjuta_init (Anjuta *anjuta)
524 static void
525 anjuta_class_init (AnjutaClass *klass)
527 GObjectClass* object_class = G_OBJECT_CLASS (klass);
528 GApplicationClass* app_class = G_APPLICATION_CLASS (klass);
530 object_class->finalize = anjuta_finalize;
532 app_class->open = anjuta_open;
533 app_class->activate = anjuta_activate;
536 Anjuta*
537 anjuta_new (void)
539 g_type_init ();
541 return g_object_new (anjuta_get_type (),
542 "application-id", "org.gnome.anjuta",
543 "flags", G_APPLICATION_HANDLES_OPEN,
544 NULL);