[frogr] Initial bits towards porting frogr to GtkApplication



commit 1eacf93f054aecec56dc740030f61998d5939ba9
Author: Mario Sanchez Prada <msanchez gnome org>
Date:   Fri Nov 16 17:08:17 2012 +0100

    Initial bits towards porting frogr to GtkApplication
    
    Some things still don't work and many are untested so far
    (e.g. menus, opening files from command line...) but it's a
    first step that compiles and kind of works

 data/gtkbuilder/frogr-main-view.xml |  204 ++++++++++----------
 src/frogr-controller.c              |   27 +--
 src/frogr-controller.h              |    4 +-
 src/frogr-global-defs.h             |    1 +
 src/frogr-main-view.c               |  364 +++++++++++++++++++++--------------
 src/frogr-main-view.h               |    2 +-
 src/main.c                          |  106 ++++++-----
 7 files changed, 391 insertions(+), 317 deletions(-)
---
diff --git a/data/gtkbuilder/frogr-main-view.xml b/data/gtkbuilder/frogr-main-view.xml
index 7a0b614..bdd8be5 100644
--- a/data/gtkbuilder/frogr-main-view.xml
+++ b/data/gtkbuilder/frogr-main-view.xml
@@ -198,138 +198,132 @@
     <property name="can_focus">False</property>
     <property name="stock">gtk-missing-image</property>
   </object>
-  <object class="GtkWindow" id="main_window">
+  <object class="GtkVBox" id="main_window_vbox">
+    <property name="visible">True</property>
     <property name="can_focus">False</property>
-    <property name="title" translatable="yes">frogr</property>
     <child>
-      <object class="GtkVBox" id="main_window_vbox">
+      <object class="GtkToolbar" id="toolbar">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <child>
-          <object class="GtkToolbar" id="toolbar">
+          <object class="GtkToolButton" id="load_project_button">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <child>
-              <object class="GtkToolButton" id="load_project_button">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="related_action">load_project_action</property>
-                <property name="label" translatable="yes">Load Project</property>
-                <property name="use_underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="save_project_button">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="related_action">save_project_action</property>
-                <property name="label" translatable="yes">Save Project</property>
-                <property name="use_underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkSeparatorToolItem" id="separator10">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="use_action_appearance">False</property>
-              </object>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="add_button">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="related_action">load_pictures_action</property>
-                <property name="label" translatable="yes">Add</property>
-                <property name="use_underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="remove_button">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="related_action">remove_pictures_action</property>
-                <property name="label" translatable="yes">Remove</property>
-                <property name="use_underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkSeparatorToolItem" id="separator11">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="use_action_appearance">False</property>
-              </object>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="upload_button">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="related_action">upload_pictures_action</property>
-                <property name="label" translatable="yes">Upload</property>
-                <property name="use_underline">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
+            <property name="related_action">load_project_action</property>
+            <property name="label" translatable="yes">Load Project</property>
+            <property name="use_underline">True</property>
           </object>
           <packing>
             <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
+            <property name="homogeneous">True</property>
           </packing>
         </child>
         <child>
-          <object class="GtkScrolledWindow" id="scrolled_window">
+          <object class="GtkToolButton" id="save_project_button">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="shadow_type">etched-in</property>
-            <property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
-            <property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
-            <child>
-              <object class="GtkIconView" id="icon_view">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <signal name="button-press-event" handler="_on_icon_view_button_press_event" swapped="no"/>
-                <signal name="key-press-event" handler="_on_icon_view_key_press_event" swapped="no"/>
-              </object>
-            </child>
+            <property name="can_focus">False</property>
+            <property name="related_action">save_project_action</property>
+            <property name="label" translatable="yes">Save Project</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="homogeneous">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkSeparatorToolItem" id="separator10">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="use_action_appearance">False</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkToolButton" id="add_button">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="related_action">load_pictures_action</property>
+            <property name="label" translatable="yes">Add</property>
+            <property name="use_underline">True</property>
           </object>
           <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
+            <property name="expand">False</property>
+            <property name="homogeneous">True</property>
           </packing>
         </child>
         <child>
-          <object class="GtkStatusbar" id="status_bar">
+          <object class="GtkToolButton" id="remove_button">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
+            <property name="related_action">remove_pictures_action</property>
+            <property name="label" translatable="yes">Remove</property>
+            <property name="use_underline">True</property>
           </object>
           <packing>
             <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="padding">3</property>
