1
0
forked from cheng/wallet

Merge remote-tracking branch 'origin/master' into docs

This commit is contained in:
reaction.la 2023-11-09 05:22:34 +10:00
commit 0eefc8fd48
No known key found for this signature in database
GPG Key ID: 99914792148C8388
7 changed files with 184 additions and 68 deletions

View File

@ -43,19 +43,19 @@
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)wxWidgets\include\msvc;$(SolutionDir)wxWidgets\include;$(SolutionDir)libsodium\src\libsodium\include;$(SolutionDir)mpir;$(IncludePath)</IncludePath> <IncludePath>..\wxWidgets\include\msvc;..\wxWidgets\include;..\libsodium\src\libsodium\include;..\mpir;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)wxWidgets\lib\vc_x64_lib\;$(SolutionDir)libsodium\bin\x64\Debug\v143\static;$(SolutionDir)mpir\lib\x64\Debug;$(LibraryPath)</LibraryPath> <LibraryPath>..\wxWidgets\lib\vc_x64_lib\;..\libsodium\bin\x64\Debug\v143\static;..\mpir\lib\x64\Debug;$(LibraryPath)</LibraryPath>
<CustomBuildAfterTargets /> <CustomBuildAfterTargets />
<IntDir>$(SolutionDir)build\$(Configuration)\</IntDir> <IntDir>..\build\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>..\build\$(Configuration)\</OutDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)wxWidgets\include\msvc;$(SolutionDir)wxWidgets\include;$(SolutionDir)libsodium\src\libsodium\include;$(SolutionDir)mpir;$(IncludePath)</IncludePath> <IncludePath>..\wxWidgets\include\msvc;..\wxWidgets\include;..\libsodium\src\libsodium\include;..\mpir;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)wxWidgets\lib\vc_x64_lib\;$(SolutionDir)libsodium\bin\x64\Release\v143\static;$(SolutionDir)mpir\lib\x64\Release;$(LibraryPath)</LibraryPath> <LibraryPath>..\wxWidgets\lib\vc_x64_lib\;..\libsodium\bin\x64\Release\v143\static;..\mpir\lib\x64\Release;$(LibraryPath)</LibraryPath>
<CustomBuildAfterTargets /> <CustomBuildAfterTargets />
<IntDir>$(SolutionDir)build\$(Configuration)\</IntDir> <IntDir>..\build\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>..\build\$(Configuration)\</OutDir>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
@ -168,7 +168,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)sqlite3\sqlite3.c"> <ClCompile Include="..\sqlite3\sqlite3.c">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile> </ClCompile>
@ -193,4 +193,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@ -3,8 +3,7 @@ using ro::base58;
static constexpr char SrcFilename[]{ "src/display_wallet.cpp" }; static constexpr char SrcFilename[]{ "src/display_wallet.cpp" };
display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) :
wxPanel(parent, myID_WALLET_UI, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, wxT("Wallet")), wxPanel(parent, myID_WALLET_UI, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, wxT("Wallet")),
m_db(nullptr), m_db(nullptr), m_DisplayWalletEditMenu(1)
m_menuitem_add_name(this, &display_wallet::add_name_event_handler)
{ {
wxLogMessage(wxT("Loading %s"), walletfile.GetFullPath()); wxLogMessage(wxT("Loading %s"), walletfile.GetFullPath());
try { try {
@ -73,10 +72,16 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) :
this->SetSize(this->GetParent()->GetClientSize()); this->SetSize(this->GetParent()->GetClientSize());
singletonFrame->m_LastUsedWallet.Assign(walletfile); singletonFrame->m_LastUsedWallet.Assign(walletfile);
wxMenu* menuFile{ singletonFrame->GetMenuBar()->GetMenu(0) }; m_DisplayWalletEditMenu.Menu->Append(
singletonFrame->GetMenuBar()->EnableTop(1, true); //enable edit menu. myID_DISPLAY_WALLET_ADD_NAME,
wxMenu* menuEdit{ singletonFrame->GetMenuBar()->GetMenu(1) }; "add name", "create new Zooko identity"
m_menuitem_add_name.Insert(menuEdit, 0, "add name", "create new Zooko identity"); );
m_DisplayWalletEditMenu.Menu->Bind(
wxEVT_MENU,
&display_wallet::add_name_event_handler,
this, myID_DISPLAY_WALLET_ADD_NAME
);
m_DisplayWalletEditMenu.Replace();
} }
catch (const MyException&) { catch (const MyException&) {
throw; throw;
@ -91,10 +96,8 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) :
} }
display_wallet::~display_wallet() {
assert(true);
singletonFrame->GetMenuBar()->EnableTop(1, false); //disable edit menu.
display_wallet::~display_wallet() {
} }
void display_wallet::close_menu_event_handler(wxCommandEvent& event) { void display_wallet::close_menu_event_handler(wxCommandEvent& event) {

View File

@ -14,6 +14,6 @@ private:
wxBoxSizer* m_rSizer; wxBoxSizer* m_rSizer;
void close_menu_event_handler(wxCommandEvent&); void close_menu_event_handler(wxCommandEvent&);
void add_name_event_handler(wxCommandEvent&); void add_name_event_handler(wxCommandEvent&);
MenuLink m_menuitem_add_name;
void OnClose(wxCloseEvent& event); void OnClose(wxCloseEvent& event);
wxMenuTracker m_DisplayWalletEditMenu;
}; };

View File

@ -1,6 +1,36 @@
#include "stdafx.h" #include "stdafx.h"
static constexpr char SrcFilename[]{ "src/frame.cpp" }; static constexpr char SrcFilename[]{ "src/frame.cpp" };
// ----------------------------------------------------------------------------
//wxMenuTracker
// ----------------------------------------------------------------------------
wxMenuTracker::wxMenuTracker(const int i) : Menu(new wxMenu), MenuPosition(i) {};
wxMenu* wxMenuTracker::InitialAndFinal[]{ nullptr, new wxMenu, nullptr };
void wxMenuTracker::Replace() {
singletonFrame->GetMenuBar()->Replace(
MenuPosition,
Menu,
menu_strings[MenuPosition].head
);
singletonFrame->GetMenuBar()->EnableTop(MenuPosition, true); //enable edit menu.
};
wxMenuTracker::~wxMenuTracker() {
auto menu_bar = singletonFrame->GetMenuBar();
if (menu_bar->GetMenu(MenuPosition) == Menu) {
assert(InitialAndFinal[MenuPosition]);
menu_bar->Replace(
MenuPosition,
InitialAndFinal[MenuPosition],
menu_strings[MenuPosition].head
);
menu_bar->EnableTop(MenuPosition, false);
delete Menu;
}
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// frame // frame
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -157,18 +187,36 @@ Frame::Frame(const wxString& wxs)
menuFile->Bind(wxEVT_MENU, &Frame::OnDeleteConfiguration, this, myID_DELETECONFIG); menuFile->Bind(wxEVT_MENU, &Frame::OnDeleteConfiguration, this, myID_DELETECONFIG);
menuFile->Append(wxID_EXIT); menuFile->Append(wxID_EXIT);
menuFile->Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT); menuFile->Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT);
wxMenu* menuEdit = wxMenuTracker::InitialAndFinal[1];
wxMenu* menuHelp = new wxMenu; wxMenu* menuHelp = new wxMenu;
menuHelp->Append(wxID_ABOUT); menuHelp->Append(wxID_ABOUT);
menuHelp->Bind(wxEVT_MENU, &Frame::OnAbout, this, wxID_ABOUT); menuHelp->Bind(wxEVT_MENU, &Frame::OnAbout, this, wxID_ABOUT);
wxMenuBar* menuBar = new wxMenuBar; wxMenuBar* menuBar = new wxMenuBar;
menuBar->Append(menuFile, menu_strings[0].head); menuBar->Append(menuFile, menu_strings[0].head);
menuBar->Append(new wxMenu, menu_strings[1].head); //Edit menu, initially empty and disabled menuBar->Append(menuEdit, menu_strings[1].head); //Edit menu, initially empty and disabled
menuBar->Append(menuHelp, menu_strings[2].head); menuBar->Append(menuHelp, menu_strings[2].head);
SetMenuBar(menuBar); SetMenuBar(menuBar);
CreateStatusBar();
menuBar->EnableTop(1, false); //disable edit menu. menuBar->EnableTop(1, false); //disable edit menu.
// child controls if constexpr (debug_mode) {
// Check that the initial values of all replaceable menus
// are at their default values as if the window handling them
// had just been destroyed and not yet replaced.
for (int i = 0; i < std::size(wxMenuTracker::InitialAndFinal); i++) {
assert(
!wxMenuTracker::InitialAndFinal[i]
||
(
wxMenuTracker::InitialAndFinal[i] == menuBar->GetMenu(i)
&&
!menuBar->IsEnabledTop(i)
)
);
}
}
CreateStatusBar();
// child controls
wxPanel* panel{ nullptr }; wxPanel* panel{ nullptr };
m_panel = panel; m_panel = panel;
wxConfigBase& Config = singletonApp->m_Config; wxConfigBase& Config = singletonApp->m_Config;
@ -374,45 +422,59 @@ COMMIT;
void Frame::OnSaveNew(wxCommandEvent& WXUNUSED(event)) void Frame::OnSaveNew(wxCommandEvent& WXUNUSED(event))
{ {
wxString wxstrWalletPath; wxFileName wxFileWallet;
wxString wxstrWalletName(wxEmptyString); if (m_DefaultWalletLocation.FileExists()) {
if (!m_LastUsedWallet.IsOk() || !m_LastUsedWallet.DirExists()) { // OK, the default wallet exists, so we need a new
m_LastUsedWallet = m_DefaultWalletLocation; // name and wallet location
RecursiveCreateDirectory(m_LastUsedWallet); wxString wxstrWalletPath;
} wxString wxstrWalletName(wxEmptyString);
wxstrWalletPath = m_LastUsedWallet.GetPath(); //Directory guaranteed to exist, so we will not get idiot default if (!m_LastUsedWallet.IsOk() || !m_LastUsedWallet.DirExists()) {
// It took me a ridiculous amount of time to fix that all paths to this file dialog m_LastUsedWallet = m_DefaultWalletLocation;
// are either terminated by an exception, or the directory exists, or is created. RecursiveCreateDirectory(m_LastUsedWallet);
// Any time the program has to deal with something external to itself, anything that can go wrong }
// will go wrong. wxstrWalletPath = m_LastUsedWallet.GetPath(); //Directory guaranteed to exist, so we will not get idiot default
if (!m_LastUsedWallet.FileExists()) wxstrWalletName = m_LastUsedWallet.GetFullName(); // It took me a ridiculous amount of time to fix that all paths to this file dialog
wxFileDialog dialog(this, // are either terminated by an exception, or the directory exists, or is created.
sz_new_wallet_new_secret, // Any time the program has to deal with something external to itself, anything that can go wrong
wxstrWalletPath, // will go wrong.
wxstrWalletName, if (!m_LastUsedWallet.FileExists()) wxstrWalletName = m_LastUsedWallet.GetFullName();
wxString::Format wxFileDialog dialog(this,
("wallet (*.wallet)|*.wallet|All (%s)|%s", sz_new_wallet_new_secret,
wxFileSelectorDefaultWildcardStr, wxstrWalletPath,
wxFileSelectorDefaultWildcardStr wxstrWalletName,
), wxString::Format
wxFD_SAVE | wxFD_OVERWRITE_PROMPT ("wallet (*.wallet)|*.wallet|All (%s)|%s",
); wxFileSelectorDefaultWildcardStr,
dialog.SetFilterIndex(m_FileDialogFilterIndex); wxFileSelectorDefaultWildcardStr
if (dialog.ShowModal() == wxID_OK) ),
{ wxFD_SAVE | wxFD_OVERWRITE_PROMPT
wxLogMessage("%s, filter %d",
dialog.GetPath(),
dialog.GetFilterIndex()
); );
wxFileName wxFileWallet(dialog.GetPath()); dialog.SetFilterIndex(m_FileDialogFilterIndex);
ristretto255::hash<256> WalletSecret( wxFileWallet.GetFullPath().ToUTF8()); if (dialog.ShowModal() == wxID_OK)
{
wxLogMessage("%s, filter %d",
dialog.GetPath(),
dialog.GetFilterIndex()
);
wxFileWallet.Assign(dialog.GetPath());
m_FileDialogFilterIndex = dialog.GetFilterIndex();
}
}
else {
// Default does not exist, so we go right
// ahead without asking the user to invent
// a name and select a directory
RecursiveCreateDirectory(m_DefaultWalletLocation);
wxFileWallet = m_DefaultWalletLocation;
}
if (wxFileWallet.IsOk()) {
ristretto255::hash<256> WalletSecret(wxFileWallet.GetFullPath().ToUTF8());
NewWallet(wxFileWallet, WalletSecret); NewWallet(wxFileWallet, WalletSecret);
wxLogMessage("new wallet created: %s", wxFileWallet.GetFullPath()); wxLogMessage("new wallet created: %s", wxFileWallet.GetFullPath());
if (m_panel)m_panel->Close(true); if (m_panel)m_panel->Close(true);
m_panel = nullptr; m_panel = nullptr;
auto panel = new display_wallet(this, wxFileWallet); auto panel = new display_wallet(this, wxFileWallet);
m_panel = panel; m_panel = panel;
m_FileDialogFilterIndex = dialog.GetFilterIndex();
m_LastUsedWallet = wxFileWallet; //We do this last, so that if an exception occurs the filename is forgotten. m_LastUsedWallet = wxFileWallet; //We do this last, so that if an exception occurs the filename is forgotten.
} }
} }
@ -497,11 +559,29 @@ Frame::~Frame() {
wxConfigBase& Config = singletonApp->m_Config; wxConfigBase& Config = singletonApp->m_Config;
StorePositionToConfig(); StorePositionToConfig();
Config.SetPath(wxT("/TipOfTheDay")); Config.SetPath(wxT("/TipOfTheDay"));
Config.Write("show", (int)m_showTipsAtStartup); Config.Write("show", (int)m_showTipsAtStartup);
Config.Write("index", (int)m_TipOfTheDayIndex); Config.Write("index", (int)m_TipOfTheDayIndex);
Config.SetPath(wxT("/FileDialog")); Config.SetPath(wxT("/FileDialog"));
Config.Write("index", (int)m_FileDialogFilterIndex); Config.Write("index", (int)m_FileDialogFilterIndex);
Config.Write(wxT("LastUsed"), m_LastUsedWallet.GetFullPath()); Config.Write(wxT("LastUsed"), m_LastUsedWallet.GetFullPath());
Config.SetPath(wxT("/")); Config.SetPath(wxT("/"));
Config.Flush(); Config.Flush();
if constexpr (debug_mode) {
// Check that the final values of all replaceable menus
// are at what they should be because the window handling
// them should have been destroyed.
auto menuBar = this->GetMenuBar();
for (int i = 0; i < std::size(wxMenuTracker::InitialAndFinal); i++) {
assert(
!wxMenuTracker::InitialAndFinal[i]
||
(
wxMenuTracker::InitialAndFinal[i] == menuBar->GetMenu(i)
&&
!menuBar->IsEnabledTop(i)
)
);
}
}
} }

View File

@ -1,4 +1,39 @@
#pragma once #pragma once
// wxWidgets has drop down menus, wxMenu, owned by the wxMenuBar,
// which is owned by the Frame window, but menus subject to replacement need
// to be destroyed by the child window.
// wxMenuOwner tracks a drop down menu that might be at a location in
// the menubar, places it in that location in the menubar on demand,
// and on destruction destroys it
// If, on destruction wxMenuBar is still pointing to this wxMenu, it
// replaces it with the default (empty) menu for that location.
// and disables it.
// We maintain an array of default empty wxMenu menus that are nullptr for
// locations not subject to replacement, and are the disabled initial and final
// wxMenuBar values for locations in the Menubar where the real drop down
// in the menubar will be installed by wxMenuTracker.
struct wxMenuTracker {
wxMenuTracker(int);
void Replace();
~wxMenuTracker() noexcept;
// Non nullptr members of InitialAndFinal have to be explicitly initially placed
// in the menubar in the frame constructor and explicitly disabled in
// the frame initializer. In the debug build, congruence between the menu bar
// and InitialAndFinal should be checked with assert.
static wxMenu* InitialAndFinal[3];
wxMenuTracker(wxMenuTracker&&) = delete; // Move constructor
wxMenuTracker(const wxMenuTracker&) = delete; // Copy constructor
wxMenuTracker& operator=(wxMenuTracker&&) = delete; // Move assignment.
wxMenuTracker& operator=(const wxMenuTracker&) = delete; // Copy assignment.
bool operator==(const wxMenuTracker&) const = delete;
auto operator<=>(const wxMenuTracker&) const = delete;
wxMenu* Menu;
const int MenuPosition;
// The menu title is defined elsewhere as an array
// of const strings
// menu_strings[MenuPosition].head
};
template <typename T> template <typename T>
// This class exists to record the needed to unbind a drop down menu action and delete // This class exists to record the needed to unbind a drop down menu action and delete
// the corresponding item from the drop down menu when the handler is destroyed. // the corresponding item from the drop down menu when the handler is destroyed.

View File

@ -106,7 +106,7 @@ enum MyIDs {
myID_DELETECONFIG = wxID_HIGHEST + 1, myID_ERRORMESSAGE, myID_Hello, myID_DELETECONFIG = wxID_HIGHEST + 1, myID_ERRORMESSAGE, myID_Hello,
myID_MAINFRAME, myID_MAINFRAME,
myID_MAINFRAME_PANEL, myID_TESTWINDOW, myID_WELCOME_TO_ROCOIN, myID_WALLET_UI, myID_MAINFRAME_PANEL, myID_TESTWINDOW, myID_WELCOME_TO_ROCOIN, myID_WALLET_UI,
mID_CLOSE_WALLET, myID_MYEXIT mID_CLOSE_WALLET, myID_MYEXIT, myID_DISPLAY_WALLET_ADD_NAME
}; };
#include "localization.h" #include "localization.h"

View File

@ -1,12 +1,10 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.0.32014.148 VisualStudioVersion = 17.7.34031.279
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wallet", "msvc\wallet.vcxproj", "{B1EC18D5-FA70-4A59-8CAE-EDC65A358314}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wallet", "msvc\wallet.vcxproj", "{B1EC18D5-FA70-4A59-8CAE-EDC65A358314}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2F7D488C-DC53-4ECE-87E2-4FEA32C153EF}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
@ -22,6 +20,6 @@ Global
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FAF44986-ACA9-4D9B-A9DA-58DBF57EB341} SolutionGuid = {3DB554F1-91C7-4C5D-9A2E-D0EF86D89C18}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal