filechooserbutton: Emit 'selection-changed' when changing the selection programmatically

We only emitted that signal when the selection changed through the underlying GtkFileChooserDialog.

To do this when the dialog is not active and the selection is changed by the calling program
(instead of by the user), we need to wait until the GtkFileChooserButton's UI has been updated
via an async callback from GIO.  So, we keep track of whether an entry point into the
button's API caused a programmatic change in the selection.

Signed-off-by: Federico Mena Quintero <federico@gnome.org>
This commit is contained in:
Federico Mena Quintero 2013-03-11 21:54:22 -06:00
parent a8c4d0935b
commit fa4878979e

View File

@ -208,6 +208,9 @@ struct _GtkFileChooserButtonPrivate
guint active : 1;
guint focus_on_click : 1;
/* Whether the next async callback from GIO should emit the "selection-changed" signal */
guint is_changing_selection : 1;
};
@ -591,6 +594,18 @@ gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface)
iface->remove_shortcut_folder = gtk_file_chooser_button_remove_shortcut_folder;
}
static void
emit_selection_changed_if_changing_selection (GtkFileChooserButton *button)
{
GtkFileChooserButtonPrivate *priv = button->priv;
if (priv->is_changing_selection)
{
priv->is_changing_selection = FALSE;
g_signal_emit_by_name (button, "selection-changed");
}
}
static gboolean
gtk_file_chooser_button_set_current_folder (GtkFileChooser *chooser,
GFile *file,
@ -662,6 +677,8 @@ gtk_file_chooser_button_select_file (GtkFileChooser *chooser,
priv->selection_while_inactive = g_object_ref (file);
priv->is_changing_selection = TRUE;
update_label_and_image (button);
update_combo_box (button);
@ -692,6 +709,8 @@ gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser,
priv->selection_while_inactive = NULL;
}
priv->is_changing_selection = TRUE;
update_label_and_image (button);
update_combo_box (button);
}
@ -2556,6 +2575,8 @@ update_label_get_info_cb (GCancellable *cancellable,
g_object_unref (pixbuf);
out:
emit_selection_changed_if_changing_selection (button);
g_object_unref (button);
g_object_unref (cancellable);
}
@ -2566,10 +2587,12 @@ update_label_and_image (GtkFileChooserButton *button)
GtkFileChooserButtonPrivate *priv = button->priv;
gchar *label_text;
GFile *file;
gboolean done_changing_selection;
file = get_selected_file (button);
label_text = NULL;
done_changing_selection = FALSE;
if (priv->update_button_cancellable)
{
@ -2607,7 +2630,10 @@ update_label_and_image (GtkFileChooserButton *button)
_gtk_file_system_volume_unref (volume);
if (label_text)
{
done_changing_selection = TRUE;
goto out;
}
}
if (g_file_is_native (file))
@ -2629,8 +2655,16 @@ update_label_and_image (GtkFileChooserButton *button)
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
if (pixbuf)
g_object_unref (pixbuf);
done_changing_selection = TRUE;
}
}
else
{
/* We know the selection is empty */
done_changing_selection = TRUE;
}
out:
if (file)
@ -2646,6 +2680,9 @@ out:
gtk_label_set_text (GTK_LABEL (priv->label), _(FALLBACK_DISPLAY_NAME));
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), NULL);
}
if (done_changing_selection)
emit_selection_changed_if_changing_selection (button);
}