tv_pc_menu_handling.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 485 行
ERL
485 行
%% ``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 via the world wide web 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.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%%%%*********************************************************************%%% %%% Description: Part of pc handling the creation of menus, as well as %%% treating the signals these menus results in, when chosen.%%%%%%*********************************************************************-module(tv_pc_menu_handling).-export([create_menus/1, exit_button/1, insert_object/1, delete_object/1, search_object/1, open_table/7, set_poll_interval/1, poll_table/1, sort_rising_order/1, sort_falling_order/1, no_sorting/1, lists_as_strings/1, lists_as_lists/1, table_info/1, help_button/1, otp_help_button/1, get_window_title/4]).-include("tv_int_def.hrl").-include("tv_int_msg.hrl").-include("tv_pc_int_def.hrl").%%%*********************************************************************%%% EXTERNAL FUNCTIONS%%%*********************************************************************%% Shortcuts currently used, in alphabetical order:%% %% c -> "Exit"%% d -> "Delete Object"%% f -> "Sort Falling Order"%% h -> "Help"%% i -> "Table Info"%% n -> "No Sorting"%% o -> "Edit Object"%% p -> "Poll Table"%% r -> "Sort Rising Order"%% s -> "Search Object"%% v -> "Set Poll Interval"%% x -> "Exit"create_menus(PwPid) -> %% 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), ListGroup = list_to_atom("lists" ++ SelfStr), % Order pw to create the 'File' menu. ?GRAPH_FUNC_FILE:create_menu(PwPid, " File ", 1, [{" Table Info ", normal, table_info, 7, i}, separator, {" Close ", normal, exit_button, 1, c} ]), ?GRAPH_FUNC_FILE:create_menu(PwPid, " Edit ", 1, [{" Edit Object... ", normal, insert_object, 1, o}, {" Delete Object ", normal, delete_object, 1, d} ]), ?GRAPH_FUNC_FILE:create_menu(PwPid, " View ", 1, [{" Lists as Lists ",{radio,false,ListGroup},lists_as_lists,10,no_char}, {" Lists as Strings ",{radio,true,ListGroup},lists_as_strings,10,no_char} ]), % Order pw to create the 'Options' menu. ?GRAPH_FUNC_FILE:create_menu(PwPid, " Options ", 1, [{" Poll Table ", normal, poll_table, 1, p}, {" Poll Interval... ",normal,set_poll_interval,6,no_char}, separator, {" Search Object ", normal, search_object, 1, s}, separator, {" Sort Ascending Order ",{radio,false,SortGroup},sort_rising_order,6,no_char}, {" Sort Descending Order ",{radio,false,SortGroup},sort_falling_order,6,no_char}, {" No Sorting ",{radio,true,SortGroup},no_sorting,1,no_char} ]). exit_button(_ProcVars) -> exit(normal).help_button(ProcVars) -> WinP = ProcVars#process_variables.window_params, HelpFile = filename:join([code:lib_dir(tv), "doc", "html", "index.html"]), tool_utils:open_help(WinP#window_params.window_id, HelpFile), ProcVars.otp_help_button(ProcVars) -> WinP = ProcVars#process_variables.window_params, IndexFile = filename:join([code:root_dir(), "doc", "index.html"]), tool_utils:open_help(WinP#window_params.window_id, IndexFile), ProcVars.table_info(ProcVars) -> #process_variables{table_id = TableId, current_node = Node, local_node = LocalNode, table_type = Type, parent_pid = ParentPid} = ProcVars, case TableId of undefined -> done; _OtherValue -> ParentPid ! {tv_start_infowin, TableId, Node, LocalNode, Type} end, ProcVars.sort_rising_order(ProcVars) -> request_sort_settings(ProcVars#process_variables.pd_pid, true, false), ProcVars. sort_falling_order(ProcVars) -> request_sort_settings(ProcVars#process_variables.pd_pid, true, true), ProcVars.no_sorting(ProcVars) -> request_sort_settings(ProcVars#process_variables.pd_pid, false, false), ProcVars. set_poll_interval(ProcVars) -> #process_variables{etsread_pid = EtsreadPid, poll_interval = PollInterval} = ProcVars, case tv_poll_dialog:start(PollInterval) of cancel -> ProcVars; NewPollInterval -> EtsreadPid ! #etsread_set_poll_interval{sender = self(), interval = NewPollInterval}, ProcVars#process_variables{poll_interval = NewPollInterval} end. poll_table(ProcVars) -> EtsreadPid = ProcVars#process_variables.etsread_pid, EtsreadPid ! #etsread_poll_table{sender = self()}, ProcVars. search_object(ProcVars) -> DbsPid = ProcVars#process_variables.dbs_pid, DbsPid ! #dbs_search_req{sender=self()}, ProcVars.lists_as_strings(ProcVars) -> PdPid = ProcVars#process_variables.pd_pid, PdPid ! #pc_list_info{sender=self(), lists_as_strings=true}, DbsPid = ProcVars#process_variables.dbs_pid, DbsPid ! #pc_list_info{sender=self(), lists_as_strings=true}, ProcVars#process_variables{lists_as_strings=true}.lists_as_lists(ProcVars) -> PdPid = ProcVars#process_variables.pd_pid, PdPid ! #pc_list_info{sender=self(), lists_as_strings=false}, DbsPid = ProcVars#process_variables.dbs_pid, DbsPid ! #pc_list_info{sender=self(), lists_as_strings=false}, ProcVars#process_variables{lists_as_strings=false}.insert_object(ProcVars) -> #process_variables{pd_pid = PdPid, current_node = Node, local_node = LocalNode, table_type = TabType, table_name = TabName, table_protection = Protection, window_params = WinP} = ProcVars, case Protection of public -> case TabType of mnesia -> case catch tv_mnesia_rpc:table_info(Node, LocalNode, TabName, attributes) of nodedown -> handle_error(nodedown); no_table -> handle_error(nodedown); mnesia_not_started -> handle_error(mnesia_not_started); {unexpected_error,Reason} -> handle_error({unexpected_error,Reason}); AttrList -> PdPid ! #pd_rec_edit{sender = self(), attributes = AttrList } end; ets -> PdPid ! #pd_rec_edit{sender = self(), attributes = [tuple] } end; _OtherProtection -> WinId = WinP#window_params.window_id, gs:config(WinId, [beep]), ErrMsg = case get(error_msg_mode) of normal -> ["The table is protected and", " cannot be edited."]; haiku -> ["The table you see", "Is cunningly protected:", "You can only watch."] end, tv_utils:notify(WinId, "TV Notification", ErrMsg) end, ProcVars.delete_object(ProcVars) -> #process_variables{dbs_pid = DbsPid, table_protection = Protection, marked_row = MarkedRow, marked_object = MarkedObject, marked_color = MarkedColor, window_params = WinP} = ProcVars, case MarkedRow of undefined -> done; _AnyRow -> case Protection of public -> DbsPid ! #dbs_delete_object{sender = self(), object = MarkedObject, color = MarkedColor, obj_no = MarkedRow}; _OtherProtection -> WinId = WinP#window_params.window_id, gs:config(WinId, [beep]), ErrMsg = case get(error_msg_mode) of normal -> ["The table is protected and", " cannot be edited."]; haiku -> ["The table you see", "Is cunningly protected:", "You can only watch."] end, tv_utils:notify(WinId, "TV Notification", ErrMsg) end end, ProcVars.open_table(CurrNode, LocalNode, TableId, TableType, TableName, Raise, ProcVars) -> #process_variables{dbs_pid = DbsPid, etsread_pid = EtsreadPid, pw_pid = PwPid, pd_pid = PdPid, poll_interval = PollInterval, window_params = WinP} = ProcVars, case Raise of true -> gs:config(WinP#window_params.window_id, [raise]); false -> done end, {Type, KeyPos, Protection} = init_etsread(EtsreadPid, DbsPid, CurrNode, LocalNode, TableId, TableType, PollInterval), WinTitle = get_window_title(TableType, CurrNode, TableId, TableName), PwPid ! #pw_set_window_title{sender = self(), win_title = WinTitle}, Writable = case Protection of public -> true; _Other -> false end, RecordName = case TableType of mnesia -> tv_mnesia_rpc:table_info(CurrNode, LocalNode, TableId, record_name); ets -> undefined end, PdPid ! #pd_new_table{sender = self(), table_type = TableType, table_name = TableName, record_name = RecordName, writable = Writable}, init_dbs(DbsPid, Type, KeyPos, EtsreadPid), ProcVars#process_variables{current_node = CurrNode, local_node = LocalNode, table_id = TableId, table_type = TableType, table_name = TableName, table_protection = Protection}.get_window_title(ets, Node, TableId, TableName) -> NameStr = lists:flatten(io_lib:write(TableName)), TableStr = case TableId of {TableName, _Pid} -> NameStr; TableName -> NameStr; _Other -> lists:flatten(io_lib:write(TableId)) ++ " (" ++ NameStr ++ ")" end, WinTitleSuffix = " Node: " ++ atom_to_list(Node), "ETS: " ++ TableStr ++ WinTitleSuffix;get_window_title(mnesia, Node, _TableId, TableName) -> TableNameStr = lists:flatten(io_lib:write(TableName)), WinTitleSuffix = " Node: " ++ atom_to_list(Node), "Mnesia: " ++ TableNameStr ++ WinTitleSuffix.%%%*********************************************************************%%% INTERNAL FUNCTIONS%%%*********************************************************************init_etsread(EtsreadPid, DbsPid, Node, LocalNode, TableId, TableType, PollInterval) -> EtsreadPid ! #etsread_deblock{sender = self(), dbs_pid = DbsPid, node = Node, local_node = LocalNode, table_id = TableId, table_type = TableType, poll_interval = PollInterval }, receive #etsread_deblock_cfm{type=Type, keypos=KeyPos, protection=Protection} -> {Type, KeyPos, Protection} after 10000 -> exit(error) end. init_dbs(DbsPid, Type, KeyPos, EtsreadPid) -> DbsPid ! #dbs_deblock{sender = self(), etsread_pid = EtsreadPid, type = Type, keypos = KeyPos, sublist_length = ?ITEMS_TO_DISPLAY }, receive #dbs_deblock_cfm{} -> done after 10000 -> exit(error) end.request_sort_settings(PdPid, Sorting, Reverse) -> PdPid ! #pd_get_sort_settings{sender = self(), sorting = Sorting, reverse = Reverse }. handle_error(mnesia_not_started) -> gs:window(errorwin, gs:start(), []), gs:config(errorwin, [beep]), case get(error_msg_mode) of normal -> tv_utils:notify(errorwin, "TV Notification", ["Mnesia not started!"]); haiku -> tv_utils:notify(errorwin, "TV Notification", ["Mnesia is stopped.", "We wish to reach all data", "But we never will."]) end, gs:destroy(errorwin);handle_error(nodedown) -> done; %% Main process handles this!handle_error({unexpected_error,Cause}) -> gs:window(errorwin, gs:start(), []), io:format("Unexpected error: ~p~n", [Cause]), gs:config(errorwin, [beep]), gs:destroy(errorwin).
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?