1 /*
2  *  window.c
3  *  Copyright (C) 2002-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
7  *  gLabels is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  gLabels is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include "window.h"
24 
25 #include <glib/gi18n.h>
26 #include <gtk/gtk.h>
27 
28 #include "ui.h"
29 #include "ui-commands.h"
30 #include "file-util.h"
31 #include "xml-label.h"
32 #include "prefs.h"
33 #include "file.h"
34 #include "units-util.h"
35 
36 #include "debug.h"
37 
38 
39 /*===========================================================================*/
40 /* Private macros and constants.                                             */
41 /*===========================================================================*/
42 
43 #define DEFAULT_WINDOW_WIDTH  788
44 #define DEFAULT_WINDOW_HEIGHT 600
45 
46 #define CURSOR_INFO_WIDTH     150
47 #define ZOOM_INFO_WIDTH        75
48 
49 
50 /*===========================================================================*/
51 /* Private globals                                                           */
52 /*===========================================================================*/
53 
54 static GList *window_list = NULL;
55 
56 
57 /*===========================================================================*/
58 /* Local function prototypes                                                 */
59 /*===========================================================================*/
60 
61 static void     gl_window_finalize     (GObject       *object);
62 static void     gl_window_dispose      (GObject       *object);
63 
64 static void     set_window_title       (glWindow *window,
65 					glLabel  *label);
66 
67 static gboolean window_delete_event_cb (glWindow      *window,
68 					GdkEvent      *event,
69 					gpointer       user_data);
70 
71 static void     selection_changed_cb   (glLabel       *label,
72 					glWindow      *window);
73 
74 static void   context_menu_activate_cb (glView       *view,
75 					gint          button,
76 					guint32       activate_time,
77 					glWindow     *window);
78 
79 static void     zoom_changed_cb        (glView        *view,
80 					gdouble        zoom,
81 					glWindow      *window);
82 
83 static void     pointer_moved_cb       (glView        *view,
84 					gdouble        x,
85 					gdouble        y,
86 					glWindow      *window);
87 
88 static void     pointer_exit_cb        (glView        *view,
89 					glWindow      *window);
90 
91 static void     name_changed_cb        (glLabel       *label,
92 					glWindow      *window);
93 
94 static void     modified_changed_cb    (glLabel       *label,
95 					glWindow      *window);
96 
97 static void     clipboard_changed_cb   (GtkClipboard  *clipboard,
98                                         GdkEvent      *event,
99 					glWindow      *window);
100 
101 static void     focus_widget_changed_cb(GtkWindow     *gtk_window,
102                                         GtkWidget     *widget,
103 					glWindow      *window);
104 
105 static void     set_copy_paste_sensitivity  (glWindow      *window,
106                                              GtkWidget     *focus_widget);
107 
108 static void     label_changed_cb       (glLabel       *label,
109 					glWindow      *window);
110 
111 
112 /****************************************************************************/
113 /* Boilerplate Object stuff.                                                */
114 /****************************************************************************/
G_DEFINE_TYPE(glWindow,gl_window,GTK_TYPE_WINDOW)115 G_DEFINE_TYPE (glWindow, gl_window, GTK_TYPE_WINDOW)
116 
117 
118 static void
119 gl_window_class_init (glWindowClass *class)
120 {
121 	GObjectClass   *object_class     = G_OBJECT_CLASS (class);
122 
123 	gl_debug (DEBUG_WINDOW, "START");
124 
125 	gl_window_parent_class = g_type_class_peek_parent (class);
126 
127 	object_class->finalize = gl_window_finalize;
128 	object_class->dispose  = gl_window_dispose;
129 
130 	gl_debug (DEBUG_WINDOW, "END");
131 }
132 
133 
134 static void
gl_window_init(glWindow * window)135 gl_window_init (glWindow *window)
136 {
137 	GtkWidget        *vbox1;
138 	GtkUIManager     *ui;
139 	GtkWidget        *status_hbox;
140 
141 	gl_debug (DEBUG_WINDOW, "START");
142 
143 	vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
144 	gtk_container_add (GTK_CONTAINER (window), vbox1);
145 
146 	window->ui = ui = gl_ui_new (window);
147 	gtk_box_pack_start (GTK_BOX (vbox1),
148 			    gtk_ui_manager_get_widget (ui, "/MenuBar"),
149 			    FALSE, FALSE, 0);
150 	gtk_box_pack_start (GTK_BOX (vbox1),
151 			    gtk_ui_manager_get_widget (ui, "/MainToolBar"),
152 			    FALSE, FALSE, 0);
153 	gtk_box_pack_start (GTK_BOX (vbox1),
154 			    gtk_ui_manager_get_widget (ui, "/DrawingToolBar"),
155 			    FALSE, FALSE, 0);
156 
157 	window->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
158 	gtk_box_pack_start (GTK_BOX (vbox1), window->hbox, TRUE, TRUE, 0);
159 
160 	window->sidebar = GL_UI_SIDEBAR (gl_ui_sidebar_new ());
161 	gtk_box_pack_end (GTK_BOX (window->hbox), GTK_WIDGET (window->sidebar), FALSE, FALSE, 0);
162 
163 	window->property_bar = GL_UI_PROPERTY_BAR (gl_ui_property_bar_new ());
164 	gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET (window->property_bar), FALSE, FALSE, 0);
165 
166 	status_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
167 	gtk_box_pack_start (GTK_BOX (vbox1), status_hbox, FALSE, FALSE, 0);
168 
169 	window->status_bar = gtk_statusbar_new ();
170 	gtk_box_pack_start (GTK_BOX (status_hbox),
171 			    window->status_bar,
172 			    TRUE, TRUE, 0);
173 	window->zoom_info = gtk_label_new (NULL);
174 	gtk_widget_set_size_request (window->zoom_info, ZOOM_INFO_WIDTH, -1);
175 	window->zoom_info_frame = gtk_frame_new (NULL);
176 	gtk_frame_set_shadow_type (GTK_FRAME(window->zoom_info_frame), GTK_SHADOW_IN);
177 	gtk_container_add (GTK_CONTAINER(window->zoom_info_frame), window->zoom_info);
178 	gtk_widget_show_all (window->zoom_info_frame);
179 	gtk_box_pack_end (GTK_BOX (status_hbox),
180 			  window->zoom_info_frame,
181 			  FALSE, FALSE, 0);
182 
183 	window->cursor_info = gtk_label_new (NULL);
184 	gtk_widget_set_size_request (window->cursor_info, CURSOR_INFO_WIDTH, -1);
185 	window->cursor_info_frame = gtk_frame_new (NULL);
186 	gtk_frame_set_shadow_type (GTK_FRAME(window->cursor_info_frame), GTK_SHADOW_IN);
187 	gtk_container_add (GTK_CONTAINER(window->cursor_info_frame), window->cursor_info);
188 	gtk_widget_show_all (window->cursor_info_frame);
189 	gtk_box_pack_end (GTK_BOX (status_hbox),
190 			  window->cursor_info_frame,
191 			  FALSE, FALSE, 0);
192 
193 	gtk_window_set_default_size (GTK_WINDOW (window),
194 				     DEFAULT_WINDOW_WIDTH,
195 				     DEFAULT_WINDOW_HEIGHT);
196 
197 	g_signal_connect (G_OBJECT(window), "delete-event",
198 			  G_CALLBACK(window_delete_event_cb), NULL);
199 
200 	window->menu_tips_context_id =
201 		gtk_statusbar_get_context_id (GTK_STATUSBAR (window->status_bar), "menu_tips");
202 
203 	window->print_settings = NULL;
204 	window->merge_dialog = NULL;
205 	window->context_menu = GTK_MENU (gtk_ui_manager_get_widget (ui, "/ContextMenu"));
206 	window->empty_selection_context_menu =
207 		GTK_MENU (gtk_ui_manager_get_widget (ui, "/EmptySelectionContextMenu"));
208 
209 	window->view = NULL;
210 
211 	window_list = g_list_append (window_list, window);
212 
213 	gl_debug (DEBUG_WINDOW, "END");
214 }
215 
216 
217 static void
gl_window_finalize(GObject * object)218 gl_window_finalize (GObject *object)
219 {
220 	gl_debug (DEBUG_WINDOW, "START");
221 
222 	g_return_if_fail (object != NULL);
223 	g_return_if_fail (GL_IS_WINDOW (object));
224 
225 	G_OBJECT_CLASS (gl_window_parent_class)->finalize (object);
226 
227 	gl_debug (DEBUG_WINDOW, "END");
228 }
229 
230 
231 static void
gl_window_dispose(GObject * object)232 gl_window_dispose (GObject *object)
233 {
234 	glWindow          *window;
235         GtkClipboard      *clipboard;
236 
237 	gl_debug (DEBUG_WINDOW, "START");
238 
239 	g_return_if_fail (object != NULL);
240 	g_return_if_fail (GL_IS_WINDOW (object));
241 
242 	window = GL_WINDOW (object);
243 	window_list = g_list_remove (window_list, window);
244 
245         if (window->ui) {
246 		gl_ui_unref(window->ui);
247 		window->ui = NULL;
248         }
249 
250         if (window->label)
251         {
252                 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window),
253                                                       GDK_SELECTION_CLIPBOARD);
254 
255                 g_signal_handlers_disconnect_by_func (G_OBJECT (clipboard),
256                                                       G_CALLBACK (clipboard_changed_cb),
257                                                       window);
258 
259 		g_object_unref (window->label);
260         }
261 
262 	if (G_OBJECT_CLASS (gl_window_parent_class)->dispose) {
263 		G_OBJECT_CLASS (gl_window_parent_class)->dispose (object);
264 	}
265 
266 	gl_debug (DEBUG_WINDOW, "END");
267 }
268 
269 
270 /****************************************************************************/
271 /** Create a glabels window.                                                */
272 /****************************************************************************/
273 GtkWidget *
gl_window_new(void)274 gl_window_new (void)
275 {
276 	glWindow *window;
277 
278 	gl_debug (DEBUG_WINDOW, "START");
279 
280 	window = g_object_new (GL_TYPE_WINDOW,
281 			       "title",    _("(none) - gLabels"),
282 			       NULL);
283 
284 	gl_debug (DEBUG_WINDOW, "window=%p", window);
285 	gl_debug (DEBUG_WINDOW, "view=%p", window->view);
286 
287 	gl_debug (DEBUG_WINDOW, "END");
288 
289 	return GTK_WIDGET(window);
290 }
291 
292 
293 /****************************************************************************/
294 /** Create a glabels window from a label.                                   */
295 /****************************************************************************/
296 GtkWidget*
gl_window_new_from_label(glLabel * label)297 gl_window_new_from_label (glLabel *label)
298 {
299 	glWindow *window;
300 
301 	gl_debug (DEBUG_WINDOW, "START");
302 
303 	window = GL_WINDOW (gl_window_new ());
304 
305 	gl_window_set_label (window, label);
306 
307 	gl_debug (DEBUG_WINDOW, "END");
308 
309 	return GTK_WIDGET(window);
310 }
311 
312 
313 /****************************************************************************/
314 /** Create a glabels window from a glabels file.                            */
315 /****************************************************************************/
316 GtkWidget*
gl_window_new_from_file(const gchar * filename)317 gl_window_new_from_file (const gchar *filename)
318 {
319 	glWindow         *window;
320 	glLabel          *label;
321 	gchar            *abs_filename;
322 	glXMLLabelStatus  status;
323 
324 	gl_debug (DEBUG_WINDOW, "START");
325 
326 	window = GL_WINDOW (gl_window_new ());
327 
328 	abs_filename = gl_file_util_make_absolute (filename);
329 	label = gl_xml_label_open (abs_filename, &status);
330 	g_free (abs_filename);
331 
332 	if (label) {
333 		gl_window_set_label (window, label);
334 	}
335 
336 	gl_debug (DEBUG_WINDOW, "END");
337 
338 	return GTK_WIDGET(window);
339 }
340 
341 
342 /****************************************************************************/
343 /** Is window empty?                                                        */
344 /****************************************************************************/
345 gboolean
gl_window_is_empty(glWindow * window)346 gl_window_is_empty (glWindow    *window)
347 {
348 	g_return_val_if_fail (GL_IS_WINDOW (window), FALSE);
349 
350 	gl_debug (DEBUG_WINDOW, "return %d", (window->view == NULL) );
351 	return ( window->view == NULL );
352 }
353 
354 
355 /****************************************************************************/
356 /** Create view from label and place in window.                             */
357 /****************************************************************************/
358 void
gl_window_set_label(glWindow * window,glLabel * label)359 gl_window_set_label (glWindow    *window,
360 		     glLabel     *label)
361 {
362 	gchar             *string;
363         GtkClipboard      *clipboard;
364         GtkWidget         *focus_widget;
365 
366 	gl_debug (DEBUG_WINDOW, "START");
367 
368 	g_return_if_fail (GL_IS_WINDOW (window));
369 	g_return_if_fail (GL_IS_LABEL (label));
370 
371         window->label = g_object_ref (label);
372 
373 	gl_label_clear_modified (label);
374 
375 	set_window_title (window, label);
376 
377 	if ( window->view != NULL ) {
378 		gtk_widget_destroy (window->view);
379 		window->view = NULL;
380 	}
381 
382 	window->view = gl_view_new (label);
383 	gtk_box_pack_start (GTK_BOX (window->hbox), window->view, TRUE, TRUE, 0);
384 
385 	gtk_widget_show_all (window->view);
386 
387 	gl_view_zoom_to_fit (GL_VIEW(window->view));
388 
389 	if (gl_prefs_model_get_grid_visible (gl_prefs)) {
390 		gl_view_show_grid (GL_VIEW(window->view));
391 	} else {
392 		gl_view_hide_grid (GL_VIEW(window->view));
393 	}
394 
395 	if (gl_prefs_model_get_markup_visible (gl_prefs)) {
396 		gl_view_show_markup (GL_VIEW(window->view));
397 	} else {
398 		gl_view_hide_markup (GL_VIEW(window->view));
399 	}
400 
401 	gl_ui_update_all (window->ui, GL_VIEW(window->view));
402 
403 	gl_ui_property_bar_set_label (window->property_bar, window->label);
404 	gl_ui_sidebar_set_label (window->sidebar, window->label);
405 
406 	string = g_strdup_printf ("%3.0f%%",
407 				  100.0*gl_view_get_zoom (GL_VIEW(window->view)));
408 	gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
409 	g_free (string);
410 
411 
412         clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window),
413                                               GDK_SELECTION_CLIPBOARD);
414 
415 
416 	g_signal_connect (G_OBJECT(window->label), "selection_changed",
417 			  G_CALLBACK(selection_changed_cb), window);
418 
419 	g_signal_connect (G_OBJECT(window->view), "context_menu_activate",
420 			  G_CALLBACK(context_menu_activate_cb), window);
421 
422 	g_signal_connect (G_OBJECT(window->view), "zoom_changed",
423 			  G_CALLBACK(zoom_changed_cb), window);
424 
425 	g_signal_connect (G_OBJECT(window->view), "pointer_moved",
426 			  G_CALLBACK(pointer_moved_cb), window);
427 
428 	g_signal_connect (G_OBJECT(window->view), "pointer_exit",
429 			  G_CALLBACK(pointer_exit_cb), window);
430 
431 	g_signal_connect (G_OBJECT(label), "name_changed",
432 			  G_CALLBACK(name_changed_cb), window);
433 
434 	g_signal_connect (G_OBJECT(label), "modified_changed",
435 			  G_CALLBACK(modified_changed_cb), window);
436 
437 	g_signal_connect (G_OBJECT(clipboard), "owner_change",
438 			  G_CALLBACK(clipboard_changed_cb), window);
439 
440 	g_signal_connect (G_OBJECT(window), "set_focus",
441 			  G_CALLBACK(focus_widget_changed_cb), window);
442 
443         /* Initialize "Paste" sensitivity. */
444         focus_widget = gtk_window_get_focus (GTK_WINDOW (window));
445         set_copy_paste_sensitivity (window, focus_widget);
446 
447 	g_signal_connect (G_OBJECT(label), "changed",
448 			  G_CALLBACK(label_changed_cb), window);
449 
450 	gl_debug (DEBUG_WINDOW, "END");
451 }
452 
453 
454 /****************************************************************************/
455 /** Return list of glabels windows.                                         */
456 /****************************************************************************/
457 const GList *
gl_window_get_window_list(void)458 gl_window_get_window_list (void)
459 {
460 	gl_debug (DEBUG_WINDOW, "");
461 	return window_list;
462 }
463 
464 
465 /*---------------------------------------------------------------------------*/
466 /** PRIVATE.  Set window title based on name and state of label.             */
467 /*---------------------------------------------------------------------------*/
468 static void
set_window_title(glWindow * window,glLabel * label)469 set_window_title (glWindow *window,
470 		  glLabel  *label)
471 {
472 	gchar *name, *title;
473 
474 	gl_debug (DEBUG_WINDOW, "START");
475 
476 	g_return_if_fail (window && GL_IS_WINDOW (window));
477 	g_return_if_fail (label && GL_IS_LABEL (label));
478 
479 	name = gl_label_get_short_name (label);
480 	g_return_if_fail (name != NULL);
481 
482 	if (gl_label_is_modified (label)) {
483 		title = g_strdup_printf ("%s %s - gLabels",
484 					 name, _("(modified)"));
485 	} else {
486 		title = g_strdup_printf ("%s - gLabels", name);
487 	}
488 
489 	gtk_window_set_title (GTK_WINDOW(window), title);
490 
491 	g_free (name);
492 	g_free (title);
493 
494 	gl_debug (DEBUG_WINDOW, "END");
495 }
496 
497 
498 /*-------------------------------------------------------------------------*/
499 /** PRIVATE.  Window "delete-event" callback.                              */
500 /*-------------------------------------------------------------------------*/
501 static gboolean
window_delete_event_cb(glWindow * window,GdkEvent * event,gpointer user_data)502 window_delete_event_cb (glWindow      *window,
503 			GdkEvent      *event,
504 			gpointer       user_data)
505 {
506 	gl_debug (DEBUG_WINDOW, "START");
507 
508 	g_return_val_if_fail (window && GL_IS_WINDOW (window), TRUE);
509 
510 	gl_file_close (window);
511 
512 	gl_debug (DEBUG_WINDOW, "END");
513 
514 	return TRUE;
515 }
516 
517 
518 /*---------------------------------------------------------------------------*/
519 /** PRIVATE.  View "selection state changed" callback.                       */
520 /*---------------------------------------------------------------------------*/
521 static void
selection_changed_cb(glLabel * label,glWindow * window)522 selection_changed_cb (glLabel  *label,
523 		      glWindow *window)
524 {
525 	gl_debug (DEBUG_WINDOW, "START");
526 
527 	g_return_if_fail (label && GL_IS_LABEL (label));
528 	g_return_if_fail (window && GL_IS_WINDOW (window));
529 
530         gl_ui_update_selection_verbs (window->ui, GL_VIEW (window->view), TRUE);
531 
532 	gl_debug (DEBUG_WINDOW, "END");
533 }
534 
535 
536 /*---------------------------------------------------------------------------*/
537 /** PRIVATE.  View "context menu activate" callback.                         */
538 /*---------------------------------------------------------------------------*/
539 static void
context_menu_activate_cb(glView * view,gint button,guint32 activate_time,glWindow * window)540 context_menu_activate_cb (glView       *view,
541 			  gint          button,
542 			  guint32       activate_time,
543 			  glWindow     *window)
544 {
545         gl_debug (DEBUG_WINDOW, "START");
546 
547         g_return_if_fail (view && GL_IS_VIEW (view));
548 	g_return_if_fail (window && GL_IS_WINDOW (window));
549 
550         if (gl_label_is_selection_empty (view->label)) {
551 
552 		gtk_menu_popup (GTK_MENU (window->empty_selection_context_menu),
553 				NULL, NULL, NULL, NULL, button, activate_time);
554 
555         } else {
556 
557 		gtk_menu_popup (GTK_MENU (window->context_menu),
558 				NULL, NULL, NULL, NULL, button, activate_time);
559 
560         }
561 
562         gl_debug (DEBUG_WINDOW, "END");
563 }
564 
565 
566 /*---------------------------------------------------------------------------*/
567 /** PRIVATE.  View "zoom state changed" callback.                            */
568 /*---------------------------------------------------------------------------*/
569 static void
zoom_changed_cb(glView * view,gdouble zoom,glWindow * window)570 zoom_changed_cb (glView   *view,
571 		 gdouble   zoom,
572 		 glWindow *window)
573 {
574 	gchar *string;
575 
576 	gl_debug (DEBUG_WINDOW, "START");
577 
578 	g_return_if_fail (view && GL_IS_VIEW (view));
579 	g_return_if_fail (window && GL_IS_WINDOW (window));
580 
581 	string = g_strdup_printf ("%3.0f%%", 100.0*zoom);
582 	gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
583 	g_free (string);
584 
585 	gl_ui_update_zoom_verbs (window->ui, view);
586 
587 	gl_debug (DEBUG_WINDOW, "END");
588 }
589 
590 
591 /*---------------------------------------------------------------------------*/
592 /** PRIVATE.  View "pointer moved" callback.                                 */
593 /*---------------------------------------------------------------------------*/
594 static void
pointer_moved_cb(glView * view,gdouble x,gdouble y,glWindow * window)595 pointer_moved_cb (glView   *view,
596 		  gdouble   x,
597 		  gdouble   y,
598 		  glWindow *window)
599 {
600 	gchar    *string;
601         lglUnits  units;
602 	gdouble   units_per_point;
603 	gint      units_precision;
604 
605 	gl_debug (DEBUG_WINDOW, "START");
606 
607 	g_return_if_fail (view && GL_IS_VIEW (view));
608 	g_return_if_fail (window && GL_IS_WINDOW (window));
609 
610         units = gl_prefs_model_get_units (gl_prefs);
611 	units_per_point = lgl_units_get_units_per_point (units);
612 	units_precision = gl_units_util_get_precision (units);
613 
614 	string = g_strdup_printf ("%.*f, %.*f",
615 				  units_precision, x*units_per_point,
616 				  units_precision, y*units_per_point);
617 	gtk_label_set_text (GTK_LABEL(window->cursor_info), string);
618 	g_free (string);
619 
620 	gl_debug (DEBUG_WINDOW, "END");
621 }
622 
623 
624 /*---------------------------------------------------------------------------*/
625 /** PRIVATE.  View "pointer exit" callback.                                  */
626 /*---------------------------------------------------------------------------*/
627 static void
pointer_exit_cb(glView * view,glWindow * window)628 pointer_exit_cb (glView   *view,
629 		 glWindow *window)
630 {
631 	gl_debug (DEBUG_WINDOW, "START");
632 
633 	g_return_if_fail (view && GL_IS_VIEW (view));
634 	g_return_if_fail (window && GL_IS_WINDOW (window));
635 
636 	gtk_label_set_text (GTK_LABEL(window->cursor_info), "");
637 
638 	gl_debug (DEBUG_WINDOW, "END");
639 }
640 
641 
642 /*---------------------------------------------------------------------------*/
643 /** PRIVATE.  Label "name changed" callback.                                 */
644 /*---------------------------------------------------------------------------*/
645 static void
name_changed_cb(glLabel * label,glWindow * window)646 name_changed_cb (glLabel  *label,
647 		 glWindow *window)
648 {
649 	gl_debug (DEBUG_WINDOW, "START");
650 
651 	g_return_if_fail (label && GL_IS_LABEL (label));
652 	g_return_if_fail (window && GL_IS_WINDOW (window));
653 
654 	set_window_title (window, label);
655 
656 	gl_debug (DEBUG_WINDOW, "END");
657 }
658 
659 
660 /*---------------------------------------------------------------------------*/
661 /** PRIVATE.  Label "modified state changed" callback.                       */
662 /*---------------------------------------------------------------------------*/
663 static void
modified_changed_cb(glLabel * label,glWindow * window)664 modified_changed_cb (glLabel  *label,
665 		     glWindow *window)
666 {
667 	gl_debug (DEBUG_WINDOW, "START");
668 
669 	g_return_if_fail (label && GL_IS_LABEL (label));
670 	g_return_if_fail (window && GL_IS_WINDOW (window));
671 
672 	set_window_title (window, label);
673 
674 	gl_ui_update_modified_verbs (window->ui, label);
675 
676 	gl_debug (DEBUG_WINDOW, "END");
677 }
678 
679 
680 /*---------------------------------------------------------------------------*/
681 /** PRIVATE.  Label "changed" callback.                                      */
682 /*---------------------------------------------------------------------------*/
683 static void
label_changed_cb(glLabel * label,glWindow * window)684 label_changed_cb (glLabel  *label,
685                   glWindow *window)
686 {
687 	gl_debug (DEBUG_WINDOW, "START");
688 
689 	g_return_if_fail (label && GL_IS_LABEL (label));
690 	g_return_if_fail (window && GL_IS_WINDOW (window));
691 
692 	gl_ui_update_undo_redo_verbs (window->ui, label);
693 
694 	gl_debug (DEBUG_WINDOW, "END");
695 }
696 
697 
698 
699 /*---------------------------------------------------------------------------*/
700 /** PRIVATE.  Clipboard "owner change" callback.                             */
701 /*---------------------------------------------------------------------------*/
702 static void
clipboard_changed_cb(GtkClipboard * clipboard,GdkEvent * event,glWindow * window)703 clipboard_changed_cb (GtkClipboard *clipboard,
704                       GdkEvent     *event,
705                       glWindow     *window)
706 {
707         GtkWidget    *focus_widget;
708 
709 	gl_debug (DEBUG_WINDOW, "START");
710 
711 	g_return_if_fail (window && GL_IS_WINDOW (window));
712 
713         focus_widget = gtk_window_get_focus (GTK_WINDOW (window));
714         set_copy_paste_sensitivity (window, focus_widget);
715 
716 	gl_debug (DEBUG_WINDOW, "END");
717 }
718 
719 
720 /*---------------------------------------------------------------------------*/
721 /** PRIVATE.  Window "set-focus" callback.                                   */
722 /*---------------------------------------------------------------------------*/
723 static void
focus_widget_changed_cb(GtkWindow * gtk_window,GtkWidget * widget,glWindow * window)724 focus_widget_changed_cb (GtkWindow *gtk_window,
725                          GtkWidget *widget,
726                          glWindow  *window)
727 {
728 	gl_debug (DEBUG_WINDOW, "START");
729 
730 	g_return_if_fail (window && GL_IS_WINDOW (window));
731 
732         if (widget)
733         {
734                 gl_debug (DEBUG_WINDOW, "SET-FOCUS %x %s\n",
735                           widget,
736                           G_OBJECT_TYPE_NAME (widget));
737 
738                 set_copy_paste_sensitivity (window, widget);
739         }
740 
741 	gl_debug (DEBUG_WINDOW, "END");
742 }
743 
744 
745 /*---------------------------------------------------------------------------*/
746 /** PRIVATE.  Set paste sensitivity.                                         */
747 /*---------------------------------------------------------------------------*/
748 static void
set_copy_paste_sensitivity(glWindow * window,GtkWidget * focus_widget)749 set_copy_paste_sensitivity (glWindow  *window,
750                             GtkWidget *focus_widget)
751 {
752 	gl_debug (DEBUG_WINDOW, "START");
753 
754 	g_return_if_fail (window && GL_IS_WINDOW (window));
755 
756         if ( focus_widget == GL_VIEW(window->view)->canvas )
757         {
758                 gl_ui_update_selection_verbs (window->ui, GL_VIEW (window->view), TRUE);
759 
760                 gl_ui_update_paste_verbs (window->ui, gl_label_can_paste (window->label));
761         }
762         else
763         {
764                 gl_ui_update_selection_verbs (window->ui, GL_VIEW (window->view), FALSE);
765                 gl_ui_update_paste_verbs (window->ui, FALSE);
766         }
767 
768 	gl_debug (DEBUG_WINDOW, "END");
769 }
770 
771 
772 /*
773  * Local Variables:       -- emacs
774  * mode: C                -- emacs
775  * c-basic-offset: 8      -- emacs
776  * tab-width: 8           -- emacs
777  * indent-tabs-mode: nil  -- emacs
778  * End:                   -- emacs
779  */
780