[gtk+/wip/native-file-chooser: 11/15] GtkFileChooserButton: Use native dialogs



commit 4fbf06c16059ba780d02f99a38518b4078b050f2
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Oct 29 15:13:14 2015 +0100

    GtkFileChooserButton: Use native dialogs
    
    Unless you explicitly set the dialog constructor property we use a
    native dialog (GtkFileChooserNative).

 gtk/gtkfilechooserbutton.c |  231 +++++++++++++++++++++++++++++---------------
 1 files changed, 153 insertions(+), 78 deletions(-)
---
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
index baff523..1df73bc 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -44,6 +44,7 @@
 #include "gtktreemodelfilter.h"
 #include "gtkseparator.h"
 #include "gtkfilechooserdialog.h"
+#include "gtkfilechoosernative.h"
 #include "gtkfilechooserprivate.h"
 #include "gtkfilechooserutils.h"
 #include "gtkmarshalers.h"
@@ -167,7 +168,9 @@ RowType;
 
 struct _GtkFileChooserButtonPrivate
 {
-  GtkWidget *dialog;
+  GtkFileChooser *chooser;      /* Points to either dialog or native, depending on which is set */
+  GtkWidget *dialog;            /* Set if you explicitly enable */
+  GtkFileChooserNative *native; /* Otherwise this is set */
   GtkWidget *button;
   GtkWidget *image;
   GtkWidget *label;
@@ -328,9 +331,9 @@ static void     combo_box_notify_popup_shown_cb  (GObject        *object,
 static void     button_clicked_cb                (GtkButton      *real_button,
                                                  gpointer        user_data);
 
-static void     dialog_update_preview_cb         (GtkFileChooser *dialog,
+static void     chooser_update_preview_cb        (GtkFileChooser *dialog,
                                                  gpointer        user_data);
-static void     dialog_notify_cb                 (GObject        *dialog,
+static void     chooser_notify_cb                (GObject        *dialog,
                                                  GParamSpec     *pspec,
                                                  gpointer        user_data);
 static gboolean dialog_delete_event_cb           (GtkWidget      *dialog,
@@ -339,6 +342,9 @@ static gboolean dialog_delete_event_cb           (GtkWidget      *dialog,
 static void     dialog_response_cb               (GtkDialog      *dialog,
                                                  gint            response,
                                                  gpointer        user_data);
+static void     native_response_cb               (GtkFileChooserNative *native,
+                                                  gint            response,
+                                                  gpointer        user_data);
 
 static guint file_chooser_button_signals[LAST_SIGNAL] = { 0 };
 
@@ -542,7 +548,7 @@ gtk_file_chooser_button_set_current_folder (GtkFileChooser    *chooser,
   g_signal_emit_by_name (button, "current-folder-changed");
 
   if (priv->active)
-    gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (priv->dialog), file, NULL);
+    gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (priv->chooser), file, NULL);
 
   return TRUE;
 }
@@ -578,7 +584,7 @@ gtk_file_chooser_button_select_file (GtkFileChooser *chooser,
   update_combo_box (button);
 
   if (priv->active)
-    gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->dialog), file, NULL);
+    gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->chooser), file, NULL);
 
   return TRUE;
 }
@@ -611,7 +617,7 @@ gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser,
     unselect_current_file (button);
 
   if (priv->active)
-    gtk_file_chooser_unselect_file (GTK_FILE_CHOOSER (priv->dialog), file);
+    gtk_file_chooser_unselect_file (GTK_FILE_CHOOSER (priv->chooser), file);
 }
 
 static void
@@ -623,7 +629,7 @@ gtk_file_chooser_button_unselect_all (GtkFileChooser *chooser)
   unselect_current_file (button);
 
   if (priv->active)
-    gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog));
+    gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->chooser));
 }
 
 static GFile *
@@ -636,7 +642,7 @@ get_selected_file (GtkFileChooserButton *button)
 
   if (priv->selection_while_inactive)
     retval = priv->selection_while_inactive;
