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>
36 #include "ui-commands.h"
38 #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,
100 static char *recent_tooltip_func (EggRecentItem *item,
104 /****************************************************************************/
105 /* Boilerplate Object stuff. */
106 /****************************************************************************/
108 gl_window_get_type (void)
110 static GType type = 0;
113 static const GTypeInfo info = {
114 sizeof (glWindowClass),
117 (GClassInitFunc) gl_window_class_init,
122 (GInstanceInitFunc) gl_window_init,
126 type = g_type_register_static (GTK_TYPE_WINDOW,
127 "glWindow", &info, 0);
134 gl_window_class_init (glWindowClass *class)
136 GObjectClass *object_class = (GObjectClass *) class;
137 GtkObjectClass *gtk_object_class = (GtkObjectClass *) class;
139 gl_debug (DEBUG_WINDOW, "START");
141 parent_class = g_type_class_peek_parent (class);
143 object_class->finalize = gl_window_finalize;
145 gtk_object_class->destroy = gl_window_destroy;
147 gl_debug (DEBUG_WINDOW, "END");
151 gl_window_init (glWindow *window)
155 GtkWidget *status_hbox;
157 gl_debug (DEBUG_WINDOW, "START");
159 vbox1 = gtk_vbox_new (FALSE, 0);
160 gtk_container_add (GTK_CONTAINER (window), vbox1);
162 window->ui = ui = gl_ui_new (GTK_WINDOW (window));
163 gtk_box_pack_start (GTK_BOX (vbox1),
164 gtk_ui_manager_get_widget (ui, "/MenuBar"),
166 gtk_box_pack_start (GTK_BOX (vbox1),
167 gtk_ui_manager_get_widget (ui, "/MainToolBar"),
169 gtk_box_pack_start (GTK_BOX (vbox1),
170 gtk_ui_manager_get_widget (ui, "/DrawingToolBar"),
173 /* add an eggRecentView */
174 window->recent_view =
175 egg_recent_view_uimanager_new (ui,
176 "/ui/MenuBar/FileMenu/FileRecentsMenu/FileRecentsPlaceHolder",
177 G_CALLBACK (gl_ui_cmd_file_open_recent),
179 egg_recent_view_uimanager_show_icons (window->recent_view, FALSE);
180 egg_recent_view_uimanager_set_tooltip_func (window->recent_view,
183 egg_recent_view_set_model (EGG_RECENT_VIEW (window->recent_view),
184 gl_recent_get_model ());
187 window->hbox = gtk_hbox_new (FALSE, 0);
188 gtk_box_pack_start (GTK_BOX (vbox1), window->hbox, TRUE, TRUE, 0);
190 window->sidebar = GL_UI_SIDEBAR (gl_ui_sidebar_new ());
191 gtk_box_pack_end (GTK_BOX (window->hbox), GTK_WIDGET (window->sidebar), FALSE, FALSE, 0);
193 window->property_bar = GL_UI_PROPERTY_BAR (gl_ui_property_bar_new ());
194 gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET (window->property_bar), FALSE, FALSE, 0);
196 status_hbox = gtk_hbox_new (FALSE, 0);
197 gtk_box_pack_start (GTK_BOX (vbox1), status_hbox, FALSE, FALSE, 0);
199 window->zoom_info = gtk_label_new (NULL);
200 gtk_widget_set_size_request (window->zoom_info, ZOOM_INFO_WIDTH, -1);
201 window->zoom_info_frame = gtk_frame_new (NULL);
202 gtk_frame_set_shadow_type (GTK_FRAME(window->zoom_info_frame), GTK_SHADOW_IN);
203 gtk_container_add (GTK_CONTAINER(window->zoom_info_frame), window->zoom_info);
204 gtk_widget_show_all (window->zoom_info_frame);
205 gtk_box_pack_end (GTK_BOX (status_hbox),
206 window->zoom_info_frame,
209 window->cursor_info = gtk_label_new (NULL);
210 gtk_widget_set_size_request (window->cursor_info, CURSOR_INFO_WIDTH, -1);
211 window->cursor_info_frame = gtk_frame_new (NULL);
212 gtk_frame_set_shadow_type (GTK_FRAME(window->cursor_info_frame), GTK_SHADOW_IN);
213 gtk_container_add (GTK_CONTAINER(window->cursor_info_frame), window->cursor_info);
214 gtk_widget_show_all (window->cursor_info_frame);
215 gtk_box_pack_end (GTK_BOX (status_hbox),
216 window->cursor_info_frame,
219 gtk_window_set_default_size (GTK_WINDOW (window),
220 DEFAULT_WINDOW_WIDTH,
221 DEFAULT_WINDOW_HEIGHT);
223 g_signal_connect (G_OBJECT(window), "delete-event",
224 G_CALLBACK(window_delete_event_cb), NULL);
228 window_list = g_list_append (window_list, window);
230 gl_debug (DEBUG_WINDOW, "END");
234 gl_window_finalize (GObject *object)
238 gl_debug (DEBUG_WINDOW, "START");
240 g_return_if_fail (object != NULL);
241 g_return_if_fail (GL_IS_WINDOW (object));
243 window = GL_WINDOW (object);
245 G_OBJECT_CLASS (parent_class)->finalize (object);
247 gl_debug (DEBUG_WINDOW, "END");
251 gl_window_destroy (GtkObject *gtk_object)
255 gl_debug (DEBUG_WINDOW, "START");
257 g_return_if_fail (gtk_object != NULL);
258 g_return_if_fail (GL_IS_WINDOW (gtk_object));
260 window = GL_WINDOW (gtk_object);
261 window_list = g_list_remove (window_list, window);
263 if (window->recent_view) {
264 g_object_unref (window->recent_view);
265 window->recent_view = NULL;
269 gl_ui_unref(window->ui);
273 if (GTK_OBJECT_CLASS (parent_class)->destroy) {
274 GTK_OBJECT_CLASS (parent_class)->destroy (gtk_object);
277 gl_debug (DEBUG_WINDOW, "END");
281 /****************************************************************************/
282 /* Create an app window. */
283 /****************************************************************************/
289 gl_debug (DEBUG_WINDOW, "START");
291 window = g_object_new (GL_TYPE_WINDOW,
292 "title", _("(none) - gLabels"),
295 gl_debug (DEBUG_WINDOW, "window=%p", window);
296 gl_debug (DEBUG_WINDOW, "view=%p", window->view);
298 gl_debug (DEBUG_WINDOW, "END");
300 return GTK_WIDGET(window);
303 /****************************************************************************/
304 /* Create an app window from a label. */
305 /****************************************************************************/
307 gl_window_new_from_label (glLabel *label)
311 gl_debug (DEBUG_WINDOW, "START");
313 window = GL_WINDOW (gl_window_new ());
315 gl_window_set_label (window, label);
317 gl_debug (DEBUG_WINDOW, "END");
319 return GTK_WIDGET(window);
322 /****************************************************************************/
323 /* Create an app window from a file. */
324 /****************************************************************************/
326 gl_window_new_from_file (const gchar *filename)
331 glXMLLabelStatus status;
333 gl_debug (DEBUG_WINDOW, "START");
335 window = GL_WINDOW (gl_window_new ());
337 abs_filename = gl_util_make_absolute (filename);
338 label = gl_xml_label_open (abs_filename, &status);
339 g_free (abs_filename);
341 gl_window_set_label (window, label);
343 gl_debug (DEBUG_WINDOW, "END");
345 return GTK_WIDGET(window);
348 /****************************************************************************/
349 /* Is window empty? */
350 /****************************************************************************/
352 gl_window_is_empty (glWindow *window)
354 g_return_val_if_fail (GL_IS_WINDOW (window), FALSE);
356 gl_debug (DEBUG_WINDOW, "return %d", (window->view == NULL) );
357 return ( window->view == NULL );
360 /****************************************************************************/
361 /* Create view from label and place in window. */
362 /****************************************************************************/
364 gl_window_set_label (glWindow *window,
369 gl_debug (DEBUG_WINDOW, "START");
371 g_return_if_fail (GL_IS_WINDOW (window));
372 g_return_if_fail (GL_IS_LABEL (label));
374 gl_label_clear_modified (label);
376 set_window_title (window, label);
378 if ( window->view != NULL ) {
379 gtk_widget_destroy (window->view);
383 window->view = gl_view_new (label);
384 gtk_box_pack_start (GTK_BOX (window->hbox), window->view,TRUE, TRUE, 0);
386 gtk_widget_show_all (window->view);
388 gl_view_zoom_to_fit (GL_VIEW(window->view));
390 if (gl_prefs->grid_visible) {
391 gl_view_show_grid (GL_VIEW(window->view));
393 gl_view_hide_grid (GL_VIEW(window->view));
396 if (gl_prefs->markup_visible) {
397 gl_view_show_markup (GL_VIEW(window->view));
399 gl_view_hide_markup (GL_VIEW(window->view));
402 gl_ui_update_all (window->ui, GL_VIEW(window->view));
404 gl_ui_property_bar_set_view (window->property_bar, GL_VIEW(window->view));
405 gl_ui_sidebar_set_view (window->sidebar, GL_VIEW(window->view));
407 string = g_strdup_printf ("%3.0f%%",
408 100.0*gl_view_get_zoom (GL_VIEW(window->view)));
409 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
412 g_signal_connect (G_OBJECT(window->view), "selection_changed",
413 G_CALLBACK(selection_changed_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 app 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 "zoom state changed" callback. */
513 /*---------------------------------------------------------------------------*/
515 zoom_changed_cb (glView *view,
521 gl_debug (DEBUG_WINDOW, "START");
523 g_return_if_fail (view && GL_IS_VIEW (view));
524 g_return_if_fail (window && GL_IS_WINDOW (window));
526 string = g_strdup_printf ("%3.0f%%", 100.0*zoom);
527 gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
530 gl_ui_update_zoom_verbs (window->ui, view);
532 gl_debug (DEBUG_WINDOW, "END");
535 /*---------------------------------------------------------------------------*/
536 /* PRIVATE. View "pointer moved" callback. */
537 /*---------------------------------------------------------------------------*/
539 pointer_moved_cb (glView *view,
545 gdouble units_per_point;
546 gint units_precision;
548 gl_debug (DEBUG_WINDOW, "START");
550 g_return_if_fail (view && GL_IS_VIEW (view));
551 g_return_if_fail (window && GL_IS_WINDOW (window));
553 units_per_point = gl_prefs_get_units_per_point ();
554 units_precision = gl_prefs_get_units_precision ();
556 string = g_strdup_printf ("%.*f, %.*f",
557 units_precision, x*units_per_point,
558 units_precision, y*units_per_point);
559 gtk_label_set_text (GTK_LABEL(window->cursor_info), string);
562 gl_debug (DEBUG_WINDOW, "END");
565 /*---------------------------------------------------------------------------*/
566 /* PRIVATE. View "pointer exit" callback. */
567 /*---------------------------------------------------------------------------*/
569 pointer_exit_cb (glView *view,
572 gl_debug (DEBUG_WINDOW, "START");
574 g_return_if_fail (view && GL_IS_VIEW (view));
575 g_return_if_fail (window && GL_IS_WINDOW (window));
577 gtk_label_set_text (GTK_LABEL(window->cursor_info), "");
579 gl_debug (DEBUG_WINDOW, "END");
582 /*---------------------------------------------------------------------------*/
583 /* PRIVATE. Label "name changed" callback. */
584 /*---------------------------------------------------------------------------*/
586 name_changed_cb (glLabel *label,
589 gl_debug (DEBUG_WINDOW, "START");
591 g_return_if_fail (label && GL_IS_LABEL (label));
592 g_return_if_fail (window && GL_IS_WINDOW (window));
594 set_window_title (window, label);
596 gl_debug (DEBUG_WINDOW, "END");
599 /*---------------------------------------------------------------------------*/
600 /* PRIVATE. Label "modified state changed" callback. */
601 /*---------------------------------------------------------------------------*/
603 modified_changed_cb (glLabel *label,
606 gl_debug (DEBUG_WINDOW, "START");
608 g_return_if_fail (label && GL_IS_LABEL (label));
609 g_return_if_fail (window && GL_IS_WINDOW (window));
611 set_window_title (window, label);
613 gl_ui_update_modified_verbs (window->ui, label);
615 gl_debug (DEBUG_WINDOW, "END");
618 /*---------------------------------------------------------------------------*/
619 /* PRIVATE. Tooltip function for recent file menu items. */
620 /*---------------------------------------------------------------------------*/
622 recent_tooltip_func (EggRecentItem *item, gpointer user_data)
625 char *uri_for_display;
627 uri_for_display = egg_recent_item_get_uri_for_display (item);
628 g_return_val_if_fail (uri_for_display != NULL, NULL);
630 tip = g_strdup_printf (_("Open '%s'"), uri_for_display);
632 g_free (uri_for_display);