]> matita.cs.unibo.it Git - helm.git/blob - helm/gtkmathview-bonobo/src/control-factory.c
ocaml 3.09 transition
[helm.git] / helm / gtkmathview-bonobo / src / control-factory.c
1 /* This file is part of GtkMathView-Bonobo, a Bonobo wrapper for GtkMathView.
2  * Copyright (C) 2003 Luca Padovani <lpadovan@cs.unibo.it>
3  *                    Pouria Masoudi <pmasoudi@cs.unibo.it>
4  * 
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  * 
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  * 
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * For more information, please visit the project's home page
20  * http://helm.cs.unibo.it/gtkmathview-bonobo
21  * or send an email to <lpadovan@cs.unibo.it>
22  */
23
24 #include <config.h>
25
26 #include <bonobo.h>
27 #include <bonobo/bonobo-shlib-factory.h>
28 #include <gtkmathview.h>
29
30 #include "control-factory.h"
31 #include "control-data.h"
32 #include "persist-file.h"
33 #include "persist-stream.h"
34 #include "handlers.h"
35 #include "view.h"
36
37 enum
38   {
39     MATH_VIEW_WIDTH,
40     MATH_VIEW_HEIGHT,
41     MATH_VIEW_TOP_X,
42     MATH_VIEW_TOP_Y,
43     MATH_VIEW_FONT_SIZE,
44     MATH_VIEW_VERBOSITY,
45     MATH_VIEW_ID_NS_URI,
46     MATH_VIEW_ID_NAME
47   } math_args;
48
49 static void
50 activate_maction(GtkMathViewControlData* control_data, guint action, GtkWidget* widget)
51 {
52   GdomeElement* elem;
53
54   g_return_if_fail(control_data != NULL);
55
56   elem = gtk_math_view_get_element_at(control_data->math_view, control_data->x, control_data->y);
57   if (elem != NULL)
58     {
59       GdomeException exc = 0;
60       GdomeElement* action = find_self_or_ancestor(elem, MATHML_NS_URI, "maction");
61       if (action != NULL)
62         {
63           gtk_math_view_freeze(control_data->math_view);
64           action_toggle(action);
65           gtk_math_view_thaw(control_data->math_view);
66           gdome_el_unref(action, &exc);
67           g_assert(exc == 0);
68         }
69       gdome_el_unref(elem, &exc);
70       g_assert(exc == 0);
71     }
72 }
73
74 static void
75 copy_link_address(GtkMathViewControlData* control_data, guint action, GtkWidget* widget)
76 {
77 }
78
79 static void
80 zoom_in(GtkMathViewControlData* control_data, guint action, GtkWidget* widget)
81 {
82   g_return_if_fail(control_data != NULL);
83   guint old_font_size = gtk_math_view_get_font_size(control_data->math_view);
84   gtk_math_view_set_font_size(control_data->math_view, old_font_size + 1);
85 }
86
87 static void
88 zoom_out(GtkMathViewControlData* control_data, guint action, GtkWidget* widget)
89 {
90   g_return_if_fail(control_data != NULL);
91   guint old_font_size = gtk_math_view_get_font_size(control_data->math_view);
92   gtk_math_view_set_font_size(control_data->math_view, old_font_size - 1);
93 }
94
95 static void
96 switch_semantic_selection(GtkMathViewControlData* control_data, guint action, GtkWidget* widget)
97 {
98   g_return_if_fail(control_data != NULL);
99   control_data->semantic_selection = !control_data->semantic_selection;
100   if (control_data->semantic_selection)
101     {
102       GdomeElement* elem = find_element_with_id(control_data->root_selected,
103                                                 control_data->id_ns_uri,
104                                                 control_data->id_name);
105     }
106 }
107
108 /*
109 static void
110 copy_selected_markup(GtkMathViewControlData* control_data, guint action, GtkWidget* widget)
111 {
112   gchar* res = copy_markup(control_data->root_selected);
113   if (res != NULL)
114     {
115       set_clipboard(res);
116       g_free(res);
117     }
118 }
119 */
120
121 static void
122 copy_selected_id(GtkMathViewControlData* control_data, guint action, GtkWidget* widget)
123 {
124 }
125
126 static void
127 select_parent(GtkMathViewControlData* control_data, guint action, GtkWidget* widget)
128 {
129   g_return_if_fail(control_data != NULL);
130   if (control_data->root_selected != NULL)
131     {
132       GdomeException exc = 0;
133       GdomeNode* parent_node = gdome_el_parentNode(control_data->root_selected, &exc);
134       g_assert(parent_node != NULL);
135       g_assert(exc == 0);
136       GdomeElement* parent = gdome_cast_el(parent_node);
137       gtk_math_view_control_data_set_root_selected(control_data, parent);
138       gdome_n_unref(parent_node, &exc);
139       g_assert(exc == 0);
140     }
141 }
142
143 static void
144 deselect(GtkMathViewControlData* control_data, guint action, GtkWidget* widget)
145 {
146   g_return_if_fail(control_data != NULL);
147
148   if (control_data->root_selected != NULL)
149     {
150       gtk_math_view_unselect(control_data->math_view, control_data->root_selected);
151       control_data->root_selected = NULL;
152     }
153 }
154
155 /* Our menu, an array of GtkItemFactoryEntry structures that defines each menu item */
156 static GtkItemFactoryEntry menu_items[] = {
157   { "/Activate <maction>", NULL,    activate_maction, 0, "<StockItem>", GTK_STOCK_EXECUTE },
158   { "/Copy Link Address",  NULL,    copy_link_address, 0, "<StockItem>", GTK_STOCK_COPY },
159   /*  { "/Jump To",       NULL,         NULL,           0, "<StockItem>", GTK_STOCK_JUMP_TO }, */
160   { "/sep1",          NULL,         NULL,           0, "<Separator>" },
161   /* { "/Semantic Selection", NULL,    switch_semantic_selection, 0, "<CheckItem>" }, */
162   /* { "/Copy Selected Markup", NULL,  copy_selected_markup, 0, "<Item>" }, */
163   /* { "/Copy Id",       NULL,         copy_selected_id, 0, "<Item>" }, */
164   /*  { "/Show Selected", NULL,         NULL,           0, "<Item>" }, */
165   { "/Select Parent", NULL,         select_parent,  0, "<Item>" },
166   { "/De-Select",     NULL,         deselect, 0, "<StockItem>", GTK_STOCK_CLEAR },
167   { "/sep2",          NULL,         NULL,           0, "<Separator>" },
168   { "/Smaller",       NULL,         zoom_out,       0, "<StockItem>", GTK_STOCK_ZOOM_OUT },
169   { "/Bigger",        NULL,         zoom_in,        0, "<StockItem>", GTK_STOCK_ZOOM_IN },
170   /* { "/Properties...", NULL,         NULL,           0, "<StockItem>", GTK_STOCK_PROPERTIES }, */
171 };
172
173 static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
174
175 void
176 button_pressed_cb(GtkMathView* math_view, GdkEventButton* event, GtkMathViewControlData* control_data)
177 {
178   g_return_if_fail(math_view != NULL);
179   g_return_if_fail(event != NULL);
180   g_return_if_fail(control_data != NULL);
181
182   if (event->button == 3)
183     {
184 #if 0
185       gtk_menu_popup (GTK_MENU(control_data->popup_menu), NULL, NULL,
186                       NULL, event, event->button, event->time);
187 #endif
188       control_data->x = (gint) event->x;
189       control_data->y = (gint) event->y;
190       printf("data %d %d\n", control_data->x, control_data->y);
191       
192       gtk_item_factory_popup_with_data(control_data->item_factory,
193                                        NULL, NULL, event->x_root, event->y_root,
194                                        event->button, gtk_get_current_event_time());
195     }
196 }
197
198
199 static void
200 get_prop(BonoboPropertyBag* bag,
201          BonoboArg* arg,
202          guint arg_id,
203          CORBA_Environment *ev,
204          gpointer user_data)
205 {
206   GtkMathViewControlData* control_data = user_data;
207   g_assert(control_data != NULL);
208
209   switch (arg_id)
210     {
211     case MATH_VIEW_WIDTH:
212       BONOBO_ARG_SET_INT(arg, gtk_math_view_get_width(control_data->math_view));
213       break;
214     case MATH_VIEW_HEIGHT:
215       BONOBO_ARG_SET_INT(arg, gtk_math_view_get_height(control_data->math_view));
216       break;
217     case MATH_VIEW_TOP_X:
218       {
219         guint top_x;
220         gtk_math_view_get_top(control_data->math_view, &top_x, NULL);
221         BONOBO_ARG_SET_INT(arg, top_x);
222       }
223       break;
224     case MATH_VIEW_TOP_Y:
225       {
226         guint top_y;
227         gtk_math_view_get_top(control_data->math_view, NULL, &top_y);
228         BONOBO_ARG_SET_INT(arg, top_y);
229       }         
230       break;
231     case MATH_VIEW_FONT_SIZE:
232       BONOBO_ARG_SET_INT(arg, gtk_math_view_get_font_size(control_data->math_view));
233       break;
234     case MATH_VIEW_VERBOSITY:
235       BONOBO_ARG_SET_INT(arg, gtk_math_view_get_log_verbosity(control_data->math_view));
236       break;
237     case MATH_VIEW_ID_NS_URI:
238       {
239         gchar* id_ns_uri = gtk_math_view_control_data_get_id_ns_uri(control_data);
240         BONOBO_ARG_SET_STRING(arg, id_ns_uri);
241         g_free(id_ns_uri);
242       }
243       break;
244     case MATH_VIEW_ID_NAME:
245       {
246         gchar* id_name = gtk_math_view_control_data_get_id_name(control_data);
247         BONOBO_ARG_SET_STRING(arg, id_name);
248         g_free(id_name);
249       }
250       break;
251     default:
252       bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
253       break;
254     }
255 }
256
257 static void
258 set_prop(BonoboPropertyBag* bag,
259          const BonoboArg* arg,
260          guint arg_id,
261          CORBA_Environment* ev,
262          gpointer user_data)
263 {
264   GtkMathViewControlData *control_data = user_data;
265   g_assert(control_data != NULL);
266
267   switch (arg_id)
268     {
269     case MATH_VIEW_TOP_X:
270       {
271         guint old_top_y;
272         gtk_math_view_get_top(control_data->math_view, NULL, &old_top_y);
273         gtk_math_view_set_top(control_data->math_view, BONOBO_ARG_GET_INT(arg), old_top_y);
274       }
275       break;
276     case MATH_VIEW_TOP_Y:
277       {
278         guint old_top_x;
279         gtk_math_view_get_top(control_data->math_view, &old_top_x, NULL);
280         gtk_math_view_set_top(control_data->math_view, BONOBO_ARG_GET_INT(arg), old_top_x);
281       }
282       break;
283     case MATH_VIEW_FONT_SIZE:
284       gtk_math_view_set_font_size(control_data->math_view, BONOBO_ARG_GET_INT(arg));
285       break;
286     case MATH_VIEW_VERBOSITY:
287       gtk_math_view_set_log_verbosity(control_data->math_view, BONOBO_ARG_GET_INT(arg));
288       break;
289     case MATH_VIEW_ID_NS_URI:
290       gtk_math_view_control_data_set_id_ns_uri(control_data, BONOBO_ARG_GET_STRING(arg));
291       break;
292     case MATH_VIEW_ID_NAME:
293       gtk_math_view_control_data_set_id_name(control_data, BONOBO_ARG_GET_STRING(arg));
294       break;
295     default:
296       bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
297       break;
298     }
299 }
300
301 static void 
302 control_destroy(BonoboObject *object, GtkMathViewControlData *cd)
303 {
304   gtk_math_view_control_data_destroy(cd);
305 }
306
307 static void 
308 gtk_math_view_control_init(BonoboControl *control, GtkWidget *scrolled_window)
309 {
310   GtkMathViewControlData *control_data;
311   GtkWidget *math_view;
312   GtkItemFactory *item_factory;
313   
314   Bonobo_UIContainer remote_ui_container;
315   BonoboUIComponent *ui_component;
316   
317   BonoboPropertyBag *prop_bag;
318   BonoboObject *persist_file;
319   BonoboObject *persist_stream;
320   BonoboEventSource *evs;
321   View* view;
322
323   math_view = gtk_math_view_new(NULL,NULL);
324   gtk_widget_show(math_view);
325
326   control_data = gtk_math_view_control_data_new(control, (GtkMathView*)math_view);
327   
328   g_signal_connect (control, "destroy", G_CALLBACK (control_destroy), control_data);
329   
330   /* Same as before but don't bother with the accelerators */
331   control_data->item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<main>", NULL);
332   gtk_item_factory_create_items (control_data->item_factory, nmenu_items, menu_items, control_data);
333   /* control_data->popup_menu = gtk_item_factory_get_widget (control_data->item_factory, "<main>"); */
334   /* gtk_widget_ref(control_data->popup_menu); */
335   
336   evs = bonobo_event_source_new();
337   bonobo_object_add_interface(BONOBO_OBJECT(control), BONOBO_OBJECT(evs));
338
339   gtk_container_add(GTK_CONTAINER (scrolled_window), GTK_WIDGET (control_data->math_view));
340
341   view = view_new(control_data);
342   bonobo_object_add_interface(BONOBO_OBJECT(control), BONOBO_OBJECT(view));
343
344   persist_file = gtk_math_view_persist_file_new(GTK_MATH_VIEW(math_view));
345   bonobo_object_add_interface(BONOBO_OBJECT(control), persist_file);
346
347   persist_stream = gtk_math_view_persist_stream_new(GTK_MATH_VIEW(math_view));
348   bonobo_object_add_interface(BONOBO_OBJECT(control), persist_stream);
349
350   prop_bag = bonobo_property_bag_new(get_prop, set_prop, control_data);
351   bonobo_control_set_properties(control, BONOBO_OBJREF(prop_bag), NULL);
352         
353   bonobo_property_bag_add(prop_bag, "width",
354                           MATH_VIEW_WIDTH, BONOBO_ARG_INT,
355                           NULL,
356                           "Width of the view", 0);
357   bonobo_property_bag_add(prop_bag, "height",
358                           MATH_VIEW_HEIGHT, BONOBO_ARG_INT,
359                           NULL,
360                           "Height of the view", 0);
361   bonobo_property_bag_add(prop_bag, "top-x",
362                           MATH_VIEW_TOP_X, BONOBO_ARG_INT,
363                           NULL,
364                           "X coordinate of the top-left corner", 0);
365   bonobo_property_bag_add(prop_bag, "top-y",
366                           MATH_VIEW_TOP_Y, BONOBO_ARG_INT,
367                           NULL, 
368                           "Y coordinate of the top-left corner", 0);
369   bonobo_property_bag_add(prop_bag, "font-size",
370                           MATH_VIEW_FONT_SIZE, BONOBO_ARG_INT,
371                           NULL,
372                           "Default font size", 0);
373   bonobo_property_bag_add(prop_bag,"verbosity",
374                           MATH_VIEW_VERBOSITY, BONOBO_ARG_INT,
375                           NULL,
376                           "Verbosity level", 0);
377   bonobo_property_bag_add(prop_bag, "id-ns-uri",
378                           MATH_VIEW_ID_NS_URI, BONOBO_ARG_STRING,
379                           NULL,
380                           "Namespace URI of ID attribute", 0);
381   bonobo_property_bag_add(prop_bag, "id-name",
382                           MATH_VIEW_ID_NAME, BONOBO_ARG_STRING,
383                           NULL,
384                           "Name of ID attribute", 0);
385
386   bonobo_object_unref(BONOBO_OBJECT(prop_bag));
387   
388   g_signal_connect(control,"set_frame", G_CALLBACK(set_frame), control_data);
389   g_signal_connect(control_data->math_view, "button_press_event", G_CALLBACK (button_pressed_cb),
390                    control_data);
391   g_signal_connect(control_data->math_view, "click", G_CALLBACK (click_cb),
392                    control_data);
393   g_signal_connect(control_data->math_view, "select_begin", G_CALLBACK(select_begin_cb),
394                    control_data);
395   g_signal_connect(control_data->math_view, "select_over", G_CALLBACK(select_over_cb),
396                    control_data);
397   g_signal_connect(control_data->math_view, "select_end", G_CALLBACK(select_end_cb),
398                    control_data);
399   g_signal_connect(control_data->math_view, "select_abort", G_CALLBACK(select_abort_cb),
400                    control_data);
401 }
402
403 static BonoboObject*
404 gtk_math_view_control_factory(BonoboGenericFactory* factory, const gchar* component_id,
405                               gpointer closure)
406 {
407   BonoboControl *control;
408   GtkWidget *scrolled_window;
409   
410   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
411   /* putting SHADOW_NONE screws the plugin window, how's that??? */
412   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
413   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 0);
414   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_window),
415                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
416   gtk_widget_show_all (scrolled_window);
417   
418   control = bonobo_control_new(scrolled_window);
419
420   if(control)
421     {
422       gtk_math_view_control_init(control,scrolled_window);
423       return BONOBO_OBJECT(control);
424     }
425   else
426     return NULL;
427 }
428
429 BONOBO_ACTIVATION_SHLIB_FACTORY (CONTROL_FACTORY_ID, "GtkMathView Factory",
430                                  gtk_math_view_control_factory, NULL);
431