]> git.saurik.com Git - wxWidgets.git/blame - src/common/listctrlcmn.cpp
fixing overrelease and out-of-bounds write, fixes #13725
[wxWidgets.git] / src / common / listctrlcmn.cpp
CommitLineData
e96bbb45
KO
1////////////////////////////////////////////////////////////////////////////////
2// Name: src/common/listctrlcmn.cpp
3// Purpose: Common defines for wxListCtrl and wxListCtrl-based classes.
4// Author: Kevin Ollivier
5// Created: 09/15/06
6// RCS-ID: $Id$
7// Copyright: (c) Kevin Ollivier
8// Licence: wxWindows licence
9////////////////////////////////////////////////////////////////////////////////
10
11// =============================================================================
12// declarations
13// =============================================================================
14
15// -----------------------------------------------------------------------------
16// headers
17// -----------------------------------------------------------------------------
18
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
e409b62a 21
b4715d08
VZ
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
e409b62a
PC
26#if wxUSE_LISTCTRL
27
e96bbb45
KO
28#include "wx/listctrl.h"
29
94248d2e
VZ
30#ifndef WX_PRECOMP
31 #include "wx/dcclient.h"
32#endif
33
f36e602b 34const char wxListCtrlNameStr[] = "listCtrl";
e409b62a 35
e96bbb45 36// ListCtrl events
9b11752c
VZ
37wxDEFINE_EVENT( wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEvent );
38wxDEFINE_EVENT( wxEVT_COMMAND_LIST_BEGIN_RDRAG, wxListEvent );
39wxDEFINE_EVENT( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, wxListEvent );
40wxDEFINE_EVENT( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEvent );
41wxDEFINE_EVENT( wxEVT_COMMAND_LIST_DELETE_ITEM, wxListEvent );
42wxDEFINE_EVENT( wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS, wxListEvent );
43wxDEFINE_EVENT( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEvent );
44wxDEFINE_EVENT( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEvent );
45wxDEFINE_EVENT( wxEVT_COMMAND_LIST_KEY_DOWN, wxListEvent );
46wxDEFINE_EVENT( wxEVT_COMMAND_LIST_INSERT_ITEM, wxListEvent );
47wxDEFINE_EVENT( wxEVT_COMMAND_LIST_COL_CLICK, wxListEvent );
48wxDEFINE_EVENT( wxEVT_COMMAND_LIST_COL_RIGHT_CLICK, wxListEvent );
49wxDEFINE_EVENT( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEvent );
50wxDEFINE_EVENT( wxEVT_COMMAND_LIST_COL_DRAGGING, wxListEvent );
51wxDEFINE_EVENT( wxEVT_COMMAND_LIST_COL_END_DRAG, wxListEvent );
52wxDEFINE_EVENT( wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, wxListEvent );
53wxDEFINE_EVENT( wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK, wxListEvent );
54wxDEFINE_EVENT( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEvent );
55wxDEFINE_EVENT( wxEVT_COMMAND_LIST_ITEM_FOCUSED, wxListEvent );
56wxDEFINE_EVENT( wxEVT_COMMAND_LIST_CACHE_HINT, wxListEvent );
e96bbb45 57
28953245
SC
58// -----------------------------------------------------------------------------
59// XTI
60// -----------------------------------------------------------------------------
61
62wxDEFINE_FLAGS( wxListCtrlStyle )
63wxBEGIN_FLAGS( wxListCtrlStyle )
64// new style border flags, we put them first to
65// use them for streaming out
66wxFLAGS_MEMBER(wxBORDER_SIMPLE)
67wxFLAGS_MEMBER(wxBORDER_SUNKEN)
68wxFLAGS_MEMBER(wxBORDER_DOUBLE)
69wxFLAGS_MEMBER(wxBORDER_RAISED)
70wxFLAGS_MEMBER(wxBORDER_STATIC)
71wxFLAGS_MEMBER(wxBORDER_NONE)
72
73// old style border flags
74wxFLAGS_MEMBER(wxSIMPLE_BORDER)
75wxFLAGS_MEMBER(wxSUNKEN_BORDER)
76wxFLAGS_MEMBER(wxDOUBLE_BORDER)
77wxFLAGS_MEMBER(wxRAISED_BORDER)
78wxFLAGS_MEMBER(wxSTATIC_BORDER)
79wxFLAGS_MEMBER(wxBORDER)
80
81// standard window styles
82wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
83wxFLAGS_MEMBER(wxCLIP_CHILDREN)
84wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
85wxFLAGS_MEMBER(wxWANTS_CHARS)
86wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
87wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
88wxFLAGS_MEMBER(wxVSCROLL)
89wxFLAGS_MEMBER(wxHSCROLL)
90
91wxFLAGS_MEMBER(wxLC_LIST)
92wxFLAGS_MEMBER(wxLC_REPORT)
93wxFLAGS_MEMBER(wxLC_ICON)
94wxFLAGS_MEMBER(wxLC_SMALL_ICON)
95wxFLAGS_MEMBER(wxLC_ALIGN_TOP)
96wxFLAGS_MEMBER(wxLC_ALIGN_LEFT)
97wxFLAGS_MEMBER(wxLC_AUTOARRANGE)
98wxFLAGS_MEMBER(wxLC_USER_TEXT)
99wxFLAGS_MEMBER(wxLC_EDIT_LABELS)
100wxFLAGS_MEMBER(wxLC_NO_HEADER)
101wxFLAGS_MEMBER(wxLC_SINGLE_SEL)
102wxFLAGS_MEMBER(wxLC_SORT_ASCENDING)
103wxFLAGS_MEMBER(wxLC_SORT_DESCENDING)
104wxFLAGS_MEMBER(wxLC_VIRTUAL)
105wxEND_FLAGS( wxListCtrlStyle )
106
107#if ((!defined(__WXMSW__) && !(defined(__WXMAC__) && wxOSX_USE_CARBON)) || defined(__WXUNIVERSAL__))
108wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxListCtrl, wxGenericListCtrl, "wx/listctrl.h")
109#else
110wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxListCtrl, wxControl, "wx/listctrl.h")
111#endif
112
113wxBEGIN_PROPERTIES_TABLE(wxListCtrl)
114wxEVENT_PROPERTY( TextUpdated, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEvent )
115
116wxPROPERTY_FLAGS( WindowStyle, wxListCtrlStyle, long, SetWindowStyleFlag, \
117 GetWindowStyleFlag, wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, \
118 wxT("Helpstring"), wxT("group")) // style
119wxEND_PROPERTIES_TABLE()
120
121wxEMPTY_HANDLERS_TABLE(wxListCtrl)
122
123wxCONSTRUCTOR_5( wxListCtrl, wxWindow*, Parent, wxWindowID, Id, \
124 wxPoint, Position, wxSize, Size, long, WindowStyle )
125
126/*
127 TODO : Expose more information of a list's layout etc. via appropriate objects
128 (see NotebookPageInfo)
129 */
130
131IMPLEMENT_DYNAMIC_CLASS(wxListView, wxListCtrl)
132IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
133IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent)
134
94248d2e
VZ
135// ----------------------------------------------------------------------------
136// wxListCtrlBase implementation
137// ----------------------------------------------------------------------------
138
c23edb1b
VZ
139long
140wxListCtrlBase::AppendColumn(const wxString& heading,
141 int format,
142 int width)
143{
144 return InsertColumn(GetColumnCount(), heading, format, width);
145}
146
94248d2e
VZ
147long
148wxListCtrlBase::InsertColumn(long col,
149 const wxString& heading,
150 int format,
151 int width)
152{
153 wxListItem item;
154 item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
155 item.m_text = heading;
0fb731b8
VZ
156 if ( width >= 0
157 || width == wxLIST_AUTOSIZE
158 || width == wxLIST_AUTOSIZE_USEHEADER )
94248d2e
VZ
159 {
160 item.m_mask |= wxLIST_MASK_WIDTH;
161 item.m_width = width;
162 }
163 item.m_format = format;
164
165 return InsertColumn(col, item);
166}
167
168long wxListCtrlBase::InsertColumn(long col, const wxListItem& info)
169{
170 long rc = DoInsertColumn(col, info);
171 if ( rc != -1 )
172 {
173 // As our best size calculation depends on the column headers,
174 // invalidate the previously cached best size when a column is added.
175 InvalidateBestSize();
176 }
177
178 return rc;
179}
180
181wxSize wxListCtrlBase::DoGetBestClientSize() const
182{
183 // There is no obvious way to determine the best size in icon and list
184 // modes so just don't do it for now.
185 if ( !InReportView() )
186 return wxControl::DoGetBestClientSize();
187
3aa1dc1e
VZ
188 int totalWidth;
189 wxClientDC dc(const_cast<wxListCtrlBase*>(this));
190
94248d2e
VZ
191 // In report mode, we use only the column headers, not items, to determine
192 // the best width. The reason for this is that it's easier (we can't just
193 // iterate over all items, especially not in a virtual control, so we'd
194 // have to do something relatively complicated such as checking the size of
195 // some items in the beginning and the end only) and also because the
196 // columns are usually static while the list contents is dynamic so it
197 // usually doesn't make much sense to adjust the control size to it anyhow.
198 // And finally, scrollbars can always be used with the items while the
199 // headers are just truncated if there is not enough place for them.
200 const int columns = GetColumnCount();
201 if ( HasFlag(wxLC_NO_HEADER) || !columns )
94248d2e 202 {
3aa1dc1e
VZ
203 // Use some arbitrary width.
204 totalWidth = 50*dc.GetCharWidth();
205 }
206 else // We do have columns, use them to determine the best width.
207 {
208 totalWidth = 0;
209 for ( int col = 0; col < columns; col++ )
210 {
211 totalWidth += GetColumnWidth(col);
212 }
94248d2e
VZ
213 }
214
215 // Use some arbitrary height, there is no good way to determine it.
216 return wxSize(totalWidth, 10*dc.GetCharHeight());
217}
218
e409b62a 219#endif // wxUSE_LISTCTRL