diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/tv/src/tv_pc_menu_handling.erl | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/tv/src/tv_pc_menu_handling.erl')
-rw-r--r-- | lib/tv/src/tv_pc_menu_handling.erl | 485 |
1 files changed, 485 insertions, 0 deletions
diff --git a/lib/tv/src/tv_pc_menu_handling.erl b/lib/tv/src/tv_pc_menu_handling.erl new file mode 100644 index 0000000000..16195bf91f --- /dev/null +++ b/lib/tv/src/tv_pc_menu_handling.erl @@ -0,0 +1,485 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-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% +%%%********************************************************************* +%%% +%%% 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). + + |