]> git.saurik.com Git - wxWidgets.git/blame - src/common/treebase.cpp
assert if ShowModal() is called after a previous Show() (#1416)
[wxWidgets.git] / src / common / treebase.cpp
CommitLineData
484523cf
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: treebase.cpp
3// Purpose: Base wxTreeCtrl classes
4// Author: Julian Smart
5// Created: 01/02/97
6// Modified:
7// Id: $Id$
8// Copyright: (c) 1998 Robert Roebling, Julian Smart et al
65571936 9// Licence: wxWindows licence
484523cf
JS
10/////////////////////////////////////////////////////////////////////////////
11
12// =============================================================================
13// declarations
14// =============================================================================
15
16// -----------------------------------------------------------------------------
17// headers
18// -----------------------------------------------------------------------------
19
484523cf
JS
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
1e6feb95 24 #pragma hdrstop
484523cf
JS
25#endif
26
1e6feb95
VZ
27#if wxUSE_TREECTRL
28
8cee4a30 29#include "wx/treectrl.h"
42e53e77 30#include "wx/imaglist.h"
ed2ec17c
GT
31
32// ----------------------------------------------------------------------------
33// events
34// ----------------------------------------------------------------------------
35
36DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_BEGIN_DRAG)
37DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_BEGIN_RDRAG)
38DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT)
39DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_END_LABEL_EDIT)
40DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_DELETE_ITEM)
41DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_GET_INFO)
42DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_SET_INFO)
43DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_EXPANDED)
44DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_EXPANDING)
45DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_COLLAPSED)
46DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_COLLAPSING)
47DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_SEL_CHANGED)
48DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_SEL_CHANGING)
49DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_KEY_DOWN)
50DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_ACTIVATED)
51DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK)
52DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK)
53DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_END_DRAG)
ae8c4b33 54DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK)
156194e1 55DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP)
f7c6f947 56DEFINE_EVENT_TYPE(wxEVT_COMMAND_TREE_ITEM_MENU)
ed2ec17c 57
484523cf
JS
58// ----------------------------------------------------------------------------
59// Tree event
60// ----------------------------------------------------------------------------
61
09f277d6 62IMPLEMENT_ABSTRACT_CLASS(wxTreeEvent, wxNotifyEvent)
b8fbf1a0
RD
63
64
09f277d6
VZ
65wxTreeEvent::wxTreeEvent(wxEventType commandType,
66 wxTreeCtrlBase *tree,
67 const wxTreeItemId& item)
68 : wxNotifyEvent(commandType, tree->GetId()),
69 m_item(item)
484523cf 70{
cb719f2e 71 m_editCancelled = false;
09f277d6
VZ
72
73 SetEventObject(tree);
74
75 if ( item.IsOk() )
76 SetClientObject(tree->GetItemData(item));
484523cf
JS
77}
78
49b6ebb7
RD
79wxTreeEvent::wxTreeEvent(wxEventType commandType, int id)
80 : wxNotifyEvent(commandType, id)
81{
82 m_itemOld = 0l;
83 m_editCancelled = false;
84}
85
0cd936a4
WS
86wxTreeEvent::wxTreeEvent(const wxTreeEvent & event)
87 : wxNotifyEvent(event)
88{
89 m_evtKey = event.m_evtKey;
90 m_item = event.m_item;
91 m_itemOld = event.m_itemOld;
92 m_pointDrag = event.m_pointDrag;
93 m_label = event.m_label;
94 m_editCancelled = event.m_editCancelled;
95}
96
8cee4a30
VZ
97// ----------------------------------------------------------------------------
98// wxTreeCtrlBase
99// ----------------------------------------------------------------------------
100
101wxTreeCtrlBase::~wxTreeCtrlBase()
102{
103 if (m_ownsImageListNormal)
104 delete m_imageListNormal;
105 if (m_ownsImageListState)
106 delete m_imageListState;
107}
108
03966fcb
RR
109void wxTreeCtrlBase::SetItemState(const wxTreeItemId& item, int state)
110{
111 if ( state == wxTREE_ITEMSTATE_NEXT )
112 {
113 state = GetItemState(item) + 1;
114 if ( m_imageListState && state >= m_imageListState->GetImageCount() )
115 state = 0;
116 }
117 else if ( state == wxTREE_ITEMSTATE_PREV )
118 {
119 state = GetItemState(item) - 1;
120 if ( state == -1 )
121 state = m_imageListState ? m_imageListState->GetImageCount() - 1 : 0;
122 }
123 // else: wxTREE_ITEMSTATE_NONE depending on platform
124
125 DoSetItemState(item, state);
126}
127
fbf8436c
VZ
128static void
129wxGetBestTreeSize(const wxTreeCtrlBase* treeCtrl, wxTreeItemId id, wxSize& size)
7c384067
JS
130{
131 wxRect rect;
70934138 132
fbf8436c 133 if ( treeCtrl->GetBoundingRect(id, rect, true /* just the item */) )
7c384067 134 {
9e7642ae 135 // Translate to logical position so we get the full extent
9766efc3 136#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
9e7642ae
JS
137 rect.x += treeCtrl->GetScrollPos(wxHORIZONTAL);
138 rect.y += treeCtrl->GetScrollPos(wxVERTICAL);
9766efc3 139#endif
9e7642ae 140
fbf8436c 141 size.IncTo(wxSize(rect.GetRight(), rect.GetBottom()));
7c384067
JS
142 }
143
144 wxTreeItemIdValue cookie;
145 for ( wxTreeItemId item = treeCtrl->GetFirstChild(id, cookie);
146 item.IsOk();
3e748fca 147 item = treeCtrl->GetNextChild(id, cookie) )
7c384067
JS
148 {
149 wxGetBestTreeSize(treeCtrl, item, size);
150 }
151}
152
8cee4a30
VZ
153wxSize wxTreeCtrlBase::DoGetBestSize() const
154{
155 wxSize size;
156
157 // this doesn't really compute the total bounding rectangle of all items
158 // but a not too bad guess of it which has the advantage of not having to
159 // examine all (potentially hundreds or thousands) items in the control
70934138 160
7c384067 161 if (GetQuickBestSize())
8cee4a30 162 {
7c384067
JS
163 for ( wxTreeItemId item = GetRootItem();
164 item.IsOk();
165 item = GetLastChild(item) )
8cee4a30 166 {
7c384067
JS
167 wxRect rect;
168
169 // last parameter is "true" to get only the dimensions of the text
170 // label, we don't want to get the entire item width as it's determined
171 // by the current size
172 if ( GetBoundingRect(item, rect, true) )
173 {
174 if ( size.x < rect.x + rect.width )
175 size.x = rect.x + rect.width;
176 if ( size.y < rect.y + rect.height )
177 size.y = rect.y + rect.height;
178 }
8cee4a30
VZ
179 }
180 }
fbf8436c
VZ
181 else // use precise, if potentially slow, size computation method
182 {
183 // iterate over all items recursively
16f32ee7
VZ
184 wxTreeItemId idRoot = GetRootItem();
185 if ( idRoot.IsOk() )
186 wxGetBestTreeSize(this, idRoot, size);
fbf8436c
VZ
187 }
188
8cee4a30
VZ
189 // need some minimal size even for empty tree
190 if ( !size.x || !size.y )
191 size = wxControl::DoGetBestSize();
b24069f2 192 else
54a4121a
VZ
193 {
194 // Add border size
195 size += GetWindowBorderSize();
196
b24069f2 197 CacheBestSize(size);
54a4121a 198 }
8cee4a30
VZ
199
200 return size;
201}
202
70934138
VZ
203void wxTreeCtrlBase::ExpandAll()
204{
9248adc8
VZ
205 if ( IsEmpty() )
206 return;
207
70934138
VZ
208 ExpandAllChildren(GetRootItem());
209}
210
211void wxTreeCtrlBase::ExpandAllChildren(const wxTreeItemId& item)
212{
624f89c2 213 Freeze();
70934138
VZ
214 // expand this item first, this might result in its children being added on
215 // the fly
e660f922
VZ
216 if ( item != GetRootItem() || !HasFlag(wxTR_HIDE_ROOT) )
217 Expand(item);
218 //else: expanding hidden root item is unsupported and unnecessary
70934138
VZ
219
220 // then (recursively) expand all the children
221 wxTreeItemIdValue cookie;
222 for ( wxTreeItemId idCurr = GetFirstChild(item, cookie);
223 idCurr.IsOk();
224 idCurr = GetNextChild(item, cookie) )
225 {
226 ExpandAllChildren(idCurr);
227 }
624f89c2 228 Thaw();
70934138
VZ
229}
230
9248adc8
VZ
231void wxTreeCtrlBase::CollapseAll()
232{
233 if ( IsEmpty() )
234 return;
235
236 CollapseAllChildren(GetRootItem());
237}
238
239void wxTreeCtrlBase::CollapseAllChildren(const wxTreeItemId& item)
240{
624f89c2 241 Freeze();
9248adc8
VZ
242 // first (recursively) collapse all the children
243 wxTreeItemIdValue cookie;
244 for ( wxTreeItemId idCurr = GetFirstChild(item, cookie);
245 idCurr.IsOk();
246 idCurr = GetNextChild(item, cookie) )
247 {
248 CollapseAllChildren(idCurr);
249 }
250
251 // then collapse this element too
252 Collapse(item);
624f89c2 253 Thaw();
9248adc8
VZ
254}
255
256bool wxTreeCtrlBase::IsEmpty() const
257{
258 return !GetRootItem().IsOk();
259}
260
1e6feb95 261#endif // wxUSE_TREECTRL