1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; 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 /*============================================================================*/
58 static GtkWindowClass *parent_class;
60 static GList *window_list = NULL;
63 /*============================================================================*/
64 /* Local function prototypes */
65 /*============================================================================*/
67 static void gl_window_class_init (glWindowClass *class);
68 static void gl_window_init (glWindow *window);
69 static void gl_window_finalize (GObject *object);
70 static void gl_window_destroy (GtkObject *gtk_object);
72 static void set_window_title (glWindow *window,
75 static gboolean window_delete_event_cb (glWindow *window,
79 static void selection_changed_cb (glView *view,
82 static void context_menu_activate_cb (glView *view,
84 guint32 activate_time,
87 static void zoom_changed_cb (glView *view,
91 static void pointer_moved_cb (glView *view,
96 static void pointer_exit_cb (glView *view,
99 static void name_changed_cb (glLabel *label,
102 static void modified_changed_cb (glLabel *label,
106 /****************************************************************************/
107 /* Boilerplate Object stuff. */
108 /****************************************************************************/
110 gl_window_get_type (void)
112 static GType type = 0;
115 static const GTypeInfo info = {
116 sizeof (glWindowClass),
119 (GClassInitFunc) gl_window_class_init,
124 (GInstanceInitFunc) gl_window_init,
128 type = g_type_register_static (GTK_TYPE_WINDOW,
129 "glWindow", &info, 0);
136 gl_window_class_init (glWindowClass *class)
138 GObjectClass *object_class = (GObjectClass *) class;
139 GtkObjectClass *gtk_object_class = (GtkObjectClass *) class;
141 gl_debug (DEBUG_WINDOW, "START");
143 parent_class = g_type_class_peek_parent (class);
145 object_class->finalize = gl_window_finalize;
147 gtk_object_class->destroy = gl_window_destroy;
149 gl_debug (DEBUG_WINDOW, "END");
153 gl_window_init (glWindow *window)
157 GtkWidget *status_hbox;
159 gl_debug (DEBUG_WINDOW, "START");
161 vbox1 = gtk_vbox_new (FALSE, 0);
162 gtk_container_add (GTK_CONTAINER (window), vbox1);
164 window->ui = ui = gl_ui_new (window);
165 gtk_box_pack_start (GTK_BOX (vbox1),
166 gtk_ui_manager_get_widget (ui, "/MenuBar"),
168 gtk_box_pack_start (GTK_BOX (vbox1),
169 gtk_ui_manager_get_widget (ui, "/MainToolBar"),
171 gtk_box_pack_start (GTK_BOX (vbox1),
172 gtk_ui_manager_get_widget (ui, "/DrawingToolBar"),
175 window->hbox = gtk_hbox_new (FALSE, 0);
176 gtk_box_pack_start (GTK_BOX (vbox1), window->hbox, TRUE, TRUE, 0);
178 window->sidebar = GL_UI_SIDEBAR (gl_ui_sidebar_new ());
179 gtk_box_pack_end (GTK_BOX (window->hbox), GTK_WIDGET (window->sidebar), FALSE, FALSE, 0);
181 window->property_bar = GL_UI_PROPERTY_BAR (gl_ui_property_bar_new ());
182 gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET (window->property_bar), FALSE, FALSE, 0);
184 status_hbox = gtk_hbox_new (FALSE, 0);
185 gtk_box_pack_start (GTK_BOX (vbox1), status_hbox, FALSE, FALSE, 0);
187 window->status_bar = gtk_statusbar_new ();
188 gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (window->status_bar), FALSE);
189 gtk_box_pack_start (GTK_BOX (status_hbox),
192 window->zoom_info = gtk_label_new (NULL);
193 gtk_widget_set_size_request (window->zoom_info, ZOOM_INFO_WIDTH, -1);
194 window->zoom_info_frame = gtk_frame_new (NULL);
195 gtk_frame_set_shadow_type (GTK_FRAME(window->zoom_info_frame), GTK_SHADOW_IN);
196 gtk_container_add (GTK_CONTAINER(window->zoom_info_frame), window->zoom_info);
197 gtk_widget_show_all (window->zoom_info_frame);
198 gtk_box_pack_end (GTK_BOX (status_hbox),
199 window->zoom_info_frame,
202 window->cursor_info = gtk_label_new (NULL);
203 gtk_widget_set_size_request (window->cursor_info, CURSOR_INFO_WIDTH, -1);
204 window->cursor_info_frame = gtk_frame_new (NULL);
205 gtk_frame_set_shadow_type (GTK_FRAME(window->cursor_info_frame), GTK_SHADOW_IN);
206 gtk_container_add (GTK_CONTAINER(window->cursor_info_frame), window->cursor_info);
207 gtk_widget_show_all (window->cursor_info_frame);
208 gtk_box_pack_end (GTK_BOX (status_hbox),
209 window->cursor_info_frame,
212 gtk_window_set_default_size (GTK_WINDOW (window),
213 DEFAULT_WINDOW_WIDTH,
214 DEFAULT_WINDOW_HEIGHT);
216 g_signal_connect (G_OBJECT(window), "delete-event",
217 G_CALLBACK(window_delete_event_cb), NULL);
219 window->menu_tips_context_id =
220 gtk_statusbar_get_context_id (GTK_STATUSBAR (window->status_bar), "menu_tips");
222 window->print_dialog = NULL;
223 window->merge_dialog = NULL;
224 window->context_menu = GTK_MENU (gtk_ui_manager_get_widget (ui, "/ContextMenu"));
225 window->empty_selection_context_menu =
226 GTK_MENU (gtk_ui_manager_get_widget (ui, "/EmptySelectionContextMenu"));
230 window_list = g_list_append (window_list, window);
232 gl_debug (DEBUG_WINDOW, "END");
236 gl_window_finalize (GObject *object)
240 gl_debug (DEBUG_WINDOW, "START");
242 g_return_if_fail (object != NULL);
243 g_return_if_fail (GL_IS_WINDOW (object));
245 window = GL_WINDOW (object);
247 G_OBJECT_CLASS (parent_class)->finalize (object);
249 gl_debug (DEBUG_WINDOW, "END");
253 gl_window_destroy (GtkObject *gtk_object)
257 gl_debug (DEBUG_WINDOW, "START");
259 g_return_if_fail (gtk_object != NULL);
260 g_return_if_fail (GL_IS_WINDOW (gtk_object));
262 window = GL_WINDOW (gtk_object);
263 window_list = g_list_remove (window_list, window);
266 gl_ui_unref(window->ui);
270 if (GTK_OBJECT_CLASS (parent_class)->destroy) {
271 GTK_OBJECT_CLASS (parent_class)->destroy (gtk_object);
274 gl_debug (DEBUG_WINDOW, "END");
278 /****************************************************************************/
279 /** Create a glabels window. */
280 /****************************************************************************/
286 gl_debug (DEBUG_WINDOW, "START");
288 window = g_object_new (GL_TYPE_WINDOW,
289 "title", _("(none) - gLabels"),
292 gl_debug (DEBUG_WINDOW, "window=%p", window);
293 gl_debug (DEBUG_WINDOW, "view=%p", window->view);
295 gl_debug (DEBUG_WINDOW, "END");
297 return GTK_WIDGET(window);
300 /****************************************************************************/
301 /** Create a glabels window from a label. */
302 /****************************************************************************/
304 gl_window_new_from_label (glLabel *label)
308 gl_debug (DEBUG_WINDOW, "START");
310 window = GL_WINDOW (gl_window_new ());
312 gl_window_set_label (window, label);
314 gl_debug (DEBUG_WINDOW, "END");
316 return GTK_WIDGET(window);
319 /****************************************************************************/
320 /** Create a glabels window from a glabels file. */
321 /****************************************************************************/
323 gl_window_new_from_file (const gchar *filename)
328 glXMLLabelStatus status;
330 gl_debug (DEBUG_WINDOW, "START");
332 window = GL_WINDOW (gl_window_new ());
334 abs_filename = gl_util_make_absolute (filename);
335 label = gl_xml_label_open (abs_filename, &status);
336 g_free (abs_filename);
338 gl_window_set_label (window, label);
340 gl_debug (DEBUG_WINDOW, "END");
342 return GTK_WIDGET(window);
345 /****************************************************************************/
346 /** Is window empty? */
347 /****************************************************************************/
349 gl_window_is_empty (glWindow *window)
351 g_return_val_if_fail (GL_IS_WINDOW (window), FALSE);
353 gl_debug (DEBUG_WINDOW, "return %d", (window->view == NULL) );
354 return ( window->view == NULL );
357 /****************************************************************************/
358 /** Create view from label and place in window. */
359 /****************************************************************************/
361 gl_window_set_label (glWindow *window,
366 gl_debug (DEBUG_WINDOW, "START");
368 g_return_if_fail (GL_IS_WINDOW (window));
369 g_return_if_fail (GL_IS_LABEL (label));
371 gl_label_clear_modified (label);
373 set_window_title (window, label);
375 if ( window->view != NULL ) {
376 gtk_widget_destroy (window->view);
380 window->view = gl_view_new (label);
381 gtk_box_pack_start (GTK_BOX (window->hbox), window->view,TRUE, TRUE, 0);
383 gtk_widget_show_all (window->view);
385 gl_view_zoom_to_fit (GL_VIEW(window->view));
387 if (gl_prefs->grid_visible) {
388 gl_view_show_grid (GL_VIEW(window->view));
390 gl_view_hide_grid (GL_VIEW(window->view));
393 if (gl_prefs->markup_visible) {
394 gl_view_show_markup (GL_VIEW(window->view));
396 gl_view_hide_markup (GL_VIEW(window->view));
399 gl_ui_update_all (window->ui, GL_VIEW(window->view));
401 gl_ui_property_bar_set_view (window->property_bar, GL_VIEW(window->view));
402 gl_ui_sidebar_set_view (window->sidebar, GL_VIEW(window->view));
404 string = g_strdup_printf ("%3.0f%%",
405 100.0*gl_view_get_zoom (GL_VIEW(window->view)));
406 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
409 g_signal_connect (G_OBJECT(window->view), "selection_changed",
410 G_CALLBACK(selection_changed_cb), window);
412 g_signal_connect (G_OBJECT(window->view), "context_menu_activate",
413 G_CALLBACK(context_menu_activate_cb), window);
415 g_signal_connect (G_OBJECT(window->view), "zoom_changed",
416 G_CALLBACK(zoom_changed_cb), window);
418 g_signal_connect (G_OBJECT(window->view), "pointer_moved",
419 G_CALLBACK(pointer_moved_cb), window);
421 g_signal_connect (G_OBJECT(window->view), "pointer_exit",
422 G_CALLBACK(pointer_exit_cb), window);
424 g_signal_connect (G_OBJECT(label), "name_changed",
425 G_CALLBACK(name_changed_cb), window);
427 g_signal_connect (G_OBJECT(label), "modified_changed",
428 G_CALLBACK(modified_changed_cb), window);
430 gl_debug (DEBUG_WINDOW, "END");
433 /****************************************************************************/
434 /** Return list of glabels windows. */
435 /****************************************************************************/
437 gl_window_get_window_list (void)
439 gl_debug (DEBUG_WINDOW, "");
443 /*---------------------------------------------------------------------------*/
444 /** PRIVATE. Set window title based on name and state of label. */
445 /*---------------------------------------------------------------------------*/
447 set_window_title (glWindow *window,
452 gl_debug (DEBUG_WINDOW, "START");
454 g_return_if_fail (window && GL_IS_WINDOW (window));
455 g_return_if_fail (label && GL_IS_LABEL (label));
457 name = gl_label_get_short_name (label);
458 g_return_if_fail (name != NULL);
460 if (gl_label_is_modified (label)) {
461 title = g_strdup_printf ("%s %s - gLabels",
462 name, _("(modified)"));
464 title = g_strdup_printf ("%s - gLabels", name);
467 gtk_window_set_title (GTK_WINDOW(window), title);
472 gl_debug (DEBUG_WINDOW, "END");
475 /*-------------------------------------------------------------------------*/
476 /** PRIVATE. Window "delete-event" callback. */
477 /*-------------------------------------------------------------------------*/
479 window_delete_event_cb (glWindow *window,
483 gl_debug (DEBUG_WINDOW, "START");
485 g_return_val_if_fail (window && GL_IS_WINDOW (window), TRUE);
487 gl_file_close (window);
489 gl_debug (DEBUG_WINDOW, "END");
494 /*---------------------------------------------------------------------------*/
495 /** PRIVATE. View "selection state changed" callback. */
496 /*---------------------------------------------------------------------------*/
498 selection_changed_cb (glView *view,
501 gl_debug (DEBUG_WINDOW, "START");
503 g_return_if_fail (view && GL_IS_VIEW (view));
504 g_return_if_fail (window && GL_IS_WINDOW (window));
506 gl_ui_update_selection_verbs (window->ui, view);
508 gl_debug (DEBUG_WINDOW, "END");
511 /*---------------------------------------------------------------------------*/
512 /** PRIVATE. View "context menu activate" callback. */
513 /*---------------------------------------------------------------------------*/
515 context_menu_activate_cb (glView *view,
517 guint32 activate_time,
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 if (gl_view_is_selection_empty (view)) {
527 gtk_menu_popup (GTK_MENU (window->empty_selection_context_menu),
528 NULL, NULL, NULL, NULL, button, activate_time);
532 gtk_menu_popup (GTK_MENU (window->context_menu),
533 NULL, NULL, NULL, NULL, button, activate_time);
537 gl_debug (DEBUG_WINDOW, "END");
540 /*---------------------------------------------------------------------------*/
541 /** PRIVATE. View "zoom state changed" callback. */
542 /*---------------------------------------------------------------------------*/
544 zoom_changed_cb (glView *view,
550 gl_debug (DEBUG_WINDOW, "START");
552 g_return_if_fail (view && GL_IS_VIEW (view));
553 g_return_if_fail (window && GL_IS_WINDOW (window));
555 string = g_strdup_printf ("%3.0f%%", 100.0*zoom);
556 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
559 gl_ui_update_zoom_verbs (window->ui, view);
561 gl_debug (DEBUG_WINDOW, "END");
564 /*---------------------------------------------------------------------------*/
565 /** PRIVATE. View "pointer moved" callback. */
566 /*---------------------------------------------------------------------------*/
568 pointer_moved_cb (glView *view,
574 gdouble units_per_point;
575 gint units_precision;
577 gl_debug (DEBUG_WINDOW, "START");
579 g_return_if_fail (view && GL_IS_VIEW (view));
580 g_return_if_fail (window && GL_IS_WINDOW (window));
582 units_per_point = gl_prefs_get_units_per_point ();
583 units_precision = gl_prefs_get_units_precision ();
585 string = g_strdup_printf ("%.*f, %.*f",
586 units_precision, x*units_per_point,
587 units_precision, y*units_per_point);
588 gtk_label_set_text (GTK_LABEL(window->cursor_info), string);
591 gl_debug (DEBUG_WINDOW, "END");
594 /*---------------------------------------------------------------------------*/
595 /** PRIVATE. View "pointer exit" callback. */
596 /*---------------------------------------------------------------------------*/
598 pointer_exit_cb (glView *view,
601 gl_debug (DEBUG_WINDOW, "START");
603 g_return_if_fail (view && GL_IS_VIEW (view));
604 g_return_if_fail (window && GL_IS_WINDOW (window));
606 gtk_label_set_text (GTK_LABEL(window->cursor_info), "");
608 gl_debug (DEBUG_WINDOW, "END");
611 /*---------------------------------------------------------------------------*/
612 /** PRIVATE. Label "name changed" callback. */
613 /*---------------------------------------------------------------------------*/
615 name_changed_cb (glLabel *label,
618 gl_debug (DEBUG_WINDOW, "START");
620 g_return_if_fail (label && GL_IS_LABEL (label));
621 g_return_if_fail (window && GL_IS_WINDOW (window));
623 set_window_title (window, label);
625 gl_debug (DEBUG_WINDOW, "END");
628 /*---------------------------------------------------------------------------*/
629 /** PRIVATE. Label "modified state changed" callback. */
630 /*---------------------------------------------------------------------------*/
632 modified_changed_cb (glLabel *label,
635 gl_debug (DEBUG_WINDOW, "START");
637 g_return_if_fail (label && GL_IS_LABEL (label));
638 g_return_if_fail (window && GL_IS_WINDOW (window));
640 set_window_title (window, label);
642 gl_ui_update_modified_verbs (window->ui, label);
644 gl_debug (DEBUG_WINDOW, "END");