diff --git a/:q b/:q new file mode 100644 index 0000000..0dee45b --- /dev/null +++ b/:q @@ -0,0 +1,10 @@ +WIP: Adjust procedure description (for now) +# Please enter the commit message for your changes. Lines starting +# with '#' will be ignored, and an empty message aborts the commit. +# +# ブランチ gajuexpress +# Your branch is up to date with 'origin/gajuexpress'. +# +# コミット予定の変更点: +# modified: src/gd_v_express.erl +# diff --git a/src/gd_v_express.erl b/src/gd_v_express.erl index 22f9ba3..69cc6e8 100644 --- a/src/gd_v_express.erl +++ b/src/gd_v_express.erl @@ -1,5 +1,35 @@ %%% @doc %%% The GajuExpress +% 0. User opens GajuDesk and selects the key (very top widget) +% +% Sending... +% +% 1. The user inputs the public key/ID of the party the data should be sent to +% 2. The user picks the file or directory to send +% 3. The user decides whether to sign the package or be anonymous +% 4. The user sets the package's TTL +% 5. GajuDesk packs up and compresses the bundle. +% 6. GajuDesk asks GajuExpress for a quote based on size/time +% 7. The price is shown +% 8. The user agrees or aborts +% 9. If the user agrees, a payment window opens and they send a payment to GajuExpress +% 10. GajuDesk polls until the payment is included or the user gives up +% 11. Once GajuExpress verifies the payment, the upload begins +% 12. Progress bar +% +% +% Receiving... +% +% 1. User clicks "check for deliveries" +% 2. GajuExpress issues an ID signature challenge +% 3. GajuDesk asks GajuExpress whether there are any packages waiting for Key +% 4. If yes, then the pending deliveries are shown in the delivery panel +% 5. The user selects + clicks open (or double clicks) a package +% 6. User selects where to unpack it in a file dialog +% 7. GajuDesk downloads the package from GajuExpress +% 8. Progress bar +% 9. File is decrypted and optionally signature verified +% 10. GajuExpress deletes their copy of the file %%% @end @@ -13,7 +43,7 @@ %-behavior(gd_v). -include_lib("wx/include/wx.hrl"). -export([to_front/0, to_front/1, trouble/1]). --export([show/2]). +-export([pending/1, accounts/1]). -export([start_link/1]). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2, handle_event/2]). @@ -28,14 +58,18 @@ lang = en :: en | jp, j = none :: none | fun(), prefs = #{} :: map(), - price = none :: none | {non_neg_integer(), wx:wx_object()}, - size = none :: none | {non_neg_integer(), wx:wx_object()}, - total = none :: none | {non_neg_integer(), wx:wx_object()}, + keys = #w{} :: #w{}, + accs = [] :: [#wr{}], + check = #w{} :: #w{}, + list = #w{} :: #w{}, + dl = #w{} :: #w{}, dest = none :: none | wx:wx_object(), - picker = none :: none | wx:wx_object(), - file = none :: none | wx:wx_object(), - sign_yn = none :: none | wx:wx_object(), - buttons = [] :: [#w{}]}). + ttl = none :: none | wx:wx_object(), + path = none :: none | wx:wx_object(), + sign = none :: none | wx:wx_object(), + size = none :: none | wx:wx_object(), + cost = none :: none | wx:wx_object(), + ul = none :: none | wx:wx_object()}). -record(mochila, {tar = <<>> :: binary(), @@ -64,12 +98,20 @@ trouble(Info) -> wx_object:cast(?MODULE, {trouble, Info}). --spec show(Win, Manifest) -> ok - when Win :: wx:xw_object(), - Manifest :: [#wr{}]. +-spec pending(Manifest) -> ok + when Manifest :: [Transfer], + Transfer :: {Name :: string(), Size :: pos_integer()}. + +pending(Manifest) -> + wx_object:cast(?MODULE, {pending, Manifest}). + + +-spec accounts(Manifest) -> ok + when Manifest :: [#wr{}]. + +accounts(Manifest) -> + wx_object:cast(?MODULE, {accounts, Manifest}). -show(Win, Manifest) -> - wx_object:cast(Win, {show, Manifest}). %%% Startup @@ -77,38 +119,7 @@ show(Win, Manifest) -> start_link(Args) -> wx_object:start_link({local, ?MODULE}, ?MODULE, Args, []). -% Sending... -% -% 0. Sender opens GajuExpress interface -% 1. The user inputs the public key/ID of the party the data should be sent to -% 2. The user picks the file or directory to send -% 3. The user decides whether to sign the package or be anonymous -% 4. The user picks which key to send (and sign with if signing) -% 5. The user sets the package's TTL -% 6. GajuDesk packs up and compresses the bundle. -% 7. GajuDesk asks GajuExpress for a quote based on size/time -% 8. The price is shown -% 9. The user agrees or aborts -% 10. If the user agrees, a payment window opens and they send a payment to GajuExpress -% 11. GajuDesk polls until the payment is included or the user gives up -% 12. Once GajuExpress verifies the payment, the upload begins -% 13. Progress bar -% -% -% Receiving... -% -% 1. Sender opens GajuExpress interface -% 2. GajuExpress issues an ID signature challenge -% 3. GajuDesk asks GajuExpress whether there are any packages waiting for Key -% 4. If yes, then the pending deliveries are shown in the delivery panel -% 5. The user selects + clicks open (or double clicks) a package -% 6. User selects where to unpack it in a file dialog -% 7. GajuDesk downloads the package from GajuExpress -% 8. Progress bar -% 9. File is decrypted and optionally signature verified -% 10. GajuExpress deletes their copy of the file - -init({Prefs, KeyManifest}) -> +init({Prefs, Selected, Keys}) -> Lang = maps:get(lang, Prefs, en), Trans = gd_jt:read_translations(?MODULE), J = gd_jt:j(Lang, Trans), @@ -120,32 +131,58 @@ init({Prefs, KeyManifest}) -> MainSz = wxBoxSizer:new(?wxVERTICAL), LR_Sz = wxBoxSizer:new(?wxHORIZONTAL), - DeliverySz = wxBoxSizer:new(?wxVERTICAL), - DeliveryP = wxListBox:new(Panel, ?wxID_ANY, [{style, ?wxLC_SINGLE_SEL}]), - -% ok = wxListBox:set(DeliveryP, Names), + KeyP = wxChoice:new(Panel, ?wxID_ANY, [{choices, Keys}]), + KP = #w{name = key_picker, id = wxChoice:getId(KeyP), wx = KeyP}, + ZeroBasedSelected = Selected - 1, + ok = wxChoice:setSelection(KeyP, ZeroBasedSelected), + _ = wxStaticBoxSizer:add(MainSz, KeyP, zxw:flags({base, 5})), + + DownloadSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, J("Downloads")}]), + DownloadBox = wxStaticBoxSizer:getStaticBox(DownloadSz), + CheckB = #w{wx = CheckW} = make_button(DownloadBox, check, J("Check for Downloads")), + DownloadP = wxListBox:new(DownloadBox, ?wxID_ANY, [{style, ?wxLC_SINGLE_SEL}]), + DL_L = #w{name = list, id = wxListBox:getId(DownloadP), wx = DownloadP}, + DownloadB = #w{wx = DownloadW} = make_button(DownloadBox, dl, J("Download")), + _ = wxButton:disable(DownloadW), + _ = wxBoxSizer:add(DownloadSz, CheckW, zxw:flags({base, 5})), + _ = wxBoxSizer:add(DownloadSz, DownloadP, zxw:flags({wide, 5})), + _ = wxBoxSizer:add(DownloadSz, DownloadW, zxw:flags({base, 5})), + UploadSz = wxStaticBoxSizer:new(?wxVERTICAL, Panel, [{label, J("Uploads")}]), + UploadBox = wxStaticBoxSizer:getStaticBox(UploadSz), + DestSz = wxStaticBoxSizer:new(?wxHORIZONTAL, UploadBox, [{label, J("Destination ID")}]), + DestBox = wxStaticBoxSizer:getStaticBox(DestSz), + DestT = wxTextCtrl:new(DestBox, ?wxID_ANY), + _ = wxStaticBoxSizer:add(DestSz, DestT), + TTL_Sz = wxStaticBoxSizer:new(?wxHORIZONTAL, UploadBox, [{label, J("Transfer Expiration (Days)")}]), + TTL_Box = wxStaticBoxSizer:getStaticBox(TTL_Sz), + TTL_T = wxTextCtrl:new(TTL_Box, ?wxID_ANY, [{value, "7"}]), + _ = wxStaticBoxSizer:add(TTL_Sz, TTL_T), + PathSz = wxStaticBoxSizer:new(?wxHORIZONTAL, UploadBox, [{label, J("File or Directory")}]), + PathBox = wxStaticBoxSizer:getStaticBox(PathSz), + PathP = wxFilePickerCtrl:new(PathBox, ?wxID_ANY), + _ = wxStaticBoxSizer:add(PathSz, PathP), + SignSz = wxStaticBoxSizer:new(?wxHORIZONTAL, UploadBox, [{label, J("Transfer Signature")}]), + SignBox = wxStaticBoxSizer:getStaticBox(SignSz), + SignC = wxCheckBox:new(SignBox, ?wxID_ANY, J("Do you want to sign this transfer?")), + _ = wxStaticBoxSizer:add(SignSz, SignC), + SizeSz = wxStaticBoxSizer:new(?wxHORIZONTAL, UploadBox, [{label, J("Transfer Details")}]), + SizeBox = wxStaticBoxSizer:getStaticBox(SizeSz), + SizeT = wxStaticText:new(SizeBox, ?wxID_ANY, J("[No File or Directory Selected]")), + _ = wxStaticBoxSizer:add(SizeSz, SizeT), + CostSz = wxStaticBoxSizer:new(?wxHORIZONTAL, UploadBox, [{label, J("Cost to Transfer")}]), + CostBox = wxStaticBoxSizer:getStaticBox(CostSz), + CostT = wxStaticText:new(CostBox, ?wxID_ANY, "[N/A]"), + _ = wxStaticBoxSizer:add(CostSz, CostT), + UploadB = #w{wx = UploadW} = make_button(UploadBox, ul, J("Upload")), + _ = wxButton:disable(UploadW), + _ = wxStaticBoxSizer:add(UploadSz, UploadW), - SendingSz = wxBoxDizer:new(?wxVERTICAL), - - KeyNames = [Name || #wr{name = Name} <- KeyManifest], - - ButtSz = wxBoxSizer:new(?wxHORIZONTAL), - ButtonTemplates = - [{open, J("Open")}, - {new, J("New")}, - {move, J("Move")}, - {import, J("Import")}, - {drop, J("Drop")}], - MakeButton = button_maker(Panel, ButtSz), - Buttons = lists:map(MakeButton, ButtonTemplates), - - _ = wxSizer:add(MainSz, Picker, zxw:flags(wide)), - _ = wxSizer:add(MainSz, ButtSz, zxw:flags(base)), - - ok = wxFrame:setSizer(Panel, MainSz), + _ = wxBoxSizer:add(MainSz, DownloadSz, zxw:flags({wide, 5})), + _ = wxBoxSizer:add(MainSz, UploadSz, zxw:flags({wide, 5})), + ok = wxPanel:setSizer(Panel, MainSz), ok = wxFrame:setSizer(Frame, TopSz), - ok = wxSizer:layout(MainSz), + ok = wxSizer:layout(TopSz), NewPrefs = case maps:is_key(geometry, Prefs) of @@ -165,21 +202,19 @@ init({Prefs, KeyManifest}) -> ok = wxFrame:connect(Frame, command_button_clicked), ok = wxFrame:connect(Frame, close_window), - ok = wxListBox:connect(Picker, command_listbox_doubleclicked), - State = #s{wx = Wx, frame = Frame, lang = Lang, j = J, prefs = Prefs, - wallets = Manifest, - picker = Picker, - buttons = Buttons}, + ok = wxListBox:connect(DownloadP, command_listbox_doubleclicked), + State = #s{wx = Wx, frame = Frame, lang = Lang, j = J, prefs = Prefs, + keys = KeyP, accs = Keys, + check = CheckB, list = DL_L, + dl = DownloadB, + dest = DestT, ttl = TTL_T, path = PathP, sign = SignC, + size = SizeT, cost = CostT, + ul = UploadB}, {Frame, State}. - -button_maker(Parent, Sizer) -> - fun({Name, Label}) -> - B = wxButton:new(Parent, ?wxID_ANY, [{label, Label}]), - _ = wxSizer:add(Sizer, B, zxw:flags({wide, 5})), - #w{name = Name, id = wxButton:getId(B), wx = B} - end. - +make_button(Parent, Name, Label) -> + B = wxButton:new(Parent, ?wxID_ANY, [{label, Label}]), + #w{name = Name, id = wxButton:getId(B), wx = B}. @@ -189,19 +224,19 @@ handle_call(Unexpected, From, State) -> ok = log(warning, "Unexpected call from ~tp: ~tp~n", [From, Unexpected]), {noreply, State}. +handle_cast({pending, Manifest}, State) -> + NewState = do_pending(Manifest, State), + {noreply, NewState}; +handle_cast({accounts, Manifest}, State) -> + NewState = do_accounts(Manifest, State), + {noreply, NewState}; handle_cast(to_front, State = #s{frame = Frame}) -> ok = ensure_shown(Frame), ok = wxFrame:raise(Frame), {noreply, State}; -handle_cast(first_run, State) -> - NewState = do_first_run(State), - {noreply, NewState}; handle_cast({trouble, Info}, State) -> ok = handle_troubling(State, Info), {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}. @@ -212,45 +247,30 @@ handle_info(Unexpected, State) -> {noreply, State}. -handle_event(#wx{event = #wxCommand{type = command_button_clicked}, - id = ID}, - State = #s{buttons = Buttons, wiz = none}) -> - 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, +handle_event(#wx{event = #wxCommand{type = command_button_clicked}, id = ID}, + State = #s{check = #w{id = ID}}) -> + NewState = do_check(State), + {noreply, NewState}; +handle_event(#wx{event = #wxCommand{type = command_button_clicked}, id = ID}, + State = #s{dl = #w{id = ID}}) -> + NewState = do_dl(State), + {noreply, NewState}; +handle_event(#wx{event = #wxCommand{type = command_button_clicked}, id = ID}, + State = #s{ul = #w{id = ID}}) -> + NewState = do_ul(State), {noreply, NewState}; handle_event(#wx{event = #wxCommand{type = command_listbox_doubleclicked, commandInt = Selected}}, - State = #s{wiz = none}) -> - ok = do_open2(Selected + 1, State), + State) -> + NewState = do_dl(State), {noreply, State}; -handle_event(#wx{event = #wxClose{}}, State = #s{wiz = none}) -> +handle_event(#wx{event = #wxClose{}}, State) -> ok = do_close(State), {noreply, State}; -handle_event(#wx{event = #wxCommand{type = command_button_clicked}, - id = ID}, - State = #s{wiz = {_, WizButtons}}) -> - NewState = - case lists:keyfind(ID, #w.id, WizButtons) of - #w{name = noob} -> wiz_noob_assist(State); - #w{name = l33t} -> close_wiz(State); - false -> State - end, - {noreply, NewState}; -handle_event(#wx{event = #wxClose{}}, State = #s{wiz = {_, _}}) -> - NewState = close_wiz(State), - {noreply, NewState}; handle_event(Event, State) -> ok = tell(info, "Unexpected event ~tp State: ~tp~n", [Event, State]), {noreply, State}. - handle_troubling(#s{frame = Frame}, Info) -> zxw:show_message(Frame, Info). @@ -269,30 +289,35 @@ terminate(Reason, State) -> %%% doers -do_show(Manifest, State = #s{picker = Picker}) -> +do_show(Manifest, State = #s{keys = KeyP}) -> Names = [Name || #wr{name = Name} <- Manifest], - ok = wxListBox:set(Picker, Names), - State#s{wallets = Manifest}. + ok = wxListBox:set(KeyP, Names), + State#s{accs = Manifest}. -do_first_run(State = #s{frame = Frame, wallets = Manifest}) -> - Count = length(Manifest), - if - Count =:= 0 -> - do_wiz(State); - Count =:= 1 -> - do_open(State); - Count > 1 -> - true = wxFrame:show(Frame), - wxFrame:raise(Frame), - State - end. +do_pending(State, Manifest) -> + ok = tell(info, "Would do_pending: ~p", [Manifest]), + State. -close_wiz(State = #s{frame = Frame, wiz = {Wiz, _}}) -> - ok = wxWindow:destroy(Wiz), - true = wxFrame:show(Frame), - State#s{wiz = none}. +do_accounts(State, Manifest) -> + ok = tell(info, "Would do_pending: ~p", [Manifest]), + State. + + +do_check(State) -> + ok = tell(info, "Would do_check."), + State. + + +do_dl(State) -> + ok = tell(info, "Would do_dl."), + State. + + +do_ul(State) -> + ok = tell(info, "Would do_ul."), + State. do_close(#s{frame = Frame, prefs = Prefs}) -> @@ -310,104 +335,6 @@ do_close(#s{frame = Frame, prefs = Prefs}) -> 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{wallets = [#wr{pass = true, path = Path}]}) -> - ok = do_open3(Path, State), - State; -do_open(State = #s{wallets = [#wr{pass = false, path = Path}], frame = Frame}) -> - ok = - case gd_con:open_wallet(Path, none) of - ok -> - do_close(State); - Error -> - ok = ensure_shown(Frame), - trouble(Error) - end, - State; -do_open(State = #s{picker = Picker}) -> - case wxListBox:getSelection(Picker) of - -1 -> - State; - Selected -> - ok = do_open2(Selected + 1, State), - 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), - do_close(State) - end. - -do_open3(Path, State = #s{frame = Frame, j = J}) -> - Title = J("Passphrase"), - case zxw_modal_text:show(Frame, Title, [{password, true}]) of - {ok, Phrase} -> - case gd_con:open_wallet(Path, Phrase) of - ok -> do_close(State); - Error -> trouble(Error) - end; - cancel -> - ok - end. - - -do_wiz(State = #s{wx = WX, lang = Lang, wiz = none}) -> - Trans = gd_jt:read_translations(?MODULE), - J = gd_jt:j(Lang, Trans), - - Wiz = wxFrame:new(WX, ?wxID_ANY, J("Initializing Wallet")), - MainSz = wxBoxSizer:new(?wxVERTICAL), - - ButtonTemplates = - [{noob, J("I'm new!\nCreate a new account for me.")}, - {l33t, J("Open the wallet manager.")}], - - MakeButton = - fun({Name, Label}) -> - B = wxButton:new(Wiz, ?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(Wiz, MainSz), - ok = wxSizer:layout(MainSz), - - ok = wxFrame:connect(Wiz, command_button_clicked), - ok = wxFrame:connect(Wiz, close_window), - ok = wxFrame:setSize(Wiz, {300, 300}), - ok = wxFrame:center(Wiz), - true = wxFrame:show(Wiz), - State#s{wiz = {Wiz, Buttons}}. - - -wiz_noob_assist(State = #s{j = J, wiz = {Wiz, _}}) -> - DefaultDir = zx_lib:path(var, "otpr", "gajudesk"), - Name = default_name(), - Path = filename:join(DefaultDir, Name), - case do_new2(Path, J, Wiz) of - ok -> - Label = J("Account 1"), - ok = gd_con:make_key({eddsa, ed25519}, 256, Label, <<>>, none, {sha3, 256}), - ok = do_close(State), - State; - abort -> - State - end. - default_name() -> {{YY, MM, DD}, {Hr, Mn, Sc}} = calendar:local_time(), Form = "~4.10.0B-~2.10.0B-~2.10.0B_~2.10.0B-~2.10.0B-~2.10.0B", @@ -415,190 +342,6 @@ default_name() -> unicode:characters_to_list(Name ++ ".gaju"). -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_name()}, - {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), - NewState = State#s{prefs = NewPrefs}, - ok = do_close(NewState), - NewState; - 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), - NetworkOptions = [J("Mainnet"), J("Testnet")], - Network = wxRadioBox:new(Dialog, ?wxID_ANY, J("Network"), {0, 0}, {50, 50}, NetworkOptions), - 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), - NewState = State#s{prefs = NewPrefs}, - ok = do_close(NewState), - NewState; - 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), - Title = J("Import Wallet"), - NameL = J("Wallet Name"), - PassL = J("Passphrase (leave blank if none)"), - OK_L = J("OK"), - CancelL = J("Cancel"), - case gd_m_wallet_importer:show(Frame, Title, NameL, PassL, OK_L, CancelL) of - {ok, Name, Pass} -> gd_con:import_wallet(Name, Path, Pass); - cancel -> abort - end. - - -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. - - ensure_shown(Frame) -> case wxWindow:isShown(Frame) of true ->