From 67d3fc4926c67818cfbee1cbb1e1b5cbb619afc0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 10 Nov 2007 00:55:14 +0000 Subject: [PATCH 1/1] added functions for setting the columns order in wxListCtrl (modified patch 1828074) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49802 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + docs/latex/wx/listctrl.tex | 49 +++++++++++++++++++++ include/wx/msw/listctrl.h | 59 ++++++++++++++++---------- src/msw/listctrl.cpp | 87 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 169 insertions(+), 27 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index df53c8c39e..f1a65323fe 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -191,6 +191,7 @@ All (GUI): - Added support for drop down toolbar buttons (Tim Kosse). - Added support for labels for toolbar controls (Vince Harron). - Added wxMessageDialog::SetMessage() and SetExtendedMessage(). +- Added wxListCtrl::Set/GetColumnsOrder() (Yury Voronov) - Added wxWindow::AlwaysShowScrollbars() (Julian Scheid) - Added wxMouseEvent::GetClickCount() (Julian Scheid) - Added wxBG_STYLE_TRANSPARENT background style (Julian Scheid) diff --git a/docs/latex/wx/listctrl.tex b/docs/latex/wx/listctrl.tex index e92d627f7d..ac0fdfb739 100644 --- a/docs/latex/wx/listctrl.tex +++ b/docs/latex/wx/listctrl.tex @@ -115,6 +115,22 @@ functions that take a \helpref{wxListEvent}{wxlistevent} argument. \twocolitem{{\bf EVT\_LIST\_CACHE\_HINT(id, func)}}{Prepare cache for a virtual list control} \end{twocollist}% +\wxheading{Column ordering} + +In report view, the control has several columns which are identified by their +internal indices. By default, these indices correspond to their order on +screen, i.e. the column $0$ appears first (in the left-to-right or maybe +right-to-left if the current language uses this writing direction), the column +$1$ next and so on. However it is possible to reorder the columns visual order +using \helpref{SetColumnsOrder}{wxlistctrlsetcolumnsorder} method and the +user can also rearrange the columns interactively by dragging them. In this +case, the index of the column is not the same as its order and the functions +\helpref{GetColumnOrder}{wxlistctrlgetcolumnorder} and +\helpref{GetColumnIndexFromOrder}{wxlistctrlgetcolumnindexfromorder} should be +used to translate between them. + +Please notice that current column reordering is implemented only in wxMSW. + \wxheading{See also} \helpref{wxListCtrl overview}{wxlistctrloverview}, \helpref{wxListView}{wxlistview}, \helpref{wxListBox}{wxlistbox},\rtfsp @@ -321,6 +337,28 @@ Returns the number of columns. Gets the column width (report view only). +\membersection{wxListCtrl::GetColumnIndexFromOrder}\label{wxlistctrlgetcolumnindexfromorder} + +\constfunc{int}{GetColumnIndexFromOrder}{\param{int }{order}} + +Gets the column number by visual order index (report view only). + + +\membersection{wxListCtrl::GetColumnOrder}\label{wxlistctrlgetcolumnorder} + +\constfunc{int}{GetColumnOrder}{\param{int }{col}} + +Gets the column visual order index (valid in report view only). + + +\membersection{wxListCtrl::GetColumnsOrder}\label{wxlistctrlgetcolumnsorder} + +\constfunc{wxArrayInt}{GetColumnsOrder}{\void} + +Returns the array containing the orders of all columns. On error, an empty +array is returned. + + \membersection{wxListCtrl::GetCountPerPage}\label{wxlistctrlgetcountperpage} \constfunc{int}{GetCountPerPage}{\void} @@ -836,6 +874,17 @@ will resize the column to the length of the header (Win32) or 80 pixels (other p In small or normal icon view, {\it col} must be -1, and the column width is set for all columns. +\membersection{wxListCtrl::SetColumnsOrder}\label{wxlistctrlsetcolumnsorder} + +\constfunc{bool}{SetColumnOrder}{\param{const wxArrayInt\& }{orders}} + +Sets the order of all columns at once. The \arg{orders} array must have the +same number elements as the number of columns and contain each position exactly +once. + +This function is valid in report view only. + + \membersection{wxListCtrl::SetImageList}\label{wxlistctrlsetimagelist} \func{void}{SetImageList}{\param{wxImageList*}{ imageList}, \param{int }{which}} diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h index b732827376..00583ea8a3 100644 --- a/include/wx/msw/listctrl.h +++ b/include/wx/msw/listctrl.h @@ -13,6 +13,7 @@ #define _WX_LISTCTRL_H_ #include "wx/textctrl.h" +#include "wx/dynarray.h" class WXDLLIMPEXP_FWD_CORE wxImageList; @@ -114,13 +115,25 @@ public: bool GetColumn(int col, wxListItem& item) const; // Sets information about this column - bool SetColumn(int col, const wxListItem& item) ; + bool SetColumn(int col, const wxListItem& item); // Gets the column width int GetColumnWidth(int col) const; // Sets the column width - bool SetColumnWidth(int col, int width) ; + bool SetColumnWidth(int col, int width); + + + // Gets the column order from its index or index from its order + int GetColumnOrder(int col) const; + int GetColumnIndexFromOrder(int order) const; + + // Gets the column order for all columns + wxArrayInt GetColumnsOrder() const; + + // Sets the column order for all columns + bool SetColumnsOrder(const wxArrayInt& orders); + // Gets the number of items that can fit vertically in the // visible area of the list control (list or report view) @@ -135,48 +148,48 @@ public: wxTextCtrl* GetEditControl() const; // Gets information about the item - bool GetItem(wxListItem& info) const ; + bool GetItem(wxListItem& info) const; // Sets information about the item - bool SetItem(wxListItem& info) ; + bool SetItem(wxListItem& info); // Sets a string field at a particular column long SetItem(long index, int col, const wxString& label, int imageId = -1); // Gets the item state - int GetItemState(long item, long stateMask) const ; + int GetItemState(long item, long stateMask) const; // Sets the item state - bool SetItemState(long item, long state, long stateMask) ; + bool SetItemState(long item, long state, long stateMask); // Sets the item image - bool SetItemImage(long item, int image, int selImage = -1) ; + bool SetItemImage(long item, int image, int selImage = -1); bool SetItemColumnImage(long item, long column, int image); // Gets the item text - wxString GetItemText(long item) const ; + wxString GetItemText(long item) const; // Sets the item text - void SetItemText(long item, const wxString& str) ; + void SetItemText(long item, const wxString& str); // Gets the item data - wxUIntPtr GetItemData(long item) const ; + wxUIntPtr GetItemData(long item) const; // Sets the item data bool SetItemPtrData(long item, wxUIntPtr data); bool SetItemData(long item, long data) { return SetItemPtrData(item, data); } // Gets the item rectangle - bool GetItemRect(long item, wxRect& rect, int code = wxLIST_RECT_BOUNDS) const ; + bool GetItemRect(long item, wxRect& rect, int code = wxLIST_RECT_BOUNDS) const; // Gets the subitem rectangle in report mode - bool GetSubItemRect(long item, long subItem, wxRect& rect, int code = wxLIST_RECT_BOUNDS) const ; + bool GetSubItemRect(long item, long subItem, wxRect& rect, int code = wxLIST_RECT_BOUNDS) const; // Gets the item position - bool GetItemPosition(long item, wxPoint& pos) const ; + bool GetItemPosition(long item, wxPoint& pos) const; // Sets the item position - bool SetItemPosition(long item, const wxPoint& pos) ; + bool SetItemPosition(long item, const wxPoint& pos); // Gets the number of items in the list control int GetItemCount() const; @@ -210,22 +223,22 @@ public: // Gets the index of the topmost visible item when in // list or report view - long GetTopItem() const ; + long GetTopItem() const; // Add or remove a single window style - void SetSingleStyle(long style, bool add = true) ; + void SetSingleStyle(long style, bool add = true); // Set the whole window style - void SetWindowStyleFlag(long style) ; + void SetWindowStyleFlag(long style); // Searches for an item, starting from 'item'. // item can be -1 to find the first item that matches the // specified flags. // Returns the item or -1 if unsuccessful. - long GetNextItem(long item, int geometry = wxLIST_NEXT_ALL, int state = wxLIST_STATE_DONTCARE) const ; + long GetNextItem(long item, int geometry = wxLIST_NEXT_ALL, int state = wxLIST_STATE_DONTCARE) const; // Gets one of the three image lists - wxImageList *GetImageList(int which) const ; + wxImageList *GetImageList(int which) const; // Sets the image list // N.B. There's a quirk in the Win95 list view implementation. @@ -234,8 +247,8 @@ public: // haven't specified wxLIST_MASK_IMAGE when inserting. // So you have to set a NULL small-icon image list to be sure that // the wxLC_LIST mode works without icons. Of course, you may want icons... - void SetImageList(wxImageList *imageList, int which) ; - void AssignImageList(wxImageList *imageList, int which) ; + void SetImageList(wxImageList *imageList, int which); + void AssignImageList(wxImageList *imageList, int which); // are we in report mode? bool InReportView() const { return HasFlag(wxLC_REPORT); } @@ -257,7 +270,7 @@ public: bool DeleteItem(long item); // Deletes all items - bool DeleteAllItems() ; + bool DeleteAllItems(); // Deletes a column bool DeleteColumn(int col); @@ -275,7 +288,7 @@ public: bool EndEditLabel(bool cancel); // Ensures this item is visible - bool EnsureVisible(long item) ; + bool EnsureVisible(long item); // Find an item whose label matches this string, starting from the item after 'start' // or the beginning if 'start' is -1. diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index b248381832..1f67a95bbc 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -342,8 +342,17 @@ bool wxListCtrl::Create(wxWindow *parent, // styles because it's prettier (and also because wxGTK does it like this) if ( InReportView() && wxApp::GetComCtl32Version() >= 470 ) { - ::SendMessage(GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE, - 0, LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES); + ::SendMessage + ( + GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE, 0, + LVS_EX_LABELTIP | + LVS_EX_FULLROWSELECT | + LVS_EX_SUBITEMIMAGES | + // normally this should be governed by a style as it's probably not + // always appropriate, but we don't have any free styles left and + // it seems better to enable it by default than disable + LVS_EX_HEADERDRAGDROP + ); } return true; @@ -663,6 +672,68 @@ bool wxListCtrl::SetColumnWidth(int col, int width) return ListView_SetColumnWidth(GetHwnd(), col, width) != 0; } +// ---------------------------------------------------------------------------- +// columns order +// ---------------------------------------------------------------------------- + +int wxListCtrl::GetColumnOrder(int col) const +{ + const int numCols = GetColumnCount(); + wxCHECK_MSG( col >= 0 && col < numCols, -1, _T("Col index out of bounds") ); + + wxArrayInt indexArray(numCols); + + if ( !ListView_GetColumnOrderArray(GetHwnd(), numCols, &indexArray[0]) ) + return -1; + + return indexArray[col]; +} + +int wxListCtrl::GetColumnIndexFromOrder(int order) const +{ + const int numCols = GetColumnCount(); + wxASSERT_MSG( order >= 0 && order < numCols, _T("Col order out of bounds") ); + + wxArrayInt indexArray(numCols); + + if ( !ListView_GetColumnOrderArray(GetHwnd(), numCols, &indexArray[0]) ) + return -1; + + for ( int col = 0; col < numCols; col++ ) + { + if ( indexArray[col] == order ) + return col; + } + + wxFAIL_MSG( _T("no column with with given order?") ); + + return -1; +} + +// Gets the column order for all columns +wxArrayInt wxListCtrl::GetColumnsOrder() const +{ + const int numCols = GetColumnCount(); + + wxArrayInt orders(numCols); + if ( !ListView_GetColumnOrderArray(GetHwnd(), numCols, &orders[0]) ) + orders.clear(); + + return orders; +} + +// Sets the column order for all columns +bool wxListCtrl::SetColumnsOrder(const wxArrayInt& orders) +{ + const int numCols = GetColumnCount(); + + wxCHECK_MSG( orders.size() == (size_t)numCols, false, + _T("wrong number of elements in column orders array") ); + + return ListView_SetColumnOrderArray(GetHwnd(), numCols, &orders[0]) != 0; +} + + // Gets the number of items that can fit vertically in the // visible area of the list control (list or report view) // or the total number of items in the list control (icon @@ -2750,14 +2821,22 @@ void wxListCtrl::OnPaint(wxPaintEvent& event) dc.SetPen(pen); dc.SetBrush(*wxTRANSPARENT_BRUSH); + + int numCols = GetColumnCount(); + int* indexArray = new int[numCols]; + BOOL rv = ListView_GetColumnOrderArray( GetHwnd(), numCols, indexArray ); + wxASSERT_MSG( rv == TRUE, _T("invalid column index array in OnPaint()") ); + int x = itemRect.GetX(); - for (int col = 0; col < GetColumnCount(); col++) + for (int col = 0; col < numCols; col++) { - int colWidth = GetColumnWidth(col); + int colWidth = GetColumnWidth(indexArray[col]); x += colWidth ; dc.DrawLine(x-1, firstItemRect.GetY() - gap, x-1, itemRect.GetBottom()); } + + delete indexArray; } } } -- 2.45.2