[gedit/wip/gtkapp: 7/14] Move command line handling to the GeditApp



commit 6ec70bf63cc54590941fbaf5e3ebb76362134871
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Fri May 11 13:34:42 2012 +0200

    Move command line handling to the GeditApp

 gedit/Makefile.am          |    2 -
 gedit/gedit-app.c          |  411 +++++++++++++++++++++++++++++++++++++++-
 gedit/gedit-command-line.c |  447 --------------------------------------------
 gedit/gedit-command-line.h |   86 ---------
 gedit/gedit.c              |   18 --
 5 files changed, 405 insertions(+), 559 deletions(-)
---
diff --git a/gedit/Makefile.am b/gedit/Makefile.am
index 282c22b..8a99a29 100644
--- a/gedit/Makefile.am
+++ b/gedit/Makefile.am
@@ -102,7 +102,6 @@ NOINST_H_FILES =			\
 	gedit-cell-renderer-button.h	\
 	gedit-close-button.h		\
 	gedit-close-confirmation-dialog.h \
-	gedit-command-line.h		\
 	gedit-dirs.h			\
 	gedit-document-input-stream.h	\
 	gedit-document-loader.h		\
@@ -176,7 +175,6 @@ libgedit_c_files =			\
 	gedit-cell-renderer-button.c	\
 	gedit-close-button.c		\
 	gedit-close-confirmation-dialog.c \
-	gedit-command-line.c		\
 	gedit-commands-documents.c	\
 	gedit-commands-edit.c		\
 	gedit-commands-file.c		\
diff --git a/gedit/gedit-app.c b/gedit/gedit-app.c
index 1f0902c..179a974 100644
--- a/gedit/gedit-app.c
+++ b/gedit/gedit-app.c
@@ -34,11 +34,16 @@
 
 #include <string.h>
 #include <unistd.h>
+#include <stdlib.h>
 
 #include <glib/gi18n.h>
 #include <libpeas/peas-extension-set.h>
 #include <gtksourceview/gtksourcestyleschememanager.h>
 
+#ifdef ENABLE_INTROSPECTION
+#include <girepository.h>
+#endif
+
 #include "gedit-app.h"
 #include "gedit-commands.h"
 #include "gedit-notebook.h"
@@ -89,11 +94,116 @@ struct _GeditAppPrivate
 
 static GeditApp *app_instance = NULL;
 
