]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkappchooserdialog.c
gtk: Parse keypad numbers correctly
[~andy/gtk] / gtk / gtkappchooserdialog.c
index 35d1d1f2e39a78ffbd879079061f301ae976b0d7..8d03cc00c921de8d4c8bb5cd7ace9979a5b117e9 100644 (file)
@@ -35,6 +35,9 @@
  * of its own. Instead, you should get the embedded #GtkAppChooserWidget
  * using gtk_app_chooser_dialog_get_widget() and call its methods if
  * the generic #GtkAppChooser interface is not sufficient for your needs.
+ *
+ * To set the heading that is shown above the #GtkAppChooserWidget,
+ * use gtk_app_chooser_dialog_set_heading().
  */
 #include "config.h"
 
@@ -74,6 +77,7 @@ struct _GtkAppChooserDialogPrivate {
   GtkWidget *show_more_button;
 
   GtkAppChooserOnline *online;
+  GCancellable *online_cancellable;
 
   gboolean show_more_clicked;
 };
@@ -121,18 +125,25 @@ search_for_mimetype_ready_cb (GObject      *source,
   GtkAppChooserDialog *self = user_data;
   GError *error = NULL;
 
+  gdk_threads_enter ();
+
   _gtk_app_chooser_online_search_for_mimetype_finish (online, res, &error);
 
-  if (error != NULL)
+  if (error != NULL &&
+      !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
     {
       show_error_dialog (_("Failed to look for applications online"),
                          error->message, GTK_WINDOW (self));
-      g_error_free (error);
     }
   else
     {
+      gtk_widget_set_sensitive (self->priv->online_button, TRUE);
       gtk_app_chooser_refresh (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
     }
+
+  g_clear_error (&error);
+
+  gdk_threads_leave ();
 }
 
 static void
@@ -141,9 +152,13 @@ online_button_clicked_cb (GtkButton *b,
 {
   GtkAppChooserDialog *self = user_data;
 
+  self->priv->online_cancellable = g_cancellable_new ();
+  gtk_widget_set_sensitive (self->priv->online_button, FALSE);
+
   _gtk_app_chooser_online_search_for_mimetype_async (self->priv->online,
                                                     self->priv->content_type,
                                                     GTK_WINDOW (self),
+                                                     self->priv->online_cancellable,
                                                     search_for_mimetype_ready_cb,
                                                     self);
 }
@@ -155,6 +170,8 @@ app_chooser_online_get_default_ready_cb (GObject *source,
 {
   GtkAppChooserDialog *self = user_data;
 
+  gdk_threads_enter ();
+
   self->priv->online = _gtk_app_chooser_online_get_default_finish (source, res);
 
   if (self->priv->online != NULL)
@@ -176,6 +193,8 @@ app_chooser_online_get_default_ready_cb (GObject *source,
 
       gtk_widget_show (self->priv->online_button);
     }
+
+  gdk_threads_leave ();
 }
 
 static void
@@ -204,6 +223,12 @@ check_application (GtkAppChooserDialog  *self,
   command = NULL;
 
   info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
+  if (info == NULL)
+    {
+      *app_out = NULL;
+      return FALSE;
+    }
+
   command = g_app_info_get_executable (info);
 
   g_shell_parse_argv (command, &argc, &argv, &error);
@@ -250,13 +275,15 @@ add_or_find_application (GtkAppChooserDialog *self)
 
   app = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (self));
 
-  /* we don't care about reporting errors here */
-  if (self->priv->content_type)
-    g_app_info_set_as_last_used_for_type (app,
-                                         self->priv->content_type,
-                                         NULL);
-
-  g_object_unref (app);
+  if (app)
+    {
+      /* we don't care about reporting errors here */
+      if (self->priv->content_type)
+        g_app_info_set_as_last_used_for_type (app,
+                                              self->priv->content_type,
+                                              NULL);
+      g_object_unref (app);
+    }
 }
 
 static void
@@ -469,8 +496,8 @@ build_dialog_ui (GtkAppChooserDialog *self)
 {
   GtkWidget *vbox;
   GtkWidget *vbox2;
-  GtkWidget *label;
   GtkWidget *button, *w;
+  GAppInfo *info;
 
   gtk_container_set_border_width (GTK_CONTAINER (self), 5);
 
@@ -484,7 +511,8 @@ build_dialog_ui (GtkAppChooserDialog *self)
   gtk_widget_show (vbox2);
 
   self->priv->label = gtk_label_new ("");
-  gtk_misc_set_alignment (GTK_MISC (self->priv->label), 0, 0.5);
+  gtk_widget_set_halign (self->priv->label, GTK_ALIGN_START);
+  gtk_widget_set_valign (self->priv->label, GTK_ALIGN_CENTER);
   gtk_label_set_line_wrap (GTK_LABEL (self->priv->label), TRUE);
   gtk_box_pack_start (GTK_BOX (vbox2), self->priv->label,
                       FALSE, FALSE, 0);
@@ -519,23 +547,14 @@ build_dialog_ui (GtkAppChooserDialog *self)
                          GTK_STOCK_CANCEL,
                          GTK_RESPONSE_CANCEL);
 
-  /* Create a custom stock icon */
-  self->priv->button = gtk_button_new ();
-
-  label = gtk_label_new_with_mnemonic (_("_Select"));
-  gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (self->priv->button));
-  gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
-  gtk_widget_show (label);
-  self->priv->open_label = label;
+  self->priv->button = gtk_dialog_add_button (GTK_DIALOG (self),
+                                              _("_Select"),
+                                              GTK_RESPONSE_OK);
 
-  gtk_container_add (GTK_CONTAINER (self->priv->button),
-                     self->priv->open_label);
-
-  gtk_widget_show (self->priv->button);
-  gtk_widget_set_can_default (self->priv->button, TRUE);
-
-  gtk_dialog_add_action_widget (GTK_DIALOG (self),
-                                self->priv->button, GTK_RESPONSE_OK);
+  info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
+  gtk_widget_set_sensitive (self->priv->button, info != NULL);
+  if (info)
+    g_object_unref (info);
 
   gtk_dialog_set_default_response (GTK_DIALOG (self),
                                    GTK_RESPONSE_OK);
@@ -601,6 +620,12 @@ gtk_app_chooser_dialog_dispose (GObject *object)
   g_clear_object (&self->priv->gfile);
   g_clear_object (&self->priv->online);
 
+  if (self->priv->online_cancellable != NULL)
+    {
+      g_cancellable_cancel (self->priv->online_cancellable);
+      g_clear_object (&self->priv->online_cancellable);
+    }
+
   G_OBJECT_CLASS (gtk_app_chooser_dialog_parent_class)->dispose (object);
 }