diff options
Diffstat (limited to 'lib/tv/src/tv_main.erl')
-rw-r--r-- | lib/tv/src/tv_main.erl | 1821 |
1 files changed, 0 insertions, 1821 deletions
diff --git a/lib/tv/src/tv_main.erl b/lib/tv/src/tv_main.erl deleted file mode 100644 index b6ffbd7c49..0000000000 --- a/lib/tv/src/tv_main.erl +++ /dev/null @@ -1,1821 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1998-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 -%% 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% --module(tv_main). --compile([{nowarn_deprecated_function,{gs,config,2}}, - {nowarn_deprecated_function,{gs,destroy,1}}, - {nowarn_deprecated_function,{gs,frame,3}}, - {nowarn_deprecated_function,{gs,grid,3}}, - {nowarn_deprecated_function,{gs,gridline,2}}, - {nowarn_deprecated_function,{gs,label,3}}, - {nowarn_deprecated_function,{gs,menu,2}}, - {nowarn_deprecated_function,{gs,menubar,3}}, - {nowarn_deprecated_function,{gs,menubutton,2}}, - {nowarn_deprecated_function,{gs,menuitem,2}}, - {nowarn_deprecated_function,{gs,menuitem,3}}, - {nowarn_deprecated_function,{gs,read,2}}, - {nowarn_deprecated_function,{gs,start,0}}, - {nowarn_deprecated_function,{gs,window,3}}]). - - - --export([start/0, - init/0 - ]). - - --export([get_ets_tables/1, - get_mnesia_tables/1 - ]). - - - --include("tv_main.hrl"). --include("tv_int_msg.hrl"). --include("tv_pd_int_msg.hrl"). --include("tv_pd_int_def.hrl"). - - - - -%%%********************************************************************* -%%% EXTERNAL FUNCTIONS -%%%********************************************************************* - - -start() -> - spawn(?MODULE, init, []). - - - -init() -> - process_flag(trap_exit,true), - %% OK, so it's *BAD* to use the process dictionary... - %% So why have I used it? Because it is simple to remove the haiku-functionality, - %% if that is desired. Otherwise a lot of functions (the parameters) would have - %% to be changed. - put(error_msg_mode, ?ERROR_MSG_MODE), - KindOfTable = ets, - SysTabHidden = true, - UnreadHidden = true, - SortKey = ?NAME_COL, - CurrNode = node(), - Children = start_tv_nodewin(CurrNode), - {MarkedCell, TempGridLines, WinSize, ShortcutList} = create_window([]), - Tables = get_tables(CurrNode, KindOfTable, UnreadHidden, SysTabHidden,SortKey), - gs:config(grid, [{rows, {1, get_nof_rows(length(Tables), - gs:read(grid, height))}}]), - GridLines = update_gridlines(Tables, TempGridLines, 1), - gs:config(win, [{map, true}, {cursor,arrow}]), - %% To avoid unpleasant error/exit messages, we surround the loop with a catch. - catch loop(KindOfTable, CurrNode, MarkedCell, GridLines, WinSize, Tables, ShortcutList, - UnreadHidden, SysTabHidden, SortKey, Children). - - - -start_tv_nodewin(CurrNode) -> - NodewinPid = tv_nodewin:start(CurrNode, get(error_msg_mode)), - [{NodewinPid, tv_nodewin, CurrNode}]. - - - - - -get_ets_tables(SysTabHidden) -> - Tables = ets:all(), - get_ets_table_info(Tables, - hidden_tables(ets, SysTabHidden) ++ - current_mnesia_tables(SysTabHidden), - owners_to_hide(ets, SysTabHidden), - []). - - - -get_mnesia_tables(SysTabHidden) -> - Tables = mnesia:system_info(tables), - get_mnesia_table_info(Tables -- hidden_tables(mnesia, SysTabHidden), - owners_to_hide(mnesia, SysTabHidden), - []). - - - - - -owners_to_hide(ets, true) -> - ?SYSTEM_OWNERS; -owners_to_hide(ets, false) -> - []; -owners_to_hide(mnesia, true) -> - []; -owners_to_hide(mnesia, false) -> - []. - - - - -get_mnesia_table_info([], _OwnersToHide, Acc) -> - lists:keysort(?NAME_ELEM, Acc); -get_mnesia_table_info([TabId | Tail], OwnersToHide, Acc) -> - case catch get_mnesia_owner_size(TabId) of - {'EXIT', _Reason} -> - %% Ignore tables ceasing to exist. - %% Nodedown errors caught above! - get_mnesia_table_info(Tail, OwnersToHide, Acc); - {OwnerPid, OwnerName, Size} -> - case lists:member(OwnerName, OwnersToHide) of - true -> - get_mnesia_table_info(Tail, OwnersToHide, Acc); - false -> - Readable = not(lists:member(TabId, ?UNREADABLE_MNESIA_TABLES)), - get_mnesia_table_info(Tail, - OwnersToHide, - [{TabId, {notext}, {notext}, Readable, - OwnerPid, OwnerName, Size} | Acc]) - end - end. - - - - -get_mnesia_owner_size(TabId) -> - {OwnerPid, OwnerName} = - case catch mnesia:table_info(TabId, owner) of - Pid when is_pid(Pid) -> - case lists:keysearch(registered_name, 1, process_info(Pid)) of - false -> - {Pid, {notext}}; - {value, {registered_name, ProcName}} -> - {Pid, ProcName} - end; - _Other -> - {{notext}, {notext}} - end, - Size = mnesia:table_info(TabId, size), - {OwnerPid, OwnerName, Size}. - - - - - - - -hidden_tables(_Any, true) -> - ?SYSTEM_TABLES ++ ?MNESIA_TABLES; -hidden_tables(ets, _SysTabHidden) -> - ?MNESIA_TABLES; -hidden_tables(mnesia, _SysTabHidden) -> - []. - - - - -get_tables(Node, KindOfTable, UnreadHidden, SysTabHidden,SortKey) -> - LocalNode = (Node =:= node()), - Tables = - case catch get_table_list(Node,LocalNode,KindOfTable,SysTabHidden) of - Result when is_list(Result) -> - case UnreadHidden of - true -> - lists:filter(fun(H) -> - element(?READABLE_ELEM, H) - end, - Result); - _Other -> - Result - end; - Error -> - analyze_error(Error, Node, undefined), - [] - end, - case SortKey of - ?PROCNAME_ELEM -> - lists:keysort(SortKey, - lists:keysort(?PID_ELEM, Tables)); - _OtherCol -> - lists:keysort(SortKey, - lists:keysort(?NAME_ELEM, Tables)) - end. - - - - - -get_ets_table_info([], _TablesToHide, _OwnersToHide, Acc) -> - lists:keysort(?ID_ELEM, Acc); -get_ets_table_info([TabId | Tail], TablesToHide, OwnersToHide, Acc) -> - case catch get_ets_name_owner_protection(TabId) of - {'EXIT', _Reason} -> - %% Ignore tables ceasing to exist. - %% Nodedown errors caught above! - get_ets_table_info(Tail, TablesToHide, OwnersToHide, Acc); - {Name, NamedTable, Id, Readable, OwnerPid, OwnerName, Size} -> - case lists:member(Name, TablesToHide) of - true -> - get_ets_table_info(Tail, TablesToHide, OwnersToHide, Acc); - false -> - case lists:member(OwnerName, OwnersToHide) of - true -> - get_ets_table_info(Tail, TablesToHide, OwnersToHide, Acc); - false -> - get_ets_table_info(Tail, TablesToHide, OwnersToHide, - [{Name,NamedTable,Id,Readable, - OwnerPid,OwnerName,Size} | Acc]) - end - end - end. - - - -get_ets_name_owner_protection(TabId) -> - Name = ets:info(TabId, name), - OwnerPid = ets:info(TabId, owner), - Readable = case ets:info(TabId, protection) of - private -> - false; - _Other -> - true - end, - Size = ets:info(TabId, size), - {NamedTable,Id} = case ets:info(TabId, named_table) of - true -> - {true,{notext}}; - false -> - {false, TabId} - end, - PName = case lists:keysearch(registered_name, 1, process_info(OwnerPid)) of - false -> - {notext}; - {value, {registered_name, ProcName}} -> - ProcName - end, - {Name, NamedTable, Id, Readable, OwnerPid, PName, Size}. - - - - - - -current_mnesia_tables(SysTabHidden) -> - case catch get_table_list(node(), true, mnesia, SysTabHidden) of - Result when is_list(Result) -> - lists:map(fun(H) -> - element(?NAME_ELEM, H) - end, - Result); - nodedown -> - handle_error(nodedown, node(), undefined), - []; - _Other -> - [] - end. - - - - -get_table_list(_Node, true, ets, SysTabHidden) -> - get_ets_tables(SysTabHidden); -get_table_list(Node, false, ets, SysTabHidden) -> - case rpc:block_call(Node, ?MODULE, get_ets_tables, [SysTabHidden]) of - {badrpc, Reason} -> - throw({badrpc,Reason}); - Result -> - Result - end; -get_table_list(_Node, true, mnesia, SysTabHidden) -> - get_mnesia_tables(SysTabHidden); -get_table_list(Node, false, mnesia, SysTabHidden) -> - case rpc:block_call(Node, ?MODULE, get_mnesia_tables, [SysTabHidden]) of - {badrpc,Reason} -> - throw({badrpc,Reason}); - Result -> - Result - end. - - - - -analyze_error(Cause, Node, Table) -> - case Cause of - {badrpc, {'EXIT', {badarg,_Reason}}} -> - done; %% Table has ceased to exist. - {'EXIT', {badarg, {ets,local_info,_Args}}} -> - done; - - {badrpc, nodedown} -> - handle_error(nodedown, Node, Table); - {'EXIT', nodedown} -> - handle_error(nodedown, Node, Table); - - {'EXIT', {aborted, {node_not_running,_ErrNode}}} -> - handle_error(mnesia_not_started, Node, Table); - {'EXIT', {'EXIT', {aborted, {node_not_running,_ErrNode}}}} -> - handle_error(mnesia_not_started, Node, Table); - {badrpc, {'EXIT', {aborted, {node_not_running,_ErrNode}}}} -> - handle_error(mnesia_not_started, Node, Table); - {'EXIT', {undef, {mnesia,_Fcn,_Args,_}}} -> - handle_error(mnesia_not_started, Node, Table); - - {'EXIT', Reason} -> - handle_error({unexpected_error,Reason}, Node, Table); - Error when is_tuple(Error) -> - handle_error({unexpected_error,Error}, Node, Table) - end. - - - -handle_error(mnesia_not_started, _Node, _Table) -> - gs:config(win, [beep]), - case get(error_msg_mode) of - normal -> - tv_utils:notify(win, "TV Notification", ["Mnesia not started!"]); - haiku -> - tv_utils:notify(win, "TV Notification", ["Mnesia is stopped.", - "We wish to reach all data", - "But we never will."]) - end; -handle_error(nodedown, _Node, _Table) -> - gs:config(win, [beep]), - case get(error_msg_mode) of - normal -> - tv_utils:notify(win, "TV Notification", ["The selected node is down!"]); - haiku -> - Msg = ["With searching comes loss", - "And the presence of absence:", - "Node is down."], - tv_utils:notify(win, "TV Notification", Msg) - end, - self() ! nodedown; -handle_error({unexpected_error,Cause}, _Node, _Table) -> - io:format("Unexpected error: ~p~n", [Cause]), - gs:config(win, [beep]). - - - - -loop(KindOfTable,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - receive - - {gs, Gridline, click, {grid,Readable}, [Col,Row,Text | _]} when Text =/= "" -> - unmark_cell(MarkedCell, Tables), - NewMarkedCell = mark_cell({Gridline, Col, Row}, MarkedCell, Readable), - loop(KindOfTable,CurrNode,NewMarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, _Gridline, click, {grid,_Readable}, [_Col,_Row,"" | _]} -> - NewMarkedCell = unmark_cell(MarkedCell, Tables), - loop(KindOfTable,CurrNode,NewMarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, Gridline, doubleclick, {grid,Data}, [?NAME_COL,Row,Text | _]} when Text =/= "" -> - unmark_cell(MarkedCell, Tables), - NewMarkedCell = mark_cell({Gridline, ?NAME_COL, Row}, undefined, Data), - {Table, Name, Readable} = get_table_id(KindOfTable, Row, Tables), - case start_tv_browser(Table,CurrNode,Name,KindOfTable,Readable,Children) of - Children -> - {FinalMarkedCell, NewTables, NewGridLines} = - refresh_window(NewMarkedCell,Tables,KindOfTable,CurrNode,GridLines, - UnreadHidden,SysTabHidden,SortKey, Children), - loop(KindOfTable,CurrNode,FinalMarkedCell,NewGridLines,WinSize,NewTables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - NewChildren -> - loop(KindOfTable,CurrNode,NewMarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren) - end; - - - {gs, Gridline, doubleclick, {grid,Data}, [?ID_COL,Row,Text | _]} when Text =/= "" -> - unmark_cell(MarkedCell, Tables), - NewMarkedCell = mark_cell({Gridline, ?ID_COL, Row}, undefined, Data), - {Table, Name, Readable} = get_table_id(KindOfTable, Row, Tables), - case start_tv_browser(Table,CurrNode,Name,KindOfTable,Readable,Children) of - Children -> - {FinalMarkedCell, NewTables, NewGridLines} = - refresh_window(NewMarkedCell,Tables,KindOfTable,CurrNode,GridLines, - UnreadHidden,SysTabHidden,SortKey, Children), - loop(KindOfTable,CurrNode,FinalMarkedCell,NewGridLines,WinSize,NewTables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - NewChildren -> - loop(KindOfTable,CurrNode,NewMarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren) - end; - - - {gs, Gridline, doubleclick, {grid,Data}, [?INFO_COL,Row,Text | _]} when Text =/= "" -> - unmark_cell(MarkedCell, Tables), - NewMarkedCell = mark_cell({Gridline, ?INFO_COL, Row}, undefined, Data), - {Table, _Name, _Readable} = get_table_id(KindOfTable, Row, Tables), - case start_tv_info(Table, CurrNode, CurrNode =:= node(), KindOfTable, Children) of - Children -> - {FinalMarkedCell, NewTables, NewGridLines} = - refresh_window(NewMarkedCell,Tables,KindOfTable,CurrNode,GridLines, - UnreadHidden,SysTabHidden,SortKey, Children), - loop(KindOfTable,CurrNode,FinalMarkedCell,NewGridLines,WinSize,NewTables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - NewChildren -> - loop(KindOfTable,CurrNode,NewMarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren) - end; - - - {gs, Gridline, doubleclick, {grid,Data}, [?PID_COL,Row,Text | _]} when Text =/= "" -> - unmark_cell(MarkedCell, Tables), - NewMarkedCell = mark_cell({Gridline, ?PID_COL, Row}, undefined, Data), - OwnerPid = element(?PID_ELEM, lists:nth(Row, Tables)), - NewChildren = start_pman(OwnerPid, Children), - loop(KindOfTable,CurrNode,NewMarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey, NewChildren); - - - {gs, Gridline, doubleclick, {grid,Data}, [?PROCNAME_COL,Row,Text | _]} when Text =/= "" -> - unmark_cell(MarkedCell, Tables), - NewMarkedCell = mark_cell({Gridline, ?PROCNAME_COL, Row}, undefined, Data), - OwnerPid = element(?PID_ELEM, lists:nth(Row, Tables)), - NewChildren = start_pman(OwnerPid, Children), - loop(KindOfTable,CurrNode,NewMarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey, NewChildren); - - -%% {gs, win, configure, _Data, [Width, Height | _]} when {Width,Height} /= WinSize -> - Msg0 = {gs, win, configure, _Data, [Width0, Height0 | _]} - when {Width0,Height0} =/= WinSize -> - {gs, win, configure, _, [Width,Height|_]} = flush_msgs(Msg0), - - NewSize = resize_window(Width, Height, length(Tables)), - loop(KindOfTable,CurrNode,MarkedCell,GridLines,NewSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, _Id, click, update, _Args} -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} = - update_grid(KindOfTable,CurrNode,GridLines,UnreadHidden,SysTabHidden,SortKey), - update_tv_info(Children), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, _Id, click, open_table, _Args} -> - {Table, Name, Readable} = get_table_id(KindOfTable, element(3, MarkedCell), - Tables), - case start_tv_browser(Table,CurrNode,Name,KindOfTable,Readable,Children) of - Children -> - {NewMarkedCell, NewTables, NewGridLines} = - refresh_window(MarkedCell,Tables,KindOfTable,CurrNode,GridLines, - UnreadHidden,SysTabHidden,SortKey, Children), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - NewChildren -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren) - end; - - - {gs, _Id, click, new_table, _Args} -> - NewChildren = start_tv_new_table(CurrNode, Children), - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren); - - - {gs, _Id, click, select_node, _Args} -> - show_tv_nodewin(Children), - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, _Id, click, show_mnesia, _Args} when KindOfTable =:= ets -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - gs:config(label2, [{fg, ?DISABLED_COLOR}]), - gs:config(sort_table_id, [{enable, false}]), - NewSortKey = - case SortKey of - ?ID_ELEM -> - gs:config(sort_table_name, [{select,true}]), - ?NAME_ELEM; - _Other -> - SortKey - end, - {NewTables, NewGridLines} = - update_grid(mnesia, CurrNode, GridLines, UnreadHidden, SysTabHidden, NewSortKey), - gs:config(win, [{cursor,arrow}]), - loop(mnesia,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,NewSortKey,Children); - - - {gs, _Id, click, show_ets, _Args} when KindOfTable =:= mnesia -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - gs:config(label2, [{fg, ?NORMAL_FG_COLOR}]), - gs:config(label3, [{fg, ?NORMAL_FG_COLOR}]), - gs:config(label4, [{fg, ?NORMAL_FG_COLOR}]), - {NewTables, NewGridLines} = - update_grid(ets, CurrNode, GridLines, UnreadHidden, SysTabHidden,SortKey), - %% gs:config(show_unreadable, [{enable, true}, - %% {select, not(UnreadHidden)}]), - gs:config(sort_table_id, [{enable, true}]), - gs:config(win, [{cursor,arrow}]), - loop(ets,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, _Id, click, show_system, _Args} when SysTabHidden -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} - = update_grid(KindOfTable, CurrNode, GridLines, UnreadHidden, false, SortKey), - gs:config(show_system, [{data, hide_system}]), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,false,SortKey,Children); - - - {gs, _Id, click, hide_system, _Args} when not SysTabHidden -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} = - update_grid(KindOfTable, CurrNode, GridLines, UnreadHidden, true, SortKey), - gs:config(show_system, [{label, {text, " System Tables "}}, - {data, show_system}]), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,true,SortKey,Children); - - - {gs, _Id, click, show_unreadable, _Args} when UnreadHidden -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} - = update_grid(KindOfTable, CurrNode, GridLines, false, SysTabHidden, SortKey), - gs:config(show_unreadable, [{data, hide_unreadable}]), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - false,SysTabHidden,SortKey,Children); - - - {gs, _Id, click, hide_unreadable, _Args} when not UnreadHidden -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} = - update_grid(KindOfTable, CurrNode, GridLines, true, SysTabHidden, SortKey), - gs:config(show_unreadable, [{label, {text, " Unreadable Tables "}}, - {data, show_unreadable}]), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - true,SysTabHidden,SortKey,Children); - - - {gs, _Id, click, show_info, _Args} -> - {Table, _Name, _Readable} = get_table_id(KindOfTable, element(3,MarkedCell), - Tables), - case start_tv_info(Table, CurrNode, CurrNode =:= node(), KindOfTable, Children) of - Children -> - {NewMarkedCell, NewTables, NewGridLines} = - refresh_window(MarkedCell,Tables,KindOfTable,CurrNode,GridLines, - UnreadHidden,SysTabHidden,SortKey, Children), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - NewChildren -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren) - end; - - - {gs, _Id, click, sort_table_name, _Args} when SortKey =/= ?NAME_ELEM -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} = - update_grid(KindOfTable,CurrNode,GridLines,UnreadHidden,SysTabHidden,?NAME_ELEM), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,?NAME_ELEM,Children); - - - {gs, _Id, click, sort_table_id, _Args} when SortKey =/= ?ID_ELEM -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} = - update_grid(KindOfTable,CurrNode,GridLines,UnreadHidden,SysTabHidden,?ID_ELEM), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,?ID_ELEM,Children); - - - {gs, _Id, click, sort_owner_name, _Args} when SortKey =/= ?PROCNAME_ELEM -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} = - update_grid(KindOfTable,CurrNode,GridLines,UnreadHidden,SysTabHidden, - ?PROCNAME_ELEM), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,?PROCNAME_ELEM,Children); - - - {gs, _Id, click, sort_owner_pid, _Args} when SortKey =/= ?PID_ELEM -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} = - update_grid(KindOfTable,CurrNode,GridLines,UnreadHidden,SysTabHidden,?PID_ELEM), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,?PID_ELEM,Children); - - - {gs, _Id, click, trace_process, _Args} -> - OwnerPid = element(?PID_ELEM, lists:nth(element(3,MarkedCell), Tables)), - NewChildren = start_pman(OwnerPid, Children), - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren); - - - {gs, _Id, click, help_button, _Args} -> - HelpFile = filename:join([code:lib_dir(tv), "doc", "html", "index.html"]), - tool_utils:open_help(win, HelpFile), - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, _Id, click, otp_help_button, _Args} -> - IndexFile = filename:join([code:root_dir(), "doc", "index.html"]), - tool_utils:open_help(win, IndexFile), - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, win, configure, _Data, _Args} -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, _Id, click, exit_button, _Args} -> - lists:foreach( - fun({Pid,pman,_OP}) -> - exit(Pid,kill); - (_) -> - done - end, - Children), - exit(normal); - - - {gs, _Id, click, show_haiku, _Args} -> - gs:config(win, [{cursor,busy}]), - gs:config(show_haiku, [{data, hide_haiku}]), - lists:foreach( - fun({Pid,tv_info,_Data}) -> - Pid ! {error_msg_mode,haiku}; - ({Pid,tv_browser,_Data}) -> - Pid ! {error_msg_mode,haiku}; - ({Pid,tv_nodewin,_Data}) -> - Pid ! {error_msg_mode,haiku}; - ({Pid,tv_new_table,_Data}) -> - Pid ! {error_msg_mode,haiku}; - (_Other) -> - done - end, - Children), - put(error_msg_mode, haiku), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable, CurrNode, MarkedCell, GridLines, WinSize, Tables, Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, _Id, click, hide_haiku, _Args} -> - gs:config(win, [{cursor,busy}]), - gs:config(show_haiku, [{data, show_haiku}]), - lists:foreach( - fun({Pid,tv_info,_Data}) -> - Pid ! {error_msg_mode,normal}; - ({Pid,tv_browser,_Data}) -> - Pid ! {error_msg_mode,normal}; - ({Pid,tv_nodewin,_Data}) -> - Pid ! {error_msg_mode,normal}; - ({Pid,tv_new_table,_Data}) -> - Pid ! {error_msg_mode,normal}; - (_Other) -> - done - end, - Children), - put(error_msg_mode, normal), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable, CurrNode, MarkedCell, GridLines, WinSize, Tables, Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {gs, win, destroy, _Data, _Args} -> - lists:foreach( - fun({Pid,pman,_OP}) -> - exit(Pid,kill); - (_) -> - done - end, - Children), - exit(normal); - - - {gs, win, keypress, _Data, [Key, _, _, 1 | _]} -> - case lists:keysearch(Key, 1, Shortcuts) of - {value, {Key, Value}} -> - handle_keypress(Value,KindOfTable,CurrNode,MarkedCell, - GridLines,WinSize,Tables, Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - false -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children) - end; - - - {gs, win, keypress, _Data, _Args} -> - loop(KindOfTable, CurrNode, MarkedCell, GridLines, WinSize, Tables, Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - - {tv_new_node, _Sender, NewCurrNode} -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} = - update_grid(KindOfTable,NewCurrNode,GridLines,UnreadHidden,SysTabHidden,SortKey), - update_tv_info(Children), - update_tv_browser(Children), - NewChildren = - case replace_node_name(NewCurrNode, CurrNode) of - false -> - Children; - true -> - update_node_name(Children) - end, - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,NewCurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren); - - - {tv_start_infowin, Table, Node, LocalNode, TableType} -> - case start_tv_info(Table, Node, LocalNode, TableType, Children) of - Children -> - {NewMarkedCell, NewTables, NewGridLines} = - refresh_window(MarkedCell,Tables,KindOfTable,CurrNode,GridLines, - UnreadHidden,SysTabHidden,SortKey, Children), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - NewChildren -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren) - end; - - - {tv_update_infowin, Table, Node, _Type} -> - case get_tv_info_pid(Table, Node, Children) of - undefined -> - done; - Pid -> - Pid ! #info_update_table_info{sender=self()} - end, - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize, - Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - - - {tv_new_table, NewTabWinPid, Node, Name, Options, KindOfTableToCreate, _Readable, false} -> - case create_table(KindOfTableToCreate, Node, Node =:= node(), Name, Options, - NewTabWinPid) of - error -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize, - Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - _TabId -> - case KindOfTable of - mnesia -> - done; - ets -> - self() ! {gs, tv_main, click, update, []} - end, - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) - end; - - - - {tv_new_table, NewTabWinPid, Node, Name, Options, KindOfTableToCreate, Readable, true} -> - case create_table(KindOfTableToCreate, Node, Node =:= node(), Name, Options, - NewTabWinPid) of - error -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize, - Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - TabId -> - case start_tv_browser(TabId,Node,Name,KindOfTableToCreate,Readable,Children) of - Children -> - {FinalMarkedCell, NewTables, NewGridLines} = - case KindOfTable of - mnesia -> - {MarkedCell, Tables, GridLines}; - ets -> - refresh_window(MarkedCell,Tables,KindOfTable, - CurrNode,GridLines,UnreadHidden, - SysTabHidden,SortKey, Children) - end, - loop(KindOfTable,CurrNode,FinalMarkedCell,NewGridLines,WinSize, - NewTables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - NewChildren -> - case KindOfTable of - mnesia -> - done; - ets -> - self() ! {gs, tv_main, click, update, []} - end, - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,NewChildren) - end - end; - - - - {'EXIT', Pid, _Reason} -> - case lists:keysearch(Pid, 1, Children) of - false -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize, - Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - {value, {Pid,Prog,_Data}} -> - NewChildren = - case Prog of - tv_nodewin -> - lists:keydelete(Pid, 1, Children) ++ start_tv_nodewin(CurrNode); - _Other -> - lists:keydelete(Pid, 1, Children) - end, - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize, - Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,NewChildren) - end; - - - _Other -> - loop(KindOfTable, CurrNode, MarkedCell, GridLines, WinSize, Tables, Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children) - end. - - -flush_msgs(Msg0 = {gs, Win, Op, _, _}) -> - receive Msg = {gs, Win,Op,_,_} -> - flush_msgs(Msg) - after 100 -> - Msg0 - end. - -handle_keypress(open_table,KindOfTable,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - NewChildren = - case MarkedCell of - {undefined,_,_} -> - case get(error_msg_mode) of - normal -> - gs:config(win, [beep]), - tv_utils:notify(win, "TV Notification", "No table selected!"); - haiku -> - Msg = ["Rather than a beep", - "Or a rude error message", - "These words: make a choice."], - tv_utils:notify(win, "TV Notification", Msg) - end, - Children; - _OtherCell -> - {Table, Name, Readable} = get_table_id(KindOfTable, element(3, MarkedCell), - Tables), - start_tv_browser(Table, CurrNode, Name, KindOfTable, Readable, Children) - end, - case NewChildren of - Children -> - {NewMarkedCell, NewTables, NewGridLines} = - refresh_window(MarkedCell,Tables,KindOfTable,CurrNode,GridLines,UnreadHidden, - SysTabHidden, SortKey, Children), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - _Other -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren) - end; - - -handle_keypress(update,KindOfTable,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTabs, NewGrLines} = - update_grid(KindOfTable,CurrNode,GridLines,UnreadHidden,SysTabHidden,SortKey), - update_tv_info(Children), - gs:config(win, [{cursor,arrow}]), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGrLines,WinSize,NewTabs,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - -handle_keypress(show_mnesia,ets,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - gs:config(label2, [{fg, ?DISABLED_COLOR}]), - gs:config(label3, [{fg, ?DISABLED_COLOR}]), - gs:config(label4, [{fg, ?DISABLED_COLOR}]), - gs:config(show_unreadable, [{label, {text, " Unreadable Tables "}}, - {data, show_unreadable}]), - %% gs:config(show_unreadable, [{enable, false}, - %% {select, false}]), - gs:config(sort_table_id, [{enable, false}]), - NewSortKey = - case SortKey of - ?ID_ELEM -> - gs:config(sort_table_name, [{select,true}]), - ?NAME_ELEM; - _Other -> - SortKey - end, - {NewTables, NewGridLines} = - update_grid(mnesia,CurrNode,GridLines,UnreadHidden,SysTabHidden,NewSortKey), - gs:config(win, [{cursor,arrow}]), - loop(mnesia,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,NewSortKey,Children); - - - -handle_keypress(show_ets,mnesia,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - gs:config(label2, [{fg, ?NORMAL_FG_COLOR}]), - gs:config(label3, [{fg, ?NORMAL_FG_COLOR}]), - gs:config(label4, [{fg, ?NORMAL_FG_COLOR}]), - {NewTables, NewGridLines} = - update_grid(ets,CurrNode,GridLines,UnreadHidden,SysTabHidden,SortKey), - %% gs:config(show_unreadable, [{enable, true}, - %% {select, not(UnreadHidden)}]), - gs:config(sort_table_id, [{enable, true}]), - gs:config(win, [{cursor,arrow}]), - loop(ets,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - -handle_keypress(trace_process,KindOfTable,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - NewChildren = - case MarkedCell of - {_Id, ?PID_COL, Row} -> - OwnerPid = element(?PID_ELEM, lists:nth(Row, Tables)), - start_pman(OwnerPid, Children); - {_Id, ?PROCNAME_COL, Row} -> - OwnerPid = element(?PID_ELEM, lists:nth(Row, Tables)), - start_pman(OwnerPid, Children); - _Other -> - Children - end, - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey, NewChildren); - - -handle_keypress(select_node,KindOfTable,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - show_tv_nodewin(Children), - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - - -handle_keypress(show_info,KindOfTable,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - NewChildren = - case MarkedCell of - {_Id, ?NAME_COL, Row} -> - {Table, _Name, _Readable} = get_table_id(KindOfTable, Row, Tables), - start_tv_info(Table, CurrNode, CurrNode =:= node(), KindOfTable, Children); - {_Id, ?ID_COL, Row} -> - {Table, _Name, _Readable} = get_table_id(KindOfTable, Row, Tables), - start_tv_info(Table, CurrNode, CurrNode =:= node(), KindOfTable, Children); - {_Id, ?INFO_COL, Row} -> - {Table, _Name, _Readable} = get_table_id(KindOfTable, Row, Tables), - start_tv_info(Table, CurrNode, CurrNode =:= node(), KindOfTable, Children); - _OtherCell -> - Children - end, - case NewChildren of - Children -> - {NewMarkedCell, NewTables, NewGridLines} = - refresh_window(MarkedCell,Tables,KindOfTable,CurrNode,GridLines,UnreadHidden, - SysTabHidden, SortKey, Children), - loop(KindOfTable,CurrNode,NewMarkedCell,NewGridLines,WinSize,NewTables, - Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children); - _Other -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,NewChildren) - end; - - -handle_keypress(help_button,KindOfTable,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - HelpFile = filename:join([code:lib_dir(tv), "doc", "html", "index.html"]), - tool_utils:open_help(win, HelpFile), - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children); - -handle_keypress(exit_button,_KindOfTable,_CurrNode,_MarkedCell,_GridLines, - _WinSize,_Tables,_Shortcuts,_UnreadHidden,_SysTabHidden,_SortKey,Children) -> - lists:foreach( - fun({Pid,pman,_OP}) -> - exit(Pid,kill); - (_) -> - done - end, - Children), - exit(normal); - - -handle_keypress(_Any,KindOfTable,CurrNode,MarkedCell,GridLines, - WinSize,Tables,Shortcuts,UnreadHidden,SysTabHidden,SortKey,Children) -> - loop(KindOfTable,CurrNode,MarkedCell,GridLines,WinSize,Tables,Shortcuts, - UnreadHidden,SysTabHidden,SortKey,Children). - - - - -refresh_window(MarkedCell,Tables,KindOfTable, - CurrNode,GridLines,UnreadHidden,SysTabHidden, SortKey, Children) -> - gs:config(win, [{cursor,busy}]), - NewMarkedCell = unmark_cell(MarkedCell, Tables), - {NewTables, NewGridLines} = - update_grid(KindOfTable,CurrNode,GridLines,UnreadHidden,SysTabHidden, - SortKey), - update_tv_info(Children), - gs:config(win, [{cursor,arrow}]), - {NewMarkedCell, NewTables, NewGridLines}. - - - - - -get_table_id(mnesia, Row, Tables) -> - TabTuple = lists:nth(Row, Tables), - Readable = element(?READABLE_ELEM, TabTuple), - Id = element(?NAME_ELEM, TabTuple), - {Id, Id, Readable}; -get_table_id(ets, Row, Tables) -> - TabTuple = lists:nth(Row, Tables), - Readable = element(?READABLE_ELEM, TabTuple), - Name = element(?NAME_ELEM, TabTuple), - case element(?NAMED_TABLE_ELEM, TabTuple) of - false -> - {element(?ID_ELEM, TabTuple), Name, Readable}; - _Other -> - {Name, Name, Readable} - end. - - - -replace_node_name('nonode@nohost', 'nonode@nohost') -> - %% Still undistributed... - false; -replace_node_name(_Node, _OldNode) when node() =:= 'nonode@nohost' -> - %% No longer distributed, but previously was! - true; -replace_node_name(_Node, 'nonode@nohost') -> - %% The system has been distributed! - true; -replace_node_name(_Node, _OldNode) -> - false. - - - -update_node_name(Children) when node() =:= 'nonode@nohost' -> - %% We have been distributed, but no longer are! - %% We change all node names stored to 'nonode@nohost'! - %% This works because we *will* receive exit signals - %% for those processes that have died on other nodes, - %% whereupon these processes will be removed from the - %% 'Children' list. - lists:map(fun({Pid, Prog, {Table,_Node}}) -> - {Pid, Prog, {Table,'nonode@nohost'}}; - (H) -> - H - end, - Children); -update_node_name(Children) -> - %% We have become distributed! - %% Change all occurrences of 'nonode@nohost' - %% to the new current node name! - HomeNode = node(), - lists:map(fun({Pid, Prog, {Table,'nonode@nohost'}}) -> - {Pid, Prog, {Table,HomeNode}}; - (H) -> - H - end, - Children). - - - - -show_tv_nodewin(Children) -> - {value, {Pid,tv_nodewin,_Node}} = lists:keysearch(tv_nodewin, 2, Children), - Pid ! show_window. - - - -update_tv_info(Children) -> - Sender = self(), - lists:foreach(fun({Pid,tv_info,{_Table,_Node}}) -> - Pid ! #info_update_table_info{sender=Sender}; - (_) -> - done - end, - Children). - - - -update_tv_browser(Children) -> - lists:foreach(fun({Pid,tv_browser,{_Table,_Node}}) -> - Pid ! check_node; - (_) -> - done - end, - Children). - - - -get_tv_info_pid(TabId,Node,Children) -> - TvInfoChildren = [X || X <- Children, element(2,X) =:= tv_info], - case lists:keysearch({TabId,Node}, 3, TvInfoChildren) of - {value, {Pid, tv_info, {_Table,Node}}} -> - Pid; - _Other -> - undefined - end. - - - -start_tv_browser(Tab,Node,_Name,KindOfTable,false,Children) -> - gs:config(win, [beep]), - case get(error_msg_mode) of - normal -> - tv_utils:notify(win, "TV Notification", - ["The selected table is unreadable!", - "Only table information may be viewed!"]); - haiku -> - Msg = ["Table protected.", - "The answers that you're seeking", - "will remain unknown."], - tv_utils:notify(win, "TV Notification", Msg) - end, - start_tv_info(Tab, Node, Node =:= node(), KindOfTable, Children); -start_tv_browser(Table,Node,Name,KindOfTable,_Readable,Children) -> - TvBrowserChildren = [X || X <- Children, element(2,X) =:= tv_browser], - case lists:keysearch({Table,Node}, 3, TvBrowserChildren) of - {value, {BPid,tv_browser,{Table,Node}}} -> - BPid ! raise, - Children; - _Other -> - %% Check that table still exists! - case table_still_there(KindOfTable, Node, Node =:= node(), Table, Name) of - true -> - LocalNode = (Node =:= node()), - NewBPid = tv:start_browser(Node, LocalNode, Table, KindOfTable, Name, - get(error_msg_mode)), - [{NewBPid, tv_browser, {Table,Node}} | Children]; - _TableDead -> - gs:config(win, [beep]), - case get(error_msg_mode) of - normal -> - tv_utils:notify(win, "TV Notification", - ["The table no longer exists!"]); - haiku -> - Msg = ["A table that big?", - "It might be very useful.", - "But now it is gone."], - tv_utils:notify(win, "TV Notification", Msg) - end, - Children - end - end. - - - - - -table_still_there(ets, Node, LocalNode, Table, Name) -> - case catch tv_ets_rpc:all(Node, LocalNode) of - Tables when is_list(Tables) -> - case lists:member(Table, Tables) of - true -> - true; - false -> %% May be a named table... - lists:keymember(Name, 1, Tables) - end; - Error -> - analyze_error(Error, Node, Table), - false - end; -table_still_there(mnesia, Node, LocalNode, Table, Name) -> - case catch tv_mnesia_rpc:system_info(Node, LocalNode, tables) of - Tables when is_list(Tables) -> - lists:member(Name, Tables); - Error -> - analyze_error(Error, Node, Table), - false - end. - - - - - - -start_tv_info(Table, Node, LocalNode, KindOfTable, Children) -> - TvInfoChildren = [X || X <- Children, element(2,X) =:= tv_info], - case lists:keysearch({Table,Node}, 3, TvInfoChildren) of - {value, {Pid,tv_info,{Table,Node}}} -> - Pid ! #info_raise_window{sender = self()}, - Children; - _Other -> - %% May have started a browser but no info window! - %% Info window may have been started from that browser, but - %% don't bother with checking *that*. - Pid = spawn_link(tv_info, info, [self(), Node, LocalNode, Table, KindOfTable, - get(error_msg_mode)]), - [{Pid, tv_info, {Table,Node}} | Children] - end. - - - - - -start_tv_new_table(CurrNode, Children) -> - TvNewTableChild = [X || X <- Children, element(2,X) =:= tv_new_table], - case TvNewTableChild of - [{Pid,tv_new_table,undefined}] -> - Pid ! raise, - Children; - [] -> - Pid = tv_new_table:start(CurrNode, get(error_msg_mode)), - [{Pid, tv_new_table, undefined} | Children] - end. - - - - -create_table(mnesia, _Node, _LocalNode, _TabName, _Options, _NewTabWinPid) -> - error; -create_table(ets, Node, LocalNode, TabName, Options, NewTabWinPid) -> - case tv_table_owner:create(ets, Node, LocalNode, TabName, Options) of - {ok, TabId} -> - NewTabWinPid ! ok, - TabId; - error -> - NewTabWinPid ! error, - error - end. - - - - -start_pman(OwnerPid, Children) -> - Pid = pman_shell:start(OwnerPid), - [{Pid,pman,OwnerPid} | Children]. - - - - -update_grid(TableType, CurrNode, GridLines, UnreadHidden, SysTabHidden,SortKey) -> - NewTables = get_tables(CurrNode, TableType, UnreadHidden, SysTabHidden,SortKey), - TabStr = case TableType of - mnesia -> - "Mnesia "; - ets -> - "ETS " - end, - NodeStr = atom_to_list(CurrNode), - gs:config(win, [{title, "[TV] " ++ TabStr ++ "tables on " ++ NodeStr}]), - gs:config(grid, [{rows, {1, get_nof_rows(length(NewTables), gs:read(grid,height))}}]), - NewGridLines = update_gridlines(NewTables, GridLines, 1), - {NewTables, NewGridLines}. - - - -unmark_cell({undefined, AnyCol, AnyRow}, _Tables) -> - {undefined, AnyCol, AnyRow}; -unmark_cell({Id, Col, Row}, Tables) -> - disable_menus(), - TabTuple = lists:nth(Row, Tables), - ReadableTable = element(?READABLE_ELEM, TabTuple), - NamedTable = element(?NAMED_TABLE_ELEM, TabTuple), - BgColor = - case ReadableTable of - false -> - ?UNREADABLE_BG_COLOR; - _Other1 -> - ?READABLE_BG_COLOR - end, - - FgColor = - case NamedTable of - false when Col =:= ?NAME_COL -> - ?UNNAMED_FG_COLOR; - _Other2 -> - ?NORMAL_FG_COLOR - end, - - gs:config(Id, [{bg, {Col, BgColor}}, - {fg, {Col, FgColor}}]), - {undefined, undefined, undefined}. - - - - -mark_cell({Id,Col,Row}, {Id,Col,Row}, _Readable) -> - {undefined, undefined, undefined}; -mark_cell({Id,Col,Row}, _Any, Readable) -> - case lists:member(Col, ?POSSIBLE_MARK_COLS) of - true -> - enable_menus(Col, Readable), - gs:config(Id, [{bg, {Col, ?GRID_MARK_COLOR}}, - {fg, {Col, ?NORMAL_FG_COLOR}}]), - {Id, Col,Row}; - false -> - {undefined, undefined, undefined} - end. - - -disable_menus() -> - disable_open_menu(), - disable_trace_menu(), - disable_info_menu(). - - -enable_menus(?ID_COL, true) -> - enable_open_menu(), - enable_info_menu(); -enable_menus(?ID_COL, {notext}) -> - enable_open_menu(), - enable_info_menu(); -enable_menus(?ID_COL, false) -> - enable_info_menu(); -enable_menus(?NAME_COL, true) -> - enable_open_menu(), - enable_info_menu(); -enable_menus(?NAME_COL, {notext}) -> - enable_open_menu(), - enable_info_menu(); -enable_menus(?NAME_COL, false) -> - enable_info_menu(); -enable_menus(?PID_COL, _Any) -> - enable_trace_menu(); -enable_menus(?PROCNAME_COL, _Any) -> - enable_trace_menu(); -enable_menus(?INFO_COL, _Any) -> - enable_info_menu(); -enable_menus(_Col, _Any) -> - done. - - - -resize_window(Width, Height, NofElems) -> - WinWidth = lists:max([Width, ?MIN_WIN_WIDTH]), - WinHeight = lists:max([Height, ?MIN_WIN_HEIGHT]), - gs:config(win, [{width, WinWidth}, - {height, WinHeight} - ]), - {BgWidth, BgHeight, FgWidth, FgHeight} = get_frame_coords(WinWidth, WinHeight), - {GridWidth, GridHeight} = get_grid_coords(FgWidth, FgHeight), - ColWidths = get_col_widths(?COL_WIDTHS, GridWidth), - resize_header_labels(ColWidths, - [label1,label2,label3,label4,label5], - ?GRID_XPOS), - gs:config(bgframe, [{width, BgWidth}, - {height, BgHeight} - ]), - gs:config(fgframe, [{width, FgWidth}, - {height, FgHeight} - ]), - gs:config(grid, [{width, GridWidth}, - {height, GridHeight}, - {columnwidths, ColWidths}, - {rows, {1, get_nof_rows(NofElems, GridHeight)}} - ]), - {WinWidth, WinHeight}. - - - - -create_window(Tables) -> - gs:window(win, gs:start(), [{width, ?WIN_WIDTH}, - {height, ?WIN_HEIGHT}, - {bg, ?DEFAULT_BG_COLOR}, - {title, "[TV] ETS tables on " ++ - atom_to_list(node())}, - {destroy, true}, - {configure, true}, - {keypress, true} - ]), - - ShortcutList = create_menus(), - - disable_menus(), - - {BgFrameWidth, BgFrameHeight, FgFrameWidth, FgFrameHeight} = - get_frame_coords(?WIN_WIDTH, ?WIN_HEIGHT), - - {GridWidth, GridHeight} = get_grid_coords(FgFrameWidth, FgFrameHeight), - - ColWidths = get_col_widths(?COL_WIDTHS, GridWidth), - - gs:frame(bgframe, win, [{width, BgFrameWidth}, - {height, BgFrameHeight}, - {x, ?GRID_XPOS}, - {y, ?GRID_YPOS}, - {bg, {0,0,0}} - ]), - gs:frame(fgframe, bgframe, [{width, FgFrameWidth}, - {height, FgFrameHeight}, - {x, 0}, - {y, 1}, - {bg, ?DEFAULT_BG_COLOR} - ]), - - - create_header_labels(ColWidths, ?HEADER_LABELS), - gs:grid(grid, fgframe, [{width, GridWidth}, - {height, GridHeight}, - {x, 0}, - {y, -1}, - {hscroll,bottom}, - {vscroll,right}, - {rows, {1, get_nof_rows(length(Tables), GridHeight)}}, - {columnwidths, ColWidths}, - {fg, ?NORMAL_FG_COLOR}, - {bg, {255,255,255}}, - {font, ?FONT} - ]), - GridLines = update_gridlines(Tables, [], 1), - {{undefined,undefined,undefined}, GridLines, {?WIN_WIDTH,?WIN_HEIGHT}, ShortcutList}. - - - - -get_frame_coords(WinWidth, WinHeight) -> - BgWidth = WinWidth - 2 * ?GRID_XPOS, - BgHeight = WinHeight - ?GRID_YPOS - ?GRID_XPOS, - FgWidth = BgWidth, - FgHeight = BgHeight - 1, - {BgWidth, BgHeight, FgWidth, FgHeight}. - - - - -get_grid_coords(ParentWidth, ParentHeight) -> - {ParentWidth, ParentHeight + 1}. - - - -get_col_widths(Cols, GridWidth) -> - SbWidth = 25, %% OK, OK, don't bother about it, this constant makes it work... :-/ - FixColWidthSum = lists:sum(lists:map(fun(H) -> - lists:nth(H, Cols) - end, - ?FIX_WIDTH_COLS)), - AvailableWidth = GridWidth - FixColWidthSum - SbWidth, - OriginalWidth = ?WIN_WIDTH - 2 * ?GRID_XPOS - FixColWidthSum - SbWidth, - get_col_widths(1, Cols, AvailableWidth, OriginalWidth). - - - -get_col_widths(N, [H | T], AvailWidth, OrigWidth) -> - NewColWidth = - case lists:member(N, ?FIX_WIDTH_COLS) of - true -> - H; - _Other -> - round(H * (AvailWidth / OrigWidth) + 0.1) - end, - [NewColWidth | get_col_widths(N + 1, T, AvailWidth, OrigWidth)]; -get_col_widths(_N, [], _AvailWidth, _OrigWidth) -> - []. - - - -create_header_labels(ColWidths, Text) -> - create_header_labels(ColWidths, Text, 1, ?GRID_XPOS). - - - -create_header_labels([W | T], [{Name, Text} | TextT], N, Xpos) -> - Ypos = ?GRID_YPOS - 20, - gs:label(Name, win, [{width, W + 1 - 3}, - {height, 20}, - {x, Xpos + 1 + 3}, - {y, Ypos}, - {bg, ?DEFAULT_BG_COLOR}, - {fg, ?NORMAL_FG_COLOR}, - {font, ?HEADER_FONT}, - {align, w}, - {label, {text, Text}} - ]), - create_header_labels(T, TextT, N + 1, Xpos + 1 + W); -create_header_labels([], [], _N, _Xpos) -> - done. - - - -resize_header_labels([W | T], [Name | NT], Xpos) -> - gs:config(Name, [{width, W + 1 - 3}, - {x, Xpos + 1 + 3} - ]), - resize_header_labels(T, NT, Xpos + 1 + W); -resize_header_labels([], [], _Xpos) -> - done. - - - -disable_open_menu() -> - gs:config(open_table, [{enable,false}]). - - -disable_info_menu() -> - gs:config(show_info, [{enable,false}]). - -disable_trace_menu() -> - gs:config(trace_process, [{enable,false}]). - - -enable_open_menu() -> - gs:config(open_table, [{enable,true}]). - - -enable_info_menu() -> - gs:config(show_info, [{enable,true}]). - - -enable_trace_menu() -> - gs:config(trace_process, [{enable,true}]). - - -create_menus() -> - gs:menubar(menubar, win, [{bg, ?DEFAULT_BG_COLOR}]), - - HelpButt = gs:menubutton(menubar, [{bg, ?DEFAULT_BG_COLOR}, - {fg, ?FIREBRICK}, % firebrick - {label, {text, " Help "}}, - {underline, 1}, - {side, right} - ]), - FileButt = gs:menubutton(menubar, [{bg, ?DEFAULT_BG_COLOR}, - {fg, ?FIREBRICK}, % firebrick - {label, {text, " File "}}, - {underline, 1}, - {side, left} - ]), - ViewButt = gs:menubutton(menubar, [{bg, ?DEFAULT_BG_COLOR}, - {fg, ?FIREBRICK}, % firebrick - {label, {text, " View "}}, - {underline, 1}, - {side, left} - ]), - OptionsButt = gs:menubutton(menubar, [{bg, ?DEFAULT_BG_COLOR}, - {fg, ?FIREBRICK}, % firebrick - {label, {text, " Options "}}, - {underline, 1}, - {side, left} - ]), - - HelpMenu = gs:menu(HelpButt, [{bg, ?DEFAULT_BG_COLOR}, - {fg, ?FIREBRICK}, - {disabledfg,?DISABLED_COLOR} - ]), - FileMenu = gs:menu(FileButt, [{bg, ?DEFAULT_BG_COLOR}, - {fg, ?FIREBRICK}, - {disabledfg,?DISABLED_COLOR} - ]), - - OptionsMenu = gs:menu(OptionsButt, [{bg, ?DEFAULT_BG_COLOR}, - {fg, ?FIREBRICK}, - {disabledfg,?DISABLED_COLOR} - ]), - - ViewMenu = gs:menu(ViewButt, [{bg, ?DEFAULT_BG_COLOR}, - {fg, ?FIREBRICK}, - {disabledfg,?DISABLED_COLOR} - ]), - - ShortCutList = - create_menulist([{" Help ",normal,help_button,1,h}, - separator, - {" OTP Documentation ",normal,otp_help_button,1,no_char}], HelpMenu) ++ - create_menulist([{" Open Table ",normal,open_table,1,o}, - {" New Table... ",normal,new_table,1,no_char}, - {" Table Info ",normal,show_info,7,i}, - separator, - {" Nodes... ",normal,select_node,1,n}, - separator, - {" Trace Process ",normal,trace_process,1,t}, - separator, - {" Exit ",normal, exit_button,2,x}], FileMenu) ++ - [{c,exit_button}, {'C',exit_button}] ++ - create_menulist([{" Refresh ",normal,update,1,r}, - separator, - {" Unreadable Tables ",check,show_unreadable,1,no_char}, - separator, - {" System Tables ",check,show_system,1,no_char}, - separator, - {" Sort by Name ",radio,sort_table_name,9,no_char}, - {" Sort by Id ",radio,sort_table_id,9,no_char}, - {" Sort by Owner PID ",radio,sort_owner_pid,15,no_char}, - {" Sort by Owner Name ",radio,sort_owner_name,9,no_char}, - separator, - {" Error Messages in Haiku ",check,show_haiku,1,no_char} - ], - OptionsMenu) ++ - create_menulist([{" ETS Tables ",radio,show_ets,1,e}, - {" Mnesia Tables ",radio,show_mnesia,1,m}], ViewMenu), - gs:config(show_unreadable, [{select,false}]), - gs:config(show_system, [{select,false}]), - gs:config(show_haiku, [{select,false}]), - %% Due to a bug (or some other reason), only one of the radiobuttons belonging - %% to a specified group can be selected, even if different processes have created - %% the radiobuttons! This means that, if we have started more than one tv_main - %% process, selecting one radiobutton will affect the radiobuttons in the other - %% tv_main process(es)!!! Since this is a highly undesirable bahaviour, we have to - %% create unique group names (i.e., atoms). - %% (We need to group the radiobuttons, since otherwise all created by one process - %% belongs to the same group, which also is undesirable...) - SelfStr = pid_to_list(self()), - SortGroup = list_to_atom("sorting" ++ SelfStr), - TypeGroup = list_to_atom("table_type" ++ SelfStr), - gs:config(sort_table_name, [{group,SortGroup},{select,true}]), - gs:config(sort_table_id, [{group,SortGroup}]), - gs:config(sort_owner_pid, [{group,SortGroup}]), - gs:config(sort_owner_name, [{group,SortGroup}]), - gs:config(show_ets, [{group,TypeGroup}, {select,true}]), - gs:config(show_mnesia, [{group,TypeGroup}]), - ShortCutList. - - - - - -create_menulist(List, Menu) -> - MaxLength = get_length_of_longest_menu_text(List, 0), - create_menulist(List, Menu, MaxLength). - - - - -create_menulist([], _Menu, _MaxLength) -> - []; -create_menulist([{Text, Type, Data, AccCharPos, ShortcutChar} | Rest], Menu, MaxLength) -> - ShortcutCapitalChar = - if - ShortcutChar =:= no_char -> - no_char; - true -> - CharAsciiValue = lists:nth(1, atom_to_list(ShortcutChar)), - CapitalCharValue = CharAsciiValue - ($a - $A), - list_to_atom([CapitalCharValue]) - end, - - FinalText = if - ShortcutChar =:= no_char -> - Text; - true -> - Text ++ lists:duplicate(MaxLength - length(Text), " ") ++ - " Ctrl+" ++ atom_to_list(ShortcutCapitalChar) ++ " " - end, - gs:menuitem(Data, Menu, [{bg, ?DEFAULT_BG_COLOR}, - {fg, ?FIREBRICK}, - {itemtype, Type}, - {label, {text, FinalText}}, - {underline, AccCharPos}, - {data, Data} - ]), - [{ShortcutChar, Data}, {ShortcutCapitalChar, Data} | create_menulist(Rest, Menu, MaxLength)]; -create_menulist([separator | Rest], Menu, MaxLength) -> - gs:menuitem(Menu, [{itemtype, separator}]), - create_menulist(Rest, Menu, MaxLength). - - - - - - - -get_length_of_longest_menu_text([], MaxLength) -> - MaxLength; -get_length_of_longest_menu_text([{Text, _Type, _Data, _APos, _SChar} | Rest], CurrMax) -> - L = length(Text), - if - L > CurrMax -> - get_length_of_longest_menu_text(Rest, L); - true -> - get_length_of_longest_menu_text(Rest, CurrMax) - end; -get_length_of_longest_menu_text([separator | Rest], CurrMax) -> - get_length_of_longest_menu_text(Rest, CurrMax). - - - - - - -get_nof_rows(NofElems, GridHeight) -> - lists:max([NofElems, round((GridHeight - 20) / 21) + 1]). - - - -config_gridline(LineId, TabTuple) -> - Readable = element(?READABLE_ELEM, TabTuple), - NamedTable = element(?NAMED_TABLE_ELEM, TabTuple), - {FgColor, BgColor} = - case Readable of - true -> - {?NORMAL_FG_COLOR, ?READABLE_BG_COLOR}; - false -> - {?UNREADABLE_FG_COLOR, ?UNREADABLE_BG_COLOR}; - {notext} -> - {?NORMAL_FG_COLOR, ?READABLE_BG_COLOR} - end, - - NameFgColor = - case NamedTable of - false -> - ?UNNAMED_FG_COLOR; - _Other -> - ?NORMAL_FG_COLOR - end, - - gs:config(LineId, [{bg, BgColor}, - {fg, FgColor}, - {fg, {?NAME_COL, NameFgColor}}, - {click, true}, - {doubleclick, true}, - {data, {grid,Readable}} | - - lists:map( - fun({Elem,Col}) -> - case element(Elem, TabTuple) of - {notext} -> - {text, {Col, ""}}; - Other when Elem =:= ?NAME_ELEM -> - case NamedTable of - false -> - {text, {Col, " " ++ - lists:flatten( - io_lib:write( - Other)) ++ " "}}; - _AnyOther -> - {text, {Col, " " ++ lists:flatten( - io_lib:write( - Other))}} - end; - Other -> - {text, {Col, " " ++ lists:flatten( - io_lib:write( - Other))}} - end - end, - [{?NAME_ELEM, ?NAME_COL}, - {?ID_ELEM, ?ID_COL}, - {?PID_ELEM, ?PID_COL}, - {?PROCNAME_ELEM, ?PROCNAME_COL}, - {?INFO_ELEM, ?INFO_COL}] - ) - ]). - - - - - -update_gridlines([TabTuple | TT], [LineId | GT], CurrRow) -> - config_gridline(LineId, TabTuple), - [LineId | update_gridlines(TT, GT, CurrRow + 1)]; -update_gridlines([TabTuple | TT], [], CurrRow) -> - LineId = gs:gridline(grid, [{row, CurrRow}]), - config_gridline(LineId, TabTuple), - [LineId | update_gridlines(TT, [], CurrRow + 1)]; -update_gridlines([], [LineId | GT], _CurrRow) -> - gs:destroy(LineId), - update_gridlines([], GT, _CurrRow); -update_gridlines([], [], _CurrRow) -> - []. - - - - - - - - - |