+static gboolean help = FALSE;
+static gboolean version = FALSE;
+static gboolean list_encodings = FALSE;
+static gchar *encoding_charset = NULL;
+static gboolean new_window = FALSE;
+static gboolean new_document = FALSE;
+static gchar *geometry = NULL;
+static gboolean wait = FALSE;
+static gboolean background = FALSE;
+static gboolean standalone = FALSE;
+static gchar **remaining_args = NULL;
+static const GeditEncoding *encoding = NULL;
+
+static const GOptionEntry options[] =
+{
+	/* Help */
+	{
+		"help", '?', 0, G_OPTION_ARG_NONE, &help,
+		N_("Show the application's help"), NULL
+	},
+
+	/* Version */
+	{
+		"version", 'V', 0, G_OPTION_ARG_NONE, &version,
+		N_("Show the application's version"), NULL
+	},
+
+	/* List available encodings */
+	{
+		"list-encodings", '\0', 0, G_OPTION_ARG_NONE, &list_encodings,
+		N_("Display list of possible values for the encoding option"),
+		NULL
+	},
+
+	/* Encoding */
+	{
+		"encoding", '\0', 0, G_OPTION_ARG_STRING,
+		&encoding_charset,
+		N_("Set the character encoding to be used to open the files listed on the command line"),
+		N_("ENCODING")
+	},
+
+	/* Open a new window */
+	{
+		"new-window", '\0', 0, G_OPTION_ARG_NONE,
+		&new_window,
+		N_("Create a new top-level window in an existing instance of gedit"),
+		NULL
+	},
+
+	/* Create a new empty document */
+	{
+		"new-document", '\0', 0, G_OPTION_ARG_NONE,
+		&new_document,
+		N_("Create a new document in an existing instance of gedit"),
+		NULL
+	},
+
+	/* Window geometry */
+	{
+		"geometry", 'g', 0, G_OPTION_ARG_STRING,
+		&geometry,
+		N_("Set the size and position of the window (WIDTHxHEIGHT+X+Y)"),
+		N_("GEOMETRY")
+	},
+
+	/* Wait for closing documents */
+	{
+		"wait", 'w', 0, G_OPTION_ARG_NONE,
+		&wait,
+		N_("Open files and block process until files are closed"),
+		NULL
+	},
+
+	/* Run in the background */
+	{
+		"background", 'b', 0, G_OPTION_ARG_NONE,
+		&background,
+		N_("Run gedit in the background"),
+		NULL
+	},
+
+	/* New instance */
+	{
+		"standalone", 's', 0, G_OPTION_ARG_NONE,
+		&standalone,
+		N_("Run gedit in standalone mode"),
+		NULL
+	},
+
+	/* collects file arguments */
+	{
+		G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY,
+		&remaining_args,
+		NULL,
+		N_("[FILE...] [+LINE[:COLUMN]]")
+	},
+
+	{NULL}
+};
+
 G_DEFINE_ABSTRACT_TYPE(GeditApp, gedit_app, GTK_TYPE_APPLICATION)
 
 static void
 gedit_app_finalize (GObject *object)
 {
+	g_free (encoding_charset);
+	g_strfreev (remaining_args);
+	g_free (geometry);
+
 	G_OBJECT_CLASS (gedit_app_parent_class)->finalize (object);
 }
 
@@ -260,16 +370,303 @@ gedit_app_startup (GApplication *application)
 }
 
 static void
