~ubuntu-branches/ubuntu/trusty/unity-control-center/trusty

« back to all changes in this revision

Viewing changes to panels/printers/pp-new-printer-dialog.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2014-01-08 16:29:18 UTC
  • Revision ID: package-import@ubuntu.com-20140108162918-g29dd08tr913y2qh
Tags: upstream-14.04.0
ImportĀ upstreamĀ versionĀ 14.04.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright 2009-2010  Red Hat, Inc,
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 *
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
 
 
23
#include <unistd.h>
 
24
#include <stdlib.h>
 
25
 
 
26
#include <glib.h>
 
27
#include <glib/gi18n.h>
 
28
#include <glib/gstdio.h>
 
29
#include <gtk/gtk.h>
 
30
 
 
31
#include <cups/cups.h>
 
32
 
 
33
#include "pp-new-printer-dialog.h"
 
34
#include "pp-utils.h"
 
35
#include "pp-host.h"
 
36
#include "pp-cups.h"
 
37
#include "pp-new-printer.h"
 
38
 
 
39
#ifdef GDK_WINDOWING_X11
 
40
#include <gdk/gdkx.h>
 
41
#endif
 
42
 
 
43
#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
 
44
#define HAVE_CUPS_1_6 1
 
45
#endif
 
46
 
 
47
#ifndef HAVE_CUPS_1_6
 
48
#define ippGetState(ipp) ipp->state
 
49
#endif
 
50
 
 
51
static void actualize_devices_list (PpNewPrinterDialog *dialog);
 
52
static void populate_devices_list (PpNewPrinterDialog *dialog);
 
53
static void search_address_cb2 (GtkEntry             *entry,
 
54
                                GtkEntryIconPosition  icon_pos,
 
55
                                GdkEvent             *event,
 
56
                                gpointer              user_data);
 
57
static void search_address_cb (GtkEntry *entry,
 
58
                               gpointer  user_data);
 
59
static void new_printer_dialog_response_cb (GtkDialog *_dialog,
 
60
                                            gint       response_id,
 
61
                                            gpointer   user_data);
 
62
static void t_device_free (gpointer data);
 
63
 
 
64
enum
 
65
{
 
66
  DEVICE_ICON_COLUMN = 0,
 
67
  DEVICE_NAME_COLUMN,
 
68
  DEVICE_DISPLAY_NAME_COLUMN,
 
69
  DEVICE_N_COLUMNS
 
70
};
 
71
 
 
72
typedef struct
 
73
{
 
74
  gchar    *display_name;
 
75
  gchar    *device_name;
 
76
  gchar    *device_original_name;
 
77
  gchar    *device_info;
 
78
  gchar    *device_location;
 
79
  gchar    *device_make_and_model;
 
80
  gchar    *device_uri;
 
81
  gchar    *device_id;
 
82
  gchar    *device_ppd;
 
83
  gchar    *host_name;
 
84
  gint      host_port;
 
85
  gboolean  network_device;
 
86
  gint      acquisition_method;
 
87
  gboolean  show;
 
88
} TDevice;
 
89
 
 
90
struct _PpNewPrinterDialogPrivate
 
91
{
 
92
  GtkBuilder *builder;
 
93
 
 
94
  GList *devices;
 
95
  GList *new_devices;
 
96
 
 
97
  cups_dest_t *dests;
 
98
  gint         num_of_dests;
 
99
 
 
100
  GCancellable *cancellable;
 
101
 
 
102
  gboolean  cups_searching;
 
103
  gboolean  remote_cups_searching;
 
104
  gboolean  snmp_searching;
 
105
 
 
106
  GtkCellRenderer *text_renderer;
 
107
  GtkCellRenderer *icon_renderer;
 
108
 
 
109
  GtkWidget *dialog;
 
110
};
 
111
 
 
112
#define PP_NEW_PRINTER_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PP_TYPE_NEW_PRINTER_DIALOG, PpNewPrinterDialogPrivate))
 
113
 
 
114
static void pp_new_printer_dialog_finalize (GObject *object);
 
115
 
 
116
enum {
 
117
  PRE_RESPONSE,
 
118
  RESPONSE,
 
119
  LAST_SIGNAL
 
120
};
 
121
 
 
122
static guint signals[LAST_SIGNAL] = { 0 };
 
123
 
 
124
G_DEFINE_TYPE (PpNewPrinterDialog, pp_new_printer_dialog, G_TYPE_OBJECT)
 
125
 
 
126
static void
 
127
pp_new_printer_dialog_class_init (PpNewPrinterDialogClass *klass)
 
128
{
 
129
  GObjectClass *object_class;
 
130
 
 
131
  object_class = G_OBJECT_CLASS (klass);
 
132
  object_class->finalize = pp_new_printer_dialog_finalize;
 
133
 
 
134
  g_type_class_add_private (object_class, sizeof (PpNewPrinterDialogPrivate));
 
135
 
 
136
  /**
 
137
   * PpNewPrinterDialog::pre-response:
 
138
   * @device: the device that is being added
 
139
   *
 
140
   * The signal which gets emitted when the new printer dialog is closed.
 
141
   */
 
142
  signals[PRE_RESPONSE] =
 
143
    g_signal_new ("pre-response",
 
144
                  G_TYPE_FROM_CLASS (object_class),
 
145
                  G_SIGNAL_RUN_LAST,
 
146
                  G_STRUCT_OFFSET (PpNewPrinterDialogClass, pre_response),
 
147
                  NULL, NULL,
 
148
                  g_cclosure_marshal_generic,
 
149
                  G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
 
150
 
 
151
  /**
 
152
   * PpNewPrinterDialog::response:
 
153
   * @response-id: response id of dialog
 
154
   *
 
155
   * The signal which gets emitted after the printer is added and configured.
 
156
   */
 
157
  signals[RESPONSE] =
 
158
    g_signal_new ("response",
 
159
                  G_TYPE_FROM_CLASS (object_class),
 
160
                  G_SIGNAL_RUN_LAST,
 
161
                  G_STRUCT_OFFSET (PpNewPrinterDialogClass, response),
 
162
                  NULL, NULL,
 
163
                  g_cclosure_marshal_generic,
 
164
                  G_TYPE_NONE, 1, G_TYPE_INT);
 
165
}
 
166
 
 
167
 
 
168
PpNewPrinterDialog *
 
169
pp_new_printer_dialog_new (GtkWindow *parent)
 
170
{
 
171
  PpNewPrinterDialogPrivate *priv;
 
172
  PpNewPrinterDialog        *dialog;
 
173
 
 
174
  dialog = g_object_new (PP_TYPE_NEW_PRINTER_DIALOG, NULL);
 
175
  priv = dialog->priv;
 
176
 
 
177
  gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), GTK_WINDOW (parent));
 
178
 
 
179
  return PP_NEW_PRINTER_DIALOG (dialog);
 
180
}
 
181
 
 
182
static void
 
183
emit_pre_response (PpNewPrinterDialog *dialog,
 
184
                   const gchar        *device_name,
 
185
                   const gchar        *device_location,
 
186
                   const gchar        *device_make_and_model,
 
187
                   gboolean            network_device)
 
188
{
 
189
  g_signal_emit (dialog,
 
190
                 signals[PRE_RESPONSE],
 
191
                 0,
 
192
                 device_name,
 
193
                 device_location,
 
194
                 device_make_and_model,
 
195
                 network_device);
 
196
}
 
