aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugger/src/dbg_wx_break_win.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/debugger/src/dbg_wx_break_win.erl')
-rw-r--r--lib/debugger/src/dbg_wx_break_win.erl272
1 files changed, 272 insertions, 0 deletions
diff --git a/lib/debugger/src/dbg_wx_break_win.erl b/lib/debugger/src/dbg_wx_break_win.erl
new file mode 100644
index 0000000000..5dafb0fbe6
--- /dev/null
+++ b/lib/debugger/src/dbg_wx_break_win.erl
@@ -0,0 +1,272 @@
+%%
+%% %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_break_win).
+
+%% External exports
+-export([create_win/5,
+ update_functions/2,
+ handle_event/2]).
+
+-include_lib("wx/include/wx.hrl").
+
+-record(winInfo, {type, % line | conditional | function
+ win, % wxobj()
+ entries, % [{atom|integer, wxobj()}]
+ trigger, % [{wxobj(),enable | disable | delete}]
+ listbox, % wxobj()
+ text, % wxobj()
+ ok, % wxobj()
+ funcs=[] % [[Name, Arity]]
+ }).
+
+%%====================================================================
+%% External exports
+%%====================================================================
+
+%%--------------------------------------------------------------------
+%% create_win(Win, Pos, Type, Mod, Line) -> #winInfo{}
+%% Win = Top level window
+%% Pos = {X, Y}
+%% X = Y = integer()
+%% Type = line | conditional | function
+%% Mod = atom() | ""
+%% Line = integer() | ""
+%%--------------------------------------------------------------------
+
+create_win(Parent, Pos, function, Mod, _Line) ->
+ Win = wxDialog:new(Parent, ?wxID_ANY, "Function Break",
+ [{pos, Pos},
+ {style, ?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER}]),
+ MainS = wxBoxSizer:new(?wxVERTICAL),
+ Label = wxStaticText:new(Win, ?wxID_ANY, "Module:"),
+ Int = int:interpreted(),
+ IntStrs = [atom_to_list(M) || M <- Int],
+ Text = wxComboBox:new(Win, ?wxID_ANY,
+ [{value, dbg_wx_win:to_string(Mod)},
+ {choices, IntStrs}]),
+
+ Expand = [{border, 5}, {flag,?wxLEFT bor ?wxRIGHT bor ?wxEXPAND}],
+ wxSizer:add(MainS, Label, [{border,5},
+ {flag,?wxTOP bor ?wxLEFT bor ?wxRIGHT}]),
+ wxSizer:add(MainS, Text, Expand),
+ FunLabel = wxStaticText:new(Win, ?wxID_ANY, "Function:"),
+ LB = wxListBox:new(Win, ?wxID_ANY, [{size,{-1, 100}},{style,?wxLB_MULTIPLE}]),
+ wxSizer:add(MainS, FunLabel, Expand),
+ wxSizer:add(MainS, LB, [{proportion,1}|Expand]),
+ wxSizer:setMinSize(MainS, 300, 400),
+ OK = wxDialog:createStdDialogButtonSizer(Win, ?wxOK bor ?wxCANCEL),
+ wxSizer:add(MainS, OK, [{border,5},{flag,?wxALL}]),
+ wxDialog:setSizer(Win,MainS),
+ wxSizer:fit(MainS, Win),
+ wxSizer:setSizeHints(MainS,Win),
+ wxComboBox:setFocus(Text),
+ wxDialog:connect(Win, command_button_clicked),
+ wxComboBox:connect(Text, command_text_updated),
+ wxListBox:connect(LB, command_listbox_selected),
+ wxListBox:connect(LB, command_listbox_doubleclicked),
+ OkId = wxDialog:getAffirmativeId(Win),
+ OKButt = wxWindow:findWindowById(OkId, [{parent, Win}]),
+ wxWindow:disable(OKButt),
+ wxDialog:centreOnParent(Win),
+ wxDialog:show(Win),
+
+ #winInfo{type=function, win=Win, text=Text, ok=OKButt,
+ entries=[], trigger=enable,
+ listbox=LB, funcs=[]};
+
+create_win(Parent, Pos, Type, Mod, Line) ->
+ Title = case Type of
+ line -> "Line Break";
+ conditional -> "Conditional Break"
+ end,
+ Style = ?wxDEFAULT_DIALOG_STYLE bor ?wxRESIZE_BORDER,
+ Win = wxDialog:new(Parent, ?wxID_ANY, Title,
+ [{pos, Pos},
+ {style, Style}]),
+ %% Create Sizers
+ MainS = wxBoxSizer:new(?wxVERTICAL),
+
+ %% Add module
+ Int = int:interpreted(),
+ IntStrs = [atom_to_list(M) || M <- Int],
+ ModT = wxComboBox:new(Win, ?wxID_ANY, [{choices,IntStrs}]),
+ ModSz = create_label_of_control(Win, "Module:", ModT, Mod),
+ wxSizer:add(MainS,ModSz,[{flag, ?wxEXPAND}]),
+ %% Create rest of text input fields
+ Add = fun({IType, Label, Def}) ->
+ {Sz, Text} = create_sizer_with_text(Win, Label, Def),
+ wxSizer:add(MainS, Sz, [{flag, ?wxEXPAND}]),
+ {Text, IType}
+ end,
+ Inputs = case Type of
+ line ->
+ [{integer,"Line:",Line}];
+ conditional ->
+ [{integer,"Line:",Line},
+ {atom,"C-Module:",""},
+ {atom,"C-Function:",""}]
+ end,
+ %% Add the rest of the entries
+ Entries = wx:map(Add, Inputs),
+ %% Create and add radio box
+ {TriggerBox,Trigger} = create_trigger_box(Win),
+ wxSizer:add(MainS, TriggerBox, [{border,5},{flag,?wxALL bor ?wxEXPAND}]),
+
+ wxSizer:addStretchSpacer(MainS),
+ %% Put it together
+ OK = wxDialog:createStdDialogButtonSizer(Win, ?wxOK bor ?wxCANCEL),
+ wxSizer:add(MainS, OK, [{border,5},{flag,?wxALL}]),
+ wxSizer:setMinSize(MainS, 300, -1),
+ wxDialog:setSizer(Win,MainS),
+ wxSizer:fit(MainS, Win),
+ wxSizer:setSizeHints(MainS,Win),
+ wxComboBox:setFocus(ModT),
+ wxDialog:connect(Win, command_button_clicked),
+ wxDialog:connect(Win, command_text_updated),
+ OkId = wxDialog:getAffirmativeId(Win),
+ OKButt = wxWindow:findWindowById(OkId),
+ wxWindow:disable(OKButt),
+ wxDialog:centreOnParent(Win),
+ wxDialog:show(Win),
+ #winInfo{type=Type, win=Win, text=ModT,
+ entries=Entries, trigger=Trigger, ok=OKButt}.
+
+%%--------------------------------------------------------------------
+%% update_functions(WinInfo, Funcs) -> WinInfo
+%% WinInfo = #winInfo{}
+%% Funcs = [{Name, Arity}]
+%% Name = atom()
+%% Arity = integer()
+%%--------------------------------------------------------------------
+update_functions(WinInfo, Funcs) ->
+ Items = lists:map(fun([N, A]) ->
+ lists:flatten(io_lib:format("~p/~p", [N,A]))
+ end,
+ Funcs),
+ wxListBox:set(WinInfo#winInfo.listbox, Items),
+ WinInfo#winInfo{funcs=Funcs}.
+
+%%--------------------------------------------------------------------
+%% handle_event(WxEvent, WinInfo) -> Command
+%% WxEvent = #wx{}
+%% WinInfo = #winInfo{}
+%% Command = ignore
+%% | stopped
+%% | {win, WinInfo}
+%% | {module, Mod}
+%% | {break, [[Mod, Line]], Action}
+%% | {break, [[Mod, Line, CMod, CFunc]], Action}
+%% | {break, [[Mod, Func, Arity]], Action}
+%%--------------------------------------------------------------------
+handle_event(#wx{id=?wxID_CANCEL}, #winInfo{win=Win}) ->
+ wxDialog:destroy(Win),
+ stopped;
+handle_event(#wx{event=#wxCommand{type=command_text_updated}},
+ #winInfo{type=function, text=Text, ok=Ok}) ->
+ Module = wxComboBox:getValue(Text),
+ wxWindow:disable(Ok),
+ {module, list_to_atom(Module)};
+handle_event(#wx{event=#wxCommand{type=command_text_updated}},
+ #winInfo{text=Text, ok=Ok, entries=Es}) ->
+ Module = wxComboBox:getValue(Text),
+ case check_input(Es) of
+ error -> wxWindow:disable(Ok);
+ _Data when Module =/= "" -> wxWindow:enable(Ok);
+ _ -> wxWindow:disable(Ok)
+ end,
+ ignore;
+handle_event(#wx{event=#wxCommand{type=command_listbox_selected}},
+ #winInfo{type=function, listbox=LB, ok=Ok}) ->
+ case wxListBox:getSelections(LB) of
+ {N,_} when N > 0 -> wxWindow:enable(Ok);
+ _ -> wxWindow:disable(Ok)
+ end,
+ ignore;
+handle_event(#wx{id=OKorListBox, event=#wxCommand{type=OkorDoubleClick}},
+ #winInfo{type=function,win=Win,listbox=LB,funcs=Funcs,text=Text})
+ when OKorListBox =:= ?wxID_OK;
+ OkorDoubleClick =:= command_listbox_doubleclicked ->
+ Mod = wxComboBox:getValue(Text),
+ {_, IndexL} = wxListBox:getSelections(LB),
+ Breaks = lists:map(fun(Index) ->
+ Func = lists:nth(Index+1, Funcs),
+ [list_to_atom(Mod) | Func]
+ end,
+ IndexL),
+ wxDialog:destroy(Win),
+ {break, Breaks, enable};
+handle_event(#wx{id=?wxID_OK},#winInfo{win=Win,text=Text, entries=Es, trigger=Trigger}) ->
+ %% Non function box
+ Mod = wxComboBox:getValue(Text),
+ Data = check_input(Es),
+ Trigged = get_trigger(Trigger),
+ wxDialog:destroy(Win),
+ {break, [[list_to_atom(Mod)|Data]], Trigged};
+
+handle_event(_WxEvent, _WinInfo) ->
+ %% io:format("Ev: ~p ~n", [_WxEvent]),
+ ignore.
+
+check_input(Entries) ->
+ check_input(Entries, []).
+check_input([{Entry, Type} | Entries], Data) ->
+ Str = wxTextCtrl:getValue(Entry),
+ case erl_scan:string(Str) of
+ {ok, [{Type, _Line, Val}], _EndLine} ->
+ check_input(Entries, [Val|Data]);
+ _Error -> error
+ end;
+check_input([], Data) -> lists:reverse(Data).
+
+create_sizer_with_text(Parent,Label,Def) ->
+ Text = wxTextCtrl:new(Parent, ?wxID_ANY),
+ Sz = create_label_of_control(Parent, Label, Text, Def),
+ {Sz, Text}.
+
+create_label_of_control(Parent, Label, Control, Def) ->
+ Sizer = wxBoxSizer:new(?wxHORIZONTAL),
+ Text = wxStaticText:new(Parent, ?wxID_ANY, Label),
+ Border = {border, 5},
+ Flag = ?wxRIGHT bor ?wxLEFT bor ?wxALIGN_CENTRE_VERTICAL,
+ wxSizer:add(Sizer, Text, [{proportion,1}, {flag,Flag}, Border]),
+ wxSizer:add(Sizer, Control, [{proportion,3}, {flag,Flag bor ?wxEXPAND}, Border]),
+ wxControl:setLabel(Control, dbg_wx_win:to_string(Def)),
+ Sizer.
+
+create_trigger_box(Win) ->
+ SBox = wxStaticBox:new(Win, ?wxID_ANY, "Trigger Action:"),
+ SBS = wxStaticBoxSizer:new(SBox, ?wxVERTICAL),
+ Ebtn = wxRadioButton:new(Win, ?wxID_ANY, "Enable"),
+ wxSizer:add(SBS,Ebtn),
+ Dibtn = wxRadioButton:new(Win, ?wxID_ANY, "Disable"),
+ wxSizer:add(SBS,Dibtn),
+ Debtn = wxRadioButton:new(Win, ?wxID_ANY, "Delete"),
+ wxSizer:add(SBS,Debtn),
+ wxRadioButton:setValue(Ebtn, true),
+ {SBS, [{Ebtn,enable},{Dibtn,disable},{Debtn,delete}]}.
+
+get_trigger([{Btn,Op}|R]) ->
+ case wxRadioButton:getValue(Btn) of
+ true -> Op;
+ false -> get_trigger(R)
+ end.
+
+