1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * anjuta-application.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.
10  *
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.
15  *
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
19  */
20 
21 #include <config.h>
22 #ifdef ENABLE_NLS
23 #  include <locale.h>
24 #endif
25 
26 #include <string.h>
27 #include <stdlib.h>
28 #include <libanjuta/anjuta-shell.h>
29 #include <libanjuta/anjuta-debug.h>
30 #include <libanjuta/anjuta-utils.h>
31 #include <libanjuta/anjuta-save-prompt.h>
32 #include <libanjuta/anjuta-plugin-manager.h>
33 #include <libanjuta/resources.h>
34 #include <libanjuta/interfaces/ianjuta-file-loader.h>
35 #include <libanjuta/interfaces/ianjuta-file.h>
36 
37 #include "anjuta-application.h"
38 #include "action-callbacks.h"
39 
40 #define ANJUTA_REMEMBERED_PLUGINS "remembered-plugins"
41 #define USER_SESSION_PATH_NEW (anjuta_util_get_user_cache_file_path ("session/", NULL))
42 
43 #define ANJUTA_SESSION_SKIP_LAST "session-skip-last"
44 #define ANJUTA_SESSION_SKIP_LAST_FILES "session-skip-last-files"
45 
46 #define PROFILE_DIRECTORY "file://"PACKAGE_DATA_DIR"/profiles"
47 #define USER_PROFILE_NAME "user"
48 
49 #define ANJUTA_PIXMAP_SPLASH_SCREEN       "anjuta_splash.png"
50 
51 #define ANJUTA_GEOMETRY_HINT ";g="
52 #define ANJUTA_PROFILE_HINT ";P="
53 #define ANJUTA_NO_SPLASH_HINT ";s"
54 #define ANJUTA_NO_SESSION_HINT ";n"
55 #define ANJUTA_NO_FILES_HINT ";f"
56 
57 static gchar DEFAULT_PROFILE[] = "default.profile";
58 
59 #define ANJUTA_MENU_UI_FILE PACKAGE_DATA_DIR"/glade/anjuta-menu.ui"
60 
61 G_DEFINE_TYPE (AnjutaApplication, anjuta_application, GTK_TYPE_APPLICATION)
62 
63 struct _AnjutaApplicationPrivate {
64 	gboolean no_splash;
65 	gboolean proper_shutdown;
66 	gboolean no_files;
67 	gboolean no_session;
68 	gchar *geometry;
69 	gchar *profile;
70 };
71 
72 static void
on_app_new_window(GSimpleAction * action,GVariant * parameter,gpointer user_data)73 on_app_new_window (GSimpleAction  *action,
74                     GVariant       *parameter,
75                     gpointer        user_data)
76 {
77 	AnjutaApplication *app;
78 
79 	app = ANJUTA_APPLICATION (user_data);
80 	anjuta_application_create_window (app);
81 }
82 
83 static void
on_app_preferences(GSimpleAction * action,GVariant * parameter,gpointer user_data)84 on_app_preferences (GSimpleAction  *action,
85                     GVariant       *parameter,
86                     gpointer        user_data)
87 {
88 	GtkApplication *app;
89 	AnjutaWindow* window;
90 
91 	app = GTK_APPLICATION (user_data);
92 	window = ANJUTA_WINDOW (gtk_application_get_active_window (app));
93 
94 	on_preferences_activate (NULL, window);
95 }
96 
97 static void
on_app_manual(GSimpleAction * action,GVariant * parameter,gpointer user_data)98 on_app_manual (GSimpleAction  *action,
99                GVariant       *parameter,
100                gpointer        user_data)
101 {
102 	GtkApplication *app;
103 	AnjutaWindow* window;
104 
105 	app = GTK_APPLICATION (user_data);
106 	window = ANJUTA_WINDOW (gtk_application_get_active_window (app));
107 
108 	on_help_manual_activate (NULL, window);
109 }
110 
111 static void
on_app_about(GSimpleAction * action,GVariant * parameter,gpointer user_data)112 on_app_about (GSimpleAction  *action,
113               GVariant       *parameter,
114               gpointer        user_data)
115 {
116 	GtkApplication *app;
117 	AnjutaWindow* window;
118 
119 	app = GTK_APPLICATION (user_data);
120 	window = ANJUTA_WINDOW (gtk_application_get_active_window (app));
121 
122 	on_about_activate (NULL, window);
123 }
124 
125 static void
on_app_quit(GSimpleAction * action,GVariant * parameter,gpointer user_data)126 on_app_quit (GSimpleAction  *action,
127              GVariant       *parameter,
128              gpointer        user_data)
129 {
130 	GtkApplication *app;
131 	AnjutaWindow* window;
132 
133 	app = GTK_APPLICATION (user_data);
134 	window = ANJUTA_WINDOW (gtk_application_get_active_window (app));
135 
136 	on_exit_activate (NULL, window);
137 }
138 
139 
140 static gboolean
on_anjuta_delete_event(AnjutaWindow * win,GdkEvent * event,gpointer user_data)141 on_anjuta_delete_event (AnjutaWindow *win, GdkEvent *event, gpointer user_data)
142 {
143 	AnjutaApplication *app = user_data;
144 	AnjutaApplicationPrivate *priv = app->priv;
145 
146 	AnjutaPluginManager *plugin_manager;
147 	AnjutaProfileManager *profile_manager;
148 	AnjutaSavePrompt *save_prompt;
149 	gchar *remembered_plugins;
150 
151 	DEBUG_PRINT ("%s", "AnjutaWindow delete event");
152 
153 	plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (win), NULL);
154 	profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (win), NULL);
155 
156 	/* Save remembered plugins */
157 	remembered_plugins =
158 		anjuta_plugin_manager_get_remembered_plugins (plugin_manager);
159 	g_settings_set_string (win->settings,
160 	                       ANJUTA_REMEMBERED_PLUGINS,
161 	                       remembered_plugins);
162 	g_free (remembered_plugins);
163 
164 	/* Check for unsaved data */
165 	save_prompt = anjuta_save_prompt_new (GTK_WINDOW (win));
166 	anjuta_shell_save_prompt (ANJUTA_SHELL (win), save_prompt, NULL);
167 
168 	if (anjuta_save_prompt_get_items_count (save_prompt) > 0)
169 	{
170 		switch (gtk_dialog_run (GTK_DIALOG (save_prompt)))
171 		{
172 			case GTK_RESPONSE_DELETE_EVENT:
173 			case ANJUTA_SAVE_PROMPT_RESPONSE_CANCEL:
174 				gtk_widget_destroy (GTK_WIDGET (save_prompt));
175 				/* Do not exit now */
176 				return TRUE;
177 			case ANJUTA_SAVE_PROMPT_RESPONSE_DISCARD:
178 			case ANJUTA_SAVE_PROMPT_RESPONSE_SAVE_CLOSE:
179 				/* exit now */
180 				break;
181 		}
182 	}
183 	gtk_widget_destroy (GTK_WIDGET (save_prompt));
184 
185 	/* Wait for files to be really saved (asyncronous operation) */
186 	if (win->save_count > 0)
187 	{
188 		g_message ("Waiting for %d file(s) to be saved!", win->save_count);
189 		while (win->save_count > 0)
190 		{
191 			g_main_context_iteration (NULL, TRUE);
192 		}
193 	}
194 
195 	/* Close the profile manager which will emit "descoped" and release
196 	 * all previous profiles. */
197 	anjuta_profile_manager_close (profile_manager);
198 
199 	/* If this is the last window we can just quit the application and skip
200 	 * deactivating plugins and other cleanup. */
201 	if (!priv->proper_shutdown &&
202 	    g_list_length (gtk_application_get_windows (GTK_APPLICATION (app))) == 1)
203 	{
204 		g_application_quit (G_APPLICATION (app));
205 		return TRUE;
206 	}
207 
208 	/* Hide the window while unloading all the plugins. */
209 	gtk_widget_hide (GTK_WIDGET (win));
210 	anjuta_plugin_manager_unload_all_plugins (plugin_manager);
211 
212 	return FALSE;
213 }
214 
215 static void
on_profile_scoped(AnjutaProfile * profile,AnjutaWindow * win)216 on_profile_scoped (AnjutaProfile *profile, AnjutaWindow *win)
217 {
218 	gchar *session_dir;
219 	static gboolean first_time = TRUE;
220 	AnjutaSession *session;
221 
222 	DEBUG_PRINT ("%s", "User profile loaded; Restoring user session");
223 
224 	/* If profile scoped to "user", restore user session */
225 	session_dir = USER_SESSION_PATH_NEW;
226 
227 	session = anjuta_session_new (session_dir);
228 	if (first_time)
229 	{
230 		if (g_settings_get_boolean (win->settings, ANJUTA_SESSION_SKIP_LAST))
231 		{
232 			/* Clear session */
233 			anjuta_session_clear (session);
234 		}
235 		else if (g_settings_get_boolean (win->settings, ANJUTA_SESSION_SKIP_LAST_FILES))
236 		{
237 			/* Clear files from session */
238 			anjuta_session_set_string_list (session, "File Loader",
239 			                                "Files", NULL);
240 		}
241 		first_time = FALSE;
242 	}
243 	else
244 	{
245 		/* Clear the files list since we don't want to load them later */
246 		anjuta_session_set_string_list (session, "File Loader",
247 		                                "Files", NULL);
248 	}
249 	anjuta_session_sync (session);
250 	g_object_unref (session);
251 
252 	/* Restore session */
253 	anjuta_shell_session_load (ANJUTA_SHELL (win), session_dir, NULL);
254 	g_free (session_dir);
255 }
256 
257 static void
on_profile_descoped(AnjutaProfile * profile,AnjutaWindow * win)258 on_profile_descoped (AnjutaProfile *profile, AnjutaWindow *win)
259 {
260 	gchar *session_dir;
261 
262 	DEBUG_PRINT ("%s", "User profile descoped; Saving user session");
263 
264 	/* If profile descoped from is "user", save user session */
265 	session_dir = USER_SESSION_PATH_NEW;
266 
267 	/* Save current session */
268 	anjuta_shell_session_save (ANJUTA_SHELL (win), session_dir, NULL);
269 	g_free (session_dir);
270 }
271 
272 /* Create hint string.
273  * Pass command line options to primary instance if needed */
274 static gchar *
create_anjuta_application_hint(const gchar * geometry,gboolean no_splash,gboolean no_session,gboolean no_files,const gchar * profile)275 create_anjuta_application_hint (const gchar *geometry,
276                                 gboolean no_splash,
277                                 gboolean no_session,
278                                 gboolean no_files,
279                                 const gchar *profile)
280 {
281 	GString *hint;
282 
283 	hint = g_string_new (NULL);
284 	if (geometry != NULL)
285 	{
286 		g_string_append (hint, ANJUTA_GEOMETRY_HINT);
287 		g_string_append (hint, geometry);
288 	}
289 	if (no_splash) g_string_append (hint,ANJUTA_NO_SPLASH_HINT);
290 	if (no_session) g_string_append (hint,ANJUTA_NO_SESSION_HINT);
291 	if (no_files) g_string_append (hint,ANJUTA_NO_FILES_HINT);
292 	if (profile != NULL)
293 	{
294 		g_string_append (hint, ANJUTA_PROFILE_HINT);
295 		g_string_append_uri_escaped (hint, profile, NULL, FALSE);
296 	}
297 	g_string_append_c(hint, ';');
298 
299 	return g_string_free (hint, FALSE);
300 }
301 
302 /* Parse hint string to set flag in primary application */
303 static void
anjuta_application_parse_hint(AnjutaApplication * app,const gchar * hint)304 anjuta_application_parse_hint (AnjutaApplication *app,
305                                const gchar* hint)
306 {
307 	const gchar *geometry;
308 	const gchar *profile;
309 
310 	g_free (app->priv->geometry);
311 	app->priv->geometry = NULL;
312 	geometry = strstr(hint, ANJUTA_GEOMETRY_HINT);
313 	if (geometry != NULL)
314 	{
315 		const gchar *end = strstr(geometry + 1, ";");
316 
317 		if (end != NULL)
318 		{
319 			geometry += strlen (ANJUTA_GEOMETRY_HINT);
320 			app->priv->geometry = g_strndup (geometry, end - geometry);
321 		}
322 	}
323 	app->priv->no_splash = strstr(hint, ANJUTA_NO_SPLASH_HINT ";") != NULL ? TRUE : FALSE;
324 	app->priv->no_session = strstr(hint, ANJUTA_NO_SESSION_HINT ";") != NULL ? TRUE : FALSE;
325 	app->priv->no_files = strstr(hint, ANJUTA_NO_FILES_HINT ";") != NULL ? TRUE : FALSE;
326 	g_free (app->priv->profile);
327 	app->priv->profile = NULL;
328 	profile = strstr(hint, ANJUTA_PROFILE_HINT);
329 	if (profile != NULL)
330 	{
331 		const gchar *end = strstr(profile + 1, ";");
332 
333 		if (end != NULL)
334 		{
335 			profile += strlen (ANJUTA_PROFILE_HINT);
336 			app->priv->profile = g_uri_unescape_segment (profile, end, NULL);
337 		}
338 	}
339 }
340 
341 static void
anjuta_application_reset_hint(AnjutaApplication * app)342 anjuta_application_reset_hint (AnjutaApplication *app)
343 {
344 	g_free (app->priv->geometry);
345 	app->priv->geometry = NULL;
346 	app->priv->no_splash = FALSE;
347 	app->priv->no_session = FALSE;
348 	app->priv->no_files = FALSE;
349 }
350 
351 
352 /* GApplication implementation
353  *---------------------------------------------------------------------------*/
354 
355 static gboolean
anjuta_application_local_command_line(GApplication * application,gchar *** arguments,gint * exit_status)356 anjuta_application_local_command_line (GApplication *application,
357                                        gchar ***arguments,
358                                        gint *exit_status)
359 {
360 	/* Command line options */
361 	gboolean no_splash = FALSE;
362 	gboolean no_client = FALSE;
363 	gboolean no_session = FALSE;
364 	gboolean no_files = FALSE;
365 	gboolean version = FALSE;
366 	gchar *geometry = NULL;
367 	gchar *profile = NULL;
368 	gchar **filenames = NULL;
369 
370 	const GOptionEntry anjuta_options[] = {
371 		{
372 			"geometry", 'g', 0, G_OPTION_ARG_STRING,
373 			&geometry,
374 			N_("Specify the size and location of the main window"),
375 			/* This is the format you can specify the size andposition
376 		 	 * of the window on command line */
377 			N_("WIDTHxHEIGHT+XOFF+YOFF")
378 		},
379 		{
380 			"no-splash", 's', 0, G_OPTION_ARG_NONE,
381 			&no_splash,
382 			N_("Do not show the splash screen"),
383 			NULL
384 		},
385 		{
386 			"no-client", 'c', 0, G_OPTION_ARG_NONE,
387 			&no_client,
388 			N_("Start a new instance and do not open the file in an existing instance"),
389 			NULL
390 		},
391 		{
392 			"no-session", 'n', 0, G_OPTION_ARG_NONE,
393 			&no_session,
394 			N_("Do not open last session on startup"),
395 			NULL
396 		},
397 		{
398 			"no-files", 'f', 0, G_OPTION_ARG_NONE,
399 			&no_files,
400 			N_("Do not open last project and files on startup"),
401 			NULL
402 		},
403 		{
404 			"proper-shutdown", 'p', 0, G_OPTION_ARG_NONE,
405 			&((ANJUTA_APPLICATION (application))->priv->proper_shutdown),
406 			N_("Shut down Anjuta properly, releasing all resources (for debugging)"),
407 			NULL
408 		},
409 		{
410 			"version", 'v', 0, G_OPTION_ARG_NONE,
411 			&version,
412 			N_("Display program version"),
413 			NULL
414 		},
415 		{
416 			"profile", 'P', 0, G_OPTION_ARG_STRING,
417 			&profile,
418 			N_("Specify another profile"),
419 			N_("PROFILE_FILE")
420 		},
421 		{
422 			G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY,
423 			&filenames,
424 			NULL,
425 			NULL
426 		},
427 		{NULL}
428 	};
429 	GOptionContext *context;
430 	gint argc = 0;
431 	gchar **argv = NULL;
432 	GError *error = NULL;
433 	gchar *hint = NULL;
434 	GPtrArray *files;
435 
436 	context = g_option_context_new (_("- Integrated Development Environment"));
437 #ifdef ENABLE_NLS
438 	g_option_context_add_main_entries (context, anjuta_options, GETTEXT_PACKAGE);
439 #else
440 	g_option_context_add_main_entries (context, anjuta_options, NULL);
441 #endif
442 	g_option_context_add_group (context, gtk_get_option_group (TRUE));
443 
444 	/* Parse arguments */
445 	argv = *arguments;
446 	argc = g_strv_length (argv);
447 	if (!g_option_context_parse (context, &argc, &argv, &error))
448 	{
449 		g_printerr ("Could not parse arguments: %s\n", error->message);
450 		g_error_free (error);
451 		g_option_context_free (context);
452 
453 		*exit_status = EXIT_FAILURE;
454 		return TRUE;
455 	}
456 	*exit_status = EXIT_SUCCESS;
457 	g_option_context_free (context);
458 
459 
460 	/* Display version */
461 	if (version)
462 	{
463 		g_print ("%s\n", PACKAGE_STRING);
464 		return TRUE;
465 	}
466 
467 	/* Set application prefix */
468 	if (profile != NULL)
469 	{
470 		gchar *application_id = g_strconcat (g_application_get_application_id (application), "-", profile, NULL);
471 
472 		g_application_set_application_id (application, application_id);
473 		anjuta_util_set_anjuta_prefix (profile);
474 		g_free (application_id);
475 	}
476 
477 	/* Register application */
478 	if (no_client) g_application_set_flags (application, G_APPLICATION_NON_UNIQUE | g_application_get_flags (application));
479 	g_application_register (G_APPLICATION (application), NULL, NULL);
480 
481 	/* Convert all file names to GFile, so an already existing instance of
482 	 * Anjuta having another current directory can still open the files */
483 	files = g_ptr_array_new ();
484 	if (filenames)
485 	{
486 		gchar** filename;
487 
488 		for (filename = filenames; *filename != NULL; filename++)
489 		{
490 			GFile* file = g_file_new_for_commandline_arg(*filename);
491 			if (file != NULL) g_ptr_array_add (files, file);
492 		}
493 	}
494 
495 	/* Create hint string */
496 	hint = create_anjuta_application_hint (geometry, no_splash, no_session, no_files, profile);
497 
498 	/* Open files */
499 	g_application_open (application, (GFile **)files->pdata, files->len, hint);
500 	g_ptr_array_foreach (files, (GFunc)g_object_unref, NULL);
501 	g_ptr_array_free (files, TRUE);
502 	g_free (hint);
503 
504 	return TRUE;
505 }
506 
507 static void
anjuta_application_open(GApplication * application,GFile ** files,gint n_files,const gchar * hint)508 anjuta_application_open (GApplication *application,
509                          GFile **files,
510                          gint n_files,
511                          const gchar* hint)
512 {
513 	GList *windows;
514 	AnjutaShell *win;
515 	IAnjutaFileLoader* loader = NULL;
516 	gint i;
517 
518 	anjuta_application_parse_hint (ANJUTA_APPLICATION (application), hint);
519 
520 	windows = gtk_application_get_windows (GTK_APPLICATION (application));
521 	if (windows == NULL)
522 	{
523 		if (n_files == 0)
524 		{
525 			win = ANJUTA_SHELL (anjuta_application_create_window (ANJUTA_APPLICATION (application)));
526 		}
527 		else
528 		{
529 			gboolean no_files = ANJUTA_APPLICATION (application)->priv->no_files;
530 			ANJUTA_APPLICATION (application)->priv->no_files = TRUE;
531 			win = ANJUTA_SHELL (anjuta_application_create_window (ANJUTA_APPLICATION (application)));
532 			ANJUTA_APPLICATION (application)->priv->no_files = no_files;
533 		}
534 	}
535 	else
536 	{
537 		if (n_files == 0)
538 		{
539 			gboolean no_files = ANJUTA_APPLICATION (application)->priv->no_files;
540 			ANJUTA_APPLICATION (application)->priv->no_files = TRUE;
541 			win = ANJUTA_SHELL (anjuta_application_create_window (ANJUTA_APPLICATION (application)));
542 			ANJUTA_APPLICATION (application)->priv->no_files = no_files;
543 		}
544 		else
545 		{
546 			win = ANJUTA_SHELL (windows->data);
547 		}
548 	}
549 
550 	if (win != NULL)
551 	{
552 		loader = anjuta_shell_get_interface(win, IAnjutaFileLoader, NULL);
553 	}
554 	if (!loader)
555 		return;
556 
557 	for (i = 0; i < n_files; i++)
558 	{
559 		ianjuta_file_loader_load(loader, files[i], FALSE, NULL);
560 	}
561 
562 	anjuta_application_reset_hint (ANJUTA_APPLICATION (application));
563 }
564 
565 static GActionEntry app_entries[] = {
566 	{ "new_window", on_app_new_window, NULL, NULL, NULL },
567 	{ "preferences", on_app_preferences, NULL, NULL, NULL },
568 	{ "help", on_app_manual, NULL, NULL, NULL },
569 	{ "about", on_app_about, NULL, NULL, NULL },
570 	{ "quit", on_app_quit, NULL, NULL, NULL }
571 };
572 
573 static void
anjuta_application_startup(GApplication * application)574 anjuta_application_startup (GApplication* application)
575 {
576 	AnjutaApplication *app = ANJUTA_APPLICATION (application);
577 	GtkBuilder *builder;
578 	GError *error = NULL;
579 	GtkSettings* settings = gtk_settings_get_default ();
580 	gboolean has_app_menu;
581 
582 
583 #ifdef ENABLE_NLS
584 	setlocale (LC_ALL, "");
585 	bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
586 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
587 	textdomain (GETTEXT_PACKAGE);
588 #endif
589 
590 	G_APPLICATION_CLASS (anjuta_application_parent_class)->startup (application);
591 
592 	g_object_get (G_OBJECT (settings),
593 	              "gtk-shell-shows-app-menu", &has_app_menu,
594 	              NULL);
595 	if (has_app_menu)
596 	{
597 		g_action_map_add_action_entries (G_ACTION_MAP (app),
598 		                                 app_entries,
599 		                                 G_N_ELEMENTS (app_entries),
600 		                                 app);
601 
602 		builder = gtk_builder_new ();
603 		if (!gtk_builder_add_from_file (builder,
604 		                                ANJUTA_MENU_UI_FILE,
605 		                                &error))
606 		{
607 			g_warning ("loading menu builder file: %s", error->message);
608 			g_error_free (error);
609 		}
610 		else
611 		{
612 			GMenuModel *app_menu;
613 
614 			app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
615 			gtk_application_set_app_menu (GTK_APPLICATION (application),
616 			                              app_menu);
617 		}
618 
619 		g_object_unref (builder);
620 	}
621 }
622 
623 /* GObject implementation
624  *---------------------------------------------------------------------------*/
625 
626 static void
anjuta_application_finalize(GObject * object)627 anjuta_application_finalize (GObject *object)
628 {
629 	AnjutaApplication *app = ANJUTA_APPLICATION (object);
630 
631 	if (app->priv->geometry != NULL)
632 	{
633 		g_free (app->priv->geometry);
634 		app->priv->geometry = NULL;
635 	}
636 	G_OBJECT_CLASS (anjuta_application_parent_class)->finalize (object);
637 }
638 
639 static void
anjuta_application_init(AnjutaApplication * application)640 anjuta_application_init (AnjutaApplication *application)
641 {
642 	application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application,
643 	                                                 ANJUTA_TYPE_APPLICATION,
644 	                                                 AnjutaApplicationPrivate);
645 	application->priv->proper_shutdown = FALSE;
646 	application->priv->no_files = FALSE;
647 	application->priv->no_session = FALSE;
648 	application->priv->no_splash = FALSE;
649 	application->priv->geometry = NULL;
650 }
651 
652 static void
anjuta_application_class_init(AnjutaApplicationClass * klass)653 anjuta_application_class_init (AnjutaApplicationClass *klass)
654 {
655 	GObjectClass* object_class = G_OBJECT_CLASS (klass);
656 	GApplicationClass* app_class = G_APPLICATION_CLASS (klass);
657 
658 	object_class->finalize = anjuta_application_finalize;
659 
660 	app_class->open = anjuta_application_open;
661 	app_class->local_command_line = anjuta_application_local_command_line;
662 	app_class->startup = anjuta_application_startup;
663 
664 	g_type_class_add_private (klass, sizeof (AnjutaApplicationPrivate));
665 }
666 
667 
668 
669 /* Public functions
670  *---------------------------------------------------------------------------*/
671 
672 AnjutaApplication*
anjuta_application_new(void)673 anjuta_application_new (void)
674 {
675   g_type_init ();
676 
677   return g_object_new (anjuta_application_get_type (),
678                        "application-id", "org.gnome.anjuta",
679                        "flags", G_APPLICATION_HANDLES_OPEN,
680                        NULL);
681 }
682 
683 gboolean
anjuta_application_get_proper_shutdown(AnjutaApplication * app)684 anjuta_application_get_proper_shutdown (AnjutaApplication *app)
685 {
686 	return app->priv->proper_shutdown;
687 }
688 
689 gboolean
anjuta_application_get_no_files(AnjutaApplication * app)690 anjuta_application_get_no_files (AnjutaApplication *app)
691 {
692 	return app->priv->no_files;
693 }
694 
695 gboolean
anjuta_application_get_no_session(AnjutaApplication * app)696 anjuta_application_get_no_session (AnjutaApplication *app)
697 {
698 	return app->priv->no_session;
699 }
700 
701 const gchar *
anjuta_application_get_geometry(AnjutaApplication * app)702 anjuta_application_get_geometry (AnjutaApplication *app)
703 {
704 	return app->priv->geometry;
705 }
706 
707 AnjutaWindow*
anjuta_application_create_window(AnjutaApplication * app)708 anjuta_application_create_window (AnjutaApplication *app)
709 {
710 	AnjutaPluginManager *plugin_manager;
711 	AnjutaProfileManager *profile_manager;
712 	AnjutaWindow *win;
713 	AnjutaStatus *status;
714 	AnjutaProfile *profile;
715 	gchar *profile_filename;
716 	GFile *profile_directory;
717 	GFile *session_profile;
718 	gchar *remembered_plugins;
719 	GError *error = NULL;
720 
721 	/* Initialize application */
722 	win = ANJUTA_WINDOW (anjuta_window_new (GTK_APPLICATION(app)));
723 	gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW(win),
724 	                                         FALSE);
725 	gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (win));
726 	status = anjuta_shell_get_status (ANJUTA_SHELL (win), NULL);
727 	anjuta_status_progress_add_ticks (status, 1);
728 
729 	gtk_window_set_role (GTK_WINDOW (win), "anjuta-app");
730 	gtk_window_set_auto_startup_notification(TRUE);
731 	gtk_window_set_default_icon_name ("anjuta");
732 	gtk_window_set_auto_startup_notification(FALSE);
733 
734 	if (app->priv->no_splash)
735 	{
736 		anjuta_status_disable_splash (status, TRUE);
737 	}
738 	else
739 	{
740 		gchar *im_file = NULL;
741 		im_file = anjuta_res_get_pixmap_file (ANJUTA_PIXMAP_SPLASH_SCREEN);
742 		if (im_file)
743 		{
744 			anjuta_status_set_splash (status, im_file, 100);
745 			g_free (im_file);
746 		}
747 	}
748 
749 	g_signal_connect (G_OBJECT (win), "delete_event",
750 					  G_CALLBACK (on_anjuta_delete_event), app);
751 
752 	/* Setup application framework */
753 	plugin_manager  = anjuta_shell_get_plugin_manager (ANJUTA_SHELL (win),
754 													   NULL);
755 	profile_manager = anjuta_shell_get_profile_manager (ANJUTA_SHELL (win),
756 														NULL);
757 
758 	/* Restore remembered plugins */
759 	remembered_plugins =
760 		g_settings_get_string (win->settings, ANJUTA_REMEMBERED_PLUGINS);
761 	if (remembered_plugins)
762 		anjuta_plugin_manager_set_remembered_plugins (plugin_manager,
763 													  remembered_plugins);
764 	g_free (remembered_plugins);
765 
766 	/* Prepare system profile */
767 	profile = anjuta_profile_new (ANJUTA_SYSTEM_PROFILE_NAME, plugin_manager);
768 	profile_filename = app->priv->profile == NULL ? DEFAULT_PROFILE : g_strconcat(app->priv->profile, ".profile", NULL);
769 	profile_directory = g_file_new_for_uri (PROFILE_DIRECTORY);
770 	session_profile = g_file_get_child(profile_directory, profile_filename);
771 	g_object_unref(profile_directory);
772 	anjuta_profile_add_plugins_from_xml (profile, session_profile,
773 										 TRUE, &error);
774 	if (error)
775 	{
776 		anjuta_util_dialog_error (GTK_WINDOW (win), _("Invalid profile %s: %s"), g_file_get_path (session_profile), error->message);
777 
778 		g_error_free (error);
779 		error = NULL;
780 	}
781 	g_object_unref (session_profile);
782 	anjuta_profile_manager_freeze (profile_manager);
783 	anjuta_profile_manager_push (profile_manager, profile, &error);
784 	if (error)
785 	{
786 		anjuta_util_dialog_error (GTK_WINDOW (win), "%s", error->message);
787 		g_error_free (error);
788 		error = NULL;
789 	}
790 
791 	/* Prepare user profile */
792 	profile = anjuta_profile_new (USER_PROFILE_NAME, plugin_manager);
793 	session_profile = anjuta_util_get_user_cache_file (profile_filename, NULL);
794 	if (g_file_query_exists (session_profile, NULL))
795 	{
796 		anjuta_profile_add_plugins_from_xml (profile, session_profile,
797 											 FALSE, &error);
798 		if (error)
799 		{
800 			anjuta_util_dialog_error (GTK_WINDOW (win), "%s", error->message);
801 			g_error_free (error);
802 			error = NULL;
803 		}
804 	}
805 	anjuta_profile_set_sync_file (profile, session_profile);
806 	g_object_unref (session_profile);
807 	if (profile_filename != DEFAULT_PROFILE) g_free (profile_filename);
808 
809 	/* Load profile */
810 	anjuta_profile_manager_push (profile_manager, profile, &error);
811 	if (error)
812 	{
813 		anjuta_util_dialog_error (GTK_WINDOW (win), "%s", error->message);
814 		g_error_free (error);
815 		error = NULL;
816 	}
817 
818 	/* Prepare for session save and load on profile change */
819 	g_signal_connect (profile, "scoped", G_CALLBACK (on_profile_scoped), win);
820 	anjuta_profile_manager_thaw (profile_manager, &error);
821 
822 	if (error)
823 	{
824 		anjuta_util_dialog_error (GTK_WINDOW (win), "%s", error->message);
825 		g_error_free (error);
826 		error = NULL;
827 	}
828 	g_signal_connect (profile, "descoped", G_CALLBACK (on_profile_descoped), win);
829 
830 	anjuta_status_progress_tick (status, NULL, _("Loaded Session…"));
831 	anjuta_status_disable_splash (status, TRUE);
832 
833 	return win;
834 }
835