1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
(**************************************************************************)
(* Lablgtk - Examples *)
(* *)
(* This code is in the public domain. *)
(* You may freely copy parts of it in your application. *)
(* *)
(**************************************************************************)
(* $Id$ *)
open StdLabels
let file_dialog ~title ~callback ?filename () =
let sel =
GWindow.file_selection ~title ~modal:true ?filename () in
sel#cancel_button#connect#clicked ~callback:sel#destroy;
sel#ok_button#connect#clicked ~callback:
begin fun () ->
let name = sel#filename in
sel#destroy ();
callback name
end;
sel#show ()
let input_channel b ic =
let buf = Bytes.create 1024 and len = ref 0 in
while len := input ic buf 0 1024; !len > 0 do
Buffer.add_subbytes b buf 0 !len
done
let with_file name ~f =
let ic = open_in name in
try f ic; close_in ic with exn -> close_in ic; raise exn
class editor ?packing ?show () = object (self)
val text = GText.view ?packing ?show ()
val mutable filename = None
method text = text
method load_file name =
try
let b = Buffer.create 1024 in
with_file name ~f:(input_channel b);
let s = Glib.Convert.locale_to_utf8 (Buffer.contents b) in
let n_buff = GText.buffer ~text:s () in
text#set_buffer n_buff;
filename <- Some name;
n_buff#place_cursor n_buff#start_iter
with _ -> prerr_endline "Load failed"
method open_file () = file_dialog ~title:"Open" ~callback:self#load_file ()
method save_dialog () =
file_dialog ~title:"Save" ?filename
~callback:(fun file -> self#output ~file) ()
method save_file () =
match filename with
Some file -> self#output ~file
| None -> self#save_dialog ()
method output ~file =
try
if Sys.file_exists file then Sys.rename file (file ^ "~");
let s = text#buffer#get_text () in
let oc = open_out file in
output_string oc (Glib.Convert.locale_from_utf8 s);
close_out oc;
filename <- Some file
with _ -> prerr_endline "Save failed"
end
let window = GWindow.window ~width:500 ~height:300 ~title:"editor" ()
let vbox = GPack.vbox ~packing:window#add ()
let menubar = GMenu.menu_bar ~packing:vbox#pack ()
let factory = new GMenu.factory ~accel_path:"<EDITOR2>/" menubar
let accel_group = factory#accel_group
let file_menu = factory#add_submenu "File"
let edit_menu = factory#add_submenu "Edit"
let scrollwin = GBin.scrolled_window ~packing:vbox#add ()
let editor = new editor ~packing:scrollwin#add ()
open GdkKeysyms
let _ =
window#connect#destroy ~callback:GMain.quit;
let factory = new GMenu.factory ~accel_path:"<EDITOR2 File>/////" file_menu ~accel_group
in
factory#add_item "Open" ~key:_O ~callback:editor#open_file;
factory#add_item "Save" ~key:_S ~callback:editor#save_file;
factory#add_item "Save as..." ~callback:editor#save_dialog;
factory#add_separator ();
factory#add_item "Quit" ~key:_Q ~callback:window#destroy;
let factory = new GMenu.factory ~accel_path:"<EDITOR2 File>///" edit_menu ~accel_group in
factory#add_item "Copy" ~key:_C ~callback:
(fun () -> editor#text#buffer#copy_clipboard GMain.clipboard);
factory#add_item "Cut" ~key:_X ~callback:
(fun () -> GtkSignal.emit_unit
editor#text#as_view GtkText.View.S.cut_clipboard);
factory#add_item "Paste" ~key:_V ~callback:
(fun () -> GtkSignal.emit_unit
editor#text#as_view GtkText.View.S.paste_clipboard);
factory#add_separator ();
factory#add_check_item "Word wrap" ~active:false ~callback:
(fun b -> editor#text#set_wrap_mode (if b then `WORD else `NONE));
factory#add_check_item "Read only" ~active:false
~callback:(fun b -> editor#text#set_editable (not b));
factory#add_item "Save accels"
~callback:(fun () -> GtkData.AccelMap.save "test.accel");
window#add_accel_group accel_group;
editor#text#event#connect#button_press
~callback:(fun ev ->
let button = GdkEvent.Button.button ev in
if button = 3 then begin
file_menu#popup ~button ~time:(GdkEvent.Button.time ev); true
end else false);
window#show ();
let () = GtkData.AccelMap.load "test.accel" in
GtkData.AccelMap.foreach
(fun ~path ~key ~modi ~changed ->
if modi = [`CONTROL] then
if GtkData.AccelMap.change_entry path ~key ~modi:[`MOD1]
then prerr_endline ("Changed " ^ path)
else prerr_endline ("Could not change "^path));
GMain.main ()
|