]> git.sur5r.net Git - glabels/blob - glabels2/src/window.c
Added grid to view.
[glabels] / glabels2 / src / window.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  window.c:  a gLabels app window
5  *
6  *  Copyright (C) 2002  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <config.h>
24
25 #include "ui.h"
26 #include "window.h"
27 #include "util.h"
28 #include "xml-label.h"
29 #include "prefs.h"
30
31 #include "debug.h"
32
33 /*============================================================================*/
34 /* Private macros and constants.                                              */
35 /*============================================================================*/
36
37 #define DEFAULT_WINDOW_WIDTH  500
38 #define DEFAULT_WINDOW_HEIGHT 375
39
40 #define CURSOR_INFO_WIDTH     150
41 #define ZOOM_INFO_WIDTH        50
42
43 /*============================================================================*/
44 /* Private globals                                                            */
45 /*============================================================================*/
46 static BonoboWindowClass *parent_class;
47
48 static GList *window_list = NULL;
49
50
51 /*============================================================================*/
52 /* Local function prototypes                                                  */
53 /*============================================================================*/
54
55 static void     gl_window_class_init   (glWindowClass *class);
56 static void     gl_window_init         (glWindow      *window);
57 static void     gl_window_finalize     (GObject       *object);
58 static void     gl_window_destroy      (GtkObject     *gtk_object);
59
60 static void     set_window_title       (glWindow *window,
61                                         glLabel  *label);
62
63 static gboolean window_delete_event_cb (glWindow      *window,
64                                         GdkEvent      *event,
65                                         gpointer       user_data);
66
67 static void     selection_changed_cb   (glView        *view,
68                                         glWindow      *window);
69
70 static void     zoom_changed_cb        (glView        *view,
71                                         gdouble        zoom,
72                                         glWindow      *window);
73
74 static void     pointer_moved_cb       (glView        *view,
75                                         gdouble        x,
76                                         gdouble        y,
77                                         glWindow      *window);
78
79 static void     pointer_exit_cb        (glView        *view,
80                                         glWindow      *window);
81
82 static void     name_changed_cb        (glLabel       *label,
83                                         glWindow      *window);
84
85 static void     modified_changed_cb    (glLabel       *label,
86                                         glWindow      *window);
87
88 \f
89 /****************************************************************************/
90 /* Boilerplate Object stuff.                                                */
91 /****************************************************************************/
92 guint
93 gl_window_get_type (void)
94 {
95         static guint window_type = 0;
96
97         if (!window_type) {
98                 GTypeInfo window_info = {
99                         sizeof (glWindowClass),
100                         NULL,
101                         NULL,
102                         (GClassInitFunc) gl_window_class_init,
103                         NULL,
104                         NULL,
105                         sizeof (glWindow),
106                         0,
107                         (GInstanceInitFunc) gl_window_init,
108                 };
109
110                 window_type =
111                     g_type_register_static (bonobo_window_get_type (),
112                                             "glWindow",
113                                             &window_info, 0);
114         }
115
116         return window_type;
117 }
118
119 static void
120 gl_window_class_init (glWindowClass *class)
121 {
122         GObjectClass   *object_class     = (GObjectClass *) class;
123         GtkObjectClass *gtk_object_class = (GtkObjectClass *) class;
124
125         gl_debug (DEBUG_WINDOW, "START");
126
127         parent_class = g_type_class_peek_parent (class);
128
129         object_class->finalize = gl_window_finalize;
130
131         gtk_object_class->destroy = gl_window_destroy;
132
133         gl_debug (DEBUG_WINDOW, "END");
134 }
135
136 static void
137 gl_window_init (glWindow *window)
138 {
139         BonoboUIContainer *ui_container;
140         BonoboUIComponent *ui_component;
141
142         gl_debug (DEBUG_WINDOW, "START");
143
144         ui_container = bonobo_window_get_ui_container(BONOBO_WINDOW(window));
145         ui_component = bonobo_ui_component_new_default ();
146         bonobo_ui_component_set_container (ui_component,
147                                            BONOBO_OBJREF (ui_container),
148                                            NULL);
149
150         window->cursor_info = gtk_label_new (NULL);
151         gtk_widget_set_size_request (window->cursor_info, CURSOR_INFO_WIDTH, -1);
152         window->cursor_info_frame = gtk_frame_new (NULL);
153         gtk_frame_set_shadow_type (GTK_FRAME(window->cursor_info_frame), GTK_SHADOW_IN);
154         gtk_container_add (GTK_CONTAINER(window->cursor_info_frame), window->cursor_info);
155         gtk_widget_show_all (window->cursor_info_frame);
156
157         window->zoom_info = gtk_label_new (NULL);
158         gtk_widget_set_size_request (window->zoom_info, ZOOM_INFO_WIDTH, -1);
159         window->zoom_info_frame = gtk_frame_new (NULL);
160         gtk_frame_set_shadow_type (GTK_FRAME(window->zoom_info_frame), GTK_SHADOW_IN);
161         gtk_container_add (GTK_CONTAINER(window->zoom_info_frame), window->zoom_info);
162         gtk_widget_show_all (window->zoom_info_frame);
163
164         gl_ui_init (ui_component,
165                     BONOBO_WINDOW (window),
166                     window->cursor_info_frame,
167                     window->zoom_info_frame);
168
169         gtk_window_set_default_size (GTK_WINDOW (window),
170                                      DEFAULT_WINDOW_WIDTH,
171                                      DEFAULT_WINDOW_HEIGHT);
172
173         g_signal_connect (G_OBJECT(window), "delete-event",
174                           G_CALLBACK(window_delete_event_cb), NULL);
175         
176         window->uic  = ui_component;
177         window->view = NULL;
178
179         window_list = g_list_append (window_list, window);
180
181         gl_debug (DEBUG_WINDOW, "END");
182 }
183
184 static void
185 gl_window_finalize (GObject *object)
186 {
187         glWindow *window;
188
189         gl_debug (DEBUG_WINDOW, "START");
190
191         g_return_if_fail (object != NULL);
192         g_return_if_fail (GL_IS_WINDOW (object));
193
194         window = GL_WINDOW (object);
195
196         G_OBJECT_CLASS (parent_class)->finalize (object);
197
198         gl_debug (DEBUG_WINDOW, "END");
199 }
200
201 static void
202 gl_window_destroy (GtkObject *gtk_object)
203 {
204         glWindow *window;
205
206         gl_debug (DEBUG_WINDOW, "START");
207
208         g_return_if_fail (gtk_object != NULL);
209         g_return_if_fail (GL_IS_WINDOW (gtk_object));
210
211         window = GL_WINDOW (gtk_object);
212         window_list = g_list_remove (window_list, window);
213
214         if (GTK_OBJECT_CLASS (parent_class)->destroy) {
215                 GTK_OBJECT_CLASS (parent_class)->destroy (gtk_object);
216         }
217
218         gl_debug (DEBUG_WINDOW, "END");
219 }
220
221
222 /****************************************************************************/
223 /* Create an app window.                                                    */
224 /****************************************************************************/
225 GtkWidget *
226 gl_window_new (void)
227 {
228         glWindow *window;
229
230         gl_debug (DEBUG_WINDOW, "START");
231
232         window = g_object_new (gl_window_get_type (),
233                                "win_name", "glabels",
234                                "title",    _("(none) - glabels"),
235                                NULL);
236
237         gl_debug (DEBUG_WINDOW, "window=%p", window);
238         gl_debug (DEBUG_WINDOW, "view=%p", window->view);
239
240         gl_debug (DEBUG_WINDOW, "END");
241
242         return GTK_WIDGET(window);
243 }
244
245 /****************************************************************************/
246 /* Create an app window from a label.                                       */
247 /****************************************************************************/
248 GtkWidget*
249 gl_window_new_from_label (glLabel *label)
250 {
251         glWindow *window;
252
253         gl_debug (DEBUG_WINDOW, "START");
254
255         window = GL_WINDOW (gl_window_new ());
256
257         gl_window_set_label (window, label);
258
259         gl_debug (DEBUG_WINDOW, "END");
260
261         return GTK_WIDGET(window);
262 }
263
264 /****************************************************************************/
265 /* Create an app window from a file.                                        */
266 /****************************************************************************/
267 GtkWidget*
268 gl_window_new_from_file (const gchar *filename)
269 {
270         glWindow         *window;
271         glLabel          *label;
272         gchar            *abs_filename;
273         glXMLLabelStatus  status;
274
275         gl_debug (DEBUG_WINDOW, "START");
276
277         window = GL_WINDOW (gl_window_new ());
278
279         abs_filename = gl_util_make_absolute (filename);
280         label = gl_xml_label_open (filename, &status);
281         g_free (abs_filename);
282
283         gl_window_set_label (window, label);
284
285         gl_debug (DEBUG_WINDOW, "END");
286
287         return GTK_WIDGET(window);
288 }
289
290 /****************************************************************************/
291 /* Is window empty?                                                         */
292 /****************************************************************************/
293 gboolean
294 gl_window_is_empty (glWindow    *window)
295 {
296         g_return_val_if_fail (GL_IS_WINDOW (window), FALSE);
297
298         gl_debug (DEBUG_WINDOW, "return %d", (window->view == NULL) );
299         return ( window->view == NULL );
300 }
301
302 /****************************************************************************/
303 /* Create view from label and place in window.                              */
304 /****************************************************************************/
305 void
306 gl_window_set_label (glWindow    *window,
307                      glLabel     *label)
308 {
309         gchar *string;
310
311         gl_debug (DEBUG_WINDOW, "START");
312
313         g_return_if_fail (GL_IS_WINDOW (window));
314         g_return_if_fail (GL_IS_LABEL (label));
315
316         gl_label_clear_modified (label);
317
318         set_window_title (window, label);
319
320         if ( window->view != NULL ) {
321                 gtk_widget_destroy (window->view);
322                 window->view = NULL;
323         }
324
325         window->view = gl_view_new (label);
326         bonobo_window_set_contents (BONOBO_WINDOW(window), window->view);
327
328         gtk_widget_show_all (window->view);
329
330         if (gl_prefs->grid_visible) {
331                 gl_view_show_grid (GL_VIEW(window->view));
332         } else {
333                 gl_view_hide_grid (GL_VIEW(window->view));
334         }
335
336         if (gl_prefs->markup_visible) {
337                 gl_view_show_markup (GL_VIEW(window->view));
338         } else {
339                 gl_view_hide_markup (GL_VIEW(window->view));
340         }
341
342         gl_ui_update_all (window->uic, GL_VIEW(window->view));
343
344         string = g_strdup_printf ("%3.0f%%",
345                                   100.0*gl_view_get_zoom (GL_VIEW(window->view)));
346         gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
347         g_free (string);
348
349         g_signal_connect (G_OBJECT(window->view), "selection_changed",
350                           G_CALLBACK(selection_changed_cb), window);
351
352         g_signal_connect (G_OBJECT(window->view), "zoom_changed",
353                           G_CALLBACK(zoom_changed_cb), window);
354
355         g_signal_connect (G_OBJECT(window->view), "pointer_moved",
356                           G_CALLBACK(pointer_moved_cb), window);
357
358         g_signal_connect (G_OBJECT(window->view), "pointer_exit",
359                           G_CALLBACK(pointer_exit_cb), window);
360
361         g_signal_connect (G_OBJECT(label), "name_changed",
362                           G_CALLBACK(name_changed_cb), window);
363
364         g_signal_connect (G_OBJECT(label), "modified_changed",
365                           G_CALLBACK(modified_changed_cb), window);
366
367         gl_debug (DEBUG_WINDOW, "END");
368 }
369
370 /****************************************************************************/
371 /* Return list of app windows.                                              */
372 /****************************************************************************/
373 const GList *
374 gl_window_get_window_list (void)
375 {
376         gl_debug (DEBUG_WINDOW, "");
377         return window_list;
378 }
379
380 /*---------------------------------------------------------------------------*/
381 /* PRIVATE.  Set window title based on name and state of label.              */
382 /*---------------------------------------------------------------------------*/
383 static void 
384 set_window_title (glWindow *window,
385                   glLabel  *label)
386 {
387         gchar *name, *title;
388
389         gl_debug (DEBUG_WINDOW, "START");
390
391         g_return_if_fail (window && GL_IS_WINDOW (window));
392         g_return_if_fail (label && GL_IS_LABEL (label));
393
394         name = gl_label_get_short_name (label);
395         g_return_if_fail (name != NULL);
396
397         if (gl_label_is_modified (label)) {
398                 title = g_strdup_printf ("%s %s - glabels",
399                                          name, _("(modified)"));
400         } else {
401                 title = g_strdup_printf ("%s - glabels", name);
402         }
403
404         gtk_window_set_title (GTK_WINDOW(window), title);
405
406         g_free (name);
407         g_free (title);
408
409         gl_debug (DEBUG_WINDOW, "END");
410 }
411
412 /*-------------------------------------------------------------------------*/
413 /* PRIVATE.  Window "delete-event" callback.                               */
414 /*-------------------------------------------------------------------------*/
415 static gboolean
416 window_delete_event_cb (glWindow      *window,
417                         GdkEvent      *event,
418                         gpointer       user_data)
419 {
420         gl_debug (DEBUG_WINDOW, "START");
421
422         g_return_val_if_fail (window && GL_IS_WINDOW (window), TRUE);
423
424         gl_file_close (window);
425
426         gl_debug (DEBUG_WINDOW, "END");
427
428         return TRUE;
429 }
430
431 /*---------------------------------------------------------------------------*/
432 /* PRIVATE.  View "selection state changed" callback.                        */
433 /*---------------------------------------------------------------------------*/
434 static void 
435 selection_changed_cb (glView   *view,
436                       glWindow *window)
437 {
438         gl_debug (DEBUG_WINDOW, "START");
439
440         g_return_if_fail (view && GL_IS_VIEW (view));
441         g_return_if_fail (window && GL_IS_WINDOW (window));
442
443         gl_ui_update_selection_verbs (window->uic, view);
444
445         gl_debug (DEBUG_WINDOW, "END");
446 }
447
448 /*---------------------------------------------------------------------------*/
449 /* PRIVATE.  View "zoom state changed" callback.                             */
450 /*---------------------------------------------------------------------------*/
451 static void 
452 zoom_changed_cb (glView   *view,
453                  gdouble   zoom,
454                  glWindow *window)
455 {
456         gchar *string;
457
458         gl_debug (DEBUG_WINDOW, "START");
459
460         g_return_if_fail (view && GL_IS_VIEW (view));
461         g_return_if_fail (window && GL_IS_WINDOW (window));
462
463         string = g_strdup_printf ("%3.0f%%", 100.0*zoom);
464         gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
465         g_free (string);
466
467         gl_ui_update_zoom_verbs (window->uic, view);
468
469         gl_debug (DEBUG_WINDOW, "END");
470 }
471
472 /*---------------------------------------------------------------------------*/
473 /* PRIVATE.  View "pointer moved" callback.                                  */
474 /*---------------------------------------------------------------------------*/
475 static void
476 pointer_moved_cb (glView   *view,
477                   gdouble   x,
478                   gdouble   y,
479                   glWindow *window)
480 {
481         gchar *string;
482         gdouble units_per_point;
483         gint    units_precision;
484
485         gl_debug (DEBUG_WINDOW, "START");
486
487         g_return_if_fail (view && GL_IS_VIEW (view));
488         g_return_if_fail (window && GL_IS_WINDOW (window));
489
490         units_per_point = gl_prefs_get_units_per_point ();
491         units_precision = gl_prefs_get_units_precision ();
492
493         string = g_strdup_printf ("%.*f, %.*f",
494                                   units_precision, x*units_per_point,
495                                   units_precision, y*units_per_point);
496         gtk_label_set_text (GTK_LABEL(window->cursor_info), string);
497         g_free (string);
498
499         gl_debug (DEBUG_WINDOW, "END");
500 }
501
502 /*---------------------------------------------------------------------------*/
503 /* PRIVATE.  View "pointer exit" callback.                                   */
504 /*---------------------------------------------------------------------------*/
505 static void
506 pointer_exit_cb (glView   *view,
507                  glWindow *window)
508 {
509         gl_debug (DEBUG_WINDOW, "START");
510
511         g_return_if_fail (view && GL_IS_VIEW (view));
512         g_return_if_fail (window && GL_IS_WINDOW (window));
513
514         gtk_label_set_text (GTK_LABEL(window->cursor_info), "");
515
516         gl_debug (DEBUG_WINDOW, "END");
517 }
518
519 /*---------------------------------------------------------------------------*/
520 /* PRIVATE.  Label "name changed" callback.                                  */
521 /*---------------------------------------------------------------------------*/
522 static void 
523 name_changed_cb (glLabel  *label,
524                  glWindow *window)
525 {
526         gl_debug (DEBUG_WINDOW, "START");
527
528         g_return_if_fail (label && GL_IS_LABEL (label));
529         g_return_if_fail (window && GL_IS_WINDOW (window));
530
531         set_window_title (window, label);
532
533         gl_debug (DEBUG_WINDOW, "END");
534 }
535
536 /*---------------------------------------------------------------------------*/
537 /* PRIVATE.  Label "modified state changed" callback.                        */
538 /*---------------------------------------------------------------------------*/
539 static void 
540 modified_changed_cb (glLabel  *label,
541                      glWindow *window)
542 {
543         gl_debug (DEBUG_WINDOW, "START");
544
545         g_return_if_fail (label && GL_IS_LABEL (label));
546         g_return_if_fail (window && GL_IS_WINDOW (window));
547
548         set_window_title (window, label);
549
550         gl_ui_update_modified_verbs (window->uic, label);
551
552         gl_debug (DEBUG_WINDOW, "END");
553 }
554