197
 
 
198
static void
 
199
emit_response (PpNewPrinterDialog *dialog,
 
200
               gint                response_id)
 
201
{
 
202
  g_signal_emit (dialog, signals[RESPONSE], 0, response_id);
 
203
}
 
204
 
 
205
/*
 
206
 * Modify padding of the content area of the GtkDialog
 
207
 * so it is aligned with the action area.
 
208
 */
 
209
static void
 
210
update_alignment_padding (GtkWidget     *widget,
 
211
                          GtkAllocation *allocation,
 
212
                          gpointer       user_data)
 
213
{
 
214
  PpNewPrinterDialog        *dialog = (PpNewPrinterDialog*) user_data;
 
215
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
216
  GtkAllocation              allocation1, allocation2;
 
217
  GtkWidget                 *action_area;
 
218
  GtkWidget                 *content_area;
 
219
  gint                       offset_left, offset_right;
 
220
  guint                      padding_left, padding_right,
 
221
                             padding_top, padding_bottom;
 
222
 
 
223
  action_area = (GtkWidget*)
 
224
    gtk_builder_get_object (priv->builder, "dialog-action-area1");
 
225
  gtk_widget_get_allocation (action_area, &allocation2);
 
226
 
 
227
  content_area = (GtkWidget*)
 
228
    gtk_builder_get_object (priv->builder, "content-alignment");
 
229
  gtk_widget_get_allocation (content_area, &allocation1);
 
230
 
 
231
  offset_left = allocation2.x - allocation1.x;
 
232
  offset_right = (allocation1.x + allocation1.width) -
 
233
                 (allocation2.x + allocation2.width);
 
234
 
 
235
  gtk_alignment_get_padding  (GTK_ALIGNMENT (content_area),
 
236
                              &padding_top, &padding_bottom,
 
237
                              &padding_left, &padding_right);
 
238
  if (allocation1.x >= 0 && allocation2.x >= 0)
 
239
    {
 
240
      if (offset_left > 0 && offset_left != padding_left)
 
241
        gtk_alignment_set_padding (GTK_ALIGNMENT (content_area),
 
242
                                   padding_top, padding_bottom,
 
243
                                   offset_left, padding_right);
 
244
 
 
245
      gtk_alignment_get_padding  (GTK_ALIGNMENT (content_area),
 
246
                                  &padding_top, &padding_bottom,
 
247
                                  &padding_left, &padding_right);
 
248
      if (offset_right > 0 && offset_right != padding_right)
 
249
        gtk_alignment_set_padding (GTK_ALIGNMENT (content_area),
 
250
                                   padding_top, padding_bottom,
 
251
                                   padding_left, offset_right);
 
252
    }
 
253
}
 
254
 
 
255
static void
 
256
pp_new_printer_dialog_init (PpNewPrinterDialog *dialog)
 
257
{
 
258
  PpNewPrinterDialogPrivate *priv;
 
259
  GtkStyleContext           *context;
 
260
  GtkWidget                 *widget;
 
261
  GError                    *error = NULL;
 
262
  gchar                     *objects[] = { "dialog", NULL };
 
263
  guint                      builder_result;
 
264
 
 
265
  priv = PP_NEW_PRINTER_DIALOG_GET_PRIVATE (dialog);
 
266
  dialog->priv = priv;
 
267
 
 
268
  priv->builder = gtk_builder_new ();
 
269
 
 
270
  builder_result = gtk_builder_add_objects_from_file (priv->builder,
 
271
                                                      DATADIR"/new-printer-dialog.ui",
 
272
                                                      objects, &error);
 
273
 
 
274
  if (builder_result == 0)
 
275
    {
 
276
      g_warning ("Could not load ui: %s", error->message);
 
277
      g_error_free (error);
 
278
    }
 
279
 
 
280
  /* GCancellable for cancelling of async operations */
 
281
  priv->cancellable = g_cancellable_new ();
 
282
 
 
283
  priv->devices = NULL;
 
284
  priv->new_devices = NULL;
 
285
  priv->dests = NULL;
 
286
  priv->num_of_dests = 0;
 
287
  priv->cups_searching = FALSE;
 
288
  priv->remote_cups_searching = FALSE;
 
289
  priv->snmp_searching = FALSE;
 
290
  priv->text_renderer = NULL;
 
291
  priv->icon_renderer = NULL;
 
292
 
 
293
  /* Construct dialog */
 
294
  priv->dialog = (GtkWidget*) gtk_builder_get_object (priv->builder, "dialog");
 
295
 
 
296
  /* Connect signals */
 
297
  g_signal_connect (priv->dialog, "response", G_CALLBACK (new_printer_dialog_response_cb), dialog);
 
298
  g_signal_connect (priv->dialog, "size-allocate", G_CALLBACK (update_alignment_padding), dialog);
 
299
 
 
300
  widget = (GtkWidget*)
 
301
    gtk_builder_get_object (priv->builder, "search-entry");
 
302
  g_signal_connect (widget, "icon-press", G_CALLBACK (search_address_cb2), dialog);
 
303
  g_signal_connect (widget, "activate", G_CALLBACK (search_address_cb), dialog);
 
304
 
 
305
  /* Set junctions */
 
306
  widget = (GtkWidget*)
 
307
    gtk_builder_get_object (priv->builder, "scrolledwindow1");
 
308
  context = gtk_widget_get_style_context (widget);
 
309
  gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
 
310
 
 
311
  widget = (GtkWidget*)
 
312
    gtk_builder_get_object (priv->builder, "toolbar1");
 
313
  context = gtk_widget_get_style_context (widget);
 
314
  gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
 
315
 
 
316
  /* Fill with data */
 
317
  populate_devices_list (dialog);
 
318
 
 
319
  gtk_widget_show (priv->dialog);
 
320
}
 
321
 
 
322
static void
 
323
pp_new_printer_dialog_finalize (GObject *object)
 
324
{
 
325
  PpNewPrinterDialog *dialog = PP_NEW_PRINTER_DIALOG (object);
 
326
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
327
 
 
328
  priv->text_renderer = NULL;
 
329
  priv->icon_renderer = NULL;
 
330
 
 
331
  if (priv->cancellable)
 
332
    {
 
333
      g_cancellable_cancel (priv->cancellable);
 
334
      g_clear_object (&priv->cancellable);
 
335
    }
 
336
 
 
337
  if (priv->builder)
 
338
    g_clear_object (&priv->builder);
 
339
 
 
340
  g_list_free_full (priv->devices, t_device_free);
 
341
  priv->devices = NULL;
 
342
 
 
343
  g_list_free_full (priv->new_devices, t_device_free);
 
344
  priv->new_devices = NULL;
 
345
 
 
346
  if (priv->num_of_dests > 0)
 
347
    {
 
348
      cupsFreeDests (priv->num_of_dests, priv->dests);
 
349
      priv->num_of_dests = 0;
 
350
      priv->dests = NULL;
 
351
    }
 
352
 
 
353
  G_OBJECT_CLASS (pp_new_printer_dialog_parent_class)->finalize (object);
 
354
}
 
355
 
 
356
static void
 
357
device_selection_changed_cb (GtkTreeSelection *selection,
 
358
                             gpointer          user_data)
 
359
{
 
360
  PpNewPrinterDialog        *dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
361
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
362
  GtkTreeModel              *model;
 
363
  GtkTreeIter                iter;
 
364
  GtkWidget                 *treeview = NULL;
 
365
  GtkWidget                 *widget;
 
366
 
 
367
  treeview = (GtkWidget*)
 
368
    gtk_builder_get_object (priv->builder, "devices-treeview");
 
369
 
 
370
  widget = (GtkWidget*)
 
371
    gtk_builder_get_object (priv->builder, "new-printer-add-button");
 
372
 
 
373
  if (treeview)
 
374
    gtk_widget_set_sensitive (widget,
 
375
      gtk_tree_selection_get_selected (
 
376
        gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
 
377
        &model,
 
378
        &iter));
 
379
}
 
380
 
 
381
static void
 
382
add_device_to_list (PpNewPrinterDialog *dialog,
 
383
                    PpPrintDevice      *device,
 
384
                    gboolean            new_device)
 
385
{
 
386
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
387
  gboolean  network_device;
 
388
  gboolean  already_present;
 
389
  TDevice  *store_device;
 
390
  TDevice  *item;
 
391
  GList    *iter;
 
392
  gchar    *name = NULL;
 
393
  gchar    *canonized_name = NULL;
 
394
  gchar    *new_name;
 
395
  gchar    *new_canonized_name = NULL;
 
396
  gint      name_index, j;
 
397
 
 
398
  if (device)
 
399
    {
 
400
      if (device->device_id ||
 
401
          device->device_ppd ||
 
402
          (device->host_name &&
 
403
           device->acquisition_method == ACQUISITION_METHOD_REMOTE_CUPS_SERVER))
 
404
        {
 
405
          network_device = FALSE;
 
406
 
 
407
          if (device->device_class &&
 
408
              g_strcmp0 (device->device_class, "network") == 0)
 
409
            network_device = TRUE;
 
410
 
 
411
          store_device = g_new0 (TDevice, 1);
 
412
          store_device->device_original_name = g_strdup (device->device_name);
 
413
          store_device->device_info = g_strdup (device->device_info);
 
414
          store_device->device_location = g_strdup (device->device_location);
 
415
          store_device->device_make_and_model = g_strdup (device->device_make_and_model);
 
416
          store_device->device_uri = g_strdup (device->device_uri);
 
417
          store_device->device_id = g_strdup (device->device_id);
 
418
          store_device->device_ppd = g_strdup (device->device_ppd);
 
419
          store_device->host_name = g_strdup (device->host_name);
 
420
          store_device->host_port = device->host_port;
 
421
          store_device->network_device = network_device;
 
422
          store_device->acquisition_method = device->acquisition_method;
 
423
          store_device->show = TRUE;
 
424
 
 
425
          if (device->device_id)
 
426
            {
 
427
              name = get_tag_value (device->device_id, "mdl");
 
428
              if (!name)
 
429
                name = get_tag_value (device->device_id, "model");
 
430
            }
 
431
 
 
432
          if (!name &&
 
433
              device->device_make_and_model &&
 
434
              device->device_make_and_model[0] != '\0')
 
435
            {
 
436
              name = g_strdup (device->device_make_and_model);
 
437
            }
 
438
 
 
439
          if (!name &&
 
440
              device->device_name &&
 
441
              device->device_name[0] != '\0')
 
442
            {
 
443
              name = g_strdup (device->device_name);
 
444
            }
 
445
 
 
446
          if (!name &&
 
447
              device->device_info &&
 
448
              device->device_info[0] != '\0')
 
449
            {
 
450
              name = g_strdup (device->device_info);
 
451
            }
 
452
 
 
453
          g_strstrip (name);
 
454
 
 
455
          name_index = 2;
 
456
          already_present = FALSE;
 
457
          do
 
458
            {
 
459
              if (already_present)
 
460
                {
 
461
                  new_name = g_strdup_printf ("%s %d", name, name_index);
 
462
                  name_index++;
 
463
                }
 
464
              else
 
465
                {
 
466
                  new_name = g_strdup (name);
 
467
                }
 
468
 
 
469
              if (new_name)
 
470
                {
 
471
                  new_canonized_name = g_strcanon (g_strdup (new_name), ALLOWED_CHARACTERS, '-');
 
472
                }
 
473
 
 
474
              already_present = FALSE;
 
475
              for (j = 0; j < priv->num_of_dests; j++)
 
476
                if (g_strcmp0 (priv->dests[j].name, new_canonized_name) == 0)
 
477
                  already_present = TRUE;
 
478
 
 
479
              for (iter = priv->devices; iter; iter = iter->next)
 
480
                {
 
481
                  item = (TDevice *) iter->data;
 
482
                  if (g_strcmp0 (item->device_name, new_canonized_name) == 0)
 
483
                    already_present = TRUE;
 
484
                }
 
485
 
 
486
              for (iter = priv->new_devices; iter; iter = iter->next)
 
487
                {
 
488
                  item = (TDevice *) iter->data;
 
489
                  if (g_strcmp0 (item->device_name, new_canonized_name) == 0)
 
490
                    already_present = TRUE;
 
491
                }
 
492
 
 
493
              if (already_present)
 
494
                {
 
495
                  g_free (new_name);
 
496
                  g_free (new_canonized_name);
 
497
                }
 
498
              else
 
499
                {
 
500
                  g_free (name);
 
501
                  g_free (canonized_name);
 
502
                  name = new_name;
 
503
                  canonized_name = new_canonized_name;
 
504
                }
 
505
            } while (already_present);
 
506
 
 
507
          store_device->display_name = g_strdup (canonized_name);
 
508
          store_device->device_name = canonized_name;
 
509
          g_free (name);
 
510
 
 
511
          if (new_device)
 
512
            priv->new_devices = g_list_append (priv->new_devices, store_device);
 
513
          else
 
514
            priv->devices = g_list_append (priv->devices, store_device);
 
515
        }
 
516
    }
 
517
}
 
518
 
 
519
static void
 
520
add_devices_to_list (PpNewPrinterDialog  *dialog,
 
521
                     GList               *devices,
 
522
                     gboolean             new_device)
 
523
{
 
524
  GList *iter;
 
525
 
 
526
  for (iter = devices; iter; iter = iter->next)
 
527
    {
 
528
      add_device_to_list (dialog, (PpPrintDevice *) iter->data, new_device);
 
529
    }
 
530
}
 
531
 
 
532
static TDevice *
 
533
device_in_list (gchar *device_uri,
 
534
                GList *device_list)
 
535
{
 
536
  GList   *iter;
 
537
  TDevice *device;
 
538
 
 
539
  for (iter = device_list; iter; iter = iter->next)
 
540
    {
 
541
      device = (TDevice *) iter->data;
 
542
      /* GroupPhysicalDevices returns uris without port numbers */
 
543
      if (g_str_has_prefix (device->device_uri, device_uri))
 
544
        return device;
 
545
    }
 
546
 
 
547
  return NULL;
 
548
}
 
549
 
 
550
static void
 
551
t_device_free (gpointer data)
 
552
{
 
553
  if (data)
 
554
    {
 
555
      TDevice *device = (TDevice *) data;
 
556
 
 
557
      g_free (device->display_name);
 
558
      g_free (device->device_name);
 
559
      g_free (device->device_original_name);
 
560
      g_free (device->device_info);
 
561
      g_free (device->device_location);
 
562
      g_free (device->device_make_and_model);
 
563
      g_free (device->device_uri);
 
564
      g_free (device->device_id);
 
565
      g_free (device->device_ppd);
 
566
      g_free (device);
 
567
    }
 
568
}
 
