]> matita.cs.unibo.it Git - helm.git/blob - helm/gTopLevel/texTermEditor.ml
First committed version that (may) use the MathML editor to enter formulas.
[helm.git] / helm / gTopLevel / texTermEditor.ml
1 (* Copyright (C) 2000-2002, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://cs.unibo.it/helm/.
24  *)
25
26 (******************************************************************************)
27 (*                                                                            *)
28 (*                               PROJECT HELM                                 *)
29 (*                                                                            *)
30 (*                Claudio Sacerdoti Coen <sacerdot@cs.unibo.it>               *)
31 (*                                 06/01/2002                                 *)
32 (*                                                                            *)
33 (*                                                                            *)
34 (******************************************************************************)
35
36 (* A WIDGET TO ENTER CIC TERMS *)
37
38 class type term_editor =
39  object
40    method coerce : GObj.widget
41    method get_as_string : string
42    method get_metasenv_and_term :
43      context:Cic.context ->
44      metasenv:Cic.metasenv -> Cic.metasenv * Cic.term
45    method reset : unit
46    method set_term : string -> unit
47    method id_to_uris : Disambiguate.domain_and_interpretation ref
48  end
49 ;;
50
51 let empty_id_to_uris = ([],function _ -> None);;
52
53 module Make(C:Disambiguate.Callbacks) =
54   struct
55
56    module Disambiguate' = Disambiguate.Make(C);;
57
58    class term_editor_impl
59     ?packing ?width ?height
60     ?isnotempty_callback ?share_id_to_uris_with () : term_editor
61    =
62     let mmlwidget =
63      GMathViewAux.single_selection_math_view
64       ?packing ?width ?height () in
65     let drawing_area = mmlwidget#get_drawing_area in
66     let _ = drawing_area#misc#set_can_focus true in
67     let _ = drawing_area#misc#grab_focus () in
68     let dictionary =
69      Misc.domImpl#createDocumentFromURI
70       "/home/claudio/miohelm/helm/DEVEL/mathml_editor/dictionary-tex.xml" () in
71     let mml_style =
72      Misc.domImpl#createDocumentFromURI
73       "/home/claudio/miohelm/helm/DEVEL/mathml_editor/xsl/tml-mmlp.xsl" () in
74     let tex_style =
75      Misc.domImpl#createDocumentFromURI
76       "/home/claudio/miohelm/helm/DEVEL/mathml_editor/xsl/tml-tex.xsl" () in
77     let logger =
78      fun l s -> prerr_endline ("TERM_EDITOR (" ^ string_of_int l ^ "): " ^ s) in
79     let tex_editor =
80      Mathml_editor.create dictionary mml_style tex_style logger in
81     let _ =
82      (new GObj.event_ops mmlwidget#coerce#as_widget)#connect#button_press
83       ~callback:(fun _ -> drawing_area#misc#grab_focus () ; true) in
84     let _ =
85      (new GObj.event_ops drawing_area#coerce#as_widget)#connect#focus_in
86        ~callback:
87          (fun _ ->
88            mmlwidget#freeze ;
89            Mathml_editor.cursor_show ~editor:tex_editor ;
90            mmlwidget#thaw ;
91            true) in
92     let _ =
93      (new GObj.event_ops drawing_area#coerce#as_widget)#connect#focus_out
94        ~callback:
95          (fun _ ->
96            mmlwidget#freeze ;
97            Mathml_editor.cursor_hide ~editor:tex_editor ;
98            mmlwidget#thaw ;
99            true) in
100     let _ = Mathml_editor.push tex_editor '$' in
101     let dom_tree = Mathml_editor.get_mml tex_editor in
102     let _ = mmlwidget#load_doc dom_tree in
103     let _ = 
104      drawing_area#event#connect#key_press
105       (function e ->
106         let key = GdkEvent.Key.keyval e in
107          mmlwidget#freeze ;
108 (*CSC: pre-lexer *)
109          if key = GdkKeysyms._space && GdkEvent.Key.state e = [] then
110           begin
111            ignore (Mathml_editor.freeze tex_editor) ;
112            Mathml_editor.push tex_editor '\\' ;
113            Mathml_editor.push tex_editor ';' ;
114            ignore (Mathml_editor.thaw tex_editor)
115           end
116 (*CSC: end of pre-lexer *)
117          else if
118           key >= 32 && key < 256 &&
119            (GdkEvent.Key.state e = [] || GdkEvent.Key.state e = [`SHIFT])
120          then
121           Mathml_editor.push tex_editor (Char.chr key)
122          else if key = GdkKeysyms._u then
123           begin
124            mmlwidget#freeze ;
125            Mathml_editor.reset tex_editor ;
126            Mathml_editor.push tex_editor '$' ;
127            mmlwidget#thaw
128           end
129          else if key = GdkKeysyms._BackSpace then
130           Mathml_editor.drop tex_editor false ;
131          mmlwidget#thaw ;
132          false) in
133     let id_to_uris =
134      match share_id_to_uris_with with
135         None -> ref empty_id_to_uris
136       | Some obj -> obj#id_to_uris
137     in
138     let _ =
139      match isnotempty_callback with
140         None -> ()
141       | Some callback ->
142          (* This approximation of the test that checks if the tree is empty *)
143          (* is utterly unprecise. We assume a tree to look as an empty tree *)
144          (* iff it is made of just one node m:mtext (which should be the    *)
145          (* cursor).                                                        *)
146          let is_empty_tree () =
147           let root = dom_tree#get_documentElement in
148            match root#get_firstChild with
149               None -> true
150             | Some n -> n#get_nodeName#to_string = "m:mtext"
151          in
152           dom_tree#addEventListener
153            ~typ:(Gdome.domString "DOMSubtreeModified")
154            ~listener:
155              (Gdome.eventListener
156                (function _ -> callback (not (is_empty_tree ()))))
157            ~useCapture:false
158     in
159      object(self)
160       method coerce = mmlwidget#coerce
161       method reset =
162        mmlwidget#freeze ;
163        Mathml_editor.reset tex_editor ;
164        Mathml_editor.push tex_editor '$' ;
165        mmlwidget#thaw
166
167       method set_term txt =
168        mmlwidget#freeze ;
169        ignore (Mathml_editor.freeze tex_editor) ;
170        self#reset ;
171        (* we need to remove the initial and final '$' *)
172        let txt' = String.sub txt 1 (String.length txt - 2) in
173         String.iter (fun ch -> Mathml_editor.push tex_editor ch) txt' ;
174         ignore (Mathml_editor.thaw tex_editor) ;
175         mmlwidget#thaw
176
177       method get_as_string =
178        Mathml_editor.get_tex tex_editor
179
180       method get_metasenv_and_term ~context ~metasenv =
181        let name_context =
182         List.map
183          (function
184              Some (n,_) -> Some n
185            | None -> None
186          ) context
187        in
188         let lexbuf = Lexing.from_string self#get_as_string in
189          let dom,mk_metasenv_and_expr =
190           TexCicTextualParserContext.main
191            ~context:name_context ~metasenv TexCicTextualLexer.token lexbuf
192          in
193           let id_to_uris',metasenv,expr =
194            Disambiguate'.disambiguate_input
195             context metasenv dom mk_metasenv_and_expr ~id_to_uris:!id_to_uris
196           in
197            id_to_uris := id_to_uris' ;
198            metasenv,expr
199       method id_to_uris = id_to_uris
200    end
201
202    let term_editor = new term_editor_impl
203
204 end
205 ;;