[gtranslator] Convert GtrApplication into an UniqueApp using libunique.



commit 46d23f8db41b78f3709dfef6b0d4df84d66ecc10
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Thu Feb 11 18:43:18 2010 +0100

    Convert GtrApplication into an UniqueApp using libunique.

 configure.ac          |    1 +
 src/gtr-application.c |  223 ++++++++++++++++++++++++++++---------------------
 src/gtr-application.h |   65 ++++++--------
 src/gtr-window.c      |  178 ++++++++++++++++++++++-----------------
 src/main.c            |  173 +++++++++++++++++++++++++++++---------
 5 files changed, 388 insertions(+), 252 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 04b2470..58d6c86 100644
--- a/configure.ac
+++ b/configure.ac
@@ -100,6 +100,7 @@ PKG_CHECK_MODULES(GTRANSLATOR, [
 	gtksourceview-2.0 >= $SOURCEVIEW_REQUIRED
 	gdl-1.0 >= $GDL_REQUIRED
 	gconf-2.0 >= $GCONF_REQUIRED
+	unique-1.0
 ])
 
 AC_SUBST(GTRANSLATOR_CFLAGS)
diff --git a/src/gtr-application.c b/src/gtr-application.c
index bf624b8..e8eab01 100644
--- a/src/gtr-application.c
+++ b/src/gtr-application.c
@@ -27,6 +27,7 @@
 #include "dialogs/gtr-assistant.h"
 #include "gtr-actions.h"
 #include "gtr-application.h"
+#include "gtr-debug.h"
 #include "gtr-dirs.h"
 #include "gtr-prefs-manager.h"
 #include "gtr-prefs-manager-app.h"
@@ -47,7 +48,7 @@
 					 GTR_TYPE_APPLICATION,     \
 					 GtrApplicationPrivate))
 
-G_DEFINE_TYPE (GtrApplication, gtr_application, G_TYPE_OBJECT)
+G_DEFINE_TYPE (GtrApplication, gtr_application, UNIQUE_TYPE_APP)
 
 struct _GtrApplicationPrivate
 {
@@ -66,9 +67,37 @@ struct _GtrApplicationPrivate
 
   GtrTranslationMemory *tm;
 
-  gboolean first_run;
+  guint first_run : 1;
 };
 
