tv_pd.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,123 行 · 第 1/2 页
ERL
1,123 行
%% ``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: Code for pd, i.e., the data displaying part of the table %%% tool.%%%%%%*********************************************************************-module(tv_pd).-export([pd/2]).-include("tv_int_def.hrl").-include("tv_int_msg.hrl").-include("tv_pd_int_def.hrl").-include("tv_pd_int_msg.hrl").%%%*********************************************************************%%% EXTERNAL FUNCTIONS%%%*********************************************************************%%======================================================================%% Function: pd.%%%% Return Value: None.%%%% Description: Process controlling the display part of the window,%% i.e., showing diagrams and handling the scale used for scrolling.%%%% Parameters: None.%%======================================================================pd(Master, ErrMsgMode) -> process_flag(trap_exit, true), put(error_msg_mode, ErrMsgMode), PgPid = spawn_link(tv_pg, pg, [self()]), PbPid = spawn_link(tv_pb, pb, [self()]), ProcVars = #process_variables{master_pid = Master, pg_pid = PgPid, pb_pid = PbPid}, blocked(ProcVars).%%%********************************************************************%%% INTERNAL FUNCTIONS%%%********************************************************************%%======================================================================%% Function: blocked.%%%% Return Value: None.%%%% Description: When started or explicitly blocked, pd enters this state,%% where nothing is performed until the module explicitly is %% deblocked.%%%% Parameters: %%======================================================================blocked(ProcVars) -> receive Msg -> case Msg of #pd_deblock{} -> deblock(Msg, ProcVars); {error_msg_mode, Mode} -> put(error_msg_mode, Mode), blocked(ProcVars); _Other -> blocked(ProcVars) end end. %%======================================================================%% Function: deblock.%%%% Return Value: None.%%%% Description: When deblocked, a canvas and scale shall be created according to %% specification received in pd_deblock message.%%%% Parameters: Rec: received pd_deblock message.%%======================================================================deblock(Msg, ProcVars) -> #pd_deblock{win = WindowId, win_width = WindowWidth, win_height = WindowHeight} = Msg, NewProcVars = ?DISP_FUNC_FILE:init_display(WindowId, WindowWidth, WindowHeight, ProcVars), receive #pg_ready{} -> Sender = Msg#pd_deblock.sender, Sender ! #pd_deblock_cfm{sender = self()}, deblocked_loop(NewProcVars) end. %%======================================================================%% Function: deblocked_loop.%%%% Return Value: None.%%%% Description: Eternal (well, almost) loop, receiving messages and %% handling them.%%%% Parameters: Master: Pid to the 'pc' process.%% Win: Id of the window created.%%======================================================================deblocked_loop(ProcVars) -> receive Msg -> case Msg of {gs, Id, Event, Data, Args} -> NewProcVars = gs_messages({Id, Event, Data, Args}, ProcVars), deblocked_loop(NewProcVars); _Other -> NewProcVars = tv_messages(Msg, ProcVars), deblocked_loop(NewProcVars) end end. tv_messages(Msg, ProcVars) -> WinId = ProcVars#process_variables.window_id, case Msg of #pg_cell_marked{} -> mark_busy(WinId), NewProcVars = handle_cell_marked(Msg, ProcVars), mark_nonbusy(WinId), NewProcVars; #pc_data{} -> mark_busy(WinId), NewProcVars = show_data(Msg, ProcVars), mark_nonbusy(WinId), NewProcVars; #pc_list_info{} -> handle_list_info(Msg, ProcVars); #pb_col_marked{} -> mark_busy(WinId), NewProcVars = handle_col_marked(Msg, ProcVars), mark_nonbusy(WinId), NewProcVars; #pb_row_marked{} -> mark_busy(WinId), NewProcVars = handle_row_marked(Msg, ProcVars), mark_nonbusy(WinId), NewProcVars; #pb_new_colwidth{} -> mark_busy(WinId), NewProcVars = resize_column(Msg, ProcVars), mark_nonbusy(WinId), NewProcVars; #pd_get_sort_settings{sorting = Sorting, reverse = Reverse} -> mark_busy(WinId), NewProcVars = case send_sort_info_signal(Sorting, Reverse, ProcVars) of ignore -> ProcVars; TempNewProcVars -> set_sort_col(Sorting, TempNewProcVars) end, mark_nonbusy(WinId), NewProcVars; #pd_new_table{table_type=TabType,table_name=TabName, record_name=RecName,writable=Writable} -> mark_busy(WinId), ToolP = ProcVars#process_variables.toolbar_params, ?DISP_FUNC_FILE:update_toolbar_label(notext, ToolP, undefined, undefined, Writable), mark_nonbusy(WinId), ProcVars#process_variables{table_type = TabType, table_name = TabName, record_name = RecName, writable = Writable}; #pd_win_conf{} -> mark_busy(WinId), NewProcVars = resize_window(Msg, ProcVars), mark_nonbusy(WinId), NewProcVars; #pd_rec_edit{} -> mark_busy(WinId), NewProcVars = open_rec_edit(Msg, ProcVars), mark_nonbusy(WinId), NewProcVars; {updated_object, UpdObj} -> get_updated_elem2(true, UpdObj, ProcVars), ProcVars; {new_object, NewObj} -> get_updated_elem2(true, NewObj, ProcVars), ProcVars; {error_msg_mode, Mode} -> put(error_msg_mode, Mode), ProcVars; {'EXIT', Pid, Reason} -> exit_signals({Pid, Reason}, ProcVars); _Other -> ProcVars end.exit_signals(ExitInfo, ProcVars) -> #process_variables{master_pid = MasterPid, pg_pid = PgPid, pb_pid = PbPid, rec_pid = RecPid} = ProcVars, case ExitInfo of {MasterPid, _Reason} -> exit(normal); {PgPid, _Reason} -> exit(normal); {PbPid, _Reason} -> exit(normal); {RecPid, _Reason} -> ProcVars#process_variables{rec_pid = undefined}; _Other -> ProcVars end.open_rec_edit(Msg, ProcVars) -> #pd_rec_edit{attributes = AttrList} = Msg, #process_variables{rec_pid = RecPid, table_type = TabType, table_name = TabName, record_name = RecordName, lists_as_strings = ListsAsStr, mark_params = MarkP} = ProcVars, #mark_params{marked_object = MarkedObject} = MarkP, TabOrRecName = case TabType of mnesia -> RecordName; ets -> TabName end, case RecPid of undefined -> NewRecPid = case MarkedObject of undefined -> tv_rec_edit:start(TabType, TabOrRecName, AttrList, ListsAsStr, get(error_msg_mode)); _Other -> AttrVals = case TabType of mnesia -> tl(tuple_to_list(MarkedObject)); ets -> [MarkedObject] end, tv_rec_edit:start(TabType, TabOrRecName, AttrList, AttrVals, ListsAsStr, get(error_msg_mode)) end, ProcVars#process_variables{rec_pid = NewRecPid}; _AnyPid -> RecPid ! raise, ProcVars end.gs_messages(Msg, ProcVars) -> case Msg of {editentry, keypress, _Data, ['Tab' | _T]} -> gs:config(editentry, [{select, {0,100000000}}]), ProcVars; {editentry, keypress, _Data, ['Return' | _T]} -> get_updated_elem(ProcVars), ProcVars; {Id, enter, {toolbar, Btn, Str}, _} -> gs:config(Id, [{motion, true}]), NewProcVars = handle_toolbar_buttons(Id, Btn, Str, false, 0, 0, ProcVars), NewProcVars; {_Id, buttonpress, _Data, [3 | _Rest]} -> ProcVars; {_Id, buttonpress, vscale, [MouseBtn | _Tail]} -> WinId = ProcVars#process_variables.window_id, mark_busy(WinId), NewProcVars = ?DISP_FUNC_FILE:scroll_vertically(MouseBtn, ProcVars), mark_nonbusy(WinId), NewProcVars; % The order of messages from gs ought to be % 1. 'buttonpress' % 2. 'click' and % 3. 'buttonrelease' % However, quite often the 'click' message comes last, meaning we have % to check for this. :-( {_Id, click, vscale, [NewScalePos | _Tail]} -> WinId = ProcVars#process_variables.window_id, mark_busy(WinId), NewProcVars = ?DISP_FUNC_FILE:perform_vertical_scroll(NewScalePos, ProcVars), mark_nonbusy(WinId), NewProcVars; {_Id, buttonpress, hscale, [MouseBtn | _Tail]} -> WinId = ProcVars#process_variables.window_id, mark_busy(WinId), NewProcVars = ?DISP_FUNC_FILE:scroll_horizontally(MouseBtn, ProcVars), mark_nonbusy(WinId), NewProcVars; {_Id, click, hscale, [NewScalePos | _Tail]} -> WinId = ProcVars#process_variables.window_id, mark_busy(WinId), NewProcVars = ?DISP_FUNC_FILE:perform_horizontal_scroll(NewScalePos, ProcVars), mark_nonbusy(WinId), NewProcVars; {_Id, click, {toolbar, poll_table, _Str}, _Arg} -> WinId = ProcVars#process_variables.window_id, mark_busy(WinId), PcPid = ProcVars#process_variables.master_pid, PcPid ! #pc_poll_table{sender = self()}, mark_nonbusy(WinId), ProcVars; {_Id, click, {toolbar, select_browser, _Str}, _Arg} -> PcPid = ProcVars#process_variables.master_pid, PcPid ! #pc_select{sender = self()}, ProcVars; {_Id, click, {toolbar, help_button, _Str}, _Arg} -> PcPid = ProcVars#process_variables.master_pid, PcPid ! #pc_help{sender = self()}, ProcVars; {_Id, click, {toolbar, insert_object, _Str}, _Arg} -> WinId = ProcVars#process_variables.window_id, mark_busy(WinId), PcPid = ProcVars#process_variables.master_pid, PcPid ! {pc_edit_object, self()}, mark_nonbusy(WinId), ProcVars; {_Id, click, {toolbar, search_object, _Str}, _Arg} -> WinId = ProcVars#process_variables.window_id, mark_busy(WinId), PcPid = ProcVars#process_variables.master_pid, PcPid ! #pc_search_req{sender = self()}, mark_nonbusy(WinId), ProcVars; {_Id, click, {toolbar, sort_rising_order, _Str}, _Arg} -> WinId = ProcVars#process_variables.window_id, mark_busy(WinId), NewProcVars = case send_sort_info_signal(true, false, ProcVars) of ignore -> ProcVars; TempNewProcVars -> set_sort_col(true, TempNewProcVars) end, mark_nonbusy(WinId), NewProcVars; {_Id, click, {toolbar, sort_falling_order, _Str}, _Arg} -> WinId = ProcVars#process_variables.window_id, mark_busy(WinId), NewProcVars = case send_sort_info_signal(true, true, ProcVars) of ignore -> ProcVars; TempNewProcVars -> set_sort_col(true, TempNewProcVars) end, mark_nonbusy(WinId), NewProcVars; {_Id, click, {toolbar, no_sorting, _Str}, _Arg} -> NewProcVars = case send_sort_info_signal(false, false, ProcVars) of ignore -> ProcVars; TempNewProcVars -> set_sort_col(false, TempNewProcVars) end, NewProcVars; {Id, click, {toolbar, table_info, _Str}, _Arg} -> ToolP = ProcVars#process_variables.toolbar_params, F = ToolP#toolbar_params.pop_up_frame_id, gs:config(F, [{y, -30}]), gs:config(Id, [{motion, false}]), PcPid = ProcVars#process_variables.master_pid, PcPid ! #pc_show_table_info{sender = self()}, ProcVars; {Id, click, {labelbtn, pop_up}, _Arg} -> gs:config(Id, [{data, {labelbtn, pop_down}}]), NewProcVars = ?DISP_FUNC_FILE:show_toolbar_editor(ProcVars), NewProcVars; {Id, click, {labelbtn, pop_down}, _Arg} -> gs:config(Id, [{data, {labelbtn, pop_up}}]), NewProcVars = ?DISP_FUNC_FILE:hide_toolbar_editor(ProcVars), NewProcVars; _OtherMessage -> ProcVars end. get_updated_elem(ProcVars) -> EditedStr = gs:read(editentry, text), case tv_db_search:string_to_term(EditedStr) of {error, {_Reason, Msg}} -> gs:config(editentry, [beep]), gs:window(pdwin, gs:start(), []), tv_utils:notify(pdwin, "TV Notification", Msg), gs:destroy(pdwin), ProcVars; {ok, NewTerm} -> get_updated_elem2(false, NewTerm, ProcVars) end.get_updated_elem2(FromRecEdit, NewTerm, ProcVars) -> #process_variables{table_type = TableType, record_name = RecordName, mark_params = MarkP, master_pid = PcPid} = ProcVars, #mark_params{marked_object = ObjToUpdate, marked_color = ObjColor, virtual_row_no = VirtualRow,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?