-  else if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog)) == 
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
+  else if (priv->chooser && gtk_file_chooser_get_action (priv->chooser) == 
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
     {
       /* If there is no "real" selection in SELECT_FOLDER mode, then we'll just return
        * the current folder, since that is what GtkFileChooserWidget would do.
@@ -770,46 +776,42 @@ gtk_file_chooser_button_constructed (GObject *object)
 
   if (!priv->dialog)
     {
-      priv->dialog = gtk_file_chooser_dialog_new (NULL, NULL,
+      priv->native = gtk_file_chooser_native_new (NULL,
+                                                  NULL,
                                                  GTK_FILE_CHOOSER_ACTION_OPEN,
-                                                 _("_Cancel"), GTK_RESPONSE_CANCEL,
-                                                 _("_Open"), GTK_RESPONSE_ACCEPT,
+                                                 NULL,
                                                  NULL);
-
-      gtk_dialog_set_default_response (GTK_DIALOG (priv->dialog),
-                                      GTK_RESPONSE_ACCEPT);
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-      gtk_dialog_set_alternative_button_order (GTK_DIALOG (priv->dialog),
-                                              GTK_RESPONSE_ACCEPT,
-                                              GTK_RESPONSE_CANCEL,
-                                              -1);
-G_GNUC_END_IGNORE_DEPRECATIONS
-
+      priv->chooser = GTK_FILE_CHOOSER (priv->native);
       gtk_file_chooser_button_set_title (button, _(DEFAULT_TITLE));
+
+      g_signal_connect (priv->native, "response",
+                        G_CALLBACK (native_response_cb), object);
     }
-  else if (!gtk_window_get_title (GTK_WINDOW (priv->dialog)))
+  else /* dialog set */
     {
-      gtk_file_chooser_button_set_title (button, _(DEFAULT_TITLE));
+      priv->chooser = GTK_FILE_CHOOSER (priv->dialog);
+
+      if (!gtk_window_get_title (GTK_WINDOW (priv->dialog)))
+        gtk_file_chooser_button_set_title (button, _(DEFAULT_TITLE));
+
+      g_signal_connect (priv->dialog, "delete-event",
+                        G_CALLBACK (dialog_delete_event_cb), object);
+      g_signal_connect (priv->dialog, "response",
+                        G_CALLBACK (dialog_response_cb), object);
+
+      g_object_add_weak_pointer (G_OBJECT (priv->dialog),
+                                 (gpointer) (&priv->dialog));
     }
 
-  g_signal_connect (priv->dialog, "delete-event",
-                   G_CALLBACK (dialog_delete_event_cb), object);
-  g_signal_connect (priv->dialog, "response",
-                   G_CALLBACK (dialog_response_cb), object);
+  g_signal_connect (priv->chooser, "notify",
+                    G_CALLBACK (chooser_notify_cb), object);
 
   /* This is used, instead of the standard delegate, to ensure that signals are only
    * delegated when the OK button is pressed. */
-  g_object_set_qdata (object, GTK_FILE_CHOOSER_DELEGATE_QUARK, priv->dialog);
-
-  g_signal_connect (priv->dialog, "update-preview",
-                   G_CALLBACK (dialog_update_preview_cb), object);
-  g_signal_connect (priv->dialog, "notify",
-                   G_CALLBACK (dialog_notify_cb), object);
-  g_object_add_weak_pointer (G_OBJECT (priv->dialog),
-                            (gpointer) (&priv->dialog));
+  g_object_set_qdata (object, GTK_FILE_CHOOSER_DELEGATE_QUARK, priv->chooser);
 
   priv->fs =
-    g_object_ref (_gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog)));
+    g_object_ref (_gtk_file_chooser_get_file_system (priv->chooser));
 
   model_add_special (button);
 
@@ -839,7 +841,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
    * the label, image and combobox
    */
   g_object_set (object,
-               "action", gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog)),
+               "action", gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->chooser)),
                NULL);
 
   priv->fs_volumes_changed_id =
@@ -888,7 +890,7 @@ gtk_file_chooser_button_set_property (GObject      *object,
          break;
        }
 
-      g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value);
+      g_object_set_property (G_OBJECT (priv->chooser), pspec->name, value);
       update_label_and_image (GTK_FILE_CHOOSER_BUTTON (object));
       update_combo_box (GTK_FILE_CHOOSER_BUTTON (object));
 
