diff --git a/src/assetspanel.cpp b/src/assetspanel.cpp index 5acfe69950..851ff66794 100644 --- a/src/assetspanel.cpp +++ b/src/assetspanel.cpp @@ -56,24 +56,26 @@ mmAssetsListCtrl::mmAssetsListCtrl(mmAssetsPanel* cp, wxWindow *parent, wxWindow mmThemeMetaColour(this, meta::COLOR_LISTPANEL); m_columns.push_back(PANEL_COLUMN(" ", 25, wxLIST_FORMAT_LEFT, false)); + m_real_columns.push_back(m_panel->COL_ICON); m_columns.push_back(PANEL_COLUMN(_("ID"), wxLIST_AUTOSIZE, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(m_panel->COL_ID); m_columns.push_back(PANEL_COLUMN(_("Name"), 150, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_panel->COL_NAME); m_columns.push_back(PANEL_COLUMN(_("Date"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_panel->COL_DATE); m_columns.push_back(PANEL_COLUMN(_("Type"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_panel->COL_TYPE); m_columns.push_back(PANEL_COLUMN(_("Initial Value"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(m_panel->COL_VALUE_INITIAL); m_columns.push_back(PANEL_COLUMN(_("Current Value"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(m_panel->COL_VALUE_CURRENT); m_columns.push_back(PANEL_COLUMN(_("Notes"), 450, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_panel->COL_NOTES); m_col_width = "ASSETS_COL%d_WIDTH"; m_col_idstr = "ASSETS"; - for (const auto& entry : m_columns) - { - int count = GetColumnCount(); - InsertColumn(count - , entry.HEADER - , entry.FORMAT - , Model_Setting::instance().GetIntSetting(wxString::Format(m_col_width, count), entry.WIDTH)); - } + + CreateColumns(); // load the global variables m_default_sort_column = m_panel->col_sort(); @@ -139,7 +141,7 @@ void mmAssetsListCtrl::OnListLeftClick(wxMouseEvent& event) wxString mmAssetsListCtrl::OnGetItemText(long item, long column) const { - return m_panel->getItem(item, column); + return m_panel->getItem(item, m_real_columns[column]); } void mmAssetsListCtrl::OnListItemSelected(wxListEvent& event) diff --git a/src/assetspanel.h b/src/assetspanel.h index b430b1f5de..fd6ae9d92c 100644 --- a/src/assetspanel.h +++ b/src/assetspanel.h @@ -93,6 +93,19 @@ class mmAssetsPanel : public mmPanelBase ICON_DOWNARROW }; + enum EColumn + { + COL_ICON = 0, + COL_ID, + COL_NAME, + COL_DATE, + COL_TYPE, + COL_VALUE_INITIAL, + COL_VALUE_CURRENT, + COL_NOTES, + COL_MAX, // number of columns + }; + mmAssetsPanel(mmGUIFrame* frame, wxWindow *parent, wxWindowID winid, const wxString& name="mmAssetsPanel"); mmGUIFrame* m_frame = nullptr; @@ -147,18 +160,6 @@ class mmAssetsPanel : public mmPanelBase IDC_PANEL_ASSET_STATIC_DETAILS = wxID_HIGHEST + 1220, IDC_PANEL_ASSET_STATIC_DETAILS_MINI, }; - enum EColumn - { - COL_ICON = 0, - COL_ID, - COL_NAME, - COL_DATE, - COL_TYPE, - COL_VALUE_INITIAL, - COL_VALUE_CURRENT, - COL_NOTES, - COL_MAX, // number of columns - }; }; inline void mmAssetsPanel::RefreshList(){ m_listCtrlAssets->doRefreshItems(); } diff --git a/src/billsdepositspanel.cpp b/src/billsdepositspanel.cpp index 3c12d296c9..832d45e14d 100644 --- a/src/billsdepositspanel.cpp +++ b/src/billsdepositspanel.cpp @@ -128,35 +128,46 @@ billsDepositsListCtrl::billsDepositsListCtrl(mmBillsDepositsPanel* bdp, wxWindow m_asc = Model_Setting::instance().GetBoolSetting("BD_ASC", true); m_columns.push_back(PANEL_COLUMN(" ", 25, wxLIST_FORMAT_LEFT, false)); + m_real_columns.push_back(m_bdp->COL_ICON); m_columns.push_back(PANEL_COLUMN(_("ID"), wxLIST_AUTOSIZE, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(m_bdp->COL_ID); m_columns.push_back(PANEL_COLUMN(_("Date Paid"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_PAYMENT_DATE); m_columns.push_back(PANEL_COLUMN(_("Date Due"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_DUE_DATE); m_columns.push_back(PANEL_COLUMN(_("Account"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_ACCOUNT); m_columns.push_back(PANEL_COLUMN(_("Payee"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_PAYEE); m_columns.push_back(PANEL_COLUMN(_("Status"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_STATUS); m_columns.push_back(PANEL_COLUMN(_("Category"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_CATEGORY); m_columns.push_back(PANEL_COLUMN(_("Tags"), 200, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_TAGS); m_columns.push_back(PANEL_COLUMN(_("Type"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_TYPE); m_columns.push_back(PANEL_COLUMN(_("Amount"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(m_bdp->COL_AMOUNT); m_columns.push_back(PANEL_COLUMN(_("Frequency"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_FREQUENCY); m_columns.push_back(PANEL_COLUMN(_("Repetitions"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(m_bdp->COL_REPEATS); m_columns.push_back(PANEL_COLUMN(_("Autorepeat"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_AUTO); m_columns.push_back(PANEL_COLUMN(_("Payment"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_DAYS); m_columns.push_back(PANEL_COLUMN(_("Number"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_NUMBER); m_columns.push_back(PANEL_COLUMN(_("Notes"), 150, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(m_bdp->COL_NOTES); m_col_width = "BD_COL%d_WIDTH"; m_col_idstr = "BD"; m_default_sort_column = m_bdp->col_sort(); - for (const auto& entry : m_columns) - { - int count = GetColumnCount(); - InsertColumn(count - , entry.HEADER - , entry.FORMAT - , Model_Setting::instance().GetIntSetting(wxString::Format(m_col_width, count), entry.WIDTH)); - } + CreateColumns(); + } billsDepositsListCtrl::~billsDepositsListCtrl() @@ -570,7 +581,7 @@ const wxString mmBillsDepositsPanel::GetRemainingDays(const Model_Billsdeposits: wxString billsDepositsListCtrl::OnGetItemText(long item, long column) const { - return m_bdp->getItem(item, column); + return m_bdp->getItem(item, m_real_columns[column]); } void billsDepositsListCtrl::OnListItemSelected(wxListEvent& event) diff --git a/src/billsdepositspanel.h b/src/billsdepositspanel.h index e6c2f424aa..fa3dd85279 100644 --- a/src/billsdepositspanel.h +++ b/src/billsdepositspanel.h @@ -86,6 +86,28 @@ class mmBillsDepositsPanel : public mmPanelBase ICON_DOWNARROW }; + enum EColumn + { + COL_ICON = 0, + COL_ID, + COL_PAYMENT_DATE, + COL_DUE_DATE, + COL_ACCOUNT, + COL_PAYEE, + COL_STATUS, + COL_CATEGORY, + COL_TAGS, + COL_TYPE, + COL_AMOUNT, + COL_FREQUENCY, + COL_REPEATS, + COL_AUTO, + COL_DAYS, + COL_NUMBER, + COL_NOTES, + COL_MAX, // number of columns + }; + mmBillsDepositsPanel(wxWindow *parent , wxWindowID winid = wxID_ANY , const wxPoint& pos = wxDefaultPosition @@ -146,28 +168,6 @@ class mmBillsDepositsPanel : public mmPanelBase wxStaticText* m_infoTextMini = nullptr; wxDate m_today; - enum EColumn - { - COL_ICON = 0, - COL_ID, - COL_PAYMENT_DATE, - COL_DUE_DATE, - COL_ACCOUNT, - COL_PAYEE, - COL_STATUS, - COL_CATEGORY, - COL_TAGS, - COL_TYPE, - COL_AMOUNT, - COL_FREQUENCY, - COL_REPEATS, - COL_AUTO, - COL_DAYS, - COL_NUMBER, - COL_NOTES, - COL_MAX, // number of columns - }; - bool transFilterActive_; void OnFilterTransactions(wxCommandEvent& WXUNUSED(event)); wxButton* m_bitmapTransFilter = nullptr; diff --git a/src/mmchecking_list.cpp b/src/mmchecking_list.cpp index 1eb63e8e4f..8afe1bebc2 100644 --- a/src/mmchecking_list.cpp +++ b/src/mmchecking_list.cpp @@ -266,13 +266,13 @@ TransactionListCtrl::TransactionListCtrl( wxAcceleratorTable tab(sizeof(entries) / sizeof(*entries), entries); SetAcceleratorTable(tab); - resetColumns(); - // V2 used as now maps to real column names and this resets everything to default // to avoid strange column widths when this code version is first m_col_width = m_cp->isAllAccounts_ ? "ALLTRANS_COLV2%d_WIDTH" : "CHECK2_COLV2%d_WIDTH"; m_col_idstr = m_cp->isAllAccounts_ ? "ALLTRANS" : "CHECK2"; + resetColumns(); + m_default_sort_column = COL_DEF_SORT; m_today = Option::instance().UseTransDateTime() ? wxDateTime::Now().FormatISOCombined() : wxDateTime(23, 59, 59, 999).FormatISOCombined(); @@ -354,25 +354,13 @@ void TransactionListCtrl::resetColumns() } m_columns.push_back(PANEL_COLUMN(_("Last Updated"), wxLIST_AUTOSIZE, wxLIST_FORMAT_LEFT, true)); m_real_columns.push_back(COL_UPDATEDTIME); + + CreateColumns(); } TransactionListCtrl::~TransactionListCtrl() {} -//---------------------------------------------------------------------------- -void TransactionListCtrl::createColumns(mmListCtrl &lst) -{ - - for (const auto& entry : m_columns) - { - int count = lst.GetColumnCount(); - lst.InsertColumn(count - , entry.HEADER - , entry.FORMAT - , Model_Setting::instance().GetIntSetting(wxString::Format(m_col_width, GetRealColumn(count)), entry.WIDTH)); - } -} - void TransactionListCtrl::setExtraTransactionData(const bool single) { bool isForeign = false; diff --git a/src/mmchecking_list.h b/src/mmchecking_list.h index e139f1861e..f6f3dc069b 100644 --- a/src/mmchecking_list.h +++ b/src/mmchecking_list.h @@ -37,7 +37,7 @@ class TransactionListCtrl : public mmListCtrl ~TransactionListCtrl(); - void createColumns(mmListCtrl &lst); + void createColumns(); Model_Checking::Full_Data_Set m_trans; void markSelectedTransaction(); void DeleteTransactionsByStatus(const wxString& status); @@ -74,7 +74,6 @@ class TransactionListCtrl : public mmListCtrl }; EColumn toEColumn(const unsigned long col); -public: EColumn g_sortcol = COL_DEF_SORT; // index of primary column to sort by EColumn prev_g_sortcol = COL_DEF_SORT2; // index of secondary column to sort by bool g_asc = true; // asc\desc sorting for primary sort column @@ -238,6 +237,7 @@ inline std::vector<int> TransactionListCtrl::getSelectedForCopy() const { return inline std::vector<int> TransactionListCtrl::getSelectedId() const { return m_selected_id; } inline void TransactionListCtrl::setVisibleItemIndex(long v) { m_topItemIndex = v; } +inline void TransactionListCtrl::createColumns(){ mmListCtrl::CreateColumns(); } #endif // MM_EX_CHECKING_LIST_H_ diff --git a/src/mmcheckingpanel.cpp b/src/mmcheckingpanel.cpp index 21c1203945..6bc232fe79 100644 --- a/src/mmcheckingpanel.cpp +++ b/src/mmcheckingpanel.cpp @@ -400,34 +400,6 @@ void mmCheckingPanel::CreateControls() m_listCtrlAccount->setSortOrder(m_listCtrlAccount->g_asc); m_listCtrlAccount->setSortColumn(m_listCtrlAccount->g_sortcol); - // Get sorted columns list and update the sorted columns with missing columns if needed. - wxArrayString columnList, sortedColumnList; - sortedColumnList = m_listCtrlAccount->GetColumnsOrder(); - wxLogDebug("CreateControls: getColumnList() = %s", wxJoin(sortedColumnList, '|')); - - // sort m_columns according to sortedColumnsList - std::vector<PANEL_COLUMN> sortedColumns = {}; - std::vector<int> sortedRealColumns = {}; - for (const auto& i : sortedColumnList) - { - for (unsigned int j = 0; j < m_listCtrlAccount->m_columns.size(); j++) - { - auto k = m_listCtrlAccount->m_columns[j]; - auto l = m_listCtrlAccount->m_real_columns[j]; - if (wxString::Format("%d", j) == i) - { - sortedColumns.push_back(k); - sortedRealColumns.push_back(l); - break; - } - } - } - - m_listCtrlAccount->m_columns = sortedColumns; - m_listCtrlAccount->m_real_columns = sortedRealColumns; - - m_listCtrlAccount->createColumns(*m_listCtrlAccount); - // load the global variables m_sortSaveTitle = isAllAccounts_ ? "ALLTRANS" : (isTrash_ ? "DELETED" : "CHECK"); @@ -936,7 +908,7 @@ void mmCheckingPanel::ResetColumnView() { m_listCtrlAccount->DeleteAllColumns(); m_listCtrlAccount->resetColumns(); - m_listCtrlAccount->createColumns(*m_listCtrlAccount); + m_listCtrlAccount->createColumns(); m_listCtrlAccount->refreshVisualList(); } diff --git a/src/mmpanelbase.cpp b/src/mmpanelbase.cpp index 2e34c0ab82..a47623a8b0 100644 --- a/src/mmpanelbase.cpp +++ b/src/mmpanelbase.cpp @@ -44,6 +44,7 @@ mmListCtrl::~mmListCtrl() Save the column widths of the list control. This will ensure that the column widths get set incase the OnItemResize does not work on some systems. */ + std::vector<int> columnOrder; for (int column_number = 0; column_number < GetColumnCount(); ++column_number) { int column_width = GetColumnWidth(column_number); @@ -51,7 +52,16 @@ mmListCtrl::~mmListCtrl() { SetColumnWidthSetting(column_number, column_width); } + +#ifdef wxHAS_LISTCTRL_COLUMN_ORDER + if (m_real_columns.size() > 0) + columnOrder.push_back(m_real_columns[GetColumnIndexFromOrder(column_number)]); +#endif + } + + if (!columnOrder.empty()) + SetColumnOrder(columnOrder); } wxListItemAttr* mmListCtrl::OnGetItemAttr(long row) const @@ -108,6 +118,28 @@ void mmListCtrl::OnItemResize(wxListEvent& event) Model_Setting::instance().Set(wxString::Format(m_col_width, GetRealColumn(i)), width); } +void mmListCtrl::CreateColumns() +{ + std::vector<int> columnOrder = GetColumnOrder(); + std::vector<PANEL_COLUMN> sortedColumns = {}; + for (unsigned int i = 0; i < columnOrder.size(); i++) + { + int index = std::find(m_real_columns.begin(), m_real_columns.end(), columnOrder[i]) - m_real_columns.begin(); + if (index < m_columns.size()) + sortedColumns.push_back(m_columns[index]); + } + + m_real_columns = columnOrder; + m_columns = sortedColumns; + + for (const auto& entry : m_columns) + { + int count = GetColumnCount(); + InsertColumn(count, entry.HEADER, entry.FORMAT, + Model_Setting::instance().GetIntSetting(wxString::Format(m_col_width, GetRealColumn(count)), entry.WIDTH)); + } +} + void mmListCtrl::OnColClick(wxListEvent& WXUNUSED(event)) { // Default to do nothing and implement in derived class @@ -186,30 +218,75 @@ void mmListCtrl::OnHeaderSort(wxCommandEvent& WXUNUSED(event)) void mmListCtrl::OnHeaderMove(wxCommandEvent& WXUNUSED(event), int direction) { - wxArrayString columnList = GetColumnsOrder(); - wxLogDebug("Moving column %d (%s) %d in list: %s", m_ColumnHeaderNbr, m_columns[m_ColumnHeaderNbr].HEADER.c_str(), direction, wxJoin(columnList, '|')); - if (0 <= m_ColumnHeaderNbr + direction && static_cast<int>(m_columns.size()) > m_ColumnHeaderNbr + direction - && static_cast<int>(m_real_columns.size()) > m_ColumnHeaderNbr + direction - && static_cast<int>(columnList.size()) > m_ColumnHeaderNbr + direction){ - // wxLogDebug("m_real_columns: %s", wxJoin(m_real_columns, '|')); + Freeze(); +#ifdef wxHAS_LISTCTRL_COLUMN_ORDER + // on Windows the visual order can differ from the array order due to drag/drop + // so we need to realign them before adjusting the column orders programatically + std::vector<int> realColumns, widths; + wxArrayInt columnorder; + + std::vector<PANEL_COLUMN> columns; + bool reindexSelection = false; + for (int i = 0; i < m_columns.size(); i++) + { + // we will reset the visual indices in sequential order + columnorder.push_back(i); + + // get the true index from the visual column position + int index = GetColumnIndexFromOrder(i); + + // update the selected column index + if (index == m_ColumnHeaderNbr && !reindexSelection) + { + m_ColumnHeaderNbr = i; + reindexSelection = true; + } + + realColumns.push_back(m_real_columns[index]); + columns.push_back(m_columns[index]); + int width = GetColumnWidth(i); + wxListItem column; + column.SetText(m_columns[index].HEADER); + column.SetAlign(static_cast<wxListColumnFormat>(m_columns[index].FORMAT)); + SetColumn(i, column); + SetColumnWidth(i, width); + } + + SetColumnsOrder(columnorder); + m_real_columns = realColumns; + m_columns = columns; +#endif + + // find the next visible column + int distance = direction; + while (m_ColumnHeaderNbr + distance > 0 + && m_ColumnHeaderNbr + distance < m_columns.size() - 1 + && GetColumnWidth(m_ColumnHeaderNbr + distance) == 0) + { + distance += direction; + } + wxLogDebug("Moving column %d (%s) %d", m_ColumnHeaderNbr, m_columns[m_ColumnHeaderNbr].HEADER.c_str(), distance); + if (0 <= m_ColumnHeaderNbr + distance + && static_cast<int>(m_columns.size()) > m_ColumnHeaderNbr + distance + && static_cast<int>(m_real_columns.size()) > m_ColumnHeaderNbr + distance) + { // swap order of column data - Freeze(); - std::swap(m_real_columns[m_ColumnHeaderNbr + direction], m_real_columns[m_ColumnHeaderNbr]); - std::swap(m_columns[m_ColumnHeaderNbr + direction], m_columns[m_ColumnHeaderNbr]); - std::swap(columnList[m_ColumnHeaderNbr + direction], columnList[m_ColumnHeaderNbr]); - SetColumnsOrder(columnList); + std::swap(m_real_columns[m_ColumnHeaderNbr + distance], m_real_columns[m_ColumnHeaderNbr]); + std::swap(m_columns[m_ColumnHeaderNbr + distance], m_columns[m_ColumnHeaderNbr]); + SetColumnOrder(m_real_columns); // swap column headers & widths wxListItem col1, col2; col1.SetText(m_columns[m_ColumnHeaderNbr].HEADER); col1.SetAlign(static_cast<wxListColumnFormat>(m_columns[m_ColumnHeaderNbr].FORMAT)); - col2.SetText(m_columns[m_ColumnHeaderNbr + direction].HEADER); - col2.SetAlign(static_cast<wxListColumnFormat>(m_columns[m_ColumnHeaderNbr + direction].FORMAT)); + col2.SetText(m_columns[m_ColumnHeaderNbr + distance].HEADER); + col2.SetAlign(static_cast<wxListColumnFormat>(m_columns[m_ColumnHeaderNbr + distance].FORMAT)); + int width = GetColumnWidth(m_ColumnHeaderNbr); SetColumn(m_ColumnHeaderNbr, col1); - SetColumnWidth(m_ColumnHeaderNbr, m_columns[m_ColumnHeaderNbr].WIDTH); - SetColumn(m_ColumnHeaderNbr + direction, col2); - SetColumnWidth(m_ColumnHeaderNbr + direction, m_columns[m_ColumnHeaderNbr + direction].WIDTH); + SetColumnWidth(m_ColumnHeaderNbr, GetColumnWidth(m_ColumnHeaderNbr + distance)); + SetColumn(m_ColumnHeaderNbr + distance, col2); + SetColumnWidth(m_ColumnHeaderNbr + distance, width); Thaw(); } } @@ -217,6 +294,7 @@ void mmListCtrl::OnHeaderMove(wxCommandEvent& WXUNUSED(event), int direction) void mmListCtrl::OnHeaderReset(wxCommandEvent& WXUNUSED(event)) { wxString parameter_name; + Freeze(); for (int i = 0; i < static_cast<int>(m_columns.size()); i++) { SetColumnWidth(i, m_columns[i].WIDTH); @@ -231,6 +309,7 @@ void mmListCtrl::OnHeaderReset(wxCommandEvent& WXUNUSED(event)) m_ColumnHeaderNbr = m_default_sort_column; m_asc = true; OnColClick(e); + Thaw(); } void mmListCtrl::OnHeaderColumn(wxCommandEvent& event) @@ -262,28 +341,44 @@ void mmListCtrl::SetColumnWidthSetting(int column_number, int column_width) } // Set new column order. Called when closing the dialog using the "OK" button -void mmListCtrl::SetColumnsOrder(wxArrayString columnList_) +void mmListCtrl::SetColumnOrder(std::vector<int> columnList) { - wxLogDebug("SetColumnsOrder: %s", wxJoin(columnList_, ',')); - Model_Setting::instance().Savepoint(); - Model_Setting::instance().Set(m_col_idstr + "_COLUMNSORDER", wxJoin(columnList_, '|')); - Model_Setting::instance().ReleaseSavepoint(); + if (columnList.empty()) + columnList = m_real_columns; + + wxString columnOrder; + for (int col_enum : columnList) + { + columnOrder.Append((columnOrder.IsEmpty() ? "" : "|") + wxString::Format("%i", col_enum)); + } + Model_Setting::instance().Set(m_col_idstr + "_COLUMNORDER", columnOrder); } // Get the current column order from the settings, or initialize a default order -wxArrayString mmListCtrl::GetColumnsOrder() +std::vector<int> mmListCtrl::GetColumnOrder() { - wxArrayString columnList_ = wxSplit(Model_Setting::instance().GetStringSetting(m_col_idstr + "_COLUMNSORDER", ""), '|'); - unsigned int e = m_columns.size(); - if(columnList_.IsEmpty()) + wxArrayString columnStringList = wxSplit(Model_Setting::instance().GetStringSetting(m_col_idstr + "_COLUMNORDER", ""), '|'); + + // if there is no defined setting, use default order of the listctrl + if(columnStringList.IsEmpty()) + return m_real_columns; + + // otherwise, read order from settings db + std::vector<int> columnOrder; + for (const auto& col_enum : columnStringList) { - for(unsigned i=0; i < e; ++i) { - columnList_.Add(std::to_string(i)); - } + columnOrder.push_back(std::atoi(col_enum.c_str())); } - wxLogDebug("GetColumnsOrder: %s_COLUMNSORDER now = %s", m_col_idstr, wxJoin(columnList_, ',')); - return columnList_; + + // add missing column enums + for (int i : m_real_columns) + { + if (std::find(columnOrder.begin(), columnOrder.end(), i) == columnOrder.end()) + columnOrder.push_back(i); + } + + return columnOrder; } diff --git a/src/mmpanelbase.h b/src/mmpanelbase.h index 4d5946990c..a44b9fc37f 100644 --- a/src/mmpanelbase.h +++ b/src/mmpanelbase.h @@ -60,10 +60,11 @@ class mmListCtrl : public wxListCtrl int GetColumnWidthSetting(int column_number, int default_size = wxLIST_AUTOSIZE); void SetColumnWidthSetting(int column_number, int column_width); - void SetColumnsOrder(wxArrayString columnList); - wxArrayString GetColumnsOrder(); + void SetColumnOrder(std::vector<int> columnList); + std::vector<int> GetColumnOrder(); protected: + void CreateColumns(); void OnItemResize(wxListEvent& event); virtual void OnColClick(wxListEvent& event); void OnColRightClick(wxListEvent& event); diff --git a/src/stocks_list.cpp b/src/stocks_list.cpp index e81dc36a25..5ac609249b 100644 --- a/src/stocks_list.cpp +++ b/src/stocks_list.cpp @@ -84,33 +84,41 @@ StocksListCtrl::StocksListCtrl(mmStocksPanel* cp, wxWindow *parent, wxWindowID w m_asc = Model_Setting::instance().GetBoolSetting("STOCKS_ASC", true); m_columns.push_back(PANEL_COLUMN(" ", 25, wxLIST_FORMAT_LEFT, false)); + m_real_columns.push_back(COL_ICON); m_columns.push_back(PANEL_COLUMN(_("ID"), wxLIST_AUTOSIZE, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(COL_ID); m_columns.push_back(PANEL_COLUMN(_("*Date"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(COL_DATE); m_columns.push_back(PANEL_COLUMN(_("Company Name"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(COL_NAME); m_columns.push_back(PANEL_COLUMN(_("Symbol"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(COL_SYMBOL); m_columns.push_back(PANEL_COLUMN(_("Share Total"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(COL_NUMBER); m_columns.push_back(PANEL_COLUMN(_("Avg Share Price"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(COL_PRICE); m_columns.push_back(PANEL_COLUMN(_("Total Cost"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(COL_VALUE); m_columns.push_back(PANEL_COLUMN(_("Realized Gain/Loss"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(COL_REAL_GAIN_LOSS); m_columns.push_back(PANEL_COLUMN(_("Unrealized Gain/Loss"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(COL_GAIN_LOSS); m_columns.push_back(PANEL_COLUMN(_("Curr. Share Price"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(COL_CURRENT); m_columns.push_back(PANEL_COLUMN(_("Curr. Total Value"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(COL_CURRVALUE); m_columns.push_back(PANEL_COLUMN(_("Price Date"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(COL_PRICEDATE); m_columns.push_back(PANEL_COLUMN(_("Commission"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT, true)); + m_real_columns.push_back(COL_COMMISSION); m_columns.push_back(PANEL_COLUMN(_("Notes"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT, true)); + m_real_columns.push_back(COL_NOTES); m_col_width = "STOCKS_COL%d_WIDTH"; m_col_idstr = "STOCKS"; m_default_sort_column = col_sort(); - for (const auto& entry : m_columns) - { - int count = GetColumnCount(); - InsertColumn(count - , entry.HEADER - , entry.FORMAT - , Model_Setting::instance().GetIntSetting(wxString::Format(m_col_width, count), entry.WIDTH)); - } + CreateColumns(); initVirtualListControl(-1, m_selected_col, m_asc); if (!m_stocks.empty()) @@ -161,6 +169,8 @@ void StocksListCtrl::OnMouseRightClick(wxMouseEvent& event) wxString StocksListCtrl::OnGetItemText(long item, long column) const { + column = m_real_columns[column]; + if (column == COL_ID) return wxString::Format("%i", m_stocks[item].STOCKID).Trim(); if (column == COL_DATE) return mmGetDateForDisplay(m_stocks[item].PURCHASEDATE); if (column == COL_NAME) return m_stocks[item].STOCKNAME;