(***********************************************************************) (* Grew - a Graph Rewriting tool dedicated to NLP applications *) (* *) (* Copyright 2011-2013 Inria, Université de Lorraine *) (* *) (* Webpage: http://grew.loria.fr *) (* License: CeCILL (see LICENSE folder or "http://www.cecill.info") *) (* Authors: see AUTHORS file *) (***********************************************************************) open Printf open Log open GMain open Libgrew open Grew_glade open Grew_rew_display open Grew_utils open Grew_args type msg = | Error of string | Warning of string | Info of string let messages = ref [] let error fmt = Printf.ksprintf (fun x -> messages := Error (Printf.sprintf "%s\n" x) :: !messages) fmt let warning fmt = Printf.ksprintf (fun x -> messages := Warning (Printf.sprintf "%s\n" x) :: !messages) fmt let info fmt = Printf.ksprintf (fun x -> messages := Info (Printf.sprintf "%s\n" x) :: !messages) fmt (* ==================================================================================================== *) (* code taken from lablgtk2 examples *) let ask_for_file_to_open filter parent = let res = ref None in let dialog = GWindow.file_chooser_dialog ~action:`OPEN ~title:"Open File" ~parent () in dialog#add_button_stock `CANCEL `CANCEL ; dialog#add_select_button_stock `OPEN `OPEN ; dialog#add_filter filter; dialog#add_filter (GFile.filter ~name:"All files" ~patterns:["*"] ()); begin match dialog#run () with | `OPEN -> res := dialog#filename | `DELETE_EVENT | `CANCEL -> () end ; dialog#destroy (); !res (* ==================================================================================================== *) let ask_for_file_to_save filter parent = let res = ref None in let dialog = GWindow.file_chooser_dialog ~action:`SAVE ~title:"Save File" ~parent () in dialog#add_button_stock `CANCEL `CANCEL ; dialog#add_select_button_stock `SAVE `SAVE ; dialog#add_filter filter; begin match dialog#run () with | `SAVE -> res := dialog#filename | `DELETE_EVENT | `CANCEL -> () end ; dialog#destroy (); !res (* ==================================================================================================== *) module Resources = struct let current_grs = ref None let current_grs_file = ref None let current_gr = ref None let current_gr_file = ref None (* -------------------------------------------------------------------------------- *) let load_grs () = current_grs := None; match !current_grs_file with | None -> () | Some file -> Log.fmessage "Loading grs file: '%s'" file; current_grs := Some (if !Grew_args.old_grs then Grs.load_old file else Grs.load file) (* -------------------------------------------------------------------------------- *) let domain () = match !current_grs with | Some grs -> Grs.domain grs | None -> None (* -------------------------------------------------------------------------------- *) let load_gr () = current_gr := None; match !current_gr_file with | None -> () | Some file -> Log.fmessage "Loading gr file: '%s'" file; let domain = domain () in current_gr := Some (Graph.load ?domain file) (* -------------------------------------------------------------------------------- *) exception Cannot_rewrite of string let rewrite strat = match (!current_grs, !current_gr) with | (Some grs, Some gr) -> begin match (Rewrite.at_least_one ~grs ~strat, Rewrite.at_most_one ~grs ~strat) with | (true, true) -> Rewrite.display gr grs strat | (false, true) -> raise (Cannot_rewrite "The current strategy may not be productive (cannot be used in GUI)") | (_, false) -> raise (Cannot_rewrite "The current strategy is not deterministic (cannot be used in GUI)") end; | (None, _) -> raise (Cannot_rewrite "No grs file loaded") | (_, None) -> raise (Cannot_rewrite "No graph file loaded") end (* module Resources *) (* ==================================================================================================== *) (* ------------------------------------------------------------ *) let filter_features = ref false let current_features = ref [] let get_current_filter () = match (!filter_features, !current_features) with | (false, _) -> None | (true, l) -> Some (List.map fst (List.filter snd l)) let feat_set label value = let rec loop = function | [] -> [] | (x,_)::t when x=label -> (x,value)::t | c::t -> c::(loop t) in current_features := loop !current_features let (config_vbox : GPack.box option ref) = ref None (* the flag is true iff the config windows is open *) let fill_vbox vbox = List.iter (fun (label,active) -> let item = GButton.check_button ~label ~active ~packing:vbox#add () in let _ = item#connect#toggled ~callback:(fun () -> feat_set label item#active) in () ) !current_features (* when GRS change *) let update_features () = begin match Resources.domain () with | None -> () | Some dom -> current_features := List.map (fun x -> (x,true)) (Domain.feature_names dom) end; match !config_vbox with | None -> () | Some vbox -> (* if the config windows is opened, it must be updated *) List.iter (fun item -> item#destroy ()) vbox#children; fill_vbox vbox (* ------------------------------------------------------------ *) let display_config_window () = if !config_vbox = None then begin let win = new config_window () in config_vbox := Some win#config_vbox; fill_vbox win#config_vbox; let main_feat = match !Grew_args.main_feat with | None -> "phon" | Some s -> s in let () = win#main_feat#set_text main_feat in let _ = win#main_feat#connect#changed ~callback: (fun () -> Grew_args.main_feat := Some win#main_feat#text) in let _ = win#btn_config_close#connect#clicked ~callback: (fun () -> config_vbox := None; win#toplevel#destroy ()) in let _ = win#toplevel#event#connect#delete ~callback: (fun _ -> config_vbox := None; false) in win#toplevel#show () end type save = Png | Pdf_dep | Pdf_dot | Dep | Dot | Gr | Conll type side = Top | Bottom let string_of_side = function Top -> "top" | Bottom -> "bottom" (* ==================================================================================================== *) let init () = let _ = GMain.Main.init () in let grew_window = new grew_window () in (* combo_box_text not implemented in lablgladecc2 *) let combo_box_text = GEdit.combo_box_text ~packing:grew_window#strat_list_viewport#add () in let main_feat = match !Grew_args.main_feat with | None -> "phon" | Some s -> s in let empty_html = "Nothing to display" in let _ = grew_window#btn_preferences#connect#clicked ~callback: (fun _ -> display_config_window ()) in (* XXX *) (** WEBKITS CREATIONS *) let grs_webkit = GWebView.web_view ~packing:grew_window#grs_view#add () in let module_webkit = GWebView.web_view ~packing:grew_window#module_view#add () in let error_webkit = GWebView.web_view ~packing:grew_window#err_view_scroll#add () in let graph_top_webkit = GWebView.web_view ~packing:grew_window#graph_view_top#add () in let graph_bottom_webkit = GWebView.web_view ~packing:grew_window#graph_view_bottom#add () in grs_webkit#set_full_content_zoom true; module_webkit#set_full_content_zoom true; graph_top_webkit#set_full_content_zoom true; graph_bottom_webkit#set_full_content_zoom true; error_webkit#set_full_content_zoom true; (* ensure UTF-8 encoding *) grs_webkit#set_custom_encoding "UTF-8"; module_webkit#set_custom_encoding "UTF-8"; graph_top_webkit#set_custom_encoding "UTF-8"; graph_bottom_webkit#set_custom_encoding "UTF-8"; error_webkit#set_custom_encoding "UTF-8"; (* By default disable the contextual menu on webview *) let web_settings_def = GWebSettings.web_settings () in web_settings_def#set_enable_default_context_menu false; grs_webkit#set_settings web_settings_def; module_webkit#set_settings web_settings_def; graph_top_webkit#set_settings web_settings_def; graph_bottom_webkit#set_settings web_settings_def; error_webkit#set_settings web_settings_def; grew_window#graph_label#set_use_markup true; grew_window#grs_label#set_use_markup true; let refresh_error () = match !messages with | [] -> grew_window#err_view_scroll#misc#hide (); | l -> let html = String.concat "
\n" (List.map (function | Error s -> sprintf "ERROR: %s" s | Warning s -> sprintf "WARNING: %s" s | Info s -> sprintf "INFO: %s" s ) l ) in error_webkit#load_html_string html ""; grew_window#err_view_scroll#misc#show () in let show_error msg = messages := []; error "%s" msg; refresh_error () in let reset () = (* empty all webkits *) graph_top_webkit#load_html_string empty_html ""; graph_bottom_webkit#load_html_string empty_html ""; module_webkit#load_html_string empty_html ""; grs_webkit#load_html_string empty_html ""; Grew_rew_display.current_bottom_graph := ""; Grew_rew_display.current_top_graph := ""; (* reset the default panes *) grew_window#vpaned_corpus#misc#show (); grew_window#err_view_scroll#misc#hide (); grew_window#vpane_right#set_position 30; grew_window#btn_show_module#set_active false; grew_window#vpaned_corpus#set_position 30; grew_window#btn_show_corpus#set_active false; grew_window#vpaned_left#set_position 30; grew_window#btn_show_grs#set_active false in let error_handling fct arg = begin try fct arg with | Libgrew.Error msg -> show_error msg | Libgrew.Bug msg -> show_error (sprintf "Libgrew.bug, please report: %s" msg) | exc -> show_error (sprintf "Uncaught exception, please report: %s" (Printexc.to_string exc)) end; refresh_error () in (** CALLBACKS *) let strat_list = ref [] in let refresh_btn_run () = match (!Resources.current_grs, !Resources.current_gr, !strat_list) with | (Some _, Some _, _::_) -> grew_window#btn_run#misc#set_sensitive true | _ -> grew_window#btn_run#misc#set_sensitive false in let _ = (fst combo_box_text)#connect#changed (fun () -> try let name = List.nth !strat_list (fst combo_box_text)#active in grew_window#strat#set_text name; with _ -> ()) in let nc = grew_window#statusbar#new_context ~name:"context" in let _ = grew_window#strat#connect#changed (fun () -> ignore (nc#pop () ); let strat = grew_window#strat#text in match !Resources.current_grs with | Some grs -> begin try match (Rewrite.at_least_one ~grs ~strat, Rewrite.at_most_one ~grs ~strat) with | (true, true) -> grew_window#btn_run#misc#set_sensitive true | (false, true) -> grew_window#btn_run#misc#set_sensitive false; ignore (nc#push "The current strategy may not be productive (cannot be used in GUI)") | (_, false) -> grew_window#btn_run#misc#set_sensitive false; ignore (nc#push "The current strategy is not deterministic (cannot be used in GUI)") with Error s -> grew_window#btn_run#misc#set_sensitive false; ignore (nc#push ("Cannot parse strategy: "^s)) end | None -> () ) in (* -------------------------------------------------------------------------------- *) let load_gr () = reset(); error_handling Resources.load_gr (); match (!Resources.current_gr, !Resources.current_gr_file) with | (Some graph, Some gr_file) -> grew_window#graph_label#set_label (Filename.basename gr_file); Grew_rew_display.graph_map := [("init", (graph, ("", "", None)))]; Grew_rew_display.current_top_graph := "init"; let domain = Resources.domain () in let svg_file = if grew_window#btn_gr_top_dot#active then Grew_rew_display.svg_dot_temp_file ?domain ~main_feat graph else Grew_rew_display.svg_dep_temp_file ?domain ~main_feat graph in grew_window#vpaned_corpus#misc#show (); grew_window#err_view_scroll#misc#hide (); graph_top_webkit#load_uri ("file://"^svg_file) | (_, Some file) -> grew_window#graph_label#set_label (""^(Filename.basename file)^"") | _ -> grew_window#graph_label#set_label "No graph loaded" in let refresh_gr () = (match !Resources.current_gr_file with | None -> () | Some gr_file -> error_handling load_gr (); refresh_btn_run () ); refresh_error () in (* -------------------------------------------------------------------------------- *) let gr_or_conll_filter = GFile.filter ~name:"Graph *.(gr|conll|melt)" ~patterns:["*.gr"; "*.conll"; "*.melt"] () in (* click on the gr file name *) let _ = grew_window#graph_button#connect#clicked (fun () -> match ask_for_file_to_open gr_or_conll_filter grew_window#toplevel with | None -> () | Some f -> Resources.current_gr_file := Some f; error_handling load_gr (); refresh_btn_run () ) in (* click on the gr refresh button *) let _ = grew_window#btn_refresh_gr#connect#clicked ~callback: (fun () -> messages := []; refresh_gr () ) in (* -------------------------------------------------------------------------------- *) let load_grs ?strat () = reset (); error_handling Resources.load_grs (); begin match (!Resources.current_grs, !Resources.current_grs_file) with | (Some grs, Some file) -> grew_window#grs_label#set_label (Filename.basename file); (* update global var [strat_list] *) strat_list := Grs.get_strat_list grs; (* remove strat list in combo box *) (fst (snd combo_box_text))#clear (); (* update combo box *) List.iter (fun s -> GEdit.text_combo_add combo_box_text s) !strat_list; begin match strat with | None -> () | Some strat -> grew_window#strat#set_text strat; begin match List_.index strat !strat_list with | None -> () | Some i -> (fst combo_box_text)#set_active i end end | (None, Some file) -> grew_window#grs_label#set_label (""^(Filename.basename file)^"") | _ -> grew_window#grs_label#set_label "No Grs loaded" end; update_features () in (* end: load_grs *) (* -------------------------------------------------------------------------------- *) (* click on the grs file name *) let grs_filter = GFile.filter ~name:"Graph Rewriting System (*.grs)" ~patterns:["*.grs"] () in let _ = grew_window#grs_button#connect#clicked (fun () -> match ask_for_file_to_open grs_filter grew_window#toplevel with | None -> () | Some new_grs -> Resources.current_grs_file := Some new_grs; error_handling load_grs (); refresh_gr (); ) in (* click on the grs refresh button *) let _ = grew_window#btn_refresh_grs#connect#clicked ~callback: (fun () -> messages := []; error_handling load_grs (); refresh_gr () ) in let check_positions () = if (grew_window#vpaned_corpus#position < 30) then (grew_window#vpaned_corpus#set_position 30; grew_window#btn_show_corpus#set_active false); if (grew_window#vpaned_left#position < 30) then (grew_window#vpaned_left#set_position 30; grew_window#btn_show_grs#set_active false); if (grew_window#vpane_right#position < 30) then (grew_window#vpane_right#set_position 30; grew_window#btn_show_module#set_active false) in let _ = grew_window#btn_show_corpus#connect#clicked ~callback: (fun () -> if grew_window#btn_show_corpus#active then grew_window#vpaned_corpus#set_position 250 else (grew_window#vpaned_corpus#set_position 30; check_positions ()) ) in let _ = grew_window#vpaned_corpus#event#connect#button_release ~callback: (fun b -> if (grew_window#vpaned_corpus#position > 30) then (grew_window#btn_show_corpus#set_active true) else (grew_window#vpaned_corpus#set_position 30; grew_window#btn_show_corpus#set_active false); check_positions (); false ) in let _ = grew_window#btn_show_grs#connect#clicked ~callback: (fun () -> if grew_window#btn_show_grs#active then grew_window#vpaned_left#set_position 400 else (grew_window#vpaned_left#set_position 30; check_positions ()) ) in let _ = grew_window#vpaned_left#event#connect#button_release ~callback: (fun _ -> if (grew_window#vpaned_left#position > 30) then grew_window#btn_show_grs#set_active true else (grew_window#vpaned_left#set_position 30; grew_window#btn_show_grs#set_active false); check_positions (); false ) in let _ = grew_window#btn_show_module#connect#clicked ~callback: (fun () -> if grew_window#btn_show_module#active then grew_window#vpane_right#set_position 400 else (grew_window#vpane_right#set_position 30; check_positions ()) ) in let _ = grew_window#vpane_right#event#connect#button_release ~callback: (fun b -> if (grew_window#vpane_right#position > 30) then grew_window#btn_show_module#set_active true else (grew_window#vpane_right#set_position 30; grew_window#btn_show_module#set_active false); check_positions (); false ) in let _ = grew_window#toplevel#connect#destroy ~callback:(GMain.quit) in let _ = grew_window#btn_run#connect#clicked ~callback: (fun () -> try let rew_display = Resources.rewrite grew_window#strat#text in let fl = ref "G0" in grew_window#vpane_right#set_position 30; grew_window#btn_show_module#set_active false; grew_window#vpaned_corpus#set_position 30; grew_window#btn_show_corpus#set_active false; grew_window#btn_show_grs#set_active true; graph_top_webkit#load_html_string empty_html ""; graph_bottom_webkit#load_html_string empty_html ""; module_webkit#load_html_string empty_html ""; if (grew_window#vpaned_left#position <= 30) then (grew_window#vpaned_left#set_position 250); let (fleaf,file_svg) = Grew_rew_display.rew_display_to_svg rew_display in fl := fleaf; Grew_rew_display.transform ~show_bottom:true file_svg (file_svg^".trans.svg") !fl; grs_webkit#load_uri ("file://"^file_svg^".trans.svg"); Log.debug ("[Grew_gtk] file://"^file_svg^".trans.svg"); grew_window#vpaned_corpus#misc#show (); grew_window#err_view_scroll#misc#hide (); grs_webkit#execute_script("alert('showOnTop2::G0')"); grs_webkit#execute_script("alert('showOnBottom2::"^(!fl)^"')"); with | Resources.Cannot_rewrite msg -> show_error msg | Libgrew.Error msg -> show_error msg | Libgrew.Bug msg -> show_error (sprintf "Libgrew.bug, please report: %s" msg) | exc -> show_error (sprintf "Uncaught exception, please report: %s" (Printexc.to_string exc)) ) in (** CLICK ON SVG GRAPHS *) let _ = grs_webkit#connect#script_alert ~callback: (fun _ msg -> let domain = Resources.domain () in match Str.split (Str.regexp "::") msg with | ["showOnBottom"; graph] -> let svg_file = if grew_window#btn_gr_bottom_dot#active then (Grew_rew_display.get_dot_graph_with_background ?domain ~main_feat ~botop:(true,false) graph) else (Grew_rew_display.get_dep_graph_with_background ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(true,false) graph) in graph_bottom_webkit#load_uri ("file://"^svg_file); Grew_rew_display.current_bottom_graph := graph; module_webkit#load_html_string empty_html ""; grs_webkit#execute_script "if (get_edge_flag()) { remove_back_from_current_top(); hide_current_edge(); current_edge_two='qsd';current_top_graph='';current_bottom_graph=''; alert('removeTop'); }"; grs_webkit#execute_script "set_edge_flag(false)"; grew_window#btn_show_module#set_active false; grew_window#vpane_right#set_position 30; true | ["showOnTop"; graph] -> let svg_file = if grew_window#btn_gr_top_dot#active then (Grew_rew_display.get_dot_graph_with_background ?domain ~main_feat ~botop:(false,true) graph) else (Grew_rew_display.get_dep_graph_with_background ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(false,true) graph) in graph_top_webkit#load_uri ("file://"^svg_file); Grew_rew_display.current_top_graph := graph; module_webkit#load_html_string empty_html ""; grs_webkit#execute_script "if (get_edge_flag()) { remove_back_from_current_bottom(); hide_current_edge(); current_edge_two='qsd';current_top_graph='';current_bottom_graph=''; alert('removeBottom'); }"; grs_webkit#execute_script "set_edge_flag(false)"; grew_window#btn_show_module#set_active false; grew_window#vpane_right#set_position 30; true | ["showOnBottom2"; graph] -> let svg_file = if grew_window#btn_gr_bottom_dot#active then (Grew_rew_display.get_dot_graph_with_background ?domain ~main_feat ~botop:(true,false) graph) else (Grew_rew_display.get_dep_graph_with_background ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(true,false) graph) in graph_bottom_webkit#load_uri ("file://"^svg_file); Grew_rew_display.current_bottom_graph := graph; true | ["showOnTop2"; graph] -> let svg_file = if grew_window#btn_gr_top_dot#active then (Grew_rew_display.get_dot_graph_with_background ?domain ~main_feat ~botop:(false,true) graph) else (Grew_rew_display.get_dep_graph_with_background ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(false,true) graph) in graph_top_webkit#load_uri ("file://"^svg_file); Grew_rew_display.current_top_graph := graph; true | ["showModuleFromGraph"; graph] -> if (grew_window#vpane_right#position <= 30) then (grew_window#vpane_right#set_position 250); let svg_file = Grew_rew_display.get_big_step_for graph in module_webkit#load_uri ("file://"^svg_file); grs_webkit#execute_script "set_edge_flag(true)"; grew_window#btn_show_module#set_active true; true | ["removeTop"] -> graph_top_webkit#load_html_string empty_html ""; true | ["removeBottom"] -> graph_bottom_webkit#load_html_string empty_html ""; true | _ -> false ) in let click_marker1 = ref false and click_marker2 = ref false in let _ = module_webkit#connect#script_alert ~callback:(fun _ msg -> let domain = Resources.domain () in match Str.split (Str.regexp "::") msg with | ["showOnBottom"; graph] | ["showOnBottom2"; graph] -> if !click_marker1 then click_marker1 := false else begin let svg_file = if grew_window#btn_gr_bottom_dot#active then (Grew_rew_display.get_dot_graph_with_background2 ?domain ~main_feat ~botop:(true,false) (graph^".2")) else (Grew_rew_display.get_dep_graph_with_background2 ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(true,false) (graph^".2")) in graph_bottom_webkit#load_uri ("file://"^svg_file); Grew_rew_display.current_bottom_graph := (graph^".2"); grs_webkit#execute_script "remove_back_from_current_bottom()"; end; true | ["showOnTop"; graph] | ["showOnTop2"; graph] -> if !click_marker2 then click_marker2 := false else begin let svg_file = if grew_window#btn_gr_top_dot#active then (Grew_rew_display.get_dot_graph_with_background2 ?domain ~main_feat ~botop:(false,true) (graph^".2")) else (Grew_rew_display.get_dep_graph_with_background2 ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(false,true) (graph^".2")) in graph_top_webkit#load_uri ("file://"^svg_file); Grew_rew_display.current_top_graph := (graph^".2"); grs_webkit#execute_script "remove_back_from_current_top()"; end; true | ["showModuleFromGraph"; graph] -> let top_dot = grew_window#btn_gr_top_dot#active and bottom_dot = grew_window#btn_gr_bottom_dot#active in let (svg_file_top,svg_file_bottom,graph_top,doc_file) = Grew_rew_display.get_rule_for ?domain ~main_feat top_dot bottom_dot (graph^".2") in graph_top_webkit#load_uri ("file://"^svg_file_top); graph_bottom_webkit#load_uri ("file://"^svg_file_bottom); Grew_rew_display.current_top_graph := (graph_top); Grew_rew_display.current_bottom_graph := (graph^".2"); click_marker1 := true; click_marker2 := true; true | _ -> false ) in (* -------------------------------------------------------------------------------- *) (** SWAP BETWEEN DEP AND DOT *) let _ = grew_window#btn_gr_bottom_dep#connect#clicked ~callback: (fun () -> let domain = Resources.domain () in grew_window#btn_gr_bottom_dot#set_active (not grew_window#btn_gr_bottom_dep#active); if (grew_window#btn_gr_bottom_dep#active) && (!Grew_rew_display.current_bottom_graph <> "") then begin Log.fdebug "[Grew_gtk] Try to display dep for '%s'" !Grew_rew_display.current_bottom_graph; let svg_file = try Grew_rew_display.get_dep_graph_with_background ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(true,false) !Grew_rew_display.current_bottom_graph with Not_found -> Grew_rew_display.get_dep_graph_with_background2 ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(true,false) !Grew_rew_display.current_bottom_graph in graph_bottom_webkit#load_uri ("file://"^svg_file); end ) in let _ = grew_window#btn_gr_top_dep#connect#clicked ~callback: (fun () -> let domain = Resources.domain () in grew_window#btn_gr_top_dot#set_active (not grew_window#btn_gr_top_dep#active); if (grew_window#btn_gr_top_dep#active) && (!Grew_rew_display.current_top_graph <> "") then begin Log.fdebug "[Grew_gtk] Try to display dep for '%s'" !Grew_rew_display.current_top_graph; let svg_file = try Grew_rew_display.get_dep_graph_with_background ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(false,true) !Grew_rew_display.current_top_graph with Not_found -> Grew_rew_display.get_dep_graph_with_background2 ?domain ~filter:(get_current_filter ()) ~main_feat ~botop:(false,true) !Grew_rew_display.current_top_graph in graph_top_webkit#load_uri ("file://"^svg_file); end ) in let _ = grew_window#btn_gr_bottom_dot#connect#clicked ~callback: (fun () -> let domain = Resources.domain () in grew_window#btn_gr_bottom_dep#set_active (not grew_window#btn_gr_bottom_dot#active); if (grew_window#btn_gr_bottom_dot#active) && (!Grew_rew_display.current_bottom_graph <> "") then begin Log.fdebug "[Grew_gtk] Try to display dot for '%s'" !Grew_rew_display.current_bottom_graph; let svg_file = try Grew_rew_display.get_dot_graph_with_background ?domain ~main_feat ~botop:(true,false) !Grew_rew_display.current_bottom_graph with Not_found -> Grew_rew_display.get_dot_graph_with_background2 ?domain ~main_feat ~botop:(true,false) !Grew_rew_display.current_bottom_graph in graph_bottom_webkit#load_uri ("file://"^svg_file); end ) in (* XXX *) let _ = grew_window#btn_gr_top_dot#connect#clicked ~callback: (fun () -> let domain = Resources.domain () in grew_window#btn_gr_top_dep#set_active (not grew_window#btn_gr_top_dot#active); if (grew_window#btn_gr_top_dot#active) && (!Grew_rew_display.current_top_graph <> "") then begin Log.fdebug "[Grew_gtk] Try to display dot for '%s'" !Grew_rew_display.current_top_graph; let svg_file = try Grew_rew_display.get_dot_graph_with_background ?domain ?deco:!Grew_rew_display.current_top_deco ~main_feat ~botop:(false,true) !Grew_rew_display.current_top_graph with Not_found -> Grew_rew_display.get_dot_graph_with_background2 ?domain ~main_feat ~botop:(false,true) !Grew_rew_display.current_top_graph in graph_top_webkit#load_uri ("file://"^svg_file); end ) in (* -------------------------------------------------------------------------------- *) (** ZOOMS *) let _ = grew_window#grs_zoom#connect#value_changed ~callback: (fun () -> grs_webkit#set_zoom_level (grew_window#grs_zoom#adjustment#value /. 100.) ) in let _ = grew_window#graph_top_zoom#connect#value_changed ~callback: (fun () -> graph_top_webkit#set_zoom_level (grew_window#graph_top_zoom#adjustment#value /. 100.) ) in let _ = grew_window#graph_bottom_zoom#connect#value_changed ~callback: (fun () -> graph_bottom_webkit#set_zoom_level (grew_window#graph_bottom_zoom#adjustment#value /. 100.) ) in let _ = grew_window#module_zoom#connect#value_changed ~callback: (fun () -> module_webkit#set_zoom_level (grew_window#module_zoom#adjustment#value /. 100.) ) in (* -------------------------------------------------------------------------------- *) (** FULLSCREEN *) let fullscreen = ref false in let _ = grew_window#btn_enter_fullscreen#connect#clicked ~callback: (fun () -> grew_window#toplevel#fullscreen (); fullscreen := true) in let _ = grew_window#btn_leave_fullscreen#connect#clicked ~callback: (fun () -> grew_window#toplevel#unfullscreen (); fullscreen := false) in (* cpt is used to avoid a loop between the two propagations of value_changed *) let cpt = ref 0 in let _ = GMain.Timeout.add ~ms:50 ~callback:(fun () -> cpt := 0; true) in let _ = grew_window#graph_bottom#hadjustment#connect#value_changed ~callback: (fun () -> if (!cpt<1 && grew_window#synchronize#active) then begin let percent = ((grew_window#graph_bottom#hadjustment#value +. (grew_window#graph_bottom#hadjustment#page_size /. 2.)) /. grew_window#graph_bottom#hadjustment#upper) in let value = percent *. grew_window#graph_top#hadjustment#upper -. (grew_window#graph_top#hadjustment#page_size /. 2.) in incr cpt; grew_window#graph_top#hadjustment#set_value value; end ) in let _ = grew_window#graph_top#hadjustment#connect#value_changed ~callback: (fun () -> if (!cpt<1 && grew_window#synchronize#active) then (let percent = ((grew_window#graph_top#hadjustment#value +. (grew_window#graph_top#hadjustment#page_size /. 2.)) /. grew_window#graph_top#hadjustment#upper) in let value = percent *. grew_window#graph_bottom#hadjustment#upper -. (grew_window#graph_bottom#hadjustment#page_size /. 2.) in incr cpt; grew_window#graph_bottom#hadjustment#set_value value; ) ) in (* ==================== Contextual menu to export ==================== *) let save extension graph save_function () = let filter = GFile.filter ~name:("*."^extension) ~patterns:["*."^extension] () in match ask_for_file_to_save filter grew_window#toplevel with | None -> () | Some filename -> save_function graph filename in (* -------------------------------------------------------------------------------- *) let view fct graph () = let text = fct graph in let sv = new src_viewer () in sv#source#buffer#set_text text; ignore(sv#toplevel#connect#destroy ~callback:sv#toplevel#destroy); ignore(sv#close#connect#clicked ~callback:sv#toplevel#destroy); sv#check_widgets (); sv#toplevel#show (); () in let contextual_menu side ev = if GdkEvent.Button.button ev <> 3 then false (* we did not handle this *) else let domain = Resources.domain () in let graph = match side with | Top -> !Grew_rew_display.current_top_graph | Bottom -> !Grew_rew_display.current_bottom_graph in if graph = "" then true else begin let dot = match side with | Top -> grew_window#btn_gr_top_dot#active | Bottom -> grew_window#btn_gr_bottom_dot#active in let deco = match side with | Top -> !Grew_rew_display.current_top_deco | Bottom -> !Grew_rew_display.current_bottom_deco in (* create the contextual menu *) let menu = GMenu.menu () in let add_item (label,callback) = let menuitem = GMenu.menu_item ~label ~packing:menu#append () in ignore (menuitem#connect#activate ~callback) in (* build save items and put them in the menu *) let save_items = ("Save as gr", save "gr" graph (Grew_rew_display.to_grfile_graph ?domain)) :: ("Save as conll", save "conll" graph (Grew_rew_display.save_conll_graph ?domain)) :: ("Save as pdf", if dot then save "pdf" graph (Grew_rew_display.to_pdf_dotfile_graph ?domain ?deco ~main_feat) else save "pdf" graph (Grew_rew_display.to_pdf_depfile_graph ?domain ?deco ~main_feat) ) :: ("Save as svg", if dot then save "svg" graph (Grew_rew_display.to_svg_dotfile_graph ?domain ?deco ~main_feat) else save "svg" graph (Grew_rew_display.to_svg_depfile_graph ?domain ?deco ~main_feat) ) :: ("Save as png", save "png" graph (Grew_rew_display.to_pngfile_graph ?domain ?deco ~main_feat)) :: (if dot then ["Save as dot", save "dot" graph (Grew_rew_display.to_dotfile_graph ?domain ?deco ~main_feat)] else ["Save as dep", save "dep" graph (Grew_rew_display.to_depfile_graph ?domain ?deco ~main_feat)] ) in List.iter add_item save_items; let _ = GMenu.separator_item ~packing:menu#append () in (* build view items and put them in the menu *) let view_items = ("View gr", view (Grew_rew_display.to_grstring_graph ?domain) graph) :: ("View conll", view (Grew_rew_display.to_conll_graph ?domain) graph) :: (if dot then ["View dot", view (Grew_rew_display.to_dotstring_graph ?domain ?deco ~main_feat) graph] else ["View dep", view (Grew_rew_display.to_depstring_graph ?domain ?deco ~main_feat) graph] ) in List.iter add_item view_items; menu#popup ~button:(GdkEvent.Button.button ev) ~time:(GdkEvent.Button.time ev); true (* we handled this *) end in (* Listen to right click in graph view *) let _ = grew_window#graph_view_top#event#add [`BUTTON_PRESS] in let _ = grew_window#graph_view_top#event#connect#button_press ~callback: (contextual_menu Top) in let _ = grew_window#graph_view_bottom#event#add [`BUTTON_PRESS] in let _ = grew_window#graph_view_bottom#event#connect#button_press ~callback: (contextual_menu Bottom) in (* Really start the gui *) grew_window#check_widgets (); grew_window#toplevel#show (); (* startup load of grs files (which implies loading of the gr file) *) Resources.current_grs_file := !Grew_args.grs; load_grs ~strat:!Grew_args.strat (); Resources.current_gr_file := !Grew_args.gr; load_gr (); refresh_btn_run (); refresh_error (); GMain.Main.main ()