diff options
Diffstat (limited to 'lib/tv/src/tv_pd.erl')
-rw-r--r-- | lib/tv/src/tv_pd.erl | 1122 |
1 files changed, 1122 insertions, 0 deletions
diff --git a/lib/tv/src/tv_pd.erl b/lib/tv/src/tv_pd.erl new file mode 100644 index 0000000000..ea14bf67b1 --- /dev/null +++ b/lib/tv/src/tv_pd.erl @@ -0,0 +1,1122 @@ +%% +%% %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: 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, + cell_col_no = VirtualCol} = MarkP, + + case ObjToUpdate of + undefined -> + case new_object_ok(TableType, RecordName, NewTerm) of + true -> + PcPid ! #pd_new_object{sender = self(), + object = NewTerm}, + ProcVars; + {false, Msg} -> + gs:window(pdwin, gs:start(), []), + tv_utils:notify(pdwin, "TV Notification", Msg), + gs:destroy(pdwin), + ProcVars + end; + _AnyObj -> + %% We need to know if the object has been deleted! + NewObj = + case VirtualCol of + undefined -> + NewTerm; + _AnyCol when FromRecEdit -> + NewTerm; + _AnyCol -> + if + is_tuple(ObjToUpdate) -> + erlang:setelement(VirtualCol, ObjToUpdate, NewTerm); + true -> + NewTerm + end + end, + %% Is the update OK? + case update_ok(TableType, ObjToUpdate, NewObj) of + true -> + PcPid ! #pd_updated_object{sender = self(), + object = NewObj, + old_object = ObjToUpdate, + old_color = ObjColor, + obj_no = VirtualRow}, + ProcVars; + false -> + gs:window(pdwin, gs:start(), []), + case get(error_msg_mode) of + normal -> + tv_utils:notify(pdwin, "TV Notification", + ["The record name cannot be changed!"]); + haiku -> + tv_utils:notify(pdwin, "TV Notification", + ["The attempt to change", + "The permanent record name", + "Is simply ignored."]) + end, + gs:destroy(pdwin), + ProcVars + end + end. + + + + +new_object_ok(ets, _RecordName, NewTerm) when is_tuple(NewTerm) -> + true; +new_object_ok(ets, _RecordName, _NewTerm) -> + Msg = case get(error_msg_mode) of + normal -> + ["Object is not a tuple!"]; + haiku -> + ["Yes, it is a term.", + "It is pretty, but it's not", + "A proper tuple."] + end, + {false, Msg}; +new_object_ok(mnesia, RecordName, NewTerm) when is_tuple(NewTerm) -> + NewRecName = element(1, NewTerm), + case NewRecName of + RecordName -> + true; + _OtherName -> + Msg = case get(error_msg_mode) of + normal -> + ["Erroneous record name!"]; + haiku -> + ["The attempt to use", + "An invalid record name", + "Is simply ignored."] + end, + {false, Msg} + end; +new_object_ok(mnesia, _RecordName, _NewTerm) -> + Msg = case get(error_msg_mode) of + normal -> + ["Object is not a record!"]; + haiku -> + ["Yes, it is a term.", + "It is pretty, but it's not", + "The proper record."] + end, + {false, Msg}. + + + + +update_ok(ets, _ObjectToUpdate, _NewObject) -> + true; +update_ok(mnesia, ObjectToUpdate, NewObject) -> + OldRecName = element(1, ObjectToUpdate), + NewRecName = element(1, NewObject), + case NewRecName of + OldRecName -> + true; + _Other -> + false + end. + + + + +handle_toolbar_buttons(Id, Btn, Str, LabelShown, X, Y, ProcVars) -> + WinId = ProcVars#process_variables.window_id, + ToolP = ProcVars#process_variables.toolbar_params, + F = ToolP#toolbar_params.pop_up_frame_id, + + receive + + {gs, Id, motion, _Data, [NewX, NewY | _]} -> + handle_toolbar_buttons(Id, Btn, Str, LabelShown, NewX, NewY, + ProcVars); + + {gs, editentry, keypress, _Data, ['Tab' | _T]} -> + gs:config(editentry, [{select, {0,100000000}}]), + handle_toolbar_buttons(Id, Btn, Str, LabelShown, X, Y, ProcVars); + + {gs, editentry, keypress, _Data, ['Return' | _T]} -> + get_updated_elem(ProcVars), + handle_toolbar_buttons(Id, Btn, Str, LabelShown, X, Y, ProcVars); + + {gs, Id, leave, {toolbar, Btn, Str}, _Arg} -> + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + ProcVars; + + {gs, Id, click, {toolbar, poll_table, _Str}, _Arg} -> + mark_busy(WinId), + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + PcPid = ProcVars#process_variables.master_pid, + PcPid ! #pc_poll_table{sender = self()}, + mark_nonbusy(WinId), + ProcVars; + + {gs, Id, click, {toolbar, select_browser, _Str}, _Arg} -> + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + PcPid = ProcVars#process_variables.master_pid, + PcPid ! #pc_select{sender = self()}, + ProcVars; + + {gs, Id, click, {toolbar, help_button, _Str}, _Arg} -> + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + PcPid = ProcVars#process_variables.master_pid, + PcPid ! #pc_help{sender = self()}, + ProcVars; + + {gs, Id, click, {toolbar, insert_object, _Str}, _Arg} -> + mark_busy(WinId), + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + PcPid = ProcVars#process_variables.master_pid, + PcPid ! {pc_edit_object, self()}, + mark_nonbusy(WinId), + ProcVars; + + + {gs, Id, click, {toolbar, search_object, _Str}, _Arg} -> + mark_busy(WinId), + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + PcPid = ProcVars#process_variables.master_pid, + PcPid ! #pc_search_req{sender = self()}, + mark_nonbusy(WinId), + ProcVars; + + {gs, Id, click, {toolbar, sort_rising_order, _Str}, _Arg} -> + mark_busy(WinId), + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + NewProcVars = + case send_sort_info_signal(true, false, ProcVars) of + ignore -> + ProcVars; + TempNewProcVars -> + set_sort_col(true, TempNewProcVars) + end, + mark_nonbusy(WinId), + NewProcVars; + + {gs, Id, click, {toolbar, sort_falling_order, _Str}, _Arg} -> + mark_busy(WinId), + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + NewProcVars = + case send_sort_info_signal(true, true, ProcVars) of + ignore -> + ProcVars; + TempNewProcVars -> + set_sort_col(true, TempNewProcVars) + end, + mark_nonbusy(WinId), + NewProcVars; + + {gs, Id, click, {toolbar, no_sorting, _Str}, _Arg} -> + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + NewProcVars = + case send_sort_info_signal(false, false, ProcVars) of + ignore -> + ProcVars; + TempNewProcVars -> + set_sort_col(false, TempNewProcVars) + end, + NewProcVars; + + {gs, Id, click, {toolbar, table_info, _Str}, _Arg} -> + gs:config(F, [{y, -30}]), + gs:config(Id, [{motion, false}]), + PcPid = ProcVars#process_variables.master_pid, + PcPid ! #pc_show_table_info{sender = self()}, + ProcVars; + + {'EXIT', Pid, Reason} -> + exit_signals({Pid, Reason}, ProcVars), + handle_toolbar_buttons(Id, Btn, Str, LabelShown, X, Y, ProcVars); + + OtherMsg -> + NewProcVars = tv_messages(OtherMsg, ProcVars), + handle_toolbar_buttons(Id, Btn, Str, LabelShown, X, Y, NewProcVars) + + after 600 -> + case LabelShown of + false -> + FrameP = ProcVars#process_variables.frame_params, + L = ToolP#toolbar_params.pop_up_label_id, + + #frame_params{toolbar_frame_width = TWidth, + toolbar_frame_height = THeight} = FrameP, + + BtnHeight = gs:read(Id, height), + BtnXpos = gs:read(Id, x), + BtnYpos = gs:read(Id, y), + FrameHeight = gs:read(F, height), + FontUsed = gs:read(L, font), + {StringWidth, _H} = gs:read(L, {font_wh, {FontUsed, Str}}), + + Width = StringWidth + 6, + Xpos = BtnXpos + X, + LblXpos = if + Xpos + Width > TWidth -> + Xpos - Width; + true -> + Xpos + end, + % Ypos = BtnYpos + Y + 15, + Ypos = BtnYpos + BtnHeight + 6, + LblYpos = if + Ypos + FrameHeight > THeight -> + Ypos - FrameHeight - 25; + true -> + Ypos + end, + gs:config(L, [{width, Width - 2}, + {label, {text, Str}}]), + gs:config(F, [{width, Width}, + {x, LblXpos}, + {y, LblYpos} + ]); + true -> + done + end, + handle_toolbar_buttons(Id, Btn, Str, true, X, Y, ProcVars) + end. + + + + + + +set_sort_col(SortingOn, ProcVars) -> + #process_variables{pb_pid = PbPid, + mark_params = MarkP} = ProcVars, + + SortCol = case SortingOn of + true -> + MarkP#mark_params.col_no; + false -> + undefined + end, + PbPid ! #pb_set_sort_col{sender = self(), + virtual_col = SortCol + }, + remove_all_marks(SortCol, ProcVars). + + + + + +send_sort_info_signal(Sorting, Reverse, ProcVars) -> + #process_variables{master_pid = PcPid, + mark_params = MarkP} = ProcVars, + + SortColNo = MarkP#mark_params.col_no, + + PcPid ! #pc_set_sorting_mode{sender = self(), + sorting = Sorting, + reverse = Reverse, + sort_key_no = SortColNo + }, + receive + #pc_set_sorting_mode_cfm{sort_key_no = FinalSortColNo} -> + NewMarkP = MarkP#mark_params{col_no = FinalSortColNo}, + ProcVars#process_variables{mark_params = NewMarkP}; + + #pd_ignore{} -> + ignore + + end. + + + + + +show_data(Msg, ProcVars) -> + #pc_data{scale_pos = Pos, + scale_range = Range, + list_range = MaxValue, + elementlist = List, + list_of_keys = KeyList, + max_elem_size = MaxElemSize, + marked_row = MarkedRowData} = Msg, + + ?DISP_FUNC_FILE:display_data(Pos, Range, MaxValue, List, KeyList, MaxElemSize, + MarkedRowData, ProcVars). + + + + + + +handle_list_info(Msg, ProcVars) -> + ListAsStr = Msg#pc_list_info.lists_as_strings, + PgPid = ProcVars#process_variables.pg_pid, + PgPid ! #pg_list_info{sender = self(), + lists_as_strings = ListAsStr}, + ProcVars#process_variables{lists_as_strings = ListAsStr}. + + + + + +handle_col_marked(Msg, ProcVars) -> + #pb_col_marked{col_marked = ColMarked, + virtual_col = VirtualCol} = Msg, + + #process_variables{master_pid = MasterPid, + pg_pid = PgPid, + rec_pid = RecPid, + writable = Writable, + toolbar_params = ToolP, + mark_params = MarkP} = ProcVars, + SortCol = MarkP#mark_params.sort_col_no, + + PgPid ! #pg_remove_marks{sender = self()}, + + case ColMarked of + true -> + PgPid ! #pg_col_marked{sender = self(), + virtual_col = VirtualCol}; + false -> + done + end, + + MasterPid ! #pc_marked_row{sender = self(), + row_no = undefined, + object = undefined, + color = undefined + }, + + ?DISP_FUNC_FILE:update_toolbar_label(notext, ToolP, undefined, undefined, Writable), + send_to_rec_edit(RecPid, insert_mode), + + NewMarkP = + if + ColMarked -> + MarkP#mark_params{col_no = VirtualCol}; + true -> + if + SortCol =:= undefined -> + MarkP; + true -> + MarkP#mark_params{col_no = SortCol} + end + end, + ProcVars#process_variables{mark_params = NewMarkP}. + + + + + + +remove_all_marks(SortCol, ProcVars) -> + #process_variables{master_pid = MasterPid, + pb_pid = PbPid, + pg_pid = PgPid, + toolbar_params = ToolP} = ProcVars, + + PgPid ! #pg_remove_marks{sender = self()}, + PbPid ! #pb_remove_marks{sender = self()}, + MasterPid ! #pc_marked_row{sender = self(), + row_no = undefined, + object = undefined, + color = undefined + }, +%% ?DISP_FUNC_FILE:update_toolbar_label(notext, ToolP, undefined, undefined, Writable), + ?DISP_FUNC_FILE:update_toolbar_editor(ToolP#toolbar_params.editor_id, notext), +%% send_to_rec_edit(RecPid, insert_mode), + ProcVars#process_variables{mark_params = #mark_params{sort_col_no = SortCol, + cell_col_no = undefined, + row_no = undefined, + virtual_row_no = undefined, + marked_object = undefined, + marked_color = undefined} + }. + + + + + + +handle_row_marked(Msg, ProcVars) -> + #pb_row_marked{row_marked = RowMarked, + virtual_row = VirtualRow, + real_row = RealRow} = Msg, + + #process_variables{master_pid = MasterPid, + rec_pid = RecPid, + pg_pid = PgPid, + data_list = DataList, + color_list = ColorList, + writable = Writable, + toolbar_params = ToolP, + mark_params = MarkP} = ProcVars, + + PgPid ! #pg_remove_marks{sender = self()}, + + case RowMarked of + true -> + PgPid ! #pg_row_marked{sender = self(), + virtual_row = VirtualRow}; + false -> + done + end, + + {DataElement, NewMarkP} = + if + RowMarked -> + {MarkedRowOrCol, RowObj} = + ?DISP_FUNC_FILE:get_data_element(row, DataList, RealRow, undefined), + + MarkedRowColor = + case MarkedRowOrCol of + notext -> + undefined; + _OtherObject -> + lists:nth(RealRow, ColorList) + end, + MasterPid ! #pc_marked_row{sender = self(), + row_no = VirtualRow, + object = RowObj, + color = MarkedRowColor + }, + send_to_rec_edit(RecPid, {update_mode,RowObj}), + {MarkedRowOrCol, MarkP#mark_params{virtual_row_no = VirtualRow, + row_no = RealRow, + cell_col_no = undefined, + col_no = undefined, + marked_object = RowObj, + marked_color = MarkedRowColor}}; + true -> + MasterPid ! #pc_marked_row{sender = self(), + row_no = undefined, + object = undefined, + color = undefined + }, + send_to_rec_edit(RecPid, insert_mode), + {notext, MarkP#mark_params{virtual_row_no = undefined, + row_no = undefined, + cell_col_no = undefined, + col_no = undefined, + marked_object = undefined, + marked_color = undefined}} + end, + + ?DISP_FUNC_FILE:update_toolbar_label(DataElement, ToolP, VirtualRow, + undefined, Writable), + ProcVars#process_variables{mark_params = NewMarkP}. + + + + + +handle_cell_marked(Msg, ProcVars) -> + #pg_cell_marked{cell_marked = CellMarked, + virtual_col = VirtualCol, + real_row = RealRow, + virtual_row = VirtualRow} = Msg, + + % We are interested in the real row number, since we only have a sublist + % stored in pd. + ?DISP_FUNC_FILE:marked_cell(CellMarked, VirtualCol, RealRow, VirtualRow, + ProcVars). + + + + +resize_window(Msg, ProcVars) -> + #pd_win_conf{width = NewWindowWidth, + height = NewWindowHeight} = Msg, + + ?DISP_FUNC_FILE:resize_display(NewWindowWidth, NewWindowHeight, ProcVars). + + + + +resize_column(Msg, ProcVars) -> + #pb_new_colwidth{real_col = RealCol, + virtual_col = VirtualCol, + xdiff = Xdiff} = Msg, + + ?DISP_FUNC_FILE:resize_column(RealCol, VirtualCol, Xdiff, ProcVars). + + + + +mark_busy(Id) -> + gs:config(Id, [{cursor, busy}]). + + + + +mark_nonbusy(Id) -> + gs:config(Id, [{cursor, arrow}]). + + + + +send_to_rec_edit(undefined, _Msg) -> + done; +send_to_rec_edit(RecPid, Msg) -> + RecPid ! Msg. + |