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");
132 on_profile_scoped (AnjutaProfileManager
*profile_manager
,
133 AnjutaProfile
*profile
, AnjutaApp
*app
)
136 static gboolean first_time
= TRUE
;
138 DEBUG_PRINT ("Profile scoped: %s", anjuta_profile_get_name (profile
));
139 if (strcmp (anjuta_profile_get_name (profile
), USER_PROFILE_NAME
) != 0)
142 DEBUG_PRINT ("%s", "User profile loaded; Restoring user session");
144 /* If profile scoped to "user", restore user session */
145 if (system_restore_session
)
147 session_dir
= system_restore_session
;
148 system_restore_session
= NULL
;
152 session_dir
= USER_SESSION_PATH_NEW
;
161 /* Clear the files list since we don't want to load them later */
162 AnjutaSession
*session
;
163 session
= anjuta_session_new (session_dir
);
164 anjuta_session_set_string_list (session
, "File Loader",
166 anjuta_session_sync (session
);
167 g_object_unref (session
);
170 /* Restore session */
171 anjuta_shell_session_load (ANJUTA_SHELL (app
), session_dir
, NULL
);
172 g_free (session_dir
);
176 on_profile_descoped (AnjutaProfileManager
*profile_manager
,
177 AnjutaProfile
*profile
, AnjutaApp
*app
)
181 DEBUG_PRINT ("Profile descoped: %s", anjuta_profile_get_name (profile
));
182 if (strcmp (anjuta_profile_get_name (profile
), USER_PROFILE_NAME
) != 0)
185 DEBUG_PRINT ("%s", "User profile descoped; Saving user session");
187 /* If profile descoped from is "user", save user session */
188 session_dir
= USER_SESSION_PATH_NEW
;
190 /* Save current session */
191 anjuta_shell_session_save (ANJUTA_SHELL (app
), session_dir
, NULL
);
192 g_free (session_dir
);
195 /* This extracts the project URI saved in the session so that it could be
196 * loaded sequencially. Returned string must be freed.
199 extract_project_from_session (const gchar
* session_dir
)
201 AnjutaSession
*session
;
203 gchar
*project_uri
= NULL
;
205 session
= anjuta_session_new (session_dir
);
207 files
= anjuta_session_get_string_list (session
, "File Loader", "Files");
208 g_object_unref (session
);
210 /* Find project file */
212 for (node
= files
; node
!= NULL
; node
= g_list_next (node
))
214 gchar
*uri
= node
->data
;
217 if (anjuta_util_is_project_file (uri
))
219 g_free (project_uri
);
234 create_window (GFile
**files
, int n_files
, gboolean no_splash
,
235 gboolean no_session
, gboolean no_files
,
236 gboolean proper_shutdown
, const gchar
*geometry
)
238 AnjutaPluginManager
*plugin_manager
;
239 AnjutaProfileManager
*profile_manager
;
241 AnjutaStatus
*status
;
242 AnjutaProfile
*profile
;
243 GFile
*session_profile
;
244 gchar
*remembered_plugins
;
245 GFile
*project
= NULL
;
246 GFile
*template = NULL
;
247 gchar
*profile_name
= NULL
;
248 gchar
*im_file
= NULL
;
249 GError
*error
= NULL
;
251 /* Initialize application */
252 app
= ANJUTA_APP (anjuta_app_new ());
253 status
= anjuta_shell_get_status (ANJUTA_SHELL (app
), NULL
);
254 anjuta_status_progress_add_ticks (status
, 1);
256 im_file
= anjuta_res_get_pixmap_file (ANJUTA_PIXMAP_SPLASH_SCREEN
);
258 gtk_window_set_role (GTK_WINDOW (app
), "anjuta-app");
259 gtk_window_set_auto_startup_notification(TRUE
);
260 gtk_window_set_default_icon_name ("anjuta");
261 gtk_window_set_auto_startup_notification(FALSE
);
265 anjuta_status_set_splash (status
, im_file
, 100);
269 anjuta_status_disable_splash (status
, no_splash
);
273 g_object_set_data (G_OBJECT (app
), "__proper_shutdown", "1");
275 g_signal_connect (G_OBJECT (app
), "delete_event",
276 G_CALLBACK (on_anjuta_delete_event
), NULL
);
277 g_signal_connect (G_OBJECT (app
), "destroy",
278 G_CALLBACK (on_anjuta_destroy
), NULL
);
280 /* Setup application framework */
281 plugin_manager
= anjuta_shell_get_plugin_manager (ANJUTA_SHELL (app
),
283 profile_manager
= anjuta_shell_get_profile_manager (ANJUTA_SHELL (app
),
286 /* Restore remembered plugins */
288 g_settings_get_string (app
->settings
, ANJUTA_REMEMBERED_PLUGINS
);
289 if (remembered_plugins
)
290 anjuta_plugin_manager_set_remembered_plugins (plugin_manager
,
292 g_free (remembered_plugins
);
294 /* Prepare profile */
295 profile
= anjuta_profile_new (USER_PROFILE_NAME
, plugin_manager
);
296 session_profile
= g_file_new_for_uri (DEFAULT_PROFILE
);
297 anjuta_profile_add_plugins_from_xml (profile
, session_profile
,
301 anjuta_util_dialog_error (GTK_WINDOW (app
), "%s", error
->message
);
302 g_error_free (error
);
305 g_object_unref (session_profile
);
307 /* Load user session profile */
308 profile_name
= g_path_get_basename (DEFAULT_PROFILE
);
309 session_profile
= anjuta_util_get_user_cache_file (profile_name
, NULL
);
310 if (g_file_query_exists (session_profile
, NULL
))
312 anjuta_profile_add_plugins_from_xml (profile
, session_profile
,
316 anjuta_util_dialog_error (GTK_WINDOW (app
), "%s", error
->message
);
317 g_error_free (error
);
321 anjuta_profile_set_sync_file (profile
, session_profile
);
322 g_object_unref (session_profile
);
323 g_free (profile_name
);
326 anjuta_profile_manager_freeze (profile_manager
);
327 anjuta_profile_manager_push (profile_manager
, profile
, &error
);
330 anjuta_util_dialog_error (GTK_WINDOW (app
), "%s", error
->message
);
331 g_error_free (error
);
335 if (files
|| geometry
)
339 AnjutaSession
*session
;
341 GList
*files_load
= NULL
;
343 /* Reset default session */
344 session_dir
= USER_SESSION_PATH_NEW
;
346 project_uri
= extract_project_from_session (session_dir
);
349 project
= g_file_new_for_uri (project_uri
);
350 g_free (project_uri
);
352 session
= anjuta_session_new (session_dir
);
353 anjuta_session_clear (session
);
355 anjuta_session_set_string (session
, "Anjuta", "Geometry",
358 /* Identify non-project files and set them for loading in session */
359 for (i
= 0; i
< n_files
; i
++)
361 gchar
* file
= g_file_get_path (files
[i
]);
364 if (anjuta_util_is_project_file (file
))
366 /* Pick up the first project file for loading later */
368 g_object_ref (project
);
370 else if (anjuta_util_is_template_file (file
))
373 g_object_ref (template);
377 files_load
= g_list_prepend (files_load
, g_file_get_uri (files
[i
]));
382 anjuta_session_set_string_list (session
, "File Loader", "Files",
384 g_list_foreach (files_load
, (GFunc
)g_free
, NULL
);
385 g_list_free (files_load
);
387 anjuta_session_sync (session
);
388 g_object_unref (session
);
389 g_free (session_dir
);
394 AnjutaSession
*session
;
396 /* Load user session */
397 session_dir
= USER_SESSION_PATH_NEW
;
399 /* If preferences is set to not load last session, clear it */
401 g_settings_get_boolean (app
->settings
,
402 ANJUTA_SESSION_SKIP_LAST
))
404 /* Reset default session */
405 session
= anjuta_session_new (session_dir
);
406 anjuta_session_clear (session
);
407 g_object_unref (session
);
409 /* If preferences is set to not load last project, clear it */
411 g_settings_get_boolean (app
->settings
,
412 ANJUTA_SESSION_SKIP_LAST_FILES
))
414 session
= anjuta_session_new (session_dir
);
415 anjuta_session_set_string_list (session
, "File Loader",
417 anjuta_session_sync (session
);
418 g_object_unref (session
);
420 /* Otherwise, load session normally */
423 gchar
*project_uri
= extract_project_from_session (session_dir
);
425 project
= g_file_new_for_uri (project_uri
);
426 g_free (project_uri
);
428 g_free (session_dir
);
431 /* Prepare for session save and load on profile change */
432 g_signal_connect (profile_manager
, "profile-scoped",
433 G_CALLBACK (on_profile_scoped
), app
);
434 /* Load project file */
435 if ((project
!= NULL
) && (template == NULL
))
437 IAnjutaFileLoader
*loader
;
438 loader
= anjuta_shell_get_interface (ANJUTA_SHELL (app
),
439 IAnjutaFileLoader
, NULL
);
440 ianjuta_file_loader_load (loader
, project
, FALSE
, NULL
);
441 g_object_unref (project
);
443 anjuta_profile_manager_thaw (profile_manager
, &error
);
447 anjuta_util_dialog_error (GTK_WINDOW (app
), "%s", error
->message
);
448 g_error_free (error
);
451 g_signal_connect (profile_manager
, "profile-descoped",
452 G_CALLBACK (on_profile_descoped
), app
);
454 anjuta_status_progress_tick (status
, NULL
, _("Loaded Session…"));
455 anjuta_status_disable_splash (status
, TRUE
);
457 /* Load template file */
458 if (template != NULL
)
460 IAnjutaFileLoader
*loader
;
461 loader
= anjuta_shell_get_interface (ANJUTA_SHELL (app
),
462 IAnjutaFileLoader
, NULL
);
463 ianjuta_file_loader_load (loader
, template, FALSE
, NULL
);
464 g_object_unref (template);
472 G_DEFINE_TYPE (Anjuta
, anjuta
, GTK_TYPE_APPLICATION
)
475 anjuta_finalize (GObject
*object
)
477 G_OBJECT_CLASS (anjuta_parent_class
)->finalize (object
);
481 anjuta_open (GApplication
*application
,
487 GList
* windows
= gtk_application_get_windows (GTK_APPLICATION (application
));
488 AnjutaApp
*app
= ANJUTA_APP (windows
->data
);
489 IAnjutaFileLoader
* loader
=
490 anjuta_shell_get_interface(ANJUTA_SHELL(app
), IAnjutaFileLoader
, NULL
);
495 /* Identify non-project files and set them for loading in session */
496 for (i
= 0; i
< n_files
; i
++)
498 gchar
* file
= g_file_get_path (files
[i
]);
501 if (anjuta_util_is_project_file (file
))
503 AnjutaApp
* new_app
= create_window (files
, n_files
,
504 TRUE
, TRUE
, FALSE
, FALSE
, NULL
);
505 gtk_application_add_window (GTK_APPLICATION (application
),
506 GTK_WINDOW (new_app
));
507 gtk_widget_show (GTK_WIDGET (new_app
));
514 for (i
= 0; i
< n_files
; i
++)
516 ianjuta_file_loader_load(loader
, files
[i
], FALSE
, NULL
);
521 anjuta_activate (GApplication
*application
)
523 /* Show first window */
524 GList
* windows
= gtk_application_get_windows (GTK_APPLICATION (application
));
526 gtk_window_present (GTK_WINDOW (g_list_last (windows
)->data
));
530 anjuta_init (Anjuta
*anjuta
)
536 anjuta_class_init (AnjutaClass
*klass
)
538 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
539 GApplicationClass
* app_class
= G_APPLICATION_CLASS (klass
);
541 object_class
->finalize
= anjuta_finalize
;
543 app_class
->open
= anjuta_open
;
544 app_class
->activate
= anjuta_activate
;
552 return g_object_new (anjuta_get_type (),
553 "application-id", "org.gnome.anjuta",
554 "flags", G_APPLICATION_HANDLES_OPEN
,