source: trunk/third/ggv/bonobo/ggv-control.c @ 18703

Revision 18703, 27.8 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18702, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2/**
3 * ggv-control.c
4 *
5 * Author:  Jaka Mocnik  <jaka@gnu.org>
6 *
7 * Copyright (c) 2001, 2002 Free Software Foundation
8 */
9
10#include <config.h>
11
12#include <stdio.h>
13#include <math.h>
14#include <string.h>
15
16#include <gtk/gtksignal.h>
17#include <gtk/gtkmarshal.h>
18#include <gtk/gtktypeutils.h>
19
20#include <gnome.h>
21
22#include <ggv-control.h>
23#include <gsdefaults.h>
24#include <ggvutils.h>
25
26struct _GgvControlPrivate {
27        GgvPostScriptView *ps_view;
28
29        BonoboZoomable *zoomable;
30        float zoom_level;
31        gboolean has_zoomable_frame;
32
33        GtkWidget *root;
34
35        GtkObject *zoom_adj;
36        BonoboControl *zoom_control;
37
38        BonoboUIComponent *uic, *popup_uic;
39
40        /* GConfClient notification ID */
41        guint gconf_notify_id;
42};
43
44struct _GgvControlClassPrivate {
45        int dummy;
46};
47
48static struct {
49        gfloat level;
50        gchar *path;
51} zoom_level_items[] = {
52        { 1.0/4.0, "/commands/Zoom0104" },
53        { 1.0/2.0, "/commands/Zoom0102" },
54        { 3.0/4.0, "/commands/Zoom0304" },
55        { 1.0/1.0, "/commands/Zoom0101" },
56        { 3.0/2.0, "/commands/Zoom0302" },
57        { 2.0/1.0, "/commands/Zoom0201" },
58        { 4.0/1.0, "/commands/Zoom0401" },
59        { 0.0, NULL }
60};
61
62static BonoboControlClass *ggv_control_parent_class;
63
64static void
65ggv_control_destroy (BonoboObject *object)
66{
67        GgvControl *control;
68
69        g_return_if_fail (object != NULL);
70        g_return_if_fail (GGV_IS_CONTROL (object));
71
72        control = GGV_CONTROL (object);
73
74        if (control->priv->gconf_notify_id) {
75                gconf_client_notify_remove (gtk_gs_defaults_gconf_client (),
76                                                                        control->priv->gconf_notify_id);
77                control->priv->gconf_notify_id = 0;
78        }
79        if (control->priv->zoom_control) {
80                bonobo_object_unref(BONOBO_OBJECT(control->priv->zoom_control));
81                control->priv->zoom_control = NULL;
82        }
83
84        if(BONOBO_OBJECT_CLASS (ggv_control_parent_class)->destroy)
85                BONOBO_OBJECT_CLASS (ggv_control_parent_class)->destroy (object);
86}
87
88static void
89ggv_control_finalize (GObject *object)
90{
91        GgvControl *control;
92
93        g_return_if_fail (object != NULL);
94        g_return_if_fail (GGV_IS_CONTROL (object));
95
96        control = GGV_CONTROL (object);
97
98        g_free (control->priv);
99
100        G_OBJECT_CLASS (ggv_control_parent_class)->finalize (object);
101}
102
103static void
104sync_zoom_level_items(GgvControl *control)
105{
106        int i;
107        Bonobo_UIContainer container;
108
109        container = bonobo_ui_component_get_container (control->priv->uic);
110        if (container == CORBA_OBJECT_NIL)
111                return;
112
113        for(i = 0; zoom_level_items[i].path; i++) {
114                if(fabs(ggv_postscript_view_get_zoom_factor(control->priv->ps_view) - zoom_level_items[i].level) < 0.001) {
115                        bonobo_ui_component_set_prop(control->priv->uic,
116                                                                                 zoom_level_items[i].path,
117                                                                                 "state", "1", NULL);
118                        return;
119                }
120        }
121        bonobo_ui_component_set_prop(control->priv->uic,
122                                                                 "/commands/ZoomOther",
123                                                                 "state", "1", NULL);
124}
125
126static void
127sync_auto_fit_items(GgvControl *control)
128{
129        int i;
130        Bonobo_UIContainer container;
131        GgvPostScriptView *ps_view = control->priv->ps_view;
132        GtkWidget *gs;
133
134        container = bonobo_ui_component_get_container (control->priv->uic);
135        if (container == CORBA_OBJECT_NIL)
136                return;
137
138        gs = ggv_postscript_view_get_widget(ps_view);
139
140        switch(gtk_gs_get_zoom_mode(GTK_GS(gs))) {
141        case GTK_GS_ZOOM_ABSOLUTE:
142                bonobo_ui_component_set_prop(control->priv->uic,
143                                                                         "/commands/AutoFitNone",
144                                                                         "state", "1", NULL);
145                break;
146        case GTK_GS_ZOOM_FIT_WIDTH:
147                bonobo_ui_component_set_prop(control->priv->uic,
148                                                                         "/commands/AutoFitWidth",
149                                                                         "state", "1", NULL);
150                break;
151        case GTK_GS_ZOOM_FIT_PAGE:
152                bonobo_ui_component_set_prop(control->priv->uic,
153                                                                         "/commands/AutoFitPage",
154                                                                         "state", "1", NULL);
155                break;
156        default:
157                break;
158        }
159}
160
161static void
162sync_command_state(GgvControl *control)
163{
164        sync_auto_fit_items(control);
165        sync_zoom_level_items(control);
166}
167
168static void
169zoomable_set_frame_cb (BonoboZoomable *zoomable, GgvControl *control)
170{
171        g_return_if_fail (control != NULL);
172        g_return_if_fail (GGV_IS_CONTROL (control));
173
174        control->priv->has_zoomable_frame = TRUE;
175}
176
177static void
178zoomable_set_zoom_level_cb (BonoboZoomable *zoomable, float new_zoom_level,
179                                                        GgvControl *control)
180{
181        g_return_if_fail (control != NULL);
182        g_return_if_fail (GGV_IS_CONTROL (control));
183
184        if(fabs(ggv_postscript_view_get_zoom_factor(control->priv->ps_view) - new_zoom_level) < 0.001)
185                return;
186
187        ggv_postscript_view_set_zoom_factor
188                (control->priv->ps_view, new_zoom_level);
189        control->priv->zoom_level = ggv_postscript_view_get_zoom_factor
190                (control->priv->ps_view);
191
192        if(control->priv->zoom_adj) {
193                if(fabs(GTK_ADJUSTMENT(control->priv->zoom_adj)->value - new_zoom_level*100.0) > 0.01)
194                        gtk_adjustment_set_value(GTK_ADJUSTMENT(control->priv->zoom_adj),
195                                                                         new_zoom_level*100.0);
196        }
197
198        bonobo_zoomable_report_zoom_level_changed
199                (zoomable, control->priv->zoom_level, NULL);
200
201        sync_zoom_level_items(control);
202}
203
204static void
205zoomable_zoom_in_cb (BonoboZoomable *zoomable, GgvControl *control)
206{
207        float new_zoom_level;
208        int index;
209
210        g_return_if_fail (control != NULL);
211        g_return_if_fail (GGV_IS_CONTROL (control));
212
213        index = ggv_zoom_index_from_float (control->priv->zoom_level);
214        if (index == ggv_max_zoom_levels)
215                return;
216
217        index++;
218        new_zoom_level = ggv_zoom_level_from_index (index);
219
220        g_signal_emit_by_name (G_OBJECT (zoomable), "set_zoom_level",
221                                                   new_zoom_level);
222}
223
224static void
225zoomable_zoom_out_cb (BonoboZoomable *zoomable, GgvControl *control)
226{
227        float new_zoom_level;
228        int index;
229
230        g_return_if_fail (control != NULL);
231        g_return_if_fail (GGV_IS_CONTROL (control));
232
233        index = ggv_zoom_index_from_float (control->priv->zoom_level);
234        if (index == 0)
235                return;
236
237        index--;
238        new_zoom_level = ggv_zoom_level_from_index (index);
239
240        g_signal_emit_by_name (G_OBJECT (zoomable), "set_zoom_level",
241                                                   new_zoom_level);
242}
243
244static void
245zoomable_zoom_to_fit_cb (BonoboZoomable *zoomable, GgvControl *control)
246{
247        float new_zoom_level;
248
249        g_return_if_fail (control != NULL);
250        g_return_if_fail (GGV_IS_CONTROL (control));
251
252        new_zoom_level =
253                ggv_postscript_view_zoom_to_fit (control->priv->ps_view, FALSE);
254
255        g_signal_emit_by_name (G_OBJECT (zoomable), "set_zoom_level",
256                                                   new_zoom_level);
257}
258
259static void
260zoomable_zoom_to_default_cb (BonoboZoomable *zoomable, GgvControl *control)
261{
262        g_return_if_fail (control != NULL);
263        g_return_if_fail (GGV_IS_CONTROL (control));
264
265        g_signal_emit_by_name (G_OBJECT (zoomable), "set_zoom_level", 1.0);
266}
267
268static gboolean
269scrollbar_button_press_event(GtkWidget *widget, GdkEventButton *event,
270                                                         gpointer data)
271{
272        GtkGS *gs = GTK_GS(data);
273
274        if(event->button == 1)
275                gtk_gs_start_scroll(gs);
276
277        return FALSE;
278}
279
280static gboolean
281scrollbar_button_release_event(GtkWidget *widget, GdkEventButton *event,
282                                                           gpointer data)
283{
284        GtkGS *gs = GTK_GS(data);
285
286        if(event->button == 1)
287                gtk_gs_end_scroll(gs);
288
289        return FALSE;
290}
291
292static void
293listener_ZoomLevel_cb(BonoboUIComponent *uic, const char *path,
294                                          Bonobo_UIComponent_EventType type, const char *state,
295                                          gpointer user_data)
296{
297        BonoboZoomable *zoomable;
298        GgvControl *control;
299        const char *zl;
300        gint i;
301
302        g_return_if_fail(user_data != NULL);
303        g_return_if_fail(GGV_IS_CONTROL(user_data));
304
305        if(type != Bonobo_UIComponent_STATE_CHANGED)
306                return;
307
308        if(!state || !atoi(state))
309                return;
310
311        control = GGV_CONTROL(user_data);
312        zoomable = control->priv->zoomable;
313
314        zl = path + strlen("Zoom");
315
316        for(i = 0; zoom_level_items[i].path != NULL; i++) {
317                if(strstr(zoom_level_items[i].path, zl) != NULL) {
318                        g_signal_emit_by_name (G_OBJECT (zoomable), "set_zoom_level",
319                                                                   (gfloat)zoom_level_items[i].level);
320                        break;
321                }
322        }
323}
324
325static void
326listener_AutoFitMode_cb(BonoboUIComponent *uic, const char *path,
327                                                Bonobo_UIComponent_EventType type, const char *state,
328                                                gpointer user_data)
329{
330        GgvControl *control;
331        GtkGS *gs;
332        gint i;
333
334        g_return_if_fail(user_data != NULL);
335        g_return_if_fail(GGV_IS_CONTROL(user_data));
336
337        if(type != Bonobo_UIComponent_STATE_CHANGED)
338                return;
339
340        if(!state || !atoi(state))
341                return;
342
343        control = GGV_CONTROL(user_data);
344        gs = GTK_GS(ggv_postscript_view_get_widget(control->priv->ps_view));
345
346        if(!strcmp(path, "AutoFitNone"))
347                gtk_gs_set_zoom_mode(gs, GTK_GS_ZOOM_ABSOLUTE);
348        if(!strcmp(path, "AutoFitWidth"))
349                gtk_gs_set_zoom_mode(gs, GTK_GS_ZOOM_FIT_WIDTH);
350        if(!strcmp(path, "AutoFitPage"))
351                gtk_gs_set_zoom_mode(gs, GTK_GS_ZOOM_FIT_PAGE);
352
353        gtk_widget_unref(GTK_WIDGET(gs));
354}
355
356static gboolean
357ggv_control_button_press_event(GtkWidget *widget, GdkEventButton *event,
358                                                           gpointer data)
359{
360        GgvControl *control = GGV_CONTROL(data);
361
362        if(event->button == 3) {
363                return bonobo_control_do_popup(BONOBO_CONTROL(control), 3, event->time);
364        }
365        return FALSE;
366}
367
368static gboolean
369ggv_control_key_press_event(GtkWidget *widget, GdkEventKey *event,
370                                                        gpointer data)
371{
372        GtkGS *gs = GTK_GS(widget);
373        gint key = event->keyval;
374        GgvControl *control = GGV_CONTROL(data);
375        GtkGSOrientation orientation = gtk_gs_get_orientation(gs);
376        GgvPostScriptView *ps_view = control->priv->ps_view;
377
378        /* ugh. the possibilities! */
379        switch (key) {
380        case GDK_space:
381                switch (orientation) {
382                case GTK_GS_ORIENTATION_PORTRAIT:
383                        if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_DOWN, TRUE)) {
384                                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) + 1);
385                        }
386                        break;
387                case GTK_GS_ORIENTATION_LANDSCAPE:
388                        if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_LEFT, TRUE)) {
389                                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) + 1);
390                        }
391                        break;
392                case GTK_GS_ORIENTATION_SEASCAPE:
393                        if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_RIGHT, TRUE)) {
394                                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) + 1);
395                        }
396                        break;
397                case GTK_GS_ORIENTATION_UPSIDEDOWN:
398                        if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_UP, TRUE)) {
399                                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) + 1);
400                        }
401                        break;
402                default:
403                        break;
404                }
405                break;
406        case GDK_BackSpace:
407        case GDK_Delete:
408                switch (orientation) {
409                case GTK_GS_ORIENTATION_PORTRAIT:
410                        if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_UP, TRUE)) {
411                                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) - 1);
412                        }
413                        break;
414                case GTK_GS_ORIENTATION_LANDSCAPE:
415                        if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_RIGHT, TRUE)) {
416                                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) - 1);
417                        }
418                        break;
419                case GTK_GS_ORIENTATION_SEASCAPE:
420                        if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_LEFT, TRUE)) {
421                                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) - 1);
422                        }
423                        break;
424                case GTK_GS_ORIENTATION_UPSIDEDOWN:
425                        if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_DOWN, TRUE)) {
426                                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) - 1);
427                        }
428                        break;
429                default:
430                        break;
431                }
432                break;
433        case GDK_Left:
434                if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_LEFT, FALSE) &&
435                   ggv_postscript_view_get_page_flip(ps_view))
436                        ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) - 1);
437                break;
438        case GDK_Right:
439                if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_RIGHT, FALSE) &&
440                   ggv_postscript_view_get_page_flip(ps_view))
441                        ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) + 1);
442                break;
443        case GDK_Up:
444                if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_UP, FALSE) &&
445                   ggv_postscript_view_get_page_flip(ps_view))
446                        ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) - 1);
447                break;
448        case GDK_Down:
449                if(!gtk_gs_scroll_step(gs, GTK_SCROLL_STEP_DOWN, FALSE) &&
450                   ggv_postscript_view_get_page_flip(ps_view))
451                        ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) + 1);
452                break;
453        case GDK_Page_Up:
454                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) - 1);
455                break;
456        case GDK_Page_Down:
457                ggv_postscript_view_goto_page(ps_view, gtk_gs_get_current_page(gs) + 1);
458                break;
459        case GDK_plus:
460                g_signal_emit_by_name(G_OBJECT (control->priv->zoomable),
461                                                          "zoom_in");
462                break;
463        case GDK_minus:
464                g_signal_emit_by_name(G_OBJECT(control->priv->zoomable),
465                                                          "zoom_out");
466                break;
467        default:
468                return FALSE;
469        }
470
471        return TRUE;
472}
473
474static void
475verb_ZoomIn_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
476{
477        GgvControl *control;
478
479        g_return_if_fail (user_data != NULL);
480        g_return_if_fail (GGV_IS_CONTROL (user_data));
481
482        control = GGV_CONTROL (user_data);
483
484        g_signal_emit_by_name (G_OBJECT (control->priv->zoomable),
485                                                   "zoom_in");
486}
487
488static void
489verb_ZoomOut_cb (BonoboUIComponent *uic, gpointer user_data, const char *cname)
490{
491        GgvControl *control;
492
493        g_return_if_fail (user_data != NULL);
494        g_return_if_fail (GGV_IS_CONTROL (user_data));
495
496        control = GGV_CONTROL (user_data);
497
498        g_signal_emit_by_name (G_OBJECT (control->priv->zoomable),
499                                                   "zoom_out");
500}
501
502static void
503verb_ZoomToDefault_cb (BonoboUIComponent *uic, gpointer user_data,
504                                           const char *cname)
505{
506        GgvControl *control;
507
508        g_return_if_fail (user_data != NULL);
509        g_return_if_fail (GGV_IS_CONTROL (user_data));
510
511        control = GGV_CONTROL (user_data);
512
513        g_signal_emit_by_name (G_OBJECT (control->priv->zoomable),
514                                                   "zoom_to_default");
515}
516
517static void
518verb_ZoomToFit_cb (BonoboUIComponent *uic, gpointer user_data,
519                                   const char *cname)
520{
521        GgvControl *control;
522
523        g_return_if_fail (user_data != NULL);
524        g_return_if_fail (GGV_IS_CONTROL (user_data));
525
526        control = GGV_CONTROL (user_data);
527
528        g_signal_emit_by_name (G_OBJECT (control->priv->zoomable),
529                                                   "zoom_to_fit");
530}
531
532static void
533verb_ZoomToFitWidth_cb (BonoboUIComponent *uic, gpointer user_data,
534                                                const char *cname)
535{
536        GgvControl *control;
537        gfloat zoom_level;
538
539        g_return_if_fail (user_data != NULL);
540        g_return_if_fail (GGV_IS_CONTROL (user_data));
541
542        control = GGV_CONTROL (user_data);
543
544        zoom_level = ggv_postscript_view_zoom_to_fit(control->priv->ps_view, TRUE);
545
546        g_signal_emit_by_name(G_OBJECT(control->priv->zoomable), "set_zoom_level",
547                                                  zoom_level);
548
549}
550
551static void
552_set_zoom_items_sensitivity(GgvControl *control, BonoboUIComponent *uic, gboolean sens)
553{
554        gchar *prop_val = sens?"1":"0";
555        Bonobo_UIContainer container;
556        gint i;
557
558        container = bonobo_ui_component_get_container (uic);
559        if (container == CORBA_OBJECT_NIL)
560                return;
561
562        bonobo_ui_component_freeze(uic, NULL);
563        bonobo_ui_component_set_prop(uic, "/commands/ZoomIn",
564                                                                 "sensitive", prop_val, NULL);
565        bonobo_ui_component_set_prop(uic, "/commands/ZoomOut",
566                                                                 "sensitive", prop_val, NULL);
567        bonobo_ui_component_set_prop(uic, "/commands/ZoomToDefault",
568                                                                 "sensitive", prop_val, NULL);
569        bonobo_ui_component_set_prop(uic, "/commands/ZoomToFit",
570                                                                 "sensitive", prop_val, NULL);
571        bonobo_ui_component_set_prop(uic, "/commands/ZoomToFitWidth",
572                                                                 "sensitive", prop_val, NULL);
573        for(i = 0; zoom_level_items[i].path != NULL; i++) {
574                bonobo_ui_component_set_prop(uic, zoom_level_items[i].path,
575                                                                         "sensitive", prop_val, NULL);
576        }
577        bonobo_ui_component_thaw(uic, NULL);
578}
579
580static void
581set_zoom_items_sensitivity(GgvControl *control, gboolean sens)
582{
583        _set_zoom_items_sensitivity(control, control->priv->uic, sens);
584        if(control->priv->popup_uic != NULL)
585                _set_zoom_items_sensitivity(control, control->priv->popup_uic, sens);
586}
587
588static void
589set_auto_fit_items_sensitivity(GgvControl *control, gboolean sens)
590{
591        gchar *prop_val = sens?"1":"0";
592        Bonobo_UIContainer container;
593
594        container = bonobo_ui_component_get_container (control->priv->uic);
595        if (container == CORBA_OBJECT_NIL)
596                return;
597
598        bonobo_ui_component_freeze(control->priv->uic, NULL);
599        bonobo_ui_component_set_prop(control->priv->uic, "/commands/AutoFitNone",
600                                                                 "sensitive", prop_val, NULL);
601        bonobo_ui_component_set_prop(control->priv->uic, "/commands/AutoFitWidth",
602                                                                 "sensitive", prop_val, NULL);
603        bonobo_ui_component_set_prop(control->priv->uic, "/commands/AutoFitPage",
604                                                                 "sensitive", prop_val, NULL);
605        bonobo_ui_component_thaw(control->priv->uic, NULL);     
606}
607
608static void
609set_command_items_sensitivity(GgvControl *control, gboolean sens)
610{
611        set_auto_fit_items_sensitivity(control, sens);
612        set_zoom_items_sensitivity(control, sens);
613}
614
615static BonoboUIVerb ggv_control_verbs[] = {
616                BONOBO_UI_VERB ("ZoomIn",         verb_ZoomIn_cb),
617                BONOBO_UI_VERB ("ZoomOut",        verb_ZoomOut_cb),
618                BONOBO_UI_VERB ("ZoomToDefault",  verb_ZoomToDefault_cb),
619                BONOBO_UI_VERB ("ZoomToFit",      verb_ZoomToFit_cb),
620                BONOBO_UI_VERB ("ZoomToFitWidth", verb_ZoomToFitWidth_cb),
621                BONOBO_UI_VERB_END
622};
623
624extern BonoboUIVerb ggv_postscript_view_verbs[];
625
626static void
627zoom_adj_value_changed_cb(GtkAdjustment *adj, gpointer data)
628{
629        GgvControl *control = GGV_CONTROL(data);
630
631        if(fabs(adj->value - ggv_postscript_view_get_zoom_factor(control->priv->ps_view)) > 0.001) {
632                g_signal_emit_by_name(G_OBJECT (control->priv->zoomable),
633                                                          "set_zoom_level", ((gfloat)adj->value)/100.0);
634        }
635}
636
637static void
638ggv_control_create_ui (GgvControl *control)
639{
640        GgvControlClass *klass;
641        GdkPixbuf *pixbuf, *pixbuf_small;
642        gchar *pixbuf_xml;
643        int i;
644
645        g_return_if_fail (control != NULL);
646        g_return_if_fail (GGV_IS_CONTROL (control));
647
648        klass = GGV_CONTROL_CLASS(G_OBJECT_GET_CLASS(control));
649
650        bonobo_ui_component_freeze(control->priv->uic, NULL);
651        bonobo_ui_util_set_ui(control->priv->uic, DATADIR, "ggv-control-ui.xml",
652                                                  "GGV", NULL);
653                                                                 
654        control->priv->popup_uic = bonobo_control_get_popup_ui_component(BONOBO_CONTROL(control));
655        bonobo_ui_component_freeze(control->priv->popup_uic, NULL);
656        bonobo_ui_util_set_ui(control->priv->popup_uic, NULL, "ggv-postscript-view-ui.xml", "GGV", NULL);
657        bonobo_ui_util_set_ui(control->priv->popup_uic, DATADIR, "ggv-control-ui.xml", "GGV", NULL);
658       
659        pixbuf = gdk_pixbuf_new_from_file(GNOMEICONDIR "/ggv/fitwidth.png", NULL);
660        if(pixbuf != NULL) {
661                pixbuf_xml = bonobo_ui_util_pixbuf_to_xml(pixbuf);
662                bonobo_ui_component_set_prop(control->priv->uic,
663                                                                         "/Toolbar/GgvItems/GgvZoomItems/ZoomToFitWidth",
664                                                                         "pixname", pixbuf_xml,
665                                                                         NULL);
666                g_free(pixbuf_xml);
667                pixbuf_small = gdk_pixbuf_scale_simple(pixbuf, 18, 18, GDK_INTERP_TILES);
668                pixbuf_xml = bonobo_ui_util_pixbuf_to_xml(pixbuf_small);
669                bonobo_ui_component_set_prop(control->priv->uic,
670                                                                         "/menu/View/Zoom Items Placeholder/Zoom/ZoomToFitWidth",
671                                                                         "pixname", pixbuf_xml,
672                                                                         NULL);
673                bonobo_ui_component_set_prop(control->priv->popup_uic,
674                                                                         "/popups/button3/ZoomMenu/ZoomToFitWidth",
675                                                                         "pixname", pixbuf_xml,
676                                                                         NULL);
677                g_free(pixbuf_xml);
678                gdk_pixbuf_unref(pixbuf);
679                gdk_pixbuf_unref(pixbuf_small);
680        }
681
682        for(i = 0; zoom_level_items[i].path; i++) {
683                bonobo_ui_component_add_listener(control->priv->uic,
684                                                                                 zoom_level_items[i].path + strlen("/commands/"),
685                                                                                 listener_ZoomLevel_cb, control);
686        }
687        bonobo_ui_component_add_listener(control->priv->uic,
688                                                                         "AutoFitNone",
689                                                                         listener_AutoFitMode_cb, control);
690        bonobo_ui_component_add_listener(control->priv->uic,
691                                                                         "AutoFitWidth",
692                                                                         listener_AutoFitMode_cb, control);
693        bonobo_ui_component_add_listener(control->priv->uic,
694                                                                         "AutoFitPage",
695                                                                         listener_AutoFitMode_cb, control);
696
697        set_command_items_sensitivity(control, ggv_postscript_view_get_page_count(control->priv->ps_view) > 0);
698
699        sync_command_state(control);
700
701        bonobo_ui_component_add_verb_list_with_data(control->priv->uic,
702                                                                                                ggv_control_verbs,
703                                                                                                control);
704        bonobo_ui_component_add_verb_list_with_data(control->priv->popup_uic,
705                                                                                                ggv_control_verbs,
706                                                                                                control);
707        bonobo_ui_component_add_verb_list_with_data(control->priv->popup_uic,
708                                                                                                ggv_postscript_view_verbs,
709                                                                                                control->priv->ps_view);
710        ggv_postscript_view_set_popup_ui_component(control->priv->ps_view,
711                                                                                           control->priv->popup_uic);
712
713        if(!control->priv->has_zoomable_frame) {
714                BonoboControl *zoom_control;
715                GtkWidget *zoom_spin, *zoom_image, *perc_label, *hbox;
716                GtkObject *zoom_adj;
717
718                hbox = gtk_hbox_new(FALSE, 2);
719                gtk_widget_show(hbox);
720                zoom_image = gtk_image_new_from_file(GNOMEICONDIR "/ggv/zoom.xpm");
721                gtk_widget_show(zoom_image);
722                gtk_box_pack_start(GTK_BOX(hbox), zoom_image, FALSE, TRUE, 0);
723                zoom_adj = gtk_adjustment_new(ggv_postscript_view_get_zoom_factor(control->priv->ps_view)*100.0,
724                                                                          16.67, 600.0, 10.0, 100.0, 100.0);
725                g_signal_connect(G_OBJECT(zoom_adj), "value-changed",
726                                                 G_CALLBACK(zoom_adj_value_changed_cb), control);
727                zoom_spin = gtk_spin_button_new(GTK_ADJUSTMENT(zoom_adj), 1.0, 0);
728                gtk_widget_show(zoom_spin);
729                gtk_box_pack_start(GTK_BOX(hbox), zoom_spin, TRUE, TRUE, 0);
730                perc_label = gtk_label_new("%");
731                gtk_widget_show(perc_label);
732                gtk_box_pack_start(GTK_BOX(hbox), perc_label, FALSE, TRUE, 0);
733
734                zoom_control = bonobo_control_new(hbox);
735                bonobo_ui_component_object_set(control->priv->uic, "/Sidebar/Zoom Control Placeholder/ZoomControl",
736                                                                           BONOBO_OBJREF(zoom_control), NULL);
737                control->priv->zoom_control = zoom_control;
738                control->priv->zoom_adj = zoom_adj;
739        }
740        bonobo_ui_component_thaw(control->priv->uic, NULL);
741        bonobo_ui_component_thaw(control->priv->popup_uic, NULL);
742}
743
744static void
745ggv_control_set_ui_container (GgvControl *control,
746                                                          Bonobo_UIContainer ui_container)
747{
748        g_return_if_fail (control != NULL);
749        g_return_if_fail (GGV_IS_CONTROL (control));
750        g_return_if_fail (ui_container != CORBA_OBJECT_NIL);
751
752        ggv_postscript_view_set_ui_container (control->priv->ps_view,
753                                                                                  ui_container);
754
755        bonobo_ui_component_set_container (control->priv->uic, ui_container, NULL);
756
757        /* NOTE: we always merge our UI, as we have more than merely zoom items
758           to offer. */
759        if(TRUE || !control->priv->has_zoomable_frame) {
760                ggv_control_create_ui(control);
761        }
762}
763
764static void
765ggv_control_unset_ui_container (GgvControl *control)
766{
767        g_return_if_fail (control != NULL);
768        g_return_if_fail (GGV_IS_CONTROL (control));
769
770        ggv_postscript_view_unset_ui_container (control->priv->ps_view);
771
772        bonobo_ui_component_unset_container (control->priv->uic, NULL);
773}
774
775static void
776ggv_control_activate (BonoboControl *object, gboolean state)
777{
778        GgvControl *control;
779
780        g_return_if_fail (object != NULL);
781        g_return_if_fail (GGV_IS_CONTROL (object));
782
783        control = GGV_CONTROL (object);
784
785        if (state) {
786                Bonobo_UIContainer ui_container;
787                       
788                ui_container = bonobo_control_get_remote_ui_container (BONOBO_CONTROL (control), NULL);
789                if (ui_container != CORBA_OBJECT_NIL) {
790                        ggv_control_set_ui_container (control, ui_container);
791                        bonobo_object_release_unref (ui_container, NULL);
792                }
793        } else
794                ggv_control_unset_ui_container (control);
795
796        if (BONOBO_CONTROL_CLASS (ggv_control_parent_class)->activate)
797                BONOBO_CONTROL_CLASS (ggv_control_parent_class)->activate (object, state);
798}
799
800static void
801ggv_control_class_init (GgvControlClass *klass)
802{
803        GObjectClass *object_class = (GObjectClass *)klass;
804        BonoboObjectClass *bonobo_object_class = (BonoboObjectClass *)klass;
805        BonoboControlClass *control_class = (BonoboControlClass *)klass;
806
807        ggv_control_parent_class = gtk_type_class (bonobo_control_get_type ());
808
809        bonobo_object_class->destroy = ggv_control_destroy;
810        object_class->finalize = ggv_control_finalize;
811
812        control_class->activate = ggv_control_activate;
813
814        klass->priv = g_new0(GgvControlClassPrivate, 1);
815}
816
817static void
818ggv_control_init (GgvControl *control)
819{
820        control->priv = g_new0 (GgvControlPrivate, 1);
821}
822
823BONOBO_TYPE_FUNC (GgvControl, BONOBO_TYPE_CONTROL, ggv_control);
824
825static void
826ps_view_property_changed_handler(BonoboListener    *listener,
827                                 char              *event_name,
828                                 CORBA_any         *any,
829                                 CORBA_Environment *ev,
830                                 gpointer           data)
831{
832        GgvControl *control = GGV_CONTROL(data);
833
834        if(!g_ascii_strcasecmp(event_name, "Bonobo/Property:change:page")) {
835                        set_command_items_sensitivity(control, BONOBO_ARG_GET_INT(any) != -1);
836        }
837}
838
839GgvControl *
840ggv_control_construct (GgvControl *control, GgvPostScriptView *ps_view)
841{
842        BonoboPropertyBag     *property_bag;
843        BonoboPropertyControl *property_control;
844        GtkWidget *view;
845        gchar *mask;
846
847        g_return_val_if_fail (ps_view != NULL, NULL);
848        g_return_val_if_fail (control != NULL, NULL);
849        g_return_val_if_fail (GGV_IS_POSTSCRIPT_VIEW (ps_view), NULL);
850        g_return_val_if_fail (GGV_IS_CONTROL (control), NULL);
851
852        control->priv->ps_view = ps_view;
853        bonobo_object_ref (BONOBO_OBJECT (ps_view));
854
855        if (!ggv_postscript_view_add_interfaces (ps_view, BONOBO_OBJECT (control))) {
856                g_message("control: can't add interfaces");
857                return NULL;
858        }
859
860        view = ggv_postscript_view_get_widget (control->priv->ps_view);
861        g_signal_connect(G_OBJECT(view), "key_press_event",
862                                         G_CALLBACK(ggv_control_key_press_event), control);
863        g_signal_connect(G_OBJECT(view), "button_press_event",
864                                         G_CALLBACK(ggv_control_button_press_event), control);
865
866        control->priv->root = gtk_scrolled_window_new(NULL, NULL);
867        gtk_widget_show(control->priv->root);
868        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(control->priv->root),
869                                                                                GTK_SHADOW_IN);
870        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(control->priv->root),
871                                                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
872        g_signal_connect(G_OBJECT(GTK_SCROLLED_WINDOW(control->priv->root)->hscrollbar),
873                                         "button_press_event",
874                                         G_CALLBACK(scrollbar_button_press_event),
875                                         view);
876        g_signal_connect(G_OBJECT(GTK_SCROLLED_WINDOW(control->priv->root)->vscrollbar),
877                                         "button_press_event",
878                                         G_CALLBACK(scrollbar_button_press_event),
879                                         view);
880        g_signal_connect(G_OBJECT(GTK_SCROLLED_WINDOW(control->priv->root)->hscrollbar),
881                                         "button_release_event",
882                                         G_CALLBACK(scrollbar_button_release_event),
883                                         view);
884        g_signal_connect(G_OBJECT(GTK_SCROLLED_WINDOW(control->priv->root)->vscrollbar),
885                                         "button_release_event",
886                                         G_CALLBACK(scrollbar_button_release_event),
887                                         view);
888        gtk_container_add(GTK_CONTAINER(control->priv->root), view);
889        /* unref the GtkGS acquired from GgvPostScriptView */
890        gtk_widget_unref(view);
891       
892        bonobo_control_construct (BONOBO_CONTROL (control), control->priv->root);
893
894        bonobo_object_add_interface (BONOBO_OBJECT (control),
895                                                                 BONOBO_OBJECT (control->priv->ps_view));
896
897        /* Interface Bonobo::Zoomable */
898        control->priv->zoomable = bonobo_zoomable_new ();
899
900        g_signal_connect (G_OBJECT (control->priv->zoomable),
901                                          "set_frame",
902                                          G_CALLBACK (zoomable_set_frame_cb),
903                                          control);
904        g_signal_connect (G_OBJECT (control->priv->zoomable),
905                                          "set_zoom_level",
906                                          G_CALLBACK (zoomable_set_zoom_level_cb),
907                                          control);
908        g_signal_connect (G_OBJECT (control->priv->zoomable),
909                                          "zoom_in",
910                                          G_CALLBACK (zoomable_zoom_in_cb),
911                                          control);
912        g_signal_connect (G_OBJECT (control->priv->zoomable),
913                                          "zoom_out",
914                                          G_CALLBACK (zoomable_zoom_out_cb),
915                                          control);
916        g_signal_connect (G_OBJECT (control->priv->zoomable),
917                                          "zoom_to_fit",
918                                          G_CALLBACK (zoomable_zoom_to_fit_cb),
919                                          control);
920        g_signal_connect (G_OBJECT (control->priv->zoomable),
921                                          "zoom_to_default",
922                                          G_CALLBACK (zoomable_zoom_to_default_cb),
923                                          control);
924
925        control->priv->zoom_level = ggv_postscript_view_get_zoom_factor(ps_view);
926        bonobo_zoomable_set_parameters_full (control->priv->zoomable,
927                                                                                 control->priv->zoom_level,
928                                                                                 ggv_zoom_levels [0],
929                                                                                 ggv_zoom_levels [ggv_max_zoom_levels],
930                                                                                 TRUE, TRUE, TRUE,
931                                                                                 ggv_zoom_levels,
932                                                                                 ggv_zoom_level_names,
933                                                                                 ggv_max_zoom_levels + 1);
934
935        bonobo_object_add_interface (BONOBO_OBJECT (control),
936                                                                 BONOBO_OBJECT (control->priv->zoomable));
937
938        property_bag =
939                ggv_postscript_view_get_property_bag (control->priv->ps_view);
940
941        bonobo_control_set_properties (BONOBO_CONTROL(control),
942                                                                   BONOBO_OBJREF(property_bag), NULL);
943        mask = "Bonobo/Property:change:page";
944        bonobo_event_source_client_add_listener(BONOBO_OBJREF(property_bag),
945                                                                                        (BonoboListenerCallbackFn)ps_view_property_changed_handler,
946                                                                                        mask, NULL, control);
947        bonobo_object_unref (BONOBO_OBJECT (property_bag));
948
949        property_control =
950                ggv_postscript_view_get_property_control (control->priv->ps_view);
951        bonobo_object_add_interface (BONOBO_OBJECT (control),
952                                                                 BONOBO_OBJECT (property_control));
953        bonobo_object_unref(BONOBO_OBJECT(property_control));
954
955        control->priv->uic =
956                bonobo_control_get_ui_component (BONOBO_CONTROL (control));
957
958        return control;
959}
960
961GgvControl *
962ggv_control_new (GgvPostScriptView *ps_view)
963{
964        GgvControl *control;
965       
966        g_return_val_if_fail (ps_view != NULL, NULL);
967        g_return_val_if_fail (GGV_IS_POSTSCRIPT_VIEW (ps_view), NULL);
968
969        control = g_object_new(GGV_CONTROL_TYPE, NULL);
970
971        return ggv_control_construct (control, ps_view);
972}
Note: See TracBrowser for help on using the repository browser.