@@ -917,11 +919,11 @@ gtk_file_chooser_button_set_property (GObject      *object,
     case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
     case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION:
     case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS:
-      g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value);
+      g_object_set_property (G_OBJECT (priv->chooser), pspec->name, value);
       break;
 
     case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
-      g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value);
+      g_object_set_property (G_OBJECT (priv->chooser), pspec->name, value);
       fs_volumes_changed_cb (priv->fs, button);
       bookmarks_changed_cb (button);
       break;
@@ -964,7 +966,7 @@ gtk_file_chooser_button_get_property (GObject    *object,
     case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
     case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION:
     case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS:
-      g_object_get_property (G_OBJECT (priv->dialog), pspec->name, value);
+      g_object_get_property (G_OBJECT (priv->chooser), pspec->name, value);
       break;
 
     default:
@@ -1006,6 +1008,10 @@ gtk_file_chooser_button_destroy (GtkWidget *widget)
       priv->dialog = NULL;
     }
 
+  g_clear_object (&priv->native);
+
+  priv->chooser = NULL;
+
   if (priv->model && gtk_tree_model_get_iter_first (priv->model, &iter))
     {
       do
@@ -1173,7 +1179,7 @@ gtk_file_chooser_button_drag_data_received (GtkWidget          *widget,
        info->uris = uris;
        info->selected = FALSE;
        info->file_system = priv->fs;
-       g_object_get (priv->dialog, "action", &info->action, NULL);
+       g_object_get (priv->chooser, "action", &info->action, NULL);
 
        info->file = g_file_new_for_uri (info->uris[info->i]);
 
@@ -1190,7 +1196,7 @@ gtk_file_chooser_button_drag_data_received (GtkWidget          *widget,
     case TEXT_PLAIN:
       text = (char*) gtk_selection_data_get_text (data);
       file = g_file_new_for_uri (text);
-      gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->dialog), file, NULL);
+      gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->chooser), file, NULL);
       g_object_unref (file);
       g_free (text);
       g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
@@ -1228,7 +1234,10 @@ gtk_file_chooser_button_hide (GtkWidget *widget)
   GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
   GtkFileChooserButtonPrivate *priv = button->priv;
 
-  gtk_widget_hide (priv->dialog);
+  if (priv->dialog)
+    gtk_widget_hide (priv->dialog);
+  else
+    gtk_native_dialog_hide (GTK_NATIVE_DIALOG (priv->native));
 
   if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->hide)
     GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->hide (widget);
@@ -1247,7 +1256,7 @@ gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget,
   GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
   GtkFileChooserButtonPrivate *priv = button->priv;
 
-  switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog)))
+  switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->chooser)))
     {
     case GTK_FILE_CHOOSER_ACTION_OPEN:
       gtk_widget_grab_focus (priv->button);
@@ -1840,7 +1849,7 @@ model_add_volumes (GtkFileChooserButton *button,
 
   store = GTK_LIST_STORE (button->priv->model);
   pos = model_get_type_position (button, ROW_TYPE_VOLUME);
-  local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (button->priv->dialog));
+  local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (button->priv->chooser));
 
   for (l = volumes; l; l = l->next)
     {
@@ -1912,7 +1921,7 @@ model_add_bookmarks (GtkFileChooserButton *button,
 
   store = GTK_LIST_STORE (button->priv->model);
   pos = model_get_type_position (button, ROW_TYPE_BOOKMARK);
-  local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (button->priv->dialog));
+  local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (button->priv->chooser));
 
   for (l = bookmarks; l; l = l->next)
     {
@@ -2195,7 +2204,7 @@ filter_model_visible_func (GtkTreeModel *model,
 
   type = ROW_TYPE_INVALID;
   data = NULL;
-  local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (priv->dialog));
+  local_only = gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (priv->chooser));
 
   gtk_tree_model_get (model, iter,
                      TYPE_COLUMN, &type,
@@ -2616,8 +2625,8 @@ save_inactive_state (GtkFileChooserButton *button)
   if (priv->selection_while_inactive)
     g_object_unref (priv->selection_while_inactive);
 
-  priv->current_folder_while_inactive = gtk_file_chooser_get_current_folder_file (GTK_FILE_CHOOSER 
(priv->dialog));
-  priv->selection_while_inactive = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (priv->dialog));
+  priv->current_folder_while_inactive = gtk_file_chooser_get_current_folder_file (GTK_FILE_CHOOSER 
(priv->chooser));
+  priv->selection_while_inactive = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (priv->chooser));
 }
 
 static void
@@ -2626,12 +2635,12 @@ restore_inactive_state (GtkFileChooserButton *button)
   GtkFileChooserButtonPrivate *priv = button->priv;
 
   if (priv->current_folder_while_inactive)
-    gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (priv->dialog), 
priv->current_folder_while_inactive, NULL);
+    gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (priv->chooser), 
priv->current_folder_while_inactive, NULL);
 
   if (priv->selection_while_inactive)
-    gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->dialog), priv->selection_while_inactive, NULL);
+    gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->chooser), priv->selection_while_inactive, NULL);
   else
-    gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog));
+    gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->chooser));
 }
 
 /* Dialog */
@@ -2639,34 +2648,63 @@ static void
 open_dialog (GtkFileChooserButton *button)
 {
   GtkFileChooserButtonPrivate *priv = button->priv;
+  GtkWidget *toplevel;
+
+  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
 
   /* Setup the dialog parent to be chooser button's toplevel, and be modal
      as needed. */
-  if (!gtk_widget_get_visible (priv->dialog))
+  if (priv->dialog != NULL)
     {
-      GtkWidget *toplevel;
-
-      toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+      if (!gtk_widget_get_visible (priv->dialog))
+        {
+          if (gtk_widget_is_toplevel (toplevel) && GTK_IS_WINDOW (toplevel))
+            {
+              if (GTK_WINDOW (toplevel) != gtk_window_get_transient_for (GTK_WINDOW (priv->dialog)))
+                gtk_window_set_transient_for (GTK_WINDOW (priv->dialog),
+                                              GTK_WINDOW (toplevel));
 
-      if (gtk_widget_is_toplevel (toplevel) && GTK_IS_WINDOW (toplevel))
+              gtk_window_set_modal (GTK_WINDOW (priv->dialog),
+                                    gtk_window_get_modal (GTK_WINDOW (toplevel)));
+            }
+        }
+    }
+  else
+    {
+      if (!gtk_native_dialog_get_visible (GTK_NATIVE_DIALOG (priv->native)))
         {
-          if (GTK_WINDOW (toplevel) != gtk_window_get_transient_for (GTK_WINDOW (priv->dialog)))
-           gtk_window_set_transient_for (GTK_WINDOW (priv->dialog),
-                                         GTK_WINDOW (toplevel));
+          if (gtk_widget_is_toplevel (toplevel) && GTK_IS_WINDOW (toplevel))
+            {
+              if (GTK_WINDOW (toplevel) != gtk_native_dialog_get_transient_for (GTK_NATIVE_DIALOG 
(priv->native)))
+                gtk_native_dialog_set_transient_for (GTK_NATIVE_DIALOG (priv->native),
+                                                     GTK_WINDOW (toplevel));
 
-         gtk_window_set_modal (GTK_WINDOW (priv->dialog),
-                               gtk_window_get_modal (GTK_WINDOW (toplevel)));
-       }
+              gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (priv->native),
+                                           gtk_window_get_modal (GTK_WINDOW (toplevel)));
+            }
+        }
     }
 
   if (!priv->active)
     {
       restore_inactive_state (button);
       priv->active = TRUE;
+
+      /* Only handle update-preview handler if it is handled on the button */
+      if (g_signal_has_handler_pending (button,
+                                        g_signal_lookup ("update-preview", GTK_TYPE_FILE_CHOOSER),
+                                        0, TRUE))
+        {
+          g_signal_connect (priv->chooser, "update-preview",
+                            G_CALLBACK (chooser_update_preview_cb), button);
+        }
     }
 
   gtk_widget_set_sensitive (priv->combo_box, FALSE);
-  gtk_window_present (GTK_WINDOW (priv->dialog));
+  if (priv->dialog)
+    gtk_window_present (GTK_WINDOW (priv->dialog));
+  else
+    gtk_native_dialog_show (GTK_NATIVE_DIALOG (priv->native));
 }
 
 /* Combo Box */
@@ -2787,16 +2825,16 @@ button_clicked_cb (GtkButton *real_button,
 /* Dialog */
 
 static void
-dialog_update_preview_cb (GtkFileChooser *dialog,
-                         gpointer        user_data)
+chooser_update_preview_cb (GtkFileChooser *dialog,
+                           gpointer        user_data)
 {
   g_signal_emit_by_name (user_data, "update-preview");
 }
 
 static void
-dialog_notify_cb (GObject    *dialog,
-                 GParamSpec *pspec,
-                 gpointer    user_data)
+chooser_notify_cb (GObject    *dialog,
+                   GParamSpec *pspec,
+                   gpointer    user_data)
 {
   gpointer iface;
 
@@ -2826,7 +2864,7 @@ dialog_notify_cb (GObject    *dialog,
          /* If the path isn't local but we're in local-only mode now, remove
           * the custom-folder row */
          if (data && _gtk_file_has_native_path (G_FILE (data)) &&
-             gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (priv->dialog)))
+             gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (priv->chooser)))
            {
              pos--;
              model_remove_rows (user_data, pos, 2);
@@ -2849,11 +2887,9 @@ dialog_delete_event_cb (GtkWidget *dialog,
 }
 
 static void
-dialog_response_cb (GtkDialog *dialog,
-                   gint       response,
-                   gpointer   user_data)
+common_response_cb (GtkFileChooserButton *button,
+                   gint       response)
 {
-  GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
   GtkFileChooserButtonPrivate *priv = button->priv;
 
   if (response == GTK_RESPONSE_ACCEPT ||
@@ -2870,12 +2906,29 @@ dialog_response_cb (GtkDialog *dialog,
     }
 
   if (priv->active)
-    priv->active = FALSE;
+    {
+      priv->active = FALSE;
+
+      g_signal_handlers_disconnect_by_func (priv->chooser, chooser_update_preview_cb, button);
+    }
 
   update_label_and_image (button);
   update_combo_box (button);
 
   gtk_widget_set_sensitive (priv->combo_box, TRUE);
+}
+
+
+static void
+dialog_response_cb (GtkDialog *dialog,
+                   gint       response,
+                   gpointer   user_data)
+{
+  GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
+  GtkFileChooserButtonPrivate *priv = button->priv;
+
+  common_response_cb (button, response);
+
   gtk_widget_hide (priv->dialog);
 
   if (response == GTK_RESPONSE_ACCEPT ||
@@ -2883,6 +2936,22 @@ dialog_response_cb (GtkDialog *dialog,
     g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
 }
 
+static void
+native_response_cb (GtkFileChooserNative *native,
+                   gint       response,
+                   gpointer   user_data)
+{
+  GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
+
+  common_response_cb (button, response);
+
+  /* dialog already hidden */
+
+  if (response == GTK_RESPONSE_ACCEPT ||
+      response == GTK_RESPONSE_OK)
+    g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
+}
+
 
 /* ************************************************************************** *
  *  Public API                                                                *
@@ -2956,7 +3025,10 @@ gtk_file_chooser_button_set_title (GtkFileChooserButton *button,
 {
   g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
 
-  gtk_window_set_title (GTK_WINDOW (button->priv->dialog), title);
+  if (button->priv->dialog)
+    gtk_window_set_title (GTK_WINDOW (button->priv->dialog), title);
+  else
+    gtk_native_dialog_set_title (GTK_NATIVE_DIALOG (button->priv->native), title);
   g_object_notify (G_OBJECT (button), "title");
 }
 
@@ -2976,7 +3048,10 @@ gtk_file_chooser_button_get_title (GtkFileChooserButton *button)
 {
   g_return_val_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button), NULL);
 
-  return gtk_window_get_title (GTK_WINDOW (button->priv->dialog));
+  if (button->priv->dialog)
+    return gtk_window_get_title (GTK_WINDOW (button->priv->dialog));
+  else
+    return gtk_native_dialog_get_title (GTK_NATIVE_DIALOG (button->priv->native));
 }
 
 /**


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