1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * window.c: a gLabels app window
8 * Copyright (C) 2002 Jim Evins <evins@snaught.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include <glib/gi18n.h>
30 #include <gtk/gtkvbox.h>
31 #include <gtk/gtkhbox.h>
32 #include <gtk/gtklabel.h>
33 #include <gtk/gtkframe.h>
34 #include <gtk/gtkstatusbar.h>
37 #include "ui-commands.h"
39 #include "xml-label.h"
45 /*===========================================================================*/
46 /* Private macros and constants. */
47 /*===========================================================================*/
49 #define DEFAULT_WINDOW_WIDTH 788
50 #define DEFAULT_WINDOW_HEIGHT 600
52 #define CURSOR_INFO_WIDTH 150
53 #define ZOOM_INFO_WIDTH 50
55 /*===========================================================================*/
57 /*===========================================================================*/
59 static GList *window_list = NULL;
62 /*===========================================================================*/
63 /* Local function prototypes */
64 /*===========================================================================*/
66 static void gl_window_finalize (GObject *object);
67 static void gl_window_destroy (GtkObject *gtk_object);
69 static void set_window_title (glWindow *window,
72 static gboolean window_delete_event_cb (glWindow *window,
76 static void selection_changed_cb (glView *view,
79 static void context_menu_activate_cb (glView *view,
81 guint32 activate_time,
84 static void zoom_changed_cb (glView *view,
88 static void pointer_moved_cb (glView *view,
93 static void pointer_exit_cb (glView *view,
96 static void name_changed_cb (glLabel *label,
99 static void modified_changed_cb (glLabel *label,
103 /****************************************************************************/
104 /* Boilerplate Object stuff. */
105 /****************************************************************************/
106 G_DEFINE_TYPE (glWindow, gl_window, GTK_TYPE_WINDOW);
110 gl_window_class_init (glWindowClass *class)
112 GObjectClass *object_class = G_OBJECT_CLASS (class);
113 GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (class);
115 gl_debug (DEBUG_WINDOW, "START");
117 gl_window_parent_class = g_type_class_peek_parent (class);
119 object_class->finalize = gl_window_finalize;
121 gtk_object_class->destroy = gl_window_destroy;
123 gl_debug (DEBUG_WINDOW, "END");
127 gl_window_init (glWindow *window)
131 GtkWidget *status_hbox;
133 gl_debug (DEBUG_WINDOW, "START");
135 vbox1 = gtk_vbox_new (FALSE, 0);
136 gtk_container_add (GTK_CONTAINER (window), vbox1);
138 window->ui = ui = gl_ui_new (window);
139 gtk_box_pack_start (GTK_BOX (vbox1),
140 gtk_ui_manager_get_widget (ui, "/MenuBar"),
142 gtk_box_pack_start (GTK_BOX (vbox1),
143 gtk_ui_manager_get_widget (ui, "/MainToolBar"),
145 gtk_box_pack_start (GTK_BOX (vbox1),
146 gtk_ui_manager_get_widget (ui, "/DrawingToolBar"),
149 window->hbox = gtk_hbox_new (FALSE, 0);
150 gtk_box_pack_start (GTK_BOX (vbox1), window->hbox, TRUE, TRUE, 0);
152 window->sidebar = GL_UI_SIDEBAR (gl_ui_sidebar_new ());
153 gtk_box_pack_end (GTK_BOX (window->hbox), GTK_WIDGET (window->sidebar), FALSE, FALSE, 0);
155 window->property_bar = GL_UI_PROPERTY_BAR (gl_ui_property_bar_new ());
156 gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET (window->property_bar), FALSE, FALSE, 0);
158 status_hbox = gtk_hbox_new (FALSE, 0);
159 gtk_box_pack_start (GTK_BOX (vbox1), status_hbox, FALSE, FALSE, 0);
161 window->status_bar = gtk_statusbar_new ();
162 gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (window->status_bar), FALSE);
163 gtk_box_pack_start (GTK_BOX (status_hbox),
166 window->zoom_info = gtk_label_new (NULL);
167 gtk_widget_set_size_request (window->zoom_info, ZOOM_INFO_WIDTH, -1);
168 window->zoom_info_frame = gtk_frame_new (NULL);
169 gtk_frame_set_shadow_type (GTK_FRAME(window->zoom_info_frame), GTK_SHADOW_IN);
170 gtk_container_add (GTK_CONTAINER(window->zoom_info_frame), window->zoom_info);
171 gtk_widget_show_all (window->zoom_info_frame);
172 gtk_box_pack_end (GTK_BOX (status_hbox),
173 window->zoom_info_frame,
176 window->cursor_info = gtk_label_new (NULL);
177 gtk_widget_set_size_request (window->cursor_info, CURSOR_INFO_WIDTH, -1);
178 window->cursor_info_frame = gtk_frame_new (NULL);
179 gtk_frame_set_shadow_type (GTK_FRAME(window->cursor_info_frame), GTK_SHADOW_IN);
180 gtk_container_add (GTK_CONTAINER(window->cursor_info_frame), window->cursor_info);
181 gtk_widget_show_all (window->cursor_info_frame);
182 gtk_box_pack_end (GTK_BOX (status_hbox),
183 window->cursor_info_frame,
186 gtk_window_set_default_size (GTK_WINDOW (window),
187 DEFAULT_WINDOW_WIDTH,
188 DEFAULT_WINDOW_HEIGHT);
190 g_signal_connect (G_OBJECT(window), "delete-event",
191 G_CALLBACK(window_delete_event_cb), NULL);
193 window->menu_tips_context_id =
194 gtk_statusbar_get_context_id (GTK_STATUSBAR (window->status_bar), "menu_tips");
196 window->print_settings = NULL;
197 window->merge_dialog = NULL;
198 window->context_menu = GTK_MENU (gtk_ui_manager_get_widget (ui, "/ContextMenu"));
199 window->empty_selection_context_menu =
200 GTK_MENU (gtk_ui_manager_get_widget (ui, "/EmptySelectionContextMenu"));
204 window_list = g_list_append (window_list, window);
206 gl_debug (DEBUG_WINDOW, "END");
210 gl_window_finalize (GObject *object)
212 gl_debug (DEBUG_WINDOW, "START");
214 g_return_if_fail (object != NULL);
215 g_return_if_fail (GL_IS_WINDOW (object));
217 G_OBJECT_CLASS (gl_window_parent_class)->finalize (object);
219 gl_debug (DEBUG_WINDOW, "END");
223 gl_window_destroy (GtkObject *gtk_object)
227 gl_debug (DEBUG_WINDOW, "START");
229 g_return_if_fail (gtk_object != NULL);
230 g_return_if_fail (GL_IS_WINDOW (gtk_object));
232 window = GL_WINDOW (gtk_object);
233 window_list = g_list_remove (window_list, window);
236 gl_ui_unref(window->ui);
240 if (GTK_OBJECT_CLASS (gl_window_parent_class)->destroy) {
241 GTK_OBJECT_CLASS (gl_window_parent_class)->destroy (gtk_object);
244 gl_debug (DEBUG_WINDOW, "END");
248 /****************************************************************************/
249 /** Create a glabels window. */
250 /****************************************************************************/
256 gl_debug (DEBUG_WINDOW, "START");
258 window = g_object_new (GL_TYPE_WINDOW,
259 "title", _("(none) - gLabels"),
262 gl_debug (DEBUG_WINDOW, "window=%p", window);
263 gl_debug (DEBUG_WINDOW, "view=%p", window->view);
265 gl_debug (DEBUG_WINDOW, "END");
267 return GTK_WIDGET(window);
270 /****************************************************************************/
271 /** Create a glabels window from a label. */
272 /****************************************************************************/
274 gl_window_new_from_label (glLabel *label)
278 gl_debug (DEBUG_WINDOW, "START");
280 window = GL_WINDOW (gl_window_new ());
282 gl_window_set_label (window, label);
284 gl_debug (DEBUG_WINDOW, "END");
286 return GTK_WIDGET(window);
289 /****************************************************************************/
290 /** Create a glabels window from a glabels file. */
291 /****************************************************************************/
293 gl_window_new_from_file (const gchar *filename)
298 glXMLLabelStatus status;
300 gl_debug (DEBUG_WINDOW, "START");
302 window = GL_WINDOW (gl_window_new ());
304 abs_filename = gl_util_make_absolute (filename);
305 label = gl_xml_label_open (abs_filename, &status);
306 g_free (abs_filename);
308 gl_window_set_label (window, label);
310 gl_debug (DEBUG_WINDOW, "END");
312 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 );
327 /****************************************************************************/
328 /** Create view from label and place in window. */
329 /****************************************************************************/
331 gl_window_set_label (glWindow *window,
336 gl_debug (DEBUG_WINDOW, "START");
338 g_return_if_fail (GL_IS_WINDOW (window));
339 g_return_if_fail (GL_IS_LABEL (label));
341 gl_label_clear_modified (label);
343 set_window_title (window, label);
345 if ( window->view != NULL ) {
346 gtk_widget_destroy (window->view);
350 window->view = gl_view_new (label);
351 gtk_box_pack_start (GTK_BOX (window->hbox), window->view,TRUE, TRUE, 0);
353 gtk_widget_show_all (window->view);
355 gl_view_zoom_to_fit (GL_VIEW(window->view));
357 if (gl_prefs->grid_visible) {
358 gl_view_show_grid (GL_VIEW(window->view));
360 gl_view_hide_grid (GL_VIEW(window->view));
363 if (gl_prefs->markup_visible) {
364 gl_view_show_markup (GL_VIEW(window->view));
366 gl_view_hide_markup (GL_VIEW(window->view));
369 gl_ui_update_all (window->ui, GL_VIEW(window->view));
371 gl_ui_property_bar_set_view (window->property_bar, GL_VIEW(window->view));
372 gl_ui_sidebar_set_view (window->sidebar, GL_VIEW(window->view));
374 string = g_strdup_printf ("%3.0f%%",
375 100.0*gl_view_get_zoom (GL_VIEW(window->view)));
376 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
379 g_signal_connect (G_OBJECT(window->view), "selection_changed",
380 G_CALLBACK(selection_changed_cb), window);
382 g_signal_connect (G_OBJECT(window->view), "context_menu_activate",
383 G_CALLBACK(context_menu_activate_cb), window);
385 g_signal_connect (G_OBJECT(window->view), "zoom_changed",
386 G_CALLBACK(zoom_changed_cb), window);
388 g_signal_connect (G_OBJECT(window->view), "pointer_moved",
389 G_CALLBACK(pointer_moved_cb), window);
391 g_signal_connect (G_OBJECT(window->view), "pointer_exit",
392 G_CALLBACK(pointer_exit_cb), window);
394 g_signal_connect (G_OBJECT(label), "name_changed",
395 G_CALLBACK(name_changed_cb), window);
397 g_signal_connect (G_OBJECT(label), "modified_changed",
398 G_CALLBACK(modified_changed_cb), window);
400 gl_debug (DEBUG_WINDOW, "END");
403 /****************************************************************************/
404 /** Return list of glabels windows. */
405 /****************************************************************************/
407 gl_window_get_window_list (void)
409 gl_debug (DEBUG_WINDOW, "");
413 /*---------------------------------------------------------------------------*/
414 /** PRIVATE. Set window title based on name and state of label. */
415 /*---------------------------------------------------------------------------*/
417 set_window_title (glWindow *window,
422 gl_debug (DEBUG_WINDOW, "START");
424 g_return_if_fail (window && GL_IS_WINDOW (window));
425 g_return_if_fail (label && GL_IS_LABEL (label));
427 name = gl_label_get_short_name (label);
428 g_return_if_fail (name != NULL);
430 if (gl_label_is_modified (label)) {
431 title = g_strdup_printf ("%s %s - gLabels",
432 name, _("(modified)"));
434 title = g_strdup_printf ("%s - gLabels", name);
437 gtk_window_set_title (GTK_WINDOW(window), title);
442 gl_debug (DEBUG_WINDOW, "END");
445 /*-------------------------------------------------------------------------*/
446 /** PRIVATE. Window "delete-event" callback. */
447 /*-------------------------------------------------------------------------*/
449 window_delete_event_cb (glWindow *window,
453 gl_debug (DEBUG_WINDOW, "START");
455 g_return_val_if_fail (window && GL_IS_WINDOW (window), TRUE);
457 gl_file_close (window);
459 gl_debug (DEBUG_WINDOW, "END");
464 /*---------------------------------------------------------------------------*/
465 /** PRIVATE. View "selection state changed" callback. */
466 /*---------------------------------------------------------------------------*/
468 selection_changed_cb (glView *view,
471 gl_debug (DEBUG_WINDOW, "START");
473 g_return_if_fail (view && GL_IS_VIEW (view));
474 g_return_if_fail (window && GL_IS_WINDOW (window));
476 gl_ui_update_selection_verbs (window->ui, view);
478 gl_debug (DEBUG_WINDOW, "END");
481 /*---------------------------------------------------------------------------*/
482 /** PRIVATE. View "context menu activate" callback. */
483 /*---------------------------------------------------------------------------*/
485 context_menu_activate_cb (glView *view,
487 guint32 activate_time,
490 gl_debug (DEBUG_WINDOW, "START");
492 g_return_if_fail (view && GL_IS_VIEW (view));
493 g_return_if_fail (window && GL_IS_WINDOW (window));
495 if (gl_view_is_selection_empty (view)) {
497 gtk_menu_popup (GTK_MENU (window->empty_selection_context_menu),
498 NULL, NULL, NULL, NULL, button, activate_time);
502 gtk_menu_popup (GTK_MENU (window->context_menu),
503 NULL, NULL, NULL, NULL, button, activate_time);
507 gl_debug (DEBUG_WINDOW, "END");
510 /*---------------------------------------------------------------------------*/
511 /** PRIVATE. View "zoom state changed" callback. */
512 /*---------------------------------------------------------------------------*/
514 zoom_changed_cb (glView *view,
520 gl_debug (DEBUG_WINDOW, "START");
522 g_return_if_fail (view && GL_IS_VIEW (view));
523 g_return_if_fail (window && GL_IS_WINDOW (window));
525 string = g_strdup_printf ("%3.0f%%", 100.0*zoom);
526 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
529 gl_ui_update_zoom_verbs (window->ui, view);
531 gl_debug (DEBUG_WINDOW, "END");
534 /*---------------------------------------------------------------------------*/
535 /** PRIVATE. View "pointer moved" callback. */
536 /*---------------------------------------------------------------------------*/
538 pointer_moved_cb (glView *view,
544 gdouble units_per_point;
545 gint units_precision;
547 gl_debug (DEBUG_WINDOW, "START");
549 g_return_if_fail (view && GL_IS_VIEW (view));
550 g_return_if_fail (window && GL_IS_WINDOW (window));
552 units_per_point = gl_prefs_get_units_per_point ();
553 units_precision = gl_prefs_get_units_precision ();
555 string = g_strdup_printf ("%.*f, %.*f",
556 units_precision, x*units_per_point,
557 units_precision, y*units_per_point);
558 gtk_label_set_text (GTK_LABEL(window->cursor_info), string);
561 gl_debug (DEBUG_WINDOW, "END");
564 /*---------------------------------------------------------------------------*/
565 /** PRIVATE. View "pointer exit" callback. */
566 /*---------------------------------------------------------------------------*/
568 pointer_exit_cb (glView *view,
571 gl_debug (DEBUG_WINDOW, "START");
573 g_return_if_fail (view && GL_IS_VIEW (view));
574 g_return_if_fail (window && GL_IS_WINDOW (window));
576 gtk_label_set_text (GTK_LABEL(window->cursor_info), "");
578 gl_debug (DEBUG_WINDOW, "END");
581 /*---------------------------------------------------------------------------*/
582 /** PRIVATE. Label "name changed" callback. */
583 /*---------------------------------------------------------------------------*/
585 name_changed_cb (glLabel *label,
588 gl_debug (DEBUG_WINDOW, "START");
590 g_return_if_fail (label && GL_IS_LABEL (label));
591 g_return_if_fail (window && GL_IS_WINDOW (window));
593 set_window_title (window, label);
595 gl_debug (DEBUG_WINDOW, "END");
598 /*---------------------------------------------------------------------------*/
599 /** PRIVATE. Label "modified state changed" callback. */
600 /*---------------------------------------------------------------------------*/
602 modified_changed_cb (glLabel *label,
605 gl_debug (DEBUG_WINDOW, "START");
607 g_return_if_fail (label && GL_IS_LABEL (label));
608 g_return_if_fail (window && GL_IS_WINDOW (window));
610 set_window_title (window, label);
612 gl_ui_update_modified_verbs (window->ui, label);
614 gl_debug (DEBUG_WINDOW, "END");