configure: fix build of vala plugin
[anjuta.git] / src / anjuta.c
blob32b230e798bbffc925cabc1778876b51585d7224
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 (AnjutaApp *app, 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", "AnjutaApp delete event");
56 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app), NULL);
57 profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (app), NULL);
59 /* Save remembered plugins */
60 remembered_plugins =
61 anjuta_plugin_manager_get_remembered_plugins (plugin_manager);
62 g_settings_set_string (app->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 (app));
69 anjuta_shell_save_prompt (ANJUTA_SHELL (app), 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 (app->save_count > 0)
89 g_message ("Waiting for %d file(s) to be saved!", app->save_count);
90 while (app->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 (app), session_dir, NULL);
105 g_free (session_dir);
108 anjuta_shell_notify_exit (ANJUTA_SHELL (app), NULL);
110 gtk_widget_destroy (GTK_WIDGET (save_prompt));
112 /* Shutdown */
113 if (g_object_get_data (G_OBJECT (app), "__proper_shutdown"))
115 gtk_widget_hide (GTK_WIDGET (app));
116 anjuta_plugin_manager_unload_all_plugins
117 (anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app), NULL));
119 return FALSE;
122 static void
123 on_anjuta_destroy (GtkWidget * w, gpointer data)
125 DEBUG_PRINT ("%s", "AnjutaApp destroy event");
127 gtk_widget_hide (w);
130 static void
131 on_profile_scoped (AnjutaProfileManager *profile_manager,
132 AnjutaProfile *profile, AnjutaApp *app)
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 (app), session_dir, NULL);
171 g_free (session_dir);
174 static void
175 on_profile_descoped (AnjutaProfileManager *profile_manager,
176 AnjutaProfile *profile, AnjutaApp *app)
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 (app), 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 gchar*
198 extract_project_from_session (const gchar* session_dir)
200 AnjutaSession *session;
201 GList *node, *files;
202 gchar *project_uri = NULL;
204 session = anjuta_session_new (session_dir);
206 files = anjuta_session_get_string_list (session, "File Loader", "Files");
207 g_object_unref (session);
209 /* Find project file */
210 node = files;
211 for (node = files; node != NULL; node = g_list_next (node))
213 gchar *uri = node->data;
214 if (uri)
216 if (anjuta_util_is_project_file (uri))
218 g_free (project_uri);
219 project_uri = uri;
221 else
223 g_free (uri);
227 g_list_free (files);
229 return project_uri;
232 AnjutaApp*
233 create_window (GFile **files, int n_files, gboolean no_splash,
234 gboolean no_session, gboolean no_files,
235 gboolean proper_shutdown, const gchar *geometry)
237 AnjutaPluginManager *plugin_manager;
238 AnjutaProfileManager *profile_manager;
239 AnjutaApp *app;
240 AnjutaStatus *status;
241 AnjutaProfile *profile;
242 GFile *session_profile;
243 gchar *remembered_plugins;
244 GFile *project = NULL;
245 GFile *template = NULL;
246 gchar *profile_name = NULL;
247 gchar *im_file = NULL;
248 GError *error = NULL;
250 /* Initialize application */
251 app = ANJUTA_APP (anjuta_app_new ());
252 status = anjuta_shell_get_status (ANJUTA_SHELL (app), NULL);
253 anjuta_status_progress_add_ticks (status, 1);
255 im_file = anjuta_res_get_pixmap_file (ANJUTA_PIXMAP_SPLASH_SCREEN);
257 gtk_window_set_role (GTK_WINDOW (app), "anjuta-app");
258 gtk_window_set_auto_startup_notification(TRUE);
259 gtk_window_set_default_icon_name ("anjuta");
260 gtk_window_set_auto_startup_notification(FALSE);
262 if (im_file)
264 anjuta_status_set_splash (status, im_file, 100);
265 g_free (im_file);
267 if (no_splash)
268 anjuta_status_disable_splash (status, no_splash);
270 if (proper_shutdown)
272 g_object_set_data (G_OBJECT (app), "__proper_shutdown", "1");
274 g_signal_connect (G_OBJECT (app), "delete_event",
275 G_CALLBACK (on_anjuta_delete_event), NULL);
276 g_signal_connect (G_OBJECT (app), "destroy",
277 G_CALLBACK (on_anjuta_destroy), NULL);
279 /* Setup application framework */
280 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app),
281 NULL);
282 profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (app),
283 NULL);
285 /* Restore remembered plugins */
286 remembered_plugins =
287 g_settings_get_string (app->settings, ANJUTA_REMEMBERED_PLUGINS);
288 if (remembered_plugins)
289 anjuta_plugin_manager_set_remembered_plugins (plugin_manager,
290 remembered_plugins);
291 g_free (remembered_plugins);
293 /* Prepare profile */
294 profile = anjuta_profile_new (USER_PROFILE_NAME, plugin_manager);
295 session_profile = g_file_new_for_uri (DEFAULT_PROFILE);
296 anjuta_profile_add_plugins_from_xml (profile, session_profile,
297 TRUE, &error);
298 if (error)
300 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
301 g_error_free (error);
302 error = NULL;
304 g_object_unref (session_profile);
306 /* Load user session profile */
307 profile_name = g_path_get_basename (DEFAULT_PROFILE);
308 session_profile = anjuta_util_get_user_cache_file (profile_name, NULL);
309 if (g_file_query_exists (session_profile, NULL))
311 anjuta_profile_add_plugins_from_xml (profile, session_profile,
312 FALSE, &error);
313 if (error)
315 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
316 g_error_free (error);
317 error = NULL;
320 anjuta_profile_set_sync_file (profile, session_profile);
321 g_object_unref (session_profile);
322 g_free (profile_name);
324 /* Load profile */
325 anjuta_profile_manager_freeze (profile_manager);
326 anjuta_profile_manager_push (profile_manager, profile, &error);
327 if (error)
329 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
330 g_error_free (error);
331 error = NULL;
334 if (files || geometry)
336 gchar *session_dir;
337 gchar *project_uri;
338 AnjutaSession *session;
339 gint i;
340 GList *files_load = NULL;
342 /* Reset default session */
343 session_dir = USER_SESSION_PATH_NEW;
345 project_uri = extract_project_from_session (session_dir);
346 template = NULL;
347 if (project_uri)
348 project = g_file_new_for_uri (project_uri);
349 g_free (project_uri);
351 session = anjuta_session_new (session_dir);
352 anjuta_session_clear (session);
353 if (geometry)
354 anjuta_session_set_string (session, "Anjuta", "Geometry",
355 geometry);
357 /* Identify non-project files and set them for loading in session */
358 for (i = 0; i < n_files; i++)
360 gchar* file = g_file_get_path (files[i]);
361 if (!file)
362 continue;
363 if (anjuta_util_is_project_file (file))
365 /* Pick up the first project file for loading later */
366 project = files[i];
367 g_object_ref (project);
369 else if (anjuta_util_is_template_file (file))
371 template = files[i];
372 g_object_ref (template);
374 else
376 files_load = g_list_prepend (files_load, g_file_get_uri (files[i]));
379 if (files_load)
381 anjuta_session_set_string_list (session, "File Loader", "Files",
382 files_load);
383 g_list_foreach (files_load, (GFunc)g_free, NULL);
384 g_list_free (files_load);
386 anjuta_session_sync (session);
387 g_object_unref (session);
388 g_free (session_dir);
390 else
392 gchar *session_dir;
393 AnjutaSession *session;
395 /* Load user session */
396 session_dir = USER_SESSION_PATH_NEW;
398 /* If preferences is set to not load last session, clear it */
399 if (no_session ||
400 g_settings_get_boolean (app->settings,
401 ANJUTA_SESSION_SKIP_LAST))
403 /* Reset default session */
404 session = anjuta_session_new (session_dir);
405 anjuta_session_clear (session);
406 g_object_unref (session);
408 /* If preferences is set to not load last project, clear it */
409 else if (no_files ||
410 g_settings_get_boolean (app->settings,
411 ANJUTA_SESSION_SKIP_LAST_FILES))
413 session = anjuta_session_new (session_dir);
414 anjuta_session_set_string_list (session, "File Loader",
415 "Files", NULL);
416 anjuta_session_sync (session);
417 g_object_unref (session);
419 /* Otherwise, load session normally */
420 else
422 gchar *project_uri = extract_project_from_session (session_dir);
423 if (project_uri)
424 project = g_file_new_for_uri (project_uri);
425 g_free (project_uri);
427 g_free (session_dir);
430 /* Prepare for session save and load on profile change */
431 g_signal_connect (profile_manager, "profile-scoped",
432 G_CALLBACK (on_profile_scoped), app);
433 /* Load project file */
434 if ((project != NULL) && (template == NULL))
436 IAnjutaFileLoader *loader;
437 loader = anjuta_shell_get_interface (ANJUTA_SHELL (app),
438 IAnjutaFileLoader, NULL);
439 ianjuta_file_loader_load (loader, project, FALSE, NULL);
440 g_object_unref (project);
442 anjuta_profile_manager_thaw (profile_manager, &error);
444 if (error)
446 anjuta_util_dialog_error (GTK_WINDOW (app), "%s", error->message);
447 g_error_free (error);
448 error = NULL;
450 g_signal_connect (profile_manager, "profile-descoped",
451 G_CALLBACK (on_profile_descoped), app);
453 anjuta_status_progress_tick (status, NULL, _("Loaded Session…"));
454 anjuta_status_disable_splash (status, TRUE);
456 /* Load template file */
457 if (template != NULL)
459 IAnjutaFileLoader *loader;
460 loader = anjuta_shell_get_interface (ANJUTA_SHELL (app),
461 IAnjutaFileLoader, NULL);
462 ianjuta_file_loader_load (loader, template, FALSE, NULL);
463 g_object_unref (template);
466 return app;
469 /* Application */
471 G_DEFINE_TYPE (Anjuta, anjuta, GTK_TYPE_APPLICATION)
473 static void
474 anjuta_finalize (GObject *object)
476 G_OBJECT_CLASS (anjuta_parent_class)->finalize (object);
479 static void
480 anjuta_open (GApplication *application,
481 GFile **files,
482 gint n_files,
483 const gchar* hint)
485 int i;
486 GList* windows = gtk_application_get_windows (GTK_APPLICATION (application));
487 AnjutaApp *app = ANJUTA_APP (windows->data);
488 IAnjutaFileLoader* loader =
489 anjuta_shell_get_interface(ANJUTA_SHELL(app), IAnjutaFileLoader, NULL);
491 if (!loader)
492 return;
494 /* Identify non-project files and set them for loading in session */
495 for (i = 0; i < n_files; i++)
497 gchar* file = g_file_get_path (files[i]);
498 if (!file)
499 continue;
500 if (anjuta_util_is_project_file (file))
502 AnjutaApp* new_app = create_window (files, n_files,
503 TRUE, TRUE, FALSE, FALSE, NULL);
504 gtk_application_add_window (GTK_APPLICATION (application),
505 GTK_WINDOW (new_app));
506 gtk_widget_show (GTK_WIDGET (new_app));
507 g_free (file);
508 return;
510 g_free (file);
513 for (i = 0; i < n_files; i++)
515 ianjuta_file_loader_load(loader, files[i], FALSE, NULL);
519 static void
520 anjuta_activate (GApplication *application)
522 /* Show first window */
523 GList* windows = gtk_application_get_windows (GTK_APPLICATION (application));
525 gtk_window_present (GTK_WINDOW (g_list_last (windows)->data));
528 static void
529 anjuta_init (Anjuta *anjuta)
534 static void
535 anjuta_class_init (AnjutaClass *klass)
537 GObjectClass* object_class = G_OBJECT_CLASS (klass);
538 GApplicationClass* app_class = G_APPLICATION_CLASS (klass);
540 object_class->finalize = anjuta_finalize;
542 app_class->open = anjuta_open;
543 app_class->activate = anjuta_activate;
546 Anjuta*
547 anjuta_new (void)
549 g_type_init ();
551 return g_object_new (anjuta_get_type (),
552 "application-id", "org.gnome.anjuta",
553 "flags", G_APPLICATION_HANDLES_OPEN,
554 NULL);