+get_line_column_position (const gchar      *arg,
+                          gint             *line,
+                          gint             *column)
+{
+	gchar **split;
+
+	split = g_strsplit (arg, ":", 2);
+
+	if (split != NULL)
+	{
+		if (split[0] != NULL)
+		{
+			*line = atoi (split[0]);
+		}
+
+		if (split[1] != NULL)
+		{
+			*column = atoi (split[1]);
+		}
+	}
+
+	g_strfreev (split);
+}
+
+static void
 gedit_app_activate (GApplication *application)
 {
+	GeditApp *app = GEDIT_APP (application);
+	GSList *file_list = NULL;
+	gint line_position = 0;
+	gint column_position = 0;
 	GeditWindow *window;
+	gboolean doc_created = FALSE;
+
+	/* XXX: have it global and move this to the command line parsing? */
+	if (remaining_args)
+	{
+		gint i;
+
+		for (i = 0; remaining_args[i]; i++)
+		{
+			if (*remaining_args[i] == '+')
+			{
+				if (*(remaining_args[i] + 1) == '\0')
+				{
+					/* goto the last line of the document */
+					line_position = G_MAXINT;
+					column_position = 0;
+				}
+				else
+				{
+					get_line_column_position (remaining_args[i] + 1,
+					                          &line_position,
+					                          &column_position);
+				}
+			}
+			else
+			{
+				GFile *file;
+
+				file = g_file_new_for_commandline_arg (remaining_args[i]);
+				file_list = g_slist_prepend (file_list, file);
+			}
+		}
+
+		file_list = g_slist_reverse (file_list);
+	}
+
+	if (app->priv->active_window == NULL)
+	{
+		gedit_debug_message (DEBUG_APP, "Create main window");
+		window = gedit_app_create_window (app, NULL);
+
+		gedit_debug_message (DEBUG_APP, "Show window");
+		gtk_widget_show (GTK_WIDGET (window));
+	}
+	else
+	{
+		window = app->priv->active_window;
+	}
+
+	if (geometry)
+	{
+		gtk_window_parse_geometry (GTK_WINDOW (window),
+		                           geometry);
+	}
+
+	if (file_list != NULL)
+	{
+		GSList *loaded;
+
+		gedit_debug_message (DEBUG_APP, "Load files");
+		loaded = _gedit_cmd_load_files_from_prompt (window,
+		                                            file_list,
+		                                            encoding,
+		                                            line_position,
+		                                            column_position);
+
+		doc_created = loaded != NULL;
+		g_slist_free (loaded);
+	}
+
+	if (!doc_created || new_document)
+	{
+		gedit_debug_message (DEBUG_APP, "Create tab");
+		gedit_window_create_tab (window, TRUE);
+	}
 
-	gedit_debug_message (DEBUG_APP, "Create main window");
-	window = gedit_app_create_window (GEDIT_APP (application), NULL);
-	gtk_application_add_window (GTK_APPLICATION (application), GTK_WINDOW (window));
+	g_slist_free_full (file_list, g_object_unref);
+}
+
+static GOptionContext *
+get_option_context (gboolean primary)
+{
+	GOptionContext *context;
+
+	context = g_option_context_new (_("- Edit text files"));
+	g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
+	g_option_context_add_group (context, gtk_get_option_group (TRUE));
+
+#ifdef ENABLE_INTROSPECTION
+	g_option_context_add_group (context, g_irepository_get_option_group ());
+#endif
+
+	/* Default help handling calls exit() and we do not want that
+	 * on the primary instance */
+	g_option_context_set_help_enabled (context, !primary);
+
+	return context;
+}
+
+static gint
+gedit_app_command_line (GApplication            *application,
+                        GApplicationCommandLine *command_line)
+{
+	GOptionContext *context;
+	GError *error = NULL;
+	gint argc;
+	gchar **argv;
+	gchar **argv_tofree;
+	gint i;
+
+	/* reset values */
+	g_free (encoding_charset);
+	g_strfreev (remaining_args);
+	g_free (geometry);
+
+	help = FALSE;
+	version = FALSE;
+	list_encodings = FALSE;
+	encoding_charset = NULL;
+	new_window = FALSE;
+	new_document = FALSE;
+	geometry = NULL;
+	wait = FALSE;
+	background = FALSE;
+	standalone = FALSE;
+	remaining_args = NULL;
+	encoding = NULL;
+
+	argv = g_application_command_line_get_arguments (command_line, &argc);
+
+	/* We have to make an extra copy of the array, since g_option_context_parse()
+	 * assumes that it can remove strings from the array without freeing them.
+	 */
+	argv_tofree = g_new (gchar*, argc + 1);
+	for (i = 0; i <= argc; i++)
+	{
+		argv[i] = argv[i];
+	}
+
+	context = get_option_context (TRUE);
+	if (!g_option_context_parse (context, &argc, &argv, &error))
+	{
+		g_application_command_line_print (command_line,
+		                                  _("%s\nRun '%s --help' to see a full list of available command line options.\n"),
+		                                  error->message, argv[0]);
+
+		g_error_free (error);
+		g_application_command_line_set_exit_status (command_line, 1);
+	}
+	else
+	{
+		/* Parse encoding */
+		if (encoding_charset)
+		{
+			encoding = gedit_encoding_get_from_charset (encoding_charset);
+
+			if (encoding == NULL)
+			{
+				g_application_command_line_print (command_line,
+				                                  _("%s: invalid encoding."),
+				                                  encoding_charset);
+			}
+
+			g_free (encoding_charset);
+		}
+
+		gedit_app_activate (application);
+	}
+
+	g_option_context_free (context);
+	g_free (argv_tofree);
+
+	return 0;
+}
+
+static gboolean
+gedit_app_local_command_line (GApplication   *application,
+                              gchar        ***arguments,
+                              gint           *exit_status)
+{
+	GOptionContext *context;
+	GError *error = NULL;
+	gint argc;
+	gchar **argv;
+	gint i;
+
+	/* We have to make an extra copy of the array, since g_option_context_parse()
+	 * assumes that it can remove strings from the array without freeing them.
+	 */
+	argc = g_strv_length (*arguments);
+	argv = g_new (gchar*, argc + 1);
+	for (i = 0; i <= argc; i++)
+	{
+		argv[i] = (*arguments)[i];
+	}
+
+	*exit_status = 0;
+
+	context = get_option_context (FALSE);
+	if (!g_option_context_parse (context, &argc, &argv, &error))
+	{
+		g_print (_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
+		         error->message, argv[0]);
+
+		g_error_free (error);
+		*exit_status = 1;
+
+		return TRUE;
+	}
+	else if (help)
+	{
+		gchar *text = g_option_context_get_help(context, FALSE, NULL);
+		g_print ("%s\n", text);
+		g_free (text);
+
+		return TRUE;
+	}
+	else if (version)
+	{
+		g_print ("%s - Version %s\n", g_get_application_name (), VERSION);
+
+		return TRUE;
+	}
+	else if (list_encodings)
+	{
+		gint i = 0;
+		const GeditEncoding *enc;
+
+		while ((enc = gedit_encoding_get_from_index (i)) != NULL)
+		{
+			g_print ("%s\n", gedit_encoding_get_charset (enc));
+
+			++i;
+		}
+
+		return TRUE;
+	}
+	else if (standalone)
+	{
+		GApplicationFlags old_flags;
+
+		old_flags = g_application_get_flags (application);
+		g_application_set_flags (application, old_flags | G_APPLICATION_NON_UNIQUE);
+	}
 
-	gedit_debug_message (DEBUG_APP, "Show window");
-	gtk_widget_show (GTK_WIDGET (window));
+	g_option_context_free (context);
+	g_free (encoding_charset);
+	g_strfreev (remaining_args);
+	g_free (geometry);
+	g_free (argv);
+
+	help = FALSE;
+	version = FALSE;
+	list_encodings = FALSE;
+	encoding_charset = NULL;
+	new_window = FALSE;
+	new_document = FALSE;
+	geometry = NULL;
+	wait = FALSE;
+	background = FALSE;
+	standalone = FALSE;
+	remaining_args = NULL;
+	encoding = NULL;
+
+	return G_APPLICATION_CLASS (gedit_app_parent_class)->local_command_line (application, arguments, exit_status);
 }
 
 static gboolean
