3 * Copyright (C) 2002-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
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.
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.
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/>.
25 #include <glib/gi18n.h>
29 #include "ui-commands.h"
30 #include "file-util.h"
31 #include "xml-label.h"
38 /*===========================================================================*/
39 /* Private macros and constants. */
40 /*===========================================================================*/
42 #define DEFAULT_WINDOW_WIDTH 788
43 #define DEFAULT_WINDOW_HEIGHT 600
45 #define CURSOR_INFO_WIDTH 150
46 #define ZOOM_INFO_WIDTH 50
49 /*===========================================================================*/
51 /*===========================================================================*/
53 static GList *window_list = NULL;
56 /*===========================================================================*/
57 /* Local function prototypes */
58 /*===========================================================================*/
60 static void gl_window_finalize (GObject *object);
61 static void gl_window_destroy (GtkObject *gtk_object);
63 static void set_window_title (glWindow *window,
66 static gboolean window_delete_event_cb (glWindow *window,
70 static void selection_changed_cb (glView *view,
73 static void context_menu_activate_cb (glView *view,
75 guint32 activate_time,
78 static void zoom_changed_cb (glView *view,
82 static void pointer_moved_cb (glView *view,
87 static void pointer_exit_cb (glView *view,
90 static void name_changed_cb (glLabel *label,
93 static void modified_changed_cb (glLabel *label,
97 /****************************************************************************/
98 /* Boilerplate Object stuff. */
99 /****************************************************************************/
100 G_DEFINE_TYPE (glWindow, gl_window, GTK_TYPE_WINDOW);
104 gl_window_class_init (glWindowClass *class)
106 GObjectClass *object_class = G_OBJECT_CLASS (class);
107 GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (class);
109 gl_debug (DEBUG_WINDOW, "START");
111 gl_window_parent_class = g_type_class_peek_parent (class);
113 object_class->finalize = gl_window_finalize;
115 gtk_object_class->destroy = gl_window_destroy;
117 gl_debug (DEBUG_WINDOW, "END");
122 gl_window_init (glWindow *window)
126 GtkWidget *status_hbox;
128 gl_debug (DEBUG_WINDOW, "START");
130 vbox1 = gtk_vbox_new (FALSE, 0);
131 gtk_container_add (GTK_CONTAINER (window), vbox1);
133 window->ui = ui = gl_ui_new (window);
134 gtk_box_pack_start (GTK_BOX (vbox1),
135 gtk_ui_manager_get_widget (ui, "/MenuBar"),
137 gtk_box_pack_start (GTK_BOX (vbox1),
138 gtk_ui_manager_get_widget (ui, "/MainToolBar"),
140 gtk_box_pack_start (GTK_BOX (vbox1),
141 gtk_ui_manager_get_widget (ui, "/DrawingToolBar"),
144 window->hbox = gtk_hbox_new (FALSE, 0);
145 gtk_box_pack_start (GTK_BOX (vbox1), window->hbox, TRUE, TRUE, 0);
147 window->sidebar = GL_UI_SIDEBAR (gl_ui_sidebar_new ());
148 gtk_box_pack_end (GTK_BOX (window->hbox), GTK_WIDGET (window->sidebar), FALSE, FALSE, 0);
150 window->property_bar = GL_UI_PROPERTY_BAR (gl_ui_property_bar_new ());
151 gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET (window->property_bar), FALSE, FALSE, 0);
153 status_hbox = gtk_hbox_new (FALSE, 0);
154 gtk_box_pack_start (GTK_BOX (vbox1), status_hbox, FALSE, FALSE, 0);
156 window->status_bar = gtk_statusbar_new ();
157 gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (window->status_bar), FALSE);
158 gtk_box_pack_start (GTK_BOX (status_hbox),
161 window->zoom_info = gtk_label_new (NULL);
162 gtk_widget_set_size_request (window->zoom_info, ZOOM_INFO_WIDTH, -1);
163 window->zoom_info_frame = gtk_frame_new (NULL);
164 gtk_frame_set_shadow_type (GTK_FRAME(window->zoom_info_frame), GTK_SHADOW_IN);
165 gtk_container_add (GTK_CONTAINER(window->zoom_info_frame), window->zoom_info);
166 gtk_widget_show_all (window->zoom_info_frame);
167 gtk_box_pack_end (GTK_BOX (status_hbox),
168 window->zoom_info_frame,
171 window->cursor_info = gtk_label_new (NULL);
172 gtk_widget_set_size_request (window->cursor_info, CURSOR_INFO_WIDTH, -1);
173 window->cursor_info_frame = gtk_frame_new (NULL);
174 gtk_frame_set_shadow_type (GTK_FRAME(window->cursor_info_frame), GTK_SHADOW_IN);
175 gtk_container_add (GTK_CONTAINER(window->cursor_info_frame), window->cursor_info);
176 gtk_widget_show_all (window->cursor_info_frame);
177 gtk_box_pack_end (GTK_BOX (status_hbox),
178 window->cursor_info_frame,
181 gtk_window_set_default_size (GTK_WINDOW (window),
182 DEFAULT_WINDOW_WIDTH,
183 DEFAULT_WINDOW_HEIGHT);
185 g_signal_connect (G_OBJECT(window), "delete-event",
186 G_CALLBACK(window_delete_event_cb), NULL);
188 window->menu_tips_context_id =
189 gtk_statusbar_get_context_id (GTK_STATUSBAR (window->status_bar), "menu_tips");
191 window->print_settings = NULL;
192 window->merge_dialog = NULL;
193 window->context_menu = GTK_MENU (gtk_ui_manager_get_widget (ui, "/ContextMenu"));
194 window->empty_selection_context_menu =
195 GTK_MENU (gtk_ui_manager_get_widget (ui, "/EmptySelectionContextMenu"));
199 window_list = g_list_append (window_list, window);
201 gl_debug (DEBUG_WINDOW, "END");
206 gl_window_finalize (GObject *object)
208 gl_debug (DEBUG_WINDOW, "START");
210 g_return_if_fail (object != NULL);
211 g_return_if_fail (GL_IS_WINDOW (object));
213 G_OBJECT_CLASS (gl_window_parent_class)->finalize (object);
215 gl_debug (DEBUG_WINDOW, "END");
220 gl_window_destroy (GtkObject *gtk_object)
224 gl_debug (DEBUG_WINDOW, "START");
226 g_return_if_fail (gtk_object != NULL);
227 g_return_if_fail (GL_IS_WINDOW (gtk_object));
229 window = GL_WINDOW (gtk_object);
230 window_list = g_list_remove (window_list, window);
233 gl_ui_unref(window->ui);
237 if (GTK_OBJECT_CLASS (gl_window_parent_class)->destroy) {
238 GTK_OBJECT_CLASS (gl_window_parent_class)->destroy (gtk_object);
241 gl_debug (DEBUG_WINDOW, "END");
245 /****************************************************************************/
246 /** Create a glabels window. */
247 /****************************************************************************/
253 gl_debug (DEBUG_WINDOW, "START");
255 window = g_object_new (GL_TYPE_WINDOW,
256 "title", _("(none) - gLabels"),
259 gl_debug (DEBUG_WINDOW, "window=%p", window);
260 gl_debug (DEBUG_WINDOW, "view=%p", window->view);
262 gl_debug (DEBUG_WINDOW, "END");
264 return GTK_WIDGET(window);
268 /****************************************************************************/
269 /** Create a glabels window from a label. */
270 /****************************************************************************/
272 gl_window_new_from_label (glLabel *label)
276 gl_debug (DEBUG_WINDOW, "START");
278 window = GL_WINDOW (gl_window_new ());
280 gl_window_set_label (window, label);
282 gl_debug (DEBUG_WINDOW, "END");
284 return GTK_WIDGET(window);
288 /****************************************************************************/
289 /** Create a glabels window from a glabels file. */
290 /****************************************************************************/
292 gl_window_new_from_file (const gchar *filename)
297 glXMLLabelStatus status;
299 gl_debug (DEBUG_WINDOW, "START");
301 window = GL_WINDOW (gl_window_new ());
303 abs_filename = gl_file_util_make_absolute (filename);
304 label = gl_xml_label_open (abs_filename, &status);
305 g_free (abs_filename);
307 gl_window_set_label (window, label);
309 gl_debug (DEBUG_WINDOW, "END");
311 return GTK_WIDGET(window);
315 /****************************************************************************/
316 /** Is window empty? */
317 /****************************************************************************/
319 gl_window_is_empty (glWindow *window)
321 g_return_val_if_fail (GL_IS_WINDOW (window), FALSE);
323 gl_debug (DEBUG_WINDOW, "return %d", (window->view == NULL) );
324 return ( window->view == NULL );
328 /****************************************************************************/
329 /** Create view from label and place in window. */
330 /****************************************************************************/
332 gl_window_set_label (glWindow *window,
337 gl_debug (DEBUG_WINDOW, "START");
339 g_return_if_fail (GL_IS_WINDOW (window));
340 g_return_if_fail (GL_IS_LABEL (label));
342 gl_label_clear_modified (label);
344 set_window_title (window, label);
346 if ( window->view != NULL ) {
347 gtk_widget_destroy (window->view);
351 window->view = gl_view_new (label);
352 gtk_box_pack_start (GTK_BOX (window->hbox), window->view,TRUE, TRUE, 0);
354 gtk_widget_show_all (window->view);
356 gl_view_zoom_to_fit (GL_VIEW(window->view));
358 if (gl_prefs->grid_visible) {
359 gl_view_show_grid (GL_VIEW(window->view));
361 gl_view_hide_grid (GL_VIEW(window->view));
364 if (gl_prefs->markup_visible) {
365 gl_view_show_markup (GL_VIEW(window->view));
367 gl_view_hide_markup (GL_VIEW(window->view));
370 gl_ui_update_all (window->ui, GL_VIEW(window->view));
372 gl_ui_property_bar_set_view (window->property_bar, GL_VIEW(window->view));
373 gl_ui_sidebar_set_view (window->sidebar, GL_VIEW(window->view));
375 string = g_strdup_printf ("%3.0f%%",
376 100.0*gl_view_get_zoom (GL_VIEW(window->view)));
377 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
380 g_signal_connect (G_OBJECT(window->view), "selection_changed",
381 G_CALLBACK(selection_changed_cb), window);
383 g_signal_connect (G_OBJECT(window->view), "context_menu_activate",
384 G_CALLBACK(context_menu_activate_cb), window);
386 g_signal_connect (G_OBJECT(window->view), "zoom_changed",
387 G_CALLBACK(zoom_changed_cb), window);
389 g_signal_connect (G_OBJECT(window->view), "pointer_moved",
390 G_CALLBACK(pointer_moved_cb), window);
392 g_signal_connect (G_OBJECT(window->view), "pointer_exit",
393 G_CALLBACK(pointer_exit_cb), window);
395 g_signal_connect (G_OBJECT(label), "name_changed",
396 G_CALLBACK(name_changed_cb), window);
398 g_signal_connect (G_OBJECT(label), "modified_changed",
399 G_CALLBACK(modified_changed_cb), window);
401 gl_debug (DEBUG_WINDOW, "END");
405 /****************************************************************************/
406 /** Return list of glabels windows. */
407 /****************************************************************************/
409 gl_window_get_window_list (void)
411 gl_debug (DEBUG_WINDOW, "");
416 /*---------------------------------------------------------------------------*/
417 /** PRIVATE. Set window title based on name and state of label. */
418 /*---------------------------------------------------------------------------*/
420 set_window_title (glWindow *window,
425 gl_debug (DEBUG_WINDOW, "START");
427 g_return_if_fail (window && GL_IS_WINDOW (window));
428 g_return_if_fail (label && GL_IS_LABEL (label));
430 name = gl_label_get_short_name (label);
431 g_return_if_fail (name != NULL);
433 if (gl_label_is_modified (label)) {
434 title = g_strdup_printf ("%s %s - gLabels",
435 name, _("(modified)"));
437 title = g_strdup_printf ("%s - gLabels", name);
440 gtk_window_set_title (GTK_WINDOW(window), title);
445 gl_debug (DEBUG_WINDOW, "END");
449 /*-------------------------------------------------------------------------*/
450 /** PRIVATE. Window "delete-event" callback. */
451 /*-------------------------------------------------------------------------*/
453 window_delete_event_cb (glWindow *window,
457 gl_debug (DEBUG_WINDOW, "START");
459 g_return_val_if_fail (window && GL_IS_WINDOW (window), TRUE);
461 gl_file_close (window);
463 gl_debug (DEBUG_WINDOW, "END");
469 /*---------------------------------------------------------------------------*/
470 /** PRIVATE. View "selection state changed" callback. */
471 /*---------------------------------------------------------------------------*/
473 selection_changed_cb (glView *view,
476 gl_debug (DEBUG_WINDOW, "START");
478 g_return_if_fail (view && GL_IS_VIEW (view));
479 g_return_if_fail (window && GL_IS_WINDOW (window));
481 gl_ui_update_selection_verbs (window->ui, view);
483 gl_debug (DEBUG_WINDOW, "END");
487 /*---------------------------------------------------------------------------*/
488 /** PRIVATE. View "context menu activate" callback. */
489 /*---------------------------------------------------------------------------*/
491 context_menu_activate_cb (glView *view,
493 guint32 activate_time,
496 gl_debug (DEBUG_WINDOW, "START");
498 g_return_if_fail (view && GL_IS_VIEW (view));
499 g_return_if_fail (window && GL_IS_WINDOW (window));
501 if (gl_view_is_selection_empty (view)) {
503 gtk_menu_popup (GTK_MENU (window->empty_selection_context_menu),
504 NULL, NULL, NULL, NULL, button, activate_time);
508 gtk_menu_popup (GTK_MENU (window->context_menu),
509 NULL, NULL, NULL, NULL, button, activate_time);
513 gl_debug (DEBUG_WINDOW, "END");
517 /*---------------------------------------------------------------------------*/
518 /** PRIVATE. View "zoom state changed" callback. */
519 /*---------------------------------------------------------------------------*/
521 zoom_changed_cb (glView *view,
527 gl_debug (DEBUG_WINDOW, "START");
529 g_return_if_fail (view && GL_IS_VIEW (view));
530 g_return_if_fail (window && GL_IS_WINDOW (window));
532 string = g_strdup_printf ("%3.0f%%", 100.0*zoom);
533 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
536 gl_ui_update_zoom_verbs (window->ui, view);
538 gl_debug (DEBUG_WINDOW, "END");
542 /*---------------------------------------------------------------------------*/
543 /** PRIVATE. View "pointer moved" callback. */
544 /*---------------------------------------------------------------------------*/
546 pointer_moved_cb (glView *view,
552 gdouble units_per_point;
553 gint units_precision;
555 gl_debug (DEBUG_WINDOW, "START");
557 g_return_if_fail (view && GL_IS_VIEW (view));
558 g_return_if_fail (window && GL_IS_WINDOW (window));
560 units_per_point = gl_prefs_get_units_per_point ();
561 units_precision = gl_prefs_get_units_precision ();
563 string = g_strdup_printf ("%.*f, %.*f",
564 units_precision, x*units_per_point,
565 units_precision, y*units_per_point);
566 gtk_label_set_text (GTK_LABEL(window->cursor_info), string);
569 gl_debug (DEBUG_WINDOW, "END");
573 /*---------------------------------------------------------------------------*/
574 /** PRIVATE. View "pointer exit" callback. */
575 /*---------------------------------------------------------------------------*/
577 pointer_exit_cb (glView *view,
580 gl_debug (DEBUG_WINDOW, "START");
582 g_return_if_fail (view && GL_IS_VIEW (view));
583 g_return_if_fail (window && GL_IS_WINDOW (window));
585 gtk_label_set_text (GTK_LABEL(window->cursor_info), "");
587 gl_debug (DEBUG_WINDOW, "END");
591 /*---------------------------------------------------------------------------*/
592 /** PRIVATE. Label "name changed" callback. */
593 /*---------------------------------------------------------------------------*/
595 name_changed_cb (glLabel *label,
598 gl_debug (DEBUG_WINDOW, "START");
600 g_return_if_fail (label && GL_IS_LABEL (label));
601 g_return_if_fail (window && GL_IS_WINDOW (window));
603 set_window_title (window, label);
605 gl_debug (DEBUG_WINDOW, "END");
609 /*---------------------------------------------------------------------------*/
610 /** PRIVATE. Label "modified state changed" callback. */
611 /*---------------------------------------------------------------------------*/
613 modified_changed_cb (glLabel *label,
616 gl_debug (DEBUG_WINDOW, "START");
618 g_return_if_fail (label && GL_IS_LABEL (label));
619 g_return_if_fail (window && GL_IS_WINDOW (window));
621 set_window_title (window, label);
623 gl_ui_update_modified_verbs (window->ui, label);
625 gl_debug (DEBUG_WINDOW, "END");
631 * Local Variables: -- emacs
633 * c-basic-offset: 8 -- emacs
634 * tab-width: 8 -- emacs
635 * indent-tabs-mode: nil -- emacs