printers: Make call of DevicesGet cancellable
Pass a GCancellable object to g_dbus_proxy_call() for DevicesGet method. This assures that g-c-c won't crash when user cancels addition of new printer before the call is finished (rhbz#691931).
This commit is contained in:
parent
eb623389fc
commit
6e479859ed
1 changed files with 140 additions and 119 deletions
|
@ -112,6 +112,8 @@ struct _PpNewPrinterDialog {
|
||||||
|
|
||||||
UserResponseCallback user_callback;
|
UserResponseCallback user_callback;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
|
|
||||||
|
GCancellable *cancellable;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -198,11 +200,11 @@ store_device_parameter (gpointer key,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
devices_get_cb (GObject *source_object,
|
devices_get_cb (GObject *source_object,
|
||||||
GAsyncResult *res,
|
GAsyncResult *res,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
PpNewPrinterDialog *pp = (PpNewPrinterDialog *) user_data;
|
PpNewPrinterDialog *pp = user_data;
|
||||||
GHashTable *devices = NULL;
|
GHashTable *devices = NULL;
|
||||||
GtkWidget *widget = NULL;
|
GtkWidget *widget = NULL;
|
||||||
GVariant *dg_output = NULL;
|
GVariant *dg_output = NULL;
|
||||||
|
@ -214,136 +216,145 @@ devices_get_cb (GObject *source_object,
|
||||||
res,
|
res,
|
||||||
&error);
|
&error);
|
||||||
|
|
||||||
if (dg_output && g_variant_n_children (dg_output) == 2)
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
{
|
{
|
||||||
GVariant *devices_variant = NULL;
|
if (dg_output && g_variant_n_children (dg_output) == 2)
|
||||||
|
|
||||||
g_variant_get (dg_output, "(&s@a{ss})",
|
|
||||||
&ret_error,
|
|
||||||
&devices_variant);
|
|
||||||
|
|
||||||
if (devices_variant)
|
|
||||||
{
|
{
|
||||||
if (g_variant_is_of_type (devices_variant, G_VARIANT_TYPE ("a{ss}")))
|
GVariant *devices_variant = NULL;
|
||||||
|
|
||||||
|
g_variant_get (dg_output, "(&s@a{ss})",
|
||||||
|
&ret_error,
|
||||||
|
&devices_variant);
|
||||||
|
|
||||||
|
if (devices_variant)
|
||||||
{
|
{
|
||||||
GVariantIter *iter;
|
if (g_variant_is_of_type (devices_variant, G_VARIANT_TYPE ("a{ss}")))
|
||||||
GVariant *item;
|
|
||||||
g_variant_get (devices_variant,
|
|
||||||
"a{ss}",
|
|
||||||
&iter);
|
|
||||||
devices = g_hash_table_new (g_str_hash, g_str_equal);
|
|
||||||
while ((item = g_variant_iter_next_value (iter)))
|
|
||||||
{
|
{
|
||||||
gchar *key;
|
GVariantIter *iter;
|
||||||
gchar *value;
|
GVariant *item;
|
||||||
g_variant_get (item,
|
g_variant_get (devices_variant,
|
||||||
"{ss}",
|
"a{ss}",
|
||||||
&key,
|
&iter);
|
||||||
&value);
|
devices = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
|
while ((item = g_variant_iter_next_value (iter)))
|
||||||
g_hash_table_insert (devices, key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_variant_unref (devices_variant);
|
|
||||||
}
|
|
||||||
g_variant_unref (dg_output);
|
|
||||||
}
|
|
||||||
g_object_unref (source_object);
|
|
||||||
|
|
||||||
if (error || (ret_error && ret_error[0] != '\0'))
|
|
||||||
{
|
|
||||||
if (error)
|
|
||||||
g_warning ("%s", error->message);
|
|
||||||
|
|
||||||
if (ret_error && ret_error[0] != '\0')
|
|
||||||
g_warning ("%s", ret_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
free_devices (pp);
|
|
||||||
if (devices)
|
|
||||||
{
|
|
||||||
GList *keys;
|
|
||||||
GList *iter;
|
|
||||||
gchar *cut;
|
|
||||||
gint max_index = -1;
|
|
||||||
gint index;
|
|
||||||
|
|
||||||
keys = g_hash_table_get_keys (devices);
|
|
||||||
for (iter = keys; iter; iter = iter->next)
|
|
||||||
{
|
|
||||||
index = -1;
|
|
||||||
|
|
||||||
cut = g_strrstr ((gchar *)iter->data, ":");
|
|
||||||
if (cut)
|
|
||||||
index = atoi (cut + 1);
|
|
||||||
|
|
||||||
if (index > max_index)
|
|
||||||
max_index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_index >= 0)
|
|
||||||
{
|
|
||||||
pp->num_devices = max_index + 1;
|
|
||||||
pp->devices = g_new0 (CupsDevice, pp->num_devices);
|
|
||||||
|
|
||||||
g_hash_table_foreach (devices, store_device_parameter, pp);
|
|
||||||
|
|
||||||
/* Assign names to devices */
|
|
||||||
for (i = 0; i < pp->num_devices; i++)
|
|
||||||
{
|
|
||||||
gchar *name = NULL;
|
|
||||||
|
|
||||||
if (pp->devices[i].device_id)
|
|
||||||
{
|
|
||||||
name = get_tag_value (pp->devices[i].device_id, "mdl");
|
|
||||||
name = g_strcanon (name, ALLOWED_CHARACTERS, '-');
|
|
||||||
}
|
|
||||||
else if (pp->devices[i].device_info)
|
|
||||||
{
|
|
||||||
name = g_strdup (pp->devices[i].device_info);
|
|
||||||
name = g_strcanon (name, ALLOWED_CHARACTERS, '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
pp->devices[i].display_name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set show bool
|
|
||||||
* Don't show duplicates.
|
|
||||||
* Show devices with device-id.
|
|
||||||
* Other preferences should apply here.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < pp->num_devices; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < pp->num_devices; j++)
|
|
||||||
{
|
|
||||||
if (i != j)
|
|
||||||
{
|
{
|
||||||
if (g_strcmp0 (pp->devices[i].display_name, pp->devices[j].display_name) == 0)
|
gchar *key;
|
||||||
|
gchar *value;
|
||||||
|
g_variant_get (item,
|
||||||
|
"{ss}",
|
||||||
|
&key,
|
||||||
|
&value);
|
||||||
|
|
||||||
|
g_hash_table_insert (devices, key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_variant_unref (devices_variant);
|
||||||
|
}
|
||||||
|
g_variant_unref (dg_output);
|
||||||
|
}
|
||||||
|
g_object_unref (source_object);
|
||||||
|
|
||||||
|
if (error || (ret_error && ret_error[0] != '\0'))
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
g_warning ("%s", error->message);
|
||||||
|
|
||||||
|
if (ret_error && ret_error[0] != '\0')
|
||||||
|
g_warning ("%s", ret_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_devices (pp);
|
||||||
|
if (devices)
|
||||||
|
{
|
||||||
|
GList *keys;
|
||||||
|
GList *iter;
|
||||||
|
gchar *cut;
|
||||||
|
gint max_index = -1;
|
||||||
|
gint index;
|
||||||
|
|
||||||
|
keys = g_hash_table_get_keys (devices);
|
||||||
|
for (iter = keys; iter; iter = iter->next)
|
||||||
|
{
|
||||||
|
index = -1;
|
||||||
|
|
||||||
|
cut = g_strrstr ((gchar *)iter->data, ":");
|
||||||
|
if (cut)
|
||||||
|
index = atoi (cut + 1);
|
||||||
|
|
||||||
|
if (index > max_index)
|
||||||
|
max_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_index >= 0)
|
||||||
|
{
|
||||||
|
pp->num_devices = max_index + 1;
|
||||||
|
pp->devices = g_new0 (CupsDevice, pp->num_devices);
|
||||||
|
|
||||||
|
g_hash_table_foreach (devices, store_device_parameter, pp);
|
||||||
|
|
||||||
|
/* Assign names to devices */
|
||||||
|
for (i = 0; i < pp->num_devices; i++)
|
||||||
|
{
|
||||||
|
gchar *name = NULL;
|
||||||
|
|
||||||
|
if (pp->devices[i].device_id)
|
||||||
|
{
|
||||||
|
name = get_tag_value (pp->devices[i].device_id, "mdl");
|
||||||
|
name = g_strcanon (name, ALLOWED_CHARACTERS, '-');
|
||||||
|
}
|
||||||
|
else if (pp->devices[i].device_info)
|
||||||
|
{
|
||||||
|
name = g_strdup (pp->devices[i].device_info);
|
||||||
|
name = g_strcanon (name, ALLOWED_CHARACTERS, '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
pp->devices[i].display_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set show bool
|
||||||
|
* Don't show duplicates.
|
||||||
|
* Show devices with device-id.
|
||||||
|
* Other preferences should apply here.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < pp->num_devices; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < pp->num_devices; j++)
|
||||||
|
{
|
||||||
|
if (i != j)
|
||||||
{
|
{
|
||||||
if (pp->devices[i].device_id && !pp->devices[j].show)
|
if (g_strcmp0 (pp->devices[i].display_name, pp->devices[j].display_name) == 0)
|
||||||
{
|
{
|
||||||
pp->devices[i].show = TRUE;
|
if (pp->devices[i].device_id && !pp->devices[j].show)
|
||||||
|
{
|
||||||
|
pp->devices[i].show = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_hash_table_destroy (devices);
|
||||||
|
actualize_devices_list (pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_destroy (devices);
|
widget = (GtkWidget*)
|
||||||
actualize_devices_list (pp);
|
gtk_builder_get_object (pp->builder, "get-devices-status-label");
|
||||||
|
gtk_label_set_text (GTK_LABEL (widget), " ");
|
||||||
|
|
||||||
|
widget = (GtkWidget*)
|
||||||
|
gtk_builder_get_object (pp->builder, "spinner");
|
||||||
|
gtk_spinner_stop (GTK_SPINNER (widget));
|
||||||
|
gtk_widget_set_sensitive (widget, FALSE);
|
||||||
|
|
||||||
|
if (pp->cancellable != NULL)
|
||||||
|
{
|
||||||
|
g_object_unref (pp->cancellable);
|
||||||
|
pp->cancellable = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
widget = (GtkWidget*)
|
|
||||||
gtk_builder_get_object (pp->builder, "get-devices-status-label");
|
|
||||||
gtk_label_set_text (GTK_LABEL (widget), " ");
|
|
||||||
|
|
||||||
widget = (GtkWidget*)
|
|
||||||
gtk_builder_get_object (pp->builder, "spinner");
|
|
||||||
gtk_spinner_stop (GTK_SPINNER (widget));
|
|
||||||
gtk_widget_set_sensitive (widget, FALSE);
|
|
||||||
|
|
||||||
g_clear_error (&error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -385,12 +396,14 @@ devices_get (PpNewPrinterDialog *pp)
|
||||||
gtk_spinner_start (GTK_SPINNER (widget));
|
gtk_spinner_start (GTK_SPINNER (widget));
|
||||||
gtk_widget_set_sensitive (widget, TRUE);
|
gtk_widget_set_sensitive (widget, TRUE);
|
||||||
|
|
||||||
|
pp->cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
g_dbus_proxy_call (proxy,
|
g_dbus_proxy_call (proxy,
|
||||||
"DevicesGet",
|
"DevicesGet",
|
||||||
dg_input,
|
dg_input,
|
||||||
G_DBUS_CALL_FLAGS_NONE,
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
60000,
|
60000,
|
||||||
NULL,
|
pp->cancellable,
|
||||||
devices_get_cb,
|
devices_get_cb,
|
||||||
pp);
|
pp);
|
||||||
|
|
||||||
|
@ -1101,6 +1114,8 @@ pp_new_printer_dialog_new (GtkWindow *parent,
|
||||||
pp->user_callback = user_callback;
|
pp->user_callback = user_callback;
|
||||||
pp->user_data = user_data;
|
pp->user_data = user_data;
|
||||||
|
|
||||||
|
pp->cancellable = NULL;
|
||||||
|
|
||||||
/* connect signals */
|
/* connect signals */
|
||||||
g_signal_connect (pp->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
|
g_signal_connect (pp->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
|
||||||
|
|
||||||
|
@ -1145,6 +1160,12 @@ pp_new_printer_dialog_free (PpNewPrinterDialog *pp)
|
||||||
g_object_unref (pp->builder);
|
g_object_unref (pp->builder);
|
||||||
pp->builder = NULL;
|
pp->builder = NULL;
|
||||||
|
|
||||||
|
if (pp->cancellable)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (pp->cancellable);
|
||||||
|
g_object_unref (pp->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
g_free (pp);
|
g_free (pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue