aboutsummaryrefslogtreecommitdiffstats
path: root/lib/appmon/src/appmon_txt.erl
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/appmon/src/appmon_txt.erl
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/appmon/src/appmon_txt.erl')
-rw-r--r--lib/appmon/src/appmon_txt.erl302
1 files changed, 302 insertions, 0 deletions
diff --git a/lib/appmon/src/appmon_txt.erl b/lib/appmon/src/appmon_txt.erl
new file mode 100644
index 0000000000..4e1785c53f
--- /dev/null
+++ b/lib/appmon/src/appmon_txt.erl
@@ -0,0 +1,302 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%------------------------------------------------------------
+%%
+%% Simple text viewer
+%%
+%%------------------------------------------------------------
+
+-module(appmon_txt).
+-export([start/0, start/1, print/1, fprint/1]).
+
+%% gen_server stuff
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2]).
+
+-define(LOADTXT, "Load file").
+-define(SAVETXT, "Save file").
+-define(SAVEASTXT, "Save as").
+-define(CLOSETXT, "Close").
+-define(HELPTXT, "Help").
+
+%%------------------------------------------------------------
+%%
+%% start/0 starts an open text viewer that can be filled with
+%% whatever.
+%%
+%%------------------------------------------------------------
+start() ->
+ start([]).
+
+%%------------------------------------------------------------
+%%
+%% start(ListOfOptions) starts an open text viewer with options
+%%
+%% Options can be
+%% {file, FileName} - insert contents of file
+%% locked - the text cannot be edited
+%% {text, Text} - insert text at startup
+%%
+%%------------------------------------------------------------
+start(Opts) ->
+ gen_server:start_link({local, ?MODULE}, ?MODULE, Opts, []).
+
+%% Start a text viewer if necessary
+print(Txt) ->
+ catch start(),
+ gen_server:call(?MODULE, {add_txt, Txt}),
+ ok.
+
+fprint(File) ->
+ catch start(),
+ gen_server:call(?MODULE, {add_file, File}),
+ ok.
+
+
+%%------------------------------------------------------------
+%% gen server admin
+
+init(Opts) ->
+ process_flag(trap_exit, true),
+ setup_base_win(),
+ default_status(),
+ setup_opts(Opts),
+ {ok, []}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+%%------------------------------------------------------------
+%% gen server stuff
+handle_call({add_txt, Txt}, _From, State) ->
+ do_insert_text(Txt),
+ scroll_to_last_line(),
+ {reply, ok, State};
+handle_call({add_file, FileName}, _From, State) ->
+ do_load_file(FileName),
+ {reply, ok, State};
+handle_call(_Request, _From, State) ->
+ {reply, ok, State}.
+handle_cast(_Request, State) ->
+ {noreply, State}.
+handle_info({gs, _, click, _, [?CLOSETXT|_]}, State) ->
+ {stop, normal, State};
+handle_info({gs, _, click, _, [?LOADTXT|_]}, State) ->
+ ui_load(),
+ {noreply, State};
+handle_info({gs, _, configure, _, [W, H | _]}, State) ->
+ resize(W, H),
+ {noreply, State};
+
+handle_info({gs, _, destroy, _, _}, State) ->
+ {stop, normal, State};
+handle_info(Request, State) ->
+ io:format("~p got info: ~p~n", [self(), Request]),
+ print_status("Not implemented"),
+ {noreply, State}.
+
+
+%%------------------------------------------------------------
+%% Handle options
+
+setup_opts([Opt|Opts]) ->
+ setup_opt(Opt),
+ setup_opts(Opts);
+setup_opts([]) -> ok.
+
+setup_opt(Opt) ->
+ case Opt of
+ {file, FileName} ->
+ do_load_file(FileName);
+ locked ->
+ do_lock();
+ {text, Text} ->
+ do_insert_text(Text);
+ _Other ->
+ ok
+ end.
+
+do_load_file(FileName) ->
+ case catch i_load_file(FileName) of
+ ok ->
+ default_status();
+ _Other ->
+ print_status(lists:append(["File not found: ", FileName]))
+ end.
+
+i_load_file(FileName) ->
+ {ok, Bin} = file:read_file(FileName),
+ L = binary_to_list(Bin),
+ i_do_clear(),
+ do_insert_text(L),
+ ok.
+
+ui_load() ->
+ Title = "Load file",
+ Files = get_file_list(),
+ case catch ui_list_dialog(Title, "File: ", Files) of
+ {ok, FileName} ->
+ do_load_file(FileName);
+ _Other ->
+ print_status("Load cancelled")
+ end.
+
+get_file_list() ->
+ case file:list_dir(".") of
+ {ok, FileList} -> lists:sort(FileList);
+ _Other -> []
+ end.
+
+do_insert_text(Text) ->
+ gs:config(editor(), {insert, {'end', Text}}),
+ ok.
+
+%% Scrolls editor to show the last rows
+scroll_to_last_line() ->
+ H = gs:read(editor(), size),
+ R = gs:read(editor(), height),
+ TopRow = H-R/15,
+ if TopRow > 0 -> gs:config(editor(), {vscrollpos, TopRow});
+ true -> gs:config(editor(), {vscrollpos, 0})
+ end,
+ ok.
+
+do_lock() ->
+ gs:config(editor(), {enable, false}).
+
+i_do_clear() ->
+ gs:config(editor(), clear).
+
+%%------------------------------------------------------------
+%% Graphical stuff
+
+label_h() -> 20.
+menu_h() -> 29.
+
+setup_base_win() ->
+ H = 400, W=580,
+ LabelHeight=label_h(), MenuHeight=menu_h(),
+
+ F = gs:start([{kernel,true}]),
+ set_winroot(F),
+
+ Win = gs:create(window, F, [{width, W}, {height, H},
+ {title,"APPMON: Process Information"}]),
+
+ E = gs:create(editor, Win, [{x, 0}, {y, MenuHeight},
+ {width, W},
+ {height, H-MenuHeight-LabelHeight-1},
+ {vscroll, right}]),
+ set_editor(E),
+
+ L = gs:create(label, Win, [{x, 0}, {y, H-LabelHeight},
+ {height,LabelHeight }, {width, W},
+ {align, w}]),
+ set_status(L),
+ print_status("Loading"),
+
+ gs:config(Win, {map, true}),
+
+ MB = gs:create(menubar, Win, []),
+
+ FMB = gs:create(menubutton, MB, [{label, {text, "File"}}]),
+ FM = gs:create(menu, FMB, []),
+ gs:create(menuitem, FM, [{label, {text, ?CLOSETXT}}]),
+
+ gs:config(Win, {configure, true}),
+ ok.
+
+resize(W, H) ->
+ gs:config(editor(), [{width, W}, {height, H-label_h()-menu_h()}]),
+ gs:config(status(), [{y, H-label_h()}, {width, W}]),
+ ok.
+
+%%------------------------------------------------------------
+%% ui_list_dialog(
+%%
+%% Traditional dialog with a list box and a selection field that
+%% is updated from the list box.
+%%
+%% Returns {ok, String} if successful and something else if not
+%%
+%% Title - the name of the window
+%% LeadText - the lead text on the selection field
+%% List - a list of items that will be displayed in the list box
+%%
+%%------------------------------------------------------------
+
+ui_list_dialog(Title, LeadText, TxtList) ->
+ W = 200, H = 300,
+
+ Win = gs:create(window, winroot(), [{title, Title},
+ {width, W},{height, H}]),
+ Ok = gs:create(button, Win, [{x, 10}, {y,10},
+ {width, 50}, {height, 20},
+ {label, {text, "Ok"}}]),
+ Cn = gs:create(button, Win, [{x, 70}, {y,10},
+ {width, 50}, {height, 20},
+ {label, {text, "Cancel"}}]),
+
+ gs:create(label, Win, [{x, 10}, {y, 50},
+ {width, 60}, {height, 20},
+ {label, {text, LeadText}}]),
+ Box = gs:create(entry, Win, [{x, 10}, {y, 70},
+ {width, 160}, {height, 20},
+ {keypress, true}]),
+ List = gs:create(listbox, Win, [{x, 10}, {y, 100}, {width, 180},
+ {height, 190},
+ {items, TxtList}, {vscroll, right},
+ {hscroll, false}, {click, true},
+ {doubleclick, true},
+ {keypress, true}]),
+ gs:config(Win, {map, true}),
+
+ RetVal = ui_load_loop(Box, List, Ok, Cn),
+
+ gs:destroy(Win),
+
+ RetVal.
+
+ui_load_loop(Box, List, Ok, Cn) ->
+ receive
+ {gs, Box, keypress, _, ['Return'|_]} ->
+ {ok, gs:read(Box, text)};
+ {gs, Box, keypress, _, _} ->
+ ui_load_loop(Box, List, Ok, Cn);
+ {gs, Ok, click, _, _} ->
+ {ok, gs:read(Box, text)};
+ {gs, List, doubleclick, _, [_Idx, Txt|_]} ->
+ {ok, Txt};
+ {gs, List, click, _, [_Idx, Txt|_]} ->
+ gs:config(Box, {text, Txt}),
+ ui_load_loop(Box, List, Ok, Cn);
+ _Other ->
+ something_else
+ end.
+
+%% The status row at the bottom of the window
+set_status(Id) -> put(status_row, Id).
+status() -> get(status_row).
+print_status(Msg) -> gs:config(get(status_row), {label, {text, Msg}}).
+default_status() -> print_status("Done").
+
+set_editor(X) -> put(editor, X).
+editor() -> get(editor).
+
+winroot() -> get(winroot).
+set_winroot(X) -> put(winroot, X).