aboutsummaryrefslogtreecommitdiffstats
path: root/lib/observer/src/observer_wx.erl
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2011-10-07 15:35:16 +0200
committerDan Gudmundsson <[email protected]>2011-11-10 08:04:51 +0100
commit87487a2534d3e790f65ac5b90cfc497d7d05dd86 (patch)
tree1b2436625a57fbd41630a14d6565beec194d3c6a /lib/observer/src/observer_wx.erl
parentffcacd111c61019a502a895b1edcfbc1578ddfa7 (diff)
downloadotp-87487a2534d3e790f65ac5b90cfc497d7d05dd86.tar.gz
otp-87487a2534d3e790f65ac5b90cfc497d7d05dd86.tar.bz2
otp-87487a2534d3e790f65ac5b90cfc497d7d05dd86.zip
[observer] Misc cleanup and fixes
Make sure that the menus work on MacOsX. Fix asserts on debug build on linux. Make sure epmd is started before distribution. Rewrote multi-selection code observer_pro_wx.
Diffstat (limited to 'lib/observer/src/observer_wx.erl')
-rw-r--r--lib/observer/src/observer_wx.erl180
1 files changed, 88 insertions, 92 deletions
diff --git a/lib/observer/src/observer_wx.erl b/lib/observer/src/observer_wx.erl
index ef3c6bb304..4688e271ee 100644
--- a/lib/observer/src/observer_wx.erl
+++ b/lib/observer/src/observer_wx.erl
@@ -20,7 +20,7 @@
-behaviour(wx_object).
-export([start/0]).
--export([create_menus/2, create_menu/2, create_txt_dialog/4, try_rpc/4,
+-export([create_menus/2, create_txt_dialog/4, try_rpc/4,
return_to_localnode/2]).
-export([init/1, handle_event/2, handle_cast/2, terminate/2, code_change/3,
@@ -44,6 +44,7 @@
-record(state,
{frame,
menubar,
+ menus = [],
status_bar,
notebook,
main_panel,
@@ -86,7 +87,7 @@ setup(#state{frame = Frame} = State) ->
{Nodes, NodeMenus} = get_nodes(),
DefMenus = default_menus(NodeMenus),
- create_menu(DefMenus, MenuBar),
+ observer_lib:create_menus(DefMenus, MenuBar, default),
wxFrame:setMenuBar(Frame, MenuBar),
StatusBar = wxFrame:createStatusBar(Frame, []),
@@ -115,9 +116,9 @@ setup(#state{frame = Frame} = State) ->
wxSizer:add(MainSizer, Notebook, [{proportion, 1}, {flag, ?wxEXPAND}]),
wxPanel:setSizer(Panel, MainSizer),
- wxNotebook:connect(Notebook, command_notebook_page_changed),
+ wxNotebook:connect(Notebook, command_notebook_page_changing),
wxFrame:connect(Frame, close_window, [{skip, true}]),
- wxMenu:connect(Frame, command_menu_selected, [{skip, true}]),
+ wxMenu:connect(Frame, command_menu_selected),
SysPid = wx_object:get_pid(SysPanel),
SysPid ! {active, node()},
@@ -139,9 +140,9 @@ setup(#state{frame = Frame} = State) ->
%%Callbacks
handle_event(#wx{obj = Notebook, id = ?ID_NOTEBOOK,
- event = #wxNotebook{type = command_notebook_page_changed}},
+ event = Ev = #wxNotebook{type = command_notebook_page_changing}},
#state{active_tab=Previous, node=Node, notebook = Notebook} = State) ->
- io:format("Command notebook changed ~n"),
+ io:format("Command notebook changed ~p ~n", [Ev]),
Pid = get_active_pid(State),
Previous ! not_active,
Pid ! {active, Node},
@@ -151,13 +152,22 @@ handle_event(#wx{event = #wxClose{}}, State) ->
{stop, normal, State};
handle_event(#wx{id = ?wxID_EXIT, event = #wxCommand{type = command_menu_selected}}, State) ->
- io:format("~p ~p, you clicked close", [?MODULE, ?LINE]),
{stop, normal, State};
handle_event(#wx{id = ?wxID_HELP, event = #wxCommand{type = command_menu_selected}}, State) ->
io:format("~p ~p, you clicked help", [?MODULE, ?LINE]),
{noreply, State};
+handle_event(#wx{id = ?wxID_ABOUT, event = #wxCommand{type = command_menu_selected}},
+ State = #state{frame=Frame}) ->
+ AboutString = "Observe an erlang system\n"
+ "Authors: Olle Mattson & Magnus Eriksson & Dan Gudmundsson",
+ Style = [{style, ?wxOK bor ?wxSTAY_ON_TOP},
+ {caption, "About"}],
+ wxMessageDialog:showModal(wxMessageDialog:new(Frame, AboutString, Style)),
+ {noreply, State};
+
+
handle_event(#wx{id = ?ID_CONNECT, event = #wxCommand{type = command_menu_selected}},
#state{frame = Frame} = State) ->
UpdState = case create_connect_dialog(connect, State) of
@@ -192,11 +202,9 @@ handle_event(#wx{id = ?ID_CONNECT, event = #wxCommand{type = command_menu_select
handle_event(#wx{id = ?ID_PING, event = #wxCommand{type = command_menu_selected}},
#state{frame = Frame} = State) ->
UpdState = case create_connect_dialog(ping, State) of
- cancel ->
- State;
+ cancel -> State;
{value, Value} when is_list(Value) ->
try
-
Node = list_to_atom(Value),
case net_adm:ping(Node) of
pang ->
@@ -205,7 +213,6 @@ handle_event(#wx{id = ?ID_PING, event = #wxCommand{type = command_menu_selected}
pong ->
change_node_view(Node, State)
end
-
catch _:_ ->
create_txt_dialog(Frame, "Connect failed", "Pang", ?wxICON_EXCLAMATION),
State
@@ -229,15 +236,13 @@ handle_cast(Cast, State) ->
io:format("~p:~p: Got cast ~p~n", [?MODULE, ?LINE, Cast]),
{noreply, State}.
-handle_call({create_menus, TabMenus}, _From, State = #state{menubar=MenuBar}) ->
+handle_call({create_menus, TabMenus}, _From,
+ State = #state{menubar=MenuBar, menus=PrevTabMenus}) ->
wx:batch(fun() ->
- {_Nodes, NodeMenus} = get_nodes(),
- DefMenus = default_menus(NodeMenus),
- Menus = merge_menus(DefMenus, TabMenus),
- clean_menus(MenuBar),
- create_menu(Menus, MenuBar)
+ clean_menus(PrevTabMenus, MenuBar),
+ observer_lib:create_menus(TabMenus, MenuBar, plugin)
end),
- {reply, ok, State};
+ {reply, ok, State#state{menus=TabMenus}};
handle_call(Msg, _From, State) ->
io:format("~p~p: Got Call ~p~n",[?MODULE, ?LINE, Msg]),
@@ -308,6 +313,13 @@ connect(NodeName, 1, Cookie) ->
connect2(NodeName, longnames, Cookie).
connect2(NodeName, Opts, Cookie) ->
+ case net_adm:names() of
+ {ok, _} -> %% Epmd is running
+ ok;
+ {error, address} ->
+ Epmd = os:find_executable("epmd"),
+ os:cmd(Epmd)
+ end,
case net_kernel:start([NodeName, Opts]) of
{ok, _} ->
case is_alive() of
@@ -367,10 +379,11 @@ create_connect_dialog(connect, #state{frame = Frame}) ->
{style, ?wxHORIZONTAL}]),
NameText = wxStaticText:new(Dialog, ?wxID_ANY, "Node name: "),
- NameCtrl = wxTextCtrl:new(Dialog, ?wxID_ANY, [{size, {200, 25}}, {style, ?wxDEFAULT}]),
+ NameCtrl = wxTextCtrl:new(Dialog, ?wxID_ANY, [{size, {200, 25}}]),
wxTextCtrl:setValue(NameCtrl, "observer"),
CookieText = wxStaticText:new(Dialog, ?wxID_ANY, "Secret cookie: "),
- CookieCtrl = wxTextCtrl:new(Dialog, ?wxID_ANY, [{size, {200, 25}}, {style, ?wxDEFAULT}]),
+ CookieCtrl = wxTextCtrl:new(Dialog, ?wxID_ANY,
+ [{size, {200, 25}}, {style, ?wxTE_PASSWORD}]),
BtnSizer = wxDialog:createStdDialogButtonSizer(Dialog, ?wxID_DEFAULT),
Flags = [{flag, ?wxEXPAND bor ?wxALL}, {border, 5}],
@@ -390,13 +403,8 @@ create_connect_dialog(connect, #state{frame = Frame}) ->
CookiePath = filename:join(os:getenv("HOME"), ".erlang.cookie"),
DefaultCookie = case filelib:is_file(CookiePath) of
true ->
- {ok, IoDevice} = file:open(CookiePath, read),
- case file:read_line(IoDevice) of
- {ok, Cookie} ->
- Cookie;
- _ ->
- ""
- end;
+ {ok, Bin} = file:read_file(CookiePath),
+ binary_to_list(Bin);
false ->
""
end,
@@ -414,66 +422,57 @@ create_connect_dialog(connect, #state{frame = Frame}) ->
end.
default_menus(NodesMenuItems) ->
- FileMenu = {"File", [#create_menu{id = ?wxID_EXIT, text = "Quit"}]},
- HelpMenu = {"Help", [#create_menu{id = ?wxID_HELP, text = "Help"}]},
+ Quit = #create_menu{id = ?wxID_EXIT, text = "Quit"},
+ About = #create_menu{id = ?wxID_ABOUT, text = "About"},
+ Help = #create_menu{id = ?wxID_HELP},
NodeMenu = case erlang:is_alive() of
- true ->
- {"Nodes", NodesMenuItems ++
- [#create_menu{id = ?ID_PING, text = "Connect Node"}]};
- false ->
- {"Nodes", NodesMenuItems ++
- [#create_menu{id = ?ID_CONNECT, text = "Enable distribution"}]}
+ true -> {"Nodes", NodesMenuItems ++
+ [#create_menu{id = ?ID_PING, text = "Connect Node"}]};
+ false -> {"Nodes", NodesMenuItems ++
+ [#create_menu{id = ?ID_CONNECT, text = "Enable distribution"}]}
end,
- [FileMenu, NodeMenu, HelpMenu].
+ case os:type() =:= {unix, darwin} of
+ false ->
+ FileMenu = {"File", [Quit]},
+ HelpMenu = {"Help", [About,Help]},
+ [FileMenu, NodeMenu, HelpMenu];
+ true ->
+ %% On Mac quit and about will be moved to the "default' place
+ %% automagicly, so just add them to a menu that always exist.
+ %% But not to the help menu for some reason
+ {Tag, Menus} = NodeMenu,
+ [{Tag, Menus ++ [Quit,About]}, {"&Help", [Help]}]
+ end.
-clean_menus(MenuBar) ->
- Count = wxMenuBar:getMenuCount(MenuBar),
- remove_menu_item(MenuBar, Count).
+clean_menus(Menus, MenuBar) ->
+ remove_menu_items(Menus, MenuBar).
-remove_menu_item(MenuBar, Item) when Item > -1 ->
- Menu = wxMenuBar:getMenu(MenuBar, Item),
- wxMenuBar:remove(MenuBar, Item),
+remove_menu_items([{MenuStr = "File", Menus}|Rest], MenuBar) ->
+ MenuId = wxMenuBar:findMenu(MenuBar, MenuStr),
+ Menu = wxMenuBar:getMenu(MenuBar, MenuId),
+ Items = [wxMenu:findItem(Menu, Tag) || #create_menu{text=Tag} <- Menus],
+ [wxMenu:delete(Menu, MItem) || MItem <- Items],
+ case os:type() =:= {unix, darwin} of
+ true ->
+ wxMenuBar:remove(MenuBar, MenuId),
+ wxMenu:destroy(Menu);
+ false ->
+ ignore
+ end,
+ remove_menu_items(Rest, MenuBar);
+remove_menu_items([{"Nodes", _}|_], _MB) ->
+ ok;
+remove_menu_items([{Tag, _Menus}|Rest], MenuBar) ->
+ MenuId = wxMenuBar:findMenu(MenuBar, Tag),
+ Menu = wxMenuBar:getMenu(MenuBar, MenuId),
+ wxMenuBar:remove(MenuBar, MenuId),
+ Items = wxMenu:getMenuItems(Menu),
+ [wxMenu:'Destroy'(Menu, Item) || Item <- Items],
wxMenu:destroy(Menu),
- remove_menu_item(MenuBar, Item-1);
-remove_menu_item(_, _) ->
- ok.
-
-merge_menus([{Label, Items}|Default], [{Label, TabItems}|TabMenus]) ->
- [{Label, TabItems ++ Items} | merge_menus(Default, TabMenus)];
-merge_menus([Menu = {"File", _}|Default], TabMenus) ->
- [Menu | merge_menus(Default, TabMenus)];
-merge_menus(Default = [{"Nodes", _}|_], TabMenus) ->
- TabMenus ++ Default.
-
-create_menu(Menus, MenuBar) ->
- Add = fun({Name, MenuItems}) ->
- Menu = wxMenu:new(),
- lists:foreach(fun(Record) ->
- create_menu_item(Record, Menu)
- end,
- MenuItems),
- wxMenuBar:append(MenuBar, Menu, Name)
- end,
- wx:foreach(Add, Menus),
+ remove_menu_items(Rest, MenuBar);
+remove_menu_items([], _MB) ->
ok.
-create_menu_item(#create_menu{id = Id, text = Text, type = Type, check = Check}, Menu) ->
- case Type of
- append ->
- wxMenu:append(Menu, Id, Text);
- check ->
- wxMenu:appendCheckItem(Menu, Id, Text),
- wxMenu:check(Menu, Id, Check);
- radio ->
- wxMenu:appendRadioItem(Menu, Id, Text),
- wxMenu:check(Menu, Id, Check);
- separator ->
- wxMenu:appendSeparator(Menu)
- end;
-create_menu_item(separator, Menu) ->
- wxMenu:appendSeparator(Menu).
-
-
get_nodes() ->
Nodes = [node()| nodes()],
{_, Menues} =
@@ -489,19 +488,16 @@ update_node_list(State = #state{menubar=MenuBar}) ->
{Nodes, NodesMenuItems} = get_nodes(),
NodeMenuId = wxMenuBar:findMenu(MenuBar, "Nodes"),
NodeMenu = wxMenuBar:getMenu(MenuBar, NodeMenuId),
- wx:foreach(fun(Item) ->
- wxMenu:'Destroy'(NodeMenu, Item)
- end,
+ wx:foreach(fun(Item) -> wxMenu:'Destroy'(NodeMenu, Item) end,
wxMenu:getMenuItems(NodeMenu)),
- wx:foreach(fun(Record) ->
- create_menu_item(Record, NodeMenu)
- end, NodesMenuItems),
+ Index = wx:foldl(fun(Record, Index) ->
+ observer_lib:create_menu_item(Record, NodeMenu, Index)
+ end, 0, NodesMenuItems),
- case erlang:is_alive() of
- true ->
- create_menu_item(#create_menu{id = ?ID_PING, text = "Connect node"}, NodeMenu);
- false ->
- create_menu_item(#create_menu{id = ?ID_CONNECT, text = "Enable distribution"}, NodeMenu)
- end,
+ Dist = case erlang:is_alive() of
+ true -> #create_menu{id = ?ID_PING, text = "Connect node"};
+ false -> #create_menu{id = ?ID_CONNECT, text = "Enable distribution"}
+ end,
+ observer_lib:create_menu_item(Dist, NodeMenu, Index),
State#state{nodes = Nodes}.