-            <property name="position">3</property>
+            <property name="homogeneous">True</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkSeparatorToolItem" id="separator11">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="use_action_appearance">False</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkToolButton" id="upload_button">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="related_action">upload_pictures_action</property>
+            <property name="label" translatable="yes">Upload</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="homogeneous">True</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkScrolledWindow" id="scrolled_window">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="shadow_type">etched-in</property>
+        <property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+        <property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+        <child>
+          <object class="GtkIconView" id="icon_view">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <signal name="button-press-event" handler="_on_icon_view_button_press_event" swapped="no"/>
+            <signal name="key-press-event" handler="_on_icon_view_key_press_event" swapped="no"/>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkStatusbar" id="status_bar">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
       </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="padding">3</property>
+        <property name="position">3</property>
+      </packing>
     </child>
   </object>
   <object class="GtkMenuBar" id="menu_bar">
diff --git a/src/frogr-controller.c b/src/frogr-controller.c
index 550399a..d0e5ca5 100644
--- a/src/frogr-controller.c
+++ b/src/frogr-controller.c
@@ -2177,24 +2177,24 @@ frogr_controller_get_model (FrogrController *self)
   return frogr_main_view_get_model (priv->mainview);;
 }
 
-gboolean
-frogr_controller_run_app (FrogrController *self)
+void
+frogr_controller_run_app (FrogrController *self, GtkApplication *app)
 {
   FrogrControllerPrivate *priv = NULL;
   FrogrAccount *account = NULL;
 
-  g_return_val_if_fail(FROGR_IS_CONTROLLER (self), FALSE);
+  g_return_if_fail(FROGR_IS_CONTROLLER (self));
 
   priv = FROGR_CONTROLLER_GET_PRIVATE (self);
 
   if (priv->app_running)
     {
       DEBUG ("%s", "Application already running");
-      return FALSE;
+      return;
     }
 
   /* Create UI window */
-  priv->mainview = frogr_main_view_new ();
+  priv->mainview = frogr_main_view_new (app);
   g_object_add_weak_pointer (G_OBJECT (priv->mainview),
                              (gpointer) & priv->mainview);
   /* Update flag */
@@ -2206,22 +2206,14 @@ frogr_controller_run_app (FrogrController *self)
   account = frogr_config_get_active_account (priv->config);
   if (account)
     frogr_controller_set_active_account (self, account);
-
-  /* Run UI */
-  gtk_main ();
-
-  /* Application shutting down from this point on */
-  DEBUG ("%s", "Shutting down application...");
-
-  return TRUE;
 }
 
-gboolean
+void
 frogr_controller_quit_app (FrogrController *self)
 {
   FrogrControllerPrivate *priv = NULL;
 
-  g_return_val_if_fail(FROGR_IS_CONTROLLER (self), FALSE);
+  g_return_if_fail(FROGR_IS_CONTROLLER (self));
 
   priv = FROGR_CONTROLLER_GET_PRIVATE (self);
 
@@ -2235,12 +2227,7 @@ frogr_controller_quit_app (FrogrController *self)
       priv->app_running = FALSE;
 
       frogr_config_save_all (priv->config);
-
-      return TRUE;
     }
-
-  /* Nothing happened */
-  return FALSE;
 }
 
 void
diff --git a/src/frogr-controller.h b/src/frogr-controller.h
index 491ec42..05e6204 100644
--- a/src/frogr-controller.h
+++ b/src/frogr-controller.h
@@ -69,9 +69,9 @@ FrogrMainView *frogr_controller_get_main_view (FrogrController *self);
 
 FrogrModel *frogr_controller_get_model (FrogrController *self);
 
-gboolean frogr_controller_run_app (FrogrController *self);
+void frogr_controller_run_app (FrogrController *self, GtkApplication *app);
 
-gboolean frogr_controller_quit_app (FrogrController *self);
+void frogr_controller_quit_app (FrogrController *self);
 
 void frogr_controller_set_active_account (FrogrController *self,
                                           FrogrAccount *account);
diff --git a/src/frogr-global-defs.h b/src/frogr-global-defs.h
index 4b62246..3666523 100644
--- a/src/frogr-global-defs.h
+++ b/src/frogr-global-defs.h
@@ -26,6 +26,7 @@
 #define APP_NAME N_("Flickr Remote Organizer")
 #define APP_SHORTNAME PACKAGE
 #define APP_VERSION VERSION