@@ -572,6 +969,8 @@ gedit_app_class_init (GeditAppClass *klass)
 
 	app_class->startup = gedit_app_startup;
 	app_class->activate = gedit_app_activate;
+	app_class->command_line = gedit_app_command_line;
+	app_class->local_command_line = gedit_app_local_command_line;
 	app_class->shutdown = gedit_app_shutdown;
 
 	klass->last_window_destroyed = gedit_app_last_window_destroyed_impl;
@@ -748,7 +1147,7 @@ gedit_app_get_default (void)
 
 	return GEDIT_APP (g_object_new (type,
 	                                "application-id", "org.gnome.Gedit",
-	                                // FIXME: should be HANDLES_COMMAND_LINE
+	                                "flags", G_APPLICATION_HANDLES_COMMAND_LINE,
 	                                NULL));
 }
 
diff --git a/gedit/gedit.c b/gedit/gedit.c
index f240cdd..b74c258 100644
--- a/gedit/gedit.c
+++ b/gedit/gedit.c
@@ -87,24 +87,6 @@ main (int argc, char *argv[])
 	g_free (metadata_filename);
 #endif
 
-	/* FIXME: This is needed if not we get a crash building with introspection */
-#ifdef ENABLE_INTROSPECTION
-	GOptionContext *context;
-	GError *error = NULL;
-
-	context = g_option_context_new (_("- Edit text files"));
-	g_option_context_add_group (context, g_irepository_get_option_group ());
-	if (!g_option_context_parse (context, &argc, &argv, &error))
-	{
-		g_print(_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
-		        error->message, argv[0]);
-
-		g_error_free (error);
-		return 1;
-	}
-	g_option_context_free (context);
-#endif
-
 	/* Init plugins en thegine */
 	gedit_debug_message (DEBUG_APP, "Init plugins");
 	engine = gedit_plugins_engine_get_default ();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]