printers: Show authenticated Samba servers in the list of new devices

When a Samba server which needs authentication is discovered, add
it to the list of new devices and allow user to authenticate against it
by pressing new "Authenticate" button.
Show only printers available on such a server when authenticated and
remove the server from the list.

https://bugzilla.gnome.org/show_bug.cgi?id=698532
This commit is contained in:
Marek Kasik 2013-09-03 18:18:56 +02:00
parent 03d463379f
commit fa5ed6cd41
2 changed files with 300 additions and 15 deletions

View file

@ -9,6 +9,8 @@
<column type="gchararray"/>
<!-- column-name device_display_name -->
<column type="gchararray"/>
<!-- column-name server_needs_authentication -->
<column type="gboolean"/>
</columns>
</object>
<object class="GtkDialog" id="dialog">
@ -46,18 +48,58 @@
</packing>
</child>
<child>
<object class="GtkButton" id="new-printer-add-button">
<property name="label" translatable="yes">_Add</property>
<object class="GtkNotebook" id="notebook">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<property name="show_tabs">False</property>
<child>
<object class="GtkButton" id="new-printer-add-button">
<property name="label" translatable="yes">_Add</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">page 1</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkButton" id="authenticate-button">
<property name="label" translatable="yes" comments="Translators: This button opens authentication dialog for selected server.">A_uthenticate</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">page 2</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
<property name="position">1</property>
</packing>
</child>
</object>

View file

