1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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)
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
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
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>
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
;
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 */
61 anjuta_plugin_manager_get_remembered_plugins (plugin_manager
);
62 g_settings_set_string (app
->settings
,
63 ANJUTA_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
));
80 case ANJUTA_SAVE_PROMPT_RESPONSE_DISCARD
:
81 case ANJUTA_SAVE_PROMPT_RESPONSE_SAVE_CLOSE
:
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
99 current_profile
= anjuta_profile_manager_get_current (profile_manager
);
100 if (strcmp (anjuta_profile_get_name (current_profile
), "user") == 0)
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
));
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
));
123 on_anjuta_destroy (GtkWidget
* w
, gpointer data
)
125 DEBUG_PRINT ("%s", "AnjutaApp destroy event");
131 on_profile_scoped (AnjutaProfileManager
*profile_manager
,
132 AnjutaProfile
*profile
, AnjutaApp
*app
)
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)
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
;
151 session_dir
= USER_SESSION_PATH_NEW
;
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",
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
);
175 on_profile_descoped (AnjutaProfileManager
*profile_manager
,
176 AnjutaProfile
*profile
, AnjutaApp
*app
)
180 DEBUG_PRINT ("Profile descoped: %s", anjuta_profile_get_name (profile
));
181 if (strcmp (anjuta_profile_get_name (profile
), USER_PROFILE_NAME
) != 0)
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.
198 extract_project_from_session (const gchar
* session_dir
)
200 AnjutaSession
*session
;
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 */
211 for (node
= files
; node
!= NULL
; node
= g_list_next (node
))
213 gchar
*uri
= node
->data
;
216 if (anjuta_util_is_project_file (uri
))
218 g_free (project_uri
);
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
;
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
);
264 anjuta_status_set_splash (status
, im_file
, 100);
268 anjuta_status_disable_splash (status
, no_splash
);
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
),
282 profile_manager
= anjuta_shell_get_profile_manager (ANJUTA_SHELL (app
),
285 /* Restore 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
,
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
,
300 anjuta_util_dialog_error (GTK_WINDOW (app
), "%s", error
->message
);
301 g_error_free (error
);
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
,
315 anjuta_util_dialog_error (GTK_WINDOW (app
), "%s", error
->message
);
316 g_error_free (error
);
320 anjuta_profile_set_sync_file (profile
, session_profile
);
321 g_object_unref (session_profile
);
322 g_free (profile_name
);
325 anjuta_profile_manager_freeze (profile_manager
);
326 anjuta_profile_manager_push (profile_manager
, profile
, &error
);
329 anjuta_util_dialog_error (GTK_WINDOW (app
), "%s", error
->message
);
330 g_error_free (error
);
334 if (files
|| geometry
)
338 AnjutaSession
*session
;
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
);
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
);
354 anjuta_session_set_string (session
, "Anjuta", "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
]);
363 if (anjuta_util_is_project_file (file
))
365 /* Pick up the first project file for loading later */
367 g_object_ref (project
);
369 else if (anjuta_util_is_template_file (file
))
372 g_object_ref (template);
376 files_load
= g_list_prepend (files_load
, g_file_get_uri (files
[i
]));
381 anjuta_session_set_string_list (session
, "File Loader", "Files",
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
);
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 */
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 */
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",
416 anjuta_session_sync (session
);
417 g_object_unref (session
);
419 /* Otherwise, load session normally */
422 gchar
*project_uri
= extract_project_from_session (session_dir
);
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
);
446 anjuta_util_dialog_error (GTK_WINDOW (app
), "%s", error
->message
);
447 g_error_free (error
);
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);
471 G_DEFINE_TYPE (Anjuta
, anjuta
, GTK_TYPE_APPLICATION
)
474 anjuta_finalize (GObject
*object
)
476 G_OBJECT_CLASS (anjuta_parent_class
)->finalize (object
);
480 anjuta_open (GApplication
*application
,
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
);
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
]);
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
));
513 for (i
= 0; i
< n_files
; i
++)
515 ianjuta_file_loader_load(loader
, files
[i
], FALSE
, NULL
);
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
));
529 anjuta_init (Anjuta
*anjuta
)
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
;
551 return g_object_new (anjuta_get_type (),
552 "application-id", "org.gnome.anjuta",
553 "flags", G_APPLICATION_HANDLES_OPEN
,