From 0facccdb16af1da339ca5cde892b1fd7279af153 Mon Sep 17 00:00:00 2001 From: aiekick Date: Wed, 19 Jun 2024 21:59:07 +0200 Subject: [PATCH] [RFR] : Refactor the Transactions Table --- src/Frontend/Tables/CategoriesTable.cpp | 8 +- src/Frontend/Tables/CategoriesTable.h | 10 +- src/Frontend/Tables/EntitiesTable.cpp | 8 +- src/Frontend/Tables/EntitiesTable.h | 10 +- src/Frontend/Tables/OperationsTable.cpp | 8 +- src/Frontend/Tables/OperationsTable.h | 10 +- src/Frontend/Tables/TransactionsTable.cpp | 617 +++++++++++++- src/Frontend/Tables/TransactionsTable.h | 87 +- src/Frontend/Tables/abstract/ADataTable.cpp | 30 +- src/Frontend/Tables/abstract/ADataTable.h | 19 +- src/Headers/CashMeBuild.h | 4 +- src/Panes/AccountPane.cpp | 897 ++------------------ src/Panes/AccountPane.h | 95 +-- 13 files changed, 822 insertions(+), 981 deletions(-) diff --git a/src/Frontend/Tables/CategoriesTable.cpp b/src/Frontend/Tables/CategoriesTable.cpp index 040e990..413a755 100644 --- a/src/Frontend/Tables/CategoriesTable.cpp +++ b/src/Frontend/Tables/CategoriesTable.cpp @@ -18,7 +18,7 @@ void CategoriesTable::unload() { } bool CategoriesTable::drawMenu() { - if (ADataTable::drawMenu()) { + if (m_drawAccountMenu()) { m_updateCategories(); return true; } @@ -36,7 +36,7 @@ RowID CategoriesTable::m_getItemRowID(const size_t& vIdx) const { return 0; // the db row id cant be 0 } -double CategoriesTable::m_getItemAmount(const size_t& vIdx) const { +double CategoriesTable::m_getItemBarAmount(const size_t& vIdx) const { return m_Categories.at(vIdx).amount; } @@ -46,7 +46,7 @@ void CategoriesTable::m_drawTableContent(const size_t& vIdx, const double& vMaxA m_drawColumnDebit(e.debit); m_drawColumnCredit(e.credit); m_drawColumnAmount(e.amount); - m_drawColumnBars(e.amount, vMaxAmount); + m_drawColumnBars(e.amount, vMaxAmount, 100.0f); } void CategoriesTable::m_setupColumns() { @@ -63,7 +63,7 @@ void CategoriesTable::m_drawContextMenuContent() { CTOOL_DEBUG_BREAK; } -void CategoriesTable::m_doActionOnDblClick() { +void CategoriesTable::m_doActionOnDblClick(const size_t& vIdx, const RowID& vRowID) { CTOOL_DEBUG_BREAK; } diff --git a/src/Frontend/Tables/CategoriesTable.h b/src/Frontend/Tables/CategoriesTable.h index a490c2b..2545cf3 100644 --- a/src/Frontend/Tables/CategoriesTable.h +++ b/src/Frontend/Tables/CategoriesTable.h @@ -10,18 +10,18 @@ class CategoriesTable : public ADataTable { CategoriesTable(); ~CategoriesTable(); - bool load(); - void unload(); - bool drawMenu(); + bool load() final; + void unload() final; + bool drawMenu() final; protected: size_t m_getItemsCount() const final; RowID m_getItemRowID(const size_t& vIdx) const final; - double m_getItemAmount(const size_t& vIdx) const final; + double m_getItemBarAmount(const size_t& vIdx) const final; void m_drawTableContent(const size_t& vIdx, const double& vMaxAmount) final; void m_setupColumns() final; void m_drawContextMenuContent() final; - void m_doActionOnDblClick() final; + void m_doActionOnDblClick(const size_t& vIdx, const RowID& vRowID) final; private: void m_updateCategories(); diff --git a/src/Frontend/Tables/EntitiesTable.cpp b/src/Frontend/Tables/EntitiesTable.cpp index 284345e..b48fc25 100644 --- a/src/Frontend/Tables/EntitiesTable.cpp +++ b/src/Frontend/Tables/EntitiesTable.cpp @@ -18,7 +18,7 @@ void EntitiesTable::unload() { } bool EntitiesTable::drawMenu() { - if (ADataTable::drawMenu()) { + if (m_drawAccountMenu()) { m_updateEntities(); return true; } @@ -36,7 +36,7 @@ RowID EntitiesTable::m_getItemRowID(const size_t& vIdx) const { return 0; // the db row id cant be 0 } -double EntitiesTable::m_getItemAmount(const size_t& vIdx) const { +double EntitiesTable::m_getItemBarAmount(const size_t& vIdx) const { return m_Entities.at(vIdx).amount; } @@ -46,7 +46,7 @@ void EntitiesTable::m_drawTableContent(const size_t& vIdx, const double& vMaxAmo m_drawColumnDebit(e.debit); m_drawColumnCredit(e.credit); m_drawColumnAmount(e.amount); - m_drawColumnBars(e.amount, vMaxAmount); + m_drawColumnBars(e.amount, vMaxAmount, 100.0f); } void EntitiesTable::m_setupColumns() { @@ -63,7 +63,7 @@ void EntitiesTable::m_drawContextMenuContent() { CTOOL_DEBUG_BREAK; } -void EntitiesTable::m_doActionOnDblClick() { +void EntitiesTable::m_doActionOnDblClick(const size_t& vIdx, const RowID& vRowID) { CTOOL_DEBUG_BREAK; } diff --git a/src/Frontend/Tables/EntitiesTable.h b/src/Frontend/Tables/EntitiesTable.h index 4712c9a..aa7fe03 100644 --- a/src/Frontend/Tables/EntitiesTable.h +++ b/src/Frontend/Tables/EntitiesTable.h @@ -10,18 +10,18 @@ class EntitiesTable : public ADataTable { EntitiesTable(); ~EntitiesTable(); - bool load(); - void unload(); - bool drawMenu(); + bool load() final; + void unload() final; + bool drawMenu() final; protected: size_t m_getItemsCount() const final; RowID m_getItemRowID(const size_t& vIdx) const final; - double m_getItemAmount(const size_t& vIdx) const final; + double m_getItemBarAmount(const size_t& vIdx) const final; void m_drawTableContent(const size_t& vIdx, const double& vMaxAmount) final; void m_setupColumns() final; void m_drawContextMenuContent() final; - void m_doActionOnDblClick() final; + void m_doActionOnDblClick(const size_t& vIdx, const RowID& vRowID) final; private: void m_updateEntities(); diff --git a/src/Frontend/Tables/OperationsTable.cpp b/src/Frontend/Tables/OperationsTable.cpp index babfeed..b773b62 100644 --- a/src/Frontend/Tables/OperationsTable.cpp +++ b/src/Frontend/Tables/OperationsTable.cpp @@ -18,7 +18,7 @@ void OperationsTable::unload() { } bool OperationsTable::drawMenu() { - if (ADataTable::drawMenu()) { + if (m_drawAccountMenu()) { m_updateOperations(); return true; } @@ -36,7 +36,7 @@ RowID OperationsTable::m_getItemRowID(const size_t& vIdx) const { return 0; // the db row id cant be 0 } -double OperationsTable::m_getItemAmount(const size_t& vIdx) const { +double OperationsTable::m_getItemBarAmount(const size_t& vIdx) const { return m_Operations.at(vIdx).amount; } @@ -46,7 +46,7 @@ void OperationsTable::m_drawTableContent(const size_t& vIdx, const double& vMaxA m_drawColumnDebit(e.debit); m_drawColumnCredit(e.credit); m_drawColumnAmount(e.amount); - m_drawColumnBars(e.amount, vMaxAmount); + m_drawColumnBars(e.amount, vMaxAmount, 100.0f); } void OperationsTable::m_setupColumns() { @@ -63,7 +63,7 @@ void OperationsTable::m_drawContextMenuContent() { CTOOL_DEBUG_BREAK; } -void OperationsTable::m_doActionOnDblClick() { +void OperationsTable::m_doActionOnDblClick(const size_t& vIdx, const RowID& vRowID) { CTOOL_DEBUG_BREAK; } diff --git a/src/Frontend/Tables/OperationsTable.h b/src/Frontend/Tables/OperationsTable.h index ba9a4f6..5812557 100644 --- a/src/Frontend/Tables/OperationsTable.h +++ b/src/Frontend/Tables/OperationsTable.h @@ -10,18 +10,18 @@ class OperationsTable : public ADataTable { OperationsTable(); ~OperationsTable(); - bool load(); - void unload(); - bool drawMenu(); + bool load() final; + void unload() final; + bool drawMenu() final; protected: size_t m_getItemsCount() const final; RowID m_getItemRowID(const size_t& vIdx) const final; - double m_getItemAmount(const size_t& vIdx) const final; + double m_getItemBarAmount(const size_t& vIdx) const final; void m_drawTableContent(const size_t& vIdx, const double& vMaxAmount) final; void m_setupColumns() final; void m_drawContextMenuContent() final; - void m_doActionOnDblClick() final; + void m_doActionOnDblClick(const size_t& vIdx, const RowID& vRowID) final; private: void m_updateOperations(); diff --git a/src/Frontend/Tables/TransactionsTable.cpp b/src/Frontend/Tables/TransactionsTable.cpp index d740aab..e69121d 100644 --- a/src/Frontend/Tables/TransactionsTable.cpp +++ b/src/Frontend/Tables/TransactionsTable.cpp @@ -1,76 +1,639 @@ #include +#include #include +#include -TransactionsTable::TransactionsTable() : ADataTable("TransactionsTable", 5) { +TransactionsTable::TransactionsTable() : ADataTable("TransactionsTable", 11) { } TransactionsTable::~TransactionsTable() { } +bool TransactionsTable::Init() { + return m_TransactionDialog.init(); +} + +void TransactionsTable::Unit() { + m_TransactionDialog.unit(); + clear(); +} + bool TransactionsTable::load() { - ADataTable::load(); - m_updateTransactions(); - return true; + if (ADataTable::load()) { + refreshDatas(); + return true; + } + return false; } void TransactionsTable::unload() { ADataTable::unload(); + clear(); } bool TransactionsTable::drawMenu() { - if (ADataTable::drawMenu()) { - m_updateTransactions(); - return true; - } return false; } +TransactionDialog& TransactionsTable::getTransactionDialogRef() { + return m_TransactionDialog; +} + size_t TransactionsTable::m_getItemsCount() const { - return m_Transactions.size(); + return m_Datas.transactions_filtered.size(); } RowID TransactionsTable::m_getItemRowID(const size_t& vIdx) const { - if (vIdx < m_Transactions.size()) { - return m_Transactions.at(vIdx).id; + if (vIdx < m_Datas.transactions_filtered.size()) { + return m_Datas.transactions_filtered.at(vIdx).id; } return 0; // the db row id cant be 0 } -double TransactionsTable::m_getItemAmount(const size_t& vIdx) const { - return m_Transactions.at(vIdx).amount; +double TransactionsTable::m_getItemBarAmount(const size_t& vIdx) const { + return m_Datas.transactions_filtered.at(vIdx).solde; } void TransactionsTable::m_drawTableContent(const size_t& vIdx, const double& vMaxAmount) { - const auto& t = m_Transactions.at(vIdx); + auto& t = m_Datas.transactions_filtered.at(vIdx); + + ImGui::TableNextColumn(); + { + if (m_IsGroupingModeTransactions()) { + ImGui::PushID(t.id); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + if (ImGui::Checkbox("##check", &t.confirmed)) { + DataBase::Instance()->ConfirmTransaction(t.id, t.confirmed); + } + ImGui::PopStyleVar(); + ImGui::PopID(); + } + } + + ImGui::TableNextColumn(); + { ImGui::Text("%s", t.date.c_str()); } + m_drawColumnSelectable(vIdx, t.id, t.description); + + ImGui::TableNextColumn(); + { + ImGui::Text("%s", t.comment.c_str()); + ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%s", t.comment.c_str()); + } + + ImGui::TableNextColumn(); + { + ImGui::Text("%s", t.entity.c_str()); + ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%s", t.entity.c_str()); + } + + ImGui::TableNextColumn(); + { + ImGui::Text("%s", t.category.c_str()); + ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%s", t.category.c_str()); + } + + ImGui::TableNextColumn(); + { + ImGui::Text("%s", t.operation.c_str()); + ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%s", t.operation.c_str()); + } + m_drawColumnDebit(t.debit); + m_drawColumnCredit(t.credit); - m_drawColumnAmount(t.amount); - m_drawColumnBars(t.amount, vMaxAmount); + + m_drawColumnAmount(t.solde); + + m_drawColumnBars(t.solde, vMaxAmount, 100.0f); } void TransactionsTable::m_setupColumns() { - ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupScrollFreeze(0, 2); + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Dates", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Descriptions", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("Comments", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("Entity", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Category", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Operation", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("Debit", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("Credit", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Amount", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Solde", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("Bars", ImGuiTableColumnFlags_WidthFixed); + m_drawSearchRow(); ImGui::TableHeadersRow(); } void TransactionsTable::m_drawContextMenuContent() { - CTOOL_DEBUG_BREAK; + if (!m_getSelectedRows().empty()) { + if (ImGui::MenuItem("Update selection")) { + std::vector transactions_to_update; + for (const auto& trans : m_Datas.transactions_filtered) { + if (m_IsRowSelected(trans.id)) { + transactions_to_update.push_back(trans); + } + } + if (transactions_to_update.size() > 1U) { + m_TransactionDialog.setTransactionsToUpdate(transactions_to_update); + m_TransactionDialog.show(DataDialogMode::MODE_UPDATE_ALL); + } else if (transactions_to_update.size() == 1U) { + m_TransactionDialog.setTransaction(transactions_to_update.front()); + m_TransactionDialog.show(DataDialogMode::MODE_UPDATE_ONCE); + } + } + if (ImGui::MenuItem("Delete selection")) { + std::vector transactions_to_delete; + for (const auto& trans : m_Datas.transactions_filtered) { + if (m_IsRowSelected(trans.id)) { + transactions_to_delete.push_back(trans); + } + } + m_TransactionDialog.setTransactionsToDelete(transactions_to_delete); + m_TransactionDialog.show(DataDialogMode::MODE_DELETE_ALL); + } + } +} + +void TransactionsTable::m_doActionOnDblClick(const size_t& vIdx, const RowID& vRowID) { + m_TransactionDialog.setTransaction(m_Datas.transactions_filtered.at(vIdx)); + m_TransactionDialog.show(DataDialogMode::MODE_UPDATE_ONCE); +} + +void TransactionsTable::refreshDatas() { + m_UpdateBanks(); + m_UpdateEntities(); + m_UpdateCategories(); + m_UpdateOperations(); + m_UpdateAccounts(); +} + +bool TransactionsTable::m_isGroupingModeTransactions() { + return (m_GroupingMode == GroupingMode::GROUPING_MODE_TRANSACTIONS); +} + +void TransactionsTable::m_drawSearchRow() { + bool change = false; + bool reset = false; + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (m_IsGroupingModeTransactions()) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + if (ImGui::ContrastedButton("R", nullptr, nullptr, ImGui::GetColumnWidth(0))) { + reset = true; + } + ImGui::PopStyleVar(); + } + for (size_t idx = 0; idx < 10; ++idx) { + ImGui::TableNextColumn(); + if (idx < SearchColumns::SEARCH_COLUMN_Count) { + if (m_IsGroupingModeTransactions()) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + if (m_SearchInputTexts.at(idx).DisplayInputText(ImGui::GetColumnWidth(idx), "", "")) { + m_SearchTokens[idx] = ct::toLower(m_SearchInputTexts.at(idx).GetText()); + m_FilteringMode = FilteringMode::FILTERING_MODE_BY_SEARCH; + change = true; + } + ImGui::PopStyleVar(); + } + } else if (idx == 6) { + m_drawAmount(m_TotalDebit); + } else if (idx == 7) { + m_drawAmount(m_TotalCredit); + } else if (idx == 8) { + // m_drawAmount(m_CurrentBaseSolde); + } else if (idx == 9) { + ImGui::Text( // + "[%u/%u]", + (uint32_t)m_Datas.transactions_filtered.size(), + (uint32_t)m_Datas.transactions.size()); + } + } + if (reset) { + resetFiltering(); + } + if (change) { + refreshFiltering(); + } +} + +void TransactionsTable::drawSelectMenu(FrameActionSystem& vFrameActionSystem) { + if (ImGui::BeginMenu("Select")) { + if (ImGui::BeginMenu("Rows")) { + if (ImGui::MenuItem("Displayed")) { + m_selectRows(0, m_getItemsCount()); + } + if (ImGui::MenuItem("UnConfirmed")) { + m_SelectUnConfirmedTransactions(); + } + if (ImGui::MenuItem("Duplicate (Date + Amount)")) { + m_SelectPossibleDuplicateEntryOnPricesAndDates(); + } + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Empty")) { + if (ImGui::MenuItem("Comments")) { + m_SelectEmptyColumn(SearchColumns::SEARCH_COLUMN_COMMENT); + } + if (ImGui::MenuItem("Entities")) { + m_SelectEmptyColumn(SearchColumns::SEARCH_COLUMN_ENTITY); + } + if (ImGui::MenuItem("Categories")) { + m_SelectEmptyColumn(SearchColumns::SEARCH_COLUMN_CATEGORY); + } + if (ImGui::MenuItem("Operations")) { + m_SelectEmptyColumn(SearchColumns::SEARCH_COLUMN_OPERATION); + } + ImGui::EndMenu(); + } + if (!m_getSelectedRows().empty()) { + if (ImGui::BeginMenu("Selection Actions")) { + if (ImGui::MenuItem("Do filter")) { + m_FilterSelection(); + } + if (ImGui::MenuItem("Do reset")) { + m_ResetSelection(); + } + ImGui::EndMenu(); + } + } + ImGui::EndMenu(); + } +} + +void TransactionsTable::drawDebugMenu(FrameActionSystem& vFrameActionSystem) { +#ifdef _DEBUG + if (ImGui::BeginMenu("Debug")) { + if (ImGui::MenuItem("Refresh")) { + refreshDatas(); + } + ImGui::Separator(); + if (ImGui::BeginMenu("Delete Tables")) { + if (ImGui::MenuItem("Banks")) { + DataBase::Instance()->DeleteBanks(); + refreshDatas(); + } + if (ImGui::MenuItem("Accounts")) { + DataBase::Instance()->DeleteAccounts(); + refreshDatas(); + } + if (ImGui::MenuItem("Entities")) { + DataBase::Instance()->DeleteEntities(); + refreshDatas(); + } + if (ImGui::MenuItem("Categories")) { + DataBase::Instance()->DeleteCategories(); + refreshDatas(); + } + if (ImGui::MenuItem("Operations")) { + DataBase::Instance()->DeleteOperations(); + refreshDatas(); + } + if (ImGui::MenuItem("Transactions")) { + DataBase::Instance()->DeleteTransactions(); + refreshDatas(); + } + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } +#endif +} + +void TransactionsTable::drawGroupingMenu(FrameActionSystem& vFrameActionSystem) { + if (ImGui::MenuItem("T", nullptr, m_GroupingMode == GroupingMode::GROUPING_MODE_TRANSACTIONS)) { + m_GroupTransactions(GroupingMode::GROUPING_MODE_TRANSACTIONS); + } + if (ImGui::MenuItem("D", nullptr, m_GroupingMode == GroupingMode::GROUPING_MODE_DAYS)) { + m_GroupTransactions(GroupingMode::GROUPING_MODE_DAYS); + } + if (ImGui::MenuItem("M", nullptr, m_GroupingMode == GroupingMode::GROUPING_MODE_MONTHS)) { + m_GroupTransactions(GroupingMode::GROUPING_MODE_MONTHS); + } + if (ImGui::MenuItem("Y", nullptr, m_GroupingMode == GroupingMode::GROUPING_MODE_YEARS)) { + m_GroupTransactions(GroupingMode::GROUPING_MODE_YEARS); + } +} + +void TransactionsTable::drawAccountsMenu(FrameActionSystem& vFrameActionSystem) { + if (ImGui::BeginMenu("Accounts")) { + for (const auto& bank : m_Accounts) { + if (ImGui::BeginMenu(bank.first.c_str())) { // bank name + for (const auto& agency : bank.second) { + if (ImGui::BeginMenu(agency.first.c_str())) { // bank agency + static auto flags = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; + if (ImGui::BeginTable("##MenuAccounts", 4, flags)) { + ImGui::TableSetupScrollFreeze(0, 1); + ImGui::TableSetupColumn("Number", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("Count", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableHeadersRow(); + size_t idx = 0U; + for (const auto& number : agency.second) { + const auto& a = number.second; + ImGui::TableNextRow(); + + ImGui::PushID(a.id); + { + ImGui::TableNextColumn(); + ImGui::PushID(&a); + { + if (ImGui::Selectable(a.number.c_str(), m_getAccountComboRef().getIndex() == idx, ImGuiSelectableFlags_SpanAllColumns)) { + m_ResetSelection(); + m_UpdateTransactions(a.id); + m_getAccountComboRef().getIndexRef() = idx; + } + } + ImGui::PopID(); + + ImGui::TableNextColumn(); + ImGui::Text("%s", a.name.c_str()); + + ImGui::TableNextColumn(); + ImGui::Text("%s", a.type.c_str()); + + ImGui::TableNextColumn(); + ImGui::Text("%u", a.count); + } + ImGui::PopID(); + + ++idx; + } + ImGui::EndTable(); + } + ImGui::EndMenu(); + } + } + ImGui::EndMenu(); + } + } + ImGui::EndMenu(); + } +} + +void TransactionsTable::clear() { + m_Datas.clear(); +} + +void TransactionsTable::resetFiltering() { + m_Datas.transactions_filtered = m_Datas.transactions; + m_Datas.transactions_filtered_rowids = {}; + m_SearchInputTexts = {}; + m_SearchTokens = {}; + m_FilteringMode = FilteringMode::FILTERING_MODE_BY_SEARCH; + m_Datas.filtered_selected_transactions.clear(); + refreshFiltering(); +} + +void TransactionsTable::refreshFiltering() { + m_Datas.transactions_filtered.clear(); + m_Datas.transactions_filtered_rowids.clear(); + bool use = false; + double solde = m_CurrentBaseSolde; + m_TotalDebit = 0.0; + m_TotalCredit = 0.0; + for (auto t : m_Datas.transactions) { + use = true; + if (m_FilteringMode == FilteringMode::FILTERING_MODE_BY_SEARCH) { + for (size_t idx = 0; idx < SearchColumns::SEARCH_COLUMN_Count; ++idx) { + const auto& tk = m_SearchTokens.at(idx); + if (!tk.empty()) { + use &= (t.optimized.at(idx).find(tk) != std::string::npos); + } + } + } else if (m_FilteringMode == FilteringMode::FILTERING_MODE_BY_SELECTED_ROW_IDS) { + use = (m_Datas.filtered_selected_transactions.find(t.id) != m_Datas.filtered_selected_transactions.end()); + } + if (use) { + t.solde = solde += t.debit + t.credit; + m_Datas.transactions_filtered.push_back(t); + m_Datas.transactions_filtered_rowids.emplace(t.id); + m_TotalDebit += t.debit; + m_TotalCredit += t.credit; + } + } +} + +void TransactionsTable::m_FilterSelection() { + m_FilteringMode = FilteringMode::FILTERING_MODE_BY_SELECTED_ROW_IDS; + m_Datas.filtered_selected_transactions = m_getSelectedRows(); + refreshFiltering(); } -void TransactionsTable::m_doActionOnDblClick() { - CTOOL_DEBUG_BREAK; +void TransactionsTable::m_SelectPossibleDuplicateEntryOnPricesAndDates() { + if (m_getAccountComboRef().getIndex() < m_Datas.accounts.size()) { + RowID account_id = m_Datas.accounts.at(m_getAccountComboRef().getIndex()).id; + m_ResetSelection(); + DataBase::Instance()->GetDuplicateTransactionsOnDatesAndAmount( // + account_id, // + [this](const RowID& vRowID) { + if (m_Datas.transactions_filtered_rowids.find(vRowID) != // + m_Datas.transactions_filtered_rowids.end()) { + m_SelectRow(vRowID); // select row id + } + }); + } } -void TransactionsTable::m_updateTransactions() { - const auto account_id = m_getAccountID(); - if (account_id > 0) { - m_Transactions.clear(); - CTOOL_DEBUG_BREAK; +void TransactionsTable::m_SelectUnConfirmedTransactions() { + if (m_getAccountComboRef().getIndex() < m_Datas.accounts.size()) { + RowID account_id = m_Datas.accounts.at(m_getAccountComboRef().getIndex()).id; + m_ResetSelection(); + DataBase::Instance()->GetUnConfirmedTransactions( // + account_id, // + [this](const RowID& vRowID) { + if (m_Datas.transactions_filtered_rowids.find(vRowID) != // + m_Datas.transactions_filtered_rowids.end()) { + m_SelectRow(vRowID); // select row id + } + }); } } + +void TransactionsTable::m_SelectEmptyColumn(const SearchColumns& vColumn) { + m_ResetSelection(); + for (const auto& t : m_Datas.transactions_filtered) { + if (vColumn == SearchColumns::SEARCH_COLUMN_COMMENT) { + if (t.comment.empty()) { + m_SelectRow(t.id); + } + } else if (vColumn == SearchColumns::SEARCH_COLUMN_ENTITY) { + if (t.entity.empty()) { + m_SelectRow(t.id); + } + } else if (vColumn == SearchColumns::SEARCH_COLUMN_CATEGORY) { + if (t.category.empty()) { + m_SelectRow(t.id); + } + } else if (vColumn == SearchColumns::SEARCH_COLUMN_OPERATION) { + if (t.operation.empty()) { + m_SelectRow(t.id); + } + } + } +} + +void TransactionsTable::m_GroupTransactions(const GroupingMode& vGroupingMode) { + m_GroupingMode = vGroupingMode; + if (m_getAccountComboRef().getIndex() < m_Datas.accounts.size()) { + m_UpdateTransactions(m_Datas.accounts.at(m_getAccountComboRef().getIndex()).id); + } +} + +void TransactionsTable::m_UpdateBanks() { + m_Datas.bankNames.clear(); + DataBase::Instance()->GetBanks( // + [this](const BankName& vUserName, const std::string& /*vUrl*/) { // + m_Datas.bankNames.push_back(vUserName); + }); +} + +void TransactionsTable::m_UpdateEntities() { + m_Datas.entityNames.clear(); + DataBase::Instance()->GetEntities( // + [this](const EntityName& vEntityName) { // + m_Datas.entityNames.push_back(vEntityName); + }); +} + +void TransactionsTable::m_UpdateCategories() { + m_Datas.categoryNames.clear(); + DataBase::Instance()->GetCategories( // + [this](const CategoryName& vCategoryName) { // + m_Datas.categoryNames.push_back(vCategoryName); + }); +} + +void TransactionsTable::m_UpdateOperations() { + m_Datas.operationNames.clear(); + DataBase::Instance()->GetOperations( // + [this](const OperationName& vOperationName) { // + m_Datas.operationNames.push_back(vOperationName); + }); +} + +void TransactionsTable::m_UpdateAccounts() { + m_Accounts.clear(); + m_Datas.accounts.clear(); + m_Datas.accountNumbers.clear(); + DataBase::Instance()->GetAccounts( // + [this](const RowID& vRowID, + const BankName& vBankName, + const BankAgency& vBankAgency, + const AccountType& vAccountType, + const AccountName& vAccountName, + const AccountNumber& vAccountNumber, + const AccounBaseSolde& vBaseSolde, + const TransactionsCount& vCount) { // + Account a; + a.id = vRowID; + a.bank = vBankName; + a.agency = vBankAgency; + a.type = vAccountType; + a.name = vAccountName; + a.number = vAccountNumber; + a.base_solde = vBaseSolde; + a.count = vCount; + m_Datas.accounts.push_back(a); + m_Datas.accountNumbers.push_back(vAccountNumber); + m_Accounts[vBankName + "##BankName"][vBankAgency + "##BankAgency"][vAccountNumber] = a; + }); + if (m_getAccountComboRef().getIndex() < m_Datas.accounts.size()) { + m_UpdateTransactions(m_Datas.accounts.at(m_getAccountComboRef().getIndex()).id); + } +} + +void TransactionsTable::m_UpdateTransactions(const RowID& vAccountID) { + m_Datas.transactions.clear(); + const auto& zero_based_account_id = vAccountID - 1; + if (zero_based_account_id < m_Datas.accounts.size()) { + double solde = m_CurrentBaseSolde = m_Datas.accounts.at(zero_based_account_id).base_solde; + const auto& account_number = m_Datas.accounts.at(zero_based_account_id).number; + if (m_IsGroupingModeTransactions()) { + DataBase::Instance()->GetTransactions( // + vAccountID, // + [this, &solde, account_number]( // + const RowID& vTransactionID, + const EntityName& vEntityName, + const CategoryName& vCategoryName, + const OperationName& vOperationName, + const SourceName& vSourceName, + const TransactionDate& vDate, + const TransactionDescription& vDescription, + const TransactionComment& vComment, + const TransactionAmount& vAmount, + const TransactionConfirmed& vConfirmed, + const TransactionHash& vHash) { // + solde += vAmount; + Transaction t; + t.id = vTransactionID; + t.account = account_number; + t.optimized[0] = ct::toLower(t.date = vDate); + t.optimized[1] = ct::toLower(t.description = vDescription); + t.optimized[2] = ct::toLower(t.comment = vComment); + t.optimized[3] = ct::toLower(t.entity = vEntityName); + t.optimized[4] = ct::toLower(t.category = vCategoryName); + t.optimized[5] = ct::toLower(t.operation = vOperationName); + t.hash = vHash; + t.source = vSourceName; + t.debit = vAmount < 0.0 ? vAmount : 0.0; + t.credit = vAmount > 0.0 ? vAmount : 0.0; + t.amount = vAmount; + t.confirmed = vConfirmed; + t.solde = solde; + m_Datas.transactions.push_back(t); + }); + } else { + DataBase::Instance()->GetGroupedTransactions( // + vAccountID, + GroupBy::DATES, + (DateFormat)(m_GroupingMode - 1), + [this]( // + const RowID& vRowID, + const TransactionDate& vTransactionDate, + const TransactionDescription& vTransactionDescription, + const EntityName& vEntityName, + const CategoryName& vCategoryName, + const OperationName& vOperationName, + const TransactionDebit& vTransactionDebit, + const TransactionCredit& vTransactionCredit) { + Transaction t; + t.id = vRowID; + t.date = vTransactionDate; + t.description = "-- grouped --"; + t.entity = "-- grouped --"; + t.category = "-- grouped --"; + t.operation = "-- grouped --"; + t.debit = vTransactionDebit; + t.credit = vTransactionCredit; + t.amount = vTransactionDebit + vTransactionCredit; + m_Datas.transactions.push_back(t); + }); + } + } + refreshFiltering(); +} + +bool TransactionsTable::m_IsGroupingModeTransactions() { + return (m_GroupingMode == GroupingMode::GROUPING_MODE_TRANSACTIONS); +} + +void TransactionsTable::m_drawAmount(const double& vAmount) { + if (vAmount < 0.0) { + const auto& bad_color = ImGui::GetColorU32(ImVec4(1, 0, 0, 1)); + ImGui::PushStyleColor(ImGuiCol_Text, bad_color); + ImGui::Text("%.2f", vAmount); + ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", vAmount); + ImGui::PopStyleColor(); + } else if (vAmount > 0.0) { + const auto& good_color = ImGui::GetColorU32(ImVec4(0, 1, 0, 1)); + ImGui::PushStyleColor(ImGuiCol_Text, good_color); + ImGui::Text("%.2f", vAmount); + ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", vAmount); + ImGui::PopStyleColor(); + } else { + ImGui::Text("%.2f", vAmount); + ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", vAmount); + } +} \ No newline at end of file diff --git a/src/Frontend/Tables/TransactionsTable.h b/src/Frontend/Tables/TransactionsTable.h index 9b18e63..0767bea 100644 --- a/src/Frontend/Tables/TransactionsTable.h +++ b/src/Frontend/Tables/TransactionsTable.h @@ -2,27 +2,100 @@ #include +#include + +#include + +#include + class TransactionsTable : public ADataTable { private: - std::vector m_Transactions; + struct Datas { + std::vector bankNames; + std::vector entityNames; + std::vector categoryNames; + std::vector operationNames; + std::vector accounts; + std::vector accountNumbers; + std::vector transactions; + std::vector transactions_filtered; + std::set transactions_filtered_rowids; + std::set filtered_selected_transactions; + void clear() { + accounts.clear(); + bankNames.clear(); + transactions.clear(); + categoryNames.clear(); + accountNumbers.clear(); + operationNames.clear(); + transactions_filtered.clear(); + } + } m_Datas; + + TransactionDialog m_TransactionDialog; + + double m_CurrentBaseSolde = 0.0; + double m_TotalDebit = 0.0; + double m_TotalCredit = 0.0; + + std::array m_SearchInputTexts; + std::array m_SearchTokens; + FilteringMode m_FilteringMode = FilteringMode::FILTERING_MODE_BY_SEARCH; + GroupingMode m_GroupingMode = GroupingMode::GROUPING_MODE_TRANSACTIONS; + + // accounts display + std::map>> + m_Accounts; public: TransactionsTable(); ~TransactionsTable(); - bool load(); - void unload(); - bool drawMenu(); + bool Init(); + void Unit(); + + bool load() final; + void unload() final; + bool drawMenu() final; + + TransactionDialog& getTransactionDialogRef(); + + void clear(); + void refreshDatas(); + void refreshFiltering(); + void resetFiltering(); + + void drawAccountsMenu(FrameActionSystem& vFrameActionSystem); + void drawSelectMenu(FrameActionSystem& vFrameActionSystem); + void drawDebugMenu(FrameActionSystem& vFrameActionSystem); + void drawGroupingMenu(FrameActionSystem& vFrameActionSystem); protected: size_t m_getItemsCount() const final; RowID m_getItemRowID(const size_t& vIdx) const final; - double m_getItemAmount(const size_t& vIdx) const final; + double m_getItemBarAmount(const size_t& vIdx) const final; void m_drawTableContent(const size_t& vIdx, const double& vMaxAmount) final; void m_setupColumns() final; void m_drawContextMenuContent() final; - void m_doActionOnDblClick() final; + void m_doActionOnDblClick(const size_t& vIdx, const RowID& vRowID) final; private: - void m_updateTransactions(); + bool m_isGroupingModeTransactions(); + void m_drawSearchRow(); + void m_FilterSelection(); + void m_SelectPossibleDuplicateEntryOnPricesAndDates(); + void m_SelectUnConfirmedTransactions(); + void m_SelectEmptyColumn(const SearchColumns& vColumn); + void m_GroupTransactions(const GroupingMode& vGroupingMode); + void m_UpdateBanks(); + void m_UpdateAccounts(); + void m_UpdateEntities(); + void m_UpdateCategories(); + void m_UpdateOperations(); + void m_UpdateTransactions(const RowID& vAccountID); + bool m_IsGroupingModeTransactions(); + void m_drawAmount(const double& vAmount); }; diff --git a/src/Frontend/Tables/abstract/ADataTable.cpp b/src/Frontend/Tables/abstract/ADataTable.cpp index 41dcfb6..7b6ae4c 100644 --- a/src/Frontend/Tables/abstract/ADataTable.cpp +++ b/src/Frontend/Tables/abstract/ADataTable.cpp @@ -2,8 +2,14 @@ #include #include -ADataTable::ADataTable(const char* vTableName, const int32_t& vColummCount) - : m_TableName(vTableName), m_ColummCount(vColummCount) { +ADataTable::ADataTable(const char* vTableName, const int32_t& vColummCount) : m_TableName(vTableName), m_ColummCount(vColummCount) { +} + +bool ADataTable::Init() { + return true; +} + +void ADataTable::Unit() { } bool ADataTable::load() { @@ -12,10 +18,9 @@ bool ADataTable::load() { } void ADataTable::unload() { - } -bool ADataTable::drawMenu() { +bool ADataTable::m_drawAccountMenu() { const auto align = 100.0f; const auto width = 10; return m_AccountsCombo.displayCombo(width, "Account", align); @@ -62,6 +67,10 @@ void ADataTable::draw(const ImVec2& vSize) { ImGui::PopStyleVar(); } +ImWidgets::QuickStringCombo& ADataTable::m_getAccountComboRef() { + return m_AccountsCombo; +} + void ADataTable::m_updateAccounts() { m_Accounts.clear(); m_AccountsCombo.clear(); @@ -95,7 +104,7 @@ double ADataTable::m_computeMaxPrice() { if (idx < 0) { continue; } - const auto& as = std::abs(m_getItemAmount(idx)); + const auto& as = std::abs(m_getItemBarAmount(idx)); if (as > max_price) { max_price = as; } @@ -132,7 +141,9 @@ void ADataTable::m_drawColumnSelectable(const size_t& vIdx, const RowID& vRowID, ImGui::Selectable(vText.c_str(), &is_selected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap); if (ImGui::IsItemHovered()) { if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { - m_doActionOnDblClick(); + m_ResetSelection(); + m_SelectRow(vRowID); + m_doActionOnDblClick(vIdx, vRowID); } else if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) { if (ImGui::IsKeyDown(ImGuiMod_Shift)) { m_CurrSelectedItemIdx = vIdx; @@ -214,14 +225,17 @@ void ADataTable::m_drawColumnAmount(const double& vAmount) { } } -void ADataTable::m_drawColumnBars(const double vAmount, const double vMaxAmount) { +void ADataTable::m_drawColumnBars(const double vAmount, const double vMaxAmount, const float vColumNWidth) { ImGui::TableNextColumn(); auto drawListPtr = ImGui::GetWindowDrawList(); const auto& cursor = ImGui::GetCursorScreenPos(); ImGuiContext& g = *GImGui; ImGuiTable* table = g.CurrentTable; const auto& table_column = table->Columns[table->CurrentColumn]; - const auto column_width = table_column.MaxX - table_column.MinX; + auto column_width = vColumNWidth; + if (column_width < 0.0f) { + column_width = table_column.MaxX - table_column.MinX; + } const ImVec2 pMin(cursor.x, cursor.y + m_TextHeight * 0.1f); const ImVec2 pMax(cursor.x + column_width, cursor.y + m_TextHeight * 0.9f); const float pMidX((pMin.x + pMax.x) * 0.5f); diff --git a/src/Frontend/Tables/abstract/ADataTable.h b/src/Frontend/Tables/abstract/ADataTable.h index 7a9cd93..8289323 100644 --- a/src/Frontend/Tables/abstract/ADataTable.h +++ b/src/Frontend/Tables/abstract/ADataTable.h @@ -20,37 +20,42 @@ class ADataTable { public: explicit ADataTable(const char* vTableName, const int32_t& vCloumnsCount); virtual ~ADataTable() = default; + + virtual bool Init(); + virtual void Unit(); virtual bool load(); virtual void unload(); - virtual bool drawMenu(); + virtual bool drawMenu() = 0; void draw(const ImVec2& vSize); protected: virtual size_t m_getItemsCount() const = 0; virtual RowID m_getItemRowID(const size_t& vIdx) const = 0; - virtual double m_getItemAmount(const size_t& vIdx) const = 0; + virtual double m_getItemBarAmount(const size_t& vIdx) const = 0; virtual void m_drawTableContent(const size_t& vIdx, const double& vMaxAmount) = 0; virtual void m_setupColumns() = 0; virtual void m_drawContextMenuContent() = 0; - virtual void m_doActionOnDblClick() = 0; + virtual void m_doActionOnDblClick(const size_t& vIdx, const RowID& vRowID) = 0; protected: RowID m_getAccountID(); void m_updateAccounts(); + bool m_drawAccountMenu(); void m_drawColumnSelectable(const size_t& vIdx, const RowID& vRowID, const std::string& vText); void m_drawColumnText(const std::string& vText); void m_drawColumnDebit(const double& vDebit); void m_drawColumnCredit(const double& vCredit); void m_drawColumnAmount(const double& vAmount); - void m_drawColumnBars(const double vAmount, const double vMaxAmount); + void m_drawColumnBars(const double vAmount, const double vMaxAmount, const float vColumNWidth = -1.0f); const std::set& m_getSelectedRows(); void m_selectRows(const size_t& vStartIdx, const size_t& vEndIdx); + ImWidgets::QuickStringCombo& m_getAccountComboRef(); + void m_ResetSelection(); + void m_SelectRow(const RowID& vRowID); + bool m_IsRowSelected(const RowID& vRowID) const; private: - bool m_IsRowSelected(const RowID& vRowID) const; - void m_SelectRow(const RowID& vRowID); void m_SelectOrDeselectRow(const RowID& vRowID); - void m_ResetSelection(); double m_computeMaxPrice(); void m_showContextMenu(const size_t& vIdx); }; diff --git a/src/Headers/CashMeBuild.h b/src/Headers/CashMeBuild.h index 2377f4c..a49daf8 100644 --- a/src/Headers/CashMeBuild.h +++ b/src/Headers/CashMeBuild.h @@ -1,7 +1,7 @@ #pragma once #define CashMe_Prefix "CashMe" -#define CashMe_BuildNumber 625 +#define CashMe_BuildNumber 640 #define CashMe_MinorNumber 0 #define CashMe_MajorNumber 0 -#define CashMe_BuildId "0.0.625" +#define CashMe_BuildId "0.0.640" diff --git a/src/Panes/AccountPane.cpp b/src/Panes/AccountPane.cpp index a029199..4591c02 100644 --- a/src/Panes/AccountPane.cpp +++ b/src/Panes/AccountPane.cpp @@ -19,12 +19,12 @@ AccountPane::~AccountPane() { bool AccountPane::Init() { bool ret = true; - m_GetAvailableDataBrokers(); + m_getAvailableDataBrokers(); ret &= m_BankDialog.init(); ret &= m_AccountDialog.init(); ret &= m_CategoryDialog.init(); ret &= m_OperationDialog.init(); - ret &= m_TransactionDialog.init(); + ret &= m_TransactionsTable.Init(); return ret; } @@ -33,8 +33,8 @@ void AccountPane::Unit() { m_AccountDialog.init(); m_CategoryDialog.init(); m_OperationDialog.init(); - m_TransactionDialog.unit(); - m_Clear(); + m_TransactionsTable.Unit(); + m_clear(); } /////////////////////////////////////////////////////////////////////////////////// @@ -55,8 +55,17 @@ bool AccountPane::DrawPanes(const uint32_t& /*vCurrentFrame*/, bool* vOpened, Im flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_MenuBar; #endif if (ProjectFile::Instance()->IsProjectLoaded()) { - m_drawMenu(MainFrontend::Instance()->GetActionSystemRef()); - m_displayTransactions(); + if (ImGui::BeginMenuBar()) { + auto& actionSystemRef = MainFrontend::Instance()->GetActionSystemRef(); + m_TransactionsTable.drawAccountsMenu(actionSystemRef); + m_drawCreationMenu(); + m_drawImportMenu(actionSystemRef); + m_TransactionsTable.drawSelectMenu(actionSystemRef); + m_TransactionsTable.drawGroupingMenu(actionSystemRef); + m_TransactionsTable.drawDebugMenu(actionSystemRef); + ImGui::EndMenuBar(); + } + m_TransactionsTable.draw(ImGui::GetContentRegionAvail()); } } @@ -83,12 +92,12 @@ bool AccountPane::DrawDialogsAndPopups(const uint32_t& /*vCurrentFrame*/, const } ret |= m_CategoryDialog.draw(center); ret |= m_OperationDialog.draw(center); - ret |= m_TransactionDialog.draw(center); + ret |= m_TransactionsTable.getTransactionDialogRef().draw(center); m_ImportThread.drawDialog(center); if (ret) { - m_refreshDatas(); + m_TransactionsTable.refreshDatas(); } ImVec2 max = vRect.GetSize(); @@ -102,7 +111,7 @@ bool AccountPane::DrawDialogsAndPopups(const uint32_t& /*vCurrentFrame*/, const for (const auto& s : selection) { files.push_back(s.second); } - m_ImportFromFiles(files); + m_importFromFiles(files); ret = true; } } @@ -122,441 +131,7 @@ void AccountPane::DoBackend() { } void AccountPane::Load() { - m_refreshDatas(); -} - -void AccountPane::m_refreshDatas() { - m_UpdateBanks(); - m_UpdateEntities(); - m_UpdateCategories(); - m_UpdateOperations(); - m_UpdateAccounts(); -} - -void AccountPane::m_drawMenu(FrameActionSystem& vFrameActionSystem) { - if (ProjectFile::Instance()->IsProjectLoaded()) { - if (ImGui::BeginMenuBar()) { - m_drawAccountsMenu(vFrameActionSystem); - m_drawCreationMenu(vFrameActionSystem); - m_drawImportMenu(vFrameActionSystem); - m_drawSelectMenu(vFrameActionSystem); - m_drawGroupingMenu(vFrameActionSystem); - m_drawDebugMenu(vFrameActionSystem); - ImGui::EndMenuBar(); - } - } -} - -void AccountPane::m_displayTransactions() { - ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 30.0f); - static auto flags = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY; - if (ImGui::BeginTable("##Transactions", 11, flags)) { - ImGui::TableSetupScrollFreeze(0, 2); - ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Dates", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Descriptions", ImGuiTableColumnFlags_WidthStretch); - ImGui::TableSetupColumn("Comments", ImGuiTableColumnFlags_WidthStretch); - ImGui::TableSetupColumn("Entity", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Category", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Operation", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Debit", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Credit", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Solde", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Bars", ImGuiTableColumnFlags_WidthFixed); - m_drawSearchRow(); - ImGui::TableHeadersRow(); - int32_t idx = 0; - double max_price = DBL_MIN; - const float& bar_column_width = 100.0f; - auto drawListPtr = ImGui::GetWindowDrawList(); - const float& text_h = ImGui::GetTextLineHeight(); - const float& item_h = ImGui::GetTextLineHeightWithSpacing(); - const auto& bad_color = ImGui::GetColorU32(ImVec4(1, 0, 0, 1)); - const auto& good_color = ImGui::GetColorU32(ImVec4(0, 1, 0, 1)); - m_CurrSelectedItemIdx = -1; - m_TransactionsListClipper.Begin((int)m_Datas.transactions_filtered.size(), item_h); - while (m_TransactionsListClipper.Step()) { - max_price = 0.0; - for (idx = m_TransactionsListClipper.DisplayStart; idx < m_TransactionsListClipper.DisplayEnd; ++idx) { - if (idx < 0) { - continue; - } - const auto& t = m_Datas.transactions_filtered.at(idx); - const auto& as = std::abs(t.solde); - if (as > max_price) { - max_price = as; - } - } - - for (idx = m_TransactionsListClipper.DisplayStart; idx < m_TransactionsListClipper.DisplayEnd; ++idx) { - if (idx < 0) { - continue; - } - - auto& t = m_Datas.transactions_filtered.at(idx); - - ImGui::TableNextRow(); - - ImGui::TableNextColumn(); - { - if (m_IsGroupingModeTransactions()) { - ImGui::PushID(t.id); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); - if (ImGui::Checkbox("##check", &t.confirmed)) { - DataBase::Instance()->ConfirmTransaction(t.id, t.confirmed); - } - ImGui::PopStyleVar(); - ImGui::PopID(); - } - } - - ImGui::TableNextColumn(); - { ImGui::Text("%s", t.date.c_str()); } - - ImGui::TableNextColumn(); - { - ImGui::PushID(&t); - auto is_selected = m_IsRowSelected(t.id); - ImGui::Selectable(t.description.c_str(), &is_selected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap); - if (m_IsGroupingModeTransactions()) { - if (ImGui::IsItemHovered()) { - if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { - m_ResetSelection(); - m_SelectOrDeselectRow(t); - m_TransactionDialog.setTransaction(t); - m_TransactionDialog.show(DataDialogMode::MODE_UPDATE_ONCE); - } else if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) { - if (ImGui::IsKeyDown(ImGuiMod_Shift)) { - m_CurrSelectedItemIdx = idx; - } else { - m_LastSelectedItemIdx = idx; - - if (!ImGui::IsKeyDown(ImGuiMod_Ctrl)) { - m_ResetSelection(); - } - - m_SelectOrDeselectRow(t); - } - } - } - } - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%s", t.description.c_str()); - ImGui::PopID(); - m_drawTransactionMenu(t); - } - - ImGui::TableNextColumn(); - { - ImGui::Text("%s", t.comment.c_str()); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%s", t.comment.c_str()); - } - - ImGui::TableNextColumn(); - { - ImGui::Text("%s", t.entity.c_str()); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%s", t.entity.c_str()); - } - - ImGui::TableNextColumn(); - { - ImGui::Text("%s", t.category.c_str()); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%s", t.category.c_str()); - } - - ImGui::TableNextColumn(); - { - ImGui::Text("%s", t.operation.c_str()); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%s", t.operation.c_str()); - } - - ImGui::TableNextColumn(); - { - if (t.debit < 0.0) { - ImGui::PushStyleColor(ImGuiCol_Text, bad_color); - ImGui::Text("%.2f", t.debit); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", t.debit); - ImGui::PopStyleColor(); - } - } - - ImGui::TableNextColumn(); - { - if (t.credit > 0.0) { - ImGui::PushStyleColor(ImGuiCol_Text, good_color); - ImGui::Text("%.2f", t.credit); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", t.credit); - ImGui::PopStyleColor(); - } - } - - ImGui::TableNextColumn(); - { - if (t.solde < 0.0) { - ImGui::PushStyleColor(ImGuiCol_Text, bad_color); - ImGui::Text("%.2f", t.solde); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", t.solde); - ImGui::PopStyleColor(); - } else if (t.solde > 0.0) { - ImGui::PushStyleColor(ImGuiCol_Text, good_color); - ImGui::Text("%.2f", t.solde); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", t.solde); - ImGui::PopStyleColor(); - } else { - ImGui::Text("%.2f", t.solde); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", t.solde); - } - } - - ImGui::TableNextColumn(); - { - const auto& cursor = ImGui::GetCursorScreenPos(); - const ImVec2 pMin(cursor.x, cursor.y + text_h * 0.1f); - const ImVec2 pMax(cursor.x + bar_column_width, cursor.y + text_h * 0.9f); - const float pMidX((pMin.x + pMax.x) * 0.5f); - ImGui::SetCursorScreenPos(pMin); - const float bw(bar_column_width * 0.5f * std::abs(t.solde) / (float)max_price); - if (t.solde < 0.0) { - drawListPtr->AddRectFilled(ImVec2(pMidX - bw, pMin.y), ImVec2(pMidX, pMax.y), bad_color); - } else if (t.solde > 0.0) { - drawListPtr->AddRectFilled(ImVec2(pMidX, pMin.y), ImVec2(pMidX + bw, pMax.y), good_color); - } - ImGui::SetCursorScreenPos(pMax); - } - } - } - m_TransactionsListClipper.End(); - - if (m_IsGroupingModeTransactions()) { - if (ImGui::IsKeyDown(ImGuiMod_Ctrl)) { - if (ImGui::IsKeyDown(ImGuiKey_A)) { - m_SelectCurrentRows(); - } - } - - // shift selection - if (ImGui::IsKeyDown(ImGuiMod_Shift) && m_LastSelectedItemIdx > -1 && m_CurrSelectedItemIdx > -1) { - int32_t min_idx = ImMin(m_LastSelectedItemIdx, m_CurrSelectedItemIdx); - int32_t max_idx = ImMax(m_LastSelectedItemIdx, m_CurrSelectedItemIdx); - m_ResetSelection(); - for (int32_t nid = min_idx; nid <= max_idx; ++nid) { - if (nid < m_Datas.transactions_filtered.size()) { - const auto& t = m_Datas.transactions_filtered.at(nid); - m_SelectOrDeselectRow(t); - } - } - } - } - - ImGui::EndTable(); - } - ImGui::PopStyleVar(); -} - -void AccountPane::m_drawImportMenu(FrameActionSystem& vFrameActionSystem) { - if (ImGui::BeginMenu("Import")) { - for (const auto& broker : m_DataBrokerModules) { - if (ImGui::BeginMenu(broker.first.c_str())) { - for (const auto& way : broker.second) { - if (ImGui::MenuItem(way.first.c_str())) { - if (way.second != nullptr) { - m_SelectedBroker = way.second; - vFrameActionSystem.Clear(); - vFrameActionSystem.Add([&way]() { - const auto& ext = way.second->getFileExt(); - IGFD::FileDialogConfig config; - config.countSelectionMax = 0; - config.flags = ImGuiFileDialogFlags_Modal; - ImGuiFileDialog::Instance()->OpenDialog("Import Datas", "Import Datas from File", ext.c_str(), config); - return true; - }); - } - } - } - ImGui::EndMenu(); - } - } - ImGui::EndMenu(); - } -} - -void AccountPane::m_drawSelectMenu(FrameActionSystem& vFrameActionSystem) { - if (ImGui::BeginMenu("Select")) { - if (ImGui::BeginMenu("Rows")) { - if (ImGui::MenuItem("Displayed")) { - m_SelectCurrentRows(); - } - if (ImGui::MenuItem("UnConfirmed")) { - m_SelectUnConfirmedTransactions(); - } - if (ImGui::MenuItem("Duplicate (Date + Amount)")) { - m_SelectPossibleDuplicateEntryOnPricesAndDates(); - } - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Empty")) { - if (ImGui::MenuItem("Comments")) { - m_SelectEmptyColumn(SearchColumns::SEARCH_COLUMN_COMMENT); - } - if (ImGui::MenuItem("Entities")) { - m_SelectEmptyColumn(SearchColumns::SEARCH_COLUMN_ENTITY); - } - if (ImGui::MenuItem("Categories")) { - m_SelectEmptyColumn(SearchColumns::SEARCH_COLUMN_CATEGORY); - } - if (ImGui::MenuItem("Operations")) { - m_SelectEmptyColumn(SearchColumns::SEARCH_COLUMN_OPERATION); - } - ImGui::EndMenu(); - } - if (!m_SelectedTransactions.empty()) { - if (ImGui::BeginMenu("Selection Actions")) { - if (ImGui::MenuItem("Do filter")) { - m_FilterSelection(); - } - if (ImGui::MenuItem("Do reset")) { - m_ResetSelection(); - } - ImGui::EndMenu(); - } - } - ImGui::EndMenu(); - } -} - -void AccountPane::m_drawDebugMenu(FrameActionSystem& vFrameActionSystem) { -#ifdef _DEBUG - if (ImGui::BeginMenu("Debug")) { - if (ImGui::MenuItem("Refresh")) { - m_refreshDatas(); - } - ImGui::Separator(); - if (ImGui::BeginMenu("Delete Tables")) { - if (ImGui::MenuItem("Banks")) { - DataBase::Instance()->DeleteBanks(); - m_refreshDatas(); - } - if (ImGui::MenuItem("Accounts")) { - DataBase::Instance()->DeleteAccounts(); - m_refreshDatas(); - } - if (ImGui::MenuItem("Entities")) { - DataBase::Instance()->DeleteEntities(); - m_refreshDatas(); - } - if (ImGui::MenuItem("Categories")) { - DataBase::Instance()->DeleteCategories(); - m_refreshDatas(); - } - if (ImGui::MenuItem("Operations")) { - DataBase::Instance()->DeleteOperations(); - m_refreshDatas(); - } - if (ImGui::MenuItem("Transactions")) { - DataBase::Instance()->DeleteTransactions(); - m_refreshDatas(); - } - ImGui::EndMenu(); - } - ImGui::EndMenu(); - } -#endif -} - -void AccountPane::m_drawGroupingMenu(FrameActionSystem& vFrameActionSystem) { - if (ImGui::MenuItem("T", nullptr, m_GroupingMode == GroupingMode::GROUPING_MODE_TRANSACTIONS)) { - m_GroupTransactions(GroupingMode::GROUPING_MODE_TRANSACTIONS); - } - if (ImGui::MenuItem("D", nullptr, m_GroupingMode == GroupingMode::GROUPING_MODE_DAYS)) { - m_GroupTransactions(GroupingMode::GROUPING_MODE_DAYS); - } - if (ImGui::MenuItem("M", nullptr, m_GroupingMode == GroupingMode::GROUPING_MODE_MONTHS)) { - m_GroupTransactions(GroupingMode::GROUPING_MODE_MONTHS); - } - if (ImGui::MenuItem("Y", nullptr, m_GroupingMode == GroupingMode::GROUPING_MODE_YEARS)) { - m_GroupTransactions(GroupingMode::GROUPING_MODE_YEARS); - } -} - -void AccountPane::m_drawAccountsMenu(FrameActionSystem& vFrameActionSystem) { - if (ImGui::BeginMenu("Accounts")) { - for (const auto& bank : m_Accounts) { - if (ImGui::BeginMenu(bank.first.c_str())) { // bank name - for (const auto& agency : bank.second) { - if (ImGui::BeginMenu(agency.first.c_str())) { // bank agency - static auto flags = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; - if (ImGui::BeginTable("##MenuAccounts", 4, flags)) { - ImGui::TableSetupScrollFreeze(0, 1); - ImGui::TableSetupColumn("Number", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthStretch); - ImGui::TableSetupColumn("Count", ImGuiTableColumnFlags_WidthFixed); - ImGui::TableHeadersRow(); - size_t idx = 0U; - for (const auto& number : agency.second) { - const auto& a = number.second; - ImGui::TableNextRow(); - - ImGui::PushID(a.id); - { - ImGui::TableNextColumn(); - ImGui::PushID(&a); - { - if (ImGui::Selectable(a.number.c_str(), m_SelectedAccountIdx == idx, ImGuiSelectableFlags_SpanAllColumns)) { - m_ResetSelection(); - m_UpdateTransactions(a.id); - m_SelectedAccountIdx = idx; - } - } - ImGui::PopID(); - m_drawAccountMenu(a); - - ImGui::TableNextColumn(); - ImGui::Text("%s", a.name.c_str()); - - ImGui::TableNextColumn(); - ImGui::Text("%s", a.type.c_str()); - - ImGui::TableNextColumn(); - ImGui::Text("%u", a.count); - } - ImGui::PopID(); - - ++idx; - } - ImGui::EndTable(); - } - ImGui::EndMenu(); - } - } - ImGui::EndMenu(); - } - } - ImGui::EndMenu(); - } -} - -void AccountPane::m_drawCreationMenu(FrameActionSystem& vFrameActionSystem) { - if (ImGui::BeginMenu("Add")) { - if (ImGui::MenuItem("Bank")) { - m_BankDialog.show(DataDialogMode::MODE_CREATION); - } - if (ImGui::MenuItem("Account")) { - m_AccountDialog.show(DataDialogMode::MODE_CREATION); - } - if (ImGui::MenuItem("Entity")) { - m_EntityDialog.show(DataDialogMode::MODE_CREATION); - } - if (ImGui::MenuItem("Category")) { - m_CategoryDialog.show(DataDialogMode::MODE_CREATION); - } - if (ImGui::MenuItem("Operation")) { - m_OperationDialog.show(DataDialogMode::MODE_CREATION); - } - if (ImGui::MenuItem("Transaction")) { - m_TransactionDialog.show(DataDialogMode::MODE_CREATION); - } - ImGui::EndMenu(); - } + m_TransactionsTable.refreshDatas(); } std::string AccountPane::getXml(const std::string& vOffset, const std::string& vUserDatas) { @@ -613,223 +188,86 @@ bool AccountPane::setFromXml(tinyxml2::XMLElement* vElem, tinyxml2::XMLElement* return true; } -void AccountPane::m_Clear() { - m_SelectedBroker.reset(); // must be reset before quit since point on the memroy of a plugin - m_DataBrokerModules.clear(); - m_Datas.clear(); +void AccountPane::m_drawCreationMenu() { + if (ImGui::BeginMenu("Add")) { + if (ImGui::MenuItem("Bank")) { + m_BankDialog.show(DataDialogMode::MODE_CREATION); + } + if (ImGui::MenuItem("Account")) { + m_AccountDialog.show(DataDialogMode::MODE_CREATION); + } + if (ImGui::MenuItem("Entity")) { + m_EntityDialog.show(DataDialogMode::MODE_CREATION); + } + if (ImGui::MenuItem("Category")) { + m_CategoryDialog.show(DataDialogMode::MODE_CREATION); + } + if (ImGui::MenuItem("Operation")) { + m_OperationDialog.show(DataDialogMode::MODE_CREATION); + } + if (ImGui::MenuItem("Transaction")) { + m_TransactionsTable.getTransactionDialogRef().show(DataDialogMode::MODE_CREATION); + } + ImGui::EndMenu(); + } } -void AccountPane::m_GetAvailableDataBrokers() { - m_Clear(); - auto modules = PluginManager::Instance()->GetPluginModulesInfos(); - for (const auto& mod : modules) { - if (mod.type == Cash::PluginModuleType::DATA_BROKER) { - auto ptr = std::dynamic_pointer_cast(PluginManager::Instance()->CreatePluginModule(mod.label)); - if (ptr != nullptr) { - m_DataBrokerModules[mod.path][mod.label] = ptr; +void AccountPane::m_drawImportMenu(FrameActionSystem& vFrameActionSystem) { + if (ImGui::BeginMenu("Import")) { + for (const auto& broker : m_DataBrokerModules) { + if (ImGui::BeginMenu(broker.first.c_str())) { + for (const auto& way : broker.second) { + if (ImGui::MenuItem(way.first.c_str())) { + if (way.second != nullptr) { + m_SelectedBroker = way.second; + vFrameActionSystem.Clear(); + vFrameActionSystem.Add([&way]() { + const auto& ext = way.second->getFileExt(); + IGFD::FileDialogConfig config; + config.countSelectionMax = 0; + config.flags = ImGuiFileDialogFlags_Modal; + ImGuiFileDialog::Instance()->OpenDialog("Import Datas", "Import Datas from File", ext.c_str(), config); + return true; + }); + } + } + } + ImGui::EndMenu(); } } + ImGui::EndMenu(); } } -void AccountPane::m_ImportFromFiles(const std::vector& vFiles) { +void AccountPane::m_importFromFiles(const std::vector& vFiles) { m_ImportThread.start( // "Import Datas", m_SelectedBroker, vFiles, [this]() { - m_refreshDatas(); - m_refreshFiltering(); + m_TransactionsTable.refreshDatas(); + m_TransactionsTable.refreshFiltering(); }, nullptr); } -void AccountPane::m_ResetFiltering() { - m_Datas.transactions_filtered = m_Datas.transactions; - m_Datas.transactions_filtered_rowids = {}; - m_SearchInputTexts = {}; - m_SearchTokens = {}; - m_FilteringMode = FilteringMode::FILTERING_MODE_BY_SEARCH; - m_FilteredSelectedTransactions.clear(); - m_refreshFiltering(); -} - -void AccountPane::m_refreshFiltering() { - m_Datas.transactions_filtered.clear(); - m_Datas.transactions_filtered_rowids.clear(); - bool use = false; - double solde = m_CurrentBaseSolde; - m_TotalDebit = 0.0; - m_TotalCredit = 0.0; - for (auto t : m_Datas.transactions) { - use = true; - if (m_FilteringMode == FilteringMode::FILTERING_MODE_BY_SEARCH) { - for (size_t idx = 0; idx < SearchColumns::SEARCH_COLUMN_Count; ++idx) { - const auto& tk = m_SearchTokens.at(idx); - if (!tk.empty()) { - use &= (t.optimized.at(idx).find(tk) != std::string::npos); - } +void AccountPane::m_getAvailableDataBrokers() { + m_clear(); + auto modules = PluginManager::Instance()->GetPluginModulesInfos(); + for (const auto& mod : modules) { + if (mod.type == Cash::PluginModuleType::DATA_BROKER) { + auto ptr = std::dynamic_pointer_cast(PluginManager::Instance()->CreatePluginModule(mod.label)); + if (ptr != nullptr) { + m_DataBrokerModules[mod.path][mod.label] = ptr; } - } else if (m_FilteringMode == FilteringMode::FILTERING_MODE_BY_SELECTED_ROW_IDS) { - use = (m_FilteredSelectedTransactions.find(t.id) != m_FilteredSelectedTransactions.end()); } - if (use) { - t.solde = solde += t.debit + t.credit; - m_Datas.transactions_filtered.push_back(t); - m_Datas.transactions_filtered_rowids.emplace(t.id); - m_TotalDebit += t.debit; - m_TotalCredit += t.credit; - } - } -} - -void AccountPane::m_FilterSelection() { - m_FilteringMode = FilteringMode::FILTERING_MODE_BY_SELECTED_ROW_IDS; - m_FilteredSelectedTransactions = m_SelectedTransactions; - m_refreshFiltering(); -} - -void AccountPane::m_SelectOrDeselectRow(const Transaction& vTransaction) { - if (m_SelectedTransactions.find(vTransaction.id) != m_SelectedTransactions.end()) { - m_SelectedTransactions.erase(vTransaction.id); // deselection - } else { - m_SelectedTransactions.emplace(vTransaction.id); // selection - } -} - -bool AccountPane::m_IsRowSelected(const RowID& vRowID) const { - return (m_SelectedTransactions.find(vRowID) != m_SelectedTransactions.end()); -} - -void AccountPane::m_ResetSelection() { - m_SelectedTransactions.clear(); -} - -void AccountPane::m_SelectCurrentRows() { - m_SelectedTransactions = m_Datas.transactions_filtered_rowids; -} - -void AccountPane::m_SelectPossibleDuplicateEntryOnPricesAndDates() { - if (m_SelectedAccountIdx < m_Datas.accounts.size()) { - RowID account_id = m_Datas.accounts.at(m_SelectedAccountIdx).id; - m_ResetSelection(); - DataBase::Instance()->GetDuplicateTransactionsOnDatesAndAmount( // - account_id, // - [this](const RowID& vRowID) { - if (m_Datas.transactions_filtered_rowids.find(vRowID) != // - m_Datas.transactions_filtered_rowids.end()) { - m_SelectedTransactions.emplace(vRowID); // select row id - } - }); - } -} - -void AccountPane::m_SelectUnConfirmedTransactions() { - if (m_SelectedAccountIdx < m_Datas.accounts.size()) { - RowID account_id = m_Datas.accounts.at(m_SelectedAccountIdx).id; - m_ResetSelection(); - DataBase::Instance()->GetUnConfirmedTransactions( // - account_id, // - [this](const RowID& vRowID) { - if (m_Datas.transactions_filtered_rowids.find(vRowID) != // - m_Datas.transactions_filtered_rowids.end()) { - m_SelectedTransactions.emplace(vRowID); // select row id - } - }); - } -} - -void AccountPane::m_SelectEmptyColumn(const SearchColumns& vColumn) { - m_SelectedTransactions.clear(); - for (const auto& t : m_Datas.transactions_filtered) { - if (vColumn == SearchColumns::SEARCH_COLUMN_COMMENT) { - if (t.comment.empty()) { - m_SelectedTransactions.emplace(t.id); - } - } else if (vColumn == SearchColumns::SEARCH_COLUMN_ENTITY) { - if (t.entity.empty()) { - m_SelectedTransactions.emplace(t.id); - } - } else if (vColumn == SearchColumns::SEARCH_COLUMN_CATEGORY) { - if (t.category.empty()) { - m_SelectedTransactions.emplace(t.id); - } - } else if (vColumn == SearchColumns::SEARCH_COLUMN_OPERATION) { - if (t.operation.empty()) { - m_SelectedTransactions.emplace(t.id); - } - } } } -void AccountPane::m_GroupTransactions(const GroupingMode& vGroupingMode) { - m_GroupingMode = vGroupingMode; - if (m_SelectedAccountIdx < m_Datas.accounts.size()) { - m_UpdateTransactions(m_Datas.accounts.at(m_SelectedAccountIdx).id); - } -} - -void AccountPane::m_UpdateBanks() { - m_Datas.bankNames.clear(); - DataBase::Instance()->GetBanks( // - [this](const BankName& vUserName, const std::string& /*vUrl*/) { // - m_Datas.bankNames.push_back(vUserName); - }); -} - -void AccountPane::m_UpdateEntities() { - m_Datas.entityNames.clear(); - DataBase::Instance()->GetEntities( // - [this](const EntityName& vEntityName) { // - m_Datas.entityNames.push_back(vEntityName); - }); -} - -void AccountPane::m_UpdateCategories() { - m_Datas.categoryNames.clear(); - DataBase::Instance()->GetCategories( // - [this](const CategoryName& vCategoryName) { // - m_Datas.categoryNames.push_back(vCategoryName); - }); -} - -void AccountPane::m_UpdateOperations() { - m_Datas.operationNames.clear(); - DataBase::Instance()->GetOperations( // - [this](const OperationName& vOperationName) { // - m_Datas.operationNames.push_back(vOperationName); - }); -} - -void AccountPane::m_UpdateAccounts() { - m_Accounts.clear(); - m_Datas.accounts.clear(); - m_Datas.accountNumbers.clear(); - DataBase::Instance()->GetAccounts( // - [this](const RowID& vRowID, - const BankName& vBankName, - const BankAgency& vBankAgency, - const AccountType& vAccountType, - const AccountName& vAccountName, - const AccountNumber& vAccountNumber, - const AccounBaseSolde& vBaseSolde, - const TransactionsCount& vCount) { // - Account a; - a.id = vRowID; - a.bank = vBankName; - a.agency = vBankAgency; - a.type = vAccountType; - a.name = vAccountName; - a.number = vAccountNumber; - a.base_solde = vBaseSolde; - a.count = vCount; - m_Datas.accounts.push_back(a); - m_Datas.accountNumbers.push_back(vAccountNumber); - m_Accounts[vBankName + "##BankName"][vBankAgency + "##BankAgency"][vAccountNumber] = a; - }); - if (m_SelectedAccountIdx < m_Datas.accounts.size()) { - m_UpdateTransactions(m_Datas.accounts.at(m_SelectedAccountIdx).id); - } +void AccountPane::m_clear() { + m_SelectedBroker.reset(); // must be reset before quit since point on the memroy of a plugin + m_DataBrokerModules.clear(); + m_TransactionsTable.clear(); } void AccountPane::m_drawAccountMenu(const Account& vAccount) { @@ -851,182 +289,3 @@ void AccountPane::m_drawAccountMenu(const Account& vAccount) { } ImGui::PopID(); } - -void AccountPane::m_UpdateTransactions(const RowID& vAccountID) { - m_Datas.transactions.clear(); - const auto& zero_based_account_id = vAccountID - 1; - if (zero_based_account_id < m_Datas.accounts.size()) { - double solde = m_CurrentBaseSolde = m_Datas.accounts.at(zero_based_account_id).base_solde; - const auto& account_number = m_Datas.accounts.at(zero_based_account_id).number; - if (m_IsGroupingModeTransactions()) { - DataBase::Instance()->GetTransactions( // - vAccountID, // - [this, &solde, account_number]( // - const RowID& vTransactionID, - const EntityName& vEntityName, - const CategoryName& vCategoryName, - const OperationName& vOperationName, - const SourceName& vSourceName, - const TransactionDate& vDate, - const TransactionDescription& vDescription, - const TransactionComment& vComment, - const TransactionAmount& vAmount, - const TransactionConfirmed& vConfirmed, - const TransactionHash& vHash) { // - solde += vAmount; - Transaction t; - t.id = vTransactionID; - t.account = account_number; - t.optimized[0] = ct::toLower(t.date = vDate); - t.optimized[1] = ct::toLower(t.description = vDescription); - t.optimized[2] = ct::toLower(t.comment = vComment); - t.optimized[3] = ct::toLower(t.entity = vEntityName); - t.optimized[4] = ct::toLower(t.category = vCategoryName); - t.optimized[5] = ct::toLower(t.operation = vOperationName); - t.hash = vHash; - t.source = vSourceName; - t.debit = vAmount < 0.0 ? vAmount : 0.0; - t.credit = vAmount > 0.0 ? vAmount : 0.0; - t.amount = vAmount; - t.confirmed = vConfirmed; - t.solde = solde; - m_Datas.transactions.push_back(t); - }); - } else { - DataBase::Instance()->GetGroupedTransactions( // - vAccountID, - GroupBy::DATES, - (DateFormat)(m_GroupingMode-1), - [this]( // - const RowID& vRowID, - const TransactionDate& vTransactionDate, - const TransactionDescription& vTransactionDescription, - const EntityName& vEntityName, - const CategoryName& vCategoryName, - const OperationName& vOperationName, - const TransactionDebit& vTransactionDebit, - const TransactionCredit& vTransactionCredit) { - Transaction t; - t.id = vRowID; - t.date = vTransactionDate; - t.description = "-- grouped --"; - t.entity = "-- grouped --"; - t.category = "-- grouped --"; - t.operation = "-- grouped --"; - t.debit = vTransactionDebit; - t.credit = vTransactionCredit; - t.amount = vTransactionDebit + vTransactionCredit; - m_Datas.transactions.push_back(t); - }); - } - } - m_refreshFiltering(); -} - -bool AccountPane::m_IsGroupingModeTransactions() { - return (m_GroupingMode == GroupingMode::GROUPING_MODE_TRANSACTIONS); -} - -void AccountPane::m_drawTransactionMenu(const Transaction& vTransaction) { - if (!m_SelectedTransactions.empty()) { - const auto* ptr = &vTransaction; - ImGui::PushID(ptr); - if (ImGui::BeginPopupContextItem( // - NULL, // - ImGuiPopupFlags_NoOpenOverItems | // - ImGuiPopupFlags_MouseButtonRight | // - ImGuiPopupFlags_NoOpenOverExistingPopup)) { - if (ImGui::MenuItem("Update selection")) { - std::vector transactions_to_update; - for (const auto& trans : m_Datas.transactions_filtered) { - if (m_SelectedTransactions.find(trans.id) != m_SelectedTransactions.end()) { - transactions_to_update.push_back(trans); - } - } - if (transactions_to_update.size() > 1U) { - m_TransactionDialog.setTransactionsToUpdate(transactions_to_update); - m_TransactionDialog.show(DataDialogMode::MODE_UPDATE_ALL); - } else if (transactions_to_update.size() == 1U) { - m_TransactionDialog.setTransaction(transactions_to_update.front()); - m_TransactionDialog.show(DataDialogMode::MODE_UPDATE_ONCE); - } - } - if (ImGui::MenuItem("Delete selection")) { - std::vector transactions_to_delete; - for (const auto& trans : m_Datas.transactions_filtered) { - if (m_SelectedTransactions.find(trans.id) != m_SelectedTransactions.end()) { - transactions_to_delete.push_back(trans); - } - } - m_TransactionDialog.setTransactionsToDelete(transactions_to_delete); - m_TransactionDialog.show(DataDialogMode::MODE_DELETE_ALL); - } - ImGui::EndPopup(); - } - ImGui::PopID(); - } -} - -void AccountPane::m_drawSearchRow() { - bool change = false; - bool reset = false; - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - if (m_IsGroupingModeTransactions()) { - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); - if (ImGui::ContrastedButton("R", nullptr, nullptr, ImGui::GetColumnWidth(0))) { - reset = true; - } - ImGui::PopStyleVar(); - } - for (size_t idx = 0; idx < 10; ++idx) { - ImGui::TableNextColumn(); - if (idx < SearchColumns::SEARCH_COLUMN_Count) { - if (m_IsGroupingModeTransactions()) { - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); - if (m_SearchInputTexts.at(idx).DisplayInputText(ImGui::GetColumnWidth(idx), "", "")) { - m_SearchTokens[idx] = ct::toLower(m_SearchInputTexts.at(idx).GetText()); - m_FilteringMode = FilteringMode::FILTERING_MODE_BY_SEARCH; - change = true; - } - ImGui::PopStyleVar(); - } - } else if (idx == 6) { - m_drawAmount(m_TotalDebit); - } else if (idx == 7) { - m_drawAmount(m_TotalCredit); - } else if (idx == 8) { - // m_drawAmount(m_CurrentBaseSolde); - } else if (idx == 9) { - ImGui::Text( // - "[%u/%u]", - (uint32_t)m_Datas.transactions_filtered.size(), - (uint32_t)m_Datas.transactions.size()); - } - } - if (reset) { - m_ResetFiltering(); - } - if (change) { - m_refreshFiltering(); - } -} - -void AccountPane::m_drawAmount(const double& vAmount) { - if (vAmount < 0.0) { - const auto& bad_color = ImGui::GetColorU32(ImVec4(1, 0, 0, 1)); - ImGui::PushStyleColor(ImGuiCol_Text, bad_color); - ImGui::Text("%.2f", vAmount); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", vAmount); - ImGui::PopStyleColor(); - } else if (vAmount > 0.0) { - const auto& good_color = ImGui::GetColorU32(ImVec4(0, 1, 0, 1)); - ImGui::PushStyleColor(ImGuiCol_Text, good_color); - ImGui::Text("%.2f", vAmount); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", vAmount); - ImGui::PopStyleColor(); - } else { - ImGui::Text("%.2f", vAmount); - ImGui::HideByFilledRectForHiddenMode(SettingsDialog::Instance()->isHiddenMode(), "%.2f", vAmount); - } -} diff --git a/src/Panes/AccountPane.h b/src/Panes/AccountPane.h index c00a0a3..75174b2 100644 --- a/src/Panes/AccountPane.h +++ b/src/Panes/AccountPane.h @@ -8,69 +8,29 @@ #include #include + #include + #include #include #include #include #include #include +#include class ProjectFile; class AccountPane : public AbstractPane, public conf::ConfigAbstract { private: - struct Datas { - std::vector bankNames; - std::vector entityNames; - std::vector categoryNames; - std::vector operationNames; - std::vector accounts; - std::vector accountNumbers; - std::vector transactions; - std::vector transactions_filtered; - std::set transactions_filtered_rowids; - void clear() { - accounts.clear(); - bankNames.clear(); - transactions.clear(); - categoryNames.clear(); - accountNumbers.clear(); - operationNames.clear(); - transactions_filtered.clear(); - } - } m_Datas; - - DataBrockerContainer m_DataBrokerModules; - Cash::BankStatementModuleWeak m_SelectedBroker; - ImGuiListClipper m_TransactionsListClipper; - size_t m_SelectedAccountIdx = 0U; - + TransactionsTable m_TransactionsTable; ImportWorkerThread m_ImportThread; - BankDialog m_BankDialog; AccountDialog m_AccountDialog; EntityDialog m_EntityDialog; CategoryDialog m_CategoryDialog; OperationDialog m_OperationDialog; - TransactionDialog m_TransactionDialog; - - TransactionAmount m_CurrentBaseSolde = 0.0; - TransactionAmount m_TotalDebit = 0.0; - TransactionAmount m_TotalCredit = 0.0; - - std::array m_SearchInputTexts; - std::array m_SearchTokens; - FilteringMode m_FilteringMode = FilteringMode::FILTERING_MODE_BY_SEARCH; - GroupingMode m_GroupingMode = GroupingMode::GROUPING_MODE_TRANSACTIONS; - - // selection - std::set m_SelectedTransactions; - std::set m_FilteredSelectedTransactions; - int32_t m_CurrSelectedItemIdx = -1; - int32_t m_LastSelectedItemIdx = -1; - - // accounts display - std::map>> m_Accounts; + DataBrockerContainer m_DataBrokerModules; + Cash::BankStatementModuleWeak m_SelectedBroker; public: bool Init() override; @@ -88,45 +48,12 @@ class AccountPane : public AbstractPane, public conf::ConfigAbstract { bool setFromXml(tinyxml2::XMLElement* vElem, tinyxml2::XMLElement* vParent, const std::string& vUserDatas) override; private: - void m_drawMenu(FrameActionSystem& vFrameActionSystem); - void m_displayTransactions(); - void m_refreshDatas(); - - void m_drawAccountsMenu(FrameActionSystem& vFrameActionSystem); - void m_drawCreationMenu(FrameActionSystem& vFrameActionSystem); - void m_drawImportMenu(FrameActionSystem& vFrameActionSystem); - void m_drawSelectMenu(FrameActionSystem& vFrameActionSystem); - void m_drawDebugMenu(FrameActionSystem& vFrameActionSystem); - void m_drawGroupingMenu(FrameActionSystem& vFrameActionSystem); - - void m_Clear(); - void m_GetAvailableDataBrokers(); - void m_ResetFiltering(); - void m_refreshFiltering(); - void m_SelectOrDeselectRow(const Transaction& vTransaction); - bool m_IsRowSelected(const RowID& vRowID) const; - void m_ResetSelection(); - void m_SelectCurrentRows(); - void m_FilterSelection(); - void m_SelectPossibleDuplicateEntryOnPricesAndDates(); - void m_SelectUnConfirmedTransactions(); - void m_SelectEmptyColumn(const SearchColumns& vColumn); - void m_GroupTransactions(const GroupingMode& vGroupingMode); - void m_UpdateBanks(); - void m_UpdateAccounts(); - void m_UpdateEntities(); - void m_UpdateCategories(); - void m_UpdateOperations(); - void m_UpdateTransactions(const RowID& vAccountID); - - bool m_IsGroupingModeTransactions(); - + void m_importFromFiles(const std::vector& vFiles); void m_drawAccountMenu(const Account& vAccount); - void m_drawTransactionMenu(const Transaction& vTransaction); - void m_drawSearchRow(); - void m_drawAmount(const double& vAmount); - - void m_ImportFromFiles(const std::vector& vFiles); + void m_drawCreationMenu(); + void m_drawImportMenu(FrameActionSystem& vFrameActionSystem); + void m_getAvailableDataBrokers(); + void m_clear(); public: // singleton static std::shared_ptr Instance() {