]> git.saurik.com Git - wxWidgets.git/blob - include/wx/clntdata.h
better leak error reporting using VC CRT (patch 828250)
[wxWidgets.git] / include / wx / clntdata.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/clntdata.h
3 // Purpose: A mixin class for holding a wxClientData or void pointer
4 // Author: Robin Dunn
5 // Modified by:
6 // Created: 9-Oct-2001
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_CLNTDATAH__
13 #define _WX_CLNTDATAH__
14
15 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
16 #pragma interface "clntdata.h"
17 #endif
18
19 #include "wx/defs.h"
20 #include "wx/string.h"
21
22 // ----------------------------------------------------------------------------
23
24 // what kind of client data do we have?
25 enum wxClientDataType
26 {
27 wxClientData_None, // we don't know yet because we don't have it at all
28 wxClientData_Object, // our client data is typed and we own it
29 wxClientData_Void // client data is untyped and we don't own it
30 };
31
32 class WXDLLEXPORT wxClientData
33 {
34 public:
35 wxClientData() { }
36 virtual ~wxClientData() { }
37 };
38
39 class WXDLLEXPORT wxStringClientData : public wxClientData
40 {
41 public:
42 wxStringClientData() : m_data() { }
43 wxStringClientData( const wxString &data ) : m_data(data) { }
44 void SetData( const wxString &data ) { m_data = data; }
45 const wxString& GetData() const { return m_data; }
46
47 private:
48 wxString m_data;
49 };
50
51 // This class is a mixin that provides storage and management of "client
52 // data." The client data stored can either be a pointer to a wxClientData
53 // object in which case it is managed by the container (i.e. it will delete
54 // the data when it's destroyed) or an untyped pointer which won't be deleted
55 // by the container - but not both of them
56 //
57 // NOTE: This functionality is currently duplicated in wxEvtHandler in order
58 // to avoid having more than one vtable in that class hierarchy.
59
60 class WXDLLEXPORT wxClientDataContainer
61 {
62 public:
63 wxClientDataContainer();
64 virtual ~wxClientDataContainer();
65
66 void SetClientObject( wxClientData *data ) { DoSetClientObject(data); }
67 wxClientData *GetClientObject() const { return DoGetClientObject(); }
68
69 void SetClientData( void *data ) { DoSetClientData(data); }
70 void *GetClientData() const { return DoGetClientData(); }
71
72 protected:
73 // The user data: either an object which will be deleted by the container
74 // when it's deleted or some raw pointer which we do nothing with. Only
75 // one type of data can be used with the given window, i.e. you cannot set
76 // the void data and then associate the container with wxClientData or vice
77 // versa.
78 union
79 {
80 wxClientData *m_clientObject;
81 void *m_clientData;
82 };
83
84 // client data accessors
85 virtual void DoSetClientObject( wxClientData *data );
86 virtual wxClientData *DoGetClientObject() const;
87
88 virtual void DoSetClientData( void *data );
89 virtual void *DoGetClientData() const;
90
91 // what kind of data do we have?
92 wxClientDataType m_clientDataType;
93
94 };
95
96 // not Motif-specific, but currently used only under Motif
97 #ifdef __WXMOTIF__
98
99 #include <wx/vector.h>
100
101 struct WXDLLEXPORT wxClientDataDictionaryPair
102 {
103 wxClientDataDictionaryPair( size_t idx ) : index( idx ), data( 0 ) { }
104
105 size_t index;
106 wxClientData* data;
107 };
108
109 WX_DECLARE_VECTOR(wxClientDataDictionaryPair,wxClientDataDictionaryPairVector);
110
111 // this class is used internally to maintain the association between items
112 // of (some subclasses of) wxControlWithItems and their client data
113 // NOTE: this class does not keep track of whether it contains
114 // wxClientData or void*. The client must ensure that
115 // it does not contain a mix of the two, and that
116 // DestroyData is called if it contains wxClientData
117 class WXDLLEXPORT wxClientDataDictionary
118 {
119 public:
120 wxClientDataDictionary() {};
121
122 // deletes all the data
123 void DestroyData()
124 {
125 for( size_t i = 0, end = m_vec.size(); i != end; ++i )
126 delete m_vec[i].data;
127 m_vec.clear();
128 }
129
130 // if data for the given index is not present, add it,
131 // if it is present, delete the old data and replace it with
132 // the new one
133 void Set( size_t index, wxClientData* data, bool doDelete )
134 {
135 size_t ptr = Find( index );
136
137 if( !data )
138 {
139 if( ptr == m_vec.size() ) return;
140 if( doDelete )
141 delete m_vec[ptr].data;
142 m_vec.erase( ptr );
143 }
144 else
145 {
146 if( ptr == m_vec.size() )
147 {
148 m_vec.push_back( wxClientDataDictionaryPair( index ) );
149 ptr = m_vec.size() - 1;
150 }
151
152 if( doDelete )
153 delete m_vec[ptr].data;
154 m_vec[ptr].data = data;
155 }
156 }
157
158 // get the data associated with the given index,
159 // return 0 if not found
160 wxClientData* Get( size_t index ) const
161 {
162 size_t it = Find( index );
163 if( it == m_vec.size() ) return 0;
164 return (wxClientData*)m_vec[it].data; // const cast
165 }
166
167 // delete the data associated with the given index
168 // it also decreases by one the indices of all the elements
169 // with an index greater than the given index
170 void Delete( size_t index, bool doDelete )
171 {
172 size_t todel = m_vec.size();
173
174 for( size_t i = 0, end = m_vec.size(); i != end; ++i )
175 {
176 if( m_vec[i].index == index )
177 todel = i;
178 else if( m_vec[i].index > index )
179 --(m_vec[i].index);
180 }
181
182 if( todel != m_vec.size() )
183 {
184 if( doDelete )
185 delete m_vec[todel].data;
186 m_vec.erase( todel );
187 }
188 }
189 private:
190 // returns MyVec.size() if not found
191 size_t Find( size_t index ) const
192 {
193 for( size_t i = 0, end = m_vec.size(); i != end; ++i )
194 {
195 if( m_vec[i].index == index )
196 return i;
197 }
198
199 return m_vec.size();
200 }
201
202 wxClientDataDictionaryPairVector m_vec;
203 };
204
205 #endif // __WXMOTIF__
206
207 // ----------------------------------------------------------------------------
208 #endif
209