diff --git a/src/:w b/src/:w deleted file mode 100644 index 5e1a02e..0000000 --- a/src/:w +++ /dev/null @@ -1,527 +0,0 @@ --module(gd_v_wallman). --vsn("0.6.6"). --author("Craig Everett "). --copyright("QPQ AG "). --license("GPL-3.0-or-later"). - --behavior(wx_object). -%-behavior(gd_v). --include_lib("wx/include/wx.hrl"). --export([to_front/1]). --export([show/2]). --export([start_link/1]). --export([init/1, terminate/2, code_change/3, - handle_call/3, handle_cast/2, handle_info/2, handle_event/2]). --include("$zx_include/zx_logger.hrl"). --include("gd.hrl"). - - --record(w, - {name = none :: atom(), - id = 0 :: integer(), - wx = none :: none | wx:wx_object()}). - --record(s, - {wx = none :: none | wx:wx_object(), - frame = none :: none | wx:wx_object(), - lang = en :: en | jp, - j = none :: none | fun(), - prefs = #{} :: map(), - wallets = [] :: [#wr{}], - picker = none :: none | wx:wx_object(), - buttons = [] :: [#w{}], - wiz = none :: none | {wx:wx_object(), Buttons :: [#w{}]}). - - -%%% Interface - --spec to_front(Win) -> ok - when Win :: wx:wx_object(). - -to_front(Win) -> - wx_object:cast(Win, to_front). - - --spec show(Win, Manifest) -> ok - when Win :: wx:xw_object(), - Manifest :: [#wr{}]. - -show(Win, Manifest) -> - wx_object:cast(Win, {show, Manifest}). - - -%%% Startup - -start_link(Args) -> - wx_object:start_link({local, ?MODULE}, ?MODULE, Args, []). - - -init({Prefs, Manifest}) -> - Lang = maps:get(lang, Prefs, en_us), - Trans = gd_jt:read_translations(?MODULE), - J = gd_jt:j(Lang, Trans), - Wx = wx:new(), - Frame = wxFrame:new(Wx, ?wxID_ANY, J("Wallets")), - - MainSz = wxBoxSizer:new(?wxVERTICAL), - - Picker = wxListBox:new(Frame, ?wxID_ANY, [{style, ?wxLC_SINGLE_SEL}]), - Names = [Name || #wr{name = Name} <- Manifest], - ok = wxListBox:set(Picker, Names), - - ButtSz = wxBoxSizer:new(?wxHORIZONTAL), - ButtonTemplates = - [{open, J("Open")}, - {new, J("New")}, - {move, J("Move")}, - {import, J("Import")}, - {drop, J("Drop")}], - MakeButton = - fun({Name, Label}) -> - B = wxButton:new(Frame, ?wxID_ANY, [{label, Label}]), - _ = wxSizer:add(ButtSz, B, zxw:flags(wide)), - #w{name = Name, id = wxButton:getId(B), wx = B} - end, - Buttons = lists:map(MakeButton, ButtonTemplates), - - _ = wxSizer:add(MainSz, Picker, zxw:flags(wide)), - _ = wxSizer:add(MainSz, ButtSz, zxw:flags(base)), - - ok = wxFrame:setSizer(Frame, MainSz), - ok = wxSizer:layout(MainSz), - - NewPrefs = - case maps:is_key(geometry, Prefs) of - true -> - Prefs; - false -> - Display = wxDisplay:new(), - {_, _, W, H} = wxDisplay:getGeometry(Display), - ok = wxDisplay:destroy(Display), - WW = 500, - WH = 350, - X = (W div 2) - (WW div 2), - Y = (H div 2) - (WH div 2), - Prefs#{geometry => {X, Y, WW, WH}} - end, - ok = gd_v:safe_size(Frame, NewPrefs), - - ok = wxFrame:connect(Frame, command_button_clicked), - ok = wxFrame:connect(Frame, close_window), - ok = wxListBox:connect(Picker, command_listbox_doubleclicked), - Count = length(Manifest) - ok = - if - Count =:= 0 -> - self() ! wiz, - ok; - Count =:= 1 -> - self() ! open_only, - ok; - Count > 1 -> - true = wxFrame:show(Frame), - ok - end, - State = #s{wx = Wx, frame = Frame, lang = Lang, j = J, prefs = Prefs, - wallets = Manifest, - picker = Picker, - buttons = Buttons}, - {Frame, State}. - - - -%%% wx_object - -handle_call(Unexpected, From, State) -> - ok = log(warning, "Unexpected call from ~tp: ~tp~n", [From, Unexpected]), - {noreply, State}. - - -handle_cast(to_front, State = #s{frame = Frame}) -> - ok = wxFrame:raise(Frame), - {noreply, State}; -handle_cast({show, Manifest}, State) -> - NewState = do_show(Manifest, State), - {noreply, NewState}; -handle_cast(Unexpected, State) -> - ok = log(warning, "Unexpected cast: ~tp~n", [Unexpected]), - {noreply, State}. - - -handle_info(wiz, State) -> - NewState = do_wiz(State), - {noreply, NewState}; -handle_info(open_only, State) -> - NewState = do_open_only(State), - {noreply, NewState}; -handle_info(Unexpected, State) -> - ok = log(warning, "Unexpected info: ~tp~n", [Unexpected]), - {noreply, State}. - - -handle_event(#wx{event = #wxCommand{type = command_button_clicked}, - id = ID}, - State = #s{buttons = Buttons}) -> - NewState = - case lists:keyfind(ID, #w.id, Buttons) of - #w{name = open} -> do_open(State); - #w{name = new} -> do_new(State); - #w{name = import} -> do_import(State); - #w{name = drop} -> do_drop(State); - #w{name = Name} -> handle_button(Name, State); - false -> State - end, - {noreply, NewState}; -handle_event(#wx{event = #wxCommand{type = command_listbox_doubleclicked, - commandInt = Selected}}, - State) -> - NewState = do_open2(Selected + 1, State), - {noreply, NewState}; -handle_event(#wx{event = #wxClose{}}, State) -> - ok = do_close(State), - {noreply, State}; -handle_event(Event, State) -> - ok = tell(info, "Unexpected event ~tp State: ~tp~n", [Event, State]), - {noreply, State}. - - -code_change(_, State, _) -> - {ok, State}. - - -terminate(wx_deleted, _) -> - wx:destroy(); -terminate(Reason, State) -> - ok = log(info, "Reason: ~tp, State: ~tp", [Reason, State]), - wx:destroy(). - - - -%%% doers - -do_show(Manifest, State = #s{picker = Picker}) -> - Names = [Name || #wr{name = Name} <- Manifest], - ok = wxListBox:set(Picker, Names), - State#s{wallets = Manifest}. - - -do_close(#s{frame = Frame, prefs = Prefs}) -> - Geometry = - case wxTopLevelWindow:isMaximized(Frame) of - true -> - max; - false -> - {X, Y} = wxWindow:getPosition(Frame), - {W, H} = wxWindow:getSize(Frame), - {X, Y, W, H} - end, - NewPrefs = maps:put(geometry, Geometry, Prefs), - ok = gd_con:save(?MODULE, NewPrefs), - ok = wxWindow:destroy(Frame). - - -handle_button(Name, State) -> - ok = tell("Button Click: ~p", [Name]), - State. - - -do_open(State = #s{wallets = []}) -> - State; -do_open(State = #s{picker = Picker}) -> - case wxListBox:getSelection(Picker) of - -1 -> State; - Selected -> do_open2(Selected + 1, State) - end. - -do_open2(Selected, State = #s{wallets = Wallets}) -> - case lists:nth(Selected, Wallets) of - #wr{pass = true, path = Path} -> - do_open3(Path, State); - #wr{pass = false, path = Path} -> - ok = gd_con:open_wallet(Path, none), - ok = do_close(State), - State - end. - -do_open3(Path, State = #s{frame = Frame, j = J}) -> - Label = J("Password"), - Dialog = wxDialog:new(Frame, ?wxID_ANY, Label), - Sizer = wxBoxSizer:new(?wxVERTICAL), - PassSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, Label}]), - PassTx = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]), - _ = wxStaticBoxSizer:add(PassSz, PassTx, zxw:flags(wide)), - ButtSz = wxBoxSizer:new(?wxHORIZONTAL), - Affirm = wxButton:new(Dialog, ?wxID_OK), - _ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)), - _ = wxBoxSizer:add(Sizer, PassSz, zxw:flags(base)), - _ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(wide)), - ok = wxDialog:setSizer(Dialog, Sizer), - ok = wxBoxSizer:layout(Sizer), - ok = wxDialog:setSize(Dialog, {500, 130}), - ok = wxFrame:center(Dialog), - ok = wxStyledTextCtrl:setFocus(PassTx), - case wxDialog:showModal(Dialog) of - ?wxID_OK -> - case wxTextCtrl:getValue(PassTx) of - "" -> - ok = wxDialog:destroy(Dialog), - State; - Phrase -> - ok = wxDialog:destroy(Dialog), - ok = gd_con:open_wallet(Path, Phrase), - ok = do_close(State), - State - end; - ?wxID_CANCEL -> - ok = wxDialog:destroy(Dialog), - State - end. - - -do_wiz(State = #s{wx = WX, lang = Lang, wiz = none}) -> - Trans = gd_jt:read_translations(?MODULE), - J = gd_jt:j(Lang, Trans), - - Frame = wxFrame:new(WX, ?wxID_ANY, J("Initializing Wallet")), - MainSz = wxBoxSizer:new(?wxVERTICAL), - - ButtonTemplates = - [{noob, J("Create a default wallet with a new account for me.")}, - {l33t, J("I know what I'm doing.\nJust show me the wallet manager.")}], - - MakeButton = - fun({Name, Label}) -> - B = wxButton:new(Frame, ?wxID_ANY, [{label, Label}]), - #w{name = Name, id = wxButton:getId(B), wx = B} - end, - - Buttons = lists:map(MakeButton, ButtonTemplates), - - Add = fun(#w{wx = Button}) -> wxBoxSizer:add(MainSz, Button, zxw:flags(wide)) end, - ok = lists:foreach(Add, Buttons), - - ok = wxFrame:setSizer(Frame, MainSz), - ok = wxSizer:layout(MainSz), - - ok = wxFrame:connect(Frame, command_button_clicked), - ok = wxFrame:connect(Frame, close_window), - ok = wxFrame:setSize(Frame, {300, 300}), - ok = wxFrame:center(Frame), - true = wxFrame:show(Frame), - State#s{wiz = {Frame, Buttons}}. - - -do_new(State = #s{frame = Frame, j = J, prefs = Prefs}) -> - DefaultDir = maps:get(dir, Prefs, zx_lib:path(var, "otpr", "gajudesk")), - Options = - [{message, J("Save Location")}, - {defaultDir, DefaultDir}, - {defaultFile, "default.gaju"}, - {wildCard, "*.gaju"}, - {sz, {300, 270}}, - {style, ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT}], - Dialog = wxFileDialog:new(Frame, Options), - case wxFileDialog:showModal(Dialog) of - ?wxID_OK -> - Dir = wxFileDialog:getDirectory(Dialog), - File = wxFileDialog:getFilename(Dialog), - Path = filename:join(Dir, File), - ok = wxFileDialog:destroy(Dialog), - case do_new2(Path, J, Frame) of - ok -> - NewPrefs = maps:put(dir, Dir, Prefs), - do_close(State#s{prefs = NewPrefs}); - abort -> - State - end; - ?wxID_CANCEL -> - ok = wxFileDialog:destroy(Dialog), - State - end. - -do_new2(Path, J, Frame) -> - Dialog = wxDialog:new(Frame, ?wxID_ANY, J("New Wallet"), [{size, {400, 250}}]), - Sizer = wxBoxSizer:new(?wxVERTICAL), - - Network = wxRadioBox:new(Dialog, ?wxID_ANY, J("Network"), {0, 0}, {50, 50}, [J("Mainnet"), J("Testnet")]), - NameSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Name")}]), - NameTx = wxTextCtrl:new(Dialog, ?wxID_ANY), - _ = wxSizer:add(NameSz, NameTx, zxw:flags(wide)), - Label1 = J("Passphrase (optional)"), - PassSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, Label1}]), - PassTx = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]), - _ = wxSizer:add(PassSz, PassTx, zxw:flags(wide)), - Label2= J("Passphrase Confirmation"), - PassConSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, Label2}]), - PassConTx = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]), - _ = wxSizer:add(PassConSz, PassConTx, zxw:flags(wide)), - - ButtSz = wxBoxSizer:new(?wxHORIZONTAL), - Affirm = wxButton:new(Dialog, ?wxID_OK), - Cancel = wxButton:new(Dialog, ?wxID_CANCEL), - _ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)), - _ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)), - - _ = wxBoxSizer:add(Sizer, Network, zxw:flags(base)), - _ = wxSizer:add(Sizer, NameSz, zxw:flags(base)), - _ = wxSizer:add(Sizer, PassSz, zxw:flags(base)), - _ = wxSizer:add(Sizer, PassConSz, zxw:flags(base)), - _ = wxSizer:add(Sizer, ButtSz, zxw:flags(wide)), - - ok = wxDialog:setSizer(Dialog, Sizer), - ok = wxDialog:setSize(Dialog, {300, 270}), - ok = wxBoxSizer:layout(Sizer), - ok = wxDialog:center(Dialog), - ok = wxStyledTextCtrl:setFocus(NameTx), - - Result = - case wxDialog:showModal(Dialog) of - ?wxID_OK -> - Net = - case wxRadioBox:getSelection(Network) of - 0 -> mainnet; - 1 -> testnet; - _ -> mainnet - end, - Name = - case wxTextCtrl:getValue(NameTx) of - "" -> Path; - N -> N - end, - Pass = - case {wxTextCtrl:getValue(PassTx), wxTextCtrl:getValue(PassConTx)} of - {"", ""} -> none; - {P, P} -> P; - {_, _} -> bad - end, - do_new3(Net, Name, Path, Pass); - ?wxID_CANCEL -> - abort - end, - ok = wxDialog:destroy(Dialog), - Result. - -do_new3(_, _, _, bad) -> - abort; -do_new3(Net, Name, Path, Pass) -> - gd_con:new_wallet(Net, Name, Path, Pass). - - -do_import(State = #s{frame = Frame, j = J, prefs = Prefs}) -> - DefaultDir = maps:get(dir, Prefs, zx_lib:path(var, "otpr", "gajudesk")), - Options = - [{message, J("Select Wallet File")}, - {defaultDir, DefaultDir}, - {wildCard, "*.gaju"}, - {style, ?wxFD_OPEN}], - Dialog = wxFileDialog:new(Frame, Options), - case wxFileDialog:showModal(Dialog) of - ?wxID_OK -> - Dir = wxFileDialog:getDirectory(Dialog), - File = wxFileDialog:getFilename(Dialog), - ok = wxFileDialog:destroy(Dialog), - case do_import2(Dir, File, J, Frame) of - ok -> - NewPrefs = maps:put(dir, Dir, Prefs), - do_close(State#s{prefs = NewPrefs}); - abort -> - State - end; - ?wxID_CANCEL -> - ok = wxFileDialog:destroy(Dialog), - State - end. - -do_import2(_, "", _, _) -> - abort; -do_import2(Dir, File, J, Frame) -> - Path = filename:join(Dir, File), - Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Import Wallet")), - Sizer = wxBoxSizer:new(?wxVERTICAL), - - NameSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Name")}]), - NameTx = wxTextCtrl:new(Dialog, ?wxID_ANY), - _ = wxSizer:add(NameSz, NameTx, zxw:flags(wide)), - PassSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Passphrase")}]), - PassTx = wxTextCtrl:new(Dialog, ?wxID_ANY), - _ = wxSizer:add(PassSz, PassTx, zxw:flags(wide)), - - ButtSz = wxBoxSizer:new(?wxHORIZONTAL), - Affirm = wxButton:new(Dialog, ?wxID_OK), - Cancel = wxButton:new(Dialog, ?wxID_CANCEL), - _ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)), - _ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)), - - _ = wxSizer:add(Sizer, NameSz, zxw:flags(base)), - _ = wxSizer:add(Sizer, PassSz, zxw:flags(base)), - _ = wxSizer:add(Sizer, ButtSz, zxw:flags(wide)), - - ok = wxDialog:setSizer(Dialog, Sizer), - ok = wxBoxSizer:layout(Sizer), - ok = wxFrame:setSize(Dialog, {500, 200}), - ok = wxFrame:center(Dialog), - ok = wxStyledTextCtrl:setFocus(NameTx), - - Result = - case wxDialog:showModal(Dialog) of - ?wxID_OK -> - Name = - case wxTextCtrl:getValue(NameTx) of - "" -> Path; - N -> N - end, - Pass = - case wxTextCtrl:getValue(PassTx) of - "" -> none; - P -> P - end, - gd_con:import_wallet(Name, Path, Pass); - ?wxID_CANCEL -> - abort - end, - ok = wxDialog:destroy(Dialog), - Result. - - -do_drop(State = #s{picker = Picker}) -> - case wxListBox:getSelection(Picker) of - -1 -> State; - Selected -> do_drop(Selected + 1, State) - end. - -do_drop(Selected, State = #s{j = J, frame = Frame, wallets = Wallets}) -> - #wr{name = Name, path = Path} = lists:nth(Selected, Wallets), - Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Drop Wallet")), - Sizer = wxBoxSizer:new(?wxVERTICAL), - - MessageM = J("REALLY delete wallet?"), - Message = ["\r\n", MessageM, "\r\n\r\n\"", Name, "\""], - MessageT = wxStaticText:new(Dialog, ?wxID_ANY, Message, - [{style, ?wxALIGN_CENTRE_HORIZONTAL}]), - DeleteM = J("Delete file data?"), - DeleteCheck = wxCheckBox:new(Dialog, ?wxID_ANY, DeleteM), - - ButtSz = wxBoxSizer:new(?wxHORIZONTAL), - Affirm = wxButton:new(Dialog, ?wxID_OK), - Cancel = wxButton:new(Dialog, ?wxID_CANCEL), - _ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)), - _ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)), - - _ = wxSizer:add(Sizer, MessageT, zxw:flags(base)), - _ = wxSizer:add(Sizer, DeleteCheck, zxw:flags(base)), - _ = wxSizer:add(Sizer, ButtSz, zxw:flags(wide)), - - ok = wxDialog:setSizer(Dialog, Sizer), - ok = wxBoxSizer:layout(Sizer), - ok = wxFrame:setSize(Dialog, {500, 200}), - ok = wxFrame:center(Dialog), - - ok = - case wxDialog:showModal(Dialog) of - ?wxID_OK -> - Delete = wxCheckBox:getValue(DeleteCheck), - gd_con:drop_wallet(Path, Delete); - ?wxID_CANCEL -> - ok - end, - State.