~ubuntu-branches/ubuntu/lucid/vino/lucid

« back to all changes in this revision

Viewing changes to capplet/vino-url.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2008-05-27 09:06:36 UTC
  • mfrom: (1.1.21 upstream) (2.1.31 hardy)
  • Revision ID: james.westby@ubuntu.com-20080527090636-lg1whxlkub1wtsw7
Tags: 2.22.2-1
New upstream bugfix release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 * Copyright (C) 2003 Sun Microsystems, Inc.
3
 
 *
4
 
 * This library is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU Library General Public
6
 
 * License as published by the Free Software Foundation; either
7
 
 * version 2 of the License, or (at your option) any later version.
8
 
 *
9
 
 * This library is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 * Library General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU Library General Public
15
 
 * License along with this library; if not, write to the
16
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 
 * Boston, MA 02111-1307, USA.
18
 
 *
19
 
 * Authors:
20
 
 *      Mark McLoughlin <mark@skynet.ie>
21
 
 */
22
 
 
23
 
#include <config.h>
24
 
 
25
 
#include "vino-url.h"
26
 
 
27
 
#include <libintl.h>
28
 
#include <gtk/gtktooltips.h>
29
 
#include <libgnomeui/gnome-url.h>
30
 
 
31
 
#define _(x) dgettext (GETTEXT_PACKAGE, x)
32
 
 
33
 
enum
34
 
{
35
 
  PROP_0,
36
 
  PROP_ADDRESS,
37
 
  PROP_TOOLTIP
38
 
};
39
 
 
40
 
struct _VinoURLPrivate
41
 
{
42
 
  char          *address;
43
 
  char          *tooltip;
44
 
 
45
 
  PangoAttrList *attributes;
46
 
  GtkTooltips   *tooltips;
47
 
  GdkWindow     *event_window;
48
 
 
49
 
  guint          button_down : 1;
50
 
  guint          foreground_modified : 1;
51
 
  guint          underline_modified : 1;
52
 
};
53
 
 
54
 
static void vino_url_class_init    (VinoURLClass *klass);
55
 
static void vino_url_instance_init (VinoURL      *url);
56
 
 
57
 
static void vino_url_finalize     (GObject      *object);
58
 
static void vino_url_set_property (GObject      *object,
59
 
                                   guint         prop_id,
60
 
                                   const GValue *value,
61
 
                                   GParamSpec   *pspec);
62
 
static void vino_url_get_property (GObject      *object,
63
 
                                   guint         prop_id,
64
 
                                   GValue       *value,
65
 
                                   GParamSpec   *pspec);
66
 
 
67
 
static void     vino_url_realize        (GtkWidget        *widget);
68
 
static void     vino_url_unrealize      (GtkWidget        *widget);
69
 
static void     vino_url_size_allocate  (GtkWidget        *widget,
70
 
                                         GtkAllocation    *allocation);
71
 
static void     vino_url_size_request   (GtkWidget        *widget,
72
 
                                         GtkRequisition   *requisition);
73
 
static void     vino_url_map            (GtkWidget        *widget);
74
 
static void     vino_url_unmap          (GtkWidget        *widget);
75
 
static gboolean vino_url_expose         (GtkWidget        *widget,
76
 
                                         GdkEventExpose   *event);
77
 
static gboolean vino_url_button_press   (GtkWidget        *widget,
78
 
                                         GdkEventButton   *event);
79
 
static gboolean vino_url_button_release (GtkWidget        *widget,
80
 
                                         GdkEventButton   *event);
81
 
static gboolean vino_url_focus          (GtkWidget        *widget,
82
 
                                         GtkDirectionType  direction);
83
 
static void     vino_url_state_changed  (GtkWidget        *widget,
84
 
                                         GtkStateType      previous_state);
85
 
 
86
 
static void vino_url_activate (VinoURL *url);
87
 
 
88
 
static void vino_url_change_attribute_internal (VinoURL        *url,
89
 
                                                PangoAttribute *attribute,
90
 
                                                gboolean        internal);
91
 
static void vino_url_set_use_underline         (VinoURL        *url,
92
 
                                                gboolean        use_underline);
