]> git.sur5r.net Git - glabels/blob - glabels2/src/window.c
Added cursor position to status bar.
[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     name_changed_cb        (glLabel       *label,
80                                         glWindow      *window);
81
82 static void     modified_changed_cb    (glLabel       *label,
83                                         glWindow      *window);
84
85 \f
86 /****************************************************************************/
87 /* Boilerplate Object stuff.                                                */
88 /****************************************************************************/
89 guint
90 gl_window_get_type (void)
91 {
92         static guint window_type = 0;
93
94         if (!window_type) {
95                 GTypeInfo window_info = {
96                         sizeof (glWindowClass),
97                         NULL,
98                         NULL,
99                         (GClassInitFunc) gl_window_class_init,
100                         NULL,
101                         NULL,
102                         sizeof (glWindow),
103                         0,
104                         (GInstanceInitFunc) gl_window_init,
105                 };
106
107                 window_type =
108                     g_type_register_static (bonobo_window_get_type (),
109                                             "glWindow",
110                                             &window_info, 0);
111         }
112
113         return window_type;
114 }
115
116 static void
117 gl_window_class_init (glWindowClass *class)
118 {
119         GObjectClass   *object_class     = (GObjectClass *) class;
120         GtkObjectClass *gtk_object_class = (GtkObjectClass *) class;
121
122         gl_debug (DEBUG_WINDOW, "START");
123
124         parent_class = g_type_class_peek_parent (class);
125
126         object_class->finalize = gl_window_finalize;
127
128         gtk_object_class->destroy = gl_window_destroy;
129
130         gl_debug (DEBUG_WINDOW, "END");
131 }
132
133 static void
134 gl_window_init (glWindow *window)
135 {
136         BonoboUIContainer *ui_container;
137         BonoboUIComponent *ui_component;
138
139         gl_debug (DEBUG_WINDOW, "START");
140
141         ui_container = bonobo_window_get_ui_container(BONOBO_WINDOW(window));
142         ui_component = bonobo_ui_component_new_default ();
143         bonobo_ui_component_set_container (ui_component,
144                                            BONOBO_OBJREF (ui_container),
145                                            NULL);
146
147         window->cursor_info = gtk_label_new (NULL);
148         gtk_widget_set_size_request (window->cursor_info, CURSOR_INFO_WIDTH, -1);
149         window->cursor_info_frame = gtk_frame_new (NULL);
150         gtk_frame_set_shadow_type (GTK_FRAME(window->cursor_info_frame), GTK_SHADOW_IN);
151         gtk_container_add (GTK_CONTAINER(window->cursor_info_frame), window->cursor_info);
152         gtk_widget_show_all (window->cursor_info_frame);
153
154         window->zoom_info = gtk_label_new (NULL);
155         gtk_widget_set_size_request (window->zoom_info, ZOOM_INFO_WIDTH, -1);
156         window->zoom_info_frame = gtk_frame_new (NULL);
157         gtk_frame_set_shadow_type (GTK_FRAME(window->zoom_info_frame), GTK_SHADOW_IN);
158         gtk_container_add (GTK_CONTAINER(window->zoom_info_frame), window->zoom_info);
159         gtk_widget_show_all (window->zoom_info_frame);
160
161         gl_ui_init (ui_component,
162                     BONOBO_WINDOW (window),
163                     window->cursor_info_frame,
164                     window->zoom_info_frame);
165
166         gtk_window_set_default_size (GTK_WINDOW (window),
167                                      DEFAULT_WINDOW_WIDTH,
168                                      DEFAULT_WINDOW_HEIGHT);
169
170         g_signal_connect (G_OBJECT(window), "delete-event",
171                           G_CALLBACK(window_delete_event_cb), NULL);
172         
173         window->uic  = ui_component;
174         window->view = NULL;
175
176         window_list = g_list_append (window_list, window);
177
178         gl_debug (DEBUG_WINDOW, "END");
179 }
180
181 static void
182 gl_window_finalize (GObject *object)
183 {
184         glWindow *window;
185
186         gl_debug (DEBUG_WINDOW, "START");
187
188         g_return_if_fail (object != NULL);
189         g_return_if_fail (GL_IS_WINDOW (object));
190
191         window = GL_WINDOW (object);
192
193         G_OBJECT_CLASS (parent_class)->finalize (object);
194
195         gl_debug (DEBUG_WINDOW, "END");
196 }
197
198 static void
199 gl_window_destroy (GtkObject *gtk_object)
200 {
201         glWindow *window;
202
203         gl_debug (DEBUG_WINDOW, "START");
204
205         g_return_if_fail (gtk_object != NULL);
206         g_return_if_fail (GL_IS_WINDOW (gtk_object));
207
208         window = GL_WINDOW (gtk_object);
209         window_list = g_list_remove (window_list, window);
210
211         if (GTK_OBJECT_CLASS (parent_class)->destroy) {
212                 GTK_OBJECT_CLASS (parent_class)->destroy (gtk_object);
213         }
214
215         gl_debug (DEBUG_WINDOW, "END");
216 }
217
218
219 /****************************************************************************/
220 /* Create an app window.                                                    */
221 /****************************************************************************/
222 GtkWidget *
223 gl_window_new (void)
224 {
225         glWindow *window;
226
227         gl_debug (DEBUG_WINDOW, "START");
228
229         window = g_object_new (gl_window_get_type (),
230                                "win_name", "glabels",
231                                "title",    _("(none) - glabels"),
232                                NULL);
233
234         gl_debug (DEBUG_WINDOW, "window=%p", window);
235         gl_debug (DEBUG_WINDOW, "view=%p", window->view);
236
237         gl_debug (DEBUG_WINDOW, "END");
238
239         return GTK_WIDGET(window);
240 }
241
242 /****************************************************************************/
243 /* Create an app window from a label.                                       */
244 /****************************************************************************/
245 GtkWidget*
246 gl_window_new_from_label (glLabel *label)
247 {
248         glWindow *window;
249
250         gl_debug (DEBUG_WINDOW, "START");
251
252         window = GL_WINDOW (gl_window_new ());
253
254         gl_window_set_label (window, label);
255
256         gl_debug (DEBUG_WINDOW, "END");
257
258         return GTK_WIDGET(window);
259 }
260
261 /****************************************************************************/
262 /* Create an app window from a file.                                        */
263 /****************************************************************************/
264 GtkWidget*
265 gl_window_new_from_file (const gchar *filename)
266 {
267         glWindow         *window;
268         glLabel          *label;
269         gchar            *abs_filename;
270         glXMLLabelStatus  status;
271
272         gl_debug (DEBUG_WINDOW, "START");
273
274         window = GL_WINDOW (gl_window_new ());
275
276         abs_filename = gl_util_make_absolute (filename);
277         label = gl_xml_label_open (filename, &status);
278         g_free (abs_filename);
279
280         gl_window_set_label (window, label);
281
282         gl_debug (DEBUG_WINDOW, "END");
283
284         return GTK_WIDGET(window);
285 }
286
287 /****************************************************************************/
288 /* Is window empty?                                                         */
289 /****************************************************************************/
290 gboolean
291 gl_window_is_empty (glWindow    *window)
292 {
293         g_return_val_if_fail (GL_IS_WINDOW (window), FALSE);
294
295         gl_debug (DEBUG_WINDOW, "return %d", (window->view == NULL) );
296         return ( window->view == NULL );
297 }
298
299 /****************************************************************************/
300 /* Create view from label and place in window.                              */
301 /****************************************************************************/
302 void
303 gl_window_set_label (glWindow    *window,
304                      glLabel     *label)
305 {
306         gchar *string;
307
308         gl_debug (DEBUG_WINDOW, "START");
309
310         g_return_if_fail (GL_IS_WINDOW (window));
311         g_return_if_fail (GL_IS_LABEL (label));
312
313         gl_label_clear_modified (label);
314
315         set_window_title (window, label);
316
317         if ( window->view != NULL ) {
318                 gtk_widget_destroy (window->view);
319                 window->view = NULL;
320         }
321
322         window->view = gl_view_new (label);
323         bonobo_window_set_contents (BONOBO_WINDOW(window), window->view);
324
325         gtk_widget_show_all (window->view);
326
327         gl_ui_update_all (window->uic, GL_VIEW(window->view));
328
329         string = g_strdup_printf ("%3.0f%%",
330                                   100.0*gl_view_get_zoom (GL_VIEW(window->view)));
331         gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
332         g_free (string);
333
334         g_signal_connect (G_OBJECT(window->view), "selection_changed",
335                           G_CALLBACK(selection_changed_cb), window);
336
337         g_signal_connect (G_OBJECT(window->view), "zoom_changed",
338                           G_CALLBACK(zoom_changed_cb), window);
339
340         g_signal_connect (G_OBJECT(window->view), "pointer_moved",
341                           G_CALLBACK(pointer_moved_cb), window);
342
343         g_signal_connect (G_OBJECT(label), "name_changed",
344                           G_CALLBACK(name_changed_cb), window);
345
346         g_signal_connect (G_OBJECT(label), "modified_changed",
347                           G_CALLBACK(modified_changed_cb), window);
348
349         gl_debug (DEBUG_WINDOW, "END");
350 }
351
352 /****************************************************************************/
353 /* Return list of app windows.                                              */
354 /****************************************************************************/
355 const GList *
356 gl_window_get_window_list (void)
357 {
358         gl_debug (DEBUG_WINDOW, "");
359         return window_list;
360 }
361
362 /*---------------------------------------------------------------------------*/
363 /* PRIVATE.  Set window title based on name and state of label.              */
364 /*---------------------------------------------------------------------------*/
365 static void 
366 set_window_title (glWindow *window,
367                   glLabel  *label)
368 {
369         gchar *name, *title;
370
371         gl_debug (DEBUG_WINDOW, "START");
372
373         g_return_if_fail (window && GL_IS_WINDOW (window));
374         g_return_if_fail (label && GL_IS_LABEL (label));
375
376         name = gl_label_get_short_name (label);
377         g_return_if_fail (name != NULL);
378
379         if (gl_label_is_modified (label)) {
380                 title = g_strdup_printf ("%s %s - glabels",
381                                          name, _("(modified)"));
382         } else {
383                 title = g_strdup_printf ("%s - glabels", name);
384         }
385
386         gtk_window_set_title (GTK_WINDOW(window), title);
387
388         g_free (name);
389         g_free (title);
390
391         gl_debug (DEBUG_WINDOW, "END");
392 }
393
394 /*-------------------------------------------------------------------------*/
395 /* PRIVATE.  Window "delete-event" callback.                               */
396 /*-------------------------------------------------------------------------*/
397 static gboolean
398 window_delete_event_cb (glWindow      *window,
399                         GdkEvent      *event,
400                         gpointer       user_data)
401 {
402         gl_debug (DEBUG_WINDOW, "START");
403
404         g_return_val_if_fail (window && GL_IS_WINDOW (window), TRUE);
405
406         gl_file_close (window);
407
408         gl_debug (DEBUG_WINDOW, "END");
409
410         return TRUE;
411 }
412
413 /*---------------------------------------------------------------------------*/
414 /* PRIVATE.  View "selection state changed" callback.                        */
415 /*---------------------------------------------------------------------------*/
416 static void 
417 selection_changed_cb (glView   *view,
418                       glWindow *window)
419 {
420         gl_debug (DEBUG_WINDOW, "START");
421
422         g_return_if_fail (view && GL_IS_VIEW (view));
423         g_return_if_fail (window && GL_IS_WINDOW (window));
424
425         gl_ui_update_selection_verbs (window->uic, view);
426
427         gl_debug (DEBUG_WINDOW, "END");
428 }
429
430 /*---------------------------------------------------------------------------*/
431 /* PRIVATE.  View "zoom state changed" callback.                             */
432 /*---------------------------------------------------------------------------*/
433 static void 
434 zoom_changed_cb (glView   *view,
435                  gdouble   zoom,
436                  glWindow *window)
437 {
438         gchar *string;
439
440         gl_debug (DEBUG_WINDOW, "START");
441
442         g_return_if_fail (view && GL_IS_VIEW (view));
443         g_return_if_fail (window && GL_IS_WINDOW (window));
444
445         string = g_strdup_printf ("%3.0f%%", 100.0*zoom);
446         gtk_label_set_text (GTK_LABEL(window->zoom_info), string);
447         g_free (string);
448
449         gl_debug (DEBUG_WINDOW, "END");
450 }
451
452 /*---------------------------------------------------------------------------*/
453 /* PRIVATE.  View "pointer moved" callback.                                  */
454 /*---------------------------------------------------------------------------*/
455 static void
456 pointer_moved_cb (glView   *view,
457                   gdouble   x,
458                   gdouble   y,
459                   glWindow *window)
460 {
461         gchar *string;
462         gdouble units_per_point;
463         gint    units_precision;
464
465         gl_debug (DEBUG_WINDOW, "START");
466
467         g_return_if_fail (view && GL_IS_VIEW (view));
468         g_return_if_fail (window && GL_IS_WINDOW (window));
469
470         units_per_point = gl_prefs_get_units_per_point ();
471         units_precision = gl_prefs_get_units_precision ();
472
473         string = g_strdup_printf ("%.*f, %.*f",
474                                   units_precision, x*units_per_point,
475                                   units_precision, y*units_per_point);
476         gtk_label_set_text (GTK_LABEL(window->cursor_info), string);
477         g_free (string);
478
479         gl_debug (DEBUG_WINDOW, "END");
480 }
481
482 /*---------------------------------------------------------------------------*/
483 /* PRIVATE.  Label "name changed" callback.                                  */
484 /*---------------------------------------------------------------------------*/
485 static void 
486 name_changed_cb (glLabel  *label,
487                  glWindow *window)
488 {
489         gl_debug (DEBUG_WINDOW, "START");
490
491         g_return_if_fail (label && GL_IS_LABEL (label));
492         g_return_if_fail (window && GL_IS_WINDOW (window));
493
494         set_window_title (window, label);
495
496         gl_debug (DEBUG_WINDOW, "END");
497 }
498
499 /*---------------------------------------------------------------------------*/
500 /* PRIVATE.  Label "modified state changed" callback.                        */
501 /*---------------------------------------------------------------------------*/
502 static void 
503 modified_changed_cb (glLabel  *label,
504                      glWindow *window)
505 {
506         gl_debug (DEBUG_WINDOW, "START");
507
508         g_return_if_fail (label && GL_IS_LABEL (label));
509         g_return_if_fail (window && GL_IS_WINDOW (window));
510
511         set_window_title (window, label);
512
513         gl_ui_update_modified_verbs (window->uic, label);
514
515         gl_debug (DEBUG_WINDOW, "END");
516 }
517