diff --git a/src/ISqlit3Impl.cpp b/src/ISqlit3Impl.cpp index c42d8e0..6b4d106 100644 --- a/src/ISqlit3Impl.cpp +++ b/src/ISqlit3Impl.cpp @@ -146,8 +146,12 @@ public: else { std::string err(error_message(rc, pdbImplOwn->pdb) + ". Bad destruction of Icompiled_sql"); ILogError(err.c_str()); - // This error should only ever happen if object failed to compile, in which case we have already handled the error - // Hence we do not queue an event to pop up a message, only log the error. (Unless ILogError pops up a message, which it might, but normally does not) + // Finalize must eventually be called on all compiled sql statements, or else we get + // a memory leak. + // This error should only ever happen if something went wrong with this statement earlier, + // in which case we have already handled the error + // Hence we do not queue an event to pop up a message, only log the error. + // (Unless ILogError pops up a message, which it might, but normally does not) } } diff --git a/src/frame.cpp b/src/frame.cpp index 5addfcb..fe9ea89 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +static constexpr char SrcFilename[]{ "src/frame.cpp" }; // ---------------------------------------------------------------------------- // frame @@ -60,6 +61,23 @@ void Frame::StorePositionToConfig() { pConfig->SetPath(wxT("/")); } } +void RecursiveCreateDirectory(wxFileName& fn){ +//Bug workaround, because wxPATH_MKDIR_FULL simply does not work + if (!fn.DirExists()) { + wxFileName parent(fn); + parent.RemoveLastDir(); + RecursiveCreateDirectory(parent); + if (!fn.Mkdir()) + { throw MyException( + std::format( + "Unable to create directory {}", + fn.GetPath().ToUTF8().operator const char* () + ), + __LINE__, __func__, SrcFilename + ); + } + } +} // main frame ctor Frame::Frame(const wxString& wxs) @@ -161,7 +179,8 @@ Frame::Frame(const wxString& wxs) StandardPaths.UseAppInfo(0); StandardPaths.DontIgnoreAppSubDir(); m_DefaultWalletLocation.AssignDir(StandardPaths.GetUserLocalDataDir()); - m_DefaultWalletLocation.AppendDir("wallet"); + m_DefaultWalletLocation.AppendDir(Config.GetVendorName()); + m_DefaultWalletLocation.AppendDir(Config.GetAppName()); m_DefaultWalletLocation.SetFullName("default.wallet"); Config.SetPath(wxT("/FileDialog")); m_FileDialogFilterIndex = Config.Read("index", int(0)); @@ -171,11 +190,19 @@ Frame::Frame(const wxString& wxs) m_LastUsedWallet = m_DefaultWalletLocation; } try { - if (m_LastUsedWallet.IsOk()) + if (m_LastUsedWallet.IsOk() && m_LastUsedWallet.FileExists()) { //Try to load an existing file. panel = new display_wallet(this, m_LastUsedWallet); } else { + if (m_LastUsedWallet != m_DefaultWalletLocation) + { + throw MyException( + std::format( + "Expected wallet file{} not found", + m_LastUsedWallet.GetPath().ToUTF8().operator const char* () + )); + } panel = new welcome_to_rhocoin(this); } @@ -252,6 +279,7 @@ void Frame::OnDeleteConfiguration(wxCommandEvent&) using ro::bin2hex, ro::to_base64_string; void Frame::NewWallet(wxFileName& filename, ristretto255::hash<256>& secret) { + RecursiveCreateDirectory(filename); /*If creation fails, abort with exception. If it succeeds, set LastUsed to default filename. The exception in unit test should simply generate an error message, but if run during initialization, should bring up the more complex UI for constructing or selecting your wallet file.*/ @@ -348,8 +376,15 @@ void Frame::OnSaveNew(wxCommandEvent& WXUNUSED(event)) { wxString wxstrWalletPath; wxString wxstrWalletName(wxEmptyString); - if (m_LastUsedWallet.IsOk())wxstrWalletPath = m_LastUsedWallet.GetPath(); - else wxstrWalletPath = m_DefaultWalletLocation.GetPath(); + if (!m_LastUsedWallet.IsOk() || !m_LastUsedWallet.DirExists()) { + m_LastUsedWallet = m_DefaultWalletLocation; + RecursiveCreateDirectory(m_LastUsedWallet); + } + wxstrWalletPath = m_LastUsedWallet.GetPath(); //Directory guaranteed to exist, so we will not get idiot default + // It took me a ridiculous amount of time to fix that all paths to this file dialog + // are either terminated by an exception, or the directory exists, or is created. + // Any time the program has to deal with something external to itself, anything that can go wrong + // will go wrong. if (!m_LastUsedWallet.FileExists()) wxstrWalletName = m_LastUsedWallet.GetFullName(); wxFileDialog dialog(this, sz_new_wallet_new_secret,