source: trunk/third/bonobo/gshell/gshell.c @ 15579

Revision 15579, 16.7 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15578, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * This program is a bonobo container whith an emacs like user interface
3 * (based on sample-container from  Nat Friedman (nat@nat.org))
4 *
5 * Author:
6 *   Dietmar Maurer (dietmar@maurer-it.com)
7 *
8 * Copyright 1999 Maurer IT Systemlösungen (http://www.maurer-it.com)
9 */
10
11#include <config.h>
12#include "gshell.h"
13#include "inout.h"
14#include "ui.h"
15#include "properties.h"
16#include "controls.h"
17#include <liboaf/liboaf.h>
18
19Application app;
20
21static void
22verb_HelpGNOME_cb (BonoboUIComponent *component, Frame *frame, const char *cname)
23{
24        gchar *p;
25
26        p = gnome_help_file_path ("help-browser", "default-page.html");
27        if (p)
28                gnome_help_goto (NULL, p);
29}
30
31static void
32verb_HelpAbout_cb (BonoboUIComponent *component, Frame *frame, const char *cname)
33{
34        static GtkWidget *about;
35
36        const gchar *authors[] = {
37                "Dietmar Maurer",
38                NULL
39        };
40
41        about = gnome_about_new
42                ( "Gnome Shell", VERSION,
43                  "Copyright (C) 1999 Maurer IT Systemlösungen"
44                  "                     ",
45                  authors,
46                  _("This program is part of the GNOME project. "
47                    "Gnome Shell comes with ABSOLUTELY NO "
48                    "WARRANTY. This is free software, and you are "
49                    "welcome to redistribute it under the conditions "
50                    "of the GNU General Public License. "
51                    "Please report bugs to dietmar@maurer-it.com"),
52                  NULL);
53       
54        gtk_widget_show (about);
55}
56
57static void
58verb_SettingsPreferences_cb (BonoboUIComponent *component,
59                             Frame *frame, const char *cname)
60{
61        show_property_dialog (
62                BONOBO_CONTROL_FRAME (frame->active_view_frame));
63}
64
65Frame *
66get_active_frame (GtkWidget *widget)
67{
68        GtkWidget *top;
69        GList *l;
70        Frame *frame;
71
72        g_return_val_if_fail (widget != NULL, NULL);
73        g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
74
75        top = gtk_widget_get_toplevel(widget);
76        for (l = app.frame_list;l;l = l->next) {
77                frame = (Frame *)l->data;
78                if (GTK_WIDGET (frame->win) == top)
79                        return frame;
80        }
81        return NULL;
82}
83
84static void
85container_system_exception_cb (BonoboObject *container_object,
86                               CORBA_Object cobject,
87                               CORBA_Environment *ev, gpointer data)
88{
89        gnome_warning_dialog (_("fatal CORBA exception!  Shutting down..."));
90
91        bonobo_object_unref (BONOBO_OBJECT (app.container));
92
93        gtk_main_quit ();
94}
95
96static void
97client_site_system_exception_cb (BonoboObject *client, CORBA_Object cobject,
98                                 CORBA_Environment *ev, gpointer data)
99{
100        //Buffer *buffer = (Buffer *) data;
101        g_warning ("component shutdown not implemented");
102        //bonobo_object_unref (BONOBO_OBJECT (buffer->client_site));
103}
104
105static void
106view_system_exception_cb (BonoboViewFrame *view_frame, CORBA_Object cobject,
107                          CORBA_Environment *ev, gpointer data)
108{
109        g_warning ("view frame system exception not implemented");
110        bonobo_object_unref (BONOBO_OBJECT (view_frame));
111}
112
113static void
114user_activate_request_cb (BonoboViewFrame *view_frame, Frame *frame)
115{
116
117        if (frame->active_view_frame == view_frame)
118                return;
119
120        if (frame->active_view_frame != NULL) {
121                bonobo_view_frame_view_deactivate (frame->active_view_frame);
122                if (frame->active_view_frame != NULL)
123                        bonobo_view_frame_set_covered
124                                (frame->active_view_frame, TRUE);
125                frame->active_view_frame = NULL;
126        }
127
128        bonobo_view_frame_view_activate (view_frame);
129}
130
131static void
132view_activated_cb (BonoboViewFrame *view_frame, gboolean activated,
133                   Frame *frame)
134{
135        GtkWidget *w;
136
137        if (activated) {
138                if (frame->active_view_frame != NULL) {
139                        g_warning ("View requested to be activated "
140                                   "but there is already "
141                                   "an active View!\n");
142                        return;
143                }
144                bonobo_view_frame_set_covered (view_frame, FALSE);
145                frame->active_view_frame = view_frame;
146                w = bonobo_view_frame_get_wrapper (view_frame);
147                //gtk_container_focus (GTK_CONTAINER(w), GTK_DIR_UP);
148                gtk_widget_grab_focus(w);
149                frame_set_sensitive (frame, TRUE);
150        } else {
151                bonobo_view_frame_set_covered (view_frame, TRUE);
152                if (view_frame == frame->active_view_frame)
153                        frame->active_view_frame = NULL;
154        }                                                   
155}
156
157static void
158zoom_level_changed_cb (GtkWidget *widget, float zoom_level, Frame *frame)
159{
160        gchar *message;
161
162        message = g_strdup_printf (_("New zoom level is %.3g."), zoom_level);
163        bonobo_ui_component_set_status (frame->component, message, NULL);
164        g_free (message);
165}
166
167static void
168buffer_create_zoomable_frame (Buffer *buffer, Frame *frame, BonoboViewFrame *view_frame)
169{
170        Bonobo_Control control;
171        Bonobo_Zoomable zoomable;
172
173        control = bonobo_control_frame_get_control (BONOBO_CONTROL_FRAME (view_frame));
174        zoomable = Bonobo_Unknown_queryInterface (control, "IDL:Bonobo/Zoomable:1.0", NULL);
175        if (zoomable != CORBA_OBJECT_NIL) {
176                g_message ("Zooming interface found");
177                buffer->zoomable_frame = bonobo_zoomable_frame_new ();
178                bonobo_zoomable_frame_bind_to_zoomable (buffer->zoomable_frame, zoomable);
179
180                gtk_signal_connect (GTK_OBJECT (buffer->zoomable_frame), "zoom_level_changed",
181                                    GTK_SIGNAL_FUNC (zoom_level_changed_cb), frame);
182
183                frame_set_zoomable (frame, TRUE);
184        } else
185                frame_set_zoomable (frame, FALSE);
186}
187
188void
189buffer_add_view (Buffer *buffer, Frame *frame, gint pos)
190{
191        BonoboViewFrame *view_frame;
192        GtkWidget *view_widget;
193        GtkWidget *box,*l;
194
195        view_frame = bonobo_client_site_new_view_full (
196                buffer->client_site,
197                bonobo_object_corba_objref (BONOBO_OBJECT (frame->container)),
198                FALSE, TRUE);
199
200        if (!view_frame) {
201                g_warning ("create view failed");
202                return;
203        }
204
205        gtk_object_set_data (GTK_OBJECT(view_frame), "gshell:buffer", buffer);
206        frame->view_list = g_list_append (frame->view_list, view_frame);
207
208        gtk_signal_connect (GTK_OBJECT (view_frame), "system_exception",
209                            view_system_exception_cb, buffer);
210        gtk_signal_connect (GTK_OBJECT (view_frame), "user_activate",
211                            GTK_SIGNAL_FUNC (user_activate_request_cb), frame);
212        gtk_signal_connect (GTK_OBJECT (view_frame), "activated",
213                            GTK_SIGNAL_FUNC (view_activated_cb), frame);
214
215        view_widget = bonobo_view_frame_get_wrapper (view_frame);
216       
217        box = gtk_vbox_new (FALSE,0);
218        gtk_object_set_data (GTK_OBJECT(box), "gshell:view_frame", view_frame);
219
220        l = gtk_label_new (buffer->name);
221        gtk_box_pack_start (GTK_BOX (box), l, FALSE, FALSE, 0);
222        gtk_box_pack_start (GTK_BOX (box), view_widget, TRUE, TRUE, 0);
223
224        gtk_box_pack_end (GTK_BOX (frame->vbox), box, TRUE, TRUE, 0);
225
226        if (pos>=0) gtk_box_reorder_child (GTK_BOX (frame->vbox), box, pos);
227
228        gtk_widget_show_all (box);
229
230        user_activate_request_cb (view_frame, frame);
231
232        buffer_create_zoomable_frame (buffer, frame, view_frame);
233}
234
235static Buffer *
236real_buffer_create (BonoboObjectClient *server)
237{
238        Buffer *buffer;
239        BonoboClientSite *client_site;
240
241        client_site = bonobo_client_site_new (app.container);
242
243        if (!bonobo_client_site_bind_embeddable (client_site, server)) {
244                bonobo_object_unref (BONOBO_OBJECT (server));
245                bonobo_object_unref (BONOBO_OBJECT (client_site));
246                g_warning("Bind component failed");
247                return NULL;
248        }
249
250        bonobo_object_client_unref (server, NULL);
251       
252        buffer = g_new0 (Buffer, 1);
253        buffer->client_site = client_site;
254        buffer->server = server;
255        app.buffer_list = g_list_append (app.buffer_list, buffer);
256
257        gtk_signal_connect (GTK_OBJECT (client_site), "system_exception",
258                            client_site_system_exception_cb, buffer);
259
260        return buffer;
261}
262
263static Buffer *
264real_buffer_create_embeddable (const char *component_oaf_iid)
265{
266        BonoboObjectClient *server;
267
268        server = bonobo_object_activate (component_oaf_iid, 0);
269
270        if (!server) {
271                g_warning ("Launching component failed");
272                return NULL;
273        }
274
275        return real_buffer_create (server);
276}
277
278static Buffer *
279real_buffer_create_control (const char *component_oaf_iid)
280{
281        BonoboObjectClient *server;
282
283        server = gshell_control_wrapper (component_oaf_iid);
284        if (!server) {
285                g_warning ("Launching component failed");
286                return NULL;
287        }
288
289        return real_buffer_create (server);
290}
291
292Buffer *
293buffer_create (const char *component_oaf_iid)
294{
295        Buffer *retval;
296        OAF_ServerInfoList *servers;
297        CORBA_Environment ev;
298        gchar *query;
299
300        CORBA_exception_init (&ev);
301        query = g_strdup_printf ("(iid == '%s') AND repo_ids.has('IDL:Bonobo/Embeddable:1.0')",
302                                 component_oaf_iid);
303        servers = oaf_query (query, NULL, &ev);
304        g_free (query);
305        CORBA_exception_free (&ev);
306
307        if ((servers != NULL) && (servers->_length > 0))
308                retval = real_buffer_create_embeddable (component_oaf_iid);
309        else
310                retval = real_buffer_create_control (component_oaf_iid);
311
312        CORBA_free (servers);
313
314        return retval;
315}
316
317Buffer *
318buffer_create_for_control (const char *component_oaf_iid)
319{
320        return real_buffer_create_control (component_oaf_iid);
321}
322
323static GtkWidget *
324find_view_frame_pos (Frame *frame, BonoboViewFrame *view_frame, gint *pos)
325{
326        GList *l;
327        gint i = 0;
328        GtkObject *o = NULL;
329
330        l = GTK_BOX(frame->vbox)->children;
331       
332        while (l && (o = GTK_OBJECT (((GtkBoxChild *)l->data)->widget)) &&
333               (gtk_object_get_data (o, "gshell:view_frame") != view_frame)) {
334                i++; l = l->next;
335        }
336
337        if (pos) *pos = i;
338
339        if (o)
340                return GTK_WIDGET (o);
341
342        return NULL;
343}
344
345gint
346view_remove (Frame *frame, BonoboViewFrame *view_frame)
347{
348        GtkWidget *w,*b;
349        gint pos;
350
351        w = bonobo_view_frame_get_wrapper (view_frame);
352        frame->view_list = g_list_remove (frame->view_list, view_frame);
353        if (frame->active_view_frame == view_frame)
354                frame->active_view_frame = NULL;
355
356        b = find_view_frame_pos (frame, view_frame, &pos);
357       
358        gtk_widget_destroy (w);
359        bonobo_object_unref (BONOBO_OBJECT (view_frame));
360
361        if (b)
362                gtk_widget_destroy (b);
363
364        return pos;
365}
366
367static void
368frame_close_cb (GtkWidget *widget, Frame *frame)
369{
370        BonoboViewFrame *view_frame;
371        GList *v;
372
373        while ((v = frame->view_list)) {
374                view_frame = (BonoboViewFrame *)v->data;
375                view_remove (frame, view_frame);
376        }
377
378        app.frame_list = g_list_remove (app.frame_list, frame);
379        gtk_widget_destroy (GTK_WIDGET (frame->win));
380        if (!g_list_length(app.frame_list))
381                gtk_main_quit ();
382}
383
384static void
385verb_FileExit_cb (BonoboUIComponent *component, Frame *frame, const char *cname)
386{
387        bonobo_object_unref (BONOBO_OBJECT (app.container));
388        gtk_main_quit ();
389}
390
391static void
392verb_WindowClose_cb (BonoboUIComponent *component, Frame *frame, const char *cname)
393{
394        frame_close_cb (NULL, frame);
395}
396
397static Frame *
398frame_create ()
399{
400        Frame *frame;
401        GtkWidget *statusbar;
402
403        frame = g_new0 (Frame, 1);
404        frame->win = BONOBO_WINDOW (bonobo_window_new ("gshell", "Gnome Shell"));
405
406        gtk_window_set_default_size (GTK_WINDOW (frame->win), 640, 400);
407        gtk_window_set_policy (GTK_WINDOW (frame->win), TRUE, TRUE, FALSE);
408
409        gtk_signal_connect (GTK_OBJECT (frame->win), "delete_event",
410                            GTK_SIGNAL_FUNC (frame_close_cb), frame);
411
412        statusbar = gtk_statusbar_new ();
413
414        frame->vbox = gtk_vbox_new (FALSE, 0);
415        bonobo_window_set_contents (frame->win, frame->vbox);
416
417        frame->container = bonobo_ui_container_new ();
418        bonobo_ui_container_set_win (frame->container, frame->win);
419
420        frame_create_ui (frame);
421        frame_set_sensitive (frame, FALSE);
422        frame_set_zoomable (frame, FALSE);
423
424        gtk_widget_show_all (GTK_WIDGET (frame->win));
425
426        app.frame_list = g_list_append (app.frame_list, frame);
427
428        return frame;
429}
430
431BonoboViewFrame *
432get_active_view_frame (Frame *frame)
433{
434        GtkWidget *w = NULL;
435        BonoboViewFrame *view_frame = NULL;
436
437        if (!(w = GTK_CONTAINER(frame->vbox)->focus_child)) {
438                if (g_list_length(frame->view_list)) {
439                        view_frame = BONOBO_VIEW_FRAME(frame->view_list->data);
440                        return view_frame;
441                }
442
443        }
444
445        if (w)
446                return gtk_object_get_data (GTK_OBJECT (w),
447                                            "gshell:view_frame");
448
449        return NULL;
450}
451
452static void
453verb_WindowCreateNew_cb (BonoboUIComponent *component, Frame *frame, const char *cname)
454{
455        BonoboViewFrame *view_frame;
456        Buffer *buffer = NULL;
457
458        if ((view_frame = get_active_view_frame (frame))) {
459                buffer = gtk_object_get_data(GTK_OBJECT(view_frame),
460                                             "gshell:buffer");
461        }
462
463        frame = frame_create ();
464        if (buffer)
465                buffer_add_view (buffer, frame, -1);
466        update_buffer_menu ();
467}
468
469static void
470verb_WindowSplit_cb (BonoboUIComponent *component, Frame *frame, const char *cname)
471{
472        BonoboViewFrame *view_frame;
473        Buffer *buffer = NULL;
474        gint pos;
475
476        if ((view_frame = get_active_view_frame (frame))) {
477                find_view_frame_pos (frame, view_frame, &pos);
478                buffer = gtk_object_get_data(GTK_OBJECT(view_frame),
479                                             "gshell:buffer");
480                if (buffer)
481                        buffer_add_view (buffer, frame, pos);
482        }
483}
484
485static void
486verb_WindowOne_cb (BonoboUIComponent *component, Frame *frame, const char *cname)
487{
488        BonoboViewFrame *view_frame, *vf;
489        GList *v;
490
491        if ((view_frame = get_active_view_frame (frame))) {
492                for (v = frame->view_list; v;) {
493                        vf = (BonoboViewFrame *) v->data;
494                        v = v->next;
495                        if (view_frame != vf)
496                                view_remove (frame, vf);
497                }
498        }
499}
500
501static void
502verb_FileKill_cb (BonoboUIComponent *component, Frame *frame, const char *cname)
503{
504        Buffer *buffer=NULL;
505        BonoboViewFrame *view_frame;
506        GList *f,*v,*b;
507        gchar *path;
508
509        if ((view_frame = get_active_view_frame (frame))) {
510                buffer = gtk_object_get_data(GTK_OBJECT(view_frame),
511                                             "gshell:buffer");
512        } else
513                return;   
514       
515        if (!buffer)
516                return;   
517
518        app.buffer_list = g_list_remove (app.buffer_list, buffer);
519
520        for (f = app.frame_list; f; f = f->next) {
521                frame = (Frame *) f->data;
522
523                for (v = frame->view_list; v;) {
524
525                        view_frame = (BonoboViewFrame *) v->data;
526                        v = v->next;
527                        if (buffer == gtk_object_get_data (
528                                GTK_OBJECT(view_frame), "gshell:buffer")) {
529                                view_remove (frame, view_frame);
530
531                                if (!g_list_length (GTK_BOX (frame->vbox)->children)) {
532
533                                        if ((b = g_list_last (app.buffer_list)))
534                                                buffer_add_view ((Buffer *) b->data,
535                                                                 frame, -1);
536                                        else
537                                                frame_set_sensitive (frame, FALSE);
538                                }
539                        }
540                }
541        }
542
543        bonobo_object_unref (BONOBO_OBJECT (buffer->client_site));
544
545        path = g_strdup_printf ("/commands/%s", buffer->verb);
546        bonobo_ui_component_rm (frame->component, path, NULL);
547        g_free (path);
548
549        update_buffer_menu ();
550
551        if (buffer->name) {
552                g_free (buffer->name);
553                buffer->name = NULL;
554        }
555        g_free (buffer);
556}
557
558void
559open_files (Frame *frame, int argc, char **argv)
560{
561        int i;
562
563        for (i = 1; i < argc; i++)
564                file_open (frame, argv [i]);
565}
566
567static void
568zoom_custom_cb (gchar *string, gpointer user_data)
569{
570        BonoboViewFrame *view_frame;
571        Frame *frame = user_data;
572        gchar *end = NULL;
573        double zoom_level;
574
575        if (string == NULL)
576                return;
577
578        zoom_level = g_strtod (string, &end);
579        if (end && *end != '\x00') {
580                g_warning ("Invalid zoom level `%s'", string);
581                return;
582        }
583
584        view_frame = get_active_view_frame (frame);
585        if (!view_frame)
586                return;
587
588        bonobo_view_frame_set_zoom_factor (view_frame, zoom_level);
589}
590
591static void
592zoom_custom (Frame *frame)
593{
594        GtkWidget *dialog;
595
596        dialog = gnome_request_dialog (FALSE, _("Set zoom level:"), NULL, 10,
597                                       zoom_custom_cb, frame, GTK_WINDOW (frame->win));
598
599        gnome_dialog_run (GNOME_DIALOG (dialog));
600}
601
602static void
603verb_Zoom_cb (BonoboUIComponent *component, Frame *frame, const char *cname)
604{
605        BonoboViewFrame *view_frame;
606        Buffer *buffer = NULL;
607
608        view_frame = get_active_view_frame (frame);
609        if (!view_frame)
610                return;
611
612        buffer = gtk_object_get_data (GTK_OBJECT (view_frame), "gshell:buffer");
613        if (!buffer)
614                return;
615
616        if (!buffer->zoomable_frame)
617                return;
618
619        if (!strcmp (cname, "ZoomIn"))
620                bonobo_zoomable_frame_zoom_in (buffer->zoomable_frame);
621        else if (!strcmp (cname, "ZoomOut"))
622                bonobo_zoomable_frame_zoom_out (buffer->zoomable_frame);
623        else if (!strcmp (cname, "ZoomToFit"))
624                bonobo_zoomable_frame_zoom_to_fit (buffer->zoomable_frame);
625        else if (!strcmp (cname, "ZoomToDefault"))
626                bonobo_zoomable_frame_zoom_to_default (buffer->zoomable_frame);
627        else
628                zoom_custom (frame);
629}
630
631int
632main (int argc, char **argv)
633{
634        CORBA_Environment ev;
635        CORBA_ORB orb;
636        Frame *frame;
637
638        bindtextdomain (PACKAGE, GNOMELOCALEDIR);
639        textdomain (PACKAGE);
640
641        CORBA_exception_init (&ev);
642
643        gnome_init_with_popt_table ("gshell", "1.0",
644                                    argc, argv,
645                                    oaf_popt_options, 0, NULL);
646
647        CORBA_exception_free (&ev);
648
649        orb = oaf_init (argc, argv);
650
651        if (bonobo_init (orb, NULL, NULL) == FALSE)
652                g_error (_("Could not initialize Bonobo!"));
653
654        app.container = bonobo_item_container_new ();
655        gtk_signal_connect (GTK_OBJECT (app.container), "system_exception",
656                            container_system_exception_cb, NULL);
657
658        frame = frame_create ();
659
660        bonobo_activate ();
661
662        open_files (frame, argc, argv);
663
664        bonobo_main ();
665
666        return 0;
667}
668
669BonoboUIVerb gshell_verbs[] = {
670        BONOBO_UI_UNSAFE_VERB ("FileKill", verb_FileKill_cb),
671        BONOBO_UI_UNSAFE_VERB ("FileExit", verb_FileExit_cb),
672        BONOBO_UI_UNSAFE_VERB ("SettingsPreferences", verb_SettingsPreferences_cb),
673        BONOBO_UI_UNSAFE_VERB ("WindowCreateNew", verb_WindowCreateNew_cb),
674        BONOBO_UI_UNSAFE_VERB ("WindowClose", verb_WindowClose_cb),
675        BONOBO_UI_UNSAFE_VERB ("WindowSplit", verb_WindowSplit_cb),
676        BONOBO_UI_UNSAFE_VERB ("WindowOne", verb_WindowOne_cb),
677        BONOBO_UI_UNSAFE_VERB ("ZoomIn", verb_Zoom_cb),
678        BONOBO_UI_UNSAFE_VERB ("ZoomOut", verb_Zoom_cb),
679        BONOBO_UI_UNSAFE_VERB ("ZoomToFit", verb_Zoom_cb),
680        BONOBO_UI_UNSAFE_VERB ("ZoomToDefault", verb_Zoom_cb),
681        BONOBO_UI_UNSAFE_VERB ("WindowZoom", verb_Zoom_cb),
682        BONOBO_UI_UNSAFE_VERB ("HelpGNOME", verb_HelpGNOME_cb),
683        BONOBO_UI_UNSAFE_VERB ("HelpAbout", verb_HelpAbout_cb),
684        BONOBO_UI_VERB_END
685};
686
Note: See TracBrowser for help on using the repository browser.