CFileDetailListCtrl::CFileDetailListCtrl(wxWindow * &parent, int id, const wxPoint & pos, wxSize siz, int flags):CMuleListCtrl(parent, id, pos, siz, flags) { // Set sorter function SetSortFunc(SortProc); // Initial sorting: Sources descending InsertColumn(0, _("File Name"), wxLIST_FORMAT_LEFT, 370); InsertColumn(1, _("Sources"), wxLIST_FORMAT_LEFT, 70); SetSorting(1, CMuleListCtrl::SORT_DES); SortList(); }
// As we will not receive WM_CREATE, we must do initialization // in this extra method. The counterpart is OnDestroy(). void CExtensionListControl::Initialize() { SetSorting(COL_BYTES, false); InsertColumn(COL_EXTENSION, LoadString(IDS_EXTCOL_EXTENSION), LVCFMT_LEFT, 60, COL_EXTENSION); InsertColumn(COL_COLOR, LoadString(IDS_EXTCOL_COLOR), LVCFMT_LEFT, 40, COL_COLOR); InsertColumn(COL_BYTES, LoadString(IDS_EXTCOL_BYTES), LVCFMT_RIGHT, 60, COL_BYTES); InsertColumn(COL_BYTESPERCENT, _T("% ") + LoadString(IDS_EXTCOL_BYTES), LVCFMT_RIGHT, 50, COL_BYTESPERCENT); InsertColumn(COL_FILES, LoadString(IDS_EXTCOL_FILES), LVCFMT_RIGHT, 50, COL_FILES); InsertColumn(COL_DESCRIPTION, LoadString(IDS_EXTCOL_DESCRIPTION), LVCFMT_LEFT, 170, COL_DESCRIPTION); OnColumnsInserted(); // We don't use the list control's image list, but attaching an image list // to the control ensures a proper line height. SetImageList(GetMyImageList(), LVSIL_SMALL); }
void CSortingListControl::OnHdnItemclick(NMHDR *pNMHDR, LRESULT *pResult) { LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR); *pResult = 0; int col= phdr->iItem; if (col == m_sorting.column1) { m_sorting.ascending1 = ! m_sorting.ascending1; } else { SetSorting(col, GetAscendingDefault(col)); } SortItems(); }
void CMuleListCtrl::OnColumnLClick(wxListEvent& evt) { // Stop if no sorter-function has been defined if (!m_sort_func) { return; } else if (evt.GetColumn() == -1) { // This happens if a user clicks past the last column header. return; } unsigned sort_order = 0; if (m_sort_orders.front().first == (unsigned)evt.GetColumn()) { // Same column as before, flip the sort-order sort_order = m_sort_orders.front().second; if (sort_order & SORT_DES) { if (AltSortAllowed(evt.GetColumn())) { sort_order = (~sort_order) & SORT_ALT; } else { sort_order = 0; } } else { sort_order = SORT_DES | (sort_order & SORT_ALT); } m_sort_orders.pop_front(); } else { // Check if the column has already been set CSortingList::iterator it = m_sort_orders.begin(); for (; it != m_sort_orders.end(); ++it) { if ((unsigned)evt.GetColumn() == it->first) { sort_order = it->second; break; } } } SetSorting(evt.GetColumn(), sort_order); }
void CMuleListCtrl::ParseOldConfigEntries(const wxString& sortOrders, const wxString& columnWidths) { // Set sort order (including sort column) wxStringTokenizer tokens(sortOrders, wxT(",")); while (tokens.HasMoreTokens()) { wxString token = tokens.GetNextToken(); long column = 0; unsigned long order = 0; if (token.BeforeFirst(wxT(' ')).Strip(wxString::both).ToLong(&column)) { if (token.AfterFirst(wxT(' ')).Strip(wxString::both).ToULong(&order)) { column = GetNewColumnIndex(column); // Sanity checking, to avoid asserting if column count changes. if (column >= 0 && column < GetColumnCount()) { // Sanity checking, to avoid asserting if data-format changes. if ((order & ~SORTING_MASK) == 0) { // SetSorting will take care of duplicate entries SetSorting(column, order); } } } } } // Set column widths int counter = 0; wxStringTokenizer tokenizer(columnWidths, wxT(",")); while (tokenizer.HasMoreTokens()) { long idx = GetNewColumnIndex(counter++); long width = StrToLong(tokenizer.GetNextToken()); if (idx >= 0) { SetColumnWidth(idx, width); } } }
void CMuleListCtrl::LoadSettings() { wxCHECK_RET(!m_name.IsEmpty(), wxT("Cannot load settings for unnamed list")); wxConfigBase* cfg = wxConfigBase::Get(); // Load sort order (including sort-column) m_sort_orders.clear(); wxString sortOrders = cfg->Read(wxT("/eMule/TableOrdering") + m_name, wxEmptyString); wxString columnWidths = cfg->Read(wxT("/eMule/TableWidths") + m_name, wxEmptyString); // Prevent sorting from occuring when calling SetSorting MuleListCtrlCompare sortFunc = m_sort_func; m_sort_func = NULL; if (columnWidths.Find(wxT(':')) == wxNOT_FOUND) { // Old-style config entries... ParseOldConfigEntries(sortOrders, columnWidths); } else { // Sort orders wxStringTokenizer tokens(sortOrders, wxT(",")); // Sort orders are stored in order primary, secondary, ... // We want to apply them with SetSorting(), so we have to apply them in reverse order, // so that the primary order is applied last and wins. // Read them with tokenizer and store them in a list in reverse order. CStringList tokenList; while (tokens.HasMoreTokens()) { tokenList.push_front(tokens.GetNextToken()); } for (CStringList::iterator it = tokenList.begin(); it != tokenList.end(); it++) { wxString token = *it; wxString name = token.BeforeFirst(wxT(':')); long order = StrToLong(token.AfterFirst(wxT(':')).BeforeLast(wxT(':'))); long alt = StrToLong(token.AfterLast(wxT(':'))); int col = GetColumnIndex(name); if (col >= 0) { SetSorting(col, (order ? SORT_DES : 0) | (alt ? SORT_ALT : 0)); } } // Column widths wxStringTokenizer tkz(columnWidths, wxT(",")); while (tkz.HasMoreTokens()) { wxString token = tkz.GetNextToken(); wxString name = token.BeforeFirst(wxT(':')); long width = StrToLong(token.AfterFirst(wxT(':'))); int col = GetColumnIndex(name); if (col >= 0) { if (col >= (int) m_column_sizes.size()) { m_column_sizes.resize(col + 1, 0); } m_column_sizes[col] = abs(width); SetColumnWidth(col, (width > 0) ? width : 0); } } } // Must have at least one sort-order specified if (m_sort_orders.empty()) { m_sort_orders.push_back(CColPair(0, 0)); } // Re-enable sorting and resort the contents (if any). m_sort_func = sortFunc; SortList(); }