(************************************************************************) (* v * The Coq Proof Assistant / The Coq Development Team *) (* 1 then let () = Minilib.log "insert_text: Placing cursor" in let () = buffer#place_cursor ~where:it in if String.contains s '\n' then let () = Minilib.log "insert_text: Recentering" in script#recenter_insert in let begin_action_cb () = (* We remove any error red zone, and place the [prev_insert] mark *) let where = get_insert () in let () = buffer#move_mark (`NAME "prev_insert") ~where in let start = get_start () in let stop = buffer#end_iter in buffer#remove_tag Tags.Script.error ~start ~stop; buffer#remove_tag Tags.Script.tooltip ~start ~stop in let end_action_cb () = let start = get_start () in let ins = get_insert () in if 0 <= ins#compare start then Sentence.tag_on_insert buffer in let mark_set_cb it m = let ins = get_insert () in let line = ins#line + 1 in let off = ins#line_offset + 1 in let msg = Printf.sprintf "Line: %5d Char: %3d" line off in let () = !Ideutils.set_location msg in match GtkText.Mark.get_name m with | Some "insert" -> () | Some s -> Minilib.log (s^" moved") | None -> () in (** Pluging callbacks *) let _ = buffer#connect#insert_text ~callback:insert_cb in let _ = buffer#connect#begin_user_action ~callback:begin_action_cb in let _ = buffer#connect#end_user_action ~callback:end_action_cb in let _ = buffer#connect#after#mark_set ~callback:mark_set_cb in () let create_proof () = let proof = Wg_ProofView.proof_view () in let _ = proof#misc#set_can_focus true in let _ = GtkBase.Widget.add_events proof#as_widget [`ENTER_NOTIFY;`POINTER_MOTION] in proof let create_messages () = let messages = Wg_MessageView.message_view () in let _ = messages#misc#set_can_focus true in messages let create file coqtop_args = let basename = match file with |None -> "*scratch*" |Some f -> Glib.Convert.filename_to_utf8 (Filename.basename f) in let coqtop = Coq.spawn_coqtop coqtop_args in let reset () = Coq.reset_coqtop coqtop in let buffer = create_buffer () in let script = create_script coqtop buffer in let _ = set_buffer_handlers (buffer :> GText.buffer) script in let proof = create_proof () in let messages = create_messages () in let command = new Wg_Command.command_window coqtop in let finder = new Wg_Find.finder (script :> GText.view) in let fops = new FileOps.fileops (buffer :> GText.buffer) file reset in let _ = fops#update_stats in let cops = new CoqOps.coqops script proof messages coqtop (fun () -> fops#filename) in let _ = Coq.set_reset_handler coqtop cops#handle_reset_initial in let _ = Coq.init_coqtop coqtop cops#initialize in { buffer = (buffer :> GText.buffer); script=script; proof=proof; messages=messages; fileops=fops; coqops=cops; coqtop=coqtop; command=command; finder=finder; tab_label= GMisc.label ~text:basename (); } let kill (sn:session) = (* To close the detached views of this script, we call manually [destroy] on it, triggering some callbacks in [detach_view]. In a more modern lablgtk, rather use the page-removed signal ? *) sn.script#destroy (); Coq.close_coqtop sn.coqtop let build_layout (sn:session) = let session_paned = GPack.paned `VERTICAL () in let session_box = GPack.vbox ~packing:(session_paned#pack1 ~shrink:false ~resize:true) () in let eval_paned = GPack.paned `HORIZONTAL ~border_width:5 ~packing:(session_box#pack ~expand:true) () in let script_frame = GBin.frame ~shadow_type:`IN ~packing:eval_paned#add1 () in let script_scroll = GBin.scrolled_window ~vpolicy:`AUTOMATIC ~hpolicy:`AUTOMATIC ~packing:script_frame#add () in let state_paned = GPack.paned `VERTICAL ~packing:eval_paned#add2 () in let proof_frame = GBin.frame ~shadow_type:`IN ~packing:state_paned#add1 () in let proof_scroll = GBin.scrolled_window ~vpolicy:`AUTOMATIC ~hpolicy:`AUTOMATIC ~packing:proof_frame#add () in let message_frame = GBin.frame ~shadow_type:`IN ~packing:state_paned#add2 () in let session_tab = GPack.hbox ~homogeneous:false () in let img = GMisc.image ~icon_size:`SMALL_TOOLBAR ~packing:session_tab#pack () in let _ = sn.buffer#connect#modified_changed ~callback:(fun () -> if sn.buffer#modified then img#set_stock `SAVE else img#set_stock `YES) in let _ = eval_paned#misc#connect#size_allocate ~callback: (let old_paned_width = ref 2 in let old_paned_height = ref 2 in fun {Gtk.width=paned_width;Gtk.height=paned_height} -> if !old_paned_width <> paned_width || !old_paned_height <> paned_height then begin eval_paned#set_position (eval_paned#position * paned_width / !old_paned_width); state_paned#set_position (state_paned#position * paned_height / !old_paned_height); old_paned_width := paned_width; old_paned_height := paned_height; end) in session_box#pack sn.finder#coerce; session_paned#pack2 ~shrink:false ~resize:false (sn.command#frame#coerce); script_scroll#add sn.script#coerce; proof_scroll#add sn.proof#coerce; message_frame#add sn.messages#coerce; session_tab#pack sn.tab_label#coerce; img#set_stock `YES; eval_paned#set_position 1; state_paned#set_position 1; (Some session_tab#coerce,None,session_paned#coerce)