[easytag/wip/gapplication: 1/2] Subclass GApplication as EtApplication



commit b35af2cf372f2bcb4c9ad227c522272faaf511c3
Author: David King <amigadave amigadave com>
Date:   Mon Mar 11 22:09:12 2013 +0000

    Subclass GApplication as EtApplication
    
    Only handle command-line parsing for the moment. Move local instance
    command-line handling from main().

 Makefile.am       |    2 +
 src/application.c |  161 +++++++++++++++++++++++++++++++
 src/application.h |   50 ++++++++++
 src/easytag.c     |  272 ++++++++++++++++++++++++++---------------------------
 4 files changed, 346 insertions(+), 139 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index d4680fd..bcaa505 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -44,6 +44,7 @@ easytag_SOURCES = \
        src/libmpg123/mpg123.c \
        src/about.c \
        src/ape_tag.c \
+       src/application.c \
        src/bar.c \
        src/browser.c \
        src/browser.h \
@@ -89,6 +90,7 @@ easytag_headers = \
        src/libmpg123/mpg123.h \
        src/about.h \
        src/ape_tag.h \
+       src/application.h \
        src/bar.h \
        src/cddb.h \
        src/charset.h \
diff --git a/src/application.c b/src/application.c
new file mode 100644
index 0000000..abadbaf
--- /dev/null
+++ b/src/application.c
@@ -0,0 +1,161 @@
+/* EasyTAG - tag editor for audio files
+ * Copyright (C) 2013  David King <amigadave amigadave com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "application.h"
+
+#include <glib/gi18n.h>
+#include <stdlib.h>
+
+G_DEFINE_TYPE (EtApplication, et_application, G_TYPE_APPLICATION)
+
+struct _EtApplicationPrivate
+{
+    gpointer *data;
+};
+
+static void
+init_i18n (void)
+{
+#if ENABLE_NLS
+    bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+    bind_textdomain_codeset (PACKAGE_TARNAME, "UTF-8");
+    textdomain (GETTEXT_PACKAGE);
+#endif /* ENABLE_NLS */
+}
+
+static void
+display_usage (void)
+{
+/* Fix from Steve Ralston for gcc-3.2.2 */
+#ifdef G_OS_WIN32
+#define xPREFIX "c:"
+#else /* !G_OS_WIN32 */
+#define xPREFIX ""
+#endif /* !G_OS_WIN32 */
+
+    /* FIXME: Translators should not have to deal with this! */
+    g_print (_("\nUsage: easytag [option] "
+               "\n   or: easytag [directory]\n"
+               "\n"
+               "Option:\n"
+               "-------\n"
+               "-h, --help        Display this text and exit.\n"
+               "-v, --version     Print basic information and exit.\n"
+               "\n"
+               "Directory:\n"
+               "----------\n"
+               "%s/path_to/files  Use an absolute path to load,\n"
+               "path_to/files     Use a relative path.\n"
+               "\n"), xPREFIX);
+
+#undef xPREFIX
+}
+
+/*
+ * et_local_command_line:
+ * @application: the application
+ * @arguments: pointer to the argument string array
+ * @exit_status: pointer to the returned exit status
+ *
+ * Parse the local instance command-line arguments.
+ *
+ * Returns: %FALSE to indicate that the command-line arguments were not
+ *          completely handled in the local instance, or does not return
+ */
+static gboolean
+et_local_command_line (GApplication *application, gchar **arguments[],
+                       gint *exit_status)
+{
+    gint i;
+    gchar **argv;
+
+    argv = *arguments;
+    *exit_status = 0;
+    i = 1;
+
+    while (argv[i])
+    {
+        /* Exit the local instance for --help and --version. */
+        if ((strcmp (argv[i], "--version") == 0)
+            || (strcmp (argv[i], "-v") == 0))
+        {
+            g_print (PACKAGE_NAME " " PACKAGE_VERSION "\n");
+            g_print (_("Website: %s"), PACKAGE_URL "\n");
+            exit (0);
+        }
+        else if ((strcmp (argv[i], "--help") == 0)
+                 || (strcmp (argv[i], "-h") == 0))
+        {
+            display_usage ();
+            exit (0);
+        }
+        else
+        {
+            /* Assume a filename otherwise, and allow the primary instance to
+             * handle it. */
+            i++;
+        }
+    }
+
+    return FALSE;
+}
+
+static void
+et_application_finalize (GObject *object)
+{
+    G_OBJECT_CLASS (et_application_parent_class)->finalize (object);
+}
+
+static void
+et_application_init (EtApplication *application)
+{
+    application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application,
+                                                     ET_TYPE_APPLICATION,
+                                                     EtApplicationPrivate);
+}
+
+static void
+et_application_class_init (EtApplicationClass *klass)
+{
+    G_OBJECT_CLASS (klass)->finalize = et_application_finalize;
+    G_APPLICATION_CLASS (klass)->local_command_line = et_local_command_line;
+
+    g_type_class_add_private (klass, sizeof (EtApplicationPrivate));
+}
+
+/*
+ * et_application_new:
+ *
+ * Create a new EtApplication instance and initialise internationalization.
+ *
+ * Returns: a new #EtApplication
+ */
+EtApplication *
+et_application_new ()
+{
+    init_i18n ();
+#if !GLIB_CHECK_VERSION (2, 35, 1)
+    g_type_init ();
+#endif /* !GLIB_CHECK_VERSION (2, 35, 1) */
+
+    return g_object_new (et_application_get_type (), "application-id",
+                         "org.gnome.EasyTAG", "flags",
+                         G_APPLICATION_FLAGS_NONE, NULL);
+}
diff --git a/src/application.h b/src/application.h
new file mode 100644
index 0000000..61ab63f
--- /dev/null
+++ b/src/application.h
@@ -0,0 +1,50 @@
+/* EasyTAG - tag editor for audio files
+ * Copyright (C) 2013  David King <amigadave amigadave com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef ET_APPLICATION_H_
+#define ET_APPLICATION_H_
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define ET_TYPE_APPLICATION (et_application_get_type ())
+
+typedef struct _EtApplication EtApplication;
+typedef struct _EtApplicationClass EtApplicationClass;
+typedef struct _EtApplicationPrivate EtApplicationPrivate;
+
+struct _EtApplication
+{
+    /*< private >*/
+    GApplication parent_instance;
+    EtApplicationPrivate *priv;
+};
+
+struct _EtApplicationClass
+{
+    /*< private >*/
+    GApplicationClass parent_class;
+};
+
+GType et_application_get_type (void);
+EtApplication *et_application_new (void);
+
+G_END_DECLS
+
+#endif /* !ET_APPLICATION_H_ */
diff --git a/src/easytag.c b/src/easytag.c
index f4aac52..d30a026 100644
--- a/src/easytag.c
+++ b/src/easytag.c
@@ -41,6 +41,7 @@
 
 #include "gtk2_compat.h"
 #include "easytag.h"
