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 zoom_changed_cb (glView *view,
86 static void pointer_moved_cb (glView *view,
91 static void pointer_exit_cb (glView *view,
94 static void name_changed_cb (glLabel *label,
97 static void modified_changed_cb (glLabel *label,
101 /****************************************************************************/
102 /* Boilerplate Object stuff. */
103 /****************************************************************************/
105 gl_window_get_type (void)
107 static GType type = 0;
110 static const GTypeInfo info = {
111 sizeof (glWindowClass),
114 (GClassInitFunc) gl_window_class_init,
119 (GInstanceInitFunc) gl_window_init,
123 type = g_type_register_static (GTK_TYPE_WINDOW,
124 "glWindow", &info, 0);
131 gl_window_class_init (glWindowClass *class)
133 GObjectClass *object_class = (GObjectClass *) class;
134 GtkObjectClass *gtk_object_class = (GtkObjectClass *) class;
136 gl_debug (DEBUG_WINDOW, "START");
138 parent_class = g_type_class_peek_parent (class);
140 object_class->finalize = gl_window_finalize;
142 gtk_object_class->destroy = gl_window_destroy;
144 gl_debug (DEBUG_WINDOW, "END");
148 gl_window_init (glWindow *window)
152 GtkWidget *status_hbox;
154 gl_debug (DEBUG_WINDOW, "START");
156 vbox1 = gtk_vbox_new (FALSE, 0);
157 gtk_container_add (GTK_CONTAINER (window), vbox1);
159 window->ui = ui = gl_ui_new (window);
160 gtk_box_pack_start (GTK_BOX (vbox1),
161 gtk_ui_manager_get_widget (ui, "/MenuBar"),
163 gtk_box_pack_start (GTK_BOX (vbox1),
164 gtk_ui_manager_get_widget (ui, "/MainToolBar"),
166 gtk_box_pack_start (GTK_BOX (vbox1),
167 gtk_ui_manager_get_widget (ui, "/DrawingToolBar"),
170 window->hbox = gtk_hbox_new (FALSE, 0);
171 gtk_box_pack_start (GTK_BOX (vbox1), window->hbox, TRUE, TRUE, 0);
173 window->sidebar = GL_UI_SIDEBAR (gl_ui_sidebar_new ());
174 gtk_box_pack_end (GTK_BOX (window->hbox), GTK_WIDGET (window->sidebar), FALSE, FALSE, 0);
176 window->property_bar = GL_UI_PROPERTY_BAR (gl_ui_property_bar_new ());
177 gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET (window->property_bar), FALSE, FALSE, 0);
179 status_hbox = gtk_hbox_new (FALSE, 0);
180 gtk_box_pack_start (GTK_BOX (vbox1), status_hbox, FALSE, FALSE, 0);
182 window->status_bar = gtk_statusbar_new ();
183 gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (window->status_bar), FALSE);
184 gtk_box_pack_start (GTK_BOX (status_hbox),
187 window->zoom_info = gtk_label_new (NULL);
188 gtk_widget_set_size_request (window->zoom_info, ZOOM_INFO_WIDTH, -1);
189 window->zoom_info_frame = gtk_frame_new (NULL);
190 gtk_frame_set_shadow_type (GTK_FRAME(window->zoom_info_frame), GTK_SHADOW_IN);
191 gtk_container_add (GTK_CONTAINER(window->zoom_info_frame), window->zoom_info);
192 gtk_widget_show_all (window->zoom_info_frame);
193 gtk_box_pack_end (GTK_BOX (status_hbox),
194 window->zoom_info_frame,
197 window->cursor_info = gtk_label_new (NULL);
198 gtk_widget_set_size_request (window->cursor_info, CURSOR_INFO_WIDTH, -1);
199 window->cursor_info_frame = gtk_frame_new (NULL);
200 gtk_frame_set_shadow_type (GTK_FRAME(window->cursor_info_frame), GTK_SHADOW_IN);
201 gtk_container_add (GTK_CONTAINER(window->cursor_info_frame), window->cursor_info);
202 gtk_widget_show_all (window->cursor_info_frame);
203 gtk_box_pack_end (GTK_BOX (status_hbox),
204 window->cursor_info_frame,
207 gtk_window_set_default_size (GTK_WINDOW (window),
208 DEFAULT_WINDOW_WIDTH,
209 DEFAULT_WINDOW_HEIGHT);
211 g_signal_connect (G_OBJECT(window), "delete-event",
212 G_CALLBACK(window_delete_event_cb), NULL);
214 window->menu_tips_context_id =
215 gtk_statusbar_get_context_id (GTK_STATUSBAR (window->status_bar), "menu_tips");
219 window_list = g_list_append (window_list, window);
221 gl_debug (DEBUG_WINDOW, "END");
225 gl_window_finalize (GObject *object)
229 gl_debug (DEBUG_WINDOW, "START");
231 g_return_if_fail (object != NULL);
232 g_return_if_fail (GL_IS_WINDOW (object));
234 window = GL_WINDOW (object);
236 G_OBJECT_CLASS (parent_class)->finalize (object);
238 gl_debug (DEBUG_WINDOW, "END");
242 gl_window_destroy (GtkObject *gtk_object)
246 gl_debug (DEBUG_WINDOW, "START");
248 g_return_if_fail (gtk_object != NULL);
249 g_return_if_fail (GL_IS_WINDOW (gtk_object));
251 window = GL_WINDOW (gtk_object);
252 window_list = g_list_remove (window_list, window);
255 gl_ui_unref(window->ui);
259 if (GTK_OBJECT_CLASS (parent_class)->destroy) {
260 GTK_OBJECT_CLASS (parent_class)->destroy (gtk_object);
263 gl_debug (DEBUG_WINDOW, "END");
267 /****************************************************************************/
268 /* Create an app window. */
269 /****************************************************************************/
275 gl_debug (DEBUG_WINDOW, "START");
277 window = g_object_new (GL_TYPE_WINDOW,
278 "title", _("(none) - gLabels"),
281 gl_debug (DEBUG_WINDOW, "window=%p", window);
282 gl_debug (DEBUG_WINDOW, "view=%p", window->view);
284 gl_debug (DEBUG_WINDOW, "END");
286 return GTK_WIDGET(window);
289 /****************************************************************************/
290 /* Create an app window from a label. */
291 /****************************************************************************/
293 gl_window_new_from_label (glLabel *label)
297 gl_debug (DEBUG_WINDOW, "START");
299 window = GL_WINDOW (gl_window_new ());
301 gl_window_set_label (window, label);
303 gl_debug (DEBUG_WINDOW, "END");
305 return GTK_WIDGET(window);
308 /****************************************************************************/
309 /* Create an app window from a file. */
310 /****************************************************************************/
312 gl_window_new_from_file (const gchar *filename)
317 glXMLLabelStatus status;
319 gl_debug (DEBUG_WINDOW, "START");
321 window = GL_WINDOW (gl_window_new ());
323 abs_filename = gl_util_make_absolute (filename);
324 label = gl_xml_label_open (abs_filename, &status);
325 g_free (abs_filename);
327 gl_window_set_label (window, label);
329 gl_debug (DEBUG_WINDOW, "END");
331 return GTK_WIDGET(window);
334 /****************************************************************************/
335 /* Is window empty? */
336 /****************************************************************************/
338 gl_window_is_empty (glWindow *window)
340 g_return_val_if_fail (GL_IS_WINDOW (window), FALSE);
342 gl_debug (DEBUG_WINDOW, "return %d", (window->view == NULL) );
343 return ( window->view == NULL );
346 /****************************************************************************/
347 /* Create view from label and place in window. */
348 /****************************************************************************/
350 gl_window_set_label (glWindow *window,
355 gl_debug (DEBUG_WINDOW, "START");
357 g_return_if_fail (GL_IS_WINDOW (window));
358 g_return_if_fail (GL_IS_LABEL (label));
360 gl_label_clear_modified (label);
362 set_window_title (window, label);
364 if ( window->view != NULL ) {
365 gtk_widget_destroy (window->view);
369 window->view = gl_view_new (label);
370 gtk_box_pack_start (GTK_BOX (window->hbox), window->view,TRUE, TRUE, 0);
372 gtk_widget_show_all (window->view);
374 gl_view_zoom_to_fit (GL_VIEW(window->view));
376 if (gl_prefs->grid_visible) {
377 gl_view_show_grid (GL_VIEW(window->view));
379 gl_view_hide_grid (GL_VIEW(window->view));
382 if (gl_prefs->markup_visible) {
383 gl_view_show_markup (GL_VIEW(window->view));
385 gl_view_hide_markup (GL_VIEW(window->view));
388 gl_ui_update_all (window->ui, GL_VIEW(window->view));
390 gl_ui_property_bar_set_view (window->property_bar, GL_VIEW(window->view));
391 gl_ui_sidebar_set_view (window->sidebar, GL_VIEW(window->view));
393 string = g_strdup_printf ("%3.0f%%",
394 100.0*gl_view_get_zoom (GL_VIEW(window->view)));
395 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
398 g_signal_connect (G_OBJECT(window->view), "selection_changed",
399 G_CALLBACK(selection_changed_cb), window);
401 g_signal_connect (G_OBJECT(window->view), "zoom_changed",
402 G_CALLBACK(zoom_changed_cb), window);
404 g_signal_connect (G_OBJECT(window->view), "pointer_moved",
405 G_CALLBACK(pointer_moved_cb), window);
407 g_signal_connect (G_OBJECT(window->view), "pointer_exit",
408 G_CALLBACK(pointer_exit_cb), window);
410 g_signal_connect (G_OBJECT(label), "name_changed",
411 G_CALLBACK(name_changed_cb), window);
413 g_signal_connect (G_OBJECT(label), "modified_changed",
414 G_CALLBACK(modified_changed_cb), window);
416 gl_debug (DEBUG_WINDOW, "END");
419 /****************************************************************************/
420 /* Return list of app windows. */
421 /****************************************************************************/
423 gl_window_get_window_list (void)
425 gl_debug (DEBUG_WINDOW, "");
429 /*---------------------------------------------------------------------------*/
430 /* PRIVATE. Set window title based on name and state of label. */
431 /*---------------------------------------------------------------------------*/
433 set_window_title (glWindow *window,
438 gl_debug (DEBUG_WINDOW, "START");
440 g_return_if_fail (window && GL_IS_WINDOW (window));
441 g_return_if_fail (label && GL_IS_LABEL (label));
443 name = gl_label_get_short_name (label);
444 g_return_if_fail (name != NULL);
446 if (gl_label_is_modified (label)) {
447 title = g_strdup_printf ("%s %s - gLabels",
448 name, _("(modified)"));
450 title = g_strdup_printf ("%s - gLabels", name);
453 gtk_window_set_title (GTK_WINDOW(window), title);
458 gl_debug (DEBUG_WINDOW, "END");
461 /*-------------------------------------------------------------------------*/
462 /* PRIVATE. Window "delete-event" callback. */
463 /*-------------------------------------------------------------------------*/
465 window_delete_event_cb (glWindow *window,
469 gl_debug (DEBUG_WINDOW, "START");
471 g_return_val_if_fail (window && GL_IS_WINDOW (window), TRUE);
473 gl_file_close (window);
475 gl_debug (DEBUG_WINDOW, "END");
480 /*---------------------------------------------------------------------------*/
481 /* PRIVATE. View "selection state changed" callback. */
482 /*---------------------------------------------------------------------------*/
484 selection_changed_cb (glView *view,
487 gl_debug (DEBUG_WINDOW, "START");
489 g_return_if_fail (view && GL_IS_VIEW (view));
490 g_return_if_fail (window && GL_IS_WINDOW (window));
492 gl_ui_update_selection_verbs (window->ui, view);
494 gl_debug (DEBUG_WINDOW, "END");
497 /*---------------------------------------------------------------------------*/
498 /* PRIVATE. View "zoom state changed" callback. */
499 /*---------------------------------------------------------------------------*/
501 zoom_changed_cb (glView *view,
507 gl_debug (DEBUG_WINDOW, "START");
509 g_return_if_fail (view && GL_IS_VIEW (view));
510 g_return_if_fail (window && GL_IS_WINDOW (window));
512 string = g_strdup_printf ("%3.0f%%", 100.0*zoom);
513 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
516 gl_ui_update_zoom_verbs (window->ui, view);
518 gl_debug (DEBUG_WINDOW, "END");
521 /*---------------------------------------------------------------------------*/
522 /* PRIVATE. View "pointer moved" callback. */
523 /*---------------------------------------------------------------------------*/
525 pointer_moved_cb (glView *view,
531 gdouble units_per_point;
532 gint units_precision;
534 gl_debug (DEBUG_WINDOW, "START");
536 g_return_if_fail (view && GL_IS_VIEW (view));
537 g_return_if_fail (window && GL_IS_WINDOW (window));
539 units_per_point = gl_prefs_get_units_per_point ();
540 units_precision = gl_prefs_get_units_precision ();
542 string = g_strdup_printf ("%.*f, %.*f",
543 units_precision, x*units_per_point,
544 units_precision, y*units_per_point);
545 gtk_label_set_text (GTK_LABEL(window->cursor_info), string);
548 gl_debug (DEBUG_WINDOW, "END");
551 /*---------------------------------------------------------------------------*/
552 /* PRIVATE. View "pointer exit" callback. */
553 /*---------------------------------------------------------------------------*/
555 pointer_exit_cb (glView *view,
558 gl_debug (DEBUG_WINDOW, "START");
560 g_return_if_fail (view && GL_IS_VIEW (view));
561 g_return_if_fail (window && GL_IS_WINDOW (window));
563 gtk_label_set_text (GTK_LABEL(window->cursor_info), "");
565 gl_debug (DEBUG_WINDOW, "END");
568 /*---------------------------------------------------------------------------*/
569 /* PRIVATE. Label "name changed" callback. */
570 /*---------------------------------------------------------------------------*/
572 name_changed_cb (glLabel *label,
575 gl_debug (DEBUG_WINDOW, "START");
577 g_return_if_fail (label && GL_IS_LABEL (label));
578 g_return_if_fail (window && GL_IS_WINDOW (window));
580 set_window_title (window, label);
582 gl_debug (DEBUG_WINDOW, "END");
585 /*---------------------------------------------------------------------------*/
586 /* PRIVATE. Label "modified state changed" callback. */
587 /*---------------------------------------------------------------------------*/
589 modified_changed_cb (glLabel *label,
592 gl_debug (DEBUG_WINDOW, "START");
594 g_return_if_fail (label && GL_IS_LABEL (label));
595 g_return_if_fail (window && GL_IS_WINDOW (window));
597 set_window_title (window, label);
599 gl_ui_update_modified_verbs (window->ui, label);
601 gl_debug (DEBUG_WINDOW, "END");