]> www.fi.muni.cz Git - evince.git/blob - libview/ev-annotation-window.c
[libview] Set word wrapping mode for text in popup annotations
[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_check_contents_modified (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
130         if (contents && annot->contents) {
131                 if (strcasecmp (contents, annot->contents) != 0) {
132                         g_free (annot->contents);
133                         annot->contents = contents;
134                         annot->changed = TRUE;
135                 } else {
136                         g_free (contents);
137                 }
138         } else if (annot->contents) {
139                 g_free (annot->contents);
140                 annot->contents = NULL;
141                 annot->changed = TRUE;
142         } else if (contents) {
143                 annot->contents = contents;
144                 annot->changed = TRUE;
145         }
146 }
147
148 static void
149 ev_annotation_window_set_color (EvAnnotationWindow *window,
150                                 GdkColor           *color)
151 {
152         GtkRcStyle *rc_style;
153         GdkColor    gcolor;
154
155         gcolor = *color;
156
157         /* Allocate these colors */
158         gdk_colormap_alloc_color (gtk_widget_get_colormap (GTK_WIDGET (window)),
159                                   &gcolor, FALSE, TRUE);
160
161         /* Apply colors to style */
162         rc_style = gtk_widget_get_modifier_style (GTK_WIDGET (window));
163         rc_style->base[GTK_STATE_NORMAL] = gcolor;
164         rc_style->bg[GTK_STATE_PRELIGHT] = gcolor;
165         rc_style->bg[GTK_STATE_NORMAL] = gcolor;
166         rc_style->bg[GTK_STATE_ACTIVE] = gcolor;
167         rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_BG;
168         rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG | GTK_RC_BASE;
169         rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_BG;
170
171         /* Apply the style to the widgets */
172         g_object_ref (rc_style);
173         gtk_widget_modify_style (GTK_WIDGET (window), rc_style);
174         gtk_widget_modify_style (window->close_button, rc_style);
175         gtk_widget_modify_style (window->resize_se, rc_style);
176         gtk_widget_modify_style (window->resize_sw, rc_style);
177         g_object_unref (rc_style);
178 }
179
180 static void
181 ev_annotation_window_dispose (GObject *object)
182 {
183         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (object);
184
185         if (window->annotation) {
186                 ev_annotation_window_check_contents_modified (window);
187                 g_object_unref (window->annotation);
188                 window->annotation = NULL;
189         }
190
191         if (window->rect) {
192                 ev_rectangle_free (window->rect);
193                 window->rect = NULL;
194         }
195
196         (* G_OBJECT_CLASS (ev_annotation_window_parent_class)->dispose) (object);
197 }
198
199 static void
200 ev_annotation_window_set_property (GObject      *object,
201                                    guint         prop_id,
202                                    const GValue *value,
203                                    GParamSpec   *pspec)
204 {
205         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (object);
206
207         switch (prop_id) {
208         case PROP_ANNOTATION:
209                 window->annotation = g_value_dup_object (value);
210                 break;
211         case PROP_PARENT:
212                 window->parent = g_value_get_object (value);
213                 break;
214         default:
215                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
216         }
217 }
218
219 static gboolean
220 ev_annotation_window_resize (EvAnnotationWindow *window,
221                              GdkEventButton     *event,
222                              GtkWidget          *ebox)
223 {
224         if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
225                 gtk_window_begin_resize_drag (GTK_WINDOW (window),
226                                               window->resize_sw == ebox ?
227                                               GDK_WINDOW_EDGE_SOUTH_WEST :
228                                               GDK_WINDOW_EDGE_SOUTH_EAST,
229                                               event->button, event->x_root,
230                                               event->y_root, event->time);
231                 return TRUE;
232         }
233
234         return FALSE;
235 }
236
237 static void
238 ev_annotation_window_set_resize_cursor (GtkWidget          *widget,
239                                         EvAnnotationWindow *window)
240 {
241         GdkWindow *gdk_window = gtk_widget_get_window (widget);
242
243         if (!gdk_window)
244                 return;
245
246         if (gtk_widget_is_sensitive (widget)) {
247                 GdkDisplay *display = gtk_widget_get_display (widget);
248                 GdkCursor  *cursor;
249
250                 cursor = gdk_cursor_new_for_display (display,
251                                                      widget == window->resize_sw ?
252                                                      GDK_BOTTOM_LEFT_CORNER :
253                                                      GDK_BOTTOM_RIGHT_CORNER);
254                 gdk_window_set_cursor (gdk_window, cursor);
255                 gdk_cursor_unref (cursor);
256         } else {
257                 gdk_window_set_cursor (gdk_window, NULL);
258         }
259 }
260
261 static gboolean
262 text_view_button_press (GtkWidget          *widget,
263                         GdkEventButton     *event,
264                         EvAnnotationWindow *window)
265 {
266         ev_annotation_window_grab_focus (window);
267
268         return FALSE;
269 }
270
271 static void
272 ev_annotation_window_close (EvAnnotationWindow *window)
273 {
274         gtk_widget_hide (GTK_WIDGET (window));
275         g_signal_emit (window, signals[CLOSED], 0);
276 }
277
278 static void
279 ev_annotation_window_init (EvAnnotationWindow *window)
280 {
281         GtkWidget *vbox, *hbox;
282         GtkWidget *icon;
283         GtkWidget *swindow;
284
285         gtk_widget_set_can_focus (GTK_WIDGET (window), TRUE);
286
287         vbox = gtk_vbox_new (FALSE, 0);
288
289         /* Title bar */
290         hbox = gtk_hbox_new (FALSE, 0);
291
292         icon = gtk_image_new (); /* FIXME: use the annot icon */
293         gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
294         gtk_widget_show (icon);
295
296         window->title = gtk_label_new (NULL);
297         gtk_box_pack_start (GTK_BOX (hbox), window->title, TRUE, TRUE, 0);
298         gtk_widget_show (window->title);
299
300         window->close_button = gtk_button_new ();
301         gtk_button_set_relief (GTK_BUTTON (window->close_button), GTK_RELIEF_NONE);
302         gtk_container_set_border_width (GTK_CONTAINER (window->close_button), 0);
303         g_signal_connect_swapped (window->close_button, "clicked",
304                                   G_CALLBACK (ev_annotation_window_close),
305                                   window);
306         icon = gtk_image_new_from_stock (EV_STOCK_CLOSE, EV_ICON_SIZE_ANNOT_WINDOW);
307         gtk_container_add (GTK_CONTAINER (window->close_button), icon);
308         gtk_widget_show (icon);
309
310         gtk_box_pack_start (GTK_BOX (hbox), window->close_button, FALSE, FALSE, 0);
311         gtk_widget_show (window->close_button);
312
313         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
314         gtk_widget_show (hbox);
315
316         /* Contents */
317         swindow = gtk_scrolled_window_new (NULL, NULL);
318         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
319                                         GTK_POLICY_AUTOMATIC,
320                                         GTK_POLICY_AUTOMATIC);
321         window->text_view = gtk_text_view_new ();
322         gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (window->text_view), GTK_WRAP_WORD);
323         g_signal_connect (window->text_view, "button_press_event",
324                           G_CALLBACK (text_view_button_press),
325                           window);
326         gtk_container_add (GTK_CONTAINER (swindow), window->text_view);
327         gtk_widget_show (window->text_view);
328
329         gtk_box_pack_start (GTK_BOX (vbox), swindow, TRUE, TRUE, 0);
330         gtk_widget_show (swindow);
331
332         /* Resize bar */
333         hbox = gtk_hbox_new (FALSE, 0);
334
335         window->resize_sw = gtk_event_box_new ();
336         gtk_widget_add_events (window->resize_sw, GDK_BUTTON_PRESS_MASK);
337         g_signal_connect_swapped (window->resize_sw, "button-press-event",
338                                   G_CALLBACK (ev_annotation_window_resize),
339                                   window);
340         g_signal_connect (window->resize_sw, "realize",
341                           G_CALLBACK (ev_annotation_window_set_resize_cursor),
342                           window);
343
344         icon = gtk_image_new_from_stock (EV_STOCK_RESIZE_SW, EV_ICON_SIZE_ANNOT_WINDOW);
345         gtk_container_add (GTK_CONTAINER (window->resize_sw), icon);
346         gtk_widget_show (icon);
347         gtk_box_pack_start (GTK_BOX (hbox), window->resize_sw, FALSE, FALSE, 0);
348         gtk_widget_show (window->resize_sw);
349
350         window->resize_se = gtk_event_box_new ();
351         gtk_widget_add_events (window->resize_se, GDK_BUTTON_PRESS_MASK);
352         g_signal_connect_swapped (window->resize_se, "button-press-event",
353                                   G_CALLBACK (ev_annotation_window_resize),
354                                   window);
355         g_signal_connect (window->resize_se, "realize",
356                           G_CALLBACK (ev_annotation_window_set_resize_cursor),
357                           window);
358
359         icon = gtk_image_new_from_stock (EV_STOCK_RESIZE_SE, EV_ICON_SIZE_ANNOT_WINDOW);
360         gtk_container_add (GTK_CONTAINER (window->resize_se), icon);
361         gtk_widget_show (icon);
362         gtk_box_pack_end (GTK_BOX (hbox), window->resize_se, FALSE, FALSE, 0);
363         gtk_widget_show (window->resize_se);
364
365         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
366         gtk_widget_show (hbox);
367
368         gtk_container_add (GTK_CONTAINER (window), vbox);
369         gtk_container_set_border_width (GTK_CONTAINER (window), 0);
370         gtk_widget_show (vbox);
371
372         gtk_widget_add_events (GTK_WIDGET (window),
373                                GDK_BUTTON_PRESS_MASK |
374                                GDK_KEY_PRESS_MASK);
375         gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
376
377         gtk_container_set_border_width (GTK_CONTAINER (window), 2);
378
379         gtk_window_set_accept_focus (GTK_WINDOW (window), TRUE);
380         gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
381         gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
382         gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
383         gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
384 }
385
386 static GObject *
387 ev_annotation_window_constructor (GType                  type,
388                                   guint                  n_construct_properties,
389                                   GObjectConstructParam *construct_params)
390 {
391         GObject            *object;
392         EvAnnotationWindow *window;
393         EvAnnotation       *annot;
394         gchar              *label;
395         gdouble             opacity;
396         EvRectangle        *rect;
397         gdouble             scale;
398
399         object = G_OBJECT_CLASS (ev_annotation_window_parent_class)->constructor (type,
400                                                                                   n_construct_properties,
401                                                                                   construct_params);
402         window = EV_ANNOTATION_WINDOW (object);
403         annot = window->annotation;
404
405         gtk_window_set_transient_for (GTK_WINDOW (window), window->parent);
406         gtk_window_set_destroy_with_parent (GTK_WINDOW (window), FALSE);
407
408         g_object_get (annot,
409                       "label", &label,
410                       "opacity", &opacity,
411                       "is_open", &window->is_open,
412                       "rectangle", &window->rect,
413                       NULL);
414         rect = window->rect;
415
416         /* Rectangle is at doc resolution (72.0) */
417         scale = get_screen_dpi (window) / 72.0;
418         gtk_window_resize (GTK_WINDOW (window),
419                            (gint)((rect->x2 - rect->x1) * scale),
420                            (gint)((rect->y2 - rect->y1) * scale));
421         ev_annotation_window_set_color (window, &annot->color);
422         gtk_widget_set_name (GTK_WIDGET (window), annot->name);
423         gtk_window_set_title (GTK_WINDOW (window), label);
424         gtk_label_set_text (GTK_LABEL (window->title), label);
425         gtk_window_set_opacity (GTK_WINDOW (window), opacity);
426         g_free (label);
427
428         if (annot->contents) {
429                 GtkTextBuffer *buffer;
430
431                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (window->text_view));
432                 gtk_text_buffer_set_text (buffer, annot->contents, -1);
433         }
434
435         return object;
436 }
437
438 static gboolean
439 ev_annotation_window_button_press_event (GtkWidget      *widget,
440                                          GdkEventButton *event)
441 {
442         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (widget);
443
444         if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
445                 window->in_move = TRUE;
446                 window->x = event->x;
447                 window->y = event->y;
448                 gtk_window_begin_move_drag (GTK_WINDOW (widget),
449                                             event->button,
450                                             event->x_root,
451                                             event->y_root,
452                                             event->time);
453                 return TRUE;
454         }
455
456         return FALSE;
457 }
458
459 static gboolean
460 ev_annotation_window_configure_event (GtkWidget         *widget,
461                                       GdkEventConfigure *event)
462 {
463         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (widget);
464
465         if (window->in_move &&
466             (window->x != event->x || window->y != event->y)) {
467                 window->x = event->x;
468                 window->y = event->y;
469         }
470
471         return GTK_WIDGET_CLASS (ev_annotation_window_parent_class)->configure_event (widget, event);
472 }
473
474 static gboolean
475 ev_annotation_window_focus_in_event (GtkWidget     *widget,
476                                      GdkEventFocus *event)
477 {
478         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (widget);
479
480         if (window->in_move) {
481                 window->orig_x = window->x;
482                 window->orig_y = window->y;
483         }
484
485         return FALSE;
486 }
487
488 static gboolean
489 ev_annotation_window_focus_out_event (GtkWidget     *widget,
490                                       GdkEventFocus *event)
491 {
492         EvAnnotationWindow *window = EV_ANNOTATION_WINDOW (widget);
493
494         if (window->in_move &&
495             (window->orig_x != window->x || window->orig_y != window->y)) {
496                 window->in_move = FALSE;
497                 g_signal_emit (window, signals[MOVED], 0, window->x, window->y);
498         }
499
500         return FALSE;
501 }
502
503 static void
504 ev_annotation_window_class_init (EvAnnotationWindowClass *klass)
505 {
506         GObjectClass   *g_object_class = G_OBJECT_CLASS (klass);
507         GtkWidgetClass *gtk_widget_class = GTK_WIDGET_CLASS (klass);
508
509         g_object_class->constructor = ev_annotation_window_constructor;
510         g_object_class->set_property = ev_annotation_window_set_property;
511         g_object_class->dispose = ev_annotation_window_dispose;
512
513         gtk_widget_class->button_press_event = ev_annotation_window_button_press_event;
514         gtk_widget_class->configure_event = ev_annotation_window_configure_event;
515         gtk_widget_class->focus_in_event = ev_annotation_window_focus_in_event;
516         gtk_widget_class->focus_out_event = ev_annotation_window_focus_out_event;
517
518         g_object_class_install_property (g_object_class,
519                                          PROP_ANNOTATION,
520                                          g_param_spec_object ("annotation",
521                                                               "Annotation",
522                                                               "The annotation associated to the window",
523                                                               EV_TYPE_ANNOTATION_MARKUP,
524                                                               G_PARAM_WRITABLE |
525                                                               G_PARAM_CONSTRUCT_ONLY));
526         g_object_class_install_property (g_object_class,
527                                          PROP_PARENT,
528                                          g_param_spec_object ("parent",
529                                                               "Parent",
530                                                               "The parent window",
531                                                               GTK_TYPE_WINDOW,
532                                                               G_PARAM_WRITABLE |
533                                                               G_PARAM_CONSTRUCT_ONLY));
534         signals[CLOSED] =
535                 g_signal_new ("closed",
536                               G_TYPE_FROM_CLASS (g_object_class),
537                               G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
538                               G_STRUCT_OFFSET (EvAnnotationWindowClass, closed),
539                               NULL, NULL,
540                               g_cclosure_marshal_VOID__VOID,
541                               G_TYPE_NONE, 0, G_TYPE_NONE);
542         signals[MOVED] =
543                 g_signal_new ("moved",
544                               G_TYPE_FROM_CLASS (g_object_class),
545                               G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
546                               G_STRUCT_OFFSET (EvAnnotationWindowClass, moved),
547                               NULL, NULL,
548                               ev_view_marshal_VOID__INT_INT,
549                               G_TYPE_NONE, 2,
550                               G_TYPE_INT, G_TYPE_INT);
551 }
552
553 /* Public methods */
554 GtkWidget *
555 ev_annotation_window_new (EvAnnotation *annot,
556                           GtkWindow    *parent)
557 {
558         GtkWidget *window;
559
560         g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (annot), NULL);
561         g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
562
563         window = g_object_new (EV_TYPE_ANNOTATION_WINDOW,
564                                "annotation", annot,
565                                "parent", parent,
566                                NULL);
567         return window;
568 }
569
570 EvAnnotation *
571 ev_annotation_window_get_annotation (EvAnnotationWindow *window)
572 {
573         g_return_val_if_fail (EV_IS_ANNOTATION_WINDOW (window), NULL);
574
575         return window->annotation;
576 }
577
578 void
579 ev_annotation_window_set_annotation (EvAnnotationWindow *window,
580                                      EvAnnotation       *annot)
581 {
582         g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
583         g_return_if_fail (EV_IS_ANNOTATION (annot));
584
585         if (annot == window->annotation)
586                 return;
587
588         g_object_unref (window->annotation);
589         window->annotation = g_object_ref (annot);
590         ev_annotation_window_check_contents_modified (window);
591         g_object_notify (G_OBJECT (window), "annotation");
592 }
593
594 gboolean
595 ev_annotation_window_is_open (EvAnnotationWindow *window)
596 {
597         g_return_val_if_fail (EV_IS_ANNOTATION_WINDOW (window), FALSE);
598
599         return window->is_open;
600 }
601
602 const EvRectangle *
603 ev_annotation_window_get_rectangle (EvAnnotationWindow *window)
604 {
605         g_return_val_if_fail (EV_IS_ANNOTATION_WINDOW (window), NULL);
606
607         return window->rect;
608 }
609
610 void
611 ev_annotation_window_set_rectangle (EvAnnotationWindow *window,
612                                     EvRectangle        *rect)
613 {
614         g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
615         g_return_if_fail (rect != NULL);
616
617         *window->rect = *rect;
618 }
619
620 void
621 ev_annotation_window_grab_focus (EvAnnotationWindow *window)
622 {
623         g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
624
625         if (!gtk_widget_has_focus (window->text_view)) {
626                 gtk_widget_grab_focus (GTK_WIDGET (window));
627                 send_focus_change (window->text_view, TRUE);
628         }
629 }
630
631 void
632 ev_annotation_window_ungrab_focus (EvAnnotationWindow *window)
633 {
634         g_return_if_fail (EV_IS_ANNOTATION_WINDOW (window));
635
636         if (gtk_widget_has_focus (window->text_view)) {
637                 send_focus_change (window->text_view, FALSE);
638         }
639
640         ev_annotation_window_check_contents_modified (window);
641 }