]> matita.cs.unibo.it Git - helm.git/blob - helm/gTopLevel/texTermEditor.ml
Eureka!
[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    (* get_as_string returns the unquoted string *)
42    method get_as_string : string
43    method get_metasenv_and_term :
44      context:Cic.context ->
45      metasenv:Cic.metasenv -> Cic.metasenv * Cic.term
46    method reset : unit
47    (* The input of set_term is unquoted *)
48    method set_term : string -> unit
49    method environment : DisambiguatingParser.EnvironmentP3.t ref
50  end
51 ;;
52
53 module Make(C:DisambiguateTypes.Callbacks) =
54   struct
55
56    module Disambiguate' = DisambiguatingParser.Make(C);;
57
58    class term_editor_impl
59     mqi_handle
60     ?packing ?width ?height
61     ?isnotempty_callback ?share_environment_with () : term_editor
62    =
63     let mmlwidget =
64      GMathViewAux.single_selection_math_view
65       ?packing ?width ?height () in
66     let drawing_area = mmlwidget#get_drawing_area in
67     let _ = drawing_area#misc#set_can_focus true in
68     let _ = drawing_area#misc#grab_focus () in
69     let logger =
70      fun l s -> prerr_endline ("TERM_EDITOR (" ^ string_of_int l ^ "): " ^ s) in
71     let tex_editor =
72      Mathml_editor.create
73       ~alt_lexer:true
74       ~dictionary_uri:"dictionary-cic.xml"
75       ~mml_uri:Mathml_editor.default_mathml_stylesheet_path
76 (*CSC: togliere il path assoluto
77       ~tml_uri:Mathml_editor.default_tex_stylesheet_path
78 *)
79       ~tml_uri:"/usr/share/editex/tml-litex.xsl"
80       ~log:logger
81     in
82     let _ =
83      (new GObj.event_ops mmlwidget#coerce#as_widget)#connect#button_press
84       ~callback:(fun _ -> drawing_area#misc#grab_focus () ; true) in
85     let _ =
86      (new GObj.event_ops drawing_area#coerce#as_widget)#connect#focus_in
87        ~callback:
88          (fun _ ->
89            mmlwidget#freeze ;
90            Mathml_editor.cursor_show ~editor:tex_editor ;
91            mmlwidget#thaw ;
92            true) in
93     let _ =
94      (new GObj.event_ops drawing_area#coerce#as_widget)#connect#focus_out
95        ~callback:
96          (fun _ ->
97            mmlwidget#freeze ;
98            Mathml_editor.cursor_hide ~editor:tex_editor ;
99            mmlwidget#thaw ;
100            true) in
101     let _ = Mathml_editor.push tex_editor '$' in
102     let dom_tree = Mathml_editor.get_mml tex_editor in
103     let _ = mmlwidget#load_doc dom_tree in
104     let _ = 
105      drawing_area#event#connect#key_press
106       (function e ->
107         let key = GdkEvent.Key.keyval e in
108          mmlwidget#freeze ;
109          if
110           key >= 32 && key < 256 &&
111            (GdkEvent.Key.state e = [] || GdkEvent.Key.state e = [`SHIFT])
112          then
113           Mathml_editor.push tex_editor (Char.chr key)
114          else if key = GdkKeysyms._u then
115           begin
116            mmlwidget#freeze ;
117            ignore (Mathml_editor.freeze tex_editor) ;
118            Mathml_editor.reset tex_editor ;
119            Mathml_editor.push tex_editor '$' ;
120            ignore (Mathml_editor.thaw tex_editor) ;
121            mmlwidget#thaw
122           end
123          else if key = GdkKeysyms._BackSpace then
124           Mathml_editor.drop tex_editor
125            (List.mem `CONTROL (GdkEvent.Key.state e))
126          else if key = GdkKeysyms._v then
127            ignore (mmlwidget#misc#convert_selection "STRING" Gdk.Atom.primary);
128          let adj = mmlwidget#get_hadjustment in
129           mmlwidget#thaw ;
130           adj#set_value adj#upper ;
131           false) in
132     let environment =
133      match share_environment_with with
134         None ->
135          ref
136           (DisambiguatingParser.EnvironmentP3.of_string
137             DisambiguatingParser.EnvironmentP3.empty)
138       | Some obj -> obj#environment
139     in
140     let _ =
141      match isnotempty_callback with
142         None -> ()
143       | Some callback ->
144          (* This approximation of the test that checks if the tree is empty *)
145          (* is utterly unprecise. We assume a tree to look as an empty tree *)
146          (* iff it is made of just one node m:mtext (which should be the    *)
147          (* cursor).                                                        *)
148          let is_empty_tree () =
149           let root = dom_tree#get_documentElement in
150            match root#get_firstChild with
151               None -> true
152             | Some n -> n#get_nodeName#to_string = "m:mtext"
153          in
154           dom_tree#addEventListener
155            ~typ:(Gdome.domString "DOMSubtreeModified")
156            ~listener:
157              (Gdome.eventListener
158                (function _ -> callback (not (is_empty_tree ()))))
159            ~useCapture:false
160     in
161      object(self)
162
163       initializer
164         ignore (mmlwidget#misc#connect#selection_received
165           ~callback: (fun selection_data ~time ->
166             let input = try selection_data#data with Gpointer.Null -> "" in
167             mmlwidget#freeze ;
168             ignore (Mathml_editor.freeze tex_editor) ;
169             for i = 0 to String.length input - 1 do
170              Mathml_editor.push tex_editor input.[i]
171             done;
172             ignore (Mathml_editor.thaw tex_editor) ;
173             mmlwidget#thaw))
174
175       method coerce = mmlwidget#coerce
176       method reset =
177        mmlwidget#freeze ;
178        ignore (Mathml_editor.freeze tex_editor) ;
179        Mathml_editor.reset tex_editor ;
180        Mathml_editor.push tex_editor '$' ;
181        ignore (Mathml_editor.thaw tex_editor) ;
182        mmlwidget#thaw
183
184       (* The input of set_term is unquoted *)
185       method set_term txt =
186        mmlwidget#freeze ;
187        ignore (Mathml_editor.freeze tex_editor) ;
188        self#reset ;
189        let txt' = Str.global_replace (Str.regexp "_") "\\_" txt in
190         String.iter (fun ch -> Mathml_editor.push tex_editor ch) txt' ;
191         ignore (Mathml_editor.thaw tex_editor) ;
192         mmlwidget#thaw
193
194       (* get_as_string returns the unquoted string *)
195       method get_as_string =
196        let term = Mathml_editor.get_tex tex_editor in
197         Str.global_replace (Str.regexp "^\\$\\$?") ""
198          (Str.global_replace (Str.regexp "\\$\\$?$") ""
199            (Str.global_replace (Str.regexp "\\\\_") "_" term))
200
201       method get_metasenv_and_term ~context ~metasenv =
202        let name_context =
203         List.map
204          (function
205              Some (n,_) -> Some n
206            | None -> None
207          ) context
208        in
209 prerr_endline ("###CSC: " ^ (Mathml_editor.get_tex tex_editor)) ;
210         let environment',metasenv,expr =
211          Disambiguate'.disambiguate_term mqi_handle 
212           context metasenv (Mathml_editor.get_tex tex_editor) !environment
213         in
214          environment := environment' ;
215          metasenv,expr
216
217       method environment = environment
218    end
219
220    let term_editor = new term_editor_impl
221
222 end
223 ;;