93
 
static void vino_url_set_use_url_color         (VinoURL        *url,
94
 
                                                gboolean        use_underline);
95
 
 
96
 
static GtkLabelClass *parent_class = NULL;
97
 
 
98
 
GType
99
 
vino_url_get_type (void)
100
 
{
101
 
  static GType url_type = 0;
102
 
  
103
 
  if (!url_type)
104
 
    {
105
 
      static const GTypeInfo url_info =
106
 
      {
107
 
        sizeof (VinoURLClass),
108
 
        NULL,           /* base_init */
109
 
        NULL,           /* base_finalize */
110
 
        (GClassInitFunc) vino_url_class_init,
111
 
        NULL,           /* class_finalize */
112
 
        NULL,           /* class_data */
113
 
        sizeof (VinoURL),
114
 
        0,              /* n_preallocs */
115
 
        (GInstanceInitFunc) vino_url_instance_init,
116
 
      };
117
 
      
118
 
      url_type = g_type_register_static (GTK_TYPE_LABEL,
119
 
                                         "VinoURL",
120
 
                                         &url_info, 0);
121
 
    }
122
 
  
123
 
  return url_type;
124
 
}
125
 
 
126
 
static void
127
 
vino_url_class_init (VinoURLClass *klass)
128
 
{
129
 
  GObjectClass  *gobject_class;
130
 
  GtkWidgetClass *widget_class;
131
 
 
132
 
  parent_class = g_type_class_peek_parent (klass);
133
 
 
134
 
  gobject_class = (GObjectClass *)   klass;
135
 
  widget_class  = (GtkWidgetClass *) klass;
136
 
 
137
 
  gobject_class->finalize     = vino_url_finalize;
138
 
  gobject_class->set_property = vino_url_set_property;
139
 
  gobject_class->get_property = vino_url_get_property;
140
 
 
141
 
  widget_class->realize              = vino_url_realize;
142
 
  widget_class->unrealize            = vino_url_unrealize;
143
 
  widget_class->size_request         = vino_url_size_request;
144
 
  widget_class->size_allocate        = vino_url_size_allocate;
145
 
  widget_class->map                  = vino_url_map;
146
 
  widget_class->unmap                = vino_url_unmap;
147
 
  widget_class->expose_event         = vino_url_expose;
148
 
  widget_class->button_press_event   = vino_url_button_press;
149
 
  widget_class->button_release_event = vino_url_button_release;
150
 
  widget_class->focus                = vino_url_focus;
151
 
  widget_class->state_changed        = vino_url_state_changed;
152
 
 
153
 
  klass->activate = vino_url_activate;
154
 
 
155
 
  g_object_class_install_property (gobject_class,
156
 
                                   PROP_ADDRESS,
157
 
                                   g_param_spec_string ("address",
158
 
                                                        _("Address"),
159
 
                                                        _("The address pointed to by the widget"),
160
 
                                                        NULL,
161
 
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
162
 
 
163
 
  g_object_class_install_property (gobject_class,
164
 
                                   PROP_TOOLTIP,
165
 
                                   g_param_spec_string ("tooltip",
166
 
                                                        _("Tooltip"),
167
 
                                                        _("A tooltip for this URL"),
168
 
                                                        NULL,
169
 
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
170
 
 
171
 
  gtk_widget_class_install_style_property (widget_class,
172
 
                                           g_param_spec_boxed ("url-color",
173
 
                                                               _("URL color"),
174
 
                                                               _("The color of the URL's label"),
175
 
                                                               GDK_TYPE_COLOR,
176
 
                                                               G_PARAM_READWRITE));
177
 
 
178
 
  widget_class->activate_signal =
179
 
    g_signal_new ("activate",
180
 
                  G_TYPE_FROM_CLASS (gobject_class),
181
 
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
182
 
                  G_STRUCT_OFFSET (VinoURLClass, activate),
183
 
                  NULL, NULL,
184
 
                  g_cclosure_marshal_VOID__VOID,
185
 
                  G_TYPE_NONE, 0);
186
 
}
187
 
 
188
 
static void
189
 
vino_url_instance_init (VinoURL *url)
190
 
{
191
 
  url->priv = g_new0 (VinoURLPrivate, 1);
192
 
 
193
 
  vino_url_set_use_url_color (url, TRUE);
194
 
  vino_url_set_use_underline (url, TRUE);
195
 
 
196
 
  url->priv->tooltips = gtk_tooltips_new ();
197
 
  g_object_ref (url->priv->tooltips);
198
 
  gtk_object_sink (GTK_OBJECT (url->priv->tooltips));
199
 
 
200
 
  /* Chain up to the label's focus handling code
201
 
   * which is meant for selection, even though
202
 
   * we're not selectable.
203
 
   */
204
 
  GTK_WIDGET_SET_FLAGS (url, GTK_CAN_FOCUS);
205
 
}
206
 
 
207
 
static void
208
 
vino_url_finalize (GObject *object)
209
 
{
210
 
  VinoURL *url = VINO_URL (object);
211
 
 
212
 
  if (url->priv->address)
213
 
    g_free (url->priv->address);
214
 
  url->priv->address = NULL;
215
 
 
216
 
  if (url->priv->attributes)
217
 
    pango_attr_list_unref (url->priv->attributes);
218
 
  url->priv->attributes = NULL;
219
 
 
220
 
  if (url->priv->tooltips)
221
 
    g_object_unref (url->priv->tooltips);
222
 
  url->priv->tooltips = NULL;
223
 
 
224
 
  if (url->priv->tooltip)
225
 
    g_free (url->priv->tooltip);
226
 
  url->priv->tooltip = NULL;
227
 
 
228
 
  g_free (url->priv);
229
 
  url->priv = NULL;
230
 
 
231
 
  G_OBJECT_CLASS (parent_class)->finalize (object);
232
 
}
233
 
 
234
 
static void
235
 
vino_url_set_property (GObject      *object,
236
 
                       guint         prop_id,
237
 
                       const GValue *value,
238
 
                       GParamSpec   *pspec)
239
 
{
240
 
  VinoURL *url = VINO_URL (object);
241
 
                                                                                                             
242
 
  switch (prop_id)
243
 
    {
244
 
    case PROP_ADDRESS:
245
 
      vino_url_set_address (url, g_value_get_string (value));
246
 
      break;
247
 
    case PROP_TOOLTIP:
248
 
      vino_url_set_tooltip (url, g_value_get_string (value));
249
 
      break;
250
 
    default:
251
 
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
252
 
      break;
253
 
    }
254
 
}
255
 
 
256
 
static void
257
 
vino_url_get_property (GObject    *object,
258
 
                       guint       prop_id,
259
 
                       GValue     *value,
260
 
                       GParamSpec *pspec)
261
 
{
262
 
  VinoURL *url = VINO_URL (object);
263
 
 
264
 
  switch (prop_id)
265
 
    {
266
 
    case PROP_ADDRESS:
267
 
      g_value_set_string (value, vino_url_get_address (url));
268
 
      break;
269
 
    case PROP_TOOLTIP:
270
 
      g_value_set_string (value, vino_url_get_tooltip (url));
271
 
      break;
272
 
    default:
273
 
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
274
 
      break;
275
 
    }
276
 
}
277
 
 
278
 
static void
279
 
vino_url_realize (GtkWidget *widget)
280
 
{
281
 
  VinoURL       *url = VINO_URL (widget);
282
 
  GdkWindowAttr  attributes;
283
 
  GdkCursor     *cursor = NULL;
284
 
  gint           attributes_mask;
285
 
 
286
 
  GTK_WIDGET_CLASS (parent_class)->realize (widget);
287
 
 
288
 
  attributes.window_type = GDK_WINDOW_CHILD;
289
 
  attributes.x           = widget->allocation.x;
290
 
  attributes.y           = widget->allocation.y;
291
 
  attributes.width       = widget->allocation.width;
292
 
  attributes.height      = widget->allocation.height;
293
 
  attributes.wclass      = GDK_INPUT_ONLY;
294
 
  attributes.event_mask  = gtk_widget_get_events (widget) |
295
 
                                GDK_BUTTON_PRESS_MASK     |
296
 
                                GDK_BUTTON_RELEASE_MASK   |
297
 
                                GDK_ENTER_NOTIFY_MASK     |
298
 
                                GDK_LEAVE_NOTIFY_MASK;
299
 
 
300
 
  attributes_mask = GDK_WA_X | GDK_WA_Y;
301
 
 
302
 
  if (GTK_WIDGET_IS_SENSITIVE (widget))
303
 
    {
304
 
      attributes.cursor = cursor =
305
 
        gdk_cursor_new_for_display (gtk_widget_get_display (widget),
306
 
                                    GDK_HAND2);
307
 
      attributes_mask |= GDK_WA_CURSOR;
308
 
    }
309
 
 
310
 
  url->priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
311
 
                                            &attributes, attributes_mask);
312
 
  gdk_window_set_user_data (url->priv->event_window, widget);
313
 
 
314
 
  if (cursor)
315
 
    gdk_cursor_unref (cursor);
316
 
}
317
 
 
318
 
static void
319
 
vino_url_unrealize (GtkWidget *widget)
320
 
{
321
 
  VinoURL *url = VINO_URL (widget);
322
 
 
323
 
  if (url->priv->event_window)
324
 
    {
325
 
      gdk_window_set_user_data (url->priv->event_window, NULL);
326
 
      gdk_window_destroy (url->priv->event_window);
327
 
      url->priv->event_window = NULL;
328
 
    }
329
 
 
330
 
  GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
331
 
}
332
 
 
333
 
static void
334
 
vino_url_size_request (GtkWidget      *widget,
335
 
                       GtkRequisition *requisition)
336
 
{
337
 
  int focus_width;
338
 
  int focus_pad;
339
 
 
340
 
  gtk_widget_style_get (widget,
341
 
                        "focus-line-width", &focus_width,
342
 
                        "focus-padding", &focus_pad,
343
 
                        NULL);
344
 
 
345
 
  GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
346
 
 
347
 
  requisition->width  += 2 * (focus_width + focus_pad);
348
 
  requisition->height += 2 * (focus_width + focus_pad);
349
 
}
350
 
 
351
 
static void
352
 
vino_url_size_allocate (GtkWidget     *widget,
353
 
                        GtkAllocation *allocation)
354
 
{
355
 
  VinoURL *url = VINO_URL (widget);
356
 
  
357
 
  GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
358
 
 
359
 
  if (GTK_WIDGET_REALIZED (widget))
360
 
    {
361
 
      gdk_window_move_resize (url->priv->event_window,
362
 
                              allocation->x,
363
 
                              allocation->y,
364
 
                              allocation->width,
365
 
                              allocation->height);
366
 
    }
367
 
}
368
 
 
369
 
static void
370
 
vino_url_map (GtkWidget *widget)
371
 
{
372
 
  VinoURL *url = VINO_URL (widget);
373
 
 
374
 
  GTK_WIDGET_CLASS (parent_class)->map (widget);
375
 
 
376
 
  if (url->priv->event_window)
377
 
    gdk_window_show (url->priv->event_window);
378
 
}
379
 
 
380
 
static void
381
 
vino_url_unmap (GtkWidget *widget)
382
 
{
383
 
  VinoURL *url = VINO_URL (widget);
384
 
 
385
 
  if (url->priv->event_window)
386
 
    gdk_window_hide (url->priv->event_window);
387
 
 
388
 
  GTK_WIDGET_CLASS (parent_class)->unmap (widget);
389
 
}
390
 
 
391
 
static gboolean
392
 
vino_url_expose (GtkWidget      *widget,
393
 
                 GdkEventExpose *event)
394
 
{
395
 
  GtkAllocation  real_allocation;
396
 
  PangoLayout   *layout;
397
 
  int            width, height;
398
 
  int            focus_width;
399
 
  int            focus_pad;
400
 
 
401
 
  gtk_widget_style_get (widget,
402
 
                        "focus-line-width", &focus_width,
403
 
                        "focus-padding", &focus_pad,
404
 
                        NULL);
405
 
 
406
 
  /* We need to fool GtkLabel into drawing the label 
407
 
   * in the right place.
408
 
   */
409
 
  real_allocation = widget->allocation;
410
 
 
411
 
  widget->allocation.x      += focus_width + focus_pad;
412
 
  widget->allocation.y      += focus_width + focus_pad;
413
 
  widget->allocation.width  -= 2 * (focus_width + focus_pad);
414
 
  widget->allocation.height -= 2 * (focus_width + focus_pad);
415
 
 
416
 
  GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
417
 
 
418
 
  layout = gtk_label_get_layout (GTK_LABEL (widget));
419
 
 
420
 
  width = height = 0;
421
 
  pango_layout_get_pixel_size (layout, &width, &height);
422
 
 
423
 
  width  += 2 * (focus_pad + focus_width);
424
 
  height += 2 * (focus_pad + focus_width);
425
 
 
426
 
  widget->allocation = real_allocation;
427
 
 
428
 
  if (GTK_WIDGET_HAS_FOCUS (widget))
429
 
    gtk_paint_focus (widget->style,
430
 
                     widget->window,
431
 
                     GTK_WIDGET_STATE (widget),
432
 
                     &event->area,
433
 
                     widget,
434
 
                     "label",
435
 
                     widget->allocation.x,
436
 
                     widget->allocation.y,
437
 
                     width,
438
 
                     height);
439
 
 
440
 
  return FALSE;
441
 
}
442
 
 
443
 
static gboolean
444
 
vino_url_button_press (GtkWidget      *widget,
445
 
                       GdkEventButton *event)
446
 
{
447
 
  VinoURL *url = VINO_URL (widget);
448
 
 
449
 
  if (event->button == 1 && event->window == url->priv->event_window)
450
 
    {
451
 
      url->priv->button_down = TRUE;
452
 
      return TRUE;
453
 
    }
454
 
 
455
 
  return FALSE;
456
 
}
457
 
 
458
 
static gboolean
459
 
vino_url_button_release (GtkWidget      *widget,
460
 
                         GdkEventButton *event)
461
 
{
462
 
  VinoURL *url = VINO_URL (widget);
463
 
 
464
 
  if (event->button == 1 && url->priv->button_down)
465
 
    {
466
 
      gtk_widget_activate (widget);
467
 
      url->priv->button_down = FALSE;
468
 
      return TRUE;
469
 
    }
470
 
 
471
 
  return FALSE;
472
 
}
473
 
 
474
 
static gboolean
475
 
vino_url_focus (GtkWidget        *widget,
476
 
                GtkDirectionType  direction)
477
 
{
478
 
  if (!gtk_widget_is_focus (widget))
479
 
    {
480
 
      gtk_widget_grab_focus (widget);
481
 
      return TRUE;
482
 
    }
483
 
 
484
 
  return FALSE;
485
 
}
486
 
 
487
 
static void
488
 
vino_url_state_changed (GtkWidget    *widget,
489
 
                        GtkStateType  previous_state)
490
 
{
491
 
  if (GTK_WIDGET_REALIZED (widget))
492
 
    {
493
 
      if (GTK_WIDGET_IS_SENSITIVE (widget))
494
 
        {
495
 
          GdkCursor *cursor;
496
 
 
497
 
          cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
498
 
                                               GDK_HAND2);
499
 
          gdk_window_set_cursor (VINO_URL (widget)->priv->event_window, cursor);
500
 
          gdk_cursor_unref (cursor);
501
 
        }
502
 
      else
503
 
        {
504
 
          gdk_window_set_cursor (VINO_URL (widget)->priv->event_window, NULL);
505
 
        }
506
 
    }
507
 
 
508
 
  vino_url_set_use_url_color (VINO_URL (widget), GTK_WIDGET_IS_SENSITIVE (widget));
509
 
}
510
 
 
511
 
static void
512
 
vino_url_activate (VinoURL *url)
513
 
{
514
 
  GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (url));
515
 
  GError    *error = NULL;
516
 
 
517
 
  if (!url->priv->address)
518
 
    return;
519
 
 
520
 
  if (!gnome_url_show_on_screen (url->priv->address, screen, &error))
521
 
    {
522
 
      /* FIXME better error handling!
523
 
       *       What best to do? For the specific case
524
 
       *       in this preferences dialog we want to be
525
 
       *       able to pop up a dialog with the error
526
 
       *       but also the vino URL as a selectable
527
 
       *       label.
528
 
       *
529
 
       *       Maybe chain this up to the caller?
530
 
       */
531
 
 
532
 
      g_warning ("Failed to show URL '%s': %s\n",
533
 
                 url->priv->address, error->message);
534
 
      g_error_free (error);
535
 
    }
536
 
}
537
 
 
538
 
GtkWidget *
539
 
vino_url_new (const char *address,
540
 
              const char *label,
541
 
              const char *tooltip)
542
 
{
543
 
  g_return_val_if_fail (address != NULL, NULL);
544
 
 
545
 
  return g_object_new (VINO_TYPE_URL,
546
 
                       "address", address,
547
 
                       "label",   label,
548
 
                       "tooltip", tooltip,
549
 
                       NULL);
550
 
}
551
 
 
552
 
static void
553
 
vino_url_set_use_underline (VinoURL  *url,
554
 
                            gboolean  use_underline)
555
 
{
556
 
  if (!url->priv->underline_modified)
557
 
    {
558
 
      if (use_underline)
559
 
        {
560
 
          vino_url_change_attribute_internal (url,
561
 
                                              pango_attr_underline_new (PANGO_UNDERLINE_SINGLE),
562
 
                                              TRUE);
563
 
        }
564
 
      else
565
 
        {
566
 
          vino_url_unset_attribute_type (url, PANGO_ATTR_UNDERLINE);
567
 
        }
568
 
    }
569
 
}
570
 
 
571
 
static void
572
 
vino_url_set_use_url_color (VinoURL  *url,
573
 
                            gboolean  use_url_color)
574
 
{
575
 
  if (!url->priv->foreground_modified)
576
 
    {
577
 
      if (use_url_color)
578
 
        {
579
 
          GdkColor        blue = { 0, 0x0000, 0x0000, 0xffff };
580
 
          GdkColor       *url_color;
581
 
          PangoAttribute *foreground;
582
 
 
583
 
          gtk_widget_style_get (GTK_WIDGET (url),
584
 
                                "url-color", &url_color,
585
 
                                NULL);
586
 
          if (!url_color)
587
 
            url_color = &blue;
588
 
 
589
 
          foreground = pango_attr_foreground_new (url_color->red,
590
 
                                                  url_color->green,
591
 
                                                  url_color->blue);
592
 
 
593
 
          vino_url_change_attribute_internal (url, foreground, TRUE);
594
 
 
595
 
          if (url_color != &blue)
596
 
            gdk_color_free (url_color);
597
 
        }
598
 
      else
599
 
        {
600
 
          vino_url_unset_attribute_type (url, PANGO_ATTR_FOREGROUND);
601
 
        }
602
 
    }
603
 
}
604
 
 
605
 
void
606
 
vino_url_set_address (VinoURL    *url,
607
 
                      const char *address)
608
 
{
609
 
  g_return_if_fail (VINO_IS_URL (url));
610
 
 
611
 
  g_free (url->priv->address);
612
 
  url->priv->address = g_strdup (address);
613
 
 
614
 
  g_object_notify (G_OBJECT (url), "address");
615
 
}
616
 
 
617
 
G_CONST_RETURN char *
618
 
vino_url_get_address (VinoURL *url)
619
 
{
620
 
  g_return_val_if_fail (VINO_IS_URL (url), NULL);
621
 
 
622
 
  return url->priv->address;
623
 
}
624
 
 
625
 
void
626
 
vino_url_set_tooltip (VinoURL    *url,
627
 
                      const char *tooltip)
628
 
{
629
 
  g_return_if_fail (VINO_IS_URL (url));
630
 
 
631
 
  g_free (url->priv->tooltip);
632
 
  url->priv->tooltip = g_strdup (tooltip);
633
 
 
634
 
  gtk_tooltips_set_tip (url->priv->tooltips,
635
 
                        GTK_WIDGET (url),
636
 
                        url->priv->tooltip,
637
 
                        NULL);
638
 
 
639
 
  g_object_notify (G_OBJECT (url), "tooltip");
640
 
}
641
 
 
642
 
G_CONST_RETURN char *
643
 
vino_url_get_tooltip (VinoURL *url)
644
 
{
645
 
  g_return_val_if_fail (VINO_IS_URL (url), NULL);
646
 
 
647
 
  return url->priv->tooltip;
648
 
}
649
 
 
650
 
/* Debugging; There should probably be a nicer API
651
 
 * for fiddling with the attributes on a label;
652
 
 * Either that or I'm being dumb again;
653
 
 */
654
 
#define SANITY_CHECK_ATTRIBUTES
655
 
 
656
 
static void
657
 
sanity_check_attributes_notify (VinoURL *url)
658
 
{
659
 
  PangoAttrList *attrs;
660
 
 
661
 
  attrs = gtk_label_get_attributes (GTK_LABEL (url));
662
 
  if (attrs != url->priv->attributes)
663
 
    {
664
 
      g_warning ("Label attributes changed, resetting");
665
 
      gtk_label_set_attributes (GTK_LABEL (url),
666
 
                                url->priv->attributes);
667
 
    }
668
 
}
669
 
 
670
 
static void
671
 
sanity_check_attributes (VinoURL *url)
672
 
{
673
 
#ifdef SANITY_CHECK_ATTRIBUTES
674
 
  g_signal_connect (url, "notify::attributes",
675
 
                    G_CALLBACK (sanity_check_attributes_notify), NULL);
676
 
#endif /* SANITY_CHECK_ATTRIBUTES */
677
 
}
678
 
 
679
 
static void
680
 
vino_url_change_attribute_internal (VinoURL        *url,
681
 
                                    PangoAttribute *attribute,
682
 
                                    gboolean        internal)
683
 
{
684
 
  if (!url->priv->attributes)
685
 
    {
686
 
      url->priv->attributes = pango_attr_list_new ();
687
 
      gtk_label_set_attributes (GTK_LABEL (url), url->priv->attributes);
688
 
      sanity_check_attributes (url);
689
 
    }
690
 
 
691
 
  attribute->start_index = 0;
692
 
  attribute->end_index = G_MAXINT;
693
 
 
694
 
  if (!internal)
695
 
    {
696
 
      if (attribute->klass->type == PANGO_ATTR_FOREGROUND)
697
 
        url->priv->foreground_modified = TRUE;
698
 
 
699
 
      if (attribute->klass->type == PANGO_ATTR_UNDERLINE)
700
 
        url->priv->underline_modified = TRUE;
701
 
    }
702
 
 
703
 
  pango_attr_list_change (url->priv->attributes, attribute);
704
 
}
705
 
 
706
 
void
707
 
vino_url_change_attribute (VinoURL        *url,
708
 
                           PangoAttribute *attribute)
709
 
{
710
 
  g_return_if_fail (VINO_IS_URL (url));
711
 
 
712
 
  vino_url_change_attribute_internal (url, attribute, FALSE);
713
 
}
714
 
 
715
 
static gboolean
716
 
filter_out_attr_type (PangoAttribute *attribute,
717
 
                      gpointer        data)
718
 
{
719
 
  PangoAttrType attr_type = GPOINTER_TO_INT (data);
720
 
 
721
 
  return attribute->klass->type == attr_type;
722
 
}
723
 
 
724
 
void
725
 
vino_url_unset_attribute_type (VinoURL       *url,
726
 
                               PangoAttrType  attr_type)
727
 
{
728
 
  g_return_if_fail (VINO_IS_URL (url));
729
 
 
730
 
  if (url->priv->attributes)
731
 
    {
732
 
      PangoAttrList *filtered;
733
 
 
734
 
      filtered =
735
 
        pango_attr_list_filter (url->priv->attributes,
736
 
                                (PangoAttrFilterFunc) filter_out_attr_type,
737
 
                                GINT_TO_POINTER (attr_type));
738
 
      if (filtered)
739
 
        pango_attr_list_unref (filtered);
740
 
    }
741
 
}