]> www.fi.muni.cz Git - evince.git/blob - libview/ev-annotation-window.c
6199660cc4416f6fb7aef03ad311d0aa25136ea3
[evince.git] / libview / ev-annotation-window.c
1 /* ev-annotation-window.c
2  *  this file is part of evince, a gnome document viewer
3  *
4  * Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
5  * Copyright (C) 2007 IƱigo Martinez <inigomartinez@gmail.com>
6  *
7  * Evince is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * Evince is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21
22 #include "config.h"
23
24 #include <string.h>
25
26 #include "ev-annotation-window.h"
27 #include "ev-stock-icons.h"
28 #include "ev-view-marshal.h"
29 #include "ev-document-misc.h"
30
31 enum {
32         PROP_0,
33         PROP_ANNOTATION,
34         PROP_PARENT
35 };
36
37 enum {
38         CLOSED,
39         MOVED,
40         N_SIGNALS
41 };
42
43 struct _EvAnnotationWindow {
44         GtkWindow     base_instance;
45
46         EvAnnotation *annotation;
47         GtkWindow    *parent;
48
49         GtkWidget    *title;
50         GtkWidget    *close_button;
51         GtkWidget    *text_view;
52         GtkWidget    *resize_se;
53         GtkWidget    *resize_sw;
54
55         gboolean      is_open;
56         EvRectangle   rect;
57
58         gboolean      in_move;
59         gint          x;
60         gint          y;
61         gint          orig_x;
62         gint          orig_y;
63 };
64
65 struct _EvAnnotationWindowClass {
66         GtkWindowClass base_class;
67
68         void (* closed) (EvAnnotationWindow *window);
69         void (* moved)  (EvAnnotationWindow *window,
70                          gint                x,
71                          gint                y);
72 };
73
74 static guint signals[N_SIGNALS];
75
76 G_DEFINE_TYPE (EvAnnotationWindow, ev_annotation_window, GTK_TYPE_WINDOW)
77
78 #define EV_ICON_SIZE_ANNOT_WINDOW (ev_annotation_window_get_icon_size())
79
80 /* Cut and paste from gtkwindow.c */
81 static void
82 send_focus_change (GtkWidget *widget,
83                    gboolean   in)
84 {
85         GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
86
87         fevent->focus_change.type = GDK_FOCUS_CHANGE;
88         fevent->focus_change.window = gtk_widget_get_window (widget);
89         fevent->focus_change.in = in;
90         if (fevent->focus_change.window)
91                 g_object_ref (fevent->focus_change.window);
92
93         gtk_widget_send_focus_change (widget, fevent);
94
95         gdk_event_free (fevent);
96 }
97
98 static gdouble
99 get_screen_dpi (EvAnnotationWindow *window)
100 {
101         GdkScreen *screen;
102
103         screen = gtk_window_get_screen (GTK_WINDOW (window));
104         return ev_document_misc_get_screen_dpi (screen);
105 }
106
107 static GtkIconSize
108 ev_annotation_window_get_icon_size (void)
109 {
110         static GtkIconSize icon_size = 0;
111
112         if (G_UNLIKELY (icon_size == 0))
113                 icon_size = gtk_icon_size_register ("ev-icon-size-annot-window", 8, 8);
114
115         return icon_size;
116 }
117
118 static void
119 ev_annotation_window_sync_contents (EvAnnotationWindow *window)
120 {
121         gchar         *contents;
122         GtkTextIter    start, end;
123         GtkTextBuffer *buffer;
124         EvAnnotation  *annot = window->annotation;
125
126         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (window->text_view));
127         gtk_text_buffer_get_bounds (buffer, &start, &end);
128         contents = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
129         ev_annotation_set_contents (annot, contents);
130         g_free (contents);
131 }
132
133 static void
134 ev_annotation_window_set_color (EvAnnotationWindow *window,
135                                 GdkColor           *color)
136 {
137         GtkRcStyle *rc_style;
138         GdkColor    gcolor;
139
140         gcolor = *color;
141
142 #if !GTK_CHECK_VERSION (2, 90, 8)
143         /* Allocate these colors */
144         gdk_colormap_alloc_color (gtk_widget_get_colormap (GTK_WIDGET (window)),
145                                   &gcolor, FALSE, TRUE);
146 #endif
147
148         /* Apply colors to style */
149         rc_style = gtk_widget_get_modifier_style (GTK_WIDGET (window));
150         rc_style->base[GTK_STATE_NORMAL] = gcolor;
151         rc_style->bg[GTK_STATE_PRELIGHT] = gcolor;
152         rc_style->bg[GTK_STATE_NORMAL] = gcolor;
153         rc_style->bg[GTK_STATE_ACTIVE] = gcolor;
154         rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_BG;
155         rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG | GTK_RC_BASE;
156         rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_BG;
157
158         /* Apply the style to the widgets */
159         g_object_ref (rc_style);
160         gtk_widget_modify_style (GTK_WIDGET (window), rc_style);
161         gtk_widget_modify_style (window->close_button, rc_style);
162         gtk_widget_modify_style (window->resize_se, rc_style);
163         gtk_widget_modify_style (window->resize_sw, rc_style);
164         g_object_unref (rc_style);
165 }
166
167 static void
168 ev_annotation_window_label_changed (EvAnnotationMarkup *annot,
169                                     GParamSpec         *pspec,
170                                     EvAnnotationWindow *window)
171 {
172         const gchar *label = ev_annotation_markup_get_label (annot);
173
174         gtk_window_set_title (GTK_WINDOW (window), label);
175         gtk_label_set_text (GTK_LABEL (window->title), label);
176 }
177
178 static void
179 ev_annotation_window_color_changed (EvAnnotation       *annot,
180                                     GParamSpec         *pspec,
181                                     EvAnnotationWindow *window)
182 {
183         GdkColor color;
184
185         ev_annotation_get_color (annot, &color);
186         ev_annotation_window_set_color (window, &color);
187 }
188
189 static void
190 ev_annotation_window_dispose (GObject *object)
191 {
192         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (object);
193
194         if (window->annotation) {
195                 ev_annotation_window_sync_contents (window);
196                 g_object_unref (window->annotation);
197                 window->annotation = NULL;
198         }
199
200         (* G_OBJECT_CLASS (ev_annotation_window_parent_class)->dispose) (object);
201 }
202
203 static void
204 ev_annotation_window_set_property (GObject      *object,
205                                    guint         prop_id,
206                                    const GValue *value,
207                                    GParamSpec   *pspec)
208 {
209         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (object);
210
211         switch (prop_id) {
212         case PROP_ANNOTATION:
213                 window->annotation = g_value_dup_object (value);
214                 break;
215         case PROP_PARENT:
216                 window->parent = g_value_get_object (value);
217                 break;
218         default:
219                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
220         }
221 }
222
223 static gboolean
224 ev_annotation_window_resize (EvAnnotationWindow *window,
225                              GdkEventButton     *event,
226                              GtkWidget          *ebox)
227 {
228         if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
229                 gtk_window_begin_resize_drag (GTK_WINDOW (window),
230                                               window->resize_sw == ebox ?
231                                               GDK_WINDOW_EDGE_SOUTH_WEST :
232                                               GDK_WINDOW_EDGE_SOUTH_EAST,
233                                               event->button, event->x_root,
234                                               event->y_root, event->time);
235                 return TRUE;
236         }
237
238         return FALSE;
239 }
240
241 static void
242 ev_annotation_window_set_resize_cursor (GtkWidget          *widget,
243                                         EvAnnotationWindow *window)
244 {
245         GdkWindow *gdk_window = gtk_widget_get_window (widget);
246
247         if (!gdk_window)
248                 return;
249
250         if (gtk_widget_is_sensitive (widget)) {
251                 GdkDisplay *display = gtk_widget_get_display (widget);
252                 GdkCursor  *cursor;
253
254                 cursor = gdk_cursor_new_for_display (display,
255                                                      widget == window->resize_sw ?
256                                                      GDK_BOTTOM_LEFT_CORNER :
257                                                      GDK_BOTTOM_RIGHT_CORNER);
258                 gdk_window_set_cursor (gdk_window, cursor);
259                 gdk_cursor_unref (cursor);
260         } else {
261                 gdk_window_set_cursor (gdk_window, NULL);
262         }
263 }
264
265 static gboolean
266 text_view_button_press (GtkWidget          *widget,
267                         GdkEventButton     *event,
268                         EvAnnotationWindow *window)
269 {
270         ev_annotation_window_grab_focus (window);
271
272         return FALSE;
273 }
274
275 static void
276 ev_annotation_window_close (EvAnnotationWindow *window)
277 {
278         gtk_widget_hide (GTK_WIDGET (window));
279         g_signal_emit (window, signals[CLOSED], 0);
280 }
281
282 static void
283 ev_annotation_window_init (EvAnnotationWindow *window)
284 {
285         GtkWidget *vbox, *hbox;
286         GtkWidget *icon;
287         GtkWidget *swindow;
288
289         gtk_widget_set_can_focus (GTK_WIDGET (window), TRUE);
290
291         vbox = gtk_vbox_new (FALSE, 0);
292
293         /* Title bar */
294         hbox = gtk_hbox_new (FALSE, 0);
295
296         icon = gtk_image_new (); /* FIXME: use the annot icon */
297         gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
298         gtk_widget_show (icon);
299
300         window->title = gtk_label_new (NULL);
301         gtk_box_pack_start (GTK_BOX (hbox), window->title, TRUE, TRUE, 0);
302         gtk_widget_show (window->title);
303
304         window->close_button = gtk_button_new ();
305         gtk_button_set_relief (GTK_BUTTON (window->close_button), GTK_RELIEF_NONE);
306         gtk_container_set_border_width (GTK_CONTAINER (window->close_button), 0);
307         g_signal_connect_swapped (window->close_button, "clicked",
308                                   G_CALLBACK (ev_annotation_window_close),
309                                   window);
310         icon = gtk_image_new_from_stock (EV_STOCK_CLOSE, EV_ICON_SIZE_ANNOT_WINDOW);
311         gtk_container_add (GTK_CONTAINER (window->close_button), icon);
312         gtk_widget_show (icon);
313
314         gtk_box_pack_start (GTK_BOX (hbox), window->close_button, FALSE, FALSE, 0);
315         gtk_widget_show (window->close_button);
316
317         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
318         gtk_widget_show (hbox);
319
320         /* Contents */
321         swindow = gtk_scrolled_window_new (NULL, NULL);
322         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
323                                         GTK_POLICY_AUTOMATIC,
324                                         GTK_POLICY_AUTOMATIC);
325         window->text_view = gtk_text_view_new ();
326         gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (window->text_view), GTK_WRAP_WORD);
327         g_signal_connect (window->text_view, "button_press_event",
328                           G_CALLBACK (text_view_button_press),
329                           window);
330         gtk_container_add (GTK_CONTAINER (swindow), window->text_view);
331         gtk_widget_show (window->text_view);
332
333         gtk_box_pack_start (GTK_BOX (vbox), swindow, TRUE, TRUE, 0);
334         gtk_widget_show (swindow);
335
336         /* Resize bar */
337         hbox = gtk_hbox_new (FALSE, 0);
338
339         window->resize_sw = gtk_event_box_new ();
340         gtk_widget_add_events (window->resize_sw, GDK_BUTTON_PRESS_MASK);
341         g_signal_connect_swapped (window->resize_sw, "button-press-event",
342                                   G_CALLBACK (ev_annotation_window_resize),
343                                   window);
344         g_signal_connect (window->resize_sw, "realize",
345                           G_CALLBACK (ev_annotation_window_set_resize_cursor),
346                           window);
347
348         icon = gtk_image_new_from_stock (EV_STOCK_RESIZE_SW, EV_ICON_SIZE_ANNOT_WINDOW);
349         gtk_container_add (GTK_CONTAINER (window->resize_sw), icon);
350         gtk_widget_show (icon);
351         gtk_box_pack_start (GTK_BOX (hbox), window->resize_sw, FALSE, FALSE, 0);
352         gtk_widget_show (window->resize_sw);
353
354         window->resize_se = gtk_event_box_new ();
355         gtk_widget_add_events (window->resize_se, GDK_BUTTON_PRESS_MASK);
356         g_signal_connect_swapped (window->resize_se, "button-press-event",
357                                   G_CALLBACK (ev_annotation_window_resize),
358                                   window);
359         g_signal_connect (window->resize_se, "realize",
360                           G_CALLBACK (ev_annotation_window_set_resize_cursor),
361                           window);
362
363         icon = gtk_image_new_from_stock (EV_STOCK_RESIZE_SE, EV_ICON_SIZE_ANNOT_WINDOW);
364         gtk_container_add (GTK_CONTAINER (window->resize_se), icon);
365         gtk_widget_show (icon);
366         gtk_box_pack_end (GTK_BOX (hbox), window->resize_se, FALSE, FALSE, 0);
367         gtk_widget_show (window->resize_se);
368
369         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
370         gtk_widget_show (hbox);
371
372         gtk_container_add (GTK_CONTAINER (window), vbox);
373         gtk_container_set_border_width (GTK_CONTAINER (window), 0);
374         gtk_widget_show (vbox);
375
376         gtk_widget_add_events (GTK_WIDGET (window),
377                                GDK_BUTTON_PRESS_MASK |
378                                GDK_KEY_PRESS_MASK);
379         gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
380
381         gtk_container_set_border_width (GTK_CONTAINER (window), 2);
382
383         gtk_window_set_accept_focus (GTK_WINDOW (window), TRUE);
384         gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
385         gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
386         gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
387         gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
388 }
389
390 static GObject *
391 ev_annotation_window_constructor (GType                  type,
392                                   guint                  n_construct_properties,
393                                   GObjectConstructParam *construct_params)
394 {
395         GObject            *object;
396         EvAnnotationWindow *window;
397         EvAnnotation       *annot;
398         EvAnnotationMarkup *markup;
399         const gchar        *contents;
400         const gchar        *label;
401         GdkColor            color;
402         EvRectangle        *rect;
403         gdouble             scale;
404
405         object = G_OBJECT_CLASS (ev_annotation_window_parent_class)->constructor (type,
406                                                                                   n_construct_properties,
407                                                                                   construct_params);
408         window = EV_ANNOTATION_WINDOW (object);
409         annot = window->annotation;
410         markup = EV_ANNOTATION_MARKUP (annot);
411
412         gtk_window_set_transient_for (GTK_WINDOW (window), window->parent);
413         gtk_window_set_destroy_with_parent (GTK_WINDOW (window), FALSE);
414
415         label = ev_annotation_markup_get_label (markup);
416         window->is_open = ev_annotation_markup_get_popup_is_open (markup);
417         ev_annotation_markup_get_rectangle (markup, &window->rect);
418
419         rect = &window->rect;
420
421         /* Rectangle is at doc resolution (72.0) */
422         scale = get_screen_dpi (window) / 72.0;
423         gtk_window_resize (GTK_WINDOW (window),
424                            (gint)((rect->x2 - rect->x1) * scale),
425                            (gint)((rect->y2 - rect->y1) * scale));
426
427         ev_annotation_get_color (annot, &color);
428         ev_annotation_window_set_color (window, &color);
429         gtk_widget_set_name (GTK_WIDGET (window), ev_annotation_get_name (annot));
430         gtk_window_set_title (GTK_WINDOW (window), label);
431         gtk_label_set_text (GTK_LABEL (window->title), label);
432
433         contents = ev_annotation_get_contents (annot);
434         if (contents) {
435                 GtkTextBuffer *buffer;
436
437                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (window->text_view));
438                 gtk_text_buffer_set_text (buffer, contents, -1);
439         }
440
441         g_signal_connect (annot, "notify::label",
442                           G_CALLBACK (ev_annotation_window_label_changed),
443                           window);
444         g_signal_connect (annot, "notify::color",
445                           G_CALLBACK (ev_annotation_window_color_changed),
446                           window);
447
448         return object;
449 }
450
451 static gboolean
452 ev_annotation_window_button_press_event (GtkWidget      *widget,
453                                          GdkEventButton *event)
454 {
455         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (widget);
456
457         if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
458                 window->in_move = TRUE;
459                 window->x = event->x_root - event->x;
460                 window->y = event->y_root - event->y;
461                 gtk_window_begin_move_drag (GTK_WINDOW (widget),
462                                             event->button,
463                                             event->x_root,
464                                             event->y_root,
465                                             event->time);
466                 return TRUE;
467         }
468
469         return FALSE;
470 }
471
472 static gboolean
473 ev_annotation_window_configure_event (GtkWidget         *widget,
474                                       GdkEventConfigure *event)
475 {
476         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (widget);
477
478         if (window->in_move &&
479             (window->x != event->x || window->y != event->y)) {
480                 window->x = event->x;
481                 window->y = event->y;
482         }
483
484         return GTK_WIDGET_CLASS (ev_annotation_window_parent_class)->configure_event (widget, event);
485 }
486
487 static gboolean
488 ev_annotation_window_focus_in_event (GtkWidget     *widget,
489                                      GdkEventFocus *event)
490 {
491         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (widget);
492
493         if (window->in_move) {
494                 if (window->orig_x != window->x || window->orig_y != window->y) {
495                         window->orig_x = window->x;
496                         window->orig_y = window->y;
497                         g_signal_emit (window, signals[MOVED], 0, window->x, window->y);
498                 }
499                 window->in_move = FALSE;
500         }
501
502         return FALSE;
503 }
504
505 static gboolean
506 ev_annotation_window_focus_out_event (GtkWidget     *widget,
507                                       GdkEventFocus *event)
508 {
509         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (widget);
510
511         ev_annotation_window_sync_contents (window);
512
513         return FALSE;
514 }
515
516 static void
517 ev_annotation_window_class_init (EvAnnotationWindowClass *klass)
518 {
519         GObjectClass   *g_object_class = G_OBJECT_CLASS (klass);
520         GtkWidgetClass *gtk_widget_class = GTK_WIDGET_CLASS (klass);
521
522         g_object_class->constructor = ev_annotation_window_constructor;
523         g_object_class->set_property = ev_annotation_window_set_property;
524         g_object_class->dispose = ev_annotation_window_dispose;
525
526         gtk_widget_class->button_press_event = ev_annotation_window_button_press_event;
527         gtk_widget_class->configure_event = ev_annotation_window_configure_event;
528         gtk_widget_class->focus_in_event = ev_annotation_window_focus_in_event;
529         gtk_widget_class->focus_out_event = ev_annotation_window_focus_out_event;
530
531         g_object_class_install_property (g_object_class,
532                                          PROP_ANNOTATION,
533                                          g_param_spec_object ("annotation",
534                                                               "Annotation",
535                                                               "The annotation associated to the window",
536                                                               EV_TYPE_ANNOTATION_MARKUP,
537                                                               G_PARAM_WRITABLE |
538                                                               G_PARAM_CONSTRUCT_ONLY));
539         g_object_class_install_property (g_object_class,
540                                          PROP_PARENT,
541                                          g_param_spec_object ("parent",
542                                                               "Parent",
543                                                               "The parent window",
544                                                               GTK_TYPE_WINDOW,
545                                                               G_PARAM_WRITABLE |
546                                                               G_PARAM_CONSTRUCT_ONLY));
547         signals[CLOSED] =
548                 g_signal_new ("closed",
549                               G_TYPE_FROM_CLASS (g_object_class),
550                               G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
551                               G_STRUCT_OFFSET (EvAnnotationWindowClass, closed),
552                               NULL, NULL,
553                               g_cclosure_marshal_VOID__VOID,
554                               G_TYPE_NONE, 0, G_TYPE_NONE);
555         signals[MOVED] =
556                 g_signal_new ("moved",
557                               G_TYPE_FROM_CLASS (g_object_class),
558                               G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
559                               G_STRUCT_OFFSET (EvAnnotationWindowClass, moved),
560                               NULL, NULL,
561                               ev_view_marshal_VOID__INT_INT,
562                               G_TYPE_NONE, 2,
563                               G_TYPE_INT, G_TYPE_INT);
564 }
565
566 /* Public methods */
567 GtkWidget *
568 ev_annotation_window_new (EvAnnotation *annot,
569                           GtkWindow    *parent)
570 {
571         GtkWidget *window;
572
573         g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (annot), NULL);
574         g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
575
576         window = g_object_new (EV_TYPE_ANNOTATION_WINDOW,
577                                "annotation", annot,
578                                "parent", parent,
579                                NULL);
580         return window;
581 }
582
583 EvAnnotation *
584 ev_annotation_window_get_annotation (EvAnnotationWindow *window)
585 {
586         g_return_val_if_fail (EV_IS_ANNOTATION_WINDOW (window), NULL);
587
588         return window->annotation;
589 }
590
591 void
592 ev_annotation_window_set_annotation (EvAnnotationWindow *window,
593                                      EvAnnotation       *annot)
594 {
595         g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
596         g_return_if_fail (EV_IS_ANNOTATION (annot));
597
598         if (annot == window->annotation)
599                 return;
600
601         g_object_unref (window->annotation);
602         window->annotation = g_object_ref (annot);
603         ev_annotation_window_sync_contents (window);
604         g_object_notify (G_OBJECT (window), "annotation");
605 }
606
607 gboolean
608 ev_annotation_window_is_open (EvAnnotationWindow *window)
609 {
610         g_return_val_if_fail (EV_IS_ANNOTATION_WINDOW (window), FALSE);
611
612         return window->is_open;
613 }
614
615 void
616 ev_annotation_window_get_rectangle (EvAnnotationWindow *window,
617                                     EvRectangle        *rect)
618 {
619         g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
620         g_return_if_fail (rect != NULL);
621
622         *rect = window->rect;
623 }
624
625 void
626 ev_annotation_window_set_rectangle (EvAnnotationWindow *window,
627                                     const EvRectangle  *rect)
628 {
629         g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
630         g_return_if_fail (rect != NULL);
631
632         window->rect = *rect;
633 }
634
635 void
636 ev_annotation_window_grab_focus (EvAnnotationWindow *window)
637 {
638         g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
639
640         if (!gtk_widget_has_focus (window->text_view)) {
641                 gtk_widget_grab_focus (GTK_WIDGET (window));
642                 send_focus_change (window->text_view, TRUE);
643         }
644 }
645
646 void
647 ev_annotation_window_ungrab_focus (EvAnnotationWindow *window)
648 {
649         g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
650
651         if (gtk_widget_has_focus (window->text_view)) {
652                 send_focus_change (window->text_view, FALSE);
653         }
654
655         ev_annotation_window_sync_contents (window);
656 }