]> git.sur5r.net Git - glabels/blob - glabels2/src/window.c
2005-01-22 Jim Evins <evins@snaught.com>
[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 #include "file.h"
31
32 #include "debug.h"
33
34 /*============================================================================*/
35 /* Private macros and constants.                                              */
36 /*============================================================================*/
37
38 #define DEFAULT_WINDOW_WIDTH  788
39 #define DEFAULT_WINDOW_HEIGHT 600
40
41 #define CURSOR_INFO_WIDTH     150
42 #define ZOOM_INFO_WIDTH        50
43
44 /*============================================================================*/
45 /* Private globals                                                            */
46 /*============================================================================*/
47 static BonoboWindowClass *parent_class;
48
49 static GList *window_list = NULL;
50
51
52 /*============================================================================*/
53 /* Local function prototypes                                                  */
54 /*============================================================================*/
55
56 static void     gl_window_class_init   (glWindowClass *class);
57 static void     gl_window_init         (glWindow      *window);
58 static void     gl_window_finalize     (GObject       *object);
59 static void     gl_window_destroy      (GtkObject     *gtk_object);
60
61 static void     set_window_title       (glWindow *window,
62                                         glLabel  *label);
63
64 static gboolean window_delete_event_cb (glWindow      *window,
65                                         GdkEvent      *event,
66                                         gpointer       user_data);
67
68 static void     selection_changed_cb   (glView        *view,
69                                         glWindow      *window);
70
71 static void     zoom_changed_cb        (glView        *view,
72                                         gdouble        zoom,
73                                         glWindow      *window);
74
75 static void     pointer_moved_cb       (glView        *view,
76                                         gdouble        x,
77                                         gdouble        y,
78                                         glWindow      *window);
79
80 static void     pointer_exit_cb        (glView        *view,
81                                         glWindow      *window);
82
83 static void     name_changed_cb        (glLabel       *label,
84                                         glWindow      *window);
85
86 static void     modified_changed_cb    (glLabel       *label,
87                                         glWindow      *window);
88
89 \f
90 /****************************************************************************/
91 /* Boilerplate Object stuff.                                                */
92 /****************************************************************************/
93 GType
94 gl_window_get_type (void)
95 {
96         static GType type = 0;
97
98         if (!type) {
99                 static const GTypeInfo info = {
100                         sizeof (glWindowClass),
101                         NULL,
102                         NULL,
103                         (GClassInitFunc) gl_window_class_init,
104                         NULL,
105                         NULL,
106                         sizeof (glWindow),
107                         0,
108                         (GInstanceInitFunc) gl_window_init,
109                         NULL
110                 };
111
112                 type = g_type_register_static (BONOBO_TYPE_WINDOW,
113                                                "glWindow", &info, 0);
114         }
115
116         return 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         window->property_bar =
170                 GL_UI_PROPERTY_BAR(gl_ui_property_bar_new (ui_component));
171         window->sidebar =
172                 GL_UI_SIDEBAR(gl_ui_sidebar_new (ui_component));
173
174         gtk_window_set_default_size (GTK_WINDOW (window),
175                                      DEFAULT_WINDOW_WIDTH,
176                                      DEFAULT_WINDOW_HEIGHT);
177
178         g_signal_connect (G_OBJECT(window), "delete-event",
179                           G_CALLBACK(window_delete_event_cb), NULL);
180         
181         window->uic  = ui_component;
182         window->view = NULL;
183
184         window_list = g_list_append (window_list, window);
185
186         gl_debug (DEBUG_WINDOW, "END");
187 }
188
189 static void
190 gl_window_finalize (GObject *object)
191 {
192         glWindow *window;
193
194         gl_debug (DEBUG_WINDOW, "START");
195
196         g_return_if_fail (object != NULL);
197         g_return_if_fail (GL_IS_WINDOW (object));
198
199         window = GL_WINDOW (object);
200
201         G_OBJECT_CLASS (parent_class)->finalize (object);
202
203         gl_debug (DEBUG_WINDOW, "END");
204 }
205
206 static void
207 gl_window_destroy (GtkObject *gtk_object)
208 {
209         glWindow *window;
210
211         gl_debug (DEBUG_WINDOW, "START");
212
213         g_return_if_fail (gtk_object != NULL);
214         g_return_if_fail (GL_IS_WINDOW (gtk_object));
215
216         window = GL_WINDOW (gtk_object);
217         window_list = g_list_remove (window_list, window);
218
219         if (window->uic) {
220                 gl_ui_unref(window->uic);
221                 window->uic = NULL;
222         }
223
224         if (GTK_OBJECT_CLASS (parent_class)->destroy) {
225                 GTK_OBJECT_CLASS (parent_class)->destroy (gtk_object);
226         }
227
228         gl_debug (DEBUG_WINDOW, "END");
229 }
230
231
232 /****************************************************************************/
233 /* Create an app window.                                                    */
234 /****************************************************************************/
235 GtkWidget *
236 gl_window_new (void)
237 {
238         glWindow *window;
239
240         gl_debug (DEBUG_WINDOW, "START");
241
242         window = g_object_new (gl_window_get_type (),
243                                "win_name", "glabels",
244                                "title",    _("(none) - gLabels"),
245                                NULL);
246
247         gl_debug (DEBUG_WINDOW, "window=%p", window);
248         gl_debug (DEBUG_WINDOW, "view=%p", window->view);
249
250         gl_debug (DEBUG_WINDOW, "END");
251
252         return GTK_WIDGET(window);
253 }
254
255 /****************************************************************************/
256 /* Create an app window from a label.                                       */
257 /****************************************************************************/
258 GtkWidget*
259 gl_window_new_from_label (glLabel *label)
260 {
261         glWindow *window;
262
263         gl_debug (DEBUG_WINDOW, "START");
264
265         window = GL_WINDOW (gl_window_new ());
266
267         gl_window_set_label (window, label);
268
269         gl_debug (DEBUG_WINDOW, "END");
270
271         return GTK_WIDGET(window);
272 }
273
274 /****************************************************************************/
275 /* Create an app window from a file.                                        */
276 /****************************************************************************/
277 GtkWidget*
278 gl_window_new_from_file (const gchar *filename)
279 {
280         glWindow         *window;
281         glLabel          *label;
282         gchar            *abs_filename;
283         glXMLLabelStatus  status;
284
285         gl_debug (DEBUG_WINDOW, "START");
286
287         window = GL_WINDOW (gl_window_new ());
288
289         abs_filename = gl_util_make_absolute (filename);
290         label = gl_xml_label_open (abs_filename, &status);
291         g_free (abs_filename);
292
293         gl_window_set_label (window, label);
294
295         gl_debug (DEBUG_WINDOW, "END");
296
297         return GTK_WIDGET(window);
298 }
299
300 /****************************************************************************/
301 /* Is window empty?                                                         */
302 /****************************************************************************/
303 gboolean
304 gl_window_is_empty (glWindow    *window)
305 {
306         g_return_val_if_fail (GL_IS_WINDOW (window), FALSE);
307
308         gl_debug (DEBUG_WINDOW, "return %d", (window->view == NULL) );
309         return ( window->view == NULL );
310 }
311
312 /****************************************************************************/
313 /* Create view from label and place in window.                              */
314 /****************************************************************************/
315 void
316 gl_window_set_label (glWindow    *window,
317                      glLabel     *label)
318 {
319         gchar *string;
320
321         gl_debug (DEBUG_WINDOW, "START");
322
323         g_return_if_fail (GL_IS_WINDOW (window));
324         g_return_if_fail (GL_IS_LABEL (label));
325
326         gl_label_clear_modified (label);
327
328         set_window_title (window, label);
329
330         if ( window->view != NULL ) {
331                 gtk_widget_destroy (window->view);
332                 window->view = NULL;
333         }
334
335         window->view = gl_view_new (label);
336         bonobo_window_set_contents (BONOBO_WINDOW(window), window->view);
337
338         gtk_widget_show_all (window->view);
339
340         gl_view_zoom_to_fit (GL_VIEW(window->view));
341
342         if (gl_prefs->grid_visible) {
343                 gl_view_show_grid (GL_VIEW(window->view));
344         } else {
345                 gl_view_hide_grid (GL_VIEW(window->view));
346         }
347
348         if (gl_prefs->markup_visible) {
349                 gl_view_show_markup (GL_VIEW(window->view));
350         } else {
351                 gl_view_hide_markup (GL_VIEW(window->view));
352         }
353
354         gl_ui_update_all (window->uic, GL_VIEW(window->view));
355
356         gl_ui_property_bar_set_view (window->property_bar, GL_VIEW(window->view));
357         gl_ui_sidebar_set_view (window->sidebar, GL_VIEW(window->view));
358
359         string = g_strdup_printf ("%3.0f%%",
360                                   100.0*gl_view_get_zoom (GL_VIEW(window->view)));
361         gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
362         g_free (string);
363
364         g_signal_connect (G_OBJECT(window->view), "selection_changed",
365                           G_CALLBACK(selection_changed_cb), window);
366
367         g_signal_connect (G_OBJECT(window->view), "zoom_changed",
368                           G_CALLBACK(zoom_changed_cb), window);
369
370         g_signal_connect (G_OBJECT(window->view), "pointer_moved",
371                           G_CALLBACK(pointer_moved_cb), window);
372
373         g_signal_connect (G_OBJECT(window->view), "pointer_exit",
374                           G_CALLBACK(pointer_exit_cb), window);
375
376         g_signal_connect (G_OBJECT(label), "name_changed",
377                           G_CALLBACK(name_changed_cb), window);
378
379         g_signal_connect (G_OBJECT(label), "modified_changed",
380                           G_CALLBACK(modified_changed_cb), window);
381
382         gl_debug (DEBUG_WINDOW, "END");
383 }
384
385 /****************************************************************************/
386 /* Return list of app windows.                                              */
387 /****************************************************************************/
388 const GList *
389 gl_window_get_window_list (void)
390 {
391         gl_debug (DEBUG_WINDOW, "");
392         return window_list;
393 }
394
395 /*---------------------------------------------------------------------------*/
396 /* PRIVATE.  Set window title based on name and state of label.              */
397 /*---------------------------------------------------------------------------*/
398 static void 
399 set_window_title (glWindow *window,
400                   glLabel  *label)
401 {
402         gchar *name, *title;
403
404         gl_debug (DEBUG_WINDOW, "START");
405
406         g_return_if_fail (window && GL_IS_WINDOW (window));
407         g_return_if_fail (label && GL_IS_LABEL (label));
408
409         name = gl_label_get_short_name (label);
410         g_return_if_fail (name != NULL);
411
412         if (gl_label_is_modified (label)) {
413                 title = g_strdup_printf ("%s %s - gLabels",
414                                          name, _("(modified)"));
415         } else {
416                 title = g_strdup_printf ("%s - gLabels", name);
417         }
418
419         gtk_window_set_title (GTK_WINDOW(window), title);
420
421         g_free (name);
422         g_free (title);
423
424         gl_debug (DEBUG_WINDOW, "END");
425 }
426
427 /*-------------------------------------------------------------------------*/
428 /* PRIVATE.  Window "delete-event" callback.                               */
429 /*-------------------------------------------------------------------------*/
430 static gboolean
431 window_delete_event_cb (glWindow      *window,
432                         GdkEvent      *event,
433                         gpointer       user_data)
434 {
435         gl_debug (DEBUG_WINDOW, "START");
436
437         g_return_val_if_fail (window && GL_IS_WINDOW (window), TRUE);
438
439         gl_file_close (window);
440
441         gl_debug (DEBUG_WINDOW, "END");
442
443         return TRUE;
444 }
445
446 /*---------------------------------------------------------------------------*/
447 /* PRIVATE.  View "selection state changed" callback.                        */
448 /*---------------------------------------------------------------------------*/
449 static void 
450 selection_changed_cb (glView   *view,
451                       glWindow *window)
452 {
453         gl_debug (DEBUG_WINDOW, "START");
454
455         g_return_if_fail (view && GL_IS_VIEW (view));
456         g_return_if_fail (window && GL_IS_WINDOW (window));
457
458         gl_ui_update_selection_verbs (window->uic, view);
459
460         gl_debug (DEBUG_WINDOW, "END");
461 }
462
463 /*---------------------------------------------------------------------------*/
464 /* PRIVATE.  View "zoom state changed" callback.                             */
465 /*---------------------------------------------------------------------------*/
466 static void 
467 zoom_changed_cb (glView   *view,
468                  gdouble   zoom,
469                  glWindow *window)
470 {
471         gchar *string;
472
473         gl_debug (DEBUG_WINDOW, "START");
474
475         g_return_if_fail (view && GL_IS_VIEW (view));
476         g_return_if_fail (window && GL_IS_WINDOW (window));
477
478         string = g_strdup_printf ("%3.0f%%", 100.0*zoom);
479         gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
480         g_free (string);
481
482         gl_ui_update_zoom_verbs (window->uic, view);
483
484         gl_debug (DEBUG_WINDOW, "END");
485 }
486
487 /*---------------------------------------------------------------------------*/
488 /* PRIVATE.  View "pointer moved" callback.                                  */
489 /*---------------------------------------------------------------------------*/
490 static void
491 pointer_moved_cb (glView   *view,
492                   gdouble   x,
493                   gdouble   y,
494                   glWindow *window)
495 {
496         gchar *string;
497         gdouble units_per_point;
498         gint    units_precision;
499
500         gl_debug (DEBUG_WINDOW, "START");
501
502         g_return_if_fail (view && GL_IS_VIEW (view));
503         g_return_if_fail (window && GL_IS_WINDOW (window));
504
505         units_per_point = gl_prefs_get_units_per_point ();
506         units_precision = gl_prefs_get_units_precision ();
507
508         string = g_strdup_printf ("%.*f, %.*f",
509                                   units_precision, x*units_per_point,
510                                   units_precision, y*units_per_point);
511         gtk_label_set_text (GTK_LABEL(window->cursor_info), string);
512         g_free (string);
513
514         gl_debug (DEBUG_WINDOW, "END");
515 }
516
517 /*---------------------------------------------------------------------------*/
518 /* PRIVATE.  View "pointer exit" callback.                                   */
519 /*---------------------------------------------------------------------------*/
520 static void
521 pointer_exit_cb (glView   *view,
522                  glWindow *window)
523 {
524         gl_debug (DEBUG_WINDOW, "START");
525
526         g_return_if_fail (view && GL_IS_VIEW (view));
527         g_return_if_fail (window && GL_IS_WINDOW (window));
528
529         gtk_label_set_text (GTK_LABEL(window->cursor_info), "");
530
531         gl_debug (DEBUG_WINDOW, "END");
532 }
533
534 /*---------------------------------------------------------------------------*/
535 /* PRIVATE.  Label "name changed" callback.                                  */
536 /*---------------------------------------------------------------------------*/
537 static void 
538 name_changed_cb (glLabel  *label,
539                  glWindow *window)
540 {
541         gl_debug (DEBUG_WINDOW, "START");
542
543         g_return_if_fail (label && GL_IS_LABEL (label));
544         g_return_if_fail (window && GL_IS_WINDOW (window));
545
546         set_window_title (window, label);
547
548         gl_debug (DEBUG_WINDOW, "END");
549 }
550
551 /*---------------------------------------------------------------------------*/
552 /* PRIVATE.  Label "modified state changed" callback.                        */
553 /*---------------------------------------------------------------------------*/
554 static void 
555 modified_changed_cb (glLabel  *label,
556                      glWindow *window)
557 {
558         gl_debug (DEBUG_WINDOW, "START");
559
560         g_return_if_fail (label && GL_IS_LABEL (label));
561         g_return_if_fail (window && GL_IS_WINDOW (window));
562
563         set_window_title (window, label);
564
565         gl_ui_update_modified_verbs (window->uic, label);
566
567         gl_debug (DEBUG_WINDOW, "END");
568 }