+#define APP_ID "org.gnome.frogr"
 
 /* Max width and heigth for pictures in the icon view.
  *
diff --git a/src/frogr-main-view.c b/src/frogr-main-view.c
index f22da8e..a2c565f 100644
--- a/src/frogr-main-view.c
+++ b/src/frogr-main-view.c
@@ -73,6 +73,7 @@ typedef struct _FrogrMainViewPrivate {
   gboolean tooltips_enabled;
   gint n_selected_pictures;
 
+  GtkApplication *gtk_app;
   GtkWindow *window;
   gchar *project_name;
   gchar *project_dir;
@@ -125,6 +126,14 @@ typedef struct _FrogrMainViewPrivate {
 #endif
 } FrogrMainViewPrivate;
 
+
+/* Properties */
+enum  {
+  PROP_0,
+  PROP_GTK_APPLICATION
+};
+
+/* Icon view treeview */
 enum {
   FILEURI_COL,
   PIXBUF_COL,
@@ -1831,82 +1840,54 @@ _update_ui (FrogrMainView *self)
 }
 
 static void
-_frogr_main_view_dispose (GObject *object)
+_frogr_main_view_set_property (GObject *object,
+                               guint prop_id,
+                               const GValue *value,
+                               GParamSpec *pspec)
 {
-  FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (object);
-
-  /* Free memory */
-  if (priv->model)
-    {
-      g_object_unref (priv->model);
-      priv->model = NULL;
-    }
-
-  if (priv->sorted_pictures)
-    {
-      g_slist_foreach (priv->sorted_pictures, (GFunc)g_object_unref, NULL);
-      g_slist_free (priv->sorted_pictures);
-      priv->sorted_pictures = NULL;
-    }
-
-  if (priv->controller)
-    {
-      g_object_unref (priv->controller);
-      priv->controller = NULL;
-    }
-
-  if (priv->config)
-    {
-      g_object_unref (priv->config);
-      priv->config = NULL;
-    }
-
-  if (priv->tree_model)
-    {
-      g_object_unref (priv->tree_model);
-      priv->tree_model = NULL;
-    }
+  FrogrMainView *self = FROGR_MAIN_VIEW (object);
+  FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
 
-  if (priv->builder)
+  switch (prop_id)
     {
-      g_object_unref (priv->builder);
-      priv->builder = NULL;
+    case PROP_GTK_APPLICATION:
+      priv->gtk_app = GTK_APPLICATION (g_value_dup_object (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
     }
-
-  G_OBJECT_CLASS(frogr_main_view_parent_class)->dispose (object);
 }
 
 static void
-_frogr_main_view_finalize (GObject *object)
+_frogr_main_view_get_property (GObject *object,
+                               guint prop_id,
+                               GValue *value,
+                               GParamSpec *pspec)
 {
   FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (object);
 
-  g_free (priv->project_name);
-  g_free (priv->project_dir);
-  g_free (priv->project_filepath);
-  g_free (priv->state_description);
-  gtk_widget_destroy (GTK_WIDGET (priv->window));
-
-  G_OBJECT_CLASS(frogr_main_view_parent_class)->finalize (object);
-}
-
-static void
-frogr_main_view_class_init (FrogrMainViewClass *klass)
-{
-  GObjectClass *obj_class = (GObjectClass *)klass;
-
-  obj_class->dispose = _frogr_main_view_dispose;
-  obj_class->finalize = _frogr_main_view_finalize;
-
-  g_type_class_add_private (obj_class, sizeof (FrogrMainViewPrivate));
+  switch (prop_id)
+    {
+    case PROP_GTK_APPLICATION:
+      g_value_set_object (value, priv->gtk_app);
+      break;
+   default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
 
-static void
-frogr_main_view_init (FrogrMainView *self)
+static GObject *
+_frogr_main_view_constructor (GType type,
+                              guint n_construct_properties,
+                              GObjectConstructParam *construct_properties)
 {
-  FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+  GObject *object = NULL;
+  FrogrMainView *self = NULL;
+  FrogrMainViewPrivate *priv = NULL;
   GtkBuilder *builder;
-  GtkWindow *window;
+  GtkWidget *main_vbox;
   GtkWidget *icon_view;
   GtkWidget *status_bar;
   GtkWidget *progress_dialog;
@@ -1914,48 +1895,15 @@ frogr_main_view_init (FrogrMainView *self)
   GtkWidget *progress_bar;
   GtkWidget *progress_label;
   GtkWidget *toolbar;
-  const gchar *icons_path;
   gchar *full_path;
-  GList *icons = NULL;
-
-#ifndef MAC_INTEGRATION
-  GtkWidget *main_vbox;
-#endif
 
-  /* Init model, controller and configuration */
-  priv->model = frogr_model_new ();
-  priv->controller = g_object_ref (frogr_controller_get_instance ());
-  priv->config = g_object_ref (frogr_config_get_instance ());
-
-  /* Provide a default icon list in several sizes */
-  icons_path = frogr_util_get_icons_dir ();
-  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("128x128"), icons_path);
-  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
-  g_free (full_path);
-
-  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("64x64"), icons_path);
-  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
-  g_free (full_path);
-
-  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("48x48"), icons_path);
-  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
-  g_free (full_path);
-
-  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("32x32"), icons_path);
-  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
-  g_free (full_path);
-
-  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("24x24"), icons_path);
-  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
-  g_free (full_path);
-
-  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("16x16"), icons_path);
-  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
-  g_free (full_path);
-
-  gtk_window_set_default_icon_list (icons);
-  g_list_foreach (icons, (GFunc) g_object_unref, NULL);
-  g_list_free (icons);
+  /* Chain up to the parent's constructor first */
+  object =
+    G_OBJECT_CLASS (frogr_main_view_parent_class)->constructor (type,
+                                                                 n_construct_properties,
+                                                                 construct_properties);
+  self = FROGR_MAIN_VIEW (object);
+  priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
 
   /* Get widgets from GtkBuilder */
   builder = gtk_builder_new ();
