mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 10:50:10 +00:00
gtkplacesview: don't rely on widgets on headers
We are showing a GtkSpinner on the networks header to provide feedback to the user if we are fetching networks, therefore we have to modify the spinner state when doing it. However GtkListBox doesn't give guarantees about the widgets set by gtk_list_box_set_header, and we could access an invalid widget. To avoid to access invalid widgets, bind the fetching networks view property to the networks header spinner active property instead of modifying directly the spinner in the private structure. Not having the spinner in the private structure also makes the code cleaner. https://bugzilla.gnome.org/show_bug.cgi?id=754150
This commit is contained in:
parent
bdb17a0890
commit
03cd8e9558
@ -69,7 +69,6 @@ struct _GtkPlacesViewPrivate
|
||||
GtkWidget *recent_servers_popover;
|
||||
GtkWidget *recent_servers_stack;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *network_header_spinner;
|
||||
GtkWidget *network_placeholder;
|
||||
GtkWidget *network_placeholder_label;
|
||||
|
||||
@ -100,6 +99,11 @@ static gboolean on_row_popup_menu (GtkPlacesViewR
|
||||
|
||||
static void populate_servers (GtkPlacesView *view);
|
||||
|
||||
static gboolean gtk_places_view_get_fetching_networks (GtkPlacesView *view);
|
||||
|
||||
static void gtk_places_view_set_fetching_networks (GtkPlacesView *view,
|
||||
gboolean fetching_networks);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkPlacesView, gtk_places_view, GTK_TYPE_BOX)
|
||||
|
||||
/* GtkPlacesView properties & signals */
|
||||
@ -107,6 +111,7 @@ enum {
|
||||
PROP_0,
|
||||
PROP_LOCAL_ONLY,
|
||||
PROP_OPEN_FLAGS,
|
||||
PROP_FETCHING_NETWORKS,
|
||||
PROP_LOADING,
|
||||
LAST_PROP
|
||||
};
|
||||
@ -416,6 +421,10 @@ gtk_places_view_get_property (GObject *object,
|
||||
g_value_set_boolean (value, gtk_places_view_get_loading (self));
|
||||
break;
|
||||
|
||||
case PROP_FETCHING_NETWORKS:
|
||||
g_value_set_boolean (value, gtk_places_view_get_fetching_networks (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -876,9 +885,8 @@ update_network_state (GtkPlacesView *view)
|
||||
gtk_list_box_invalidate_headers (GTK_LIST_BOX (priv->listbox));
|
||||
}
|
||||
|
||||
if (priv->fetching_networks)
|
||||
if (gtk_places_view_get_fetching_networks (view))
|
||||
{
|
||||
gtk_spinner_start (GTK_SPINNER (priv->network_header_spinner));
|
||||
/* only show a placeholder with a message if the list is empty.
|
||||
* otherwise just show the spinner in the header */
|
||||
if (!has_networks (view))
|
||||
@ -890,14 +898,12 @@ update_network_state (GtkPlacesView *view)
|
||||
}
|
||||
else if (!has_networks (view))
|
||||
{
|
||||
gtk_spinner_stop (GTK_SPINNER (priv->network_header_spinner));
|
||||
gtk_widget_show_all (priv->network_placeholder);
|
||||
gtk_label_set_text (GTK_LABEL (priv->network_placeholder_label),
|
||||
_("No network locations found"));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_spinner_stop (GTK_SPINNER (priv->network_header_spinner));
|
||||
gtk_widget_hide (priv->network_placeholder);
|
||||
}
|
||||
}
|
||||
@ -950,7 +956,7 @@ network_enumeration_next_files_finished (GObject *source_object,
|
||||
priv = gtk_places_view_get_instance_private (view);
|
||||
error = NULL;
|
||||
|
||||
priv->fetching_networks = FALSE;
|
||||
gtk_places_view_set_fetching_networks (view, FALSE);
|
||||
detected_networks = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source_object),
|
||||
res, &error);
|
||||
|
||||
@ -1021,7 +1027,7 @@ fetch_networks (GtkPlacesView *view)
|
||||
g_cancellable_cancel (priv->networks_fetching_cancellable);
|
||||
g_clear_object (&priv->networks_fetching_cancellable);
|
||||
priv->networks_fetching_cancellable = g_cancellable_new ();
|
||||
priv->fetching_networks = TRUE;
|
||||
gtk_places_view_set_fetching_networks (view, TRUE);
|
||||
update_network_state (view);
|
||||
|
||||
g_file_enumerate_children_async (network_file,
|
||||
@ -1053,7 +1059,6 @@ update_places (GtkPlacesView *view)
|
||||
children = gtk_container_get_children (GTK_CONTAINER (priv->listbox));
|
||||
g_list_free_full (children, (GDestroyNotify) gtk_widget_destroy);
|
||||
priv->network_placeholder = NULL;
|
||||
priv->network_header_spinner = NULL;
|
||||
|
||||
priv->loading = TRUE;
|
||||
g_object_notify_by_pspec (G_OBJECT (view), properties[PROP_LOADING]);
|
||||
@ -1931,11 +1936,9 @@ listbox_header_func (GtkListBoxRow *row,
|
||||
GtkListBoxRow *before,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkPlacesViewPrivate *priv;
|
||||
gboolean row_is_network;
|
||||
gchar *text;
|
||||
|
||||
priv = gtk_places_view_get_instance_private (GTK_PLACES_VIEW (user_data));
|
||||
text = NULL;
|
||||
row_is_network = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row), "is-network"));
|
||||
|
||||
@ -1973,18 +1976,25 @@ listbox_header_func (GtkListBoxRow *row,
|
||||
if (row_is_network)
|
||||
{
|
||||
GtkWidget *header_name;
|
||||
GtkWidget *network_header_spinner;
|
||||
|
||||
g_object_set (label,
|
||||
"margin-end", 6,
|
||||
NULL);
|
||||
|
||||
header_name = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
priv->network_header_spinner = gtk_spinner_new ();
|
||||
g_object_set (priv->network_header_spinner,
|
||||
network_header_spinner = gtk_spinner_new ();
|
||||
g_object_set (network_header_spinner,
|
||||
"margin-end", 12,
|
||||
NULL);
|
||||
g_object_bind_property (GTK_PLACES_VIEW (user_data),
|
||||
"fetching-networks",
|
||||
network_header_spinner,
|
||||
"active",
|
||||
G_BINDING_SYNC_CREATE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (header_name), label);
|
||||
gtk_container_add (GTK_CONTAINER (header_name), priv->network_header_spinner);
|
||||
gtk_container_add (GTK_CONTAINER (header_name), network_header_spinner);
|
||||
gtk_container_add (GTK_CONTAINER (header), header_name);
|
||||
}
|
||||
else
|
||||
@ -2190,6 +2200,13 @@ gtk_places_view_class_init (GtkPlacesViewClass *klass)
|
||||
FALSE,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_FETCHING_NETWORKS] =
|
||||
g_param_spec_boolean ("fetching-networks",
|
||||
P_("Fetching networks"),
|
||||
P_("Whether the view is fetching networks"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
properties[PROP_OPEN_FLAGS] =
|
||||
g_param_spec_flags ("open-flags",
|
||||
P_("Open Flags"),
|
||||
@ -2387,6 +2404,35 @@ gtk_places_view_get_loading (GtkPlacesView *view)
|
||||
return priv->loading;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_places_view_get_fetching_networks (GtkPlacesView *view)
|
||||
{
|
||||
GtkPlacesViewPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_PLACES_VIEW (view), FALSE);
|
||||
|
||||
priv = gtk_places_view_get_instance_private (view);
|
||||
|
||||
return priv->fetching_networks;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_places_view_set_fetching_networks (GtkPlacesView *view,
|
||||
gboolean fetching_networks)
|
||||
{
|
||||
GtkPlacesViewPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_PLACES_VIEW (view));
|
||||
|
||||
priv = gtk_places_view_get_instance_private (view);
|
||||
|
||||
if (priv->fetching_networks != fetching_networks)
|
||||
{
|
||||
priv->fetching_networks = fetching_networks;
|
||||
g_object_notify_by_pspec (G_OBJECT (view), properties [PROP_FETCHING_NETWORKS]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_places_view_get_local_only:
|
||||
* @view: a #GtkPlacesView
|
||||
|
Loading…
Reference in New Issue
Block a user