569
 
 
570
static void
 
571
update_spinner_state (PpNewPrinterDialog *dialog)
 
572
{
 
573
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
574
  GtkWidget *spinner;
 
575
 
 
576
  if (priv->cups_searching ||
 
577
      priv->remote_cups_searching ||
 
578
      priv->snmp_searching)
 
579
    {
 
580
      spinner = (GtkWidget*)
 
581
        gtk_builder_get_object (priv->builder, "spinner");
 
582
      gtk_spinner_start (GTK_SPINNER (spinner));
 
583
      gtk_widget_show (spinner);
 
584
    }
 
585
  else
 
586
    {
 
587
      spinner = (GtkWidget*)
 
588
        gtk_builder_get_object (priv->builder, "spinner");
 
589
      gtk_spinner_stop (GTK_SPINNER (spinner));
 
590
      gtk_widget_hide (spinner);
 
591
    }
 
592
}
 
593
 
 
594
static void
 
595
group_physical_devices_cb (gchar    ***device_uris,
 
596
                           gpointer    user_data)
 
597
{
 
598
  PpNewPrinterDialog        *dialog = (PpNewPrinterDialog *) user_data;
 
599
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
600
  TDevice                   *device, *tmp;
 
601
  gint                       i, j;
 
602
 
 
603
  if (device_uris)
 
604
    {
 
605
      for (i = 0; device_uris[i]; i++)
 
606
        {
 
607
          if (device_uris[i])
 
608
            {
 
609
              for (j = 0; device_uris[i][j]; j++)
 
610
                {
 
611
                  device = device_in_list (device_uris[i][j], priv->devices);
 
612
                  if (device)
 
613
                    break;
 
614
                }
 
615
 
 
616
              if (device)
 
617
                {
 
618
                  for (j = 0; device_uris[i][j]; j++)
 
619
                    {
 
620
                      tmp = device_in_list (device_uris[i][j], priv->new_devices);
 
621
                      if (tmp)
 
622
                        {
 
623
                          priv->new_devices = g_list_remove (priv->new_devices, tmp);
 
624
                          t_device_free (tmp);
 
625
                        }
 
626
                    }
 
627
                }
 
628
              else
 
629
                {
 
630
                  for (j = 0; device_uris[i][j]; j++)
 
631
                    {
 
632
                      tmp = device_in_list (device_uris[i][j], priv->new_devices);
 
633
                      if (tmp)
 
634
                        {
 
635
                          priv->new_devices = g_list_remove (priv->new_devices, tmp);
 
636
                          if (j == 0)
 
637
                            {
 
638
                              priv->devices = g_list_append (priv->devices, tmp);
 
639
                            }
 
640
                          else
 
641
                            {
 
642
                              t_device_free (tmp);
 
643
                            }
 
644
                        }
 
645
                    }
 
646
                }
 
647
            }
 
648
        }
 
649
 
 
650
      for (i = 0; device_uris[i]; i++)
 
651
        {
 
652
          for (j = 0; device_uris[i][j]; j++)
 
653
            {
 
654
              g_free (device_uris[i][j]);
 
655
            }
 
656
 
 
657
          g_free (device_uris[i]);
 
658
        }
 
659
 
 
660
      g_free (device_uris);
 
661
    }
 
662
  else
 
663
    {
 
664
      priv->devices = g_list_concat (priv->devices, priv->new_devices);
 
665
      priv->new_devices = NULL;
 
666
    }
 
667
 
 
668
  actualize_devices_list (dialog);
 
669
}
 
670
 
 
671
static void
 
672
group_physical_devices_dbus_cb (GObject      *source_object,
 
673
                                GAsyncResult *res,
 
674
                                gpointer      user_data)
 
675
{
 
676
  GVariant   *output;
 
677
  GError     *error = NULL;
 
678
  gchar    ***result = NULL;
 
679
  gint        i, j;
 
680
 
 
681
  output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
 
682
                                          res,
 
683
                                          &error);
 
684
  g_object_unref (source_object);
 
685
 
 
686
  if (output)
 
687
    {
 
688
      GVariant *array;
 
689
 
 
690
      g_variant_get (output, "(@aas)", &array);
 
691
 
 
692
      if (array)
 
693
        {
 
694
          GVariantIter *iter;
 
695
          GVariantIter *subiter;
 
696
          GVariant     *item;
 
697
          GVariant     *subitem;
 
698
          gchar        *device_uri;
 
699
 
 
700
          result = g_new0 (gchar **, g_variant_n_children (array) + 1);
 
701
          g_variant_get (array, "aas", &iter);
 
702
          i = 0;
 
703
          while ((item = g_variant_iter_next_value (iter)))
 
704
            {
 
705
              result[i] = g_new0 (gchar *, g_variant_n_children (item) + 1);
 
706
              g_variant_get (item, "as", &subiter);
 
707
              j = 0;
 
708
              while ((subitem = g_variant_iter_next_value (subiter)))
 
709
                {
 
710
                  g_variant_get (subitem, "s", &device_uri);
 
711
 
 
712
                  result[i][j] = device_uri;
 
713
 
 
714
                  g_variant_unref (subitem);
 
715
                  j++;
 
716
                }
 
717
 
 
718
              g_variant_unref (item);
 
719
              i++;
 
720
            }
 
721
 
 
722
          g_variant_unref (array);
 
723
        }
 
724
 
 
725
      g_variant_unref (output);
 
726
    }
 
727
  else if (error &&
 
728
           error->domain == G_DBUS_ERROR &&
 
729
           (error->code == G_DBUS_ERROR_SERVICE_UNKNOWN ||
 
730
            error->code == G_DBUS_ERROR_UNKNOWN_METHOD))
 
731
    {
 
732
      g_warning ("Install system-config-printer which provides \
 
733
DBus method \"GroupPhysicalDevices\" to group duplicates in device list.");
 
734
    }
 
735
  else
 
736
    {
 
737
      if (error->domain != G_IO_ERROR ||
 
738
          error->code != G_IO_ERROR_CANCELLED)
 
739
        g_warning ("%s", error->message);
 
740
    }
 
741
 
 
742
  if (!error ||
 
743
      error->domain != G_IO_ERROR ||
 
744
      error->code != G_IO_ERROR_CANCELLED)
 
745
    group_physical_devices_cb (result, user_data);
 
746
 
 
747
  if (error)
 
748
    g_error_free (error);
 
749
}
 
750
 
 
751
static void
 
752
get_cups_devices_cb (GList    *devices,
 
753
                     gboolean  finished,
 
754
                     gboolean  cancelled,
 
755
                     gpointer  user_data)
 
