diff options
Diffstat (limited to 'lib/debugger/src/dbg_wx_winman.erl')
-rwxr-xr-x | lib/debugger/src/dbg_wx_winman.erl | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/lib/debugger/src/dbg_wx_winman.erl b/lib/debugger/src/dbg_wx_winman.erl new file mode 100755 index 0000000000..1daabe3435 --- /dev/null +++ b/lib/debugger/src/dbg_wx_winman.erl @@ -0,0 +1,175 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-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% +%% + +%% +-module(dbg_wx_winman). +-behaviour(gen_server). + +%% External exports +-export([start/0]). +-export([insert/2, is_started/1, + clear_process/1, + raise/1, + update_windows_menu/2]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +-record(win, {owner, % pid() + title, % string() + win % gsobj() + }). + +-record(state, {wins=[] % [#win{}] + }). + +%%==================================================================== +%% External exports +%%==================================================================== + +%%-------------------------------------------------------------------- +%% start() +%%-------------------------------------------------------------------- +start() -> + gen_server:start({local,?MODULE}, ?MODULE, [], []). + +%%-------------------------------------------------------------------- +%% insert(Title, Win) +%% Title = string() +%% Win = gsobj() +%%-------------------------------------------------------------------- +insert(Title, Win) -> + gen_server:cast(?MODULE, {insert, self(), Title, Win}). + +%%-------------------------------------------------------------------- +%% is_started(Title) -> true | false +%% Title = string() +%%-------------------------------------------------------------------- +is_started(Title) -> + case gen_server:call(?MODULE, {is_started, Title}, infinity) of + {true, Win} -> + raise(Win), + true; + false -> + false + end. + +%%-------------------------------------------------------------------- +%% clear_process(Title) +%% Title = string() +%%-------------------------------------------------------------------- +clear_process(Title) -> + gen_server:cast(?MODULE, {clear_process, Title}). + +%%-------------------------------------------------------------------- +%% raise(Win) +%% Win = gsobj() +%%-------------------------------------------------------------------- +raise(Win) -> + case wxTopLevelWindow:isIconized(Win) of + true -> wxTopLevelWindow:iconize(Win, [{iconize, false}]); + false -> ignore + end, + wxWindow:raise(Win). + +%%-------------------------------------------------------------------- +%% update_windows_menu(Data) +%% Data = {New, Old} +%% New = Old = list() +%%-------------------------------------------------------------------- +update_windows_menu(Win, [MonInfo|Infos]) -> + Menu = get('Windows'), + OldItems = wxMenu:getMenuItems(Menu), + [wxMenu:delete(Menu, Item) || Item <- OldItems], + menuitem(Win, Menu,MonInfo, 700), + wxMenu:appendSeparator(Menu), + wx:foldl(fun(Info,Acc) -> menuitem(Win,Menu,Info,Acc) end, 701, Infos). + +menuitem(Window, Menu, {Title, Win}, Id) -> + wxMenu:append(Menu, Id, Title), + wxWindow:connect(Window, command_menu_selected, + [{id,Id},{userData,{dbg_ui_winman,Win}}]), + Id+1. + + +%%==================================================================== +%% gen_server callbacks +%%==================================================================== + +init([]) -> + process_flag(trap_exit, true), + {ok, #state{}}. + +handle_call({is_started, Title}, _From, State) -> + Reply = case lists:keysearch(Title, #win.title, State#state.wins) of + {value, Win} -> {true, Win#win.win}; + false -> false + end, + {reply, Reply, State}. + +handle_cast({insert, Pid, Title, Win}, State) -> + link(Pid), + Wins = State#state.wins ++ [#win{owner=Pid, title=Title, win=Win}], + inform_all(Wins), + {noreply, State#state{wins=Wins}}; + +handle_cast({clear_process, Title}, State) -> + OldWins = State#state.wins, + Wins = case lists:keysearch(Title, #win.title, OldWins) of + {value, #win{owner=Pid}} -> + Msg = {dbg_ui_winman, destroy}, + Pid ! Msg, + lists:keydelete(Title, #win.title, OldWins); + false -> + OldWins + end, + {noreply, State#state{wins=Wins}}. + +handle_info({'EXIT', Pid, _Reason}, State) -> + [Mon | _Wins] = State#state.wins, + if + Pid==Mon#win.owner -> {stop, normal, State}; + true -> + Wins2 = lists:keydelete(Pid, #win.owner, State#state.wins), + inform_all(Wins2), + {noreply, State#state{wins=Wins2}} + end. + +terminate(_Reason, State) -> + delete_all(State#state.wins), + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + + +%%==================================================================== +%% Internal functions +%%==================================================================== + +inform_all(Wins) -> + Infos = lists:map(fun(#win{title=Title, win=Win}) -> {Title, Win} end, + Wins), + Msg = {dbg_ui_winman, update_windows_menu, Infos}, + lists:foreach(fun(#win{owner=Pid}) -> Pid ! Msg end, Wins). + +delete_all(Wins) -> + Msg = {dbg_ui_winman, destroy}, + lists:foreach(fun(#win{owner=Pid}) -> Pid ! Msg end, Wins). |