+#include "application.h"
 #include "browser.h"
 #include "log.h"
 #include "misc.h"
@@ -121,8 +122,6 @@ static gint Save_List_Of_Files (GList *etfilelist,
 static gint Delete_Selected_Files_With_Answer (void);
 static gboolean Copy_File (const gchar *fileold, const gchar *filenew);
 
-static void Display_Usage (void) G_GNUC_NORETURN;
-
 static void Init_Load_Default_Dir (void);
 static void EasyTAG_Exit (void);
 
@@ -166,14 +165,131 @@ setup_sigchld (void)
 }
 #endif /* !G_OS_WIN32 */
 
+/*
+ * command_line:
+ * @application: the application
+ * @command_line: the command line to process
+ * @user_data: user data set when the signal handler was connected
+ *
+ * Handle the command-line arguments passed to the primary instance. The local
+ * instance arguments are handled in EtApplication.
+ *
+ * Returns: the exit status to be passed to the calling process
+ */
+static gint
+command_line (EtApplication *application,
+              GApplicationCommandLine *command_line, gpointer user_data)
+{
+    gchar **argv;
+    gint argc;
+
+    argv = g_application_command_line_get_arguments (command_line, &argc);
+
+    /* Check given arguments */
+    if (argc > 1)
+    {
+        /* TODO: Replace this mess with GFile. */
+        struct stat statbuf;
+        gchar *path2check = NULL, *path2check_tmp = NULL;
+        gint resultstat;
+        gchar **pathsplit;
+        gint ps_index = 0;
+
+        /* Check if relative or absolute path */
+        if (g_path_is_absolute(argv[1]))
+        {
+            path2check = g_strdup(argv[1]);
+        }
+        else
+        {
+            gchar *curdir = g_get_current_dir();
+            path2check = g_strconcat(g_get_current_dir(),G_DIR_SEPARATOR_S,argv[1],NULL);
+            g_free(curdir);
+        }
+
+#ifdef G_OS_WIN32
+        ET_Win32_Path_Replace_Slashes(path2check);
+#endif /* G_OS_WIN32 */
+
+        /* Check if contains hidden directories. */
+        pathsplit = g_strsplit(path2check,G_DIR_SEPARATOR_S,0);
+        g_free(path2check);
+        path2check = NULL;
+
+        /* Browse the list to build again the path. */
+        /* FIXME: Should manage directory ".." in path. */
+        while (pathsplit[ps_index])
+        {
+            /* Activate hidden directories in browser if path contains a dir
+             * like ".hidden_dir". */
+            if ( (g_ascii_strcasecmp (pathsplit[ps_index],"..")   != 0)
+            &&   (g_ascii_strncasecmp(pathsplit[ps_index],".", 1) == 0)
+            &&   (strlen(pathsplit[ps_index]) > 1) )
+                BROWSE_HIDDEN_DIR = 1;
+                /* If user saves the config for this session, this value will
+                 * be saved to 1. */
+
+            if (pathsplit[ps_index]
+            && g_ascii_strcasecmp(pathsplit[ps_index],".") != 0
+            && g_ascii_strcasecmp(pathsplit[ps_index],"")  != 0)
+            {
+                if (path2check)
+                {
+                    path2check_tmp = g_strconcat(path2check,G_DIR_SEPARATOR_S,pathsplit[ps_index],NULL);
+                }else
+                {
+#ifdef G_OS_WIN32
+                    /* Build a path starting with the drive letter. */
+                    path2check_tmp = g_strdup(pathsplit[ps_index]);
+#else /* !G_OS_WIN32 */
+                    path2check_tmp = g_strconcat(G_DIR_SEPARATOR_S,pathsplit[ps_index],NULL);
+#endif /* !G_OS_WIN32 */
+
+                }
+
+                path2check = g_strdup(path2check_tmp);
+                g_free(path2check_tmp);
+            }
+            ps_index++;
+        }
+
+        g_strfreev (pathsplit);
+
+        /* Check if file or directory. */
+        resultstat = stat(path2check,&statbuf);
+        if (resultstat==0 && S_ISDIR(statbuf.st_mode))
+        {
+            INIT_DIRECTORY = g_strdup(path2check);
+        }else if (resultstat==0 && S_ISREG(statbuf.st_mode))
+        {
+            /* When passing a file, we load only the directory. */
+            INIT_DIRECTORY = g_path_get_dirname(path2check);
+        }else
+        {
+            g_application_command_line_printerr (command_line,
+                                                 _("Unknown parameter or path '%s'\n"),
+                                                 argv[1]);
+            g_free (path2check);
+            g_strfreev (argv);
+            return 1;
+        }
+        g_free(path2check);
+    }
+
+    g_strfreev (argv);
+
+    return 0;
+}
+
 /********
  * Main *
  ********/
 int main (int argc, char *argv[])
 {
+    EtApplication *application;
+    gint status;
     GtkWidget *MainVBox;
     GtkWidget *HBox, *VBox;
-    struct stat statbuf;
     //GError *error = NULL;
 
 
@@ -187,20 +303,24 @@ int main (int argc, char *argv[])
     setup_sigchld ();
 #endif /* !G_OS_WIN32 */
 
-#ifdef ENABLE_NLS
-    bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
-    bind_textdomain_codeset(PACKAGE_TARNAME, "UTF-8");
-    textdomain(GETTEXT_PACKAGE);
-    /* Initialize i18n support */
-    //gtk_set_locale();
-#endif
+    INIT_DIRECTORY = NULL;
+
+    /* FIXME: Move remaining initialisation code into EtApplication. */
+    application = et_application_new ();
+    g_signal_connect (application, "command-line", G_CALLBACK (command_line),
+                      NULL);
+    status = g_application_run (G_APPLICATION (application), argc, argv);
+    g_object_unref (application);
+    if (status != 0)
+    {
+        return status;
+    }
+
     Charset_Insert_Locales_Init();
 
     /* Initialize GTK */
     gtk_init(&argc, &argv);
 
-    INIT_DIRECTORY = NULL;
-
     /* Starting messages */
     Log_Print(LOG_OK,_("Starting EasyTAG version %s (PID: %d)…"),PACKAGE_VERSION,getpid());
 #ifdef ENABLE_MP3
@@ -235,98 +355,6 @@ int main (int argc, char *argv[])
     Read_Config();
     /* Display_Config(); // <- for debugging */
 
-    /* Check given arguments */
-    if (argc>1)
-    {
-        if ( (strcmp(argv[1],"--version")==0) || (strcmp(argv[1],"-v")==0) ) // Query version
-        {
-            g_print (PACKAGE_NAME " " PACKAGE_VERSION "\n");
-            g_print (_("Website: %s"), PACKAGE_URL"\n");
-            exit (0);
-        }else if ( (strcmp(argv[1],"--help")==0) || (strcmp(argv[1],"-h")==0) ) // Query help
-        {
-            Display_Usage();
-        }else
-        {
-            gchar *path2check = NULL, *path2check_tmp = NULL;
-            gint resultstat;
-            gchar **pathsplit;
-            gint ps_index = 0;
-
-            // Check if relative or absolute path
-            if (g_path_is_absolute(argv[1])) // Passed an absolute path
-            {
-                path2check = g_strdup(argv[1]);
-            }else                            // Passed a relative path
-            {
-                gchar *curdir = g_get_current_dir();
-                path2check = g_strconcat(g_get_current_dir(),G_DIR_SEPARATOR_S,argv[1],NULL);
-                g_free(curdir);
-            }
-
-#ifdef G_OS_WIN32
-            ET_Win32_Path_Replace_Slashes(path2check);
-#endif /* G_OS_WIN32 */
-
-            // Check if contains hidden directories
-            pathsplit = g_strsplit(path2check,G_DIR_SEPARATOR_S,0);
-            g_free(path2check);
-            path2check = NULL;
-
-            // Browse the list to build again the path
-            //FIX ME : Should manage directory ".." in path
-            while (pathsplit[ps_index])
-            {
-                // Activate hidden directories in browser if path contains a dir like ".hidden_dir"
-                if ( (g_ascii_strcasecmp (pathsplit[ps_index],"..")   != 0)
-                &&   (g_ascii_strncasecmp(pathsplit[ps_index],".", 1) == 0)
-                &&   (strlen(pathsplit[ps_index]) > 1) )
-                    BROWSE_HIDDEN_DIR = 1; // If user saves the config for this session, this value will be 
saved to 1
-
-                if (pathsplit[ps_index]
-                && g_ascii_strcasecmp(pathsplit[ps_index],".") != 0
-                && g_ascii_strcasecmp(pathsplit[ps_index],"")  != 0)
-                {
-                    if (path2check)
-                    {
-                        path2check_tmp = g_strconcat(path2check,G_DIR_SEPARATOR_S,pathsplit[ps_index],NULL);
-                    }else
-                    {
-#ifdef G_OS_WIN32
-                        // Build a path starting with the drive letter
-                        path2check_tmp = g_strdup(pathsplit[ps_index]);
-#else /* !G_OS_WIN32 */
-                        path2check_tmp = g_strconcat(G_DIR_SEPARATOR_S,pathsplit[ps_index],NULL);
-#endif /* !G_OS_WIN32 */
-
-                    }
-
-                    path2check = g_strdup(path2check_tmp);
-                    g_free(path2check_tmp);
-                }
-                ps_index++;
-            }
-
-            g_strfreev (pathsplit);
-
-            // Check if file or directory
-            resultstat = stat(path2check,&statbuf);
-            if (resultstat==0 && S_ISDIR(statbuf.st_mode))       // Directory
-            {
-                INIT_DIRECTORY = g_strdup(path2check);
-            }else if (resultstat==0 && S_ISREG(statbuf.st_mode)) // File
-            {
-                // When passing a file, we load only the directory
-                INIT_DIRECTORY = g_path_get_dirname(path2check);
-            }else
-            {
-                g_print(_("Unknown parameter or path '%s'\n"),argv[1]);
-                g_free (path2check);
-                Display_Usage();
-            }
-            g_free(path2check);
-        }
-    }
 
 
     /* Initialization */
@@ -426,7 +454,7 @@ int main (int argc, char *argv[])
 
     /* Enter the event loop */
     gtk_main ();
-    return 0;
+    return status;
 }
 
 
@@ -4915,40 +4943,6 @@ signal_to_string (gint signal)
 
 
 /*
- * Display usage information
- */
-static void
-Display_Usage (void)
-{
-    // Fix from Steve Ralston for gcc-3.2.2
-#ifdef G_OS_WIN32
-#define xPREFIX "c:"
-#else /* !G_OS_WIN32 */
-#define xPREFIX ""
-#endif /* !G_OS_WIN32 */
-
-    g_print(_("\nUsage: easytag [option] "
-              "\n   or: easytag [directory]\n"
-              "\n"
-              "Option:\n"
-              "-------\n"
-              "-h, --help        Display this text and exit.\n"
-              "-v, --version     Print basic information and exit.\n"
-              "\n"
-              "Directory:\n"
-              "----------\n"
-              "%s/path_to/files  Use an absolute path to load,\n"
-              "path_to/files     Use a relative path.\n"
-              "\n"),xPREFIX);
-
-#undef xPREFIX
-
-    exit(0);
-}
-
-
-
-/*
  * Exit the program
  */
 static void


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