756
{
 
757
  PpNewPrinterDialog         *dialog;
 
758
  PpNewPrinterDialogPrivate  *priv;
 
759
  GDBusConnection            *bus;
 
760
  GVariantBuilder             device_list;
 
761
  GVariantBuilder             device_hash;
 
762
  PpPrintDevice             **all_devices;
 
763
  PpPrintDevice              *pp_device;
 
764
  TDevice                    *device;
 
765
  GError                     *error = NULL;
 
766
  GList                      *iter;
 
767
  gint                        length, i;
 
768
 
 
769
 
 
770
  if (!cancelled)
 
771
    {
 
772
      dialog = (PpNewPrinterDialog*) user_data;
 
773
      priv = dialog->priv;
 
774
 
 
775
      if (finished)
 
776
        {
 
777
          priv->cups_searching = FALSE;
 
778
        }
 
779
 
 
780
      if (devices)
 
781
        {
 
782
          add_devices_to_list (dialog,
 
783
                               devices,
 
784
                               TRUE);
 
785
 
 
786
          length = g_list_length (priv->devices) + g_list_length (devices);
 
787
          if (length > 0)
 
788
            {
 
789
              all_devices = g_new0 (PpPrintDevice *, length);
 
790
 
 
791
              i = 0;
 
792
              for (iter = priv->devices; iter; iter = iter->next)
 
793
                {
 
794
                  device = (TDevice *) iter->data;
 
795
                  if (device)
 
796
                    {
 
797
                      all_devices[i] = g_new0 (PpPrintDevice, 1);
 
798
                      all_devices[i]->device_id = g_strdup (device->device_id);
 
799
                      all_devices[i]->device_make_and_model = g_strdup (device->device_make_and_model);
 
800
                      all_devices[i]->device_class = device->network_device ? g_strdup ("network") : strdup ("direct");
 
801
                      all_devices[i]->device_uri = g_strdup (device->device_uri);
 
802
                    }
 
803
                  i++;
 
804
                }
 
805
 
 
806
              for (iter = devices; iter; iter = iter->next)
 
807
                {
 
808
                  pp_device = (PpPrintDevice *) iter->data;
 
809
                  if (pp_device)
 
810
                    {
 
811
                      all_devices[i] = g_new0 (PpPrintDevice, 1);
 
812
                      all_devices[i]->device_id = g_strdup (pp_device->device_id);
 
813
                      all_devices[i]->device_make_and_model = g_strdup (pp_device->device_make_and_model);
 
814
                      all_devices[i]->device_class = g_strdup (pp_device->device_class);
 
815
                      all_devices[i]->device_uri = g_strdup (pp_device->device_uri);
 
816
                    }
 
817
                  i++;
 
818
                }
 
819
 
 
820
              bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
 
821
              if (bus)
 
822
                {
 
823
                  g_variant_builder_init (&device_list, G_VARIANT_TYPE ("a{sv}"));
 
824
 
 
825
                  for (i = 0; i < length; i++)
 
826
                    {
 
827
                      if (all_devices[i]->device_uri)
 
828
                        {
 
829
                          g_variant_builder_init (&device_hash, G_VARIANT_TYPE ("a{ss}"));
 
830
 
 
831
                          if (all_devices[i]->device_id)
 
832
                            g_variant_builder_add (&device_hash,
 
833
                                                   "{ss}",
 
834
                                                   "device-id",
 
835
                                                   all_devices[i]->device_id);
 
836
 
 
837
                          if (all_devices[i]->device_make_and_model)
 
838
                            g_variant_builder_add (&device_hash,
 
839
                                                   "{ss}",
 
840
                                                   "device-make-and-model",
 
841
                                                   all_devices[i]->device_make_and_model);
 
842
 
 
843
                          if (all_devices[i]->device_class)
 
844
                            g_variant_builder_add (&device_hash,
 
845
                                                   "{ss}",
 
846
                                                   "device-class",
 
847
                                                   all_devices[i]->device_class);
 
848
 
 
849
                          g_variant_builder_add (&device_list,
 
850
                                                 "{sv}",
 
851
                                                 all_devices[i]->device_uri,
 
852
                                                 g_variant_builder_end (&device_hash));
 
853
                        }
 
854
                    }
 
855
 
 
856
                  g_dbus_connection_call (bus,
 
857
                                          SCP_BUS,
 
858
                                          SCP_PATH,
 
859
                                          SCP_IFACE,
 
860
                                          "GroupPhysicalDevices",
 
861
                                          g_variant_new ("(v)", g_variant_builder_end (&device_list)),
 
862
                                          G_VARIANT_TYPE ("(aas)"),
 
863
                                          G_DBUS_CALL_FLAGS_NONE,
 
864
                                          -1,
 
865
                                          priv->cancellable,
 
866
                                          group_physical_devices_dbus_cb,
 
867
                                          dialog);
 
868
                }
 
869
              else
 
870
                {
 
871
                  g_warning ("Failed to get system bus: %s", error->message);
 
872
                  g_error_free (error);
 
873
                  group_physical_devices_cb (NULL, user_data);
 
874
                }
 
875
 
 
876
              for (i = 0; i < length; i++)
 
877
                {
 
878
                  if (all_devices[i])
 
879
                    {
 
880
                      g_free (all_devices[i]->device_id);
 
881
                      g_free (all_devices[i]->device_make_and_model);
 
882
                      g_free (all_devices[i]->device_class);
 
883
                      g_free (all_devices[i]->device_uri);
 
884
                      g_free (all_devices[i]);
 
885
                    }
 
886
                }
 
887
 
 
888
              g_free (all_devices);
 
889
            }
 
890
          else
 
891
            {
 
892
              actualize_devices_list (dialog);
 
893
            }
 
894
        }
 
895
      else
 
896
        {
 
897
          actualize_devices_list (dialog);
 
898
        }
 
899
    }
 
900
 
 
901
  for (iter = devices; iter; iter = iter->next)
 
902
    pp_print_device_free ((PpPrintDevice *) iter->data);
 
903
  g_list_free (devices);
 
904
}
 
905
 
 
906
static void
 
907
get_snmp_devices_cb (GObject      *source_object,
 
908
                     GAsyncResult *res,
 
909
                     gpointer      user_data)
 
910
{
 
911
  PpNewPrinterDialog        *dialog;
 
912
  PpNewPrinterDialogPrivate *priv;
 
913
  PpHost                    *host = (PpHost *) source_object;
 
914
  GError                    *error = NULL;
 
915
  PpDevicesList             *result;
 
916
  GList                     *iter;
 
917
 
 
918
  result = pp_host_get_snmp_devices_finish (host, res, &error);
 
919
  g_object_unref (source_object);
 
920
 
 
921
  if (result)
 
922
    {
 
923
      dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
924
      priv = dialog->priv;
 
925
 
 
926
      priv->snmp_searching = FALSE;
 
927
      update_spinner_state (dialog);
 
928
 
 
929
      if (result->devices)
 
930
        {
 
931
          add_devices_to_list (dialog,
 
932
                               result->devices,
 
933
                               FALSE);
 
934
        }
 
935
 
 
936
      actualize_devices_list (dialog);
 
937
 
 
938
      for (iter = result->devices; iter; iter = iter->next)
 
939
        pp_print_device_free ((PpPrintDevice *) iter->data);
 
940
      g_list_free (result->devices);
 
941
      g_free (result);
 
942
    }
 
943
  else
 
944
    {
 
945
      if (error->domain != G_IO_ERROR ||
 
946
          error->code != G_IO_ERROR_CANCELLED)
 
947
        {
 
948
          dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
949
          priv = dialog->priv;
 
950
 
 
951
          g_warning ("%s", error->message);
 
952
 
 
953
          priv->snmp_searching = FALSE;
 
954
          update_spinner_state (dialog);
 
955
        }
 
956
 
 
957
      g_error_free (error);
 
958
    }
 
959
}
 
960
 
 
961
static void
 
962
get_remote_cups_devices_cb (GObject      *source_object,
 
963
                            GAsyncResult *res,
 
964
                            gpointer      user_data)
 
