diff options
Diffstat (limited to 'lib/observer/src/observer_tv_table.erl')
-rw-r--r-- | lib/observer/src/observer_tv_table.erl | 196 |
1 files changed, 95 insertions, 101 deletions
diff --git a/lib/observer/src/observer_tv_table.erl b/lib/observer/src/observer_tv_table.erl index 7b5cdb44b9..f432173f57 100644 --- a/lib/observer/src/observer_tv_table.erl +++ b/lib/observer/src/observer_tv_table.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2012. 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 @@ -24,8 +24,6 @@ -export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3, handle_event/2, handle_sync_event/3, handle_cast/2]). --export([get_table/3]). - -include("observer_defs.hrl"). -import(observer_lib, [to_str/1]). @@ -60,7 +58,7 @@ source, tab, attrs, - timer + timer={false, 30} }). -record(opt, @@ -221,33 +219,10 @@ search_area(Parent) -> edit(Index, #state{pid=Pid, frame=Frame}) -> Str = get_row(Pid, Index, all), - Dialog = wxTextEntryDialog:new(Frame, "Edit object:", [{value, Str}]), - case wxTextEntryDialog:showModal(Dialog) of - ?wxID_OK -> - New = wxTextEntryDialog:getValue(Dialog), - wxTextEntryDialog:destroy(Dialog), - case Str =:= New of - true -> ok; - false -> - complete_edit(Index, New, Pid) - end; - ?wxID_CANCEL -> - wxTextEntryDialog:destroy(Dialog) - end. - -complete_edit(Row, New0, Pid) -> - New = case lists:reverse(New0) of - [$.|_] -> New0; - _ -> New0 ++ "." - end, - try - {ok, Tokens, _} = erl_scan:string(New), - {ok, Term} = erl_parse:parse_term(Tokens), - Pid ! {edit, Row, Term} - catch _:{badmatch, {error, {_, _, Err}}} -> - self() ! {error, ["Parse error: ", Err]}; - _Err -> - self() ! {error, ["Syntax error in: ", New]} + case observer_lib:user_term(Frame, "Edit object:", Str) of + cancel -> ok; + {ok, Term} -> Pid ! {edit, Index, Term}; + Err = {error, _} -> self() ! Err end. handle_event(#wx{id=?ID_REFRESH},State = #state{pid=Pid}) -> @@ -260,14 +235,7 @@ handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}}, {noreply, State}; handle_event(#wx{event=#wxSize{size={W,_}}}, State=#state{grid=Grid}) -> - wx:batch(fun() -> - Cols = wxListCtrl:getColumnCount(Grid), - Last = lists:foldl(fun(I, Last) -> - Last - wxListCtrl:getColumnWidth(Grid, I) - end, W-?LCTRL_WDECR, lists:seq(0, Cols - 2)), - Size = max(?DEFAULT_COL_WIDTH, Last), - wxListCtrl:setColumnWidth(Grid, Cols-1, Size) - end), + observer_lib:set_listctrl_col_size(Grid, W), {noreply, State}; handle_event(#wx{event=#wxList{type=command_list_item_selected, itemIndex=Index}}, @@ -300,8 +268,8 @@ handle_event(#wx{id=?ID_DELETE}, handle_event(#wx{id=?wxID_CLOSE}, State) -> {stop, normal, State}; -handle_event(Help = #wx{id=?wxID_HELP}, State = #state{parent=Parent}) -> - Parent ! Help, +handle_event(Help = #wx{id=?wxID_HELP}, State) -> + observer ! Help, {noreply, State}; handle_event(#wx{id=?GOTO_ENTRY, event=#wxCommand{cmdString=Str}}, @@ -406,40 +374,51 @@ handle_event(#wx{id=?ID_REFRESH_INTERVAL}, Timer = observer_lib:interval_dialog(Grid, Timer0, 10, 5*60), {noreply, State#state{timer=Timer}}; -handle_event(Event, State) -> - io:format("~p:~p, handle event ~p\n", [?MODULE, ?LINE, Event]), +handle_event(_Event, State) -> + %io:format("~p:~p, handle event ~p\n", [?MODULE, ?LINE, Event]), {noreply, State}. -handle_sync_event(Event, _Obj, _State) -> - io:format("~p:~p, handle sync_event ~p\n", [?MODULE, ?LINE, Event]), +handle_sync_event(_Event, _Obj, _State) -> + %io:format("~p:~p, handle sync_event ~p\n", [?MODULE, ?LINE, Event]), ok. -handle_call(Event, From, State) -> - io:format("~p:~p, handle call (~p) ~p\n", [?MODULE, ?LINE, From, Event]), +handle_call(_Event, _From, State) -> + %io:format("~p:~p, handle call (~p) ~p\n", [?MODULE, ?LINE, From, Event]), {noreply, State}. -handle_cast(Event, State) -> - io:format("~p:~p, handle cast ~p\n", [?MODULE, ?LINE, Event]), +handle_cast(_Event, State) -> + %io:format("~p:~p, handle cast ~p\n", [?MODULE, ?LINE, Event]), {noreply, State}. handle_info({no_rows, N}, State = #state{grid=Grid, status=StatusBar}) -> wxListCtrl:setItemCount(Grid, N), wxStatusBar:setStatusText(StatusBar, io_lib:format("Objects: ~w",[N])), {noreply, State}; + handle_info({new_cols, New}, State = #state{grid=Grid, columns=Cols0}) -> Cols = add_columns(Grid, Cols0, New), {noreply, State#state{columns=Cols}}; + handle_info({refresh, Min, Max}, State = #state{grid=Grid}) -> wxListCtrl:refreshItems(Grid, Min, Max), {noreply, State}; + +handle_info(refresh_interval, State = #state{pid=Pid}) -> + Pid ! refresh, + {noreply, State}; + handle_info({error, Error}, State = #state{frame=Frame}) -> - Dlg = wxMessageDialog:new(Frame, Error), + ErrorStr = + try io_lib:format("~ts", [Error]), Error + catch _:_ -> io_lib:format("~p", [Error]) + end, + Dlg = wxMessageDialog:new(Frame, ErrorStr), wxMessageDialog:showModal(Dlg), wxMessageDialog:destroy(Dlg), {noreply, State}; -handle_info(Event, State) -> - io:format("~p:~p, handle info ~p\n", [?MODULE, ?LINE, Event]), +handle_info(_Event, State) -> + %% io:format("~p:~p, handle info ~p\n", [?MODULE, ?LINE, _Event]), {noreply, State}. terminate(_Event, #state{pid=Pid, attrs=Attrs}) -> @@ -537,7 +516,7 @@ table_holder(S0 = #holder{parent=Parent, pid=Pid, table=Table}) -> %% io:format("ignoring refresh", []), table_holder(S0); refresh -> - GetTab = rpc:call(S0#holder.node, ?MODULE, get_table, + GetTab = rpc:call(S0#holder.node, observer_backend, get_table, [self(), S0#holder.tabid, S0#holder.source]), table_holder(S0#holder{pid=GetTab}); {delete, Row} -> @@ -620,19 +599,22 @@ search([Str, Row, Dir0, CaseSens], true -> []; false -> [caseless] end, - {ok, Re} = re:compile(Str, Opt), Dir = case Dir0 of true -> 1; false -> -1 end, - Res = search(Row, Dir, Re, Table), + Res = case re:compile(Str, Opt) of + {ok, Re} -> + search(Row, Dir, Re, Table); + {error, _} -> false + end, Parent ! {self(), Res}, S#holder{search=Res}. search(Row, Dir, Re, Table) -> Res = try lists:nth(Row+1, Table) of Term -> - Str = io_lib:format("~w", [Term]), + Str = format(Term), re:run(Str, Re) catch _:_ -> no_more end, @@ -645,9 +627,9 @@ search(Row, Dir, Re, Table) -> get_row(From, Row, Col, Table) -> case lists:nth(Row+1, Table) of [Object|_] when Col =:= all -> - From ! {self(), io_lib:format("~w", [Object])}; + From ! {self(), format(Object)}; [Object|_] when tuple_size(Object) >= Col -> - From ! {self(), io_lib:format("~w", [element(Col, Object)])}; + From ! {self(), format(element(Col, Object))}; _ -> From ! {self(), ""} end. @@ -738,49 +720,6 @@ insert(Object, #holder{tabid=Id, source=Source, node=Node}) -> end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -get_table(Parent, Table, Module) -> - spawn(fun() -> - link(Parent), - get_table2(Parent, Table, Module) - end). - -get_table2(Parent, Table, Type) -> - Size = case Type of - ets -> ets:info(Table, size); - mnesia -> mnesia:table_info(Table, size) - end, - case Size > 0 of - false -> - Parent ! {self(), '$end_of_table'}, - normal; - true when Type =:= ets -> - Mem = ets:info(Table, memory), - Average = Mem div Size, - NoElements = max(10, 20000 div Average), - get_ets_loop(Parent, ets:match(Table, '$1', NoElements)); - true -> - Mem = mnesia:table_info(Table, memory), - Average = Mem div Size, - NoElements = max(10, 20000 div Average), - Ms = [{'$1', [], ['$1']}], - Get = fun() -> - get_mnesia_loop(Parent, mnesia:select(Table, Ms, NoElements, read)) - end, - %% Not a transaction, we don't want to grab locks when inspecting the table - mnesia:async_dirty(Get) - end. - -get_ets_loop(Parent, '$end_of_table') -> - Parent ! {self(), '$end_of_table'}; -get_ets_loop(Parent, {Match, Cont}) -> - Parent ! {self(), Match}, - get_ets_loop(Parent, ets:match(Cont)). - -get_mnesia_loop(Parent, '$end_of_table') -> - Parent ! {self(), '$end_of_table'}; -get_mnesia_loop(Parent, {Match, Cont}) -> - Parent ! {self(), Match}, - get_ets_loop(Parent, mnesia:select(Cont)). column_names(Node, Type, Table) -> case Type of @@ -799,3 +738,58 @@ key_pos(Node, ets, TabId) -> KeyPos = rpc:call(Node, ets, info, [TabId, keypos]), is_integer(KeyPos) orelse throw(node_or_table_down), KeyPos. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +format(Tuple) when is_tuple(Tuple) -> + [${ |format_tuple(Tuple, 1, tuple_size(Tuple))]; +format(List) when is_list(List) -> + format_list(List); +format(Bin) when is_binary(Bin), byte_size(Bin) > 100 -> + io_lib:format("<<#Bin:~w>>", [byte_size(Bin)]); +format(Float) when is_float(Float) -> + io_lib:format("~.3g", [Float]); +format(Term) -> + io_lib:format("~w", [Term]). + +format_tuple(Tuple, I, Max) when I < Max -> + [format(element(I, Tuple)), $,|format_tuple(Tuple, I+1, Max)]; +format_tuple(Tuple, Max, Max) -> + [format(element(Max, Tuple)), $}]; +format_tuple(_Tuple, 1, 0) -> + [$}]. + +format_list([]) -> "[]"; +format_list(List) -> + case printable_list(List) of + true -> io_lib:format("\"~ts\"", [List]); + false -> [$[ | make_list(List)] + end. + +make_list([Last]) -> + [format(Last), $]]; +make_list([Head|Tail]) -> + [format(Head), $,|make_list(Tail)]. + +%% printable_list([Char]) -> bool() +%% Return true if CharList is a list of printable characters, else +%% false. + +printable_list([C|Cs]) when is_integer(C), C >= $ , C =< 255 -> + printable_list(Cs); +printable_list([$\n|Cs]) -> + printable_list(Cs); +printable_list([$\r|Cs]) -> + printable_list(Cs); +printable_list([$\t|Cs]) -> + printable_list(Cs); +printable_list([$\v|Cs]) -> + printable_list(Cs); +printable_list([$\b|Cs]) -> + printable_list(Cs); +printable_list([$\f|Cs]) -> + printable_list(Cs); +printable_list([$\e|Cs]) -> + printable_list(Cs); +printable_list([]) -> true; +printable_list(_Other) -> false. %Everything else is false |