]> matita.cs.unibo.it Git - helm.git/blob - helm/matita/matitaMathView.ml
- sync with the new ApplyTransformation API
[helm.git] / helm / matita / matitaMathView.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 open Printf
27
28 open MatitaCicMisc
29 open MatitaTypes
30
31 (* List utility functions *)
32 exception Skip
33
34 let list_map_fail f =
35  let rec aux =
36   function
37      [] -> []
38    | he::tl ->
39       try
40        let he' = f he in
41         he'::(aux tl)
42       with Skip ->
43        (aux tl)
44  in
45   aux
46
47 class clickable_math_view obj =
48   let href = Gdome.domString "href" in
49   let xref = Gdome.domString "xref" in
50   object (self)
51     inherit GMathViewAux.multi_selection_math_view obj
52
53     val mutable href_callback: (UriManager.uri -> unit) option = None
54     method set_href_callback f = href_callback <- f
55
56     initializer
57       ignore (self#connect#selection_changed self#choose_selection);
58       ignore (self#connect#click (fun (gdome_elt, _, _, _) ->
59         match gdome_elt with
60         | Some elt  (* element is an hyperlink, use href_callback on it *)
61           when elt#hasAttributeNS ~namespaceURI:Misc.xlink_ns ~localName:href ->
62             (match href_callback with
63             | None -> ()
64             | Some f ->
65                 let uri =
66                   elt#getAttributeNS ~namespaceURI:Misc.xlink_ns ~localName:href
67                 in
68                 f (UriManager.uri_of_string (uri#to_string)))
69         | Some elt -> ignore (self#action_toggle elt)
70         | None -> ()))
71     method private choose_selection gdome_elt =
72       let rec aux elt =
73         if elt#hasAttributeNS ~namespaceURI:Misc.helm_ns ~localName:xref then
74           self#set_selection (Some elt)
75         else
76           try
77             (match elt#get_parentNode with
78             | None -> assert false
79             | Some p -> aux (new Gdome.element_of_node p))
80           with GdomeInit.DOMCastException _ -> ()
81 (*             debug_print "trying to select above the document root" *)
82       in
83       match gdome_elt with
84       | Some elt -> aux elt
85       | None   -> self#set_selection None
86   end
87
88 let clickable_math_view =
89   GtkBase.Widget.size_params
90     ~cont:(OgtkMathViewProps.pack_return (fun p ->
91       OgtkMathViewProps.set_params
92         (new clickable_math_view (GtkMathViewProps.MathView_GMetaDOM.create p))
93         ~font_size:None ~log_verbosity:None))
94     []
95 let clickable_math_view () = clickable_math_view ()
96
97 class proof_viewer obj =
98   object (self)
99
100     inherit clickable_math_view obj
101
102     val mutable current_infos = None
103     val mutable current_mathml = None
104
105     method load_proof ((uri_opt, _, _, _) as proof, (goal_opt: int option)) =
106       let uri = unopt_uri uri_opt in
107       let obj = cicCurrentProof proof in
108       let (mathml, (_,(ids_to_terms, ids_to_father_ids, ids_to_conjectures,
109            ids_to_hypotheses,_,_))) =
110         ApplyTransformation.mml_of_cic_object uri obj
111       in
112       current_infos <- Some (ids_to_terms, ids_to_father_ids,
113         ids_to_conjectures, ids_to_hypotheses);
114       debug_print "load_proof: dumping MathML to ./proof";
115       ignore (Misc.domImpl#saveDocumentToFile ~name:"./proof" ~doc:mathml ());
116       match current_mathml with
117       |  None ->
118           self#load_root ~root:mathml#get_documentElement ;
119           current_mathml <- Some mathml
120       | Some current_mathml ->
121           self#freeze;
122           XmlDiff.update_dom ~from:current_mathml mathml ;
123           self#thaw
124   end
125
126 class sequent_viewer obj =
127   object(self)
128
129     inherit clickable_math_view obj
130
131     val mutable current_infos = None
132
133     method get_selected_terms =
134       let selections = self#get_selections in
135       list_map_fail
136         (fun node ->
137           let xpath =
138             ((node : Gdome.element)#getAttributeNS
139               ~namespaceURI:Misc.helm_ns
140               ~localName:(Gdome.domString "xref"))#to_string
141           in
142           if xpath = "" then assert false (* "ERROR: No xref found!!!" *)
143           else
144             match current_infos with
145             | Some (ids_to_terms,_,_) ->
146                 (try
147                   Hashtbl.find ids_to_terms xpath
148                  with _ -> raise Skip)
149             | None -> assert false) (* "ERROR: No current term!!!" *)
150         selections
151
152     method get_selected_hypotheses =
153       let selections = self#get_selections in
154       list_map_fail
155         (fun node ->
156           let xpath =
157             ((node : Gdome.element)#getAttributeNS
158               ~namespaceURI:Misc.helm_ns
159               ~localName:(Gdome.domString "xref"))#to_string
160           in
161           if xpath = "" then assert false (* "ERROR: No xref found!!!" *)
162           else
163             match current_infos with
164             | Some (_,_,ids_to_hypotheses) ->
165                 (try
166                   Hashtbl.find ids_to_hypotheses xpath
167                 with _ -> raise Skip)
168             | None -> assert false) (* "ERROR: No current term!!!" *)
169         selections
170   
171   method load_sequent metasenv metano =
172 (*
173     let (annconjecture, ids_to_terms, ids_to_father_ids, ids_to_inner_sorts,
174         ids_to_hypotheses) =
175       Cic2acic.asequent_of_sequent metasenv conjecture
176     in
177 *)
178     let sequent = CicUtil.lookup_meta metano metasenv in
179     let (mathml,(_,(ids_to_terms, ids_to_father_ids, ids_to_hypotheses,_))) =
180       ApplyTransformation.mml_of_cic_sequent metasenv sequent
181     in
182     current_infos <- Some (ids_to_terms, ids_to_father_ids, ids_to_hypotheses);
183     debug_print "load_sequent: dumping MathML to ./prova";
184     ignore (Misc.domImpl#saveDocumentToFile ~name:"./prova" ~doc:mathml ());
185     self#load_root ~root:mathml#get_documentElement
186  end
187
188
189 class sequents_viewer ~(notebook:GPack.notebook)
190   ~(sequent_viewer:sequent_viewer) ~set_goal ()
191 =
192   let tab_label metano =
193     (GMisc.label ~text:(sprintf "?%d" metano) ~show:true ())#coerce
194   in
195   object (self)
196     val mutable pages = 0
197     val mutable switch_page_callback = None
198     val mutable page2goal = []  (* associative list: page no -> goal no *)
199     val mutable goal2page = []  (* the other way round *)
200     val mutable goal2win = []   (* associative list: goal no -> scrolled win *)
201     val mutable _metasenv = []
202
203     method reset =
204       for i = 1 to pages do notebook#remove_page 0 done;
205       pages <- 0;
206       page2goal <- [];
207       goal2page <- [];
208       goal2win <- [];
209       _metasenv <- [];
210       (match switch_page_callback with
211       | Some id ->
212           GtkSignal.disconnect notebook#as_widget id;
213           switch_page_callback <- None
214       | None -> ())
215
216     method load_sequents metasenv =
217       let sequents_no = List.length metasenv in
218       _metasenv <- metasenv;
219       pages <- sequents_no;
220       let win metano =
221         let w =
222           GBin.scrolled_window ~hpolicy:`AUTOMATIC ~vpolicy:`AUTOMATIC
223             ~shadow_type:`IN ~show:true ()
224         in
225         let reparent () =
226           match sequent_viewer#misc#parent with
227           | None -> w#add sequent_viewer#coerce
228           | Some _ -> sequent_viewer#misc#reparent w#coerce
229         in
230         goal2win <- (metano, reparent) :: goal2win;
231         w#coerce
232       in
233       let page = ref 0 in
234       List.iter
235         (fun (metano, _, _) ->
236           page2goal <- (!page, metano) :: page2goal;
237           goal2page <- (metano, !page) :: goal2page;
238           incr page;
239           notebook#append_page ~tab_label:(tab_label metano) (win metano))
240         metasenv;
241       switch_page_callback <-
242         Some (notebook#connect#switch_page ~callback:(fun page ->
243           let goal =
244             try
245               List.assoc page page2goal
246             with Not_found -> assert false
247           in
248           set_goal goal;
249           self#render_page ~page ~goal))
250
251     method private render_page ~page ~goal =
252       sequent_viewer#load_sequent _metasenv goal;
253       try
254         List.assoc goal goal2win ();
255         sequent_viewer#set_selection None
256       with Not_found -> assert false
257
258     method goto_sequent goal =
259       let page =
260         try
261           List.assoc goal goal2page
262         with Not_found -> assert false
263       in
264       notebook#goto_page page;
265       self#render_page page goal;
266
267   end
268
269  (** constructors *)
270
271 let sequent_viewer ?hadjustment ?vadjustment ?font_size ?log_verbosity =
272   GtkBase.Widget.size_params
273     ~cont:(OgtkMathViewProps.pack_return (fun p ->
274       OgtkMathViewProps.set_params
275         (new sequent_viewer (GtkMathViewProps.MathView_GMetaDOM.create p))
276         ~font_size ~log_verbosity))
277     []
278
279 class cicBrowser =
280   object (self)
281     val widget =
282       let gui = MatitaGui.instance () in
283       sequent_viewer ~show:true ~packing:gui#browser#scrolledBrowser#add ()
284
285     initializer
286       widget#set_href_callback (Some (fun uri -> self#load_uri uri))
287
288     method load_uri uri = ()
289   end
290
291 let proof_viewer ?hadjustment ?vadjustment ?font_size ?log_verbosity =
292   GtkBase.Widget.size_params
293     ~cont:(OgtkMathViewProps.pack_return (fun p ->
294       OgtkMathViewProps.set_params
295         (new proof_viewer (GtkMathViewProps.MathView_GMetaDOM.create p))
296         ~font_size ~log_verbosity))
297     []
298
299 let proof_viewer_instance =
300   let instance = lazy (
301     let gui = MatitaGui.instance () in
302     proof_viewer ~show:true ~packing:gui#proof#scrolledProof#add ()
303   ) in
304   fun () -> Lazy.force instance
305
306 class mathViewer =
307   let href_callback: (UriManager.uri -> unit) option ref = ref None in
308   object
309     val check_widget =
310       lazy
311         (let gui = MatitaGui.instance () in
312         let sequent_viewer =
313           sequent_viewer ~show:true ~packing:gui#check#scrolledCheck#add ()
314         in
315         sequent_viewer#set_href_callback !href_callback;
316         sequent_viewer)
317
318     method set_href_callback f = href_callback := f
319
320     method checkTerm sequent metasenv =
321       let (metano, context, expr) = sequent in
322       let widget = Lazy.force check_widget in
323       let gui = MatitaGui.instance () in
324       gui#check#checkWin#show ();
325       gui#main#showCheckMenuItem#set_active true;
326       widget#load_sequent (sequent :: metasenv) metano
327
328     method unload () = (proof_viewer_instance ())#unload
329   end
330
331 let sequents_viewer ~(notebook:GPack.notebook)
332   ~(sequent_viewer:sequent_viewer) ~set_goal ()
333 =
334   new sequents_viewer ~notebook ~sequent_viewer ~set_goal ()
335
336 let mathViewer () = new mathViewer
337
338 let cicBrowser () = new cicBrowser
339