965
{
 
966
  PpNewPrinterDialog        *dialog;
 
967
  PpNewPrinterDialogPrivate *priv;
 
968
  PpHost                    *host = (PpHost *) source_object;
 
969
  GError                    *error = NULL;
 
970
  PpDevicesList             *result;
 
971
  GList                     *iter;
 
972
 
 
973
  result = pp_host_get_remote_cups_devices_finish (host, res, &error);
 
974
  g_object_unref (source_object);
 
975
 
 
976
  if (result)
 
977
    {
 
978
      dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
979
      priv = dialog->priv;
 
980
 
 
981
      priv->remote_cups_searching = FALSE;
 
982
      update_spinner_state (dialog);
 
983
 
 
984
      if (result->devices)
 
985
        {
 
986
          add_devices_to_list (dialog,
 
987
                               result->devices,
 
988
                               FALSE);
 
989
        }
 
990
 
 
991
      actualize_devices_list (dialog);
 
992
 
 
993
      for (iter = result->devices; iter; iter = iter->next)
 
994
        pp_print_device_free ((PpPrintDevice *) iter->data);
 
995
      g_list_free (result->devices);
 
996
      g_free (result);
 
997
    }
 
998
  else
 
999
    {
 
1000
      if (error->domain != G_IO_ERROR ||
 
1001
          error->code != G_IO_ERROR_CANCELLED)
 
1002
        {
 
1003
          dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
1004
          priv = dialog->priv;
 
1005
 
 
1006
          g_warning ("%s", error->message);
 
1007
 
 
1008
          priv->remote_cups_searching = FALSE;
 
1009
          update_spinner_state (dialog);
 
1010
        }
 
1011
 
 
1012
      g_error_free (error);
 
1013
    }
 
1014
}
 
1015
 
 
1016
static void
 
1017
get_cups_devices (PpNewPrinterDialog *dialog)
 
1018
{
 
1019
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
1020
 
 
1021
  priv->cups_searching = TRUE;
 
1022
  update_spinner_state (dialog);
 
1023
 
 
1024
  get_cups_devices_async (priv->cancellable,
 
1025
                          get_cups_devices_cb,
 
1026
                          dialog);
 
1027
}
 
1028
 
 
1029
static gboolean
 
1030
parse_uri (gchar  *uri,
 
1031
           gchar **host,
 
1032
           gint   *port)
 
1033
{
 
1034
  gchar *tmp = NULL;
 
1035
  gchar *resulting_host = NULL;
 
1036
  gchar *port_string = NULL;
 
1037
  gchar *position;
 
1038
  int    resulting_port = 631;
 
1039
 
 
1040
  if (g_strrstr (uri, "://"))
 
1041
    tmp = g_strrstr (uri, "://") + 3;
 
1042
  else
 
1043
    tmp = uri;
 
1044
 
 
1045
  if (g_strrstr (tmp, "@"))
 
1046
    tmp = g_strrstr (tmp, "@") + 1;
 
1047
 
 
1048
  if ((position = g_strrstr (tmp, "/")))
 
1049
    {
 
1050
      *position = '\0';
 
1051
      resulting_host = g_strdup (tmp);
 
1052
      *position = '/';
 
1053
    }
 
1054
  else
 
1055
    resulting_host = g_strdup (tmp);
 
1056
 
 
1057
  if ((position = g_strrstr (resulting_host, ":")))
 
1058
    {
 
1059
      *position = '\0';
 
1060
      port_string = position + 1;
 
1061
    }
 
1062
 
 
1063
  if (port_string)
 
1064
    resulting_port = atoi (port_string);
 
1065
 
 
1066
  *host = resulting_host;
 
1067
  *port = resulting_port;
 
1068
 
 
1069
  return TRUE;
 
1070
}
 
1071
 
 
1072
 
 
1073
static void
 
1074
search_address_cb (GtkEntry *entry,
 
1075
                   gpointer  user_data)
 
1076
{
 
1077
  PpNewPrinterDialog        *dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
1078
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
1079
  gboolean             found = FALSE;
 
1080
  gboolean             subfound;
 
1081
  TDevice             *device;
 
1082
  GList               *iter, *tmp;
 
1083
  gchar               *text;
 
1084
  gchar               *lowercase_name;
 
1085
  gchar               *lowercase_location;
 
1086
  gchar               *lowercase_text;
 
1087
  gchar              **words;
 
1088
  gint                 words_length = 0;
 
1089
  gint                 i;
 
1090
 
 
1091
  text = g_strdup (gtk_entry_get_text (entry));
 
1092
 
 
1093
  lowercase_text = g_ascii_strdown (text, -1);
 
1094
  words = g_strsplit_set (lowercase_text, " ", -1);
 
1095
  g_free (lowercase_text);
 
1096
 
 
1097
  if (words)
 
1098
    {
 
1099
      words_length = g_strv_length (words);
 
1100
 
 
1101
      for (iter = priv->devices; iter; iter = iter->next)
 
1102
        {
 
1103
          device = iter->data;
 
1104
 
 
1105
          lowercase_name = g_ascii_strdown (device->device_name, -1);
 
1106
          if (device->device_location)
 
1107
            lowercase_location = g_ascii_strdown (device->device_location, -1);
 
1108
          else
 
1109
            lowercase_location = NULL;
 
1110
 
 
1111
          subfound = TRUE;
 
1112
          for (i = 0; words[i]; i++)
 
1113
            {
 
1114
              if (!g_strrstr (lowercase_name, words[i]) &&
 
1115
                  (!lowercase_location || !g_strrstr (lowercase_location, words[i])))
 
1116
                subfound = FALSE;
 
1117
            }
 
1118
 
 
1119
          if (subfound)
 
1120
            {
 
1121
              device->show = TRUE;
 
1122
              found = TRUE;
 
1123
            }
 
1124
          else
 
1125
            {
 
1126
              device->show = FALSE;
 
1127
            }
 
1128
 
 
1129
          g_free (lowercase_location);
 
1130
          g_free (lowercase_name);
 
1131
        }
 
1132
 
 
1133
      g_strfreev (words);
 
1134
  }
 
1135
 
 
1136
  if (!found && words_length == 1)
 
1137
    {
 
1138
      iter = priv->devices;
 
1139
      while (iter)
 
1140
        {
 
1141
          device = iter->data;
 
1142
          device->show = TRUE;
 
1143
 
 
1144
          if (device->acquisition_method == ACQUISITION_METHOD_REMOTE_CUPS_SERVER ||
 
1145
              device->acquisition_method == ACQUISITION_METHOD_SNMP)
 
1146
            {
 
1147
              tmp = iter;
 
1148
              iter = iter->next;
 
1149
              priv->devices = g_list_remove_link (priv->devices, tmp);
 
1150
              g_list_free_full (tmp, t_device_free);
 
1151
            }
 
1152
          else
 
1153
            iter = iter->next;
 
1154
        }
 
1155
 
 
1156
      iter = priv->new_devices;
 
1157
      while (iter)
 
1158
        {
 
1159
          device = iter->data;
 
1160
 
 
1161
          if (device->acquisition_method == ACQUISITION_METHOD_REMOTE_CUPS_SERVER ||
 
1162
              device->acquisition_method == ACQUISITION_METHOD_SNMP)
 
1163
            {
 
1164
              tmp = iter;
 
1165
              iter = iter->next;
 
1166
              priv->new_devices = g_list_remove_link (priv->new_devices, tmp);
 
1167
              g_list_free_full (tmp, t_device_free);
 
1168
            }
 
1169
          else
 
1170
            iter = iter->next;
 
1171
        }
 
1172
 
 
1173
      if (text && text[0] != '\0')
 
1174
        {
 
1175
          gchar *host = NULL;
 
1176
          gint   port = 631;
 
1177
 
 
1178
          parse_uri (text, &host, &port);
 
1179
 
 
1180
          if (host)
 
1181
            {
 
1182
              PpHost *snmp_host;
 
1183
              PpHost *remote_cups_host;
 
1184
 
 
1185
              snmp_host = pp_host_new (host, port);
 
1186
              remote_cups_host = g_object_ref (snmp_host);
 
1187
 
 
1188
              priv->remote_cups_searching = TRUE;
 
1189
              priv->snmp_searching = TRUE;
 
1190
              update_spinner_state (dialog);
 
1191
 
 
1192
              pp_host_get_remote_cups_devices_async (snmp_host,
 
1193
                                                     priv->cancellable,
 
1194
                                                     get_remote_cups_devices_cb,
 
1195
                                                     dialog);
 
1196
 
 
1197
              pp_host_get_snmp_devices_async (remote_cups_host,
 
1198
                                              priv->cancellable,
 
1199
                                              get_snmp_devices_cb,
 
1200
                                              dialog);
 
1201
 
 
1202
              g_free (host);
 
1203
            }
 
1204
        }
 
1205
    }
 
1206
 
 
1207
  actualize_devices_list (dialog);
 
1208
 
 
1209
  g_free (text);
 
1210
}
 
