From 0d1f9ff76aa6df3f17edd2d73c76ab444fec8528 Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Mon, 2 Jan 2017 17:56:04 +0100 Subject: Corrected some issues with odf documents --- screen.ml | 112 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 51 deletions(-) (limited to 'screen.ml') diff --git a/screen.ml b/screen.ml index d48381a..a8e2d0c 100755 --- a/screen.ml +++ b/screen.ml @@ -4,13 +4,13 @@ module Color = Curses.Color module T2 = Tools.Tuple2 +module Option = Tools.Option + let cell_size = 10 let u = UTF8.from_utf8string -type t = Sheet.t - -type screen = { +type t = { window: Curses.window; (* the main window *) sheet: Curses.window; (* the spreadsheet *) input: Curses.window; (* the input window *) @@ -52,15 +52,16 @@ end let status screen msg = begin let height, width = screen.size in - let encoded = UTF8.encode msg in - let status = Bytes.make (width -1) ' ' in - Bytes.blit encoded 0 status 0 (String.length encoded); - Curses.werase screen.status; - if not ( - Curses.mvwaddstr screen.status 0 0 encoded - && Curses.wrefresh screen.status - ) then + UTF8.encode msg |> Option.iter (fun encoded -> + let status = Bytes.make (width -1) ' ' in + Bytes.blit encoded 0 status 0 (String.length encoded); + Curses.werase screen.status; + if not ( + Curses.mvwaddstr screen.status 0 0 encoded + && Curses.wrefresh screen.status + ) then raise (Failure "Status update") + ) end (** Draw the spreadsheet *) @@ -99,10 +100,13 @@ let draw data screen = begin else Curses.wattrset screen.sheet (Attrs.color_pair 1 ) end; + ignore @@ Curses.mvwaddstr screen.sheet 0 (x * cell_size + screen.left_margin) - @@ Printf.sprintf "%-*s" cell_size (UTF8.encode @@ Cell.to_hname pos_x); + @@ Printf.sprintf "%-*s" cell_size (UTF8.raw_encode @@ Cell.to_hname pos_x); + Curses.wattrset screen.sheet Attrs.normal; + for y = 1 to (height-2) do let pos_y = y + (snd screen.start) - 1 in @@ -118,22 +122,25 @@ let draw data screen = begin Curses.wattrset screen.sheet Attrs.normal; end; + + (* Get the content from the cell *) let content = Sheet.Raw.get_value (pos_x, pos_y) data.Sheet.data - |> ScTypes.Result.show - |> UTF8.split ~sep:(u"\n") in - - let value = UTF8.encode content - and length = UTF8.length content in - let strlength = String.length value in - let blank = cell_size - length in - let padding = if blank > 0 - then String.make blank ' ' - else "" in - - ignore - @@ Curses.mvwaddnstr screen.sheet y (x * cell_size + screen.left_margin) - (Printf.sprintf "%s%s" value padding) - 0 (blank + strlength) + |> Option.map (fun x -> UTF8.split ~sep:(u"\n") (ScTypes.Result.show x)) + |> Option.default UTF8.empty in + + (* If the content is defined, try to encode it and print it*) + UTF8.encode content |> Tools.Option.iter (fun value -> + let length = UTF8.length content in + let strlength = String.length value in + let blank = cell_size - length in + let padding = if blank > 0 + then String.make blank ' ' + else "" in + ignore + @@ Curses.mvwaddnstr screen.sheet y (x * cell_size + screen.left_margin) + (Printf.sprintf "%s%s" value padding) + 0 (blank + strlength) + ) done done; ignore @@ Curses.wrefresh screen.sheet; @@ -190,20 +197,23 @@ let draw_input t screen = begin let expr = Sheet.Raw.get_expr (Selection.extract t.Sheet.selected) t.Sheet.data |> Expression.show in - (* Compute the difference between number of bytes in the string, and the - number of character printed : Printf.sprintf format use the bytes number - in the string, while Curses print the characters in the user encoding *) let result = Sheet.Raw.get_value (Selection.extract t.Sheet.selected) t.Sheet.data - |> ScTypes.Result.show in - let encoded_result = UTF8.encode result in - let result_length_delta = (UTF8.length result) - (String.length encoded_result) in + |> Option.map ScTypes.Result.show + |> Option.default UTF8.empty in - ignore ( - encoded_result - |> Printf.sprintf "%-*s" (width - 11 - result_length_delta) - |> Curses.mvwaddstr screen.input 0 10 + UTF8.encode result |> Option.iter (fun encoded_result -> + (* Compute the difference between number of bytes in the string, and the + number of character printed : Printf.sprintf format use the bytes number + in the string, while Curses print the characters in the user encoding *) + let result_length_delta = (UTF8.length result) - (String.length encoded_result) in + + ignore ( + encoded_result + |> Printf.sprintf "%-*s" (width - 11 - result_length_delta) + |> Curses.mvwaddstr screen.input 0 10 - && Curses.wrefresh screen.input); + && Curses.wrefresh screen.input) + ); status screen expr; screen end @@ -248,8 +258,8 @@ let resize data t = begin end let editor ?position ?(prefix=UTF8.empty) ?(init=UTF8.empty) t = begin - let encodedPrefix = UTF8.encode prefix - and encodedInit = UTF8.encode init in + let encodedPrefix = UTF8.raw_encode prefix + and encodedInit = UTF8.raw_encode init in let with_refs, position = match position with | None -> false, (1, 1) | Some x -> true, x in @@ -262,7 +272,7 @@ let editor ?position ?(prefix=UTF8.empty) ?(init=UTF8.empty) t = begin | [] -> () | elems -> ( (* Rewrite each char after the cursor *) let y, x = Curses.getyx t.status in - List.iter (fun x -> ignore @@ Curses.waddstr t.status (UTF8.encode x)) elems; + List.iter (fun x -> ignore @@ Curses.waddstr t.status (UTF8.raw_encode x)) elems; ignore @@ Curses.wmove t.status y x ) end @@ -285,6 +295,10 @@ let editor ?position ?(prefix=UTF8.empty) ?(init=UTF8.empty) t = begin | "\027" -> (* Escape, cancel the modifications *) None | "\010" -> (* Enter, validate the input *) + + (* We concatenate all the characters. This can create an invalid string in + * the current locale (if there are copy/paste, or other events). + *) Some (UTF8.implode @@ (UTF8.rev_implode before)::after) | "\001\004" -> (* Left *) @@ -414,7 +428,7 @@ let editor ?position ?(prefix=UTF8.empty) ?(init=UTF8.empty) t = begin and insert_cell_name position name before after = begin let cell_name = Cell.to_string @@ (position, (false, false)) in ignore @@ delete_previous name; - ignore @@ Curses.waddstr t.status (UTF8.encode cell_name); + ignore @@ Curses.waddstr t.status (UTF8.raw_encode cell_name); rewrite_after after; ignore @@ Curses.wrefresh t.status; select_content position cell_name before after @@ read_key t @@ -438,12 +452,8 @@ let search screen = begin end end -(* -let read_input position screen = begin - let result = editor ~position ~init:(u"=") screen in - begin match result with - | Some content -> content - | None -> UTF8.empty - end -end -*) +let run f = + let window = init () in + Tools.try_finally + (fun () -> f window) + (fun () -> ignore @@ close window ) -- cgit v1.2.3