+static GtrApplication *instance = NULL;
+
+static gboolean
+ensure_user_config_dir (void)
+{
+  gchar *config_dir;
+  gboolean ret = TRUE;
+  gint res;
+
+  config_dir = gtr_dirs_get_user_config_dir ();
+  if (config_dir == NULL)
+    {
+      g_warning ("Could not get config directory\n");
+      return FALSE;
+    }
+
+  res = g_mkdir_with_parents (config_dir, 0755);
+  if (res < 0)
+    {
+      g_warning ("Could not create config directory\n");
+      ret = FALSE;
+    }
+
+  g_free (config_dir);
+
+  return ret;
+}
+
 static void
 load_accels (void)
 {
@@ -104,75 +133,52 @@ on_window_delete_event_cb (GtrWindow * window,
 }
 
 static void
-on_window_destroy_cb (GtrWindow * window, GtrApplication * app)
+set_active_window (GtrApplication *app,
+                   GtrWindow      *window)
 {
-  save_accels ();
-  //if(app->priv->active_window == NULL)
-  g_object_unref (app);
+  app->priv->active_window = window;
 }
 
 static void
-gtr_application_init (GtrApplication * application)
+on_window_destroy_cb (GtrWindow *window, GtrApplication *app)
+{
+  app->priv->windows = g_list_remove (app->priv->windows,
+                                      window);
+
+  if (window == app->priv->active_window)
+    set_active_window (app, app->priv->windows != NULL ? app->priv->windows->data : NULL);
+
+  if(app->priv->active_window == NULL)
+    {
+      ensure_user_config_dir ();
+      save_accels ();
+      gtk_main_quit ();
+    }
+}
+
+static void
+gtr_application_init (GtrApplication *application)
 {
   gchar *gtr_folder;
   gchar *path_default_gtr_toolbar;
   gchar *profiles_file;
   gchar *dir;
-
   GtrApplicationPrivate *priv;
 
   application->priv = GTR_APPLICATION_GET_PRIVATE (application);
   priv = application->priv;
 
+  priv->active_window = NULL;
   priv->windows = NULL;
   priv->last_dir = NULL;
   priv->first_run = FALSE;
   priv->profiles = NULL;
 
-  /*
-   * Creating config folder
-   */
-  gtr_folder = gtr_dirs_get_user_config_dir ();
-
-  if (!g_file_test (gtr_folder, G_FILE_TEST_IS_DIR))
-    {
-      GFile *file;
-      GError *error = NULL;
-
-      file = g_file_new_for_path (gtr_folder);
-
-      if (g_file_test (gtr_folder, G_FILE_TEST_IS_REGULAR))
-        {
-          if (!g_file_delete (file, NULL, &error))
-            {
-              g_warning ("There was an error deleting the "
-                         "old gtranslator file: %s", error->message);
-              g_error_free (error);
-              g_object_unref (file);
-              g_free (gtr_folder);
-              gtr_application_shutdown (application);
-            }
-        }
-
-      if (!g_file_make_directory (file, NULL, &error))
-        {
-          g_warning
-            ("There was an error making the gtranslator config directory: %s",
-             error->message);
-
-          g_error_free (error);
-          g_object_unref (file);
-          g_free (gtr_folder);
-          gtr_application_shutdown (application);
-        }
-
-      priv->first_run = TRUE;
-      g_object_unref (file);
-    }
+  /* Creating config folder */
+  ensure_user_config_dir (); /* FIXME: is this really needed ? */
 
-  /*
-   * If the config folder exists but there is no profile
-   */
+  /* If the config folder exists but there is no profile */
+  gtr_folder = gtr_dirs_get_user_config_dir ();
   profiles_file = g_build_filename (gtr_folder, "profiles.xml", NULL);
   if (!g_file_test (profiles_file, G_FILE_TEST_EXISTS))
     priv->first_run = TRUE;
@@ -223,35 +229,63 @@ gtr_application_init (GtrApplication * application)
 
 
 static void
-gtr_application_finalize (GObject * object)
+gtr_application_dispose (GObject * object)
 {
   GtrApplication *app = GTR_APPLICATION (object);
 
-  if (app->priv->icon_factory)
-    g_object_unref (app->priv->icon_factory);
+  DEBUG_PRINT ("Disposing app");
 
-  g_free (app->priv->last_dir);
+  if (app->priv->icon_factory != NULL)
+    {
+      g_object_unref (app->priv->icon_factory);
+      app->priv->icon_factory = NULL;
+    }
 
   if (app->priv->tm)
-    g_object_unref (app->priv->tm);
+    {
+      g_object_unref (app->priv->tm);
+      app->priv->tm = NULL;
+    }
+
+  if (app->priv->toolbars_model)
+    {
+      g_object_unref (app->priv->toolbars_model);
+      app->priv->toolbars_model = NULL;
+    }
+
+  G_OBJECT_CLASS (gtr_application_parent_class)->dispose (object);
+}
+
+static void
+gtr_application_finalize (GObject *object)
+{
+  GtrApplication *app = GTR_APPLICATION (object);
+
+  g_free (app->priv->last_dir);
+  g_free (app->priv->toolbars_file);
 
   G_OBJECT_CLASS (gtr_application_parent_class)->finalize (object);
 }
 
 static void
-gtr_application_class_init (GtrApplicationClass * klass)
+gtr_application_class_init (GtrApplicationClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   g_type_class_add_private (klass, sizeof (GtrApplicationPrivate));
 
+  object_class->dispose = gtr_application_dispose;
   object_class->finalize = gtr_application_finalize;
 }
 
-static void
-app_weak_notify (gpointer data, GObject * where_the_app_was)
+GtrApplication *
+_gtr_application_new ()
 {
-  gtk_main_quit ();
+  instance = GTR_APPLICATION (g_object_new (GTR_TYPE_APPLICATION,
+                                            "name", "org.gnome.Gtranslator",
+                                            "startup-id", NULL, NULL));
+
+  return instance;
 }
 
 /**
@@ -264,14 +298,6 @@ app_weak_notify (gpointer data, GObject * where_the_app_was)
 GtrApplication *
 gtr_application_get_default (void)
 {
-  static GtrApplication *instance = NULL;
-
-  if (!instance)
-    {
-      instance = GTR_APPLICATION (g_object_new (GTR_TYPE_APPLICATION, NULL));
-
-      g_object_weak_ref (G_OBJECT (instance), app_weak_notify, NULL);
-    }
   return instance;
 }
 
@@ -284,14 +310,30 @@ gtr_application_get_default (void)
  * Returns: the #GtrWindow to be opened
  */
 GtrWindow *
-gtr_application_open_window (GtrApplication * app)
+gtr_application_create_window (GtrApplication *app)
 {
   GtrWindow *window;
   GdkWindowState state;
   gint w, h;
 
-  app->priv->active_window = window =
-    GTR_WINDOW (g_object_new (GTR_TYPE_WINDOW, NULL));
+  g_return_val_if_fail (GTR_IS_APPLICATION (app), NULL);
+
+  /*
+   * We need to be careful here, there is a race condition:
+   * when another gedit is launched it checks active_window,
+   * so we must do our best to ensure that active_window
+   * is never NULL when at least a window exists.
+   */
+  if (app->priv->windows == NULL)
+    {
+      window = g_object_new (GTR_TYPE_WINDOW, NULL);
+      set_active_window (app, window);
+    }
+  else
+    window = g_object_new (GTR_TYPE_WINDOW, NULL);
+
+  app->priv->windows = g_list_prepend (app->priv->windows,
+                                       window);
 
   state = gtr_prefs_manager_get_window_state ();
 
@@ -320,7 +362,7 @@ gtr_application_open_window (GtrApplication * app)
    * If it is the first run, the default directory was created in this
    * run, then we show the First run Assistant
    */
-  if (app->priv->first_run)
+  if (app->priv->first_run && app->priv->windows->next == NULL)
     gtr_show_assistant (window);
 
   return window;
@@ -354,26 +396,6 @@ _gtr_application_save_toolbars_model (GtrApplication * application)
 }
 
 /**
- * gtr_application_shutdown:
- * @app: a #GtrApplication
- * 
- * Shutdowns the application.
- */
-void
-gtr_application_shutdown (GtrApplication * app)
-{
-  if (app->priv->toolbars_model)
-    {
-      g_object_unref (app->priv->toolbars_model);
-      g_free (app->priv->toolbars_file);
-      app->priv->toolbars_model = NULL;
-      app->priv->toolbars_file = NULL;
-    }
-
-  g_object_unref (app);
-}
-
-/**
  * gtr_application_get_views:
  * @app: the #GtranslationApplication
  * @original: TRUE if you want original TextViews.
@@ -408,6 +430,8 @@ gtr_application_get_views (GtrApplication * app,
 GtrWindow *
 gtr_application_get_active_window (GtrApplication * app)
 {
+  g_return_val_if_fail (GTR_IS_APPLICATION (app), NULL);
+
   return GTR_WINDOW (app->priv->active_window);
 }
 
@@ -475,8 +499,11 @@ gtr_application_get_profiles (GtrApplication * app)
  *
  **/
 void
-gtr_application_set_profiles (GtrApplication * app, GList * profiles)
+gtr_application_set_profiles (GtrApplication *app, GList *profiles)
 {
+  g_return_if_fail (GTR_IS_APPLICATION (app));
+  g_return_if_fail (profiles != NULL);
+
   app->priv->profiles = profiles;
 }
 
@@ -489,15 +516,19 @@ gtr_application_set_profiles (GtrApplication * app, GList * profiles)
  * Registers a new @icon with the @stock_id.
  */
 void
-gtr_application_register_icon (GtrApplication * app,
-                               const gchar * icon, const gchar * stock_id)
+gtr_application_register_icon (GtrApplication *app,
+                               const gchar *icon, const gchar *stock_id)
 {
   GtkIconSet *icon_set;
-  GtkIconSource *icon_source = gtk_icon_source_new ();
+  GtkIconSource *icon_source;
   gchar *pixmaps_dir;
   gchar *path;
   GdkPixbuf *pixbuf;
 
+  g_return_if_fail (GTR_IS_APPLICATION (app));
+  g_return_if_fail (icon != NULL && stock_id != NULL);
+
+  icon_source = gtk_icon_source_new ();
   pixmaps_dir = gtr_dirs_get_pixmaps_dir ();
   path = g_build_filename (pixmaps_dir, icon, NULL);
   g_free (pixmaps_dir);
diff --git a/src/gtr-application.h b/src/gtr-application.h
index 0770519..89bd2d1 100644
--- a/src/gtr-application.h
+++ b/src/gtr-application.h
@@ -26,6 +26,7 @@
 #include <glib.h>
 #include <glib-object.h>
 #include <gtk/gtk.h>
+#include <unique/uniqueapp.h>
 
 #include "gtr-profile.h"
 #include "gtr-window.h"
@@ -51,7 +52,7 @@ typedef struct _GtrApplication GtrApplication;
 
 struct _GtrApplication
 {
-  GObject base_instance;
+  UniqueApp base_instance;
 
   /*< private > */
   GtrApplicationPrivate *priv;
@@ -64,63 +65,53 @@ typedef struct _GtrApplicationClass GtrApplicationClass;
 
 struct _GtrApplicationClass
 {
-  GObjectClass parent_class;
+  UniqueAppClass parent_class;
 };
 
 /*
  * Public methods
  */
-GType
-gtr_application_get_type (void)
-  G_GNUC_CONST;
-     GtrApplication *gtr_application_get_default (void);
+GType             gtr_application_get_type               (void)G_GNUC_CONST;
 
-     void gtr_application_shutdown (GtrApplication * app);
+GtrApplication  *_gtr_application_new                    (void);
 
-     GList *gtr_application_get_views (GtrApplication * app,
-                                       gboolean original,
-                                       gboolean translated);
+GtrApplication   *gtr_application_get_default            (void);
 
-GtrWindow * gtr_application_open_window (GtrApplication * app);
+GList *           gtr_application_get_views              (GtrApplication *app,
+                                                          gboolean        original,
+                                                          gboolean        translated);
 
-GtrWindow * gtr_application_get_active_window (GtrApplication * app);
+GtrWindow        *gtr_application_create_window          (GtrApplication *app);
 
-     const GList *
-     gtr_application_get_windows (GtrApplication * app);
+GtrWindow        *gtr_application_get_active_window      (GtrApplication *app);
 
-GtrProfile * gtr_application_get_active_profile (GtrApplication * app);
+const GList      *gtr_application_get_windows            (GtrApplication *app);
 
-     void
-     gtr_application_set_active_profile (GtrApplication *
-                                         app, GtrProfile * profile);
+GtrProfile       *gtr_application_get_active_profile     (GtrApplication *app);
 
-     GList *
-     gtr_application_get_profiles (GtrApplication * app);
+void              gtr_application_set_active_profile     (GtrApplication *app,
+                                                          GtrProfile * profile);
 
-     void
-     gtr_application_set_profiles (GtrApplication * app, GList * profiles);
+GList            *gtr_application_get_profiles           (GtrApplication *app);
 
-     void
-     gtr_application_register_icon (GtrApplication * app,
-                                    const gchar * icon,
-                                    const gchar * stock_id);
+void              gtr_application_set_profiles           (GtrApplication *app,
+                                                          GList * profiles);
 
-GObject * gtr_application_get_translation_memory (GtrApplication * app);
+void              gtr_application_register_icon          (GtrApplication *app,
+                                                          const gchar    *icon,
+                                                          const gchar    *stock_id);
 
-/* Non exported funcs */
+GObject          *gtr_application_get_translation_memory (GtrApplication *app);
 
-GObject * _gtr_application_get_toolbars_model (GtrApplication * application);
+/* Non exported funcs */
+GObject         *_gtr_application_get_toolbars_model     (GtrApplication *application);
 
-     void
-     _gtr_application_save_toolbars_model (GtrApplication * application);
+void             _gtr_application_save_toolbars_model    (GtrApplication *application);
 
-     const
-       gchar *
-     _gtr_application_get_last_dir (GtrApplication * app);
+const gchar     *_gtr_application_get_last_dir           (GtrApplication *app);
 
-     void
-     _gtr_application_set_last_dir (GtrApplication * app,
-                                    const gchar * last_dir);
+void             _gtr_application_set_last_dir           (GtrApplication *app,
+                                                          const gchar    *last_dir);
 
 G_END_DECLS
 #endif /* __APPLICATION_H__ */
diff --git a/src/gtr-window.c b/src/gtr-window.c
index 46459ec..c15ee6c 100644
--- a/src/gtr-window.c
+++ b/src/gtr-window.c
@@ -71,80 +71,81 @@ static void gtr_window_cmd_edit_toolbar (GtkAction * action,
 
 
 G_DEFINE_TYPE (GtrWindow, gtr_window, GTK_TYPE_WINDOW)
-     struct _GtrWindowPrivate
-     {
-       GtkWidget *main_box;
-
-       GtkWidget *menubar;
-       GtkWidget *view_menu;
-       GtkWidget *toolbar;
-       GtkActionGroup *always_sensitive_action_group;
-       GtkActionGroup *action_group;
-       GtkActionGroup *documents_list_action_group;
-       guint documents_list_menu_ui_id;
-
-       GtkWidget *notebook;
-       GtrTab *active_tab;
-
-       GtkWidget *dock;
-       GdlDockLayout *layout_manager;
-       GHashTable *widgets;
-
-       GtkWidget *statusbar;
-
-       GtkUIManager *ui_manager;
-       GtkRecentManager *recent_manager;
-       GtkWidget *recent_menu;
-
-       GtkWidget *tm_menu;
-
-       gint width;
-       gint height;
-       GdkWindowState window_state;
-
-       gboolean destroy_has_run:1;
-     };
-
-     enum
-     {
-       TARGET_URI_LIST = 100
-     };
-
-     static const GtkActionEntry always_sensitive_entries[] = {
-
-       {"File", NULL, N_("_File")},
-       {"Edit", NULL, N_("_Edit")},
-       {"View", NULL, N_("_View")},
-       {"Search", NULL, N_("_Search")},
-       {"Go", NULL, N_("_Go")},
-       {"Documents", NULL, N_("_Documents")},
-       {"Help", NULL, N_("_Help")},
-
-       /* File menu */
-       {"FileOpen", GTK_STOCK_OPEN, NULL, "<control>O",
-        N_("Open a PO file"),
-        G_CALLBACK (gtr_open_file_dialog)},
-       {"FileRecentFiles", NULL, N_("_Recent Files"), NULL,
-        NULL, NULL},
-       {"FileQuitWindow", GTK_STOCK_QUIT, NULL, "<control>Q",
-        N_("Quit the program"),
-        G_CALLBACK (gtr_file_quit)},
-
-       /* Edit menu */
-       {"EditToolbar", NULL, N_("T_oolbar"), NULL, NULL,
-        G_CALLBACK (gtr_window_cmd_edit_toolbar)},
-       {"EditPreferences", GTK_STOCK_PREFERENCES, NULL, NULL,
-        N_("Edit gtr preferences"),
-        G_CALLBACK (gtr_actions_edit_preferences)},
-       {"EditHeader", GTK_STOCK_PROPERTIES, N_("_Header..."), NULL, NULL,
-        G_CALLBACK (gtr_actions_edit_header)},
-
-       /* Help menu */
-       {"HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL,
-        G_CALLBACK (gtr_cmd_help_contents)},
-       {"HelpAbout", GTK_STOCK_ABOUT, NULL, NULL, NULL,
-        G_CALLBACK (gtr_about_dialog)},
-     };
+
+struct _GtrWindowPrivate
+{
+  GtkWidget *main_box;
+
+  GtkWidget *menubar;
+  GtkWidget *view_menu;
+  GtkWidget *toolbar;
+  GtkActionGroup *always_sensitive_action_group;
+  GtkActionGroup *action_group;
+  GtkActionGroup *documents_list_action_group;
+  guint documents_list_menu_ui_id;
+
+  GtkWidget *notebook;
+  GtrTab *active_tab;
+
+  GtkWidget *dock;
+  GdlDockLayout *layout_manager;
+  GHashTable *widgets;
+
+  GtkWidget *statusbar;
+
+  GtkUIManager *ui_manager;
+  GtkRecentManager *recent_manager;
+  GtkWidget *recent_menu;
+
+  GtkWidget *tm_menu;
+
+  gint width;
+  gint height;
+  GdkWindowState window_state;
+
+  gboolean destroy_has_run : 1;
+};
+
+enum
+{
+  TARGET_URI_LIST = 100
+};
+
+static const GtkActionEntry always_sensitive_entries[] = {
+
+  {"File", NULL, N_("_File")},
+  {"Edit", NULL, N_("_Edit")},
+  {"View", NULL, N_("_View")},
+  {"Search", NULL, N_("_Search")},
+  {"Go", NULL, N_("_Go")},
+  {"Documents", NULL, N_("_Documents")},
+  {"Help", NULL, N_("_Help")},
+
+  /* File menu */
+  {"FileOpen", GTK_STOCK_OPEN, NULL, "<control>O",
+   N_("Open a PO file"),
+   G_CALLBACK (gtr_open_file_dialog)},
+  {"FileRecentFiles", NULL, N_("_Recent Files"), NULL,
+   NULL, NULL},
+  {"FileQuitWindow", GTK_STOCK_QUIT, NULL, "<control>Q",
+   N_("Quit the program"),
+   G_CALLBACK (gtr_file_quit)},
+
+  /* Edit menu */
+  {"EditToolbar", NULL, N_("T_oolbar"), NULL, NULL,
+   G_CALLBACK (gtr_window_cmd_edit_toolbar)},
+  {"EditPreferences", GTK_STOCK_PREFERENCES, NULL, NULL,
+   N_("Edit gtr preferences"),
+   G_CALLBACK (gtr_actions_edit_preferences)},
+  {"EditHeader", GTK_STOCK_PROPERTIES, N_("_Header..."), NULL, NULL,
+   G_CALLBACK (gtr_actions_edit_header)},
+
+  /* Help menu */
+  {"HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL,
+   G_CALLBACK (gtr_cmd_help_contents)},
+  {"HelpAbout", GTK_STOCK_ABOUT, NULL, NULL, NULL,
+   G_CALLBACK (gtr_about_dialog)},
+};
 
 /* Normal items */
 static const GtkActionEntry entries[] = {
@@ -312,6 +313,8 @@ static void
 on_layout_dirty_notify (GObject * object,
                         GParamSpec * pspec, GtrWindow * window)
 {
+  g_return_if_fail (GTR_IS_WINDOW (window));
+
   if (!strcmp (pspec->name, "dirty"))
     {
       gboolean dirty;
@@ -378,7 +381,7 @@ remove_from_widgets_hash (gpointer name,
 static void
 on_widget_destroy (GtkWidget * widget, GtrWindow * window)
 {
-  //DEBUG_PRINT ("Widget about to be destroyed");
+  DEBUG_PRINT ("Widget about to be destroyed");
   g_hash_table_foreach_remove (window->priv->widgets,
                                remove_from_widgets_hash, widget);
 }
@@ -403,7 +406,7 @@ on_widget_remove (GtkWidget * container,
   if (g_hash_table_foreach_remove (window->priv->widgets,
                                    remove_from_widgets_hash, widget))
     {
-      //DEBUG_PRINT ("Widget removed from container");
+      DEBUG_PRINT ("Widget removed from container");
     }
 }
 
@@ -414,7 +417,7 @@ on_widget_removed_from_hash (gpointer widget)
   GtkWidget *menuitem;
   GdlDockItem *dockitem;
 
-  //DEBUG_PRINT ("Removing widget from hash");
+  DEBUG_PRINT ("Removing widget from hash");
 
   window = g_object_get_data (G_OBJECT (widget), "window-object");
   dockitem = g_object_get_data (G_OBJECT (widget), "dockitem");
@@ -1588,6 +1591,8 @@ gtr_window_dispose (GObject * object)
   GtrWindow *window = GTR_WINDOW (object);
   GtrWindowPrivate *priv = window->priv;
 
+  DEBUG_PRINT ("window dispose");
+
   if (priv->ui_manager)
     {
       g_object_unref (priv->ui_manager);
@@ -1599,6 +1604,11 @@ gtr_window_dispose (GObject * object)
       priv->action_group = NULL;
     }
 
+  /* Now that there have broken some reference loops,
+   * force collection again.
+   */
+  gtr_plugins_engine_garbage_collect (gtr_plugins_engine_get_default ());
+
   G_OBJECT_CLASS (gtr_window_parent_class)->dispose (object);
 }
 
@@ -1636,9 +1646,23 @@ gtr_window_destroy (GtkObject * object)
 
   window = GTR_WINDOW (object);
 
+  DEBUG_PRINT ("Destroy window");
+
   if (!window->priv->destroy_has_run)
     {
       save_panes_state (window);
+
+      if (window->priv->widgets)
+        {
+          g_hash_table_destroy (window->priv->widgets);
+          window->priv->widgets = NULL;
+        }
+
+      if (window->priv->layout_manager)
+        {
+          g_object_unref (window->priv->layout_manager);
+          window->priv->layout_manager = NULL;
+        }
       window->priv->destroy_has_run = TRUE;
     }
 
diff --git a/src/main.c b/src/main.c
index 64a02fd..f349938 100644
--- a/src/main.c
+++ b/src/main.c
@@ -47,20 +47,25 @@
 #undef SAVE_DATADIR
 #endif
 
-
 static gchar **file_arguments = NULL;
+static gboolean option_new_window = FALSE;
 
 static const GOptionEntry options[] = {
-  {G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &file_arguments,
-   NULL, N_("[FILE...]")},      /* collects file arguments */
+  { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &file_arguments,
+    NULL, N_("[FILE...]")},      /* collects file arguments */
+
+  { "new-window", 'n',  0, G_OPTION_ARG_NONE, &option_new_window,
+    NULL, N_("Create a new toplevel window in an existing instance of Gtranslator")},
 
   {NULL}
 };
 
-static GSList *
+static gchar **
 get_command_line_data ()
 {
-  GSList *file_list = NULL;
+  GPtrArray *array;
+
+  array = g_ptr_array_new ();
 
   if (file_arguments)
     {
@@ -74,21 +79,99 @@ get_command_line_data ()
 
           if (file != NULL)
             {
-              file_list = g_slist_prepend (file_list, file);
-
+              g_ptr_array_add (array, g_file_get_uri (file));
+              g_object_unref (file);
             }
           else
             g_print (_("%s: malformed file name or URI.\n"),
                      file_arguments[i]);
         }
+    }
 
-      file_list = g_slist_reverse (file_list);
+  g_ptr_array_add (array, NULL);
+
+  return (gchar **)g_ptr_array_free (array, FALSE);
+}
+
+static GSList *
+get_files_from_command_line_data (const gchar **data)
+{
+  const gchar **ptr;
+  GSList *l = NULL;
+
+  for (ptr = data; ptr != NULL && *ptr != NULL; ptr++)
+    {
+      l = g_slist_prepend (l, g_file_new_for_uri (*ptr));
     }
 
-  return file_list;
+  l = g_slist_reverse (l);
+
+  return l;
+}
+
+static UniqueResponse
+unique_app_message_cb (UniqueApp *unique_app,
+                       gint command,
+                       UniqueMessageData *data,
+                       guint timestamp,
+                       gpointer user_data)
+{
+  GtrWindow *window;
+
+  if (command == UNIQUE_NEW)
+    {
+      window = gtr_application_create_window (GTR_APPLICATION (unique_app));
+
+      return UNIQUE_RESPONSE_OK;
+    }
+
+  window = gtr_application_get_active_window (GTR_APPLICATION (unique_app));
+
+  if (command == UNIQUE_OPEN)
+    {
+      gchar **uris;
+      GSList *files;
+
+      uris = unique_message_data_get_uris (data);
+      files = get_files_from_command_line_data ((const gchar **)uris);
+      g_strfreev (uris);
+
+      if (files != NULL)
+        {
+          gtr_actions_load_locations (window, files);
+          g_slist_foreach (files, (GFunc) g_object_unref, NULL);
+          g_slist_free (files);
+        }
+    }
+
+    gtk_window_present (GTK_WINDOW (window));
+
+    return UNIQUE_RESPONSE_OK;
+}
+
+static void
+send_unique_data (GtrApplication *app)
+{
+  UniqueMessageData *message_data = NULL;
+
+  if (option_new_window)
+    unique_app_send_message (UNIQUE_APP (app), UNIQUE_NEW, NULL);
+
+  if (file_arguments != NULL)
+    {
+      gchar **uris;
+
+      uris = get_command_line_data ();
+      message_data = unique_message_data_new ();
+      unique_message_data_set_uris (message_data, uris);
+      g_strfreev (uris);
+      unique_app_send_message (UNIQUE_APP (app), UNIQUE_OPEN, message_data);
+      unique_message_data_free (message_data);
+    }
+  else
+    unique_app_send_message (UNIQUE_APP (app), UNIQUE_ACTIVATE, NULL);
 }
 
-/* This method is from the file gedit.c which is part of gedit */
 #ifdef G_OS_WIN32
 static void
 setup_path (void)
@@ -113,12 +196,11 @@ setup_path (void)
 }
 #endif
 
-/*
- * The ubiquitous main function...
- */
+/* The ubiquitous main function... */
 gint
 main (gint argc, gchar * argv[])
 {
+  GtrApplication *app;
   GError *error = NULL;
   GtrPluginsEngine *engine;
   GtrWindow *window;
@@ -129,10 +211,9 @@ main (gint argc, gchar * argv[])
   GList *profiles_list = NULL;
   GFile *file;
   gchar *pixmaps_dir;
+  gchar **uris;
 
-  /*
-   * Initialize gettext.
-   */
+  /* Initialize gettext. */
   setlocale (LC_ALL, "");
 
   bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
@@ -150,9 +231,7 @@ main (gint argc, gchar * argv[])
   setup_path ();
 #endif
 
-  /*
-   * Initialize the GConf library.
-   */
+  /* Initialize the GConf library. */
   if (!(gconf_init (argc, argv, &error)))
     {
       if (error)
@@ -170,28 +249,41 @@ main (gint argc, gchar * argv[])
 
   g_option_context_parse (context, &argc, &argv, NULL);
 
+  /* Init preferences manager */
+  gtr_prefs_manager_app_init ();
+
+  app = _gtr_application_new ();
+
+  if (unique_app_is_running (UNIQUE_APP (app)))
+    {
+      send_unique_data (app);
+
+      /* we never popup a window... tell startup-notification
+       * that we are done. */
+      gdk_notify_startup_complete ();
+
+      g_object_unref (app);
+      exit (0);
+    }
+  else
+    {
+      g_signal_connect (app, "message-received",
+                        G_CALLBACK (unique_app_message_cb), NULL);
+    }
+
   /* We set the default icon dir */
   pixmaps_dir = gtr_dirs_get_pixmaps_dir ();
   gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
                                      pixmaps_dir);
   g_free (pixmaps_dir);
 
-  /*
-   * Init preferences manager
-   */
-  gtr_prefs_manager_app_init ();
-
-  /*
-   * Init plugin engine
-   */
+  /* Init plugin engine */
   engine = gtr_plugins_engine_get_default ();
 
   gtk_about_dialog_set_url_hook (gtr_utils_activate_url, NULL, NULL);
   gtk_about_dialog_set_email_hook (gtr_utils_activate_email, NULL, NULL);
 
-  /*
-   * Load profiles list
-   */
+  /* Load profiles list */
   config_folder = gtr_dirs_get_user_config_dir ();
   filename = g_build_filename (config_folder, "profiles.xml", NULL);
   file = g_file_new_for_path (filename);
@@ -201,17 +293,15 @@ main (gint argc, gchar * argv[])
       profiles_list = gtr_profile_get_profiles_from_xml_file (filename);
     }
 
-  gtr_application_set_profiles (GTR_APP, profiles_list);
+  gtr_application_set_profiles (app, profiles_list);
 
-  /* 
-   * Create the main app-window. 
-   */
-  window = gtr_application_open_window (GTR_APP);
+  /* Create the main app-window. */
+  window = gtr_application_create_window (app);
 
-  /*
-   * Now we open the files passed as arguments
-   */
-  file_list = get_command_line_data ();
+  /* Now we open the files passed as arguments */
+  uris = get_command_line_data ();
+  file_list = get_files_from_command_line_data ((const gchar **)uris);
+  g_strfreev (uris);
   if (file_list)
     {
       gtr_actions_load_locations (window, (const GSList *) file_list);
@@ -221,12 +311,11 @@ main (gint argc, gchar * argv[])
 
   g_option_context_free (context);
 
-  /*
-   * Enter main GTK loop
-   */
+  /* Enter main GTK loop */
   gtk_main ();
 
   gtr_prefs_manager_app_shutdown ();
+  g_object_unref (app);
 
   return 0;
 }



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