1211
 
 
1212
static void
 
1213
search_address_cb2 (GtkEntry             *entry,
 
1214
                    GtkEntryIconPosition  icon_pos,
 
1215
                    GdkEvent             *event,
 
1216
                    gpointer              user_data)
 
1217
{
 
1218
  search_address_cb (entry, user_data);
 
1219
}
 
1220
 
 
1221
static void
 
1222
actualize_devices_list (PpNewPrinterDialog *dialog)
 
1223
{
 
1224
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
1225
  GtkTreeViewColumn *column;
 
1226
  GtkTreeSelection  *selection;
 
1227
  GtkListStore      *store;
 
1228
  GtkTreeView       *treeview;
 
1229
  GtkTreeIter        iter;
 
1230
  gboolean           no_device = TRUE;
 
1231
  TDevice           *device;
 
1232
  gfloat             yalign;
 
1233
  GList             *item;
 
1234
  gchar             *display_string;
 
1235
 
 
1236
  treeview = (GtkTreeView *)
 
1237
    gtk_builder_get_object (priv->builder, "devices-treeview");
 
1238
 
 
1239
  store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 
1240
 
 
1241
  for (item = priv->devices; item; item = item->next)
 
1242
    {
 
1243
      device = (TDevice *) item->data;
 
1244
 
 
1245
      if (device->display_name &&
 
1246
          (device->device_id ||
 
1247
           device->device_ppd ||
 
1248
           (device->host_name &&
 
1249
            device->acquisition_method == ACQUISITION_METHOD_REMOTE_CUPS_SERVER)) &&
 
1250
          device->show)
 
1251
        {
 
1252
          if (device->device_location)
 
1253
            display_string = g_markup_printf_escaped ("<b>%s</b>\n<small><span foreground=\"#555555\">%s</span></small>",
 
1254
                                                      device->display_name,
 
1255
                                                      device->device_location);
 
1256
          else
 
1257
            display_string = g_markup_printf_escaped ("<b>%s</b>\n ",
 
1258
                                                      device->display_name);
 
1259
 
 
1260
          gtk_list_store_append (store, &iter);
 
1261
          gtk_list_store_set (store, &iter,
 
1262
                              DEVICE_ICON_COLUMN, device->network_device ? "printer-network" : "printer",
 
1263
                              DEVICE_NAME_COLUMN, device->device_name,
 
1264
                              DEVICE_DISPLAY_NAME_COLUMN, display_string,
 
1265
                              -1);
 
1266
          no_device = FALSE;
 
1267
 
 
1268
          g_free (display_string);
 
1269
        }
 
1270
    }
 
1271
 
 
1272
  column = gtk_tree_view_get_column (treeview, 0);
 
1273
  if (priv->text_renderer)
 
1274
    gtk_cell_renderer_get_alignment (priv->text_renderer, NULL, &yalign);
 
1275
 
 
1276
  if (no_device &&
 
1277
      !priv->cups_searching &&
 
1278
      !priv->remote_cups_searching &&
 
1279
      !priv->snmp_searching)
 
1280
    {
 
1281
      if (priv->text_renderer)
 
1282
        gtk_cell_renderer_set_alignment (priv->text_renderer, 0.5, yalign);
 
1283
 
 
1284
      if (column)
 
1285
        gtk_tree_view_column_set_max_width (column, 0);
 
1286
 
 
1287
      gtk_widget_set_sensitive (GTK_WIDGET (treeview), FALSE);
 
1288
 
 
1289
      display_string = g_markup_printf_escaped ("<b>%s</b>\n",
 
1290
      /* Translators: No printers were found */
 
1291
                                                _("No printers detected."));
 
1292
 
 
1293
      gtk_list_store_append (store, &iter);
 
1294
      gtk_list_store_set (store, &iter,
 
1295
                          DEVICE_DISPLAY_NAME_COLUMN, display_string,
 
1296
                          -1);
 
1297
 
 
1298
      g_free (display_string);
 
1299
    }
 
1300
  else
 
1301
    {
 
1302
      if (priv->text_renderer)
 
1303
        gtk_cell_renderer_set_alignment (priv->text_renderer, 0.0, yalign);
 
1304
 
 
1305
      if (column)
 
1306
        {
 
1307
          gtk_tree_view_column_set_max_width (column, -1);
 
1308
          gtk_tree_view_column_set_min_width (column, 80);
 
1309
        }
 
1310
      gtk_widget_set_sensitive (GTK_WIDGET (treeview), TRUE);
 
1311
    }
 
1312
 
 
1313
  gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store));
 
1314
 
 
1315
  if (!no_device &&
 
1316
      gtk_tree_model_get_iter_first ((GtkTreeModel *) store, &iter) &&
 
1317
      (selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview))) != NULL)
 
1318
    gtk_tree_selection_select_iter (selection, &iter);
 
1319
 
 
1320
  g_object_unref (store);
 
1321
  update_spinner_state (dialog);
 
1322
}
 
1323
 
 
1324
static void
 
1325
cups_get_dests_cb (GObject      *source_object,
 
1326
                   GAsyncResult *res,
 
1327
                   gpointer      user_data)
 
1328
{
 
1329
  PpNewPrinterDialog        *dialog;
 
1330
  PpNewPrinterDialogPrivate *priv;
 
1331
  PpCupsDests               *dests;
 
1332
  PpCups                    *cups = (PpCups *) source_object;
 
1333
  GError                    *error = NULL;
 
1334
 
 
1335
  dests = pp_cups_get_dests_finish (cups, res, &error);
 
1336
  g_object_unref (source_object);
 
1337
 
 
1338
  if (dests)
 
1339
    {
 
1340
      dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
1341
      priv = dialog->priv;
 
1342
 
 
1343
      priv->dests = dests->dests;
 
1344
      priv->num_of_dests = dests->num_of_dests;
 
1345
 
 
1346
      get_cups_devices (dialog);
 
1347
    }
 
1348
  else
 
1349
    {
 
1350
      if (error->domain != G_IO_ERROR ||
 
1351
          error->code != G_IO_ERROR_CANCELLED)
 
1352
        {
 
1353
          dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
1354
 
 
1355
          g_warning ("%s", error->message);
 
1356
 
 
1357
          get_cups_devices (dialog);
 
1358
        }
 
1359
 
 
1360
      g_error_free (error);
 
1361
    }
 
1362
}
 