@ -59,12 +59,20 @@ static void search_address_cb (GtkEntry *entry,
static void new_printer_dialog_response_cb (GtkDialog *_dialog,
gint response_id,
gpointer user_data);
static void update_spinner_state (PpNewPrinterDialog *dialog);
static void add_devices_to_list (PpNewPrinterDialog *dialog,
GList *devices,
gboolean new_device);
static void remove_device_from_list (PpNewPrinterDialog *dialog,
const gchar *device_name);
static void pp_devices_list_free (PpDevicesList *result);
enum
{
DEVICE_GICON_COLUMN = 0,
DEVICE_NAME_COLUMN,
DEVICE_DISPLAY_NAME_COLUMN,
SERVER_NEEDS_AUTHENTICATION_COLUMN,
DEVICE_N_COLUMNS
};
@ -83,6 +91,7 @@ typedef struct
gint host_port;
gboolean network_device;
gint acquisition_method;
gboolean is_authenticated_server;
gboolean show;
} TDevice;
@ -105,6 +114,7 @@ struct _PpNewPrinterDialogPrivate
gboolean remote_cups_searching;
gboolean snmp_searching;
gboolean samba_host_searching;
gboolean samba_authenticated_searching;
gboolean samba_searching;
GtkCellRenderer *text_renderer;
@ -121,6 +131,7 @@ struct _PpNewPrinterDialogPrivate
GIcon *local_printer_icon;
GIcon *remote_printer_icon;
GIcon *authenticated_server_icon;
};
#define PP_NEW_PRINTER_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PP_TYPE_NEW_PRINTER_DIALOG, PpNewPrinterDialogPrivate))
@ -282,6 +293,142 @@ update_alignment_padding (GtkWidget *widget,
}
}
typedef struct
{
gchar *server_name;
gpointer dialog;
} AuthSMBData;
static void
get_authenticated_samba_devices_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
PpNewPrinterDialogPrivate *priv;
PpNewPrinterDialog *dialog;
PpDevicesList *result;
PpPrintDevice *device;
AuthSMBData *data;
GtkWidget *widget;
gboolean cancelled = FALSE;
PpSamba *samba = (PpSamba *) source_object;
GError *error = NULL;
GList *iter;
result = pp_samba_get_devices_finish (samba, res, &error);
g_object_unref (source_object);
data = (AuthSMBData *) user_data;
if (result != NULL)
{
dialog = PP_NEW_PRINTER_DIALOG (data->dialog);
priv = dialog->priv;
priv->samba_authenticated_searching = FALSE;
update_spinner_state (dialog);
for (iter = result->devices; iter; iter = iter->next)
{
device = (PpPrintDevice *) iter->data;
if (device->is_authenticated_server)
{
cancelled = TRUE;
break;
}
}
if (!cancelled)
{
remove_device_from_list (dialog,
data->server_name);
if (result->devices != NULL)
{
add_devices_to_list (dialog,
result->devices,
FALSE);
device = (PpPrintDevice *) result->devices->data;
if (device != NULL)
{
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "search-entry");
gtk_entry_set_text (GTK_ENTRY (widget), device->device_location);
search_address_cb (GTK_ENTRY (widget), dialog);
}
}
actualize_devices_list (dialog);
}
pp_devices_list_free (result);
}
else
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
dialog = PP_NEW_PRINTER_DIALOG (data->dialog);
priv = dialog->priv;
g_warning ("%s", error->message);
priv->samba_authenticated_searching = FALSE;
update_spinner_state (dialog);
}
g_error_free (error);
}
g_free (data->server_name);
g_free (data);
}
static void
authenticate_samba_server (GtkButton *button,
gpointer user_data)
{
PpNewPrinterDialog *dialog = (PpNewPrinterDialog *) user_data;
PpNewPrinterDialogPrivate *priv = dialog->priv;
GtkTreeModel *model;
GtkTreeIter iter;
AuthSMBData *data;
GtkWidget *treeview;
PpSamba *samba_host;
gchar *server_name = NULL;
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, &server_name,
-1);
if (server_name != NULL)
{
samba_host = pp_samba_new (GTK_WINDOW (priv->dialog),
server_name);
priv->samba_authenticated_searching = TRUE;
update_spinner_state (dialog);
data = g_new (AuthSMBData, 1);
data->server_name = server_name;
data->dialog = dialog;
pp_samba_get_devices_async (samba_host,
TRUE,
priv->cancellable,
get_authenticated_samba_devices_cb,
data);
}
}
}
static void
pp_new_printer_dialog_init (PpNewPrinterDialog *dialog)
{
@ -322,6 +469,10 @@ pp_new_printer_dialog_init (PpNewPrinterDialog *dialog)
g_signal_connect (widget, "icon-press", G_CALLBACK (search_address_cb2), dialog);
g_signal_connect (widget, "activate", G_CALLBACK (search_address_cb), dialog);
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "authenticate-button");
g_signal_connect (widget, "clicked", G_CALLBACK (authenticate_samba_server), dialog);
/* Set junctions */
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "scrolledwindow1");
@ -372,6 +523,7 @@ pp_new_printer_dialog_finalize (GObject *object)
g_clear_object (&priv->local_printer_icon);
g_clear_object (&priv->remote_printer_icon);
g_clear_object (&priv->authenticated_server_icon);
G_OBJECT_CLASS (pp_new_printer_dialog_parent_class)->finalize (object);
}
@ -386,19 +538,64 @@ device_selection_changed_cb (GtkTreeSelection *selection,
GtkTreeIter iter;
GtkWidget *treeview = NULL;
GtkWidget *widget;
GtkWidget *notebook;
gboolean authentication_needed;
gboolean selected;
treeview = (GtkWidget*)
gtk_builder_get_object (priv->builder, "devices-treeview");
widget = (GtkWidget*)
gtk_builder_get_object (priv->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));
{
selected = gtk_tree_selection_get_selected (
gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
&model,
&iter);
if (selected)
{
gtk_tree_model_get (model, &iter,
SERVER_NEEDS_AUTHENTICATION_COLUMN, &authentication_needed,
-1);
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "new-printer-add-button");
gtk_widget_set_sensitive (widget, selected);
widget = (GtkWidget*)
gtk_builder_get_object (priv->builder, "authenticate-button");
gtk_widget_set_sensitive (widget, authentication_needed);
notebook = (GtkWidget*)
gtk_builder_get_object (priv->builder, "notebook");
if (authentication_needed)
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1);
else
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0);
}
}
}
static void
remove_device_from_list (PpNewPrinterDialog *dialog,
const gchar *device_name)
{
PpNewPrinterDialogPrivate *priv = dialog->priv;
TDevice *device;
GList *iter;
for (iter = priv->devices; iter; iter = iter->next)
{
device = (TDevice *) iter->data;
if (g_strcmp0 (device->device_name, device_name) == 0)
{
priv->devices = g_list_remove_link (priv->devices, iter);
t_device_free (iter->data);
g_list_free (iter);
break;
}
}
}
static void
@ -538,6 +735,17 @@ add_device_to_list (PpNewPrinterDialog *dialog,
else
priv->devices = g_list_append (priv->devices, store_device);
}
else if (device->is_authenticated_server &&
device->host_name != NULL)
{
store_device = g_new0 (TDevice, 1);
store_device->device_name = g_strdup (device->host_name);
store_device->host_name = g_strdup (device->host_name);
store_device->is_authenticated_server = device->is_authenticated_server;
store_device->show = TRUE;
priv->devices = g_list_append (priv->devices, store_device);
}
}
}
@ -565,7 +773,8 @@ device_in_list (gchar *device_uri,
{
device = (TDevice *) iter->data;
/* GroupPhysicalDevices returns uris without port numbers */
if (g_str_has_prefix (device->device_uri, device_uri))
if (device->device_uri != NULL &&
g_str_has_prefix (device->device_uri, device_uri))
return device;
}
@ -614,6 +823,7 @@ t_device_copy (TDevice *device)
result->host_port = device->host_port;
result->network_device = device->network_device;
result->acquisition_method = device->acquisition_method;
result->is_authenticated_server = device->is_authenticated_server;
result->show = device->show;
}
@ -644,6 +854,7 @@ update_spinner_state (PpNewPrinterDialog *dialog)
priv->remote_cups_searching ||
priv->snmp_searching ||
priv->samba_host_searching ||
priv->samba_authenticated_searching ||
priv->samba_searching)
{
spinner = (GtkWidget*)
@ -1445,6 +1656,25 @@ actualize_devices_list (PpNewPrinterDialog *dialog)
-1);
no_device = FALSE;
g_free (display_string);
}
else if (device->is_authenticated_server &&
device->host_name != NULL)
{
display_string = g_markup_printf_escaped ("<b>%s</b>\n<small><span foreground=\"#555555\">%s</span></small>",
device->host_name,
/* Translators: This item is a server which needs authentication to show its printers */
_("Server requires authentication"));
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
DEVICE_GICON_COLUMN, priv->authenticated_server_icon,
DEVICE_NAME_COLUMN, device->host_name,
DEVICE_DISPLAY_NAME_COLUMN, display_string,
SERVER_NEEDS_AUTHENTICATION_COLUMN, TRUE,
-1);
no_device = FALSE;
g_free (display_string);
}
}
@ -1458,6 +1688,7 @@ actualize_devices_list (PpNewPrinterDialog *dialog)
!priv->remote_cups_searching &&
!priv->snmp_searching &&
!priv->samba_host_searching &&
!priv->samba_authenticated_searching &&
!priv->samba_searching)
{
if (priv->text_renderer)
@ -1547,7 +1778,9 @@ populate_devices_list (PpNewPrinterDialog *dialog)
GtkTreeViewColumn *column;
GtkWidget *treeview;
PpSamba *samba;
GEmblem *emblem;
PpCups *cups;
GIcon *icon, *emblem_icon;
treeview = (GtkWidget*)
gtk_builder_get_object (priv->builder, "devices-treeview");
@ -1558,6 +1791,16 @@ populate_devices_list (PpNewPrinterDialog *dialog)
priv->local_printer_icon = g_themed_icon_new ("printer");
priv->remote_printer_icon = g_themed_icon_new ("printer-network");
icon = g_themed_icon_new ("network-server");
emblem_icon = g_themed_icon_new ("changes-prevent");
emblem = g_emblem_new (emblem_icon);
priv->authenticated_server_icon = g_emblemed_icon_new (icon, emblem);
g_object_unref (icon);
g_object_unref (emblem_icon);
g_object_unref (emblem);
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);