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 + -
显示快捷键?