1363
 
 
1364
static void
 
1365
populate_devices_list (PpNewPrinterDialog *dialog)
 
1366
{
 
1367
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
1368
  GtkTreeViewColumn         *column;
 
1369
  GtkWidget                 *treeview;
 
1370
  PpCups                    *cups;
 
1371
 
 
1372
  treeview = (GtkWidget*)
 
1373
    gtk_builder_get_object (priv->builder, "devices-treeview");
 
1374
 
 
1375
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
 
1376
                    "changed", G_CALLBACK (device_selection_changed_cb), dialog);
 
1377
 
 
1378
  priv->icon_renderer = gtk_cell_renderer_pixbuf_new ();
 
1379
  g_object_set (priv->icon_renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL);
 
1380
  gtk_cell_renderer_set_alignment (priv->icon_renderer, 1.0, 0.5);
 
1381
  gtk_cell_renderer_set_padding (priv->icon_renderer, 4, 4);
 
1382
  column = gtk_tree_view_column_new_with_attributes ("Icon", priv->icon_renderer,
 
1383
                                                     "icon-name", DEVICE_ICON_COLUMN, NULL);
 
1384
  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
 
1385
 
 
1386
 
 
1387
  priv->text_renderer = gtk_cell_renderer_text_new ();
 
1388
  column = gtk_tree_view_column_new_with_attributes ("Devices", priv->text_renderer,
 
1389
                                                     "markup", DEVICE_DISPLAY_NAME_COLUMN, NULL);
 
1390
  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
 
1391
 
 
1392
  cups = pp_cups_new ();
 
1393
  pp_cups_get_dests_async (cups, priv->cancellable, cups_get_dests_cb, dialog);
 
1394
}
 
1395
 
 
1396
static void
 
1397
printer_add_async_cb (GObject      *source_object,
 
1398
                      GAsyncResult *res,
 
1399
                      gpointer      user_data)
 
1400
{
 
1401
  PpNewPrinterDialog        *dialog;
 
1402
  GtkResponseType            response_id = GTK_RESPONSE_OK;
 
1403
  PpNewPrinter              *new_printer = (PpNewPrinter *) source_object;
 
1404
  gboolean                   success;
 
1405
  GError                    *error = NULL;
 
1406
 
 
1407
  success = pp_new_printer_add_finish (new_printer, res, &error);
 
1408
  g_object_unref (source_object);
 
1409
 
 
1410
  if (success)
 
1411
    {
 
1412
      dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
1413
 
 
1414
      emit_response (dialog, response_id);
 
1415
    }
 
1416
  else
 
1417
    {
 
1418
      if (error->domain != G_IO_ERROR ||
 
1419
          error->code != G_IO_ERROR_CANCELLED)
 
1420
        {
 
1421
          dialog = PP_NEW_PRINTER_DIALOG (user_data);
 
1422
 
 
1423
          g_warning ("%s", error->message);
 
1424
 
 
1425
          response_id = GTK_RESPONSE_REJECT;
 
1426
 
 
1427
          emit_response (dialog, response_id);
 
1428
        }
 
1429
 
 
1430
      g_error_free (error);
 
1431
    }
 
1432
}
 
1433
 
 
1434
static void
 
1435
new_printer_dialog_response_cb (GtkDialog *_dialog,
 
1436
                                gint       response_id,
 
1437
                                gpointer   user_data)
 
1438
{
 
1439
  PpNewPrinterDialog        *dialog = (PpNewPrinterDialog*) user_data;
 
1440
  PpNewPrinterDialogPrivate *priv = dialog->priv;
 
1441
  GtkTreeModel              *model;
 
1442
  GtkTreeIter                iter;
 
1443
  GtkWidget                 *treeview;
 
1444
  TDevice                   *device = NULL;
 
1445
  TDevice                   *tmp;
 
1446
  GList                     *list_iter;
 
1447
  gchar                     *device_name = NULL;
 
1448
 
 
1449
  gtk_widget_hide (GTK_WIDGET (_dialog));
 
1450
 
 
1451
  if (response_id == GTK_RESPONSE_OK)
 
1452
    {
 
1453
      g_cancellable_cancel (priv->cancellable);
 
1454
      g_clear_object (&priv->cancellable);
 
1455
 
 
1456
      treeview = (GtkWidget*)
 
1457
        gtk_builder_get_object (priv->builder, "devices-treeview");
 
1458
 
 
1459
      if (treeview &&
 
1460
          gtk_tree_selection_get_selected (
 
1461
            gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), &model, &iter))
 
1462
        {
 
1463
          gtk_tree_model_get (model, &iter,
 
1464
                              DEVICE_NAME_COLUMN, &device_name,
 
1465
                              -1);
 
1466
        }
 
1467
 
 
1468
      for (list_iter = priv->devices; list_iter; list_iter = list_iter->next)
 
1469
        {
 
1470
          tmp = (TDevice *) list_iter->data;
 
1471
          if (tmp && g_strcmp0 (tmp->device_name, device_name) == 0)
 
1472
            {
 
1473
              device = tmp;
 
1474
              break;
 
1475
            }
 
1476
        }
 
1477
 
 
1478
      if (device)
 
1479
        {
 
1480
          PpNewPrinter *new_printer;
 
1481
          guint         window_id = 0;
 
1482
 
 
1483
          emit_pre_response (dialog,
 
1484
                             device->device_name,
 
1485
                             device->device_location,
 
1486
                             device->device_make_and_model,
 
1487
                             device->network_device);
 
1488
 
 
1489
#ifdef GDK_WINDOWING_X11
 
1490
          window_id = GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (_dialog)));
 
1491
#endif
 
1492
 
 
1493
          new_printer = pp_new_printer_new ();
 
1494
          g_object_set (new_printer,
 
1495
                        "name", device->device_name,
 
1496
                        "original-name""", device->device_original_name,
 
1497
                        "device-uri", device->device_uri,
 
1498
                        "device-id", device->device_id,
 
1499
                        "ppd-name", device->device_ppd,
 
1500
                        "ppd-file-name", device->device_ppd,
 
1501
                        "info", device->device_info,
 
1502
                        "location", device->device_location,
 
1503
                        "make-and-model", device->device_make_and_model,
 
1504
                        "host-name", device->host_name,
 
1505
                        "host-port", device->host_port,
 
1506
                        "is-network-device", device->network_device,
 
1507
                        "window-id", window_id,
 
1508
                        NULL);
 
1509
 
 
1510
          priv->cancellable = g_cancellable_new ();
 
1511
 
 
1512
          pp_new_printer_add_async (new_printer,
 
1513
                                    priv->cancellable,
 
1514
                                    printer_add_async_cb,
 
1515
                                    dialog);
 
1516
        }
 
1517
    }
 
1518
  else
 
1519
    {
 
1520
      emit_response (dialog, GTK_RESPONSE_CANCEL);
 
1521
    }
 
1522
}