@@ -1965,17 +1913,11 @@ frogr_main_view_init (FrogrMainView *self)
   gtk_builder_add_from_file (builder, full_path, NULL);
   g_free (full_path);
 
-  window = GTK_WINDOW(gtk_builder_get_object (builder, "main_window"));
-  priv->window = window;
+  priv->window = GTK_WINDOW (gtk_application_window_new (GTK_APPLICATION (priv->gtk_app)));
+  gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (priv->window), TRUE);
 
-  priv->menu_bar = GTK_WIDGET (gtk_builder_get_object (builder, "menu_bar"));
-  gtk_widget_show_all (priv->menu_bar);
-
-#ifndef MAC_INTEGRATION
   main_vbox = GTK_WIDGET (gtk_builder_get_object (builder, "main_window_vbox"));
-  gtk_box_pack_start (GTK_BOX (main_vbox), priv->menu_bar, FALSE, FALSE, 0);
-  gtk_box_reorder_child (GTK_BOX (main_vbox), priv->menu_bar, 0);
-#endif
+  gtk_container_add (GTK_CONTAINER (priv->window), main_vbox);
 
   toolbar = GTK_WIDGET (gtk_builder_get_object (builder, "toolbar"));
   gtk_style_context_add_class (gtk_widget_get_style_context (toolbar),
@@ -2050,9 +1992,7 @@ frogr_main_view_init (FrogrMainView *self)
   /* Init the details of the current project */
   _update_project_path (self, NULL);
 
-  /* Initialize sorting criteria and reverse */
-  priv->sorted_pictures = NULL;
-  priv->sorting_criteria = frogr_config_get_mainview_sorting_criteria (priv->config);
+  /* Initialize sorting criteria and reverse in the UI */
   if (priv->sorting_criteria == SORT_BY_TITLE)
     gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->sort_by_title_action), TRUE);
   else if (priv->sorting_criteria == SORT_BY_DATE)
@@ -2060,17 +2000,12 @@ frogr_main_view_init (FrogrMainView *self)
   else
     gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->sort_as_loaded_action), TRUE);
 
-  priv->sorting_reversed = frogr_config_get_mainview_sorting_reversed (priv->config);
   gtk_toggle_action_set_active (priv->reversed_order_action, priv->sorting_reversed);
 
-  /* Read value for 'tooltips enabled' */
-  priv->tooltips_enabled = frogr_config_get_mainview_enable_tooltips (priv->config);
+  /* Initialize 'tooltips enabled' in the UI */
   gtk_toggle_action_set_active (priv->enable_tooltips_action, priv->tooltips_enabled);
 
-  /* No selected pictures at the beginning */
-  priv->n_selected_pictures = 0;
-
-  /* initialize extra widgets */
+  /* Initialize extra widgets */
 
   /* Accounts menu */
   priv->accounts_menu_item =
@@ -2147,10 +2082,6 @@ frogr_main_view_init (FrogrMainView *self)
                                   "Status bar messages");
 
   /* Connect signals */
-  g_signal_connect (G_OBJECT (priv->window), "destroy",
-                    G_CALLBACK (gtk_main_quit),
-                    NULL);
-
   g_signal_connect (G_OBJECT (priv->window), "delete-event",
                     G_CALLBACK (_on_main_view_delete_event),
                     self);
@@ -2172,6 +2103,168 @@ frogr_main_view_init (FrogrMainView *self)
                     G_CALLBACK(_progress_dialog_delete_event),
                     self);
 
+  gtk_builder_connect_signals (builder, self);
+
+  /* Show the UI */
+  gtk_widget_show_all (GTK_WIDGET(priv->window));
+
+#ifdef MAC_INTEGRATION
+  _tweak_menu_bar_for_mac (self);
+#endif
+
+  /* Update window title */
+  _update_window_title (self, FALSE);
+
+  /* Update UI */
+  _update_ui (FROGR_MAIN_VIEW (self));
+
+  /* Show the auth dialog, if needed, on idle */
+  g_idle_add ((GSourceFunc) _maybe_show_auth_dialog_on_idle, self);
+
+  return object;
+}
+
+static void
+_frogr_main_view_dispose (GObject *object)
+{
+  FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (object);
+
+  /* Free memory */
+  if (priv->model)
+    {
+      g_object_unref (priv->model);
+      priv->model = NULL;
+    }
+
+  if (priv->sorted_pictures)
+    {
+      g_slist_foreach (priv->sorted_pictures, (GFunc)g_object_unref, NULL);
+      g_slist_free (priv->sorted_pictures);
+      priv->sorted_pictures = NULL;
+    }
+
+  if (priv->controller)
+    {
+      g_object_unref (priv->controller);
+      priv->controller = NULL;
+    }
+
+  if (priv->config)
+    {
+      g_object_unref (priv->config);
+      priv->config = NULL;
+    }
+
+  if (priv->tree_model)
+    {
+      g_object_unref (priv->tree_model);
+      priv->tree_model = NULL;
+    }
+
+  if (priv->builder)
+    {
+      g_object_unref (priv->builder);
+      priv->builder = NULL;
+    }
+
+  G_OBJECT_CLASS(frogr_main_view_parent_class)->dispose (object);
+}
+
+static void
+_frogr_main_view_finalize (GObject *object)
+{
+  FrogrMainViewPrivate *priv = FROGR_MAIN_VIEW_GET_PRIVATE (object);
+
+  g_free (priv->project_name);
+  g_free (priv->project_dir);
+  g_free (priv->project_filepath);
+  g_free (priv->state_description);
+  gtk_widget_destroy (GTK_WIDGET (priv->window));
+
+  g_application_quit (G_APPLICATION (priv->gtk_app));
+  g_object_unref (priv->gtk_app);
+
+  G_OBJECT_CLASS(frogr_main_view_parent_class)->finalize (object);
+}
+
+static void
+frogr_main_view_class_init (FrogrMainViewClass *klass)
+{
+  GObjectClass *obj_class = (GObjectClass *)klass;
+
+  obj_class->set_property = _frogr_main_view_set_property;
+  obj_class->get_property = _frogr_main_view_get_property;
+  obj_class->constructor = _frogr_main_view_constructor;
+  obj_class->dispose = _frogr_main_view_dispose;
+  obj_class->finalize = _frogr_main_view_finalize;
+
+  g_object_class_install_property (obj_class,
+                                   PROP_GTK_APPLICATION,
+                                   g_param_spec_object ("gtk-application",
+                                                        "gtk-application",
+                                                        "GtkApplication associated to the main view",
+                                                        GTK_TYPE_APPLICATION,
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_type_class_add_private (obj_class, sizeof (FrogrMainViewPrivate));
+}
+
+static void
+frogr_main_view_init (FrogrMainView *self)
+{
+  FrogrMainViewPrivate *priv = NULL;
+  const gchar *icons_path = NULL;
+  gchar *full_path = NULL;
+  GList *icons = NULL;
+
+  /* Init model, controller and configuration */
+  priv = FROGR_MAIN_VIEW_GET_PRIVATE (self);
+  priv->model = frogr_model_new ();
+  priv->controller = g_object_ref (frogr_controller_get_instance ());
+  priv->config = g_object_ref (frogr_config_get_instance ());
+
+  /* Provide a default icon list in several sizes */
+  icons_path = frogr_util_get_icons_dir ();
+  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("128x128"), icons_path);
+  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+  g_free (full_path);
+
+  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("64x64"), icons_path);
+  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+  g_free (full_path);
+
+  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("48x48"), icons_path);
+  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+  g_free (full_path);
+
+  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("32x32"), icons_path);
+  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+  g_free (full_path);
+
+  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("24x24"), icons_path);
+  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+  g_free (full_path);
+
+  full_path = g_strdup_printf ("%s/" MAIN_VIEW_ICON("16x16"), icons_path);
+  icons = g_list_prepend (icons, gdk_pixbuf_new_from_file (full_path, NULL));
+  g_free (full_path);
+
+  gtk_window_set_default_icon_list (icons);
+  g_list_foreach (icons, (GFunc) g_object_unref, NULL);
+  g_list_free (icons);
+
+  /* Initialize sorting criteria and reverse */
+  priv->sorted_pictures = NULL;
+  priv->sorting_criteria = frogr_config_get_mainview_sorting_criteria (priv->config);
+  priv->sorting_reversed = frogr_config_get_mainview_sorting_reversed (priv->config);
+
+  /* Read value for 'tooltips enabled' */
+  priv->tooltips_enabled = frogr_config_get_mainview_enable_tooltips (priv->config);
+
+  /* No selected pictures at the beginning */
+  priv->n_selected_pictures = 0;
+
+  /* Connect signals */
   g_signal_connect (G_OBJECT (priv->controller), "state-changed",
                     G_CALLBACK (_controller_state_changed), self);
 
@@ -2192,33 +2285,16 @@ frogr_main_view_init (FrogrMainView *self)
 
   g_signal_connect (G_OBJECT (priv->model), "model-deserialized",
                     G_CALLBACK (_model_deserialized), self);
-
-  gtk_builder_connect_signals (builder, self);
-
-  /* Show the UI */
-  gtk_widget_show_all (GTK_WIDGET(priv->window));
-
-#ifdef MAC_INTEGRATION
-  _tweak_menu_bar_for_mac (self);
-#endif
-
-  /* Update window title */
-  _update_window_title (self, FALSE);
-
-  /* Update UI */
-  _update_ui (FROGR_MAIN_VIEW (self));
-
-  /* Show the auth dialog, if needed, on idle */
-  g_idle_add ((GSourceFunc) _maybe_show_auth_dialog_on_idle, self);
 }
 
 
 /* Public API */
 
 FrogrMainView *
-frogr_main_view_new (void)
+frogr_main_view_new (GtkApplication *app)
 {
   GObject *new = g_object_new (FROGR_TYPE_MAIN_VIEW,
+                               "gtk-application", app,
                                NULL);
   return FROGR_MAIN_VIEW (new);
 }
diff --git a/src/frogr-main-view.h b/src/frogr-main-view.h
index c0df2df..686b62f 100644
--- a/src/frogr-main-view.h
+++ b/src/frogr-main-view.h
@@ -49,7 +49,7 @@ struct _FrogrMainView
 
 GType frogr_main_view_get_type (void) G_GNUC_CONST;
 
-FrogrMainView *frogr_main_view_new (void);
+FrogrMainView *frogr_main_view_new (GtkApplication *app);
 
 GtkWindow *frogr_main_view_get_window (FrogrMainView *self);
 
diff --git a/src/main.c b/src/main.c
index 9b6ee39..48c84b6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -29,32 +29,19 @@
 #include <gst/gst.h>
 #include <libxml/parser.h>
 
-#ifdef MAC_INTEGRATION
-#include <gtkosxapplication.h>
-#endif
-
 static GSList *
-_get_uris_list_from_array (char **uris_str, int n_uris)
+_get_files_list_from_array (GFile **files, int n_files)
 {
   GSList *fileuris = NULL;
   int i = 0;
 
-  for (i = 0; i < n_uris; i++)
+  for (i = 0; i < n_files; i++)
     {
-      gchar *uri = NULL;
       gchar *fileuri = NULL;
 
-      /* Add the 'file://' schema if not present */
-      if (g_str_has_prefix (uris_str[i], "/"))
-        uri = g_strdup_printf ("file://%s", uris_str[i]);
-      else
-        uri = g_strdup (uris_str[i]);
-
-      fileuri = g_strdup (uri);
+      fileuri = g_strdup (g_file_get_uri (files[i]));
       if (fileuri)
         fileuris = g_slist_append (fileuris, fileuri);
-
-      g_free (uri);
     }
 
   return fileuris;
@@ -75,17 +62,58 @@ _load_pictures_on_idle (gpointer data)
   return FALSE;
 }
 
+static void
+_app_startup_cb (GApplication *app, gpointer data)
+{
+  FrogrController *fcontroller = NULL;
+
+  DEBUG ("Started!\n");
+
+  /* Initialize libxml2 library */
+  xmlInitParser ();
+
+  /* Initialize internationalization */
+  bindtextdomain (GETTEXT_PACKAGE, frogr_util_get_locale_dir ());
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+  textdomain (GETTEXT_PACKAGE);
+
+  /* Actually start the application */
+  fcontroller = frogr_controller_get_instance ();
+  frogr_controller_run_app (fcontroller, GTK_APPLICATION (app));
+}
+
+static void
+_app_activate_cb (GApplication *app, gpointer data)
+{
+  DEBUG ("Activated!\n");
+}
+
+static void
+_app_shutdown_cb (GApplication *app, gpointer data)
+{
+  DEBUG ("%s", "Shutting down application...");
+
+  /* cleanup libxml2 library */
+  xmlCleanupParser();
+}
+
+static void
+_app_open_files_cb (GApplication *app, GFile **files, gint n_files, gchar *hint, gpointer data)
+{
+  DEBUG ("Trying to open %d files\n", n_files);
+
+  GSList *fileuris = _get_files_list_from_array (files, n_files);
+  gdk_threads_add_idle (_load_pictures_on_idle, fileuris);
+}
+
 int
 main (int argc, char **argv)
 {
-  FrogrController *fcontroller = NULL;
-  GSList *fileuris = NULL;
+  GtkApplication *app = NULL;
   GError *error = NULL;
+  int status;
 
-  /* Check optional command line parameters */
-  if (argc > 1)
-    fileuris = _get_uris_list_from_array (&argv[1], argc - 1);
-
+  /* Initialize gstreamer before using any other GLib function */
   gst_init_check (&argc, &argv, &error);
   if (error)
     {
@@ -93,32 +121,20 @@ main (int argc, char **argv)
       DEBUG ("Gstreamer could not be initialized: %s", error->message);
       g_error_free (error);
     }
-  gtk_init (&argc, &argv);
 
+  /* Initialize and run the Gtk application */
   g_set_application_name(APP_SHORTNAME);
+  app = gtk_application_new (APP_ID,
+                             G_APPLICATION_NON_UNIQUE
+                             | G_APPLICATION_HANDLES_OPEN);
 
-#ifdef MAC_INTEGRATION
-  /* Initialize the GtkOSXApplication singleton */
-  g_object_new (GTK_TYPE_OSX_APPLICATION, NULL);
-#endif
+  g_signal_connect (app, "activate", G_CALLBACK (_app_activate_cb), NULL);
+  g_signal_connect (app, "startup", G_CALLBACK (_app_startup_cb), NULL);
+  g_signal_connect (app, "shutdown", G_CALLBACK (_app_shutdown_cb), NULL);
+  g_signal_connect (app, "open", G_CALLBACK (_app_open_files_cb), NULL);
 
-  /* Translation domain */
-  bindtextdomain (GETTEXT_PACKAGE, frogr_util_get_locale_dir ());
-  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-  textdomain (GETTEXT_PACKAGE);
-
-  /* Init libxml2 library */
-  xmlInitParser ();
-
-  /* Run app (and load pictures if present) */
-  fcontroller = frogr_controller_get_instance ();
-  if (fileuris)
-    gdk_threads_add_idle (_load_pictures_on_idle, fileuris);
-
-  frogr_controller_run_app (fcontroller);
-
-  /* cleanup libxml2 library */
-  xmlCleanupParser();
+  status = g_application_run (G_APPLICATION (app), argc, argv);
+  g_object_unref (app);
 
-  return 0;
+  return status;
 }



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