diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index 70a04fc1b..85f29b270 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -37,6 +37,7 @@
#include "pp-options-dialog.h"
#include "pp-jobs-dialog.h"
#include "pp-utils.h"
+#include "pp-maintenance-command.h"
CC_PANEL_REGISTER (CcPrintersPanel, cc_printers_panel)
@@ -104,6 +105,12 @@ struct _CcPrintersPanelPrivate
GHashTable *preferred_drivers;
GCancellable *get_all_ppds_cancellable;
+ gchar *new_printer_name;
+ gchar *new_printer_location;
+ gchar *new_printer_make_and_model;
+ gboolean new_printer_on_network;
+ gboolean select_new_printer;
+
gpointer dummy;
};
@@ -153,13 +160,14 @@ cc_printers_panel_dispose (GObject *object)
CcPrintersPanelPrivate *priv = CC_PRINTERS_PANEL (object)->priv;
if (priv->pp_new_printer_dialog)
- {
- pp_new_printer_dialog_free (priv->pp_new_printer_dialog);
- priv->pp_new_printer_dialog = NULL;
- }
+ g_clear_object (&priv->pp_new_printer_dialog);
free_dests (CC_PRINTERS_PANEL (object));
+ g_clear_pointer (&priv->new_printer_name, g_free);
+ g_clear_pointer (&priv->new_printer_location, g_free);
+ g_clear_pointer (&priv->new_printer_make_and_model, g_free);
+
if (priv->builder)
{
g_object_unref (priv->builder);
@@ -538,7 +546,6 @@ printer_selection_changed_cb (GtkTreeSelection *selection,
GtkWidget *widget;
GtkWidget *model_button;
GtkWidget *model_label;
- gboolean sensitive;
GValue value = G_VALUE_INIT;
gchar *printer_make_and_model = NULL;
gchar *printer_model = NULL;
@@ -710,10 +717,19 @@ printer_selection_changed_cb (GtkTreeSelection *selection,
printer_model = g_strdup (printer_make_and_model);
}
+ if (priv->new_printer_name &&
+ g_strcmp0 (priv->new_printer_name, printer_name) == 0)
+ {
+ /* Translators: Printer's state (printer is being configured right now) */
+ status = g_strdup ( C_("printer state", "Configuring"));
+ }
+
/* Find the first of the most severe reasons
* and show it in the status field
*/
- if (reason && g_strcmp0 (reason, "none") != 0)
+ if (!status &&
+ reason &&
+ !g_str_equal (reason, "none"))
{
int errors = 0, warnings = 0, reports = 0;
int error_index = -1, warning_index = -1, report_index = -1;
@@ -871,11 +887,9 @@ printer_selection_changed_cb (GtkTreeSelection *selection,
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "printer-default-check-button");
- sensitive = gtk_widget_get_sensitive (widget);
g_signal_handlers_block_by_func (G_OBJECT (widget), printer_set_default_cb, self);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), priv->dests[id].is_default);
g_signal_handlers_unblock_by_func (G_OBJECT (widget), printer_set_default_cb, self);
- gtk_widget_set_sensitive (widget, sensitive);
widget = (GtkWidget*)
@@ -907,33 +921,107 @@ printer_selection_changed_cb (GtkTreeSelection *selection,
}
else
{
+ if (id == -1)
+ {
+ if (priv->new_printer_name &&
+ g_strcmp0 (priv->new_printer_name, printer_name) == 0)
+ {
+ /* Translators: Printer's state (printer is being installed right now) */
+ status = g_strdup ( C_("printer state", "Installing"));
+ location = g_strdup (priv->new_printer_location);
+ printer_model = g_strdup (priv->new_printer_make_and_model);
+
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "notebook");
+ if (gtk_notebook_get_current_page (GTK_NOTEBOOK (widget)) >= NOTEBOOK_NO_PRINTERS_PAGE)
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), NOTEBOOK_INFO_PAGE);
+ }
+ }
+
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "printer-icon");
+ g_value_init (&value, G_TYPE_INT);
+ g_object_get_property ((GObject *) widget, "icon-size", &value);
+
+ if (printer_icon)
+ {
+ gtk_image_set_from_icon_name ((GtkImage *) widget, printer_icon, g_value_get_int (&value));
+ g_free (printer_icon);
+ }
+ else
+ gtk_image_set_from_icon_name ((GtkImage *) widget, "printer", g_value_get_int (&value));
+
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "printer-name-label");
- cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), "");
+ if (printer_name)
+ {
+ cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), printer_name);
+ g_free (printer_name);
+ }
+ else
+ cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), EMPTY_TEXT);
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "printer-status-label");
- cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), "");
+ if (status)
+ {
+ cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), status);
+ g_free (status);
+ }
+ else
+ cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), EMPTY_TEXT);
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "printer-location-label");
- cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), "");
- widget = (GtkWidget*)
+ if (location)
+ {
+ cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), location);
+ g_free (location);
+ }
+ else
+ cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), EMPTY_TEXT);
+
+
+ model_button = (GtkWidget*)
gtk_builder_get_object (priv->builder, "printer-model-button");
- gtk_button_set_label (GTK_BUTTON (widget), "");
- widget = (GtkWidget*)
+ model_label = (GtkWidget*)
gtk_builder_get_object (priv->builder, "printer-model-label");
- gtk_label_set_text (GTK_LABEL (widget), "");
+
+ if (printer_model)
+ {
+ gtk_button_set_label (GTK_BUTTON (model_button), printer_model);
+ gtk_label_set_text (GTK_LABEL (model_label), printer_model);
+ g_free (printer_model);
+ }
+ else
+ {
+ gtk_button_set_label (GTK_BUTTON (model_button), EMPTY_TEXT);
+ gtk_label_set_text (GTK_LABEL (model_label), EMPTY_TEXT);
+ }
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "printer-ip-address-label");
- cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), "");
+ cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), EMPTY_TEXT);
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "printer-jobs-label");
- cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), "");
+ cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), EMPTY_TEXT);
+
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "printer-disable-switch");
+
+ g_signal_handlers_block_by_func (G_OBJECT (widget), printer_disable_cb, self);
+ gtk_switch_set_active (GTK_SWITCH (widget), FALSE);
+ g_signal_handlers_unblock_by_func (G_OBJECT (widget), printer_disable_cb, self);
+
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "printer-default-check-button");
+
+ g_signal_handlers_block_by_func (G_OBJECT (widget), printer_set_default_cb, self);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+ g_signal_handlers_unblock_by_func (G_OBJECT (widget), printer_set_default_cb, self);
}
update_sensitivity (self);
@@ -943,34 +1031,47 @@ static void
actualize_printers_list (CcPrintersPanel *self)
{
CcPrintersPanelPrivate *priv;
+ GtkTreeSelection *selection;
GtkListStore *store;
cups_ptype_t printer_type = 0;
+ GtkTreeModel *model;
GtkTreeIter selected_iter;
GtkTreeView *treeview;
GtkTreeIter iter;
cups_job_t *jobs = NULL;
GtkWidget *widget;
gboolean paused = FALSE;
+ gboolean selected_iter_set = FALSE;
gboolean valid = FALSE;
http_t *http;
- gchar *current_printer_instance = NULL;
gchar *current_printer_name = NULL;
gchar *printer_icon_name = NULL;
gchar *default_icon_name = NULL;
gchar *device_uri = NULL;
+ gint new_printer_position = 0;
int current_dest = -1;
int i, j;
int num_jobs = 0;
priv = PRINTERS_PANEL_PRIVATE (self);
- if (priv->current_dest >= 0 &&
- priv->current_dest < priv->num_dests &&
- priv->dests != NULL)
+ treeview = (GtkTreeView*)
+ gtk_builder_get_object (priv->builder, "printers-treeview");
+
+ if ((selection = gtk_tree_view_get_selection (treeview)) != NULL &&
+ gtk_tree_selection_get_selected (selection, &model, &iter))
{
- current_printer_name = g_strdup (priv->dests[priv->current_dest].name);
- if (priv->dests[priv->current_dest].instance)
- current_printer_instance = g_strdup (priv->dests[priv->current_dest].instance);
+ gtk_tree_model_get (model, &iter,
+ PRINTER_NAME_COLUMN, ¤t_printer_name,
+ -1);
+ }
+
+ if (priv->new_printer_name &&
+ priv->select_new_printer)
+ {
+ g_free (current_printer_name);
+ current_printer_name = g_strdup (priv->new_printer_name);
+ priv->select_new_printer = FALSE;
}
free_dests (self);
@@ -978,9 +1079,6 @@ actualize_printers_list (CcPrintersPanel *self)
priv->dest_model_names = g_new0 (gchar *, priv->num_dests);
priv->ppd_file_names = g_new0 (gchar *, priv->num_dests);
- treeview = (GtkTreeView*)
- gtk_builder_get_object (priv->builder, "printers-treeview");
-
store = gtk_list_store_new (PRINTER_N_COLUMNS,
G_TYPE_INT,
G_TYPE_STRING,
@@ -988,7 +1086,7 @@ actualize_printers_list (CcPrintersPanel *self)
G_TYPE_STRING,
G_TYPE_STRING);
- if (priv->num_dests == 0)
+ if (priv->num_dests == 0 && !priv->new_printer_name)
{
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "notebook");
@@ -1020,30 +1118,25 @@ actualize_printers_list (CcPrintersPanel *self)
{
gchar *instance;
+ if (priv->new_printer_name && new_printer_position >= 0)
+ {
+ gint comparison_result = g_ascii_strcasecmp (priv->dests[i].name, priv->new_printer_name);
+
+ if (comparison_result < 0)
+ new_printer_position = i + 1;
+ else if (comparison_result == 0)
+ new_printer_position = -1;
+ }
+
gtk_list_store_append (store, &iter);
if (priv->dests[i].instance)
{
instance = g_strdup_printf ("%s / %s", priv->dests[i].name, priv->dests[i].instance);
-
- if (current_printer_instance &&
- g_strcmp0 (current_printer_name, priv->dests[i].name) == 0 &&
- g_strcmp0 (current_printer_instance, priv->dests[i].instance) == 0)
- {
- current_dest = i;
- selected_iter = iter;
- }
}
else
{
instance = g_strdup (priv->dests[i].name);
-
- if (current_printer_instance == NULL &&
- g_strcmp0 (current_printer_name, priv->dests[i].name) == 0)
- {
- current_dest = i;
- selected_iter = iter;
- }
}
for (j = 0; j < priv->dests[i].num_options; j++)
@@ -1074,11 +1167,37 @@ actualize_printers_list (CcPrintersPanel *self)
PRINTER_ICON_COLUMN, printer_icon_name,
-1);
+ if (g_strcmp0 (current_printer_name, instance) == 0)
+ {
+ current_dest = i;
+ selected_iter = iter;
+ selected_iter_set = TRUE;
+ }
+
g_free (instance);
g_free (printer_icon_name);
g_free (default_icon_name);
}
+ if (priv->new_printer_name && new_printer_position >= 0)
+ {
+ gtk_list_store_insert (store, &iter, new_printer_position);
+ gtk_list_store_set (store, &iter,
+ PRINTER_ID_COLUMN, -1,
+ PRINTER_NAME_COLUMN, priv->new_printer_name,
+ PRINTER_PAUSED_COLUMN, TRUE,
+ PRINTER_DEFAULT_ICON_COLUMN, NULL,
+ PRINTER_ICON_COLUMN, priv->new_printer_on_network ?
+ "printer-network" : "printer",
+ -1);
+
+ if (g_strcmp0 (current_printer_name, priv->new_printer_name) == 0)
+ {
+ selected_iter = iter;
+ selected_iter_set = TRUE;
+ }
+ }
+
g_signal_handlers_block_by_func (
G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview))),
printer_selection_changed_cb,
@@ -1091,7 +1210,7 @@ actualize_printers_list (CcPrintersPanel *self)
printer_selection_changed_cb,
self);
- if (current_dest >= 0)
+ if (selected_iter_set)
{
priv->current_dest = current_dest;
gtk_tree_selection_select_iter (
@@ -1160,7 +1279,6 @@ actualize_printers_list (CcPrintersPanel *self)
}
g_free (current_printer_name);
- g_free (current_printer_instance);
g_object_unref (store);
update_sensitivity (self);
@@ -1192,14 +1310,20 @@ set_cell_sensitivity_func (GtkTreeViewColumn *tree_column,
"width-chars", 18,
NULL);
- if (paused)
- g_object_set (cell,
- "sensitive", FALSE,
- NULL);
- else
- g_object_set (cell,
- "sensitive", TRUE,
- NULL);
+ g_object_set (cell, "sensitive", !paused, NULL);
+}
+
+static void
+set_pixbuf_cell_sensitivity_func (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer func_data)
+{
+ gboolean paused = FALSE;
+
+ gtk_tree_model_get (tree_model, iter, PRINTER_PAUSED_COLUMN, &paused, -1);
+ g_object_set (cell, "sensitive", !paused, NULL);
}
static void
@@ -1228,6 +1352,8 @@ populate_printers_list (CcPrintersPanel *self)
gtk_cell_renderer_set_padding (icon_renderer, 4, 4);
column = gtk_tree_view_column_new_with_attributes ("Icon", icon_renderer,
"icon-name", PRINTER_ICON_COLUMN, NULL);
+ gtk_tree_view_column_set_cell_data_func (column, icon_renderer, set_pixbuf_cell_sensitivity_func,
+ self, NULL);
gtk_tree_view_column_set_expand (column, FALSE);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
@@ -1524,7 +1650,7 @@ supply_levels_draw_cb (GtkWidget *widget,
gtk_widget_set_has_tooltip (widget, FALSE);
}
}
-
+
return TRUE;
}
@@ -1555,21 +1681,45 @@ printer_set_default_cb (GtkToggleButton *button,
}
static void
-new_printer_dialog_response_cb (GtkDialog *dialog,
- gint response_id,
- gpointer user_data)
+new_printer_dialog_pre_response_cb (PpNewPrinterDialog *dialog,
+ const gchar *device_name,
+ const gchar *device_location,
+ const gchar *device_make_and_model,
+ gboolean is_network_device,
+ gpointer user_data)
{
CcPrintersPanelPrivate *priv;
CcPrintersPanel *self = (CcPrintersPanel*) user_data;
priv = PRINTERS_PANEL_PRIVATE (self);
- pp_new_printer_dialog_free (priv->pp_new_printer_dialog);
- priv->pp_new_printer_dialog = NULL;
+ priv->new_printer_name = g_strdup (device_name);
+ priv->new_printer_location = g_strdup (device_location);
+ priv->new_printer_make_and_model = g_strdup (device_make_and_model);
+ priv->new_printer_on_network = is_network_device;
+ priv->select_new_printer = TRUE;
- if (response_id == GTK_RESPONSE_OK)
- actualize_printers_list (self);
- else if (response_id == GTK_RESPONSE_REJECT)
+ actualize_printers_list (self);
+}
+
+static void
+new_printer_dialog_response_cb (PpNewPrinterDialog *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ CcPrintersPanelPrivate *priv;
+ CcPrintersPanel *self = (CcPrintersPanel*) user_data;
+
+ priv = PRINTERS_PANEL_PRIVATE (self);
+
+ if (priv->pp_new_printer_dialog)
+ g_clear_object (&priv->pp_new_printer_dialog);
+
+ g_clear_pointer (&priv->new_printer_name, g_free);
+ g_clear_pointer (&priv->new_printer_location, g_free);
+ g_clear_pointer (&priv->new_printer_make_and_model, g_free);
+
+ if (response_id == GTK_RESPONSE_REJECT)
{
GtkWidget *message_dialog;
@@ -1585,6 +1735,8 @@ new_printer_dialog_response_cb (GtkDialog *dialog,
NULL);
gtk_widget_show (message_dialog);
}
+
+ actualize_printers_list (self);
}
static void
@@ -1593,17 +1745,22 @@ printer_add_cb (GtkToolButton *toolbutton,
{
CcPrintersPanelPrivate *priv;
CcPrintersPanel *self = (CcPrintersPanel*) user_data;
- GtkWidget *widget;
+ GtkWidget *toplevel;
priv = PRINTERS_PANEL_PRIVATE (self);
- widget = (GtkWidget*)
- gtk_builder_get_object (priv->builder, "main-vbox");
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
+ priv->pp_new_printer_dialog = PP_NEW_PRINTER_DIALOG (pp_new_printer_dialog_new (GTK_WINDOW (toplevel)));
- priv->pp_new_printer_dialog = pp_new_printer_dialog_new (
- GTK_WINDOW (gtk_widget_get_toplevel (widget)),
- new_printer_dialog_response_cb,
- self);
+ g_signal_connect (priv->pp_new_printer_dialog,
+ "pre-response",
+ G_CALLBACK (new_printer_dialog_pre_response_cb),
+ self);
+
+ g_signal_connect (priv->pp_new_printer_dialog,
+ "response",
+ G_CALLBACK (new_printer_dialog_response_cb),
+ self);
}
static void
@@ -2184,6 +2341,19 @@ popup_model_menu_cb (GtkButton *button,
}
}
+static void
+pp_maintenance_command_execute_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PpMaintenanceCommand *command = (PpMaintenanceCommand *) source_object;
+ GError *error = NULL;
+
+ pp_maintenance_command_execute_finish (command, res, &error);
+
+ g_object_unref (command);
+}
+
static void
test_page_cb (GtkButton *button,
gpointer user_data)
@@ -2286,23 +2456,27 @@ test_page_cb (GtkButton *button,
httpClose (http);
}
+ if (response)
+ {
+ if (ippGetState (response) == IPP_ERROR)
+ g_warning ("An error has occured during printing of test page.");
+ ippDelete (response);
+ }
+
g_free (filename);
g_free (printer_uri);
g_free (resource);
}
else
{
- response = execute_maintenance_command (printer_name,
- "PrintSelfTestPage",
- /* Translators: Name of job which makes printer to print test page */
- _("Test page"));
- }
+ PpMaintenanceCommand *command;
- if (response)
- {
- if (ippGetState (response) == IPP_ERROR)
- g_warning ("An error has occured during printing of test page.");
- ippDelete (response);
+ command = pp_maintenance_command_new (printer_name,
+ "PrintSelfTestPage",
+ /* Translators: Name of job which makes printer to print test page */
+ _("Test page"));
+
+ pp_maintenance_command_execute_async (command, NULL, pp_maintenance_command_execute_cb, self);
}
}
}
@@ -2311,8 +2485,12 @@ static void
update_sensitivity (gpointer user_data)
{
CcPrintersPanelPrivate *priv;
+ GtkTreeSelection *selection;
CcPrintersPanel *self = (CcPrintersPanel*) user_data;
cups_ptype_t type = 0;
+ GtkTreeModel *model;
+ GtkTreeView *treeview;
+ GtkTreeIter tree_iter;
const char *cups_server = NULL;
GtkWidget *widget;
gboolean is_authorized;
@@ -2322,7 +2500,10 @@ update_sensitivity (gpointer user_data)
gboolean printer_selected;
gboolean local_server = TRUE;
gboolean no_cups = FALSE;
+ gboolean is_new = FALSE;
+ gboolean already_present_local;
GList *iter;
+ gchar *current_printer_name = NULL;
gint i;
priv = PRINTERS_PANEL_PRIVATE (self);
@@ -2361,6 +2542,29 @@ update_sensitivity (gpointer user_data)
}
}
+ treeview = (GtkTreeView*)
+ gtk_builder_get_object (priv->builder, "printers-treeview");
+
+ selection = gtk_tree_view_get_selection (treeview);
+ if (selection &&
+ gtk_tree_selection_get_selected (selection, &model, &tree_iter))
+ {
+ gtk_tree_model_get (model, &tree_iter,
+ PRINTER_NAME_COLUMN, ¤t_printer_name,
+ -1);
+ }
+
+ if (priv->new_printer_name &&
+ g_strcmp0 (priv->new_printer_name, current_printer_name) == 0)
+ {
+ printer_selected = TRUE;
+ is_discovered = FALSE;
+ is_class = FALSE;
+ is_new = TRUE;
+ }
+
+ g_free (current_printer_name);
+
cups_server = cupsServer ();
if (cups_server &&
g_ascii_strncasecmp (cups_server, "localhost", 9) != 0 &&
@@ -2373,39 +2577,41 @@ update_sensitivity (gpointer user_data)
if (gtk_notebook_get_current_page (GTK_NOTEBOOK (widget)) == NOTEBOOK_NO_CUPS_PAGE)
no_cups = TRUE;
+ already_present_local = local_server && !is_discovered && is_authorized && !is_new;
+
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-add-button");
- gtk_widget_set_sensitive (widget, local_server && is_authorized && !no_cups);
+ gtk_widget_set_sensitive (widget, local_server && is_authorized && !no_cups && !priv->new_printer_name);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-add-button2");
- gtk_widget_set_sensitive (widget, local_server && is_authorized && !no_cups);
+ gtk_widget_set_sensitive (widget, local_server && is_authorized && !no_cups && !priv->new_printer_name);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-remove-button");
- gtk_widget_set_sensitive (widget, local_server && !is_discovered && is_authorized && printer_selected && !no_cups);
+ gtk_widget_set_sensitive (widget, already_present_local && printer_selected && !no_cups);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-disable-switch");
- gtk_widget_set_sensitive (widget, local_server && !is_discovered && is_authorized);
+ gtk_widget_set_sensitive (widget, already_present_local);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-default-check-button");
- gtk_widget_set_sensitive (widget, is_authorized);
+ gtk_widget_set_sensitive (widget, is_authorized && !is_new);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "print-test-page-button");
- gtk_widget_set_sensitive (widget, printer_selected);
+ gtk_widget_set_sensitive (widget, printer_selected && !is_new);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-options-button");
gtk_widget_set_sensitive (widget, printer_selected && local_server && !is_discovered &&
- !priv->pp_options_dialog);
+ !priv->pp_options_dialog && !is_new);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-jobs-button");
- gtk_widget_set_sensitive (widget, printer_selected);
+ gtk_widget_set_sensitive (widget, printer_selected && !is_new);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-icon");
gtk_widget_set_sensitive (widget, printer_selected);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-name-label");
- cc_editable_entry_set_editable (CC_EDITABLE_ENTRY (widget), local_server && !is_discovered && is_authorized);
+ cc_editable_entry_set_editable (CC_EDITABLE_ENTRY (widget), already_present_local);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-location-label");
- cc_editable_entry_set_editable (CC_EDITABLE_ENTRY (widget), local_server && !is_discovered && is_authorized);
+ cc_editable_entry_set_editable (CC_EDITABLE_ENTRY (widget), already_present_local);
widget = (GtkWidget*) gtk_builder_get_object (priv->builder, "printer-model-notebook");
if (is_changing_driver)
@@ -2414,7 +2620,7 @@ update_sensitivity (gpointer user_data)
}
else
{
- if (local_server && !is_discovered && is_authorized && !is_class && !priv->getting_ppd_names)
+ if (already_present_local && !is_class && !priv->getting_ppd_names)
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0);
else
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1);
@@ -2648,6 +2854,12 @@ cc_printers_panel_init (CcPrintersPanel *self)
priv->cups_bus_connection = NULL;
priv->dbus_subscription_id = 0;
+ priv->new_printer_name = NULL;
+ priv->new_printer_location = NULL;
+ priv->new_printer_make_and_model = NULL;
+ priv->new_printer_on_network = FALSE;
+ priv->select_new_printer = FALSE;
+
priv->permission = NULL;
priv->lockdown_settings = NULL;
diff --git a/panels/printers/new-printer-dialog.ui b/panels/printers/new-printer-dialog.ui
index fa490872c..07d946a81 100644
--- a/panels/printers/new-printer-dialog.ui
+++ b/panels/printers/new-printer-dialog.ui
@@ -1,378 +1,230 @@
-
+
-
-
+
diff --git a/panels/printers/pp-new-printer-dialog.c b/panels/printers/pp-new-printer-dialog.c
index 0d3ddb0aa..88c7a9ded 100644
--- a/panels/printers/pp-new-printer-dialog.c
+++ b/panels/printers/pp-new-printer-dialog.c
@@ -22,8 +22,6 @@
#include
#include
-#include
-#include
#include
#include
@@ -31,26 +29,17 @@
#include
#include
-#include
#include "pp-new-printer-dialog.h"
#include "pp-utils.h"
-
-#include
+#include "pp-host.h"
+#include "pp-cups.h"
+#include "pp-new-printer.h"
#ifdef GDK_WINDOWING_X11
#include
#endif
-#define PACKAGE_KIT_BUS "org.freedesktop.PackageKit"
-#define PACKAGE_KIT_PATH "/org/freedesktop/PackageKit"
-#define PACKAGE_KIT_MODIFY_IFACE "org.freedesktop.PackageKit.Modify"
-#define PACKAGE_KIT_QUERY_IFACE "org.freedesktop.PackageKit.Query"
-
-#define FIREWALLD_BUS "org.fedoraproject.FirewallD"
-#define FIREWALLD_PATH "/org/fedoraproject/FirewallD"
-#define FIREWALLD_IFACE "org.fedoraproject.FirewallD"
-
#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
#define HAVE_CUPS_1_6 1
#endif
@@ -59,198 +48,327 @@
#define ippGetState(ipp) ipp->state
#endif
-static void pp_new_printer_dialog_hide (PpNewPrinterDialog *pp);
-static void actualize_devices_list (PpNewPrinterDialog *pp);
+static void actualize_devices_list (PpNewPrinterDialog *dialog);
+static void populate_devices_list (PpNewPrinterDialog *dialog);
+static void search_address_cb2 (GtkEntry *entry,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event,
+ gpointer user_data);
+static void search_address_cb (GtkEntry *entry,
+ gpointer user_data);
+static void new_printer_dialog_response_cb (GtkDialog *_dialog,
+ gint response_id,
+ gpointer user_data);
+static void t_device_free (gpointer data);
enum
{
- NOTEBOOK_LOCAL_PAGE = 0,
- NOTEBOOK_NETWORK_PAGE,
- NOTEBOOK_N_PAGES
-};
-
-enum
-{
- DEVICE_TYPE_ID_COLUMN = 0,
- DEVICE_TYPE_NAME_COLUMN,
- DEVICE_TYPE_TYPE_COLUMN,
- DEVICE_TYPE_N_COLUMNS
-};
-
-enum
-{
- DEVICE_ID_COLUMN = 0,
+ DEVICE_ICON_COLUMN = 0,
DEVICE_NAME_COLUMN,
+ DEVICE_DISPLAY_NAME_COLUMN,
DEVICE_N_COLUMNS
};
-enum
+typedef struct
{
- DEVICE_TYPE_LOCAL = 0,
- DEVICE_TYPE_NETWORK
-};
+ gchar *display_name;
+ gchar *device_name;
+ gchar *device_original_name;
+ gchar *device_info;
+ gchar *device_location;
+ gchar *device_make_and_model;
+ gchar *device_uri;
+ gchar *device_id;
+ gchar *device_ppd;
+ gchar *host_name;
+ gint host_port;
+ gboolean network_device;
+ gint acquisition_method;
+ gboolean show;
+} TDevice;
-enum
+struct _PpNewPrinterDialogPrivate
{
- STANDARD_TAB = 0,
- WARNING_TAB
-};
-
-typedef struct{
- gchar *device_class;
- gchar *device_id;
- gchar *device_info;
- gchar *device_make_and_model;
- gchar *device_uri;
- gchar *device_location;
- gchar *device_ppd_uri;
- gchar *display_name;
- gchar *hostname;
- gint host_port;
- gboolean show;
- gboolean found;
-} CupsDevice;
-
-struct _PpNewPrinterDialog {
GtkBuilder *builder;
- GtkWidget *parent;
- GtkWidget *dialog;
+ GList *devices;
+ GList *new_devices;
- gchar **device_connection_types;
- gint num_device_connection_types;
-
- CupsDevice *devices;
- gint num_devices;
-
- UserResponseCallback user_callback;
- gpointer user_data;
+ cups_dest_t *dests;
+ gint num_of_dests;
GCancellable *cancellable;
- gchar *warning;
- gboolean show_warning;
- gboolean searching;
+ gboolean cups_searching;
+ gboolean remote_cups_searching;
+ gboolean snmp_searching;
+
+ GtkCellRenderer *text_renderer;
+ GtkCellRenderer *icon_renderer;
+
+ GtkWidget *dialog;
};
-static void
-show_notification (gchar *primary_text,
- gchar *secondary_text,
- gchar *icon_name)
-{
- if (primary_text)
- {
- NotifyNotification *notification;
- notification = notify_notification_new (primary_text,
- secondary_text,
- icon_name);
- notify_notification_set_app_name (notification, _("Printers"));
- notify_notification_set_hint (notification, "transient", g_variant_new_boolean (TRUE));
+#define PP_NEW_PRINTER_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PP_TYPE_NEW_PRINTER_DIALOG, PpNewPrinterDialogPrivate))
- notify_notification_show (notification, NULL);
- g_object_unref (notification);
+static void pp_new_printer_dialog_finalize (GObject *object);
+
+enum {
+ PRE_RESPONSE,
+ RESPONSE,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (PpNewPrinterDialog, pp_new_printer_dialog, G_TYPE_OBJECT)
+
+static void
+pp_new_printer_dialog_class_init (PpNewPrinterDialogClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = pp_new_printer_dialog_finalize;
+
+ g_type_class_add_private (object_class, sizeof (PpNewPrinterDialogPrivate));
+
+ /**
+ * PpNewPrinterDialog::pre-response:
+ * @device: the device that is being added
+ *
+ * The signal which gets emitted when the new printer dialog is closed.
+ */
+ signals[PRE_RESPONSE] =
+ g_signal_new ("pre-response",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PpNewPrinterDialogClass, pre_response),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
+
+ /**
+ * PpNewPrinterDialog::response:
+ * @response-id: response id of dialog
+ *
+ * The signal which gets emitted after the printer is added and configured.
+ */
+ signals[RESPONSE] =
+ g_signal_new ("response",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PpNewPrinterDialogClass, response),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+}
+
+
+PpNewPrinterDialog *
+pp_new_printer_dialog_new (GtkWindow *parent)
+{
+ PpNewPrinterDialogPrivate *priv;
+ PpNewPrinterDialog *dialog;
+
+ dialog = g_object_new (PP_TYPE_NEW_PRINTER_DIALOG, NULL);
+ priv = dialog->priv;
+
+ gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), GTK_WINDOW (parent));
+
+ return PP_NEW_PRINTER_DIALOG (dialog);
+}
+
+static void
+emit_pre_response (PpNewPrinterDialog *dialog,
+ const gchar *device_name,
+ const gchar *device_location,
+ const gchar *device_make_and_model,
+ gboolean network_device)
+{
+ g_signal_emit (dialog,
+ signals[PRE_RESPONSE],
+ 0,
+ device_name,
+ device_location,
+ device_make_and_model,
+ network_device);
+}
+
+static void
+emit_response (PpNewPrinterDialog *dialog,
+ gint response_id)
+{
+ g_signal_emit (dialog, signals[RESPONSE], 0, response_id);
+}
+
+/*
+ * Modify padding of the content area of the GtkDialog
+ * so it is aligned with the action area.
+ */
+static void
+update_alignment_padding (GtkWidget *widget,
+ GtkAllocation *allocation,
+ gpointer user_data)
+{
+ PpNewPrinterDialog *dialog = (PpNewPrinterDialog*) user_data;
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+ GtkAllocation allocation1, allocation2;
+ GtkWidget *action_area;
+ GtkWidget *content_area;
+ gint offset_left, offset_right;
+ guint padding_left, padding_right,
+ padding_top, padding_bottom;
+
+ action_area = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "dialog-action-area1");
+ gtk_widget_get_allocation (action_area, &allocation2);
+
+ content_area = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "content-alignment");
+ gtk_widget_get_allocation (content_area, &allocation1);
+
+ offset_left = allocation2.x - allocation1.x;
+ offset_right = (allocation1.x + allocation1.width) -
+ (allocation2.x + allocation2.width);
+
+ gtk_alignment_get_padding (GTK_ALIGNMENT (content_area),
+ &padding_top, &padding_bottom,
+ &padding_left, &padding_right);
+ if (allocation1.x >= 0 && allocation2.x >= 0)
+ {
+ if (offset_left > 0 && offset_left != padding_left)
+ gtk_alignment_set_padding (GTK_ALIGNMENT (content_area),
+ padding_top, padding_bottom,
+ offset_left, padding_right);
+
+ gtk_alignment_get_padding (GTK_ALIGNMENT (content_area),
+ &padding_top, &padding_bottom,
+ &padding_left, &padding_right);
+ if (offset_right > 0 && offset_right != padding_right)
+ gtk_alignment_set_padding (GTK_ALIGNMENT (content_area),
+ padding_top, padding_bottom,
+ padding_left, offset_right);
}
}
static void
-device_type_selection_changed_cb (GtkTreeSelection *selection,
- gpointer user_data)
+pp_new_printer_dialog_init (PpNewPrinterDialog *dialog)
{
- PpNewPrinterDialog *pp = (PpNewPrinterDialog *) user_data;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkWidget *treeview = NULL;
- GtkWidget *notebook = NULL;
- GtkWidget *widget;
- gchar *device_type_name = NULL;
- gint device_type_id = -1;
- gint device_type = -1;
+ PpNewPrinterDialogPrivate *priv;
+ GtkStyleContext *context;
+ GtkWidget *widget;
+ GError *error = NULL;
+ gchar *objects[] = { "dialog", NULL };
+ guint builder_result;
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ priv = PP_NEW_PRINTER_DIALOG_GET_PRIVATE (dialog);
+ dialog->priv = priv;
+
+ priv->builder = gtk_builder_new ();
+
+ builder_result = gtk_builder_add_objects_from_file (priv->builder,
+ DATADIR"/new-printer-dialog.ui",
+ objects, &error);
+
+ if (builder_result == 0)
{
- gtk_tree_model_get (model, &iter,
- DEVICE_TYPE_ID_COLUMN, &device_type_id,
- DEVICE_TYPE_NAME_COLUMN, &device_type_name,
- DEVICE_TYPE_TYPE_COLUMN, &device_type,
- -1);
+ g_warning ("Could not load ui: %s", error->message);
+ g_error_free (error);
}
- if (device_type >= 0)
+ /* GCancellable for cancelling of async operations */
+ priv->cancellable = g_cancellable_new ();
+
+ priv->devices = NULL;
+ priv->new_devices = NULL;
+ priv->dests = NULL;
+ priv->num_of_dests = 0;
+ priv->cups_searching = FALSE;
+ priv->remote_cups_searching = FALSE;
+ priv->snmp_searching = FALSE;
+ priv->text_renderer = NULL;
+ priv->icon_renderer = NULL;
+
+ /* Construct dialog */
+ priv->dialog = (GtkWidget*) gtk_builder_get_object (priv->builder, "dialog");
+
+ /* Connect signals */
+ g_signal_connect (priv->dialog, "response", G_CALLBACK (new_printer_dialog_response_cb), dialog);
+ g_signal_connect (priv->dialog, "size-allocate", G_CALLBACK (update_alignment_padding), dialog);
+
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "search-entry");
+ g_signal_connect (widget, "icon-press", G_CALLBACK (search_address_cb2), dialog);
+ g_signal_connect (widget, "activate", G_CALLBACK (search_address_cb), dialog);
+
+ /* Set junctions */
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "scrolledwindow1");
+ context = gtk_widget_get_style_context (widget);
+ gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
+
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "toolbar1");
+ context = gtk_widget_get_style_context (widget);
+ gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+
+ /* Fill with data */
+ populate_devices_list (dialog);
+
+ gtk_widget_show (priv->dialog);
+}
+
+static void
+pp_new_printer_dialog_finalize (GObject *object)
+{
+ PpNewPrinterDialog *dialog = PP_NEW_PRINTER_DIALOG (object);
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+
+ priv->text_renderer = NULL;
+ priv->icon_renderer = NULL;
+
+ if (priv->cancellable)
{
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "device-type-notebook");
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), device_type);
-
- if (device_type == DEVICE_TYPE_LOCAL)
- {
- treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "local-devices-treeview");
- notebook = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "local-devices-notebook");
- }
- else if (device_type == DEVICE_TYPE_NETWORK)
- {
- treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "network-devices-treeview");
- notebook = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "network-devices-notebook");
- }
-
- if (notebook)
- {
- if (pp->show_warning && device_type == DEVICE_TYPE_NETWORK)
- gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), WARNING_TAB);
- else
- gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), STANDARD_TAB);
- }
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "new-printer-add-button");
-
- if (treeview)
- gtk_widget_set_sensitive (widget,
- gtk_tree_selection_get_selected (
- gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
- &model,
- &iter));
+ g_cancellable_cancel (priv->cancellable);
+ g_clear_object (&priv->cancellable);
}
+
+ if (priv->builder)
+ g_clear_object (&priv->builder);
+
+ g_list_free_full (priv->devices, t_device_free);
+ priv->devices = NULL;
+
+ g_list_free_full (priv->new_devices, t_device_free);
+ priv->new_devices = NULL;
+
+ if (priv->num_of_dests > 0)
+ {
+ cupsFreeDests (priv->num_of_dests, priv->dests);
+ priv->num_of_dests = 0;
+ priv->dests = NULL;
+ }
+
+ G_OBJECT_CLASS (pp_new_printer_dialog_parent_class)->finalize (object);
}
static void
device_selection_changed_cb (GtkTreeSelection *selection,
gpointer user_data)
{
- PpNewPrinterDialog *pp = (PpNewPrinterDialog *) user_data;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkWidget *treeview = NULL;
- GtkWidget *widget;
- gchar *device_type_name = NULL;
- gint device_type_id = -1;
- gint device_type = -1;
+ PpNewPrinterDialog *dialog = PP_NEW_PRINTER_DIALOG (user_data);
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *treeview = NULL;
+ GtkWidget *widget;
treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "device-types-treeview");
-
- if (gtk_tree_selection_get_selected (
- gtk_tree_view_get_selection (
- GTK_TREE_VIEW (treeview)), &model, &iter))
- gtk_tree_model_get (model, &iter,
- DEVICE_TYPE_ID_COLUMN, &device_type_id,
- DEVICE_TYPE_NAME_COLUMN, &device_type_name,
- DEVICE_TYPE_TYPE_COLUMN, &device_type,
- -1);
-
- if (device_type == DEVICE_TYPE_LOCAL)
- treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "local-devices-treeview");
- else if (device_type == DEVICE_TYPE_NETWORK)
- treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "network-devices-treeview");
+ gtk_builder_get_object (priv->builder, "devices-treeview");
widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "new-printer-add-button");
+ gtk_builder_get_object (priv->builder, "new-printer-add-button");
if (treeview)
gtk_widget_set_sensitive (widget,
@@ -261,1846 +379,1144 @@ device_selection_changed_cb (GtkTreeSelection *selection,
}
static void
-free_devices (PpNewPrinterDialog *pp)
+add_device_to_list (PpNewPrinterDialog *dialog,
+ PpPrintDevice *device,
+ gboolean new_device)
{
- int i;
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+ gboolean network_device;
+ gboolean already_present;
+ TDevice *store_device;
+ TDevice *item;
+ GList *iter;
+ gchar *name = NULL;
+ gchar *canonized_name = NULL;
+ gchar *new_name;
+ gchar *new_canonized_name = NULL;
+ gint name_index, j;
- for (i = 0; i < pp->num_devices; i++)
+ if (device)
{
- g_free (pp->devices[i].device_class);
- g_free (pp->devices[i].device_id);
- g_free (pp->devices[i].device_info);
- g_free (pp->devices[i].device_make_and_model);
- g_free (pp->devices[i].device_uri);
- g_free (pp->devices[i].device_location);
- g_free (pp->devices[i].device_ppd_uri);
- g_free (pp->devices[i].display_name);
- g_free (pp->devices[i].hostname);
- }
-
- pp->num_devices = 0;
- pp->devices = NULL;
-}
-
-static void
-store_device_parameter (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- PpNewPrinterDialog *pp = (PpNewPrinterDialog *) user_data;
- gchar *cut;
- gint index = -1;
-
- cut = g_strrstr ((gchar *)key, ":");
- if (cut)
- index = atoi ((gchar *)cut + 1);
-
- if (index >= 0)
- {
- if (g_str_has_prefix ((gchar *)key, "device-class"))
- pp->devices[index].device_class = g_strdup ((gchar *)value);
- else if (g_str_has_prefix ((gchar *)key, "device-id"))
- pp->devices[index].device_id = g_strdup ((gchar *)value);
- else if (g_str_has_prefix ((gchar *)key, "device-info"))
- pp->devices[index].device_info = g_strdup ((gchar *)value);
- else if (g_str_has_prefix ((gchar *)key, "device-make-and-model"))
- pp->devices[index].device_make_and_model = g_strdup ((gchar *)value);
- else if (g_str_has_prefix ((gchar *)key, "device-uri"))
- pp->devices[index].device_uri = g_strdup ((gchar *)value);
- else if (g_str_has_prefix ((gchar *)key, "device-location"))
- pp->devices[index].device_location = g_strdup ((gchar *)value);
- }
-}
-
-static void
-devices_get_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- PpNewPrinterDialog *pp = user_data;
- cups_dest_t *dests;
- GHashTable *devices = NULL;
- GDBusConnection *bus;
- GtkWidget *widget = NULL;
- GVariant *dg_output = NULL;
- gboolean already_present;
- GError *error = NULL;
- gchar *new_name = NULL;
- gchar *device_uri = NULL;
- char *ret_error = NULL;
- gint i, j, k;
- gint name_index;
- gint num_dests;
-
-
- dg_output = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
- res,
- &error);
-
- /* Do nothing if cancelled */
- if (!dg_output && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- {
- g_error_free (error);
- return;
- }
-
- if (dg_output)
- {
- if (g_variant_n_children (dg_output) == 2)
+ if (device->device_id ||
+ device->device_ppd ||
+ (device->host_name &&
+ device->acquisition_method == ACQUISITION_METHOD_REMOTE_CUPS_SERVER))
{
- GVariant *devices_variant = NULL;
+ network_device = FALSE;
- g_variant_get (dg_output, "(&s@a{ss})",
- &ret_error,
- &devices_variant);
+ if (device->device_class &&
+ g_strcmp0 (device->device_class, "network") == 0)
+ network_device = TRUE;
- if (devices_variant)
+ store_device = g_new0 (TDevice, 1);
+ store_device->device_original_name = g_strdup (device->device_name);
+ store_device->device_info = g_strdup (device->device_info);
+ store_device->device_location = g_strdup (device->device_location);
+ store_device->device_make_and_model = g_strdup (device->device_make_and_model);
+ store_device->device_uri = g_strdup (device->device_uri);
+ store_device->device_id = g_strdup (device->device_id);
+ store_device->device_ppd = g_strdup (device->device_ppd);
+ store_device->host_name = g_strdup (device->host_name);
+ store_device->host_port = device->host_port;
+ store_device->network_device = network_device;
+ store_device->acquisition_method = device->acquisition_method;
+ store_device->show = TRUE;
+
+ if (device->device_id)
{
- if (g_variant_is_of_type (devices_variant, G_VARIANT_TYPE ("a{ss}")))
- {
- GVariantIter *iter;
- 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;
- gchar *value;
- g_variant_get (item,
- "{ss}",
- &key,
- &value);
-
- g_hash_table_insert (devices, key, value);
-
- g_variant_unref (item);
- }
- }
- g_variant_unref (devices_variant);
+ name = get_tag_value (device->device_id, "mdl");
+ if (!name)
+ name = get_tag_value (device->device_id, "model");
}
- }
- g_variant_unref (dg_output);
- }
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
- g_object_unref (source_object);
-
- 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++)
+ if (!name &&
+ device->device_make_and_model &&
+ device->device_make_and_model[0] != '\0')
{
- gchar *name = NULL;
+ name = g_strdup (device->device_make_and_model);
+ }
- if (pp->devices[i].device_id)
+ if (!name &&
+ device->device_name &&
+ device->device_name[0] != '\0')
+ {
+ name = g_strdup (device->device_name);
+ }
+
+ if (!name &&
+ device->device_info &&
+ device->device_info[0] != '\0')
+ {
+ name = g_strdup (device->device_info);
+ }
+
+ g_strstrip (name);
+
+ name_index = 2;
+ already_present = FALSE;
+ do
+ {
+ if (already_present)
{
- name = get_tag_value (pp->devices[i].device_id, "mdl");
- if (!name)
- name = get_tag_value (pp->devices[i].device_id, "model");
-
- if (name)
- name = g_strcanon (name, ALLOWED_CHARACTERS, '-');
+ new_name = g_strdup_printf ("%s %d", name, name_index);
+ name_index++;
+ }
+ else
+ {
+ new_name = g_strdup (name);
}
- if (!name &&
- pp->devices[i].device_info)
+ if (new_name)
{
- name = g_strdup (pp->devices[i].device_info);
- if (name)
- name = g_strcanon (name, ALLOWED_CHARACTERS, '-');
+ new_canonized_name = g_strcanon (g_strdup (new_name), ALLOWED_CHARACTERS, '-');
}
- name_index = 2;
already_present = FALSE;
- num_dests = cupsGetDests (&dests);
- do
+ for (j = 0; j < priv->num_of_dests; j++)
+ if (g_strcmp0 (priv->dests[j].name, new_canonized_name) == 0)
+ already_present = TRUE;
+
+ for (iter = priv->devices; iter; iter = iter->next)
{
- if (already_present)
- {
- new_name = g_strdup_printf ("%s-%d", name, name_index);
- name_index++;
- }
- else
- new_name = g_strdup (name);
-
- already_present = FALSE;
- for (j = 0; j < num_dests; j++)
- if (g_strcmp0 (dests[j].name, new_name) == 0)
- already_present = TRUE;
-
- if (already_present)
- g_free (new_name);
- else
- {
- g_free (name);
- name = new_name;
- }
- } while (already_present);
- cupsFreeDests (num_dests, dests);
-
- pp->devices[i].display_name = name;
- }
-
- /* Set show bool
- * Don't show duplicates.
- * Show devices with device-id.
- * Other preferences should apply here.
- */
- bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
- if (bus)
- {
- GVariantBuilder device_list;
- GVariantBuilder device_hash;
- GVariant *output = NULL;
- GVariant *array = NULL;
- GVariant *subarray = NULL;
-
- g_variant_builder_init (&device_list, G_VARIANT_TYPE ("a{sv}"));
-
- for (i = 0; i < pp->num_devices; i++)
- {
- if (pp->devices[i].device_uri)
- {
- g_variant_builder_init (&device_hash, G_VARIANT_TYPE ("a{ss}"));
-
- if (pp->devices[i].device_id)
- g_variant_builder_add (&device_hash,
- "{ss}",
- "device-id",
- pp->devices[i].device_id);
-
- if (pp->devices[i].device_make_and_model)
- g_variant_builder_add (&device_hash,
- "{ss}",
- "device-make-and-model",
- pp->devices[i].device_make_and_model);
-
- if (pp->devices[i].device_class)
- g_variant_builder_add (&device_hash,
- "{ss}",
- "device-class",
- pp->devices[i].device_class);
-
- g_variant_builder_add (&device_list,
- "{sv}",
- pp->devices[i].device_uri,
- g_variant_builder_end (&device_hash));
- }
+ item = (TDevice *) iter->data;
+ if (g_strcmp0 (item->device_name, new_canonized_name) == 0)
+ already_present = TRUE;
}
- output = g_dbus_connection_call_sync (bus,
- SCP_BUS,
- SCP_PATH,
- SCP_IFACE,
- "GroupPhysicalDevices",
- g_variant_new ("(v)", g_variant_builder_end (&device_list)),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- 60000,
- NULL,
- &error);
-
- if (output && g_variant_n_children (output) == 1)
+ for (iter = priv->new_devices; iter; iter = iter->next)
{
- array = g_variant_get_child_value (output, 0);
- if (array)
- {
- for (i = 0; i < g_variant_n_children (array); i++)
- {
- subarray = g_variant_get_child_value (array, i);
- if (subarray)
- {
- device_uri = g_strdup (g_variant_get_string (
- g_variant_get_child_value (subarray, 0),
- NULL));
-
- for (k = 0; k < pp->num_devices; k++)
- if (g_str_has_prefix (pp->devices[k].device_uri, device_uri))
- pp->devices[k].show = TRUE;
-
- g_free (device_uri);
- }
- }
- }
+ item = (TDevice *) iter->data;
+ if (g_strcmp0 (item->device_name, new_canonized_name) == 0)
+ already_present = TRUE;
}
- if (output)
- g_variant_unref (output);
- g_object_unref (bus);
- }
-
- if (error)
- {
- if (bus == NULL ||
- (error->domain == G_DBUS_ERROR &&
- (error->code == G_DBUS_ERROR_SERVICE_UNKNOWN ||
- error->code == G_DBUS_ERROR_UNKNOWN_METHOD)))
- g_warning ("Install system-config-printer which provides \
-DBus method \"GroupPhysicalDevices\" to group duplicates in device list.");
-
- for (i = 0; i < pp->num_devices; i++)
- pp->devices[i].show = TRUE;
- }
-
- for (i = 0; i < pp->num_devices; i++)
- if (!pp->devices[i].device_id)
- pp->devices[i].show = FALSE;
- }
-
- g_hash_table_destroy (devices);
- actualize_devices_list (pp);
- }
-
- 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);
- gtk_widget_hide (widget);
-
- if (pp->cancellable != NULL)
- {
- g_object_unref (pp->cancellable);
- pp->cancellable = NULL;
- }
-}
-
-static void
-devices_get (PpNewPrinterDialog *pp)
-{
- GDBusProxy *proxy;
- GError *error = NULL;
- GVariantBuilder *in_include = NULL;
- GVariantBuilder *in_exclude = NULL;
- GtkWidget *widget = NULL;
-
- pp->searching = TRUE;
-
- proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- MECHANISM_BUS,
- "/",
- MECHANISM_BUS,
- NULL,
- &error);
-
- if (!proxy)
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- pp->searching = FALSE;
- return;
- }
-
- if (pp->show_warning)
- {
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "local-devices-notebook");
- gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), WARNING_TAB);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "network-devices-notebook");
- gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), WARNING_TAB);
- }
-
- in_include = g_variant_builder_new (G_VARIANT_TYPE ("as"));
- in_exclude = g_variant_builder_new (G_VARIANT_TYPE ("as"));
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "get-devices-status-label");
- gtk_label_set_text (GTK_LABEL (widget), _("Getting devices..."));
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "spinner");
- gtk_spinner_start (GTK_SPINNER (widget));
- gtk_widget_set_sensitive (widget, TRUE);
- gtk_widget_show (widget);
-
- pp->cancellable = g_cancellable_new ();
-
- g_dbus_proxy_call (proxy,
- "DevicesGet",
- g_variant_new ("(iiasas)",
- 0,
- 60,
- in_include,
- in_exclude),
- G_DBUS_CALL_FLAGS_NONE,
- 60000,
- pp->cancellable,
- devices_get_cb,
- pp);
-
- pp->searching = FALSE;
-}
-
-static gchar **
-line_split (gchar *line)
-{
- gboolean escaped = FALSE;
- gboolean quoted = FALSE;
- gboolean in_word = FALSE;
- gchar **words = NULL;
- gchar **result = NULL;
- gchar *buffer = NULL;
- gchar ch;
- gint n = 0;
- gint i, j = 0, k = 0;
-
- if (line)
- {
- n = strlen (line);
- words = g_new0 (gchar *, n + 1);
- buffer = g_new0 (gchar, n + 1);
-
- for (i = 0; i < n; i++)
- {
- ch = line[i];
-
- if (escaped)
- {
- buffer[k++] = ch;
- escaped = FALSE;
- continue;
- }
-
- if (ch == '\\')
- {
- in_word = TRUE;
- escaped = TRUE;
- continue;
- }
-
- if (in_word)
- {
- if (quoted)
+ if (already_present)
{
- if (ch == '"')
- quoted = FALSE;
- else
- buffer[k++] = ch;
+ g_free (new_name);
+ g_free (new_canonized_name);
}
- else if (g_ascii_isspace (ch))
- {
- words[j++] = g_strdup (buffer);
- memset (buffer, 0, n + 1);
- k = 0;
- in_word = FALSE;
- }
- else if (ch == '"')
- quoted = TRUE;
else
- buffer[k++] = ch;
- }
+ {
+ g_free (name);
+ g_free (canonized_name);
+ name = new_name;
+ canonized_name = new_canonized_name;
+ }
+ } while (already_present);
+
+ store_device->display_name = g_strdup (canonized_name);
+ store_device->device_name = canonized_name;
+ g_free (name);
+
+ if (new_device)
+ priv->new_devices = g_list_append (priv->new_devices, store_device);
else
- {
- if (ch == '"')
- {
- in_word = TRUE;
- quoted = TRUE;
- }
- else if (!g_ascii_isspace (ch))
- {
- in_word = TRUE;
- buffer[k++] = ch;
- }
- }
+ priv->devices = g_list_append (priv->devices, store_device);
}
}
-
- if (buffer && buffer[0] != '\0')
- words[j++] = g_strdup (buffer);
-
- result = g_strdupv (words);
- g_strfreev (words);
- g_free (buffer);
-
- return result;
}
static void
-service_enable (gchar *service_name,
- gint service_timeout)
+add_devices_to_list (PpNewPrinterDialog *dialog,
+ GList *devices,
+ gboolean new_device)
{
- GDBusConnection *bus;
- GVariant *output = NULL;
- GError *error = NULL;
+ GList *iter;
- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
- if (!bus)
+ for (iter = devices; iter; iter = iter->next)
{
- g_warning ("%s", error->message);
- g_error_free (error);
- return;
+ add_device_to_list (dialog, (PpPrintDevice *) iter->data, new_device);
+ }
+}
+
+static TDevice *
+device_in_list (gchar *device_uri,
+ GList *device_list)
+{
+ GList *iter;
+ TDevice *device;
+
+ for (iter = device_list; iter; iter = iter->next)
+ {
+ device = (TDevice *) iter->data;
+ /* GroupPhysicalDevices returns uris without port numbers */
+ if (g_str_has_prefix (device->device_uri, device_uri))
+ return device;
}
- output = g_dbus_connection_call_sync (bus,
- FIREWALLD_BUS,
- FIREWALLD_PATH,
- FIREWALLD_IFACE,
- "enableService",
- g_variant_new ("(si)",
- service_name,
- service_timeout),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- 60000,
- NULL,
- &error);
+ return NULL;
+}
- g_object_unref (bus);
+static void
+t_device_free (gpointer data)
+{
+ if (data)
+ {
+ TDevice *device = (TDevice *) data;
- if (output)
- {
- g_variant_unref (output);
- }
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
+ g_free (device->display_name);
+ g_free (device->device_name);
+ g_free (device->device_original_name);
+ g_free (device->device_info);
+ g_free (device->device_location);
+ g_free (device->device_make_and_model);
+ g_free (device->device_uri);
+ g_free (device->device_id);
+ g_free (device->device_ppd);
+ g_free (device);
}
}
static void
-service_disable (gchar *service_name)
+update_spinner_state (PpNewPrinterDialog *dialog)
{
- GDBusConnection *bus;
- GVariant *output = NULL;
- GError *error = NULL;
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+ GtkWidget *spinner;
- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
- if (!bus)
+ if (priv->cups_searching ||
+ priv->remote_cups_searching ||
+ priv->snmp_searching)
{
- g_warning ("%s", error->message);
- g_error_free (error);
- return;
- }
-
- output = g_dbus_connection_call_sync (bus,
- FIREWALLD_BUS,
- FIREWALLD_PATH,
- FIREWALLD_IFACE,
- "disableService",
- g_variant_new ("(s)", service_name),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- 60000,
- NULL,
- &error);
-
- g_object_unref (bus);
-
- if (output)
- {
- g_variant_unref (output);
+ spinner = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "spinner");
+ gtk_spinner_start (GTK_SPINNER (spinner));
+ gtk_widget_show (spinner);
}
else
{
- g_warning ("%s", error->message);
- g_error_free (error);
+ spinner = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "spinner");
+ gtk_spinner_stop (GTK_SPINNER (spinner));
+ gtk_widget_hide (spinner);
}
}
-static gboolean
-service_enabled (gchar *service_name)
-{
- GDBusConnection *bus;
- GVariant *output = NULL;
- GError *error = NULL;
- gint query_result = 0;
-
- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
- if (!bus)
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- return FALSE;
- }
-
- output = g_dbus_connection_call_sync (bus,
- FIREWALLD_BUS,
- FIREWALLD_PATH,
- FIREWALLD_IFACE,
- "queryService",
- g_variant_new ("(s)", service_name),
- G_VARIANT_TYPE ("(i)"),
- G_DBUS_CALL_FLAGS_NONE,
- 60000,
- NULL,
- &error);
-
- g_object_unref (bus);
-
- if (output)
- {
- if (g_variant_n_children (output) == 1)
- g_variant_get (output, "(i)", &query_result);
- g_variant_unref (output);
- }
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- return FALSE;
- }
-
- if (query_result > 0)
- return TRUE;
- else
- return FALSE;
-}
-
-static gboolean
-dbus_method_available (gchar *name,
- gchar *path,
- gchar *iface,
- gchar *method)
-{
- GDBusConnection *bus;
- GError *error = NULL;
- GVariant *output = NULL;
- gboolean result = FALSE;
-
- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
- if (!bus)
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- return FALSE;
- }
-
- output = g_dbus_connection_call_sync (bus,
- name,
- path,
- iface,
- method,
- NULL,
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- 60000,
- NULL,
- &error);
-
- g_object_unref (bus);
-
- if (output)
- {
- g_variant_unref (output);
- result = TRUE;
- }
- else
- {
- if (error->domain == G_DBUS_ERROR &&
- error->code == G_DBUS_ERROR_SERVICE_UNKNOWN)
- result = FALSE;
- else
- result = TRUE;
- }
-
- return result;
-}
-
static void
-search_address_cb (GtkToggleButton *togglebutton,
- gpointer user_data)
+group_physical_devices_cb (gchar ***device_uris,
+ gpointer user_data)
{
- PpNewPrinterDialog *pp = (PpNewPrinterDialog*) user_data;
- GtkWidget *widget;
- gint i;
+ PpNewPrinterDialog *dialog = (PpNewPrinterDialog *) user_data;
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+ TDevice *device, *tmp;
+ gint i, j;
- pp->searching = TRUE;
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "search-by-address-checkbutton");
-
- if (widget && gtk_toggle_button_get_active (togglebutton))
+ if (device_uris)
{
- gchar *uri = NULL;
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "address-entry");
- uri = g_strdup (gtk_entry_get_text (GTK_ENTRY (widget)));
-
- if (uri && uri[0] != '\0')
+ for (i = 0; device_uris[i]; i++)
{
- cups_dest_t *dests = NULL;
- http_t *http;
- GError *error = NULL;
- gchar *tmp = NULL;
- gchar *host = NULL;
- gchar *port_string = NULL;
- gchar *position;
- gchar *command;
- gchar *standard_output = NULL;
- gint exit_status = -1;
- gint num_dests = 0;
- gint length;
- int port = 631;
-
- if (g_strrstr (uri, "://"))
- tmp = g_strrstr (uri, "://") + 3;
- else
- tmp = uri;
-
- if (g_strrstr (tmp, "@"))
- tmp = g_strrstr (tmp, "@") + 1;
-
- if ((position = g_strrstr (tmp, "/")))
+ if (device_uris[i])
{
- *position = '\0';
- host = g_strdup (tmp);
- *position = '/';
- }
- else
- host = g_strdup (tmp);
-
- if ((position = g_strrstr (host, ":")))
- {
- *position = '\0';
- port_string = position + 1;
- }
-
- if (port_string)
- port = atoi (port_string);
-
- if (host)
- {
- /* Use CUPS to get printer's informations */
- http = httpConnectEncrypt (host, port, cupsEncryption ());
- if (http)
+ for (j = 0; device_uris[i][j]; j++)
{
- gchar *device_uri = NULL;
- gchar *device_ppd_uri = NULL;
-
- num_dests = cupsGetDests2 (http, &dests);
-
- if (num_dests > 0)
- {
- CupsDevice *devices = NULL;
- devices = g_new0 (CupsDevice, pp->num_devices + num_dests);
-
- for (i = 0; i < pp->num_devices; i++)
- {
- devices[i] = pp->devices[i];
- pp->devices[i].device_class = NULL;
- pp->devices[i].device_id = NULL;
- pp->devices[i].device_info = NULL;
- pp->devices[i].device_make_and_model = NULL;
- pp->devices[i].device_uri = NULL;
- pp->devices[i].device_location = NULL;
- pp->devices[i].device_ppd_uri = NULL;
- pp->devices[i].display_name = NULL;
- pp->devices[i].hostname = NULL;
- }
-
- g_free (pp->devices);
- pp->devices = devices;
-
- for (i = 0; i < num_dests; i++)
- {
- device_uri = g_strdup_printf ("ipp://%s:%d/printers/%s", host, port, dests[i].name);
- device_ppd_uri = g_strdup_printf ("%s.ppd", device_uri);
-
- pp->devices[pp->num_devices + i].device_class = g_strdup ("network");
- pp->devices[pp->num_devices + i].device_uri = device_uri;
- pp->devices[pp->num_devices + i].display_name = g_strdup (dests[i].name);
- pp->devices[pp->num_devices + i].device_ppd_uri = device_ppd_uri;
- pp->devices[pp->num_devices + i].show = TRUE;
- pp->devices[pp->num_devices + i].hostname = g_strdup (host);
- pp->devices[pp->num_devices + i].host_port = port;
- pp->devices[pp->num_devices + i].found = TRUE;
- }
-
- pp->num_devices += num_dests;
- }
-
- httpClose (http);
+ device = device_in_list (device_uris[i][j], priv->devices);
+ if (device)
+ break;
}
- /* Use SNMP to get printer's informations */
- command = g_strdup_printf ("/usr/lib/cups/backend/snmp %s", host);
- if (g_spawn_command_line_sync (command, &standard_output, NULL, &exit_status, &error))
+ if (device)
{
- if (exit_status == 0 && standard_output)
+ for (j = 0; device_uris[i][j]; j++)
{
- gchar **printer_informations = NULL;
-
- printer_informations = line_split (standard_output);
- length = g_strv_length (printer_informations);
-
- if (length >= 4)
+ tmp = device_in_list (device_uris[i][j], priv->new_devices);
+ if (tmp)
{
- CupsDevice *devices = NULL;
- devices = g_new0 (CupsDevice, pp->num_devices + 1);
-
- for (i = 0; i < pp->num_devices; i++)
- {
- devices[i] = pp->devices[i];
- pp->devices[i].device_class = NULL;
- pp->devices[i].device_id = NULL;
- pp->devices[i].device_info = NULL;
- pp->devices[i].device_make_and_model = NULL;
- pp->devices[i].device_uri = NULL;
- pp->devices[i].device_location = NULL;
- pp->devices[i].device_ppd_uri = NULL;
- pp->devices[i].display_name = NULL;
- pp->devices[i].hostname = NULL;
- }
-
- g_free (pp->devices);
- pp->devices = devices;
-
- pp->devices[pp->num_devices].device_class = g_strdup (printer_informations[0]);
- pp->devices[pp->num_devices].device_uri = g_strdup (printer_informations[1]);
- pp->devices[pp->num_devices].device_make_and_model = g_strdup (printer_informations[2]);
- pp->devices[pp->num_devices].device_info = g_strdup (printer_informations[3]);
- pp->devices[pp->num_devices].display_name = g_strdup (printer_informations[3]);
- pp->devices[pp->num_devices].display_name =
- g_strcanon (pp->devices[pp->num_devices].display_name, ALLOWED_CHARACTERS, '-');
- pp->devices[pp->num_devices].show = TRUE;
- pp->devices[pp->num_devices].hostname = g_strdup (host);
- pp->devices[pp->num_devices].host_port = port;
- pp->devices[pp->num_devices].found = TRUE;
-
- if (length >= 5 && printer_informations[4][0] != '\0')
- pp->devices[pp->num_devices].device_id = g_strdup (printer_informations[4]);
-
- if (length >= 6 && printer_informations[5][0] != '\0')
- pp->devices[pp->num_devices].device_location = g_strdup (printer_informations[5]);
-
- pp->num_devices++;
+ priv->new_devices = g_list_remove (priv->new_devices, tmp);
+ t_device_free (tmp);
}
- g_strfreev (printer_informations);
- g_free (standard_output);
}
}
else
{
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_free (command);
- g_free (host);
- }
- }
- g_free (uri);
- }
- else
- {
- gint length = 0;
- gint j = 0;
-
- for (i = 0; i < pp->num_devices; i++)
- if (!pp->devices[i].found)
- length++;
-
- CupsDevice *devices = NULL;
- devices = g_new0 (CupsDevice, length);
-
- for (i = 0; i < pp->num_devices; i++)
- {
- if (!pp->devices[i].found)
- {
- devices[j] = pp->devices[i];
- pp->devices[i].device_class = NULL;
- pp->devices[i].device_id = NULL;
- pp->devices[i].device_info = NULL;
- pp->devices[i].device_make_and_model = NULL;
- pp->devices[i].device_uri = NULL;
- pp->devices[i].device_location = NULL;
- pp->devices[i].device_ppd_uri = NULL;
- pp->devices[i].display_name = NULL;
- pp->devices[i].hostname = NULL;
- j++;
- }
- }
-
- g_free (pp->devices);
- pp->devices = devices;
- pp->num_devices = length;
- }
-
- pp->searching = FALSE;
-
- actualize_devices_list (pp);
-}
-
-static void
-actualize_devices_list (PpNewPrinterDialog *pp)
-{
- GtkListStore *network_store;
- GtkListStore *local_store;
- GtkTreeModel *model;
- GtkTreeView *network_treeview;
- GtkTreeView *local_treeview;
- GtkTreeIter iter;
- GtkWidget *treeview;
- GtkWidget *widget;
- GtkWidget *local_notebook;
- GtkWidget *network_notebook;
- gboolean no_local_device = TRUE;
- gboolean no_network_device = TRUE;
- gint i;
- gint device_type = -1;
-
- network_treeview = (GtkTreeView*)
- gtk_builder_get_object (pp->builder, "network-devices-treeview");
-
- local_treeview = (GtkTreeView*)
- gtk_builder_get_object (pp->builder, "local-devices-treeview");
-
- network_store = gtk_list_store_new (DEVICE_N_COLUMNS,
- G_TYPE_INT,
- G_TYPE_STRING);
-
- local_store = gtk_list_store_new (DEVICE_N_COLUMNS,
- G_TYPE_INT,
- G_TYPE_STRING);
-
- for (i = 0; i < pp->num_devices; i++)
- {
- if ((pp->devices[i].device_id || pp->devices[i].device_ppd_uri) &&
- pp->devices[i].show)
- {
- if (g_strcmp0 (pp->devices[i].device_class, "network") == 0)
- {
- gtk_list_store_append (network_store, &iter);
- gtk_list_store_set (network_store, &iter,
- DEVICE_ID_COLUMN, i,
- DEVICE_NAME_COLUMN, pp->devices[i].display_name,
- -1);
- pp->show_warning = FALSE;
- no_network_device = FALSE;
- }
- else if (g_strcmp0 (pp->devices[i].device_class, "direct") == 0)
- {
- gtk_list_store_append (local_store, &iter);
- gtk_list_store_set (local_store, &iter,
- DEVICE_ID_COLUMN, i,
- DEVICE_NAME_COLUMN, pp->devices[i].display_name,
- -1);
- no_local_device = FALSE;
- }
- }
- }
-
- if (no_local_device && !pp->searching)
- {
- gtk_list_store_append (local_store, &iter);
- gtk_list_store_set (local_store, &iter,
- DEVICE_ID_COLUMN, 0,
- /* Translators: No localy connected printers were found */
- DEVICE_NAME_COLUMN, _("No local printers found"),
- -1);
- gtk_widget_set_sensitive (GTK_WIDGET (local_treeview), FALSE);
- }
- else
- gtk_widget_set_sensitive (GTK_WIDGET (local_treeview), TRUE);
-
- if (no_network_device && !pp->show_warning && !pp->searching)
- {
- gtk_list_store_append (network_store, &iter);
- gtk_list_store_set (network_store, &iter,
- DEVICE_ID_COLUMN, 0,
- /* Translators: No network printers were found */
- DEVICE_NAME_COLUMN, _("No network printers found"),
- -1);
- gtk_widget_set_sensitive (GTK_WIDGET (network_treeview), FALSE);
- }
- else
- gtk_widget_set_sensitive (GTK_WIDGET (network_treeview), TRUE);
-
- gtk_tree_view_set_model (network_treeview, GTK_TREE_MODEL (network_store));
- gtk_tree_view_set_model (local_treeview, GTK_TREE_MODEL (local_store));
-
- if (!no_network_device &&
- gtk_tree_model_get_iter_first ((GtkTreeModel *) network_store, &iter))
- gtk_tree_selection_select_iter (
- gtk_tree_view_get_selection (GTK_TREE_VIEW (network_treeview)),
- &iter);
-
- if (!no_local_device &&
- gtk_tree_model_get_iter_first ((GtkTreeModel *) local_store, &iter))
- gtk_tree_selection_select_iter (
- gtk_tree_view_get_selection (GTK_TREE_VIEW (local_treeview)),
- &iter);
-
- treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "device-types-treeview");
-
- if (gtk_tree_selection_get_selected (
- gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), &model, &iter))
- gtk_tree_model_get (model, &iter,
- DEVICE_TYPE_TYPE_COLUMN, &device_type,
- -1);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "device-type-notebook");
-
- local_notebook = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "local-devices-notebook");
-
- network_notebook = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "network-devices-notebook");
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (network_notebook), pp->show_warning ? WARNING_TAB : STANDARD_TAB);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (local_notebook), STANDARD_TAB);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), device_type);
-
- g_object_unref (network_store);
- g_object_unref (local_store);
-}
-
-static void
-populate_devices_list (PpNewPrinterDialog *pp)
-{
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
- GtkTextBuffer *text_buffer;
- GtkTextView *warning_textview;
- GtkTextIter text_iter;
- GtkWidget *network_treeview;
- GtkWidget *local_treeview;
-
- network_treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "network-devices-treeview");
-
- local_treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "local-devices-treeview");
-
- g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (network_treeview)),
- "changed", G_CALLBACK (device_selection_changed_cb), pp);
-
- g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (local_treeview)),
- "changed", G_CALLBACK (device_selection_changed_cb), pp);
-
- actualize_devices_list (pp);
-
- if (dbus_method_available (FIREWALLD_BUS,
- FIREWALLD_PATH,
- FIREWALLD_IFACE,
- "getServices"))
- {
- if (!service_enabled ("mdns"))
- service_enable ("mdns", 300);
-
- if (!service_enabled ("ipp"))
- service_enable ("ipp", 300);
-
- if (!service_enabled ("ipp-client"))
- service_enable ("ipp-client", 300);
-
- if (!service_enabled ("samba-client"))
- service_enable ("samba-client", 300);
- }
- else
- {
- pp->warning = g_strdup (_("FirewallD is not running. \
-Network printer detection needs services mdns, ipp, ipp-client \
-and samba-client enabled on firewall."));
-
- warning_textview = (GtkTextView*)
- gtk_builder_get_object (pp->builder, "local-warning");
- text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (warning_textview));
-
- gtk_text_buffer_set_text (text_buffer, "", 0);
- gtk_text_buffer_get_iter_at_offset (text_buffer, &text_iter, 0);
- gtk_text_buffer_insert (text_buffer, &text_iter, pp->warning, -1);
-
- warning_textview = (GtkTextView*)
- gtk_builder_get_object (pp->builder, "network-warning");
- text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (warning_textview));
-
- gtk_text_buffer_set_text (text_buffer, "", 0);
- gtk_text_buffer_get_iter_at_offset (text_buffer, &text_iter, 0);
- gtk_text_buffer_insert (text_buffer, &text_iter, pp->warning, -1);
-
- pp->show_warning = TRUE;
- }
-
- devices_get (pp);
-
- renderer = gtk_cell_renderer_text_new ();
-
- /* Translators: Column of devices which can be installed */
- column = gtk_tree_view_column_new_with_attributes (_("Devices"), renderer,
- "text", DEVICE_NAME_COLUMN, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (network_treeview), column);
-
- /* Translators: Column of devices which can be installed */
- column = gtk_tree_view_column_new_with_attributes (_("Devices"), renderer,
- "text", DEVICE_NAME_COLUMN, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (local_treeview), column);
-}
-
-static void
-actualize_device_types_list (PpNewPrinterDialog *pp)
-{
- GtkListStore *store;
- GtkTreeView *treeview;
- GtkTreeIter iter;
- gint i;
-
- treeview = (GtkTreeView*)
- gtk_builder_get_object (pp->builder, "device-types-treeview");
-
- store = gtk_list_store_new (DEVICE_TYPE_N_COLUMNS,
- G_TYPE_INT,
- G_TYPE_STRING,
- G_TYPE_INT);
-
- pp->device_connection_types = g_new (gchar*, 2);
- pp->num_device_connection_types = 2;
-
- /* Translators: Local means local printers */
- pp->device_connection_types[0] = g_strdup (C_("printer type", "Local"));
- /* Translators: Network means network printers */
- pp->device_connection_types[1] = g_strdup (C_("printer type", "Network"));
-
- for (i = 0; i < pp->num_device_connection_types; i++)
- {
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- DEVICE_TYPE_ID_COLUMN, i,
- DEVICE_TYPE_NAME_COLUMN, pp->device_connection_types[i],
- DEVICE_TYPE_TYPE_COLUMN, i,
- -1);
- }
-
- gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store));
-
- gtk_tree_model_get_iter_first ((GtkTreeModel *) store,
- &iter);
-
- gtk_tree_selection_select_iter (
- gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
- &iter);
-
- g_object_unref (store);
-}
-
-static void
-populate_device_types_list (PpNewPrinterDialog *pp)
-{
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
- GtkWidget *treeview;
-
- treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "device-types-treeview");
-
- actualize_device_types_list (pp);
-
- g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
- "changed", G_CALLBACK (device_type_selection_changed_cb), pp);
-
- renderer = gtk_cell_renderer_text_new ();
- /* Translators: Device types column (network or local) */
- column = gtk_tree_view_column_new_with_attributes (_("Device types"), renderer,
- "text", DEVICE_TYPE_NAME_COLUMN, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-}
-
-static GList *
-glist_uniq (GList *list)
-{
- GList *result = NULL;
- GList *iter = NULL;
- GList *tmp = NULL;
-
- for (iter = list; iter; iter = iter->next)
- {
- if (tmp == NULL ||
- g_strcmp0 ((gchar *) tmp->data, (gchar *) iter->data) != 0)
- {
- tmp = iter;
- result = g_list_append (result, g_strdup (iter->data));
- }
- }
-
- g_list_free_full (list, g_free);
-
- return result;
-}
-
-static void
-new_printer_add_button_cb (GtkButton *button,
- gpointer user_data)
-{
- PpNewPrinterDialog *pp = (PpNewPrinterDialog*) user_data;
- GtkResponseType dialog_response = GTK_RESPONSE_OK;
- GtkTreeModel *model;
- cups_dest_t *dests;
- GtkTreeIter iter;
- GtkWidget *treeview;
- gboolean success = FALSE;
- PPDName *ppd_name = NULL;
- gchar *device_name = NULL;
- gint device_id = -1;
- gint device_type = -1;
- gint i;
- int num_dests;
-
- treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "device-types-treeview");
-
- if (gtk_tree_selection_get_selected (
- gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), &model, &iter))
- gtk_tree_model_get (model, &iter,
- DEVICE_TYPE_TYPE_COLUMN, &device_type,
- -1);
-
- switch (device_type)
- {
- case DEVICE_TYPE_LOCAL:
- treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "local-devices-treeview");
- break;
- case DEVICE_TYPE_NETWORK:
- treeview = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "network-devices-treeview");
- break;
- default:
- treeview = NULL;
- break;
- }
-
- if (treeview &&
- gtk_tree_selection_get_selected (
- gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), &model, &iter))
- {
- gtk_tree_model_get (model, &iter,
- DEVICE_ID_COLUMN, &device_id,
- DEVICE_NAME_COLUMN, &device_name,
- -1);
- }
-
- if (device_id >= 0)
- {
- if (pp->devices[device_id].device_ppd_uri)
- {
- http_t *http;
-
- http = httpConnectEncrypt (pp->devices[device_id].hostname,
- pp->devices[device_id].host_port,
- cupsEncryption ());
-
- if (http)
- {
- const char *ppd_file_name;
-
- ppd_file_name = cupsGetPPD2 (http, pp->devices[device_id].display_name);
-
- if (ppd_file_name)
- {
- GDBusConnection *bus;
- GError *error = NULL;
-
- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
- if (!bus)
+ for (j = 0; device_uris[i][j]; j++)
{
- g_warning ("Failed to get system bus: %s", error->message);
- g_error_free (error);
- }
- else
- {
- GVariant *output;
-
- output = g_dbus_connection_call_sync (bus,
- MECHANISM_BUS,
- "/",
- MECHANISM_BUS,
- "PrinterAddWithPpdFile",
- g_variant_new ("(sssss)",
- pp->devices[device_id].display_name,
- pp->devices[device_id].device_uri,
- ppd_file_name,
- pp->devices[device_id].device_info ? pp->devices[device_id].device_info : "",
- pp->devices[device_id].device_location ? pp->devices[device_id].device_location : ""),
- G_VARIANT_TYPE ("(s)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- g_object_unref (bus);
-
- if (output)
+ tmp = device_in_list (device_uris[i][j], priv->new_devices);
+ if (tmp)
{
- const gchar *ret_error;
-
- g_variant_get (output, "(&s)", &ret_error);
- if (ret_error[0] != '\0')
+ priv->new_devices = g_list_remove (priv->new_devices, tmp);
+ if (j == 0)
{
- g_warning ("%s", ret_error);
- dialog_response = GTK_RESPONSE_REJECT;
+ priv->devices = g_list_append (priv->devices, tmp);
}
else
- success = TRUE;
-
- g_variant_unref (output);
- }
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- dialog_response = GTK_RESPONSE_REJECT;
+ {
+ t_device_free (tmp);
+ }
}
}
-
- g_unlink (ppd_file_name);
- }
- else
- {
- dialog_response = GTK_RESPONSE_REJECT;
- g_warning ("Getting of PPD for %s from %s:%d failed.",
- pp->devices[device_id].display_name,
- pp->devices[device_id].hostname,
- pp->devices[device_id].host_port);
}
}
}
- else if (pp->devices[device_id].device_id)
+
+ for (i = 0; device_uris[i]; i++)
{
- /* Try whether CUPS has a driver for the new printer */
- ppd_name = get_ppd_name (pp->devices[device_id].device_id,
- pp->devices[device_id].device_make_and_model,
- pp->devices[device_id].device_uri);
-
- if (ppd_name == NULL || ppd_name->ppd_match_level < PPD_EXACT_MATCH)
+ for (j = 0; device_uris[i][j]; j++)
{
- /* Try PackageKit to install printer driver */
- GDBusConnection *bus;
- GError *error = NULL;
-
- bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
- if (!bus)
- {
- g_warning ("Failed to get session bus: %s", error->message);
- g_error_free (error);
- }
- else
- {
- GVariantBuilder array_builder;
- GVariant *output;
- guint window_id = 0;
-
- g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as"));
- g_variant_builder_add (&array_builder, "s", pp->devices[device_id].device_id);
-
-#ifdef GDK_WINDOWING_X11
- window_id = GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (pp->dialog)));
-#endif
-
- output = g_dbus_connection_call_sync (bus,
- PACKAGE_KIT_BUS,
- PACKAGE_KIT_PATH,
- PACKAGE_KIT_MODIFY_IFACE,
- "InstallPrinterDrivers",
- g_variant_new ("(uass)",
- window_id,
- &array_builder,
- "hide-finished"),
- G_VARIANT_TYPE ("()"),
- G_DBUS_CALL_FLAGS_NONE,
- 3600000,
- NULL,
- &error);
- g_object_unref (bus);
-
- if (output)
- g_variant_unref (output);
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- if (ppd_name)
- {
- g_free (ppd_name->ppd_name);
- g_free (ppd_name);
- }
-
- /* Search CUPS for driver */
- ppd_name = get_ppd_name (pp->devices[device_id].device_id,
- pp->devices[device_id].device_make_and_model,
- pp->devices[device_id].device_uri);
- }
+ g_free (device_uris[i][j]);
}
- /* Add the new printer */
- if (ppd_name && ppd_name->ppd_name)
- {
- GDBusConnection *bus;
- GError *error = NULL;
- GVariant *output;
-
- bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
- if (!bus)
- {
- g_warning ("Failed to get system bus: %s", error->message);
- g_error_free (error);
- }
- else
- {
- output = g_dbus_connection_call_sync (bus,
- MECHANISM_BUS,
- "/",
- MECHANISM_BUS,
- "PrinterAdd",
- g_variant_new ("(sssss)",
- pp->devices[device_id].display_name,
- pp->devices[device_id].device_uri,
- ppd_name->ppd_name,
- pp->devices[device_id].device_info ? pp->devices[device_id].device_info : "",
- pp->devices[device_id].device_location ? pp->devices[device_id].device_location : ""),
- G_VARIANT_TYPE ("(s)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- g_object_unref (bus);
-
- if (output)
- {
- const gchar *ret_error;
-
- g_variant_get (output, "(&s)", &ret_error);
- if (ret_error[0] != '\0')
- {
- g_warning ("%s", ret_error);
- dialog_response = GTK_RESPONSE_REJECT;
- }
-
- g_variant_unref (output);
- }
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- dialog_response = GTK_RESPONSE_REJECT;
- }
- }
-
- g_free (ppd_name->ppd_name);
- g_free (ppd_name);
- }
-
- num_dests = cupsGetDests (&dests);
- for (i = 0; i < num_dests; i++)
- if (g_strcmp0 (dests[i].name, pp->devices[device_id].display_name) == 0)
- success = TRUE;
- cupsFreeDests (num_dests, dests);
+ g_free (device_uris[i]);
}
- /* Set some options of the new printer */
- if (success)
+ g_free (device_uris);
+ }
+ else
+ {
+ priv->devices = g_list_concat (priv->devices, priv->new_devices);
+ priv->new_devices = NULL;
+ }
+
+ actualize_devices_list (dialog);
+}
+
+static void
+group_physical_devices_dbus_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GVariant *output;
+ GError *error = NULL;
+ gchar ***result = NULL;
+ gint i, j;
+
+ output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
+ res,
+ &error);
+ g_object_unref (source_object);
+
+ if (output)
+ {
+ GVariant *array;
+
+ g_variant_get (output, "(@aas)", &array);
+
+ if (array)
{
- const char *ppd_file_name = NULL;
- GDBusConnection *bus;
- GError *error = NULL;
+ GVariantIter *iter;
+ GVariantIter *subiter;
+ GVariant *item;
+ GVariant *subitem;
+ gchar *device_uri;
- ppd_file_name = cupsGetPPD (pp->devices[device_id].display_name);
-
- printer_set_accepting_jobs (pp->devices[device_id].display_name, TRUE, NULL);
- printer_set_enabled (pp->devices[device_id].display_name, TRUE);
-
- if (g_strcmp0 (pp->devices[device_id].device_class, "direct") == 0)
+ result = g_new0 (gchar **, g_variant_n_children (array) + 1);
+ g_variant_get (array, "aas", &iter);
+ i = 0;
+ while ((item = g_variant_iter_next_value (iter)))
{
- gchar *commands = get_dest_attr (pp->devices[device_id].display_name, "printer-commands");
- gchar *commands_lowercase = g_ascii_strdown (commands, -1);
- ipp_t *response = NULL;
-
- if (g_strrstr (commands_lowercase, "autoconfigure"))
+ result[i] = g_new0 (gchar *, g_variant_n_children (item) + 1);
+ g_variant_get (item, "as", &subiter);
+ j = 0;
+ while ((subitem = g_variant_iter_next_value (subiter)))
{
- response = execute_maintenance_command (pp->devices[device_id].display_name,
- "AutoConfigure",
- /* Translators: Name of job which makes printer to autoconfigure itself */
- _("Automatic configuration"));
- if (response)
+ g_variant_get (subitem, "s", &device_uri);
+
+ result[i][j] = device_uri;
+
+ g_variant_unref (subitem);
+ j++;
+ }
+
+ g_variant_unref (item);
+ i++;
+ }
+
+ g_variant_unref (array);
+ }
+
+ g_variant_unref (output);
+ }
+ else if (error &&
+ error->domain == G_DBUS_ERROR &&
+ (error->code == G_DBUS_ERROR_SERVICE_UNKNOWN ||
+ error->code == G_DBUS_ERROR_UNKNOWN_METHOD))
+ {
+ g_warning ("Install system-config-printer which provides \
+DBus method \"GroupPhysicalDevices\" to group duplicates in device list.");
+ }
+ else
+ {
+ if (error->domain != G_IO_ERROR ||
+ error->code != G_IO_ERROR_CANCELLED)
+ g_warning ("%s", error->message);
+ }
+
+ if (!error ||
+ error->domain != G_IO_ERROR ||
+ error->code != G_IO_ERROR_CANCELLED)
+ group_physical_devices_cb (result, user_data);
+
+ if (error)
+ g_error_free (error);
+}
+
+static void
+get_cups_devices_cb (GList *devices,
+ gboolean finished,
+ gboolean cancelled,
+ gpointer user_data)
+{
+ PpNewPrinterDialog *dialog;
+ PpNewPrinterDialogPrivate *priv;
+ GDBusConnection *bus;
+ GVariantBuilder device_list;
+ GVariantBuilder device_hash;
+ PpPrintDevice **all_devices;
+ PpPrintDevice *pp_device;
+ TDevice *device;
+ GError *error = NULL;
+ GList *iter;
+ gint length, i;
+
+
+ if (!cancelled)
+ {
+ dialog = (PpNewPrinterDialog*) user_data;
+ priv = dialog->priv;
+
+ if (finished)
+ {
+ priv->cups_searching = FALSE;
+ }
+
+ if (devices)
+ {
+ add_devices_to_list (dialog,
+ devices,
+ TRUE);
+
+ length = g_list_length (priv->devices) + g_list_length (devices);
+ if (length > 0)
+ {
+ all_devices = g_new0 (PpPrintDevice *, length);
+
+ i = 0;
+ for (iter = priv->devices; iter; iter = iter->next)
+ {
+ device = (TDevice *) iter->data;
+ if (device)
{
- if (ippGetState (response) == IPP_ERROR)
- g_warning ("An error has occured during automatic configuration of new printer.");
- ippDelete (response);
+ all_devices[i] = g_new0 (PpPrintDevice, 1);
+ all_devices[i]->device_id = g_strdup (device->device_id);
+ all_devices[i]->device_make_and_model = g_strdup (device->device_make_and_model);
+ all_devices[i]->device_class = device->network_device ? g_strdup ("network") : strdup ("direct");
+ all_devices[i]->device_uri = g_strdup (device->device_uri);
}
+ i++;
}
- g_free (commands);
- g_free (commands_lowercase);
- }
- printer_set_default_media_size (pp->devices[device_id].display_name);
-
- if (pp->devices[device_id].device_uri &&
- dbus_method_available (FIREWALLD_BUS,
- FIREWALLD_PATH,
- FIREWALLD_IFACE,
- "getServices"))
- {
- if (g_str_has_prefix (pp->devices[device_id].device_uri, "dnssd:") ||
- g_str_has_prefix (pp->devices[device_id].device_uri, "mdns:"))
+ for (iter = devices; iter; iter = iter->next)
{
- show_notification (_("Opening firewall for mDNS connections"),
- NULL,
- "dialog-information-symbolic");
- service_disable ("mdns");
- service_enable ("mdns", 0);
+ pp_device = (PpPrintDevice *) iter->data;
+ if (pp_device)
+ {
+ all_devices[i] = g_new0 (PpPrintDevice, 1);
+ all_devices[i]->device_id = g_strdup (pp_device->device_id);
+ all_devices[i]->device_make_and_model = g_strdup (pp_device->device_make_and_model);
+ all_devices[i]->device_class = g_strdup (pp_device->device_class);
+ all_devices[i]->device_uri = g_strdup (pp_device->device_uri);
+ }
+ i++;
}
- if (g_strrstr (pp->devices[device_id].device_uri, "smb:") != NULL)
- {
- show_notification (_("Opening firewall for Samba connections"),
- NULL,
- "dialog-information-symbolic");
- service_disable ("samba-client");
- service_enable ("samba-client", 0);
- }
-
- if (g_strrstr (pp->devices[device_id].device_uri, "ipp:") != NULL)
- {
- show_notification (_("Opening firewall for IPP connections"),
- NULL,
- "dialog-information-symbolic");
- service_disable ("ipp");
- service_enable ("ipp", 0);
- service_disable ("ipp-client");
- service_enable ("ipp-client", 0);
- }
- }
-
- if (ppd_file_name)
- {
- GVariant *output;
- GVariant *array;
- GList *executables = NULL;
- GList *packages = NULL;
-
- error = NULL;
-
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
if (bus)
{
- output = g_dbus_connection_call_sync (bus,
- SCP_BUS,
- SCP_PATH,
- SCP_IFACE,
- "MissingExecutables",
- g_variant_new ("(s)", ppd_file_name),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- 60000,
- NULL,
- &error);
- g_object_unref (bus);
+ g_variant_builder_init (&device_list, G_VARIANT_TYPE ("a{sv}"));
- if (output)
+ for (i = 0; i < length; i++)
{
- if (g_variant_n_children (output) == 1)
+ if (all_devices[i]->device_uri)
{
- array = g_variant_get_child_value (output, 0);
- if (array)
- {
- for (i = 0; i < g_variant_n_children (array); i++)
- {
- executables = g_list_append (
- executables,
- g_strdup (g_variant_get_string (
- g_variant_get_child_value (array, i),
- NULL)));
- }
- }
- }
- g_variant_unref (output);
- }
- }
+ g_variant_builder_init (&device_hash, G_VARIANT_TYPE ("a{ss}"));
- if (bus == NULL ||
- (error &&
- error->domain == G_DBUS_ERROR &&
- (error->code == G_DBUS_ERROR_SERVICE_UNKNOWN ||
- error->code == G_DBUS_ERROR_UNKNOWN_METHOD)))
+ if (all_devices[i]->device_id)
+ g_variant_builder_add (&device_hash,
+ "{ss}",
+ "device-id",
+ all_devices[i]->device_id);
+
+ if (all_devices[i]->device_make_and_model)
+ g_variant_builder_add (&device_hash,
+ "{ss}",
+ "device-make-and-model",
+ all_devices[i]->device_make_and_model);
+
+ if (all_devices[i]->device_class)
+ g_variant_builder_add (&device_hash,
+ "{ss}",
+ "device-class",
+ all_devices[i]->device_class);
+
+ g_variant_builder_add (&device_list,
+ "{sv}",
+ all_devices[i]->device_uri,
+ g_variant_builder_end (&device_hash));
+ }
+ }
+
+ g_dbus_connection_call (bus,
+ SCP_BUS,
+ SCP_PATH,
+ SCP_IFACE,
+ "GroupPhysicalDevices",
+ g_variant_new ("(v)", g_variant_builder_end (&device_list)),
+ G_VARIANT_TYPE ("(aas)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->cancellable,
+ group_physical_devices_dbus_cb,
+ dialog);
+ }
+ else
{
- g_warning ("Install system-config-printer which provides \
-DBus method \"MissingExecutables\" to find missing executables and filters.");
+ g_warning ("Failed to get system bus: %s", error->message);
g_error_free (error);
+ group_physical_devices_cb (NULL, user_data);
}
- executables = g_list_sort (executables, (GCompareFunc) g_strcmp0);
- executables = glist_uniq (executables);
-
- if (executables)
+ for (i = 0; i < length; i++)
{
- bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
- if (bus)
+ if (all_devices[i])
{
- GList *exec_iter;
-
- for (exec_iter = executables; exec_iter; exec_iter = exec_iter->next)
- {
- output = g_dbus_connection_call_sync (bus,
- PACKAGE_KIT_BUS,
- PACKAGE_KIT_PATH,
- PACKAGE_KIT_QUERY_IFACE,
- "SearchFile",
- g_variant_new ("(ss)",
- (gchar *) exec_iter->data,
- ""),
- G_VARIANT_TYPE ("(bs)"),
- G_DBUS_CALL_FLAGS_NONE,
- 60000,
- NULL,
- &error);
-
- if (output)
- {
- gboolean installed;
- gchar *package;
-
- g_variant_get (output,
- "(bs)",
- &installed,
- &package);
- if (!installed)
- packages = g_list_append (packages, g_strdup (package));
- g_variant_unref (output);
- }
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
- }
-
- g_object_unref (bus);
+ g_free (all_devices[i]->device_id);
+ g_free (all_devices[i]->device_make_and_model);
+ g_free (all_devices[i]->device_class);
+ g_free (all_devices[i]->device_uri);
+ g_free (all_devices[i]);
}
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_list_free_full (executables, g_free);
}
- packages = g_list_sort (packages, (GCompareFunc) g_strcmp0);
- packages = glist_uniq (packages);
-
- if (packages)
- {
- bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
- if (bus)
- {
- GVariantBuilder array_builder;
- GList *pkg_iter;
- guint window_id = 0;
-
- g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as"));
-
- for (pkg_iter = packages; pkg_iter; pkg_iter = pkg_iter->next)
- g_variant_builder_add (&array_builder,
- "s",
- (gchar *) pkg_iter->data);
-
-#ifdef GDK_WINDOWING_X11
- window_id = GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (pp->dialog))),
-#endif
-
- output = g_dbus_connection_call_sync (bus,
- PACKAGE_KIT_BUS,
- PACKAGE_KIT_PATH,
- PACKAGE_KIT_MODIFY_IFACE,
- "InstallPackageNames",
- g_variant_new ("(uass)",
- window_id,
- &array_builder,
- "hide-finished"),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- 60000,
- NULL,
- &error);
- g_object_unref (bus);
-
- if (output)
- {
- g_variant_unref (output);
- }
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
- }
- else
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_list_free_full (packages, g_free);
- }
+ g_free (all_devices);
}
-
- if (ppd_file_name)
- g_unlink (ppd_file_name);
+ else
+ {
+ actualize_devices_list (dialog);
+ }
+ }
+ else
+ {
+ actualize_devices_list (dialog);
}
}
- pp_new_printer_dialog_hide (pp);
- pp->user_callback (GTK_DIALOG (pp->dialog), dialog_response, pp->user_data);
+ for (iter = devices; iter; iter = iter->next)
+ pp_print_device_free ((PpPrintDevice *) iter->data);
+ g_list_free (devices);
}
static void
-new_printer_cancel_button_cb (GtkButton *button,
- gpointer user_data)
+get_snmp_devices_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- PpNewPrinterDialog *pp = (PpNewPrinterDialog*) user_data;
+ PpNewPrinterDialog *dialog;
+ PpNewPrinterDialogPrivate *priv;
+ PpHost *host = (PpHost *) source_object;
+ GError *error = NULL;
+ PpDevicesList *result;
+ GList *iter;
- pp_new_printer_dialog_hide (pp);
- pp->user_callback (GTK_DIALOG (pp->dialog), GTK_RESPONSE_CANCEL, pp->user_data);
-}
+ result = pp_host_get_snmp_devices_finish (host, res, &error);
+ g_object_unref (source_object);
-PpNewPrinterDialog *
-pp_new_printer_dialog_new (GtkWindow *parent,
- UserResponseCallback user_callback,
- gpointer user_data)
-{
- PpNewPrinterDialog *pp;
- GtkWidget *widget;
- GError *error = NULL;
- gchar *objects[] = { "dialog", "main-vbox", NULL };
- guint builder_result;
-
- pp = g_new0 (PpNewPrinterDialog, 1);
-
- pp->builder = gtk_builder_new ();
- pp->parent = GTK_WIDGET (parent);
-
- builder_result = gtk_builder_add_objects_from_file (pp->builder,
- DATADIR"/new-printer-dialog.ui",
- objects, &error);
-
- if (builder_result == 0)
+ if (result)
{
- g_warning ("Could not load ui: %s", error->message);
+ dialog = PP_NEW_PRINTER_DIALOG (user_data);
+ priv = dialog->priv;
+
+ priv->snmp_searching = FALSE;
+ update_spinner_state (dialog);
+
+ if (result->devices)
+ {
+ add_devices_to_list (dialog,
+ result->devices,
+ FALSE);
+ }
+
+ actualize_devices_list (dialog);
+
+ for (iter = result->devices; iter; iter = iter->next)
+ pp_print_device_free ((PpPrintDevice *) iter->data);
+ g_list_free (result->devices);
+ g_free (result);
+ }
+ else
+ {
+ if (error->domain != G_IO_ERROR ||
+ error->code != G_IO_ERROR_CANCELLED)
+ {
+ dialog = PP_NEW_PRINTER_DIALOG (user_data);
+ priv = dialog->priv;
+
+ g_warning ("%s", error->message);
+
+ priv->snmp_searching = FALSE;
+ update_spinner_state (dialog);
+ }
+
g_error_free (error);
- return NULL;
}
-
- pp->device_connection_types = NULL;
- pp->num_device_connection_types = 0;
-
- pp->devices = NULL;
- pp->num_devices = 0;
-
- pp->dialog = (GtkWidget *) gtk_builder_get_object (pp->builder, "dialog");
-
- pp->user_callback = user_callback;
- pp->user_data = user_data;
-
- pp->cancellable = NULL;
- pp->warning = NULL;
- pp->show_warning = FALSE;
-
- /* connect signals */
- g_signal_connect (pp->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "new-printer-add-button");
- g_signal_connect (widget, "clicked", G_CALLBACK (new_printer_add_button_cb), pp);
- gtk_widget_set_sensitive (widget, FALSE);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "new-printer-cancel-button");
- g_signal_connect (widget, "clicked", G_CALLBACK (new_printer_cancel_button_cb), pp);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (pp->builder, "search-by-address-checkbutton");
- g_signal_connect (widget, "toggled", G_CALLBACK (search_address_cb), pp);
-
- gtk_window_set_transient_for (GTK_WINDOW (pp->dialog), GTK_WINDOW (parent));
- gtk_window_set_modal (GTK_WINDOW (pp->dialog), TRUE);
- gtk_window_present (GTK_WINDOW (pp->dialog));
- gtk_widget_show_all (GTK_WIDGET (pp->dialog));
-
- pp->searching = TRUE;
- populate_device_types_list (pp);
- populate_devices_list (pp);
-
- return pp;
-}
-
-void
-pp_new_printer_dialog_free (PpNewPrinterDialog *pp)
-{
- gint i;
-
- for (i = 0; i < pp->num_device_connection_types; i++)
- g_free (pp->device_connection_types[i]);
- g_free (pp->device_connection_types);
- pp->device_connection_types = NULL;
-
- free_devices (pp);
-
- gtk_widget_destroy (GTK_WIDGET (pp->dialog));
- pp->dialog = NULL;
-
- g_object_unref (pp->builder);
- pp->builder = NULL;
-
- if (pp->cancellable)
- {
- g_cancellable_cancel (pp->cancellable);
- g_object_unref (pp->cancellable);
- }
-
- g_free (pp->warning);
-
- g_free (pp);
}
static void
-pp_new_printer_dialog_hide (PpNewPrinterDialog *pp)
+get_remote_cups_devices_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- gtk_widget_hide (GTK_WIDGET (pp->dialog));
+ PpNewPrinterDialog *dialog;
+ PpNewPrinterDialogPrivate *priv;
+ PpHost *host = (PpHost *) source_object;
+ GError *error = NULL;
+ PpDevicesList *result;
+ GList *iter;
+
+ result = pp_host_get_remote_cups_devices_finish (host, res, &error);
+ g_object_unref (source_object);
+
+ if (result)
+ {
+ dialog = PP_NEW_PRINTER_DIALOG (user_data);
+ priv = dialog->priv;
+
+ priv->remote_cups_searching = FALSE;
+ update_spinner_state (dialog);
+
+ if (result->devices)
+ {
+ add_devices_to_list (dialog,
+ result->devices,
+ FALSE);
+ }
+
+ actualize_devices_list (dialog);
+
+ for (iter = result->devices; iter; iter = iter->next)
+ pp_print_device_free ((PpPrintDevice *) iter->data);
+ g_list_free (result->devices);
+ g_free (result);
+ }
+ else
+ {
+ if (error->domain != G_IO_ERROR ||
+ error->code != G_IO_ERROR_CANCELLED)
+ {
+ dialog = PP_NEW_PRINTER_DIALOG (user_data);
+ priv = dialog->priv;
+
+ g_warning ("%s", error->message);
+
+ priv->remote_cups_searching = FALSE;
+ update_spinner_state (dialog);
+ }
+
+ g_error_free (error);
+ }
+}
+
+static void
+get_cups_devices (PpNewPrinterDialog *dialog)
+{
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+
+ priv->cups_searching = TRUE;
+ update_spinner_state (dialog);
+
+ get_cups_devices_async (priv->cancellable,
+ get_cups_devices_cb,
+ dialog);
+}
+
+static gboolean
+parse_uri (gchar *uri,
+ gchar **host,
+ gint *port)
+{
+ gchar *tmp = NULL;
+ gchar *resulting_host = NULL;
+ gchar *port_string = NULL;
+ gchar *position;
+ int resulting_port = 631;
+
+ if (g_strrstr (uri, "://"))
+ tmp = g_strrstr (uri, "://") + 3;
+ else
+ tmp = uri;
+
+ if (g_strrstr (tmp, "@"))
+ tmp = g_strrstr (tmp, "@") + 1;
+
+ if ((position = g_strrstr (tmp, "/")))
+ {
+ *position = '\0';
+ resulting_host = g_strdup (tmp);
+ *position = '/';
+ }
+ else
+ resulting_host = g_strdup (tmp);
+
+ if ((position = g_strrstr (resulting_host, ":")))
+ {
+ *position = '\0';
+ port_string = position + 1;
+ }
+
+ if (port_string)
+ resulting_port = atoi (port_string);
+
+ *host = resulting_host;
+ *port = resulting_port;
+
+ return TRUE;
+}
+
+
+static void
+search_address_cb (GtkEntry *entry,
+ gpointer user_data)
+{
+ PpNewPrinterDialog *dialog = PP_NEW_PRINTER_DIALOG (user_data);
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+ gboolean found = FALSE;
+ gboolean subfound;
+ TDevice *device;
+ GList *iter, *tmp;
+ gchar *text;
+ gchar *lowercase_name;
+ gchar *lowercase_location;
+ gchar *lowercase_text;
+ gchar **words;
+ gint words_length = 0;
+ gint i;
+
+ text = g_strdup (gtk_entry_get_text (entry));
+
+ lowercase_text = g_ascii_strdown (text, -1);
+ words = g_strsplit_set (lowercase_text, " ", -1);
+ g_free (lowercase_text);
+
+ if (words)
+ {
+ words_length = g_strv_length (words);
+
+ for (iter = priv->devices; iter; iter = iter->next)
+ {
+ device = iter->data;
+
+ lowercase_name = g_ascii_strdown (device->device_name, -1);
+ if (device->device_location)
+ lowercase_location = g_ascii_strdown (device->device_location, -1);
+ else
+ lowercase_location = NULL;
+
+ subfound = TRUE;
+ for (i = 0; words[i]; i++)
+ {
+ if (!g_strrstr (lowercase_name, words[i]) &&
+ (!lowercase_location || !g_strrstr (lowercase_location, words[i])))
+ subfound = FALSE;
+ }
+
+ if (subfound)
+ {
+ device->show = TRUE;
+ found = TRUE;
+ }
+ else
+ {
+ device->show = FALSE;
+ }
+
+ g_free (lowercase_location);
+ g_free (lowercase_name);
+ }
+
+ g_strfreev (words);
+ }
+
+ if (!found && words_length == 1)
+ {
+ iter = priv->devices;
+ while (iter)
+ {
+ device = iter->data;
+ device->show = TRUE;
+
+ if (device->acquisition_method == ACQUISITION_METHOD_REMOTE_CUPS_SERVER ||
+ device->acquisition_method == ACQUISITION_METHOD_SNMP)
+ {
+ tmp = iter;
+ iter = iter->next;
+ priv->devices = g_list_remove_link (priv->devices, tmp);
+ g_list_free_full (tmp, t_device_free);
+ }
+ else
+ iter = iter->next;
+ }
+
+ iter = priv->new_devices;
+ while (iter)
+ {
+ device = iter->data;
+
+ if (device->acquisition_method == ACQUISITION_METHOD_REMOTE_CUPS_SERVER ||
+ device->acquisition_method == ACQUISITION_METHOD_SNMP)
+ {
+ tmp = iter;
+ iter = iter->next;
+ priv->new_devices = g_list_remove_link (priv->new_devices, tmp);
+ g_list_free_full (tmp, t_device_free);
+ }
+ else
+ iter = iter->next;
+ }
+
+ if (text && text[0] != '\0')
+ {
+ gchar *host = NULL;
+ gint port = 631;
+
+ parse_uri (text, &host, &port);
+
+ if (host)
+ {
+ PpHost *snmp_host;
+ PpHost *remote_cups_host;
+
+ snmp_host = pp_host_new (host, port);
+ remote_cups_host = g_object_ref (snmp_host);
+
+ priv->remote_cups_searching = TRUE;
+ priv->snmp_searching = TRUE;
+ update_spinner_state (dialog);
+
+ pp_host_get_remote_cups_devices_async (snmp_host,
+ priv->cancellable,
+ get_remote_cups_devices_cb,
+ dialog);
+
+ pp_host_get_snmp_devices_async (remote_cups_host,
+ priv->cancellable,
+ get_snmp_devices_cb,
+ dialog);
+
+ g_free (host);
+ }
+ }
+ }
+
+ actualize_devices_list (dialog);
+
+ g_free (text);
+}
+
+static void
+search_address_cb2 (GtkEntry *entry,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ search_address_cb (entry, user_data);
+}
+
+static void
+actualize_devices_list (PpNewPrinterDialog *dialog)
+{
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+ GtkTreeViewColumn *column;
+ GtkTreeSelection *selection;
+ GtkListStore *store;
+ GtkTreeView *treeview;
+ GtkTreeIter iter;
+ gboolean no_device = TRUE;
+ TDevice *device;
+ gfloat yalign;
+ GList *item;
+ gchar *display_string;
+
+ treeview = (GtkTreeView *)
+ gtk_builder_get_object (priv->builder, "devices-treeview");
+
+ store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ for (item = priv->devices; item; item = item->next)
+ {
+ device = (TDevice *) item->data;
+
+ if (device->display_name &&
+ (device->device_id ||
+ device->device_ppd ||
+ (device->host_name &&
+ device->acquisition_method == ACQUISITION_METHOD_REMOTE_CUPS_SERVER)) &&
+ device->show)
+ {
+ if (device->device_location)
+ display_string = g_markup_printf_escaped ("%s\n%s",
+ device->display_name,
+ device->device_location);
+ else
+ display_string = g_markup_printf_escaped ("%s\n ",
+ device->display_name);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ DEVICE_ICON_COLUMN, device->network_device ? "printer-network" : "printer",
+ DEVICE_NAME_COLUMN, device->device_name,
+ DEVICE_DISPLAY_NAME_COLUMN, display_string,
+ -1);
+ no_device = FALSE;
+
+ g_free (display_string);
+ }
+ }
+
+ column = gtk_tree_view_get_column (treeview, 0);
+ if (priv->text_renderer)
+ gtk_cell_renderer_get_alignment (priv->text_renderer, NULL, &yalign);
+
+ if (no_device &&
+ !priv->cups_searching &&
+ !priv->remote_cups_searching &&
+ !priv->snmp_searching)
+ {
+ if (priv->text_renderer)
+ gtk_cell_renderer_set_alignment (priv->text_renderer, 0.5, yalign);
+
+ if (column)
+ gtk_tree_view_column_set_max_width (column, 0);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (treeview), FALSE);
+
+ display_string = g_markup_printf_escaped ("%s\n",
+ /* Translators: No printers were found */
+ _("No printers detected."));
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ DEVICE_DISPLAY_NAME_COLUMN, display_string,
+ -1);
+
+ g_free (display_string);
+ }
+ else
+ {
+ if (priv->text_renderer)
+ gtk_cell_renderer_set_alignment (priv->text_renderer, 0.0, yalign);
+
+ if (column)
+ {
+ gtk_tree_view_column_set_max_width (column, -1);
+ gtk_tree_view_column_set_min_width (column, 80);
+ }
+ gtk_widget_set_sensitive (GTK_WIDGET (treeview), TRUE);
+ }
+
+ gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store));
+
+ if (!no_device &&
+ gtk_tree_model_get_iter_first ((GtkTreeModel *) store, &iter) &&
+ (selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview))) != NULL)
+ gtk_tree_selection_select_iter (selection, &iter);
+
+ g_object_unref (store);
+ update_spinner_state (dialog);
+}
+
+static void
+cups_get_dests_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PpNewPrinterDialog *dialog;
+ PpNewPrinterDialogPrivate *priv;
+ PpCupsDests *dests;
+ PpCups *cups = (PpCups *) source_object;
+ GError *error = NULL;
+
+ dests = pp_cups_get_dests_finish (cups, res, &error);
+ g_object_unref (source_object);
+
+ if (dests)
+ {
+ dialog = PP_NEW_PRINTER_DIALOG (user_data);
+ priv = dialog->priv;
+
+ priv->dests = dests->dests;
+ priv->num_of_dests = dests->num_of_dests;
+
+ get_cups_devices (dialog);
+ }
+ else
+ {
+ if (error->domain != G_IO_ERROR ||
+ error->code != G_IO_ERROR_CANCELLED)
+ {
+ dialog = PP_NEW_PRINTER_DIALOG (user_data);
+
+ g_warning ("%s", error->message);
+
+ get_cups_devices (dialog);
+ }
+
+ g_error_free (error);
+ }
+}
+
+static void
+populate_devices_list (PpNewPrinterDialog *dialog)
+{
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+ GtkTreeViewColumn *column;
+ GtkWidget *treeview;
+ PpCups *cups;
+
+ treeview = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "devices-treeview");
+
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
+ "changed", G_CALLBACK (device_selection_changed_cb), dialog);
+
+ priv->icon_renderer = gtk_cell_renderer_pixbuf_new ();
+ g_object_set (priv->icon_renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL);
+ gtk_cell_renderer_set_alignment (priv->icon_renderer, 1.0, 0.5);
+ gtk_cell_renderer_set_padding (priv->icon_renderer, 4, 4);
+ column = gtk_tree_view_column_new_with_attributes ("Icon", priv->icon_renderer,
+ "icon-name", DEVICE_ICON_COLUMN, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+
+ priv->text_renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Devices", priv->text_renderer,
+ "markup", DEVICE_DISPLAY_NAME_COLUMN, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+ cups = pp_cups_new ();
+ pp_cups_get_dests_async (cups, priv->cancellable, cups_get_dests_cb, dialog);
+}
+
+static void
+printer_add_async_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PpNewPrinterDialog *dialog;
+ GtkResponseType response_id = GTK_RESPONSE_OK;
+ PpNewPrinter *new_printer = (PpNewPrinter *) source_object;
+ gboolean success;
+ GError *error = NULL;
+
+ success = pp_new_printer_add_finish (new_printer, res, &error);
+ g_object_unref (source_object);
+
+ if (success)
+ {
+ dialog = PP_NEW_PRINTER_DIALOG (user_data);
+
+ emit_response (dialog, response_id);
+ }
+ else
+ {
+ if (error->domain != G_IO_ERROR ||
+ error->code != G_IO_ERROR_CANCELLED)
+ {
+ dialog = PP_NEW_PRINTER_DIALOG (user_data);
+
+ g_warning ("%s", error->message);
+
+ response_id = GTK_RESPONSE_REJECT;
+
+ emit_response (dialog, response_id);
+ }
+
+ g_error_free (error);
+ }
+}
+
+static void
+new_printer_dialog_response_cb (GtkDialog *_dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ PpNewPrinterDialog *dialog = (PpNewPrinterDialog*) user_data;
+ PpNewPrinterDialogPrivate *priv = dialog->priv;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *treeview;
+ TDevice *device = NULL;
+ TDevice *tmp;
+ GList *list_iter;
+ gchar *device_name = NULL;
+
+ gtk_widget_hide (GTK_WIDGET (_dialog));
+
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ g_cancellable_cancel (priv->cancellable);
+ g_clear_object (&priv->cancellable);
+
+ treeview = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "devices-treeview");
+
+ if (treeview &&
+ gtk_tree_selection_get_selected (
+ gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), &model, &iter))
+ {
+ gtk_tree_model_get (model, &iter,
+ DEVICE_NAME_COLUMN, &device_name,
+ -1);
+ }
+
+ for (list_iter = priv->devices; list_iter; list_iter = list_iter->next)
+ {
+ tmp = (TDevice *) list_iter->data;
+ if (tmp && g_strcmp0 (tmp->device_name, device_name) == 0)
+ {
+ device = tmp;
+ break;
+ }
+ }
+
+ if (device)
+ {
+ PpNewPrinter *new_printer;
+ guint window_id = 0;
+
+ emit_pre_response (dialog,
+ device->device_name,
+ device->device_location,
+ device->device_make_and_model,
+ device->network_device);
+
+#ifdef GDK_WINDOWING_X11
+ window_id = GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (_dialog)));
+#endif
+
+ new_printer = pp_new_printer_new ();
+ g_object_set (new_printer,
+ "name", device->device_name,
+ "original-name""", device->device_original_name,
+ "device-uri", device->device_uri,
+ "device-id", device->device_id,
+ "ppd-name", device->device_ppd,
+ "ppd-file-name", device->device_ppd,
+ "info", device->device_info,
+ "location", device->device_location,
+ "make-and-model", device->device_make_and_model,
+ "host-name", device->host_name,
+ "host-port", device->host_port,
+ "is-network-device", device->network_device,
+ "window-id", window_id,
+ NULL);
+
+ priv->cancellable = g_cancellable_new ();
+
+ pp_new_printer_add_async (new_printer,
+ priv->cancellable,
+ printer_add_async_cb,
+ dialog);
+ }
+ }
+ else
+ {
+ emit_response (dialog, GTK_RESPONSE_CANCEL);
+ }
}
diff --git a/panels/printers/pp-new-printer-dialog.h b/panels/printers/pp-new-printer-dialog.h
index 618c0d716..ba4eb881a 100644
--- a/panels/printers/pp-new-printer-dialog.h
+++ b/panels/printers/pp-new-printer-dialog.h
@@ -25,15 +25,40 @@
G_BEGIN_DECLS
-typedef struct _PpNewPrinterDialog PpNewPrinterDialog;
+#define PP_TYPE_NEW_PRINTER_DIALOG (pp_new_printer_dialog_get_type ())
+#define PP_NEW_PRINTER_DIALOG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PP_TYPE_NEW_PRINTER_DIALOG, PpNewPrinterDialog))
+#define PP_NEW_PRINTER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PP_TYPE_NEW_PRINTER_DIALOG, PpNewPrinterDialogClass))
+#define PP_IS_NEW_PRINTER_DIALOG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PP_TYPE_NEW_PRINTER_DIALOG))
+#define PP_IS_NEW_PRINTER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PP_TYPE_NEW_PRINTER_DIALOG))
+#define PP_NEW_PRINTER_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PP_TYPE_NEW_PRINTER_DIALOG, PpNewPrinterDialogClass))
-typedef void (*UserResponseCallback) (GtkDialog *dialog, gint response_id, gpointer user_data);
+typedef struct _PpNewPrinterDialog PpNewPrinterDialog;
+typedef struct _PpNewPrinterDialogClass PpNewPrinterDialogClass;
+typedef struct _PpNewPrinterDialogPrivate PpNewPrinterDialogPrivate;
-PpNewPrinterDialog *pp_new_printer_dialog_new (GtkWindow *parent,
- UserResponseCallback user_callback,
- gpointer user_data);
-void pp_new_printer_dialog_free (PpNewPrinterDialog *dialog);
+struct _PpNewPrinterDialog
+{
+ GObject parent_instance;
+ PpNewPrinterDialogPrivate *priv;
+};
+
+struct _PpNewPrinterDialogClass
+{
+ GObjectClass parent_class;
+
+ void (*pre_response) (PpNewPrinterDialog *dialog,
+ const gchar *device_name,
+ const gchar *device_location,
+ const gchar *device_make_and_model,
+ gboolean is_network_device);
+
+ void (*response) (PpNewPrinterDialog *dialog,
+ gint response_id);
+};
+
+GType pp_new_printer_dialog_get_type (void) G_GNUC_CONST;
+PpNewPrinterDialog *pp_new_printer_dialog_new (GtkWindow *parent);
G_END_DECLS
-#endif
+#endif /* __PP_NEW_PRINTER_DIALOG_H__ */