]> matita.cs.unibo.it Git - helm.git/blobdiff - matita/matita/matitaGui.ml
Merge branch 'declarative' into matita-lablgtk3
[helm.git] / matita / matita / matitaGui.ml
index cd9603f85291ea19b45874d3715122422ac08b06..5b7352d743f9cbaf4ade7b39b3af0cd85fb3cbe7 100644 (file)
@@ -31,19 +31,78 @@ open MatitaGeneratedGui
 open MatitaGtkMisc
 open MatitaMisc
 
-exception Found of int
-
 let all_disambiguation_passes = ref false
 
-let gui_instance = ref None
+(* this is a shit and should be changed :-{ *)
+let interactive_uri_choice
+  ?(selection_mode:[`SINGLE|`MULTIPLE] = `MULTIPLE) ?(title = "")
+  ?(msg = "") ?(nonvars_button = false) ?(hide_uri_entry=false) 
+  ?(hide_try=false) ?(ok_label="_Auto") ?(ok_action:[`SELECT|`AUTO] = `AUTO) 
+  ?copy_cb ()
+  ~id:_ uris
+=
+  if (selection_mode <> `SINGLE) &&
+    (Helm_registry.get_opt_default Helm_registry.get_bool ~default:true "matita.auto_disambiguation")
+  then
+    uris
+  else begin
+    let dialog = new uriChoiceDialog () in
+    if hide_uri_entry then
+      dialog#uriEntryHBox#misc#hide ();
+    if hide_try then
+      begin
+      dialog#uriChoiceSelectedButton#misc#hide ();
+      dialog#uriChoiceConstantsButton#misc#hide ();
+      end;
+    dialog#okLabel#set_label ok_label;  
+    dialog#uriChoiceTreeView#selection#set_mode
+      (selection_mode :> Gtk.Tags.selection_mode);
+    let model = new stringListModel dialog#uriChoiceTreeView in
+    let choices = ref None in
+    (match copy_cb with
+    | None -> ()
+    | Some cb ->
+        dialog#copyButton#misc#show ();
+        connect_button dialog#copyButton 
+        (fun _ ->
+          match model#easy_selection () with
+          | [u] -> (cb u)
+          | _ -> ()));
+    dialog#uriChoiceDialog#set_title title;
+    dialog#uriChoiceLabel#set_text msg;
+    List.iter model#easy_append (List.map NReference.string_of_reference uris);
+    dialog#uriChoiceConstantsButton#misc#set_sensitive nonvars_button;
+    let return v =
+      choices := v;
+      dialog#uriChoiceDialog#destroy ();
+      GMain.Main.quit ()
+    in
+    ignore (dialog#uriChoiceDialog#event#connect#delete (fun _ -> true));
+    connect_button dialog#uriChoiceConstantsButton (fun _ ->
+      return (Some uris));
+    if ok_action = `AUTO then
+      connect_button dialog#uriChoiceAutoButton (fun _ ->
+        Helm_registry.set_bool "matita.auto_disambiguation" true;
+        return (Some uris))
+    else
+      connect_button dialog#uriChoiceAutoButton (fun _ ->
+        match model#easy_selection () with
+        | [] -> ()
+        | uris -> return (Some (List.map NReference.reference_of_string uris)));
+    connect_button dialog#uriChoiceSelectedButton (fun _ ->
+      match model#easy_selection () with
+      | [] -> ()
+      | uris -> return (Some (List.map NReference.reference_of_string uris)));
+    connect_button dialog#uriChoiceAbortButton (fun _ -> return None);
+    dialog#uriChoiceDialog#show ();
+    (* CSC: old Gtk2 code. Use #run instead. Look for similar code handling
+       other dialogs *)
+    GtkThread.main ();
+    (match !choices with 
+    | None -> raise MatitaTypes.Cancel
+    | Some uris -> uris)
+  end
 
-class type browserWin =
-  (* this class exists only because GEdit.combo_box_entry is not supported by
-   * lablgladecc :-(((( *)
-object
-  inherit MatitaGeneratedGui.browserWin
-  method browserUri: GEdit.entry
-end
 
 class console ~(buffer: GText.buffer) () =
   object (self)
@@ -66,24 +125,28 @@ class console ~(buffer: GText.buffer) () =
       | `Warning -> self#warning (s ^ "\n")
   end
         
-let clean_current_baseuri grafite_status = 
-  LibraryClean.clean_baseuris [grafite_status#baseuri]
+let clean_current_baseuri status = 
+  LibraryClean.clean_baseuris [status#baseuri]
 
-let save_moo grafite_status = 
-  let script = MatitaScript.current () in
-  let baseuri = grafite_status#baseuri in
+let save_moo0 ~do_clean script status = 
+  let baseuri = status#baseuri in
   match script#bos, script#eos with
   | true, _ -> ()
   | _, true ->
      GrafiteTypes.Serializer.serialize ~baseuri:(NUri.uri_of_string baseuri)
-      grafite_status
-  | _ -> clean_current_baseuri grafite_status 
+      status
+  | _ -> if do_clean then clean_current_baseuri status 
+;;
+
+let save_moo status = 
+ let script = MatitaScript.current () in
+  save_moo0 ~do_clean:true script status
 ;;
     
-let ask_unsaved parent =
+let ask_unsaved parent filename =
   MatitaGtkMisc.ask_confirmation 
     ~parent ~title:"Unsaved work!" 
-    ~message:("Your work is <b>unsaved</b>!\n\n"^
+    ~message:("Script <b>" ^ filename ^ "</b> is modified.!\n\n"^
          "<i>Do you want to save the script before continuing?</i>")
     ()
 
@@ -115,7 +178,7 @@ class interpErrorModel =
               (let loc_row = tree_store#append () in
                 begin
                  match lll with
-                    [passes,envs_and_diffs,_,_] ->
+                    [passes,_envs_and_diffs,_,_] ->
                       tree_store#set ~row:loc_row ~column:id_col
                        ("Error location " ^ string_of_int (!idx1+1) ^
                         ", error message " ^ string_of_int (!idx1+1) ^ ".1" ^
@@ -191,8 +254,8 @@ class interpErrorModel =
 
 exception UseLibrary;;
 
-let rec interactive_error_interp ~all_passes
-  (source_buffer:GSourceView2.source_buffer) notify_exn offset errorll filename
+let interactive_error_interp ~all_passes
+  (source_buffer:GSourceView3.source_buffer) notify_exn offset errorll filename
 = 
   (* hook to save a script for each disambiguation error *)
   if false then
@@ -255,10 +318,12 @@ let rec interactive_error_interp ~all_passes
           (MultiPassDisambiguator.DisambiguationError
             (offset,[[env,diff,lazy (loffset,Lazy.force msg),significant]]));
     | _::_ ->
+      GtkThread.sync (fun _ ->
        let dialog = new disambiguationErrors () in
-       dialog#check_widgets ();
-       if all_passes then
-        dialog#disambiguationErrorsMoreErrors#misc#set_sensitive false;
+       dialog#toplevel#add_button "Fix this interpretation" `OK;
+       dialog#toplevel#add_button "Close" `DELETE_EVENT;
+       if not all_passes then
+        dialog#toplevel#add_button "More errors" `HELP; (* HELP means MORE *)
        let model = new interpErrorModel dialog#treeview choices in
        dialog#disambiguationErrors#set_title "Disambiguation error";
        dialog#disambiguationErrorsLabel#set_label
@@ -290,125 +355,83 @@ let rec interactive_error_interp ~all_passes
             (MultiPassDisambiguator.DisambiguationError
               (offset,[[env,diff,lazy(loffset,Lazy.force msg),significant]]))
            ));
-       let return _ =
-         dialog#disambiguationErrors#destroy ();
-         GMain.Main.quit ()
+   (match GtkThread.sync dialog#toplevel#run () with
+    | `OK ->
+       let tree_path =
+        match fst (dialog#treeview#get_cursor ()) with
+           None -> assert false
+        | Some tp -> tp in
+       let idx1,idx2,idx3 = model#get_interp_no tree_path in
+       let diff =
+        match idx2,idx3 with
+           Some idx2, Some idx3 ->
+            let _,lll = List.nth choices idx1 in
+            let _,envs_and_diffs,_,_ = List.nth lll idx2 in
+            let _,_,diff = List.nth envs_and_diffs idx3 in
+             diff
+         | _,_ -> assert false
        in
-       let fail _ = return () in
-       ignore(dialog#disambiguationErrors#event#connect#delete (fun _ -> true));
-       connect_button dialog#disambiguationErrorsOkButton
-        (fun _ ->
-          let tree_path =
-           match fst (dialog#treeview#get_cursor ()) with
-              None -> assert false
-           | Some tp -> tp in
-          let idx1,idx2,idx3 = model#get_interp_no tree_path in
-          let diff =
-           match idx2,idx3 with
-              Some idx2, Some idx3 ->
-               let _,lll = List.nth choices idx1 in
-               let _,envs_and_diffs,_,_ = List.nth lll idx2 in
-               let _,_,diff = List.nth envs_and_diffs idx3 in
-                diff
-            | _,_ -> assert false
-          in
-           let newtxt =
-            String.concat "\n"
-             ("" ::
-               List.map
-                (fun k,desc -> 
-                  let alias =
-                   match k with
-                   | DisambiguateTypes.Id id ->
-                       GrafiteAst.Ident_alias (id, desc)
-                   | DisambiguateTypes.Symbol (symb, i)-> 
-                       GrafiteAst.Symbol_alias (symb, i, desc)
-                   | DisambiguateTypes.Num i ->
-                       GrafiteAst.Number_alias (i, desc)
-                  in
-                   GrafiteAstPp.pp_alias alias)
-                diff) ^ "\n"
-           in
-            source_buffer#insert
-             ~iter:
-               (source_buffer#get_iter_at_mark
-                (`NAME "beginning_of_statement")) newtxt ;
-            return ()
-        );
-       connect_button dialog#disambiguationErrorsMoreErrors
-        (fun _ -> return () ; raise UseLibrary);
-       connect_button dialog#disambiguationErrorsCancelButton fail;
-       dialog#disambiguationErrors#show ();
-       GtkThread.main ()
-
-
-(** Selection handling
- * Two clipboards are used: "clipboard" and "primary".
- * "primary" is used by X, when you hit the middle button mouse is content is
- *    pasted between applications. In Matita this selection always contain the
- *    textual version of the selected term.
- * "clipboard" is used inside Matita only and support ATM two different targets:
- *    "TERM" and "PATTERN", in the future other targets like "MATHMLCONTENT" may
- *    be added
- *)
+        let newtxt =
+         String.concat "\n"
+          ("" ::
+            List.map
+             (fun k,desc -> 
+               let alias =
+                match k with
+                | DisambiguateTypes.Id id ->
+                    GrafiteAst.Ident_alias (id, desc)
+                | DisambiguateTypes.Symbol (symb, i)-> 
+                    GrafiteAst.Symbol_alias (symb, i, desc)
+                | DisambiguateTypes.Num i ->
+                    GrafiteAst.Number_alias (i, desc)
+               in
+                GrafiteAstPp.pp_alias alias)
+             diff) ^ "\n"
+        in
+         source_buffer#insert
+          ~iter:
+            (source_buffer#get_iter_at_mark
+             (`NAME "beginning_of_statement")) newtxt
+    | `HELP (* HELP MEANS MORE *) ->
+        dialog#toplevel#destroy () ;
+        raise UseLibrary
+    | `DELETE_EVENT -> ()
+    | _ -> assert false) ;
+   dialog#toplevel#destroy ()
+  ) ()
 
 class gui () =
     (* creation order _is_ relevant for windows placement *)
   let main = new mainWin () in
-  let fileSel = new fileSelectionWin () in
+  let sequents_viewer =
+   MatitaMathView.sequentsViewer_instance main#sequentsNotebook in
   let findRepl = new findReplWin () in
   let keyBindingBoxes = (* event boxes which should receive global key events *)
     [ main#mainWinEventBox ]
   in
   let console = new console ~buffer:main#logTextView#buffer () in
-  let (source_view: GSourceView2.source_view) =
-    GSourceView2.source_view
-      ~auto_indent:true
-      ~insert_spaces_instead_of_tabs:true ~tab_width:2
-      ~right_margin_position:80 ~show_right_margin:true
-      ~smart_home_end:`AFTER
-      ~packing:main#scriptScrolledWin#add
-      ()
-  in
-  let default_font_size =
-    Helm_registry.get_opt_default Helm_registry.int
-      ~default:BuildTimeConf.default_font_size "matita.font_size"
-  in
-  let similarsymbols_tag_name = "similarsymbolos" in
-  let similarsymbols_tag = `NAME similarsymbols_tag_name in
-  let source_buffer = source_view#source_buffer in
   object (self)
     val mutable chosen_file = None
     val mutable _ok_not_exists = false
     val mutable _only_directory = false
-    val mutable font_size = default_font_size
-    val mutable similarsymbols = []
-    val mutable similarsymbols_orig = []
-    val clipboard = GData.clipboard Gdk.Atom.clipboard
-    val primary = GData.clipboard Gdk.Atom.primary
+    val mutable current_page = -1
       
-    method private reset_similarsymbols =
-      similarsymbols <- []; 
-      similarsymbols_orig <- []; 
-      try source_buffer#delete_mark similarsymbols_tag
-      with GText.No_such_mark _ -> ()
-   
     initializer
       let s () = MatitaScript.current () in
-        (* glade's check widgets *)
-      List.iter (fun w -> w#check_widgets ())
-        (let c w = (w :> <check_widgets: unit -> unit>) in
-        [ c fileSel; c main; c findRepl]);
         (* key bindings *)
       List.iter (* global key bindings *)
-        (fun (key, callback) -> self#addKeyBinding key callback)
+        (fun (key, modifiers, callback) -> 
+                self#addKeyBinding key ~modifiers callback)
 (*
         [ GdkKeysyms._F3,
             toggle_win ~check:main#showProofMenuItem proof#proofWin;
           GdkKeysyms._F4,
             toggle_win ~check:main#showCheckMenuItem check#checkWin;
 *)
-        [ ];
+        [ 
+          GdkKeysyms._Page_Down, [`CONTROL], main#scriptNotebook#next_page;
+          GdkKeysyms._Page_Up,   [`CONTROL], main#scriptNotebook#previous_page
+        ];
         (* about win *)
       let parse_txt_file file =
        let ch = open_in (BuildTimeConf.runtime_base_dir ^ "/" ^ file) in
@@ -434,6 +457,7 @@ class gui () =
         ~website:"http://matita.cs.unibo.it"
         ()
       in
+      ignore(about_dialog#event#connect#delete (fun _ -> true));
       ignore(about_dialog#connect#response (fun _ ->about_dialog#misc#hide ()));
       connect_menu_item main#contentsMenuItem (fun () ->
         if 0 = Sys.command "which gnome-help" then
@@ -456,28 +480,30 @@ class gui () =
       in
       let hide_find_Repl () = findRepl#toplevel#misc#hide () in
       let find_forward _ = 
+          let source_view = (s ())#source_view in
           let highlight start end_ =
-            source_buffer#move_mark `INSERT ~where:start;
-            source_buffer#move_mark `SEL_BOUND ~where:end_;
+            source_view#source_buffer#move_mark `INSERT ~where:start;
+            source_view#source_buffer#move_mark `SEL_BOUND ~where:end_;
             source_view#scroll_mark_onscreen `INSERT
           in
           let text = findRepl#findEntry#text in
-          let iter = source_buffer#get_iter `SEL_BOUND in
+          let iter = source_view#source_buffer#get_iter `SEL_BOUND in
           match iter#forward_search text with
           | None -> 
-              (match source_buffer#start_iter#forward_search text with
+              (match source_view#source_buffer#start_iter#forward_search text with
               | None -> ()
               | Some (start,end_) -> highlight start end_)
           | Some (start,end_) -> highlight start end_ 
       in
       let replace _ =
+        let source_view = (s ())#source_view in
         let text = findRepl#replaceEntry#text in
-        let ins = source_buffer#get_iter `INSERT in
-        let sel = source_buffer#get_iter `SEL_BOUND in
+        let ins = source_view#source_buffer#get_iter `INSERT in
+        let sel = source_view#source_buffer#get_iter `SEL_BOUND in
         if ins#compare sel < 0 then 
           begin
-            ignore(source_buffer#delete_selection ());
-            source_buffer#insert text
+            ignore(source_view#source_buffer#delete_selection ());
+            source_view#source_buffer#insert text
           end
       in
       connect_button findRepl#findButton find_forward;
@@ -485,175 +511,51 @@ class gui () =
       connect_button findRepl#cancelButton (fun _ -> hide_find_Repl ());
       ignore(findRepl#toplevel#event#connect#delete 
         ~callback:(fun _ -> hide_find_Repl ();true));
-      let safe_undo =
-       fun () ->
-        (* phase 1: we save the actual status of the marks and we undo *)
-        let locked_mark = `MARK ((MatitaScript.current ())#locked_mark) in
-        let locked_iter = source_view#buffer#get_iter_at_mark locked_mark in
-        let locked_iter_offset = locked_iter#offset in
-        let mark2 =
-         `MARK
-           (source_view#buffer#create_mark ~name:"lock_point"
-             ~left_gravity:true locked_iter) in
-        source_view#source_buffer#undo ();
-        (* phase 2: we save the cursor position and we redo, restoring
-           the previous status of all the marks *)
-        let cursor_iter = source_view#buffer#get_iter_at_mark `INSERT in
-        let mark =
-         `MARK
-           (source_view#buffer#create_mark ~name:"undo_point"
-             ~left_gravity:true cursor_iter)
-        in
-         source_view#source_buffer#redo ();
-         let mark_iter = source_view#buffer#get_iter_at_mark mark in
-         let mark2_iter = source_view#buffer#get_iter_at_mark mark2 in
-         let mark2_iter = mark2_iter#set_offset locked_iter_offset in
-          source_view#buffer#move_mark locked_mark ~where:mark2_iter;
-          source_view#buffer#delete_mark mark;
-          source_view#buffer#delete_mark mark2;
-          (* phase 3: if after the undo the cursor was in the locked area,
-             then we move it there again and we perform a goto *)
-          if mark_iter#offset < locked_iter_offset then
-           begin
-            source_view#buffer#move_mark `INSERT ~where:mark_iter;
-            (MatitaScript.current ())#goto `Cursor ();
-           end;
-          (* phase 4: we perform again the undo. This time we are sure that
-             the text to undo is not locked *)
-          source_view#source_buffer#undo ();
-          source_view#misc#grab_focus () in
-      let safe_redo =
-       fun () ->
-        (* phase 1: we save the actual status of the marks, we redo and
-           we undo *)
-        let locked_mark = `MARK ((MatitaScript.current ())#locked_mark) in
-        let locked_iter = source_view#buffer#get_iter_at_mark locked_mark in
-        let locked_iter_offset = locked_iter#offset in
-        let mark2 =
-         `MARK
-           (source_view#buffer#create_mark ~name:"lock_point"
-             ~left_gravity:true locked_iter) in
-        source_view#source_buffer#redo ();
-        source_view#source_buffer#undo ();
-        (* phase 2: we save the cursor position and we restore
-           the previous status of all the marks *)
-        let cursor_iter = source_view#buffer#get_iter_at_mark `INSERT in
-        let mark =
-         `MARK
-           (source_view#buffer#create_mark ~name:"undo_point"
-             ~left_gravity:true cursor_iter)
-        in
-         let mark_iter = source_view#buffer#get_iter_at_mark mark in
-         let mark2_iter = source_view#buffer#get_iter_at_mark mark2 in
-         let mark2_iter = mark2_iter#set_offset locked_iter_offset in
-          source_view#buffer#move_mark locked_mark ~where:mark2_iter;
-          source_view#buffer#delete_mark mark;
-          source_view#buffer#delete_mark mark2;
-          (* phase 3: if after the undo the cursor is in the locked area,
-             then we move it there again and we perform a goto *)
-          if mark_iter#offset < locked_iter_offset then
-           begin
-            source_view#buffer#move_mark `INSERT ~where:mark_iter;
-            (MatitaScript.current ())#goto `Cursor ();
-           end;
-          (* phase 4: we perform again the redo. This time we are sure that
-             the text to redo is not locked *)
-          source_view#source_buffer#redo ();
-          source_view#misc#grab_focus ()
-      in
-      connect_menu_item main#undoMenuItem safe_undo;
-(*CSC: XXX
-      ignore(source_view#source_buffer#connect#can_undo
-        ~callback:main#undoMenuItem#misc#set_sensitive);
-*) main#undoMenuItem#misc#set_sensitive true;
-      connect_menu_item main#redoMenuItem safe_redo;
-(*CSC: XXX
-      ignore(source_view#source_buffer#connect#can_redo
-        ~callback:main#redoMenuItem#misc#set_sensitive);
-*) main#redoMenuItem#misc#set_sensitive true;
-      ignore(source_view#connect#after#populate_popup
-       ~callback:(fun pre_menu ->
-         let menu = new GMenu.menu pre_menu in
-         let menuItems = menu#children in
-         let undoMenuItem, redoMenuItem =
-          match menuItems with
-             [undo;redo;sep1;cut;copy;paste;delete;sep2;
-              selectall;sep3;inputmethod;insertunicodecharacter] ->
-                List.iter menu#remove [ copy; cut; delete; paste ];
-                undo,redo
-           | _ -> assert false in
-         let add_menu_item =
-           let i = ref 2 in (* last occupied position *)
-           fun ?label ?stock () ->
-             incr i;
-             GMenu.image_menu_item ?label ?stock ~packing:(menu#insert ~pos:!i)
-              ()
-         in
-         let copy = add_menu_item ~stock:`COPY () in
-         let cut = add_menu_item ~stock:`CUT () in
-         let delete = add_menu_item ~stock:`DELETE () in
-         let paste = add_menu_item ~stock:`PASTE () in
-         let paste_pattern = add_menu_item ~label:"Paste as pattern" () in
-         copy#misc#set_sensitive self#canCopy;
-         cut#misc#set_sensitive self#canCut;
-         delete#misc#set_sensitive self#canDelete;
-         paste#misc#set_sensitive self#canPaste;
-         paste_pattern#misc#set_sensitive self#canPastePattern;
-         connect_menu_item copy self#copy;
-         connect_menu_item cut self#cut;
-         connect_menu_item delete self#delete;
-         connect_menu_item paste self#paste;
-         connect_menu_item paste_pattern self#pastePattern;
-         let new_undoMenuItem =
-          GMenu.image_menu_item
-           ~image:(GMisc.image ~stock:`UNDO ())
-           ~use_mnemonic:true
-           ~label:"_Undo"
-           ~packing:(menu#insert ~pos:0) () in
-         new_undoMenuItem#misc#set_sensitive
-          (undoMenuItem#misc#get_flag `SENSITIVE);
-         menu#remove (undoMenuItem :> GMenu.menu_item);
-         connect_menu_item new_undoMenuItem safe_undo;
-         let new_redoMenuItem =
-          GMenu.image_menu_item
-           ~image:(GMisc.image ~stock:`REDO ())
-           ~use_mnemonic:true
-           ~label:"_Redo"
-           ~packing:(menu#insert ~pos:1) () in
-         new_redoMenuItem#misc#set_sensitive
-          (redoMenuItem#misc#get_flag `SENSITIVE);
-          menu#remove (redoMenuItem :> GMenu.menu_item);
-          connect_menu_item new_redoMenuItem safe_redo));
-
+      connect_menu_item main#undoMenuItem
+       (fun () -> (MatitaScript.current ())#safe_undo);
+      main#undoMenuItem#misc#set_sensitive false;
+      connect_menu_item main#redoMenuItem
+       (fun () -> (MatitaScript.current ())#safe_redo);
+      main#redoMenuItem#misc#set_sensitive false;
       connect_menu_item main#editMenu (fun () ->
-        main#copyMenuItem#misc#set_sensitive self#canCopy;
-        main#cutMenuItem#misc#set_sensitive self#canCut;
-        main#deleteMenuItem#misc#set_sensitive self#canDelete;
-        main#pasteMenuItem#misc#set_sensitive self#canPaste;
-        main#pastePatternMenuItem#misc#set_sensitive self#canPastePattern);
-      connect_menu_item main#copyMenuItem self#copy;
-      connect_menu_item main#cutMenuItem self#cut;
-      connect_menu_item main#deleteMenuItem self#delete;
-      connect_menu_item main#pasteMenuItem self#paste;
-      connect_menu_item main#pastePatternMenuItem self#pastePattern;
+        main#copyMenuItem#misc#set_sensitive
+         (MatitaScript.current ())#canCopy;
+        main#cutMenuItem#misc#set_sensitive
+         (MatitaScript.current ())#canCut;
+        main#deleteMenuItem#misc#set_sensitive
+         (MatitaScript.current ())#canDelete;
+        main#pasteMenuItem#misc#set_sensitive
+         (MatitaScript.current ())#canPaste;
+        main#pastePatternMenuItem#misc#set_sensitive
+         (MatitaScript.current ())#canPastePattern);
+      connect_menu_item main#copyMenuItem
+         (fun () -> (MatitaScript.current ())#copy ());
+      connect_menu_item main#cutMenuItem
+         (fun () -> (MatitaScript.current ())#cut ());
+      connect_menu_item main#deleteMenuItem
+         (fun () -> (MatitaScript.current ())#delete ());
+      connect_menu_item main#pasteMenuItem
+         (fun () -> (MatitaScript.current ())#paste ());
+      connect_menu_item main#pastePatternMenuItem
+         (fun () -> (MatitaScript.current ())#pastePattern ());
       connect_menu_item main#selectAllMenuItem (fun () ->
-        source_buffer#move_mark `INSERT source_buffer#start_iter;
-        source_buffer#move_mark `SEL_BOUND source_buffer#end_iter);
+       let source_view = (s ())#source_view in
+        source_view#source_buffer#move_mark `INSERT source_view#source_buffer#start_iter;
+        source_view#source_buffer#move_mark `SEL_BOUND source_view#source_buffer#end_iter);
       connect_menu_item main#findReplMenuItem show_find_Repl;
       connect_menu_item main#externalEditorMenuItem self#externalEditor;
-      connect_menu_item main#ligatureButton self#nextSimilarSymbol;
-      ignore(source_buffer#connect#after#insert_text 
-       ~callback:(fun iter str -> 
-          if main#menuitemAutoAltL#active && (str = " " || str = "\n") then 
-            ignore(self#expand_virtual_if_any iter str)));
+      connect_menu_item main#ligatureButton
+       (fun () -> (MatitaScript.current ())#nextSimilarSymbol);
       ignore (findRepl#findEntry#connect#activate find_forward);
         (* interface lockers *)
       let lock_world _ =
+       let source_view = (s ())#source_view in
         main#buttonsToolbar#misc#set_sensitive false;
         main#scriptMenu#misc#set_sensitive false;
         source_view#set_editable false
       in
       let unlock_world _ =
+       let source_view = (s ())#source_view in
         main#buttonsToolbar#misc#set_sensitive true;
         main#scriptMenu#misc#set_sensitive true;
         source_view#set_editable true;
@@ -661,7 +563,7 @@ class gui () =
         GtkThread.sync (fun () -> ()) ()
       in
       let worker_thread = ref None in
-      let notify_exn exn =
+      let notify_exn (source_view : GSourceView3.source_view) exn =
        let floc, msg = MatitaExcPp.to_string exn in
         begin
          match floc with
@@ -672,56 +574,64 @@ class gui () =
              let locked_mark = script#locked_mark in
              let error_tag = script#error_tag in
              let baseoffset =
-              (source_buffer#get_iter_at_mark (`MARK locked_mark))#offset in
+              (source_view#source_buffer#get_iter_at_mark (`MARK locked_mark))#offset in
              let x' = baseoffset + x in
              let y' = baseoffset + y in
-             let x_iter = source_buffer#get_iter (`OFFSET x') in
-             let y_iter = source_buffer#get_iter (`OFFSET y') in
-             source_buffer#apply_tag error_tag ~start:x_iter ~stop:y_iter;
+             let x_iter = source_view#source_buffer#get_iter (`OFFSET x') in
+             let y_iter = source_view#source_buffer#get_iter (`OFFSET y') in
+             source_view#source_buffer#apply_tag error_tag ~start:x_iter ~stop:y_iter;
              let id = ref None in
-             id := Some (source_buffer#connect#changed ~callback:(fun () ->
-               source_buffer#remove_tag error_tag
-                 ~start:source_buffer#start_iter
-                 ~stop:source_buffer#end_iter;
+             id := Some (source_view#source_buffer#connect#changed ~callback:(fun () ->
+               source_view#source_buffer#remove_tag error_tag
+                 ~start:source_view#source_buffer#start_iter
+                 ~stop:source_view#source_buffer#end_iter;
                match !id with
                | None -> assert false (* a race condition occurred *)
                | Some id ->
-                   (new GObj.gobject_ops source_buffer#as_buffer)#disconnect id));
-             source_buffer#place_cursor
-              (source_buffer#get_iter (`OFFSET x'));
+                   source_view#source_buffer#misc#disconnect id));
+             source_view#source_buffer#place_cursor
+              (source_view#source_buffer#get_iter (`OFFSET x'));
         end;
         HLog.error msg in
-      let locker f () =
+      let locker f script =
+       let source_view = script#source_view in
        let thread_main =
         fun () -> 
           lock_world ();
           let saved_use_library= !MultiPassDisambiguator.use_library in
           try
            MultiPassDisambiguator.use_library := !all_disambiguation_passes;
-           f ();
+           prerr_endline "PRIMA";
+           f script;
            MultiPassDisambiguator.use_library := saved_use_library;
-           unlock_world ()
+           prerr_endline "DOPO";
+           unlock_world () ;
+           prerr_endline "FINE";
           with
            | MultiPassDisambiguator.DisambiguationError (offset,errorll) ->
+              prerr_endline "EXC1";
               (try
                 interactive_error_interp 
-                 ~all_passes:!all_disambiguation_passes source_buffer
-                 notify_exn offset errorll (s())#filename
+                 ~all_passes:!all_disambiguation_passes source_view#source_buffer
+                 (notify_exn source_view) offset errorll (s())#filename
                with
                 | UseLibrary ->
                    MultiPassDisambiguator.use_library := true;
-                   (try f ()
+                   (try f script
                     with
                     | MultiPassDisambiguator.DisambiguationError (offset,errorll) ->
-                       interactive_error_interp ~all_passes:true source_buffer
-                        notify_exn offset errorll (s())#filename
+                       interactive_error_interp ~all_passes:true source_view#source_buffer
+                        (notify_exn source_view) offset errorll (s())#filename
                     | exc ->
-                       notify_exn exc);
-                | exc -> notify_exn exc);
+                       notify_exn source_view exc);
+                | exc -> notify_exn source_view exc);
               MultiPassDisambiguator.use_library := saved_use_library;
-              unlock_world ()
+              prerr_endline "DOPO1";
+              unlock_world ();
+              prerr_endline "FINE1"
            | exc ->
-              (try notify_exn exc with Sys.Break as e -> notify_exn e);
+              (try notify_exn source_view exc
+               with Sys.Break as e -> notify_exn source_view e);
               unlock_world ()
        in
        (*thread_main ();*)
@@ -746,39 +656,12 @@ class gui () =
          match !worker_thread with
             None -> assert false
           | Some t -> interrupt := Some (Thread.id t) in
-      let keep_focus f =
-        fun () ->
+      let keep_focus f (script: MatitaScript.script) =
          try
-          f (); source_view#misc#grab_focus ()
+          f script; script#source_view#misc#grab_focus ()
          with
-          exc -> source_view#misc#grab_focus (); raise exc in
+          exc -> script#source_view#misc#grab_focus (); raise exc in
       
-        (* file selection win *)
-      ignore (fileSel#fileSelectionWin#event#connect#delete (fun _ -> true));
-      ignore (fileSel#fileSelectionWin#connect#response (fun event ->
-        let return r =
-          chosen_file <- r;
-          fileSel#fileSelectionWin#misc#hide ();
-          GMain.Main.quit ()
-        in
-        match event with
-        | `OK ->
-            let fname = fileSel#fileSelectionWin#filename in
-            if Sys.file_exists fname then
-              begin
-                if HExtlib.is_regular fname && not (_only_directory) then 
-                  return (Some fname) 
-                else if _only_directory && HExtlib.is_dir fname then 
-                  return (Some fname)
-              end
-            else
-              begin
-                if _ok_not_exists then 
-                  return (Some fname)
-              end
-        | `CANCEL -> return None
-        | `HELP -> ()
-        | `DELETE_EVENT -> return None));
         (* menus *)
       List.iter (fun w -> w#misc#set_sensitive false) [ main#saveMenuItem ];
         (* console *)
@@ -794,55 +677,51 @@ class gui () =
           else main#tacticsButtonsHandlebox#misc#hide ())
         ~check:main#menuitemPalette;
       connect_button main#butImpl_intro
-        (fun () -> source_buffer#insert "apply rule (⇒#i […] (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (⇒#i […] (…));\n");
       connect_button main#butAnd_intro
-        (fun () -> source_buffer#insert 
+        (fun () -> (s ())#source_view#source_buffer#insert 
           "apply rule (∧#i (…) (…));\n\t[\n\t|\n\t]\n");
       connect_button main#butOr_intro_left
-        (fun () -> source_buffer#insert "apply rule (∨#i_l (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (∨#i_l (…));\n");
       connect_button main#butOr_intro_right
-        (fun () -> source_buffer#insert "apply rule (∨#i_r (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (∨#i_r (…));\n");
       connect_button main#butNot_intro
-        (fun () -> source_buffer#insert "apply rule (¬#i […] (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (¬#i […] (…));\n");
       connect_button main#butTop_intro
-        (fun () -> source_buffer#insert "apply rule (⊤#i);\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (⊤#i);\n");
       connect_button main#butImpl_elim
-        (fun () -> source_buffer#insert 
+        (fun () -> (s ())#source_view#source_buffer#insert 
           "apply rule (⇒#e (…) (…));\n\t[\n\t|\n\t]\n");
       connect_button main#butAnd_elim_left
-        (fun () -> source_buffer#insert "apply rule (∧#e_l (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (∧#e_l (…));\n");
       connect_button main#butAnd_elim_right
-        (fun () -> source_buffer#insert "apply rule (∧#e_r (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (∧#e_r (…));\n");
       connect_button main#butOr_elim
-        (fun () -> source_buffer#insert 
+        (fun () -> (s ())#source_view#source_buffer#insert 
           "apply rule (∨#e (…) […] (…) […] (…));\n\t[\n\t|\n\t|\n\t]\n");
       connect_button main#butNot_elim
-        (fun () -> source_buffer#insert 
+        (fun () -> (s ())#source_view#source_buffer#insert 
           "apply rule (¬#e (…) (…));\n\t[\n\t|\n\t]\n");
       connect_button main#butBot_elim
-        (fun () -> source_buffer#insert "apply rule (⊥#e (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (⊥#e (…));\n");
       connect_button main#butRAA
-        (fun () -> source_buffer#insert "apply rule (RAA […] (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (RAA […] (…));\n");
       connect_button main#butUseLemma
-        (fun () -> source_buffer#insert "apply rule (lem #premises name â€¦);\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (lem #premises name â€¦);\n");
       connect_button main#butDischarge
-        (fun () -> source_buffer#insert "apply rule (discharge […]);\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (discharge […]);\n");
       
       connect_button main#butForall_intro
-        (fun () -> source_buffer#insert "apply rule (∀#i {…} (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (∀#i {…} (…));\n");
       connect_button main#butForall_elim
-        (fun () -> source_buffer#insert "apply rule (∀#e {…} (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (∀#e {…} (…));\n");
       connect_button main#butExists_intro
-        (fun () -> source_buffer#insert "apply rule (∃#i {…} (…));\n");
+        (fun () -> (s ())#source_view#source_buffer#insert "apply rule (∃#i {…} (…));\n");
       connect_button main#butExists_elim
-        (fun () -> source_buffer#insert 
+        (fun () -> (s ())#source_view#source_buffer#insert 
           "apply rule (∃#e (…) {…} […] (…));\n\t[\n\t|\n\t]\n");
 
     
-      (* TO BE REMOVED *)
-      main#scriptNotebook#remove_page 1;
-      main#scriptNotebook#set_show_tabs false;
-      (* / TO BE REMOVED *)
       let module Hr = Helm_registry in
       MatitaGtkMisc.toggle_callback ~check:main#fullscreenMenuItem
         ~callback:(function 
@@ -852,10 +731,9 @@ class gui () =
       MatitaGtkMisc.toggle_callback ~check:main#ppNotationMenuItem
         ~callback:(function b ->
           let s = s () in
-          let status =
-           Interpretations.toggle_active_interpretations s#grafite_status b
+          let _status = Interpretations.toggle_active_interpretations s#status b
           in
-           assert false (* MATITA1.0 ???
+           assert false (* MATITA 1.0 ???
            s#set_grafite_status status*)
          );
       MatitaGtkMisc.toggle_callback ~check:main#hideCoercionsMenuItem
@@ -866,104 +744,47 @@ class gui () =
       main#unicodeAsTexMenuItem#set_active
         (Helm_registry.get_bool "matita.paste_unicode_as_tex");
         (* log *)
-      HLog.set_log_callback self#console#log_callback;
+      HLog.set_log_callback (fun tag msg -> GtkThread.async (self#console#log_callback tag) msg);
       GtkSignal.user_handler :=
         (function 
         | MatitaScript.ActionCancelled s -> HLog.error s
         | exn ->
           if not (Helm_registry.get_bool "matita.debug") then
-           notify_exn exn
+           (* MatitaScript.current is problably wrong, but what else
+              can we do? *)
+           notify_exn (MatitaScript.current ())#source_view exn
           else raise exn);
-        (* script *)
-      let _ =
-       source_buffer#set_language (Some MatitaGtkMisc.matita_lang);
-       source_buffer#set_highlight_syntax true
-      in
-      let disableSave () =
-        (s())#assignFileName None;
-        main#saveMenuItem#misc#set_sensitive false
-      in
-      let saveAsScript () =
-        let script = s () in
-        match self#chooseFile ~ok_not_exists:true () with
-        | Some f -> 
-              HExtlib.touch f;
-              script#assignFileName (Some f);
-              script#saveToFile (); 
-              console#message ("'"^f^"' saved.\n");
-              self#_enableSaveTo f
-        | None -> ()
-      in
-      let saveScript () =
-        let script = s () in
-        if script#has_name then 
-          (script#saveToFile (); 
-          console#message ("'"^script#filename^"' saved.\n"))
-        else saveAsScript ()
-      in
-      let abandon_script () =
-        let grafite_status = (s ())#grafite_status in
-        if source_view#buffer#modified then
-          (match ask_unsaved main#toplevel with
-          | `YES -> saveScript ()
-          | `NO -> ()
-          | `CANCEL -> raise MatitaTypes.Cancel);
-        save_moo grafite_status
-      in
       let loadScript () =
-        let script = s () in 
         try 
           match self#chooseFile () with
-          | Some f -> 
-              abandon_script ();
-              script#reset (); 
-              script#assignFileName (Some f);
-              source_view#source_buffer#begin_not_undoable_action ();
-              script#loadFromFile f; 
-              source_view#source_buffer#end_not_undoable_action ();
-              source_view#buffer#move_mark `INSERT source_view#buffer#start_iter;
-              source_view#buffer#place_cursor source_view#buffer#start_iter;
-              console#message ("'"^f^"' loaded.\n");
-              self#_enableSaveTo f
+          | Some f -> self#loadScript f
           | None -> ()
         with MatitaTypes.Cancel -> ()
       in
-      let newScript () = 
-        abandon_script ();
-        source_view#source_buffer#begin_not_undoable_action ();
-        (s ())#reset (); 
-        (s ())#template (); 
-        source_view#source_buffer#end_not_undoable_action ();
-        disableSave ();
-        (s ())#assignFileName None
-      in
       let cursor () =
-        source_buffer#place_cursor
-          (source_buffer#get_iter_at_mark (`NAME "locked")) in
-      let advance _ = (MatitaScript.current ())#advance (); cursor () in
-      let retract _ = (MatitaScript.current ())#retract (); cursor () in
-      let top _ = (MatitaScript.current ())#goto `Top (); cursor () in
-      let bottom _ = (MatitaScript.current ())#goto `Bottom (); cursor () in
-      let jump _ = (MatitaScript.current ())#goto `Cursor (); cursor () in
-      let advance = locker (keep_focus advance) in
-      let retract = locker (keep_focus retract) in
-      let top = locker (keep_focus top) in
-      let bottom = locker (keep_focus bottom) in
-      let jump = locker (keep_focus jump) in
+       let source_view = (s ())#source_view in
+        source_view#source_buffer#place_cursor
+          (source_view#source_buffer#get_iter_at_mark (`NAME "locked")) in
+      let advance (script: MatitaScript.script) = script#advance (); cursor () in
+      let retract (script: MatitaScript.script) = script#retract (); cursor () in
+      let top (script: MatitaScript.script) = script#goto `Top (); cursor () in
+      let bottom (script: MatitaScript.script) = script#goto `Bottom (); cursor () in
+      let jump (script: MatitaScript.script) = script#goto `Cursor (); cursor () in
+      let advance () = locker (keep_focus advance) (MatitaScript.current ()) in
+      let retract () = locker (keep_focus retract) (MatitaScript.current ()) in
+      let top () = locker (keep_focus top) (MatitaScript.current ()) in
+      let bottom () = locker (keep_focus bottom) (MatitaScript.current ()) in
+      let jump () = locker (keep_focus jump) (MatitaScript.current ()) in
         (* quit *)
       self#setQuitCallback (fun () -> 
-        let script = MatitaScript.current () in
-        if source_view#buffer#modified then
-          match ask_unsaved main#toplevel with
-          | `YES -> 
-               saveScript ();
-               save_moo script#grafite_status;
-               GMain.Main.quit ()
-          | `NO -> GMain.Main.quit ()
-          | `CANCEL -> ()
-        else 
-          (save_moo script#grafite_status;
-          GMain.Main.quit ()));
+       let cancel = ref false in
+        MatitaScript.iter_scripts
+         (fun script ->
+           if not !cancel then
+            if not (self#closeScript0 script) then
+             cancel := true);
+        if not !cancel then
+         GMain.Main.quit ());
       connect_button main#scriptAdvanceButton advance;
       connect_button main#scriptRetractButton retract;
       connect_button main#scriptTopButton top;
@@ -976,27 +797,20 @@ class gui () =
       connect_menu_item main#scriptBottomMenuItem bottom;
       connect_menu_item main#scriptJumpMenuItem jump;
       connect_menu_item main#openMenuItem   loadScript;
-      connect_menu_item main#saveMenuItem   saveScript;
-      connect_menu_item main#saveAsMenuItem saveAsScript;
-      connect_menu_item main#newMenuItem    newScript;
+      connect_menu_item main#saveMenuItem 
+       (fun () -> self#saveScript (MatitaScript.current ()));
+      connect_menu_item main#saveAsMenuItem
+       (fun () -> self#saveAsScript (MatitaScript.current ()));
+      connect_menu_item main#newMenuItem self#newScript;
+      connect_menu_item main#closeMenuItem self#closeCurrentScript;
       connect_menu_item main#showCoercionsGraphMenuItem 
-        (fun _ -> 
-          let c = MatitaMathView.cicBrowser () in
-          c#load (`About `Coercions));
+        (fun _ -> MatitaMathView.cicBrowser (Some (`About `Coercions)));
       connect_menu_item main#showHintsDbMenuItem 
-        (fun _ -> 
-          let c = MatitaMathView.cicBrowser () in
-          c#load (`About `Hints));
+        (fun _ -> MatitaMathView.cicBrowser (Some (`About `Hints)));
       connect_menu_item main#showTermGrammarMenuItem 
-        (fun _ -> 
-          let c = MatitaMathView.cicBrowser () in
-          c#load (`About `Grammar));
+        (fun _ -> MatitaMathView.cicBrowser (Some (`About `Grammar)));
       connect_menu_item main#showUnicodeTable
-        (fun _ -> 
-          let c = MatitaMathView.cicBrowser () in
-          c#load (`About `TeX));
-         (* script monospace font stuff *)  
-      self#updateFontSize ();
+        (fun _ -> MatitaMathView.cicBrowser (Some (`About `TeX)));
         (* debug menu *)
       main#debugMenu#misc#hide ();
         (* HBUGS *)
@@ -1006,8 +820,6 @@ class gui () =
       main#hintMediumImage#set_file (image_path "matita-bulb-medium.png");
       main#hintHighImage#set_file (image_path "matita-bulb-high.png");
       *)
-        (* focus *)
-      self#sourceView#misc#grab_focus ();
         (* main win dimension *)
       let width = Gdk.Screen.width ~screen:(Gdk.Screen.default ()) () in
       let height = Gdk.Screen.height ~screen:(Gdk.Screen.default ()) () in
@@ -1019,177 +831,29 @@ class gui () =
       let script_w = main_w * 6 / 10 in
       main#toplevel#resize ~width:main_w ~height:main_h;
       main#hpaneScriptSequent#set_position script_w;
-        (* source_view *)
-      ignore(source_view#connect#after#paste_clipboard 
-        ~callback:(fun () -> (MatitaScript.current ())#clean_dirty_lock));
-      (* clean_locked is set to true only "during" a PRIMARY paste
-         operation (i.e. by clicking with the second mouse button) *)
-      let clean_locked = ref false in
-      ignore(source_view#event#connect#button_press
-        ~callback:
-          (fun button ->
-            if GdkEvent.Button.button button = 2 then
-             clean_locked := true;
-            false
-          ));
-      ignore(source_view#event#connect#button_release
-        ~callback:(fun button -> clean_locked := false; false));
-      ignore(source_view#buffer#connect#after#apply_tag
-       ~callback:(
-         fun tag ~start:_ ~stop:_ ->
-          if !clean_locked &&
-             tag#get_oid = (MatitaScript.current ())#locked_tag#get_oid
-          then
-           begin
-            clean_locked := false;
-            (MatitaScript.current ())#clean_dirty_lock;
-            clean_locked := true
-           end));
       (* math view handling *)
       connect_menu_item main#newCicBrowserMenuItem (fun () ->
-        ignore(MatitaMathView.cicBrowser ()));
-      connect_menu_item main#increaseFontSizeMenuItem (fun () ->
-        self#increaseFontSize ();
-        MatitaMisc.increase_font_size ();
-        MatitaMathView.update_font_sizes ());
-      connect_menu_item main#decreaseFontSizeMenuItem (fun () ->
-        self#decreaseFontSize ();
-        MatitaMisc.decrease_font_size ();
-        MatitaMathView.update_font_sizes ());
-      connect_menu_item main#normalFontSizeMenuItem (fun () ->
-        self#resetFontSize ();
-        MatitaMisc.reset_font_size ();
-        MatitaMathView.update_font_sizes ());
-      MatitaMisc.reset_font_size ();
-
-      (** selections / clipboards handling *)
-
-    method markupSelected = MatitaMathView.has_selection ()
-    method private textSelected =
-      (source_buffer#get_iter_at_mark `INSERT)#compare
-        (source_buffer#get_iter_at_mark `SEL_BOUND) <> 0
-    method private somethingSelected = self#markupSelected || self#textSelected
-    method private markupStored = MatitaMathView.has_clipboard ()
-    method private textStored = clipboard#text <> None
-    method private somethingStored = self#markupStored || self#textStored
-
-    method canCopy = self#somethingSelected
-    method canCut = self#textSelected
-    method canDelete = self#textSelected
-    method canPaste = self#somethingStored
-    method canPastePattern = self#markupStored
-
-    method copy () =
-      if self#textSelected
-      then begin
-        MatitaMathView.empty_clipboard ();
-        source_view#buffer#copy_clipboard clipboard;
-      end else
-        MatitaMathView.copy_selection ()
-    method cut () =
-      source_view#buffer#cut_clipboard clipboard;
-      MatitaMathView.empty_clipboard ()
-    method delete () = ignore (source_view#buffer#delete_selection ())
-    method paste () =
-      if MatitaMathView.has_clipboard ()
-      then source_view#buffer#insert (MatitaMathView.paste_clipboard `Term)
-      else source_view#buffer#paste_clipboard clipboard;
-      (MatitaScript.current ())#clean_dirty_lock
-    method pastePattern () =
-      source_view#buffer#insert (MatitaMathView.paste_clipboard `Pattern)
-    
-    method private expand_virtual_if_any iter tok =
-      try
-       let len = MatitaGtkMisc.utf8_string_length tok in
-       let last_word =
-        let prev = iter#copy#backward_chars len in
-         prev#get_slice ~stop:(prev#copy#backward_find_char 
-          (fun x -> Glib.Unichar.isspace x || x = Glib.Utf8.first_char "\\"))
-       in
-       let inplaceof, symb = Virtuals.symbol_of_virtual last_word in
-       self#reset_similarsymbols;
-       let s = Glib.Utf8.from_unichar symb in
-       assert(Glib.Utf8.validate s);
-       source_buffer#delete ~start:iter 
-         ~stop:(iter#copy#backward_chars
-           (MatitaGtkMisc.utf8_string_length inplaceof + len));
-       source_buffer#insert ~iter
-         (if inplaceof.[0] = '\\' then s else (s ^ tok));
-       true
-      with Virtuals.Not_a_virtual -> false
-         
-    val similar_memory = Hashtbl.create 97
-    val mutable old_used_memory = false
-
-    method private nextSimilarSymbol () = 
-      let write_similarsymbol s =
-        let s = Glib.Utf8.from_unichar s in
-        let iter = source_buffer#get_iter_at_mark `INSERT in
-        assert(Glib.Utf8.validate s);
-        source_buffer#delete ~start:iter ~stop:(iter#copy#backward_chars 1);
-        source_buffer#insert ~iter:(source_buffer#get_iter_at_mark `INSERT) s;
-        (try source_buffer#delete_mark similarsymbols_tag
-         with GText.No_such_mark _ -> ());
-        ignore(source_buffer#create_mark ~name:similarsymbols_tag_name
-          (source_buffer#get_iter_at_mark `INSERT));
-      in
-      let new_similarsymbol =
-        try
-          let iter_ins = source_buffer#get_iter_at_mark `INSERT in
-          let iter_lig = source_buffer#get_iter_at_mark similarsymbols_tag in
-          not (iter_ins#equal iter_lig)
-        with GText.No_such_mark _ -> true
-      in
-      if new_similarsymbol then
-        (if not(self#expand_virtual_if_any (source_buffer#get_iter_at_mark `INSERT) "")then
-          let last_symbol = 
-            let i = source_buffer#get_iter_at_mark `INSERT in
-            Glib.Utf8.first_char (i#get_slice ~stop:(i#copy#backward_chars 1))
-          in
-          (match Virtuals.similar_symbols last_symbol with
-          | [] ->  ()
-          | eqclass ->
-              similarsymbols_orig <- eqclass;
-              let is_used = 
-                try Hashtbl.find similar_memory similarsymbols_orig  
-                with Not_found -> 
-                  let is_used = List.map (fun x -> x,false) eqclass in
-                  Hashtbl.add similar_memory eqclass is_used; 
-                  is_used
-              in
-              let hd, next, tl = 
-                let used, unused = 
-                  List.partition (fun s -> List.assoc s is_used) eqclass 
-                in
-                match used @ unused with a::b::c -> a,b,c | _ -> assert false
-              in
-              let hd, tl = 
-                if hd = last_symbol then next, tl @ [hd] else hd, (next::tl)
-              in
-              old_used_memory <- List.assoc hd is_used;
-              let is_used = 
-                (hd,true) :: List.filter (fun (x,_) -> x <> hd) is_used
-              in
-              Hashtbl.replace similar_memory similarsymbols_orig is_used;
-              write_similarsymbol hd;
-              similarsymbols <- tl @ [ hd ]))
-      else 
-        match similarsymbols with
-        | [] -> ()
-        | hd :: tl ->
-            let is_used = Hashtbl.find similar_memory similarsymbols_orig in
-            let last = HExtlib.list_last tl in
-            let old_used_for_last = old_used_memory in
-            old_used_memory <- List.assoc hd is_used;
-            let is_used = 
-              (hd, true) :: (last,old_used_for_last) ::
-                List.filter (fun (x,_) -> x <> last && x <> hd) is_used 
-            in
-            Hashtbl.replace similar_memory similarsymbols_orig is_used;
-            similarsymbols <- tl @ [ hd ];
-            write_similarsymbol hd
+        ignore(MatitaMathView.cicBrowser None));
+      connect_menu_item main#increaseFontSizeMenuItem
+        MatitaMisc.increase_font_size;
+      connect_menu_item main#decreaseFontSizeMenuItem
+        MatitaMisc.decrease_font_size;
+      connect_menu_item main#normalFontSizeMenuItem
+        MatitaMisc.reset_font_size;
+      ignore (main#scriptNotebook#connect#switch_page (fun page ->
+        self#save_page ();
+        current_page <- page;
+        let script = MatitaScript.at_page page in
+        script#activate;
+        main#undoMenuItem#misc#set_sensitive
+         script#source_view#source_buffer#can_undo ;
+        main#redoMenuItem#misc#set_sensitive
+         script#source_view#source_buffer#can_redo ;
+        main#saveMenuItem#misc#set_sensitive script#has_name))
 
     method private externalEditor () =
+     let script = MatitaScript.current () in
+     let source_view = script#source_view in
       let cmd = Helm_registry.get "matita.external_editor" in
 (* ZACK uncomment to enable interactive ask of external editor command *)
 (*      let cmd =
@@ -1202,11 +866,10 @@ class gui () =
         ask_text ~gui:self ~title:"External editor" ~msg ~multiline:false
           ~default:(Helm_registry.get "matita.external_editor") ()
       in *)
-      let script = MatitaScript.current () in
       let fname = script#filename in
       let slice mark =
-        source_buffer#start_iter#get_slice
-          ~stop:(source_buffer#get_iter_at_mark mark)
+        source_view#source_buffer#start_iter#get_slice
+          ~stop:(source_view#source_buffer#get_iter_at_mark mark)
       in
       let locked = `MARK script#locked_mark in
       let string_pos mark = string_of_int (String.length (slice mark)) in
@@ -1219,21 +882,21 @@ class gui () =
               cmd))
       in
       let locked_before = slice locked in
-      let locked_offset = (source_buffer#get_iter_at_mark locked)#offset in
+      let locked_offset = (source_view#source_buffer#get_iter_at_mark locked)#offset in
       ignore (Unix.system cmd);
-      source_buffer#set_text (HExtlib.input_file fname);
-      let locked_iter = source_buffer#get_iter (`OFFSET locked_offset) in
-      source_buffer#move_mark locked locked_iter;
-      source_buffer#apply_tag script#locked_tag
-        ~start:source_buffer#start_iter ~stop:locked_iter;
+      source_view#source_buffer#set_text (HExtlib.input_file fname);
+      let locked_iter = source_view#source_buffer#get_iter (`OFFSET locked_offset) in
+      source_view#source_buffer#move_mark locked locked_iter;
+      source_view#source_buffer#apply_tag script#locked_tag
+        ~start:source_view#source_buffer#start_iter ~stop:locked_iter;
       let locked_after = slice locked in
       let line = ref 0 in
       let col = ref 0 in
       try
         for i = 0 to String.length locked_before - 1 do
           if locked_before.[i] <> locked_after.[i] then begin
-            source_buffer#place_cursor
-              ~where:(source_buffer#get_iter (`LINEBYTE (!line, !col)));
+            source_view#source_buffer#place_cursor
+              ~where:(source_view#source_buffer#get_iter (`LINEBYTE (!line, !col)));
             script#goto `Cursor ();
             raise Exit
           end else if locked_before.[i] = '\n' then begin
@@ -1245,8 +908,98 @@ class gui () =
       | Exit -> ()
       | Invalid_argument _ -> script#goto `Bottom ()
 
+    method private saveAsScript script = 
+     match self#chooseFile ~ok_not_exists:true () with
+     | Some f -> 
+           HExtlib.touch f;
+           script#assignFileName (Some f);
+           script#saveToFile (); 
+           console#message ("'"^f^"' saved.\n");
+           self#_enableSaveTo f
+     | None -> ()
+
+    method private saveScript script = 
+     if script#has_name then 
+       (script#saveToFile (); 
+        console#message ("'"^script#filename^"' saved.\n"))
+     else self#saveAsScript script
+    
+    (* returns false if closure is aborted by the user *)
+    method private closeScript0 script = 
+      if script#source_view#buffer#modified then
+        match
+         ask_unsaved main#toplevel (Filename.basename script#filename)
+        with
+        | `YES -> 
+             self#saveScript script;
+             save_moo script#status;
+             true
+        | `NO -> true
+        | `DELETE_EVENT -> false
+      else 
+       (save_moo script#status; true)
+
+    method private closeScript page script = 
+     if self#closeScript0 script then
+      begin
+       MatitaScript.destroy page;
+       ignore (main#scriptNotebook#remove_page page)
+      end
+
+    method private closeCurrentScript () = 
+     let page = main#scriptNotebook#current_page in
+     let script = MatitaScript.at_page page in 
+      self#closeScript page script
+
+    method private save_page () =
+      if current_page >= 0 then
+        let old_script = MatitaScript.at_page current_page in
+        save_moo0 ~do_clean:false old_script old_script#status
+
+    method newScript () = 
+       self#save_page ();
+       let scrolledWindow = GBin.scrolled_window () in
+       let hbox = GPack.hbox () in
+       let tab_label = GMisc.label ~text:"foo" ~packing:hbox#pack () in
+       let _ =
+        GMisc.label ~text:"" ~packing:(hbox#pack ~expand:true ~fill:true) () in
+       let closebutton =
+        GButton.button ~relief:`NONE ~packing:hbox#pack () in
+       let image = GMisc.image ~stock:`CLOSE ~icon_size:`MENU () in
+       closebutton#set_image image#coerce;
+       let script = MatitaScript.script ~parent:scrolledWindow ~tab_label () in
+        ignore (main#scriptNotebook#prepend_page ~tab_label:hbox#coerce
+         scrolledWindow#coerce);
+        ignore (closebutton#connect#clicked (fun () ->
+         self#closeScript
+          (main#scriptNotebook#page_num scrolledWindow#coerce) script));
+        main#scriptNotebook#goto_page 0;
+        sequents_viewer#reset;
+        sequents_viewer#load_logo;
+        let browser_observer _ = MatitaMathView.refresh_all_browsers () in
+        let sequents_observer status =
+          sequents_viewer#reset;
+          match status#ng_mode with
+             `ProofMode ->
+              sequents_viewer#nload_sequents status;
+              (try
+                let goal =
+                 Continuationals.Stack.find_goal status#stack
+                in
+                 sequents_viewer#goto_sequent status goal
+              with Failure _ -> ());
+           | `CommandMode -> sequents_viewer#load_logo
+        in
+        script#addObserver sequents_observer;
+        script#addObserver browser_observer
+
     method loadScript file =       
-      let script = MatitaScript.current () in
+     let page = main#scriptNotebook#current_page in
+     let script = MatitaScript.at_page page in
+      if script#source_view#buffer#modified || script#has_name then
+       self#newScript ();
+     let script = MatitaScript.current () in
+     let source_view = script#source_view in
       script#reset (); 
       script#assignFileName (Some file);
       let file = script#filename in
@@ -1261,196 +1014,79 @@ class gui () =
       source_view#buffer#place_cursor source_view#buffer#start_iter;
       console#message ("'"^file^"' loaded.");
       self#_enableSaveTo file
-      
-    method setStar b =
-      let s = MatitaScript.current () in
-      let w = main#toplevel in
-      let set x = w#set_title x in
-      let name = 
-        "Matita - " ^ Filename.basename s#filename ^ 
-        (if b then "*" else "") ^
-        " in " ^ s#buri_of_current_file 
-      in
-        set name
-        
-    method private _enableSaveTo file =
+
+    method private _enableSaveTo _file =
       self#main#saveMenuItem#misc#set_sensitive true
         
-    method console = console
-    method sourceView: GSourceView2.source_view =
-      (source_view: GSourceView2.source_view)
-    method fileSel = fileSel
-    method findRepl = findRepl
+    method private console = console
+    method private findRepl = findRepl
     method main = main
 
-    method newBrowserWin () =
-      object (self)
-        inherit browserWin ()
-        val combo = GEdit.entry ()
-        initializer
-          self#check_widgets ();
-          let combo_widget = combo#coerce in
-          uriHBox#pack ~from:`END ~fill:true ~expand:true combo_widget;
-          combo#misc#grab_focus ()
-        method browserUri = combo
-      end
-
-    method newUriDialog () =
-      let dialog = new uriChoiceDialog () in
-      dialog#check_widgets ();
-      dialog
-
-    method newConfirmationDialog () =
-      let dialog = new confirmationDialog () in
-      dialog#check_widgets ();
-      dialog
-
-    method newEmptyDialog () =
-      let dialog = new emptyDialog () in
-      dialog#check_widgets ();
-      dialog
-
-    method private addKeyBinding key callback =
-      List.iter (fun evbox -> add_key_binding key callback evbox)
+    method private addKeyBinding key ?modifiers callback =
+(*       List.iter (fun evbox -> add_key_binding key callback evbox) *)
+      List.iter (fun evbox -> connect_key evbox#event key ?modifiers callback)
         keyBindingBoxes
 
-    method setQuitCallback callback =
+    method private setQuitCallback callback =
       connect_menu_item main#quitMenuItem callback;
       ignore (main#toplevel#event#connect#delete 
         (fun _ -> callback ();true));
       self#addKeyBinding GdkKeysyms._q callback
 
-    method chooseFile ?(ok_not_exists = false) () =
-      _ok_not_exists <- ok_not_exists;
-      _only_directory <- false;
-      fileSel#fileSelectionWin#show ();
-      GtkThread.main ();
-      chosen_file
+    method private chooseFileOrDir ok_not_exists only_directory =
+      let fileSel = GWindow.file_chooser_dialog
+       ~action:`OPEN
+       ~title:"Select file"
+       ~modal:true
+       ~type_hint:`DIALOG
+       ~position:`CENTER
+       () in
+     fileSel#add_select_button_stock `OPEN `OK;
+     fileSel#add_button_stock `CANCEL `CANCEL;
+     ignore (fileSel#set_current_folder(Sys.getcwd ())) ;
+     let res =
+      let rec aux () =
+       match fileSel#run () with
+        | `OK ->
+             (match fileSel#filename with
+                None -> aux ()
+              | Some fname ->
+                 if Sys.file_exists fname then
+                   begin
+                     if HExtlib.is_regular fname && not (only_directory) then 
+                       Some fname
+                     else if only_directory && HExtlib.is_dir fname then 
+                       Some fname
+                     else
+                      aux ()
+                   end
+                 else if ok_not_exists then Some fname else aux ())
+        | `CANCEL -> None
+        | `DELETE_EVENT -> None in
+      aux () in
+     fileSel#destroy () ;
+     res
+
+    method private chooseFile ?(ok_not_exists = false) () =
+      self#chooseFileOrDir ok_not_exists false
 
     method private chooseDir ?(ok_not_exists = false) () =
-      _ok_not_exists <- ok_not_exists;
-      _only_directory <- true;
-      fileSel#fileSelectionWin#show ();
-      GtkThread.main ();
       (* we should check that this is a directory *)
-      chosen_file
+      self#chooseFileOrDir ok_not_exists true
   
-    method askText ?(title = "") ?(msg = "") () =
-      let dialog = new textDialog () in
-      dialog#textDialog#set_title title;
-      dialog#textDialogLabel#set_label msg;
-      let text = ref None in
-      let return v =
-        text := v;
-        dialog#textDialog#destroy ();
-        GMain.Main.quit ()
-      in
-      ignore (dialog#textDialog#event#connect#delete (fun _ -> true));
-      connect_button dialog#textDialogCancelButton (fun _ -> return None);
-      connect_button dialog#textDialogOkButton (fun _ ->
-        let text = dialog#textDialogTextView#buffer#get_text () in
-        return (Some text));
-      dialog#textDialog#show ();
-      GtkThread.main ();
-      !text
-
-    method private updateFontSize () =
-      self#sourceView#misc#modify_font_by_name
-        (sprintf "%s %d" BuildTimeConf.script_font font_size)
-
-    method increaseFontSize () =
-      font_size <- font_size + 1;
-      self#updateFontSize ()
-
-    method decreaseFontSize () =
-      font_size <- font_size - 1;
-      self#updateFontSize ()
-
-    method resetFontSize () =
-      font_size <- default_font_size;
-      self#updateFontSize ()
-
   end
 
 let gui () = 
   let g = new gui () in
-  gui_instance := Some g;
-  MatitaMisc.set_gui g;
-  g
+  let rg = (g :> MatitaGuiTypes.gui) in
+  MatitaMisc.set_gui rg;
+  g#newScript ();
+  rg
   
 let instance = singleton gui
 
 let non p x = not (p x)
 
-(* this is a shit and should be changed :-{ *)
-let interactive_uri_choice
-  ?(selection_mode:[`SINGLE|`MULTIPLE] = `MULTIPLE) ?(title = "")
-  ?(msg = "") ?(nonvars_button = false) ?(hide_uri_entry=false) 
-  ?(hide_try=false) ?(ok_label="_Auto") ?(ok_action:[`SELECT|`AUTO] = `AUTO) 
-  ?copy_cb ()
-  ~id uris
-=
-  let gui = instance () in
-  if (selection_mode <> `SINGLE) &&
-    (Helm_registry.get_opt_default Helm_registry.get_bool ~default:true "matita.auto_disambiguation")
-  then
-    uris
-  else begin
-    let dialog = gui#newUriDialog () in
-    if hide_uri_entry then
-      dialog#uriEntryHBox#misc#hide ();
-    if hide_try then
-      begin
-      dialog#uriChoiceSelectedButton#misc#hide ();
-      dialog#uriChoiceConstantsButton#misc#hide ();
-      end;
-    dialog#okLabel#set_label ok_label;  
-    dialog#uriChoiceTreeView#selection#set_mode
-      (selection_mode :> Gtk.Tags.selection_mode);
-    let model = new stringListModel dialog#uriChoiceTreeView in
-    let choices = ref None in
-    (match copy_cb with
-    | None -> ()
-    | Some cb ->
-        dialog#copyButton#misc#show ();
-        connect_button dialog#copyButton 
-        (fun _ ->
-          match model#easy_selection () with
-          | [u] -> (cb u)
-          | _ -> ()));
-    dialog#uriChoiceDialog#set_title title;
-    dialog#uriChoiceLabel#set_text msg;
-    List.iter model#easy_append (List.map NReference.string_of_reference uris);
-    dialog#uriChoiceConstantsButton#misc#set_sensitive nonvars_button;
-    let return v =
-      choices := v;
-      dialog#uriChoiceDialog#destroy ();
-      GMain.Main.quit ()
-    in
-    ignore (dialog#uriChoiceDialog#event#connect#delete (fun _ -> true));
-    connect_button dialog#uriChoiceConstantsButton (fun _ ->
-      return (Some uris));
-    if ok_action = `AUTO then
-      connect_button dialog#uriChoiceAutoButton (fun _ ->
-        Helm_registry.set_bool "matita.auto_disambiguation" true;
-        return (Some uris))
-    else
-      connect_button dialog#uriChoiceAutoButton (fun _ ->
-        match model#easy_selection () with
-        | [] -> ()
-        | uris -> return (Some (List.map NReference.reference_of_string uris)));
-    connect_button dialog#uriChoiceSelectedButton (fun _ ->
-      match model#easy_selection () with
-      | [] -> ()
-      | uris -> return (Some (List.map NReference.reference_of_string uris)));
-    connect_button dialog#uriChoiceAbortButton (fun _ -> return None);
-    dialog#uriChoiceDialog#show ();
-    GtkThread.main ();
-    (match !choices with 
-    | None -> raise MatitaTypes.Cancel
-    | Some uris -> uris)
-  end
-
 class interpModel =
   let cols = new GTree.column_list in
   let id_col = cols#add Gobject.Data.string in
@@ -1501,68 +1137,65 @@ class interpModel =
 
 
 let interactive_string_choice 
-  text prefix_len ?(title = "") ?(msg = "") () ~id locs uris 
+  text prefix_len ?(title = "") ?msg:(_ = "") () ~id:_ locs uris 
 = 
-  let gui = instance () in
   let dialog = gui#newUriDialog () in
   dialog#uriEntryHBox#misc#hide ();
   dialog#uriChoiceSelectedButton#misc#hide ();
   dialog#uriChoiceAutoButton#misc#hide ();
   dialog#uriChoiceConstantsButton#misc#hide ();
   dialog#uriChoiceTreeView#selection#set_mode
-      (`SINGLE :> Gtk.Tags.selection_mode);
   let model = new stringListModel dialog#uriChoiceTreeView in
   let choices = ref None in
   dialog#uriChoiceDialog#set_title title; 
   let hack_len = MatitaGtkMisc.utf8_string_length text in
   let rec colorize acc_len = function
-      | [] -> 
-          let floc = HExtlib.floc_of_loc (acc_len,hack_len) in
-          escape_pango_markup (fst(MatitaGtkMisc.utf8_parsed_text text floc))
-      | he::tl -> 
-          let start, stop =  HExtlib.loc_of_floc he in
-          let floc1 = HExtlib.floc_of_loc (acc_len,start) in
-          let str1,_=MatitaGtkMisc.utf8_parsed_text text floc1 in
-          let str2,_ = MatitaGtkMisc.utf8_parsed_text text he in
-          escape_pango_markup str1 ^ "<b>" ^ 
-          escape_pango_markup str2 ^ "</b>" ^ 
-          colorize stop tl
   in
+ GtkThread.sync (fun _ ->
let dialog = new uriChoiceDialog () in
+ dialog#uriEntryHBox#misc#hide ();
+ dialog#uriChoiceSelectedButton#misc#hide ();
+ dialog#uriChoiceAutoButton#misc#hide ();
+ dialog#uriChoiceConstantsButton#misc#hide ();
+ dialog#uriChoiceTreeView#selection#set_mode
+   (`SINGLE :> Gtk.Tags.selection_mode);
+ let model = new stringListModel dialog#uriChoiceTreeView in
let choices = ref [] in
+ dialog#uriChoiceDialog#set_title title; 
+ let hack_len = MatitaGtkMisc.utf8_string_length text in
+ let rec colorize acc_len = function
+   | [] -> 
+       let floc = HExtlib.floc_of_loc (acc_len,hack_len) in
+       escape_pango_markup (fst(MatitaGtkMisc.utf8_parsed_text text floc))
+   | he::tl -> 
+       let start, stop =  HExtlib.loc_of_floc he in
+       let floc1 = HExtlib.floc_of_loc (acc_len,start) in
+       let str1,_=MatitaGtkMisc.utf8_parsed_text text floc1 in
+       let str2,_ = MatitaGtkMisc.utf8_parsed_text text he in
+       escape_pango_markup str1 ^ "<b>" ^ 
+       escape_pango_markup str2 ^ "</b>" ^ 
+       colorize stop tl
+ in
 (*     List.iter (fun l -> let start, stop = HExtlib.loc_of_floc l in
-                Printf.eprintf "(%d,%d)" start stop) locs; *)
-    let locs = 
-      List.sort 
-        (fun loc1 loc2 -> 
-          fst (HExtlib.loc_of_floc loc1) - fst (HExtlib.loc_of_floc loc2)) 
-        locs 
-    in
+              Printf.eprintf "(%d,%d)" start stop) locs; *)
+  let locs = 
+    List.sort 
+      (fun loc1 loc2 -> 
+        fst (HExtlib.loc_of_floc loc1) - fst (HExtlib.loc_of_floc loc2)) 
+      locs 
+  in
 (*     prerr_endline "XXXXXXXXXXXXXXXXXXXX";
-    List.iter (fun l -> let start, stop = HExtlib.loc_of_floc l in
-                Printf.eprintf "(%d,%d)" start stop) locs;
-    prerr_endline "XXXXXXXXXXXXXXXXXXXX2"; *)
-    dialog#uriChoiceLabel#set_use_markup true;
-    let txt = colorize 0 locs in
-    let txt,_ = MatitaGtkMisc.utf8_parsed_text txt
-      (HExtlib.floc_of_loc (prefix_len,MatitaGtkMisc.utf8_string_length txt))
-    in
-    dialog#uriChoiceLabel#set_label txt;
-    List.iter model#easy_append uris;
-    let return v =
-      choices := v;
-      dialog#uriChoiceDialog#destroy ();
-      GMain.Main.quit ()
-    in
-    ignore (dialog#uriChoiceDialog#event#connect#delete (fun _ -> true));
-    connect_button dialog#uriChoiceForwardButton (fun _ ->
-      match model#easy_selection () with
-      | [] -> ()
-      | uris -> return (Some uris));
-    connect_button dialog#uriChoiceAbortButton (fun _ -> return None);
-    dialog#uriChoiceDialog#show ();
-    GtkThread.main ();
-    (match !choices with 
-    | None -> raise MatitaTypes.Cancel
-    | Some uris -> uris)
+  List.iter (fun l -> let start, stop = HExtlib.loc_of_floc l in
+              Printf.eprintf "(%d,%d)" start stop) locs;
+  prerr_endline "XXXXXXXXXXXXXXXXXXXX2"; *)
+  dialog#uriChoiceLabel#set_use_markup true;
+  let txt = colorize 0 locs in
+  let txt,_ = MatitaGtkMisc.utf8_parsed_text txt
+    (HExtlib.floc_of_loc (prefix_len,MatitaGtkMisc.utf8_string_length txt))
+  in
+  dialog#uriChoiceLabel#set_label txt;
+  List.iter model#easy_append uris;
+  connect_button dialog#uriChoiceForwardButton (fun _ ->
+    match model#easy_selection () with
+    | [] -> ()
+    | uris -> choices := uris; dialog#toplevel#response `OK);
+  connect_button dialog#uriChoiceAbortButton (fun _ -> dialog#toplevel#response `DELETE_EVENT);
+  dialog#uriChoiceDialog#show ();
+  let res =
+   match dialog#toplevel#run () with 
+    | `DELETE_EVENT -> dialog#toplevel#destroy() ; raise MatitaTypes.Cancel
+    | `OK -> !choices
+    | _ -> assert false in
+  dialog#toplevel#destroy () ;
+  res) ()
 
 let interactive_interp_choice () text prefix_len choices =
 (*List.iter (fun l -> prerr_endline "==="; List.iter (fun (_,id,dsc) -> prerr_endline (id ^ " = " ^ dsc)) l) choices;*)
@@ -1629,10 +1262,8 @@ let interactive_interp_choice () text prefix_len choices =
 let _ =
   (* disambiguator callbacks *)
   Disambiguate.set_choose_uris_callback
-   (fun ~selection_mode ?ok ?(enable_button_for_non_vars=false) ~title ~msg ->
+   (fun ~selection_mode ?ok ?enable_button_for_non_vars:(_=false) ~title ~msg ->
      interactive_uri_choice ~selection_mode ?ok_label:ok ~title ~msg ());
   Disambiguate.set_choose_interp_callback (interactive_interp_choice ());
   (* gtk initialization *)
-  GtkMain.Rc.add_default_file BuildTimeConf.gtkrc_file; (* loads gtk rc *)
-  ignore (GMain.Main.init ())
-
+  GtkMain.Rc.add_default_file BuildTimeConf.gtkrc_file (* loads gtk rc *)