--- gnome-control-center-3.28.2/panels/printers/cc-printers-panel.c +++ gnome-control-center-3.28.2/panels/printers/cc-printers-panel.c @@ -105,6 +105,8 @@ struct _CcPrintersPanelPrivate gchar *renamed_printer_name; gchar *old_printer_name; gchar *deleted_printer_name; + GList *deleted_printers; + GObject *reference; GHashTable *printer_entries; gboolean entries_filled; @@ -267,18 +269,40 @@ printer_removed_cb (GObject *source GAsyncResult *result, gpointer user_data) { - GError *error = NULL; + PpPrinter *printer = PP_PRINTER (source_object); + g_autoptr(GError) error = NULL; + g_autofree gchar *printer_name = NULL; - pp_printer_delete_finish (PP_PRINTER (source_object), result, &error); - g_object_unref (source_object); + g_object_get (printer, "printer-name", &printer_name, NULL); + pp_printer_delete_finish (printer, result, &error); - if (error != NULL) + if (user_data != NULL) { - g_warning ("Printer could not be deleted: %s", error->message); - g_error_free (error); + g_autoptr(GObject) reference = G_OBJECT (user_data); + + if (g_object_get_data (reference, "self") != NULL) + { + CcPrintersPanel *self = CC_PRINTERS_PANEL (g_object_get_data (reference, "self")); + CcPrintersPanelPrivate *priv = self->priv; + GList *iter; + + for (iter = priv->deleted_printers; iter != NULL; iter = iter->next) + { + if (g_strcmp0 (iter->data, printer_name) == 0) + { + g_free (iter->data); + priv->deleted_printers = g_list_delete_link (priv->deleted_printers, iter); + break; + } + } + } } + + if (error != NULL) + g_warning ("Printer could not be deleted: %s", error->message); } + static void cc_printers_panel_dispose (GObject *object) { @@ -368,6 +392,12 @@ cc_printers_panel_dispose (GObject *obje g_clear_pointer (&priv->printer_entries, g_hash_table_destroy); + g_list_free_full (priv->deleted_printers, g_free); + priv->deleted_printers = NULL; + if (priv->reference != NULL) + g_object_set_data (priv->reference, "self", NULL); + g_clear_object (&priv->reference); + G_OBJECT_CLASS (cc_printers_panel_parent_class)->dispose (object); } @@ -740,13 +770,16 @@ on_printer_deletion_undone (GtkButton *b { CcPrintersPanelPrivate *priv; CcPrintersPanel *self = (CcPrintersPanel*) user_data; + GtkWidget *widget; priv = PRINTERS_PANEL_PRIVATE (self); gtk_revealer_set_reveal_child (priv->notification, FALSE); g_clear_pointer (&priv->deleted_printer_name, g_free); - actualize_printers_list (self); + + widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "content"); + gtk_list_box_invalidate_filter (GTK_LIST_BOX (widget)); cancel_notification_timeout (self); } @@ -768,9 +801,11 @@ on_notification_dismissed (GtkButton *bu pp_printer_delete_async (printer, NULL, printer_removed_cb, - NULL); + g_object_ref (priv->reference)); - g_clear_pointer (&priv->deleted_printer_name, g_free); + priv->deleted_printers = g_list_prepend (priv->deleted_printers, priv->deleted_printer_name); + priv->deleted_printer_name = NULL; + g_object_unref (printer); } gtk_revealer_set_reveal_child (priv->notification, FALSE); @@ -793,8 +828,7 @@ on_printer_deleted (PpPrinterEntry *prin GtkLabel *label; gchar *notification_message; gchar *printer_name; - - gtk_widget_hide (GTK_WIDGET (printer_entry)); + GtkWidget *widget; priv = PRINTERS_PANEL_PRIVATE (self); @@ -816,6 +850,9 @@ on_printer_deleted (PpPrinterEntry *prin priv->deleted_printer_name = g_strdup (printer_name); g_free (printer_name); + widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "content"); + gtk_list_box_invalidate_filter (GTK_LIST_BOX (widget)); + gtk_revealer_set_reveal_child (priv->notification, TRUE); priv->remove_printer_timeout_id = g_timeout_add_seconds (10, on_remove_printer_timeout, self); @@ -910,6 +947,36 @@ set_current_page (GObject *source_o } static void +destroy_nonexisting_entries (PpPrinterEntry *entry, + gpointer user_data) +{ + CcPrintersPanelPrivate *priv; + CcPrintersPanel *self = (CcPrintersPanel *) user_data; + g_autofree gchar *printer_name = NULL; + gboolean exists = FALSE; + gint i; + + priv = PRINTERS_PANEL_PRIVATE (self); + + g_object_get (G_OBJECT (entry), "printer-name", &printer_name, NULL); + + for (i = 0; i < priv->num_dests; i++) + { + if (g_strcmp0 (priv->dests[i].name, printer_name) == 0) + { + exists = TRUE; + break; + } + } + + if (!exists) + { + gtk_widget_destroy (GTK_WIDGET (entry)); + g_hash_table_remove (priv->printer_entries, printer_name); + } +} + +static void actualize_printers_list_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) @@ -920,6 +987,7 @@ actualize_printers_list_cb (GObject PpCups *cups = PP_CUPS (source_object); PpCupsDests *cups_dests; gboolean new_printer_available = FALSE; + gpointer item; GError *error = NULL; int i; @@ -950,7 +1018,7 @@ actualize_printers_list_cb (GObject gtk_stack_set_visible_child_name (GTK_STACK (widget), "printers-list"); widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "content"); - gtk_container_foreach (GTK_CONTAINER (widget), (GtkCallback) gtk_widget_destroy, NULL); + gtk_container_foreach (GTK_CONTAINER (widget), (GtkCallback) destroy_nonexisting_entries, self); for (i = 0; i < priv->num_dests; i++) { @@ -961,13 +1029,14 @@ actualize_printers_list_cb (GObject for (i = 0; i < priv->num_dests; i++) { - if (g_strcmp0 (priv->dests[i].name, priv->deleted_printer_name) == 0) - continue; - if (new_printer_available && g_strcmp0 (priv->dests[i].name, priv->old_printer_name) == 0) continue; - add_printer_entry (self, priv->dests[i]); + item = g_hash_table_lookup (priv->printer_entries, priv->dests[i].name); + if (item != NULL) + pp_printer_entry_update (PP_PRINTER_ENTRY (item), priv->dests[i], priv->is_authorized); + else + add_printer_entry (self, priv->dests[i]); } if (!priv->entries_filled) @@ -983,6 +1052,30 @@ actualize_printers_list_cb (GObject } update_sensitivity (user_data); + + if (priv->new_printer_name != NULL) + { + GtkScrolledWindow *scrolled_window; + GtkAllocation allocation; + GtkAdjustment *adjustment; + GtkWidget *printer_entry; + + /* Scroll the view to show the newly added printer-entry. */ + scrolled_window = GTK_SCROLLED_WINDOW (gtk_builder_get_object (priv->builder, + "scrolled-window")); + adjustment = gtk_scrolled_window_get_vadjustment (scrolled_window); + + printer_entry = GTK_WIDGET (g_hash_table_lookup (priv->printer_entries, + priv->new_printer_name)); + if (printer_entry != NULL) + { + gtk_widget_get_allocation (printer_entry, &allocation); + g_clear_pointer (&priv->new_printer_name, g_free); + + gtk_adjustment_set_value (adjustment, + allocation.y - gtk_widget_get_margin_top (printer_entry)); + } + } } static void @@ -1028,10 +1121,6 @@ new_printer_dialog_response_cb (PpNewPri { CcPrintersPanelPrivate *priv; CcPrintersPanel *self = (CcPrintersPanel*) user_data; - GtkScrolledWindow *scrolled_window; - GtkAllocation allocation; - GtkAdjustment *adjustment; - GtkWidget *printer_entry; priv = PRINTERS_PANEL_PRIVATE (self); @@ -1059,22 +1148,6 @@ new_printer_dialog_response_cb (PpNewPri } actualize_printers_list (self); - - if (priv->new_printer_name == NULL) - return; - - /* Scroll the view to show the newly added printer-entry. */ - scrolled_window = GTK_SCROLLED_WINDOW (gtk_builder_get_object (priv->builder, - "scrolled-window")); - adjustment = gtk_scrolled_window_get_vadjustment (scrolled_window); - - printer_entry = GTK_WIDGET (g_hash_table_lookup (priv->printer_entries, - priv->new_printer_name)); - gtk_widget_get_allocation (printer_entry, &allocation); - g_clear_pointer (&priv->new_printer_name, g_free); - - gtk_adjustment_set_value (adjustment, - allocation.y - gtk_widget_get_margin_top (printer_entry)); } static void @@ -1288,11 +1361,17 @@ filter_function (GtkListBoxRow *row, CcPrintersPanel *self = (CcPrintersPanel*) user_data; GtkWidget *search_entry; gboolean retval; - gchar *search; - gchar *name; - gchar *location; - gchar *printer_name; - gchar *printer_location; + g_autofree gchar *search = NULL; + g_autofree gchar *name = NULL; + g_autofree gchar *location = NULL; + g_autofree gchar *printer_name = NULL; + g_autofree gchar *printer_location = NULL; + GList *iter; + + g_object_get (G_OBJECT (row), + "printer-name", &printer_name, + "printer-location", &printer_location, + NULL); priv = PRINTERS_PANEL_PRIVATE (self); @@ -1300,31 +1379,72 @@ filter_function (GtkListBoxRow *row, gtk_builder_get_object (priv->builder, "search-entry"); if (gtk_entry_get_text_length (GTK_ENTRY (search_entry)) == 0) - return TRUE; + { + retval = TRUE; + } + else + { + name = cc_util_normalize_casefold_and_unaccent (printer_name); + location = cc_util_normalize_casefold_and_unaccent (printer_location); - g_object_get (G_OBJECT (row), - "printer-name", &printer_name, - "printer-location", &printer_location, - NULL); + search = cc_util_normalize_casefold_and_unaccent (gtk_entry_get_text (GTK_ENTRY (search_entry))); - name = cc_util_normalize_casefold_and_unaccent (printer_name); - location = cc_util_normalize_casefold_and_unaccent (printer_location); + retval = strstr (name, search) != NULL; + if (location != NULL) + retval = retval || (strstr (location, search) != NULL); + } - g_free (printer_name); - g_free (printer_location); + if (priv->deleted_printer_name != NULL && + g_strcmp0 (priv->deleted_printer_name, printer_name) == 0) + { + retval = FALSE; + } - search = cc_util_normalize_casefold_and_unaccent (gtk_entry_get_text (GTK_ENTRY (search_entry))); + if (priv->deleted_printers != NULL) + { + for (iter = priv->deleted_printers; iter != NULL; iter = iter->next) + { + if (g_strcmp0 (iter->data, printer_name) == 0) + { + retval = FALSE; + break; + } + } + } + return retval; +} - retval = strstr (name, search) != NULL; - if (location != NULL) - retval = retval || (strstr (location, search) != NULL); +static gint +sort_function (GtkListBoxRow *row1, + GtkListBoxRow *row2, + gpointer user_data) +{ + g_autofree gchar *printer_name1 = NULL; + g_autofree gchar *printer_name2 = NULL; - g_free (search); - g_free (name); - g_free (location); + g_object_get (G_OBJECT (row1), + "printer-name", &printer_name1, + NULL); - return retval; + g_object_get (G_OBJECT (row2), + "printer-name", &printer_name2, + NULL); + + if (printer_name1 != NULL) + { + if (printer_name2 != NULL) + return g_ascii_strcasecmp (printer_name1, printer_name2); + else + return 1; + } + else + { + if (printer_name2 != NULL) + return -1; + else + return 0; + } } static void @@ -1364,6 +1484,8 @@ cc_printers_panel_init (CcPrintersPanel priv->renamed_printer_name = NULL; priv->old_printer_name = NULL; priv->deleted_printer_name = NULL; + priv->deleted_printers = NULL; + priv->reference = g_object_new (G_TYPE_OBJECT, NULL); priv->permission = NULL; priv->lockdown_settings = NULL; @@ -1380,6 +1502,8 @@ cc_printers_panel_init (CcPrintersPanel priv->actualize_printers_list_cancellable = g_cancellable_new (); priv->cups_status_check_cancellable = g_cancellable_new (); + g_object_set_data_full (priv->reference, "self", self, NULL); + builder_result = gtk_builder_add_objects_from_resource (priv->builder, "/org/gnome/control-center/printers/printers.ui", objects, &error); @@ -1430,6 +1554,10 @@ cc_printers_panel_init (CcPrintersPanel "search-changed", G_CALLBACK (gtk_list_box_invalidate_filter), widget); + gtk_list_box_set_sort_func (GTK_LIST_BOX (widget), + sort_function, + NULL, + NULL); priv->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown"); if (priv->lockdown_settings) --- gnome-control-center-3.28.2/panels/printers/pp-printer-entry.c +++ gnome-control-center-3.28.2/panels/printers/pp-printer-entry.c @@ -45,7 +45,6 @@ struct _PpPrinterEntry { GtkListBoxRow parent; - gchar *printer_uri; gchar *printer_name; gchar *ppd_file_name; int num_jobs; @@ -156,10 +155,27 @@ pp_printer_entry_set_property (GObject } } +static InkLevelData * +ink_level_data_new (void) +{ + return g_slice_new0 (InkLevelData); +} + +static void +ink_level_data_free (InkLevelData *data) +{ + g_clear_pointer (&data->marker_names, g_free); + g_clear_pointer (&data->marker_levels, g_free); + g_clear_pointer (&data->marker_colors, g_free); + g_clear_pointer (&data->marker_types, g_free); + g_slice_free (InkLevelData, data); +} + static void pp_printer_entry_init (PpPrinterEntry *self) { gtk_widget_init_template (GTK_WIDGET (self)); + self->inklevel = ink_level_data_new (); } typedef struct { @@ -260,9 +276,8 @@ tone_down_color (GdkRGBA *color, } static gboolean -supply_levels_draw_cb (GtkWidget *widget, - cairo_t *cr, - PpPrinterEntry *self) +supply_levels_draw_cb (PpPrinterEntry *self, + cairo_t *cr) { GtkStyleContext *context; gboolean is_empty = TRUE; @@ -271,10 +286,10 @@ supply_levels_draw_cb (GtkWidget *w gint height; int i; - context = gtk_widget_get_style_context (widget); + context = gtk_widget_get_style_context (GTK_WIDGET (self->supply_drawing_area)); - width = gtk_widget_get_allocated_width (widget); - height = gtk_widget_get_allocated_height (widget); + width = gtk_widget_get_allocated_width (GTK_WIDGET (self->supply_drawing_area)); + height = gtk_widget_get_allocated_height (GTK_WIDGET (self->supply_drawing_area)); gtk_render_background (context, cr, 0, 0, width, height); @@ -376,13 +391,13 @@ supply_levels_draw_cb (GtkWidget *w if (tooltip_text) { - gtk_widget_set_tooltip_text (widget, tooltip_text); + gtk_widget_set_tooltip_text (GTK_WIDGET (self->supply_drawing_area), tooltip_text); g_free (tooltip_text); } else { - gtk_widget_set_tooltip_text (widget, NULL); - gtk_widget_set_has_tooltip (widget, FALSE); + gtk_widget_set_tooltip_text (GTK_WIDGET (self->supply_drawing_area), NULL); + gtk_widget_set_has_tooltip (GTK_WIDGET (self->supply_drawing_area), FALSE); } } @@ -727,11 +742,34 @@ pp_printer_entry_new (cups_dest_t print gboolean is_authorized) { PpPrinterEntry *self; + + self = g_object_new (PP_PRINTER_ENTRY_TYPE, "printer-name", printer.name, NULL); + + self->clean_command = pp_maintenance_command_new (self->printer_name, + "Clean", + "all", + /* Translators: Name of job which makes printer to clean its heads */ + _("Clean print heads")); + check_clean_heads_maintenance_command (self); + + g_signal_connect_object (self->supply_drawing_area, "draw", G_CALLBACK (supply_levels_draw_cb), self, G_CONNECT_SWAPPED); + + pp_printer_entry_update (self, printer, is_authorized); + + return self; +} + +void +pp_printer_entry_update (PpPrinterEntry *self, + cups_dest_t printer, + gboolean is_authorized) +{ cups_ptype_t printer_type = 0; - gboolean is_accepting_jobs; + gboolean is_accepting_jobs = TRUE; gboolean ink_supply_is_empty; gchar *instance; gchar *printer_uri = NULL; + const gchar *device_uri = NULL; gchar *location = NULL; gchar *printer_icon_name = NULL; gchar *default_icon_name = NULL; @@ -798,10 +836,6 @@ pp_printer_entry_new (cups_dest_t print N_("The optical photo conductor is no longer functioning") }; - self = g_object_new (PP_PRINTER_ENTRY_TYPE, "printer-name", printer.name, NULL); - - self->inklevel = g_slice_new0 (InkLevelData); - if (printer.instance) { instance = g_strdup_printf ("%s / %s", printer.name, printer.instance); @@ -816,7 +850,7 @@ pp_printer_entry_new (cups_dest_t print for (i = 0; i < printer.num_options; i++) { if (g_strcmp0 (printer.options[i].name, "device-uri") == 0) - self->printer_uri = printer.options[i].value; + device_uri = printer.options[i].value; else if (g_strcmp0 (printer.options[i].name, "printer-uri-supported") == 0) printer_uri = printer.options[i].value; else if (g_strcmp0 (printer.options[i].name, "printer-type") == 0) @@ -826,13 +860,25 @@ pp_printer_entry_new (cups_dest_t print else if (g_strcmp0 (printer.options[i].name, "printer-state-reasons") == 0) reason = printer.options[i].value; else if (g_strcmp0 (printer.options[i].name, "marker-names") == 0) - self->inklevel->marker_names = g_strcompress (printer.options[i].value); + { + g_free (self->inklevel->marker_names); + self->inklevel->marker_names = g_strcompress (printer.options[i].value); + } else if (g_strcmp0 (printer.options[i].name, "marker-levels") == 0) - self->inklevel->marker_levels = g_strdup (printer.options[i].value); + { + g_free (self->inklevel->marker_levels); + self->inklevel->marker_levels = g_strdup (printer.options[i].value); + } else if (g_strcmp0 (printer.options[i].name, "marker-colors") == 0) - self->inklevel->marker_colors = g_strdup (printer.options[i].value); + { + g_free (self->inklevel->marker_colors); + self->inklevel->marker_colors = g_strdup (printer.options[i].value); + } else if (g_strcmp0 (printer.options[i].name, "marker-types") == 0) - self->inklevel->marker_types = g_strdup (printer.options[i].value); + { + g_free (self->inklevel->marker_types); + self->inklevel->marker_types = g_strdup (printer.options[i].value); + } else if (g_strcmp0 (printer.options[i].name, "printer-make-and-model") == 0) printer_make_and_model = printer.options[i].value; else if (g_strcmp0 (printer.options[i].name, "printer-state") == 0) @@ -896,6 +942,11 @@ pp_printer_entry_new (cups_dest_t print gtk_label_set_label (self->error_status, status); gtk_widget_set_visible (GTK_WIDGET (self->printer_error), TRUE); } + else + { + gtk_label_set_label (self->error_status, ""); + gtk_widget_set_visible (GTK_WIDGET (self->printer_error), FALSE); + } switch (self->printer_state) { @@ -921,7 +972,7 @@ pp_printer_entry_new (cups_dest_t print break; } - if (printer_is_local (printer_type, self->printer_uri)) + if (printer_is_local (printer_type, device_uri)) printer_icon_name = g_strdup ("printer"); else printer_icon_name = g_strdup ("printer-network"); @@ -931,14 +982,8 @@ pp_printer_entry_new (cups_dest_t print self->is_accepting_jobs = is_accepting_jobs; self->is_authorized = is_authorized; - self->printer_hostname = printer_get_hostname (printer_type, self->printer_uri, printer_uri); - - self->clean_command = pp_maintenance_command_new (self->printer_name, - "Clean", - "all", - /* Translators: Name of job which makes printer to clean its heads */ - _("Clean print heads")); - check_clean_heads_maintenance_command (self); + g_free (self->printer_hostname); + self->printer_hostname = printer_get_hostname (printer_type, device_uri, printer_uri); gtk_image_set_from_icon_name (self->printer_icon, printer_icon_name, GTK_ICON_SIZE_DIALOG); gtk_label_set_text (self->printer_status, printer_status); @@ -970,7 +1015,6 @@ pp_printer_entry_new (cups_dest_t print gtk_label_set_text (self->printer_location_address_label, location); } - g_signal_connect (self->supply_drawing_area, "draw", G_CALLBACK (supply_levels_draw_cb), self); ink_supply_is_empty = supply_level_is_empty (self); gtk_widget_set_visible (GTK_WIDGET (self->printer_inklevel_label), !ink_supply_is_empty); gtk_widget_set_visible (GTK_WIDGET (self->supply_frame), !ink_supply_is_empty); @@ -983,8 +1027,6 @@ pp_printer_entry_new (cups_dest_t print g_free (instance); g_free (printer_icon_name); g_free (default_icon_name); - - return self; } static void @@ -1008,6 +1050,7 @@ pp_printer_entry_dispose (GObject *objec g_clear_pointer (&self->printer_location, g_free); g_clear_pointer (&self->printer_make_and_model, g_free); g_clear_pointer (&self->printer_hostname, g_free); + g_clear_pointer (&self->inklevel, ink_level_data_free); if (self->get_jobs_cancellable != NULL) { --- gnome-control-center-3.28.2/panels/printers/pp-printer-entry.h +++ gnome-control-center-3.28.2/panels/printers/pp-printer-entry.h @@ -42,4 +42,8 @@ void pp_printer_entry_show_jo void pp_printer_entry_authenticate_jobs (PpPrinterEntry *self); +void pp_printer_entry_update (PpPrinterEntry *self, + cups_dest_t printer, + gboolean is_authorized); + #endif /* PP_PRINTER_ENTRY_H */