From 35a3be9aa71e9313636e5c96209bed0f567ff898 Mon Sep 17 00:00:00 2001 From: Cheng Date: Fri, 10 Nov 2023 12:00:15 +0000 Subject: [PATCH 1/5] Made a start on amending the code to take advantage of the sqlite view capability VIEW UserZookoIDs Made add_name responsive, but add_name still does not use the VIEW triggers. Got distracted by sizing issues. There is some issues with resizing architecture - I know they put an ad hoc workaround in on dialogs, need to read up on what they did and why. --- src/display_wallet.cpp | 118 +++++++++++++++++++++---------------- src/display_wallet.h | 3 + src/frame.cpp | 84 +++++++++++++------------- src/frame.h | 1 + src/welcome_to_rhocoin.cpp | 1 + 5 files changed, 112 insertions(+), 95 deletions(-) diff --git a/src/display_wallet.cpp b/src/display_wallet.cpp index 5fbdadd..954c880 100644 --- a/src/display_wallet.cpp +++ b/src/display_wallet.cpp @@ -12,10 +12,9 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : walletfile.GetFullPath().append(" does not exist.").ToUTF8(), __LINE__, __func__, SrcFilename); m_db.reset(Sqlite3_open(walletfile.GetFullPath().ToUTF8())); + m_insert_name.reset(new sql_insert_name(m_db)); m_read_from_misc.reset(new sql_read_from_misc(m_db)); - m_read_names_and_keys.reset(new ro::sql(m_db, - R"|(SELECT "Names".name AS name, "Keys".pubkey AS pubkey FROM "Names" INNER JOIN "Keys" )|" - R"|(ON "Names"."ROWID"="Keys".id AND "Keys".use=1 ORDER BY LOWER(name), name COLLATE BINARY;)|")); + m_read_names_and_keys.reset(new ro::sql(m_db, R"|(SELECT * FROM "UserZookoIDs" )|")); if (!(*m_read_from_misc)(1) || m_read_from_misc->value() != WALLET_FILE_IDENTIFIER)throw MyException(sz_unrecognizable_wallet_file_format); if (!(*m_read_from_misc)(2) || m_read_from_misc->value() != WALLET_FILE_SCHEMA_VERSION_0_0 || !(*m_read_from_misc)(4))throw MyException(sz_unrecognized_wallet_schema); m_MasterSecret= *(m_read_from_misc->value()); @@ -24,52 +23,12 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : auto sizer = new wxBoxSizer(wxHORIZONTAL); m_lSizer = new wxBoxSizer(wxVERTICAL); m_rSizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(m_lSizer, 0, wxGROW, 4); - sizer->Add(m_rSizer, 50, wxGROW, 4); + sizer->Add(m_lSizer, 0, 0, 4); + sizer->Add(m_rSizer, 50, 0, 4); SetSizer(sizer); - try { - while (m_read_names_and_keys->step() == Icompiled_sql::ROW) { - std::string name = m_read_names_and_keys->column(0); - auto pubkey = *(m_read_names_and_keys->column(1)); - if (m_MasterSecret(name).timesBase() != pubkey)throw MyException(std::string(sz_public_key_of) + name + sz_fails_to_correspond); - m_lSizer->Add( - new wxStaticText( - this, - wxID_ANY, - name, - wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT | wxST_ELLIPSIZE_END - ), - 10, - wxEXPAND | // make horizontally stretchable - wxALL, // and make border all around - 2); - m_rSizer->Add( - new wxStaticText( - this, - wxID_ANY, - "#" + base58(pubkey).operator std::string(), - wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END - ), - 10, - wxEXPAND | // make horizontally stretchable - wxALL, // and make border all around - 2); - } - } - catch (const MyException& e) { - throw MyException(e, __LINE__, __func__, SrcFilename); - // sql exceptions tend to be unintelligible and excessively generic - // because unclear what statement provoked them. - } - catch (const std::exception& e) { - throw MyException(e, __LINE__, __func__, SrcFilename); - } - catch (...) { - szError = sz_unknown_error; - throw MyException(sz_unknown_error, __LINE__, __func__, SrcFilename); - } - Bind(wxEVT_CLOSE_WINDOW, &display_wallet::OnClose, this); + refresh_from_database(); this->SetSize(this->GetParent()->GetClientSize()); + Bind(wxEVT_CLOSE_WINDOW, &display_wallet::OnClose, this); singletonFrame->m_LastUsedWallet.Assign(walletfile); m_DisplayWalletEditMenu.Menu->Append( @@ -93,8 +52,6 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : szError = sz_unknown_error; throw MyException(sz_unknown_error, __LINE__, __func__, SrcFilename); } - - } display_wallet::~display_wallet() { @@ -114,12 +71,12 @@ and a public key defined by the name and the wallet master secret)", if (dialog.ShowModal() == wxID_OK) { std::string zookoNickname(dialog.GetValue().ToUTF8()); - sql_insert_name insert_name(m_db); auto zookoNickname_psz = zookoNickname.c_str(); - insert_name( + (*m_insert_name)( zookoNickname_psz, m_MasterSecret(zookoNickname_psz).timesBase() ); + refresh_from_database(); } } @@ -134,3 +91,62 @@ void display_wallet::OnClose(wxCloseEvent& event) { if (singletonFrame->m_panel ==this)singletonFrame->m_panel = nullptr; } + +void display_wallet::refresh_from_database() { + auto sizer = this->GetSizer(); + auto m_lsizer = sizer->GetItem((size_t)0)->GetSizer(); + assert(m_lsizer); + auto m_rsizer = sizer->GetItem(1)->GetSizer(); + assert(m_rsizer); + m_lsizer->Clear(); + m_rsizer->Clear(); + try { + m_read_names_and_keys->reset(); + while (m_read_names_and_keys->step() == Icompiled_sql::ROW) { + std::string name = m_read_names_and_keys->column(0); + auto pubkey = *(m_read_names_and_keys->column(1)); + if (m_MasterSecret(name).timesBase() != pubkey)throw MyException(std::string(sz_public_key_of) + name + sz_fails_to_correspond); + m_lSizer->Add( + new wxStaticText( + this, + wxID_ANY, + name, + wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT | wxST_ELLIPSIZE_END + ), + 10, + wxALL, // and make border all around + 2); + m_rSizer->Add( + new wxStaticText( + this, + wxID_ANY, + "#" + base58(pubkey).operator std::string(), + wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END + ), + 10, + wxALL, // and make border all around + 2); + } + } + catch (const MyException& e) { + throw MyException(e, __LINE__, __func__, SrcFilename); + // sql exceptions tend to be unintelligible and excessively generic + // because unclear what statement provoked them. + } + catch (const std::exception& e) { + throw MyException(e, __LINE__, __func__, SrcFilename); + } + catch (...) { + szError = sz_unknown_error; + throw MyException(sz_unknown_error, __LINE__, __func__, SrcFilename); + } + auto desired_size = sizer->ComputeFittingClientSize(singletonFrame); + singletonFrame->SetMinClientSize(desired_size); + auto clientSize = singletonFrame->GetClientSize(); + desired_size.IncTo(clientSize); + if (desired_size.GetHeight() > clientSize.GetHeight() + || desired_size.GetWidth() > clientSize.GetWidth() + )singletonFrame->SetClientSize(desired_size); + + +} diff --git a/src/display_wallet.h b/src/display_wallet.h index 0080c5e..1573bc6 100644 --- a/src/display_wallet.h +++ b/src/display_wallet.h @@ -9,6 +9,8 @@ private: std::unique_ptr m_db; std::unique_ptr m_read_from_misc; std::unique_ptr m_read_names_and_keys; + std::unique_ptr m_insert_name; + ristretto255::CMasterSecret m_MasterSecret; wxBoxSizer* m_lSizer; wxBoxSizer* m_rSizer; @@ -16,4 +18,5 @@ private: void add_name_event_handler(wxCommandEvent&); void OnClose(wxCloseEvent& event); wxMenuTracker m_DisplayWalletEditMenu; + void refresh_from_database(); }; diff --git a/src/frame.cpp b/src/frame.cpp index 2ac8cb9..ab63b07 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -10,27 +10,50 @@ 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. + auto menuBar = singletonFrame->GetMenuBar(); + if ((menuBar->GetMenu(MenuPosition) != Menu)) { + menuBar->Replace( + MenuPosition, + Menu, + menu_strings[MenuPosition].head + ); + menuBar->EnableTop(MenuPosition, true); //enable edit menu. + } }; wxMenuTracker::~wxMenuTracker() { - auto menu_bar = singletonFrame->GetMenuBar(); - if (menu_bar->GetMenu(MenuPosition) == Menu) { + auto menuBar = singletonFrame->GetMenuBar(); + if (menuBar->GetMenu(MenuPosition) == Menu) { assert(InitialAndFinal[MenuPosition]); - menu_bar->Replace( + menuBar->Replace( MenuPosition, InitialAndFinal[MenuPosition], menu_strings[MenuPosition].head ); - menu_bar->EnableTop(MenuPosition, false); + menuBar->EnableTop(MenuPosition, false); delete Menu; } }; +void wxMenuTracker::check_dynamic_menus_absent() { + if constexpr (debug_mode) { + // Check that the values of all replaceable menus + // are at their default values as if the window handling them + // had just been destroyed and not yet replaced. + auto menuBar = singletonFrame->GetMenuBar(); + for (int i = 0; i < std::size(InitialAndFinal); i++) { + assert( + !InitialAndFinal[i] + || + ( + InitialAndFinal[i] == menuBar->GetMenu(i) + && + !menuBar->IsEnabledTop(i) + ) + ); + } + } +} + // ---------------------------------------------------------------------------- // frame // ---------------------------------------------------------------------------- @@ -199,21 +222,10 @@ Frame::Frame(const wxString& wxs) SetMenuBar(menuBar); menuBar->EnableTop(1, false); //disable edit menu. 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) - ) - ); - - } + wxMenuTracker::check_dynamic_menus_absent(); + // Because the initial values of the dynamic menus are not being deleted by the child windows + // that own the modified windows, they need to be the same as the final values, + // which is to say, the values in wxMenuTracker::InitialAndFinal[] } CreateStatusBar(); // child controls @@ -374,8 +386,7 @@ SELECT "Keys".pubkey AS pubkey FROM "Names" INNER JOIN "Keys" ON "Names"."ROWID"="Keys"."id" AND "Keys"."use"=1 -ORDER BY LOWER("name"), "name" -COLLATE BINARY; +ORDER BY LOWER("name"), "name" COLLATE BINARY; COMMIT; BEGIN IMMEDIATE TRANSACTION; @@ -555,7 +566,6 @@ void Frame::OnMenuOpen(wxMenuEvent& evt) { Frame::~Frame() { assert(singletonFrame == this); - singletonFrame = nullptr; wxConfigBase& Config = singletonApp->m_Config; StorePositionToConfig(); Config.SetPath(wxT("/TipOfTheDay")); @@ -567,21 +577,7 @@ Frame::~Frame() { Config.SetPath(wxT("/")); 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) - ) - ); - - } + wxMenuTracker::check_dynamic_menus_absent(); } + singletonFrame = nullptr; } diff --git a/src/frame.h b/src/frame.h index 40800b5..d882faf 100644 --- a/src/frame.h +++ b/src/frame.h @@ -21,6 +21,7 @@ struct wxMenuTracker { // the frame initializer. In the debug build, congruence between the menu bar // and InitialAndFinal should be checked with assert. static wxMenu* InitialAndFinal[3]; + static void check_dynamic_menus_absent(); wxMenuTracker(wxMenuTracker&&) = delete; // Move constructor wxMenuTracker(const wxMenuTracker&) = delete; // Copy constructor wxMenuTracker& operator=(wxMenuTracker&&) = delete; // Move assignment. diff --git a/src/welcome_to_rhocoin.cpp b/src/welcome_to_rhocoin.cpp index 449c39d..b03bbcb 100644 --- a/src/welcome_to_rhocoin.cpp +++ b/src/welcome_to_rhocoin.cpp @@ -138,6 +138,7 @@ welcome_to_rhocoin::welcome_to_rhocoin( Bind(wxEVT_CLOSE_WINDOW, &welcome_to_rhocoin::OnClose, this); assert(singletonWelcome == nullptr); singletonWelcome = this; + singletonFrame->SetMinClientSize(sizer->ComputeFittingClientSize(singletonFrame)); } welcome_to_rhocoin::~welcome_to_rhocoin() { From f819b98d9ef14f13e3a6c6c2399c9ac39953fba2 Mon Sep 17 00:00:00 2001 From: Cheng Date: Sat, 11 Nov 2023 02:10:36 +0000 Subject: [PATCH 2/5] window refreshed on add username but the overhead and screen flash of destroying and recreating every little window is annoying. I should use something like: SELECT COUNT(*) FROM UserZookoIDs WHERE LOWER("name")& p) : sql_insert_name(p.get()) {} void operator()(const char* psz, const ristretto255::point& pt) { - csql_begin.do_one(); - try { - csql_into_names.do_one(psz); - csql_namekey_into_keys.do_one(pt); - } - catch (const MyException& e) { - csql_rollback.do_one(); - if (e.what_num() == 19) { - throw MyException("Name already in database"); - } - else { - throw; - } - } - catch (const std::exception &) { - csql_rollback.do_one(); - throw; - } - csql_commit.do_one(); + csql_into_names.do_one(psz,pt); } }; @@ -234,7 +202,5 @@ public: } }; - - constexpr auto WALLET_FILE_IDENTIFIER (0x56d34bc5a655dd1fi64); constexpr auto WALLET_FILE_SCHEMA_VERSION_0_0(1); diff --git a/src/display_wallet.cpp b/src/display_wallet.cpp index 954c880..0a3ee71 100644 --- a/src/display_wallet.cpp +++ b/src/display_wallet.cpp @@ -94,12 +94,13 @@ void display_wallet::OnClose(wxCloseEvent& event) { void display_wallet::refresh_from_database() { auto sizer = this->GetSizer(); + auto dirty_area = sizer->ComputeFittingClientSize(singletonFrame); auto m_lsizer = sizer->GetItem((size_t)0)->GetSizer(); assert(m_lsizer); auto m_rsizer = sizer->GetItem(1)->GetSizer(); assert(m_rsizer); - m_lsizer->Clear(); - m_rsizer->Clear(); + m_lsizer->Clear(true); + m_rsizer->Clear(true); try { m_read_names_and_keys->reset(); while (m_read_names_and_keys->step() == Icompiled_sql::ROW) { @@ -111,7 +112,7 @@ void display_wallet::refresh_from_database() { this, wxID_ANY, name, - wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT | wxST_ELLIPSIZE_END + wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT | wxEXPAND| wxFIXED_MINSIZE| wxST_ELLIPSIZE_END ), 10, wxALL, // and make border all around @@ -121,7 +122,7 @@ void display_wallet::refresh_from_database() { this, wxID_ANY, "#" + base58(pubkey).operator std::string(), - wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxST_ELLIPSIZE_END + wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxEXPAND | wxFIXED_MINSIZE | wxST_ELLIPSIZE_END ), 10, wxALL, // and make border all around @@ -141,12 +142,11 @@ void display_wallet::refresh_from_database() { throw MyException(sz_unknown_error, __LINE__, __func__, SrcFilename); } auto desired_size = sizer->ComputeFittingClientSize(singletonFrame); - singletonFrame->SetMinClientSize(desired_size); + dirty_area.IncTo(desired_size); + //singletonFrame->SetMinClientSize(desired_size); auto clientSize = singletonFrame->GetClientSize(); desired_size.IncTo(clientSize); if (desired_size.GetHeight() > clientSize.GetHeight() || desired_size.GetWidth() > clientSize.GetWidth() )singletonFrame->SetClientSize(desired_size); - - } diff --git a/src/frame.cpp b/src/frame.cpp index ab63b07..4ae63cf 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -391,11 +391,11 @@ COMMIT; BEGIN IMMEDIATE TRANSACTION; CREATE TRIGGER InsertUserZookoID INSTEAD OF INSERT ON UserZookoIDs FOR EACH ROW BEGIN - INSERT OR FAIL INTO "Names" VALUES( + INSERT OR ROLLBACK INTO "Names" VALUES( NULL, NEW."name" ); - INSERT OR FAIL INTO "Keys" VALUES( + INSERT OR ROLLBACK INTO "Keys" VALUES( NULL, NEW."pubkey", last_insert_rowid(), From ffa392b92221b8e22449b669c476e3658396dec6 Mon Sep 17 00:00:00 2001 From: Cheng Date: Sat, 11 Nov 2023 22:27:59 +0000 Subject: [PATCH 3/5] removed a the redundantly explicit std::uniques from display_wallet.h and display_wallet.cpp They are now all wrapped in the long promised and long forgotten wrapper class. Long, long ago, I intended to implement the Pimpl idiom, but these days std::unique takes care of all that work for you. You just wrap your low level pimple class in a high level wrapper whose base class is an std_unique_ptr to to an instance of your low level class. --- msvc/wallet.vcxproj | 1 + src/ISqlite3.h | 9 +-------- src/db_accessors.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++ src/db_accessors.h | 31 ++++++++++++++++++++++------- src/display_wallet.cpp | 28 +++++++++++--------------- src/display_wallet.h | 7 ++++--- 6 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 src/db_accessors.cpp diff --git a/msvc/wallet.vcxproj b/msvc/wallet.vcxproj index d4424b6..c4f4483 100644 --- a/msvc/wallet.vcxproj +++ b/msvc/wallet.vcxproj @@ -150,6 +150,7 @@ + diff --git a/src/ISqlite3.h b/src/ISqlite3.h index 87a2750..4c31833 100644 --- a/src/ISqlite3.h +++ b/src/ISqlite3.h @@ -1,13 +1,8 @@ #pragma once #include "ILog.h" -// this is pure virtual interface base class between sqlite3, which speaks only C and utf8 char[] +// this is an interface base class between sqlite3, which speaks only C and utf8 char[] // and wxWidgets which speaks only C++ and unicode strings. -// Usage: Call the factory function std::shared_ptr sqlite3_open(const char *) to get a shared -// pointer to the // Sqlite3 database object. Then call the factory function -// sqlite3_prepare(std::shared_ptr, const char *) to get a unique pointer to -// a compiled SQL statement - // Its primary purpose is to avoid code that needs both the wxWidgets header files, // and the sqlite3.h header file. // @@ -25,8 +20,6 @@ // substantially more difficult in C++14, because one is effectively rolling one's own // unique pointer. // -// It is therefore easier to implement a pure virtual base class with a virtual destructor and -// factory function that returns a smart pointer to a member of the derived implementation // /* This code is at a low level abstraction, because it provides low level C++ interface to inherently low level C It is intended to be wrapped in higher level code that does not know about the nuts and bolts of sqlite3, but which supports throwing, templated functions, and all that.*/ diff --git a/src/db_accessors.cpp b/src/db_accessors.cpp new file mode 100644 index 0000000..c076ef9 --- /dev/null +++ b/src/db_accessors.cpp @@ -0,0 +1,45 @@ +#include "stdafx.h" +namespace ro { + static constexpr char SrcFilename[]{ "src/db_accessors.cpp" }; + + dbconnect::dbconnect(const wxFileName& filename) { + if (!filename.IsOk() || !filename.HasName() || !filename.HasExt()) throw + MyException("unexpected file name", __LINE__, __func__, SrcFilename); + if (!filename.FileExists())throw MyException( + std::string(filename.GetFullPath().ToUTF8()) + " does not exist.", + __LINE__, __func__, SrcFilename); + this->reset(Sqlite3_open(filename.GetFullPath().ToUTF8())); + } + + // move constructor + dbconnect::dbconnect(dbconnect&& p) noexcept :std::unique_ptr(p.release()) { + } + + // Move assignment + dbconnect& dbconnect::operator=(dbconnect&& p) noexcept { + std::unique_ptr::reset(p.release()); + return *this; + } + + sql::sql(const std::unique_ptr& p, const char* sz) : + std::unique_ptr(sqlite3_prepare(p.get(), sz)) { + } + + // move constructor + sql::sql(sql&& p) noexcept :std::unique_ptr(p.release()) { + } + + // Move assignment + sql& sql::operator=(sql&& p) noexcept { + std::unique_ptr::reset(p.release()); + return *this; + } + + sql::sql(Icompiled_sql* p) : + std::unique_ptr(p) { + } + + sql::sql(std::unique_ptr&& p) : + std::unique_ptr(p.release()) { + } +} \ No newline at end of file diff --git a/src/db_accessors.h b/src/db_accessors.h index 4091fda..6a1f4a1 100644 --- a/src/db_accessors.h +++ b/src/db_accessors.h @@ -15,26 +15,43 @@ namespace ro { static_assert(is_sqlite3_field_type::value); + //Owns a database connection and closes it when it is deconstructed + //Has move semantics + class dbconnect : public std::unique_ptr { + public: + dbconnect(const wxFileName&); //And here we wrap our Cish implementation in C++ish implementation + dbconnect() = delete; + ~dbconnect() = default; //Our base class takes care of it + // copy constructor + dbconnect(const dbconnect& a) = delete; //Move semantics + // move constructor + dbconnect(dbconnect&& p) noexcept; + // copy assignment + dbconnect& operator=(const dbconnect) = delete; //Move semantics + // Move assignment + dbconnect& operator=(dbconnect&& p) noexcept; + }; + //Owns a compiled sql statement and destroys it when it is deconstructed. //Has move semantics. class sql : public std::unique_ptr { public: class monostate {}; + sql() = delete; sql(ISqlite3* p, const char* sz) :std::unique_ptr(sqlite3_prepare(p, sz)) {} - sql(const std::unique_ptr& p, const char* sz) :std::unique_ptr(sqlite3_prepare(p.get(), sz)) {} + sql(const std::unique_ptr& p, const char* sz); // copy constructor sql(const sql& a) = delete; // move constructor - sql(sql&& p) noexcept :std::unique_ptr(p.release()) { } + sql(sql&& p) noexcept; // copy assignment sql& operator=(const sql) = delete; // Move assignment - sql& operator=(sql&& p) noexcept { - std::unique_ptr::reset(p.release()); - } - sql(Icompiled_sql* p) :std::unique_ptr(p) {} - sql(std::unique_ptr&& p) :std::unique_ptr(p.release()) { } + sql& operator=(sql&& p) noexcept; + sql(Icompiled_sql* p); + sql(std::unique_ptr&& p); ~sql() = default; + template auto column(int i) const { if constexpr (ro::blob_type) { auto st = (*this)->Isqlite3_column_blob(i); diff --git a/src/display_wallet.cpp b/src/display_wallet.cpp index 0a3ee71..f11dbaa 100644 --- a/src/display_wallet.cpp +++ b/src/display_wallet.cpp @@ -1,23 +1,19 @@ #include "stdafx.h" using ro::base58; static constexpr char SrcFilename[]{ "src/display_wallet.cpp" }; + display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : wxPanel(parent, myID_WALLET_UI, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, wxT("Wallet")), - m_db(nullptr), m_DisplayWalletEditMenu(1) + m_db(walletfile), m_DisplayWalletEditMenu(1), + m_read_names_and_keys(m_db, R"|(SELECT * FROM "UserZookoIDs"; )|"), + m_read_from_misc(m_db), + m_find_position(m_db, R"|( SELECT COUNT(*) FROM UserZookoIDs WHERE LOWER("name")value() != WALLET_FILE_IDENTIFIER)throw MyException(sz_unrecognizable_wallet_file_format); - if (!(*m_read_from_misc)(2) || m_read_from_misc->value() != WALLET_FILE_SCHEMA_VERSION_0_0 || !(*m_read_from_misc)(4))throw MyException(sz_unrecognized_wallet_schema); - m_MasterSecret= *(m_read_from_misc->value()); + if (!m_read_from_misc(1) || m_read_from_misc.value() != WALLET_FILE_IDENTIFIER)throw MyException(sz_unrecognizable_wallet_file_format); + if (!m_read_from_misc(2) || m_read_from_misc.value() != WALLET_FILE_SCHEMA_VERSION_0_0 || !m_read_from_misc(4))throw MyException(sz_unrecognized_wallet_schema); + m_MasterSecret= *(m_read_from_misc.value()); ILogMessage(std::format("\t\tmaster secret: #{}", ro::base58(m_MasterSecret).operator const char* ()).c_str()); if(!m_MasterSecret.valid()) throw MyException(sz_cold_wallets_not_yet_implemented, __LINE__, __func__, SrcFilename); auto sizer = new wxBoxSizer(wxHORIZONTAL); @@ -102,10 +98,10 @@ void display_wallet::refresh_from_database() { m_lsizer->Clear(true); m_rsizer->Clear(true); try { - m_read_names_and_keys->reset(); - while (m_read_names_and_keys->step() == Icompiled_sql::ROW) { - std::string name = m_read_names_and_keys->column(0); - auto pubkey = *(m_read_names_and_keys->column(1)); + m_read_names_and_keys.reset(); + while (m_read_names_and_keys.step() == Icompiled_sql::ROW) { + std::string name = m_read_names_and_keys.column(0); + auto pubkey = *(m_read_names_and_keys.column(1)); if (m_MasterSecret(name).timesBase() != pubkey)throw MyException(std::string(sz_public_key_of) + name + sz_fails_to_correspond); m_lSizer->Add( new wxStaticText( diff --git a/src/display_wallet.h b/src/display_wallet.h index 1573bc6..3461ee4 100644 --- a/src/display_wallet.h +++ b/src/display_wallet.h @@ -6,10 +6,11 @@ public: ~display_wallet(); private: typedef MenuLink MenuLink; - std::unique_ptr m_db; - std::unique_ptr m_read_from_misc; - std::unique_ptr m_read_names_and_keys; + ro::dbconnect m_db; + sql_read_from_misc m_read_from_misc; + ro::sql m_read_names_and_keys; std::unique_ptr m_insert_name; + ro::sql m_find_position; ristretto255::CMasterSecret m_MasterSecret; wxBoxSizer* m_lSizer; From 55d0d69c8f7151b4279683269fcdea076a9c1b9e Mon Sep 17 00:00:00 2001 From: Cheng Date: Sun, 12 Nov 2023 03:56:47 +0000 Subject: [PATCH 4/5] removed redundant std_uniques, and fixed add name so it does not flash so horribly Massively violating dry - I need to extract the repeated code into a struct that does the cleanup when it is destroyed --- src/db_accessors.h | 5 ++--- src/display_wallet.cpp | 48 ++++++++++++++++++++++++++++++++++++++---- src/display_wallet.h | 2 +- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/db_accessors.h b/src/db_accessors.h index 6a1f4a1..9759d42 100644 --- a/src/db_accessors.h +++ b/src/db_accessors.h @@ -17,8 +17,7 @@ namespace ro { //Owns a database connection and closes it when it is deconstructed //Has move semantics - class dbconnect : public std::unique_ptr { - public: + struct dbconnect : std::unique_ptr { dbconnect(const wxFileName&); //And here we wrap our Cish implementation in C++ish implementation dbconnect() = delete; ~dbconnect() = default; //Our base class takes care of it @@ -200,7 +199,7 @@ class sql_insert_name { ro::sql csql_into_names; public: sql_insert_name(ISqlite3* p) : - csql_into_names(p, R"|(INSERT OR FAIL INTO "UserZookoIDs" VALUES(?1, ?2);)|"){} + csql_into_names(p, R"|(INSERT OR FAIL INTO "UserZookoIDs" VALUES(?1, ?2);)|"){} sql_insert_name(const std::unique_ptr& p) : sql_insert_name(p.get()) {} void operator()(const char* psz, const ristretto255::point& pt) { csql_into_names.do_one(psz,pt); diff --git a/src/display_wallet.cpp b/src/display_wallet.cpp index f11dbaa..5f0ac60 100644 --- a/src/display_wallet.cpp +++ b/src/display_wallet.cpp @@ -7,7 +7,9 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : m_db(walletfile), m_DisplayWalletEditMenu(1), m_read_names_and_keys(m_db, R"|(SELECT * FROM "UserZookoIDs"; )|"), m_read_from_misc(m_db), - m_find_position(m_db, R"|( SELECT COUNT(*) FROM UserZookoIDs WHERE LOWER("name")GetSizer(); + auto dirty_area = sizer->ComputeFittingClientSize(singletonFrame); + auto m_lsizer = sizer->GetItem((size_t)0)->GetSizer(); + assert(m_lsizer); + auto m_rsizer = sizer->GetItem(1)->GetSizer(); + assert(m_rsizer); + auto position = m_find_position.column(0); + m_lSizer->Insert(position, + new wxStaticText( + this, + wxID_ANY, + zookoNickname_psz, + wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT | wxEXPAND | wxFIXED_MINSIZE | wxST_ELLIPSIZE_END + ), + 10, + wxALL, // and make border all around + 2); + m_rSizer->Insert(position, + new wxStaticText( + this, + wxID_ANY, + "#" + base58(pubkey).operator std::string(), + wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT | wxEXPAND | wxFIXED_MINSIZE | wxST_ELLIPSIZE_END + ), + 10, + wxALL, // and make border all around + 2); + + auto desired_size = sizer->ComputeFittingClientSize(singletonFrame); + dirty_area.IncTo(desired_size); + //singletonFrame->SetMinClientSize(desired_size); + auto clientSize = singletonFrame->GetClientSize(); + desired_size.IncTo(clientSize); + if (desired_size.GetHeight() > clientSize.GetHeight() + || desired_size.GetWidth() > clientSize.GetWidth() + )singletonFrame->SetClientSize(desired_size); } + } diff --git a/src/display_wallet.h b/src/display_wallet.h index 3461ee4..5328328 100644 --- a/src/display_wallet.h +++ b/src/display_wallet.h @@ -9,7 +9,7 @@ private: ro::dbconnect m_db; sql_read_from_misc m_read_from_misc; ro::sql m_read_names_and_keys; - std::unique_ptr m_insert_name; + sql_insert_name m_insert_name; ro::sql m_find_position; ristretto255::CMasterSecret m_MasterSecret; From c65f2fbf6edab3e642ff895bc5877d4455d65242 Mon Sep 17 00:00:00 2001 From: Cheng Date: Sun, 12 Nov 2023 04:44:17 +0000 Subject: [PATCH 5/5] Cleaned up the add name on the dry prinicple fixed bug in the position of the inserted name that happened with names identical except for capitalization. --- src/display_wallet.cpp | 68 ++++++++++++++++++++++-------------------- src/display_wallet.h | 1 + 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/display_wallet.cpp b/src/display_wallet.cpp index 5f0ac60..b1dbacf 100644 --- a/src/display_wallet.cpp +++ b/src/display_wallet.cpp @@ -9,7 +9,7 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : m_read_from_misc(m_db), m_insert_name(m_db), m_find_position(m_db, R"|( SELECT COUNT(*) FROM UserZookoIDs -WHERE LOWER("name")GetSizer()), + dirty_area(sizer->ComputeFittingClientSize(singletonFrame)) + { + assert(sizer); + } + ~cleanup() { + auto desired_size = sizer->ComputeFittingClientSize(singletonFrame); + dirty_area.IncTo(desired_size); + //singletonFrame->SetMinClientSize(desired_size); + auto clientSize = singletonFrame->GetClientSize(); + desired_size.IncTo(clientSize); + if (desired_size.GetHeight() > clientSize.GetHeight() + || desired_size.GetWidth() > clientSize.GetWidth() + )singletonFrame->SetClientSize(desired_size); + } +}; + void display_wallet::add_name_event_handler(wxCommandEvent& event) { wxTextEntryDialog dialog(this, R"("A Zooko name has a human readable name, @@ -76,13 +109,8 @@ and a public key defined by the name and the wallet master secret)", pubkey ); m_find_position.read_one(zookoNickname_psz); - auto sizer = this->GetSizer(); - auto dirty_area = sizer->ComputeFittingClientSize(singletonFrame); - auto m_lsizer = sizer->GetItem((size_t)0)->GetSizer(); - assert(m_lsizer); - auto m_rsizer = sizer->GetItem(1)->GetSizer(); - assert(m_rsizer); auto position = m_find_position.column(0); + cleanup cln(this); m_lSizer->Insert(position, new wxStaticText( this, @@ -103,15 +131,6 @@ and a public key defined by the name and the wallet master secret)", 10, wxALL, // and make border all around 2); - - auto desired_size = sizer->ComputeFittingClientSize(singletonFrame); - dirty_area.IncTo(desired_size); - //singletonFrame->SetMinClientSize(desired_size); - auto clientSize = singletonFrame->GetClientSize(); - desired_size.IncTo(clientSize); - if (desired_size.GetHeight() > clientSize.GetHeight() - || desired_size.GetWidth() > clientSize.GetWidth() - )singletonFrame->SetClientSize(desired_size); } } @@ -129,14 +148,7 @@ void display_wallet::OnClose(wxCloseEvent& event) { } void display_wallet::refresh_from_database() { - auto sizer = this->GetSizer(); - auto dirty_area = sizer->ComputeFittingClientSize(singletonFrame); - auto m_lsizer = sizer->GetItem((size_t)0)->GetSizer(); - assert(m_lsizer); - auto m_rsizer = sizer->GetItem(1)->GetSizer(); - assert(m_rsizer); - m_lsizer->Clear(true); - m_rsizer->Clear(true); + cleanup cln(this); try { m_read_names_and_keys.reset(); while (m_read_names_and_keys.step() == Icompiled_sql::ROW) { @@ -177,12 +189,4 @@ void display_wallet::refresh_from_database() { szError = sz_unknown_error; throw MyException(sz_unknown_error, __LINE__, __func__, SrcFilename); } - auto desired_size = sizer->ComputeFittingClientSize(singletonFrame); - dirty_area.IncTo(desired_size); - //singletonFrame->SetMinClientSize(desired_size); - auto clientSize = singletonFrame->GetClientSize(); - desired_size.IncTo(clientSize); - if (desired_size.GetHeight() > clientSize.GetHeight() - || desired_size.GetWidth() > clientSize.GetWidth() - )singletonFrame->SetClientSize(desired_size); } diff --git a/src/display_wallet.h b/src/display_wallet.h index 5328328..7290518 100644 --- a/src/display_wallet.h +++ b/src/display_wallet.h @@ -5,6 +5,7 @@ public: display_wallet(wxWindow*, wxFileName&); ~display_wallet(); private: + struct cleanup; typedef MenuLink MenuLink; ro::dbconnect m_db; sql_read_from_misc m_read_from_misc;