]> git.saurik.com Git - wxWidgets.git/blame - src/common/statbar.cpp
added wxMBConv::Clone() to be able to copy conversion objects polymorphically
[wxWidgets.git] / src / common / statbar.cpp
CommitLineData
71e03035
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: common/statbar.cpp
3// Purpose: wxStatusBarBase implementation
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 14.10.01
7// RCS-ID: $Id$
8// Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 9// License: wxWindows licence
71e03035
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
71e03035
VZ
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
e9a05074 28 #include "wx/frame.h"
71e03035
VZ
29 #include "wx/statusbr.h"
30#endif //WX_PRECOMP
31
32#if wxUSE_STATUSBAR
33
1f361cdd 34#include "wx/listimpl.cpp"
259c43f6 35WX_DEFINE_LIST(wxListString)
1f361cdd 36
71e03035
VZ
37// ============================================================================
38// wxStatusBarBase implementation
39// ============================================================================
40
a93e536b 41IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
71e03035
VZ
42
43// ----------------------------------------------------------------------------
44// ctor/dtor
45// ----------------------------------------------------------------------------
46
47wxStatusBarBase::wxStatusBarBase()
48{
49 m_nFields = 0;
50
51 InitWidths();
1f361cdd 52 InitStacks();
c2919ab3 53 InitStyles();
71e03035
VZ
54}
55
56wxStatusBarBase::~wxStatusBarBase()
57{
58 FreeWidths();
1f361cdd 59 FreeStacks();
97152f78 60 FreeStyles();
2ab82214
VZ
61
62 // notify the frame that it doesn't have a status bar any longer to avoid
63 // dangling pointers
b2e3be1c 64 wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
2ab82214
VZ
65 if ( frame && frame->GetStatusBar() == this )
66 {
67 frame->SetStatusBar(NULL);
68 }
71e03035
VZ
69}
70
71// ----------------------------------------------------------------------------
72// widths array handling
73// ----------------------------------------------------------------------------
74
75void wxStatusBarBase::InitWidths()
76{
77 m_statusWidths = NULL;
78}
79
80void wxStatusBarBase::FreeWidths()
81{
82 delete [] m_statusWidths;
83}
84
c2919ab3
VZ
85// ----------------------------------------------------------------------------
86// styles array handling
87// ----------------------------------------------------------------------------
88
89void wxStatusBarBase::InitStyles()
90{
91 m_statusStyles = NULL;
92}
93
94void wxStatusBarBase::FreeStyles()
95{
96 delete [] m_statusStyles;
97}
98
71e03035
VZ
99// ----------------------------------------------------------------------------
100// field widths
101// ----------------------------------------------------------------------------
102
103void wxStatusBarBase::SetFieldsCount(int number, const int *widths)
104{
105 wxCHECK_RET( number > 0, _T("invalid field number in SetFieldsCount") );
106
d775fa82 107 bool refresh = false;
71e03035
VZ
108
109 if ( number != m_nFields )
110 {
1f361cdd
MB
111 // copy stacks if present
112 if(m_statusTextStacks)
113 {
114 wxListString **newStacks = new wxListString*[number];
115 size_t i, j, max = wxMin(number, m_nFields);
116
117 // copy old stacks
118 for(i = 0; i < max; ++i)
119 newStacks[i] = m_statusTextStacks[i];
120 // free old stacks in excess
121 for(j = i; j < (size_t)m_nFields; ++j)
122 {
123 if(m_statusTextStacks[j])
124 {
125 m_statusTextStacks[j]->Clear();
126 delete m_statusTextStacks[j];
127 }
128 }
129 // initialize new stacks to NULL
130 for(j = i; j < (size_t)number; ++j)
131 newStacks[j] = 0;
132
133 m_statusTextStacks = newStacks;
134 }
135
c2919ab3
VZ
136 // Resize styles array
137 if (m_statusStyles)
138 {
139 int *oldStyles = m_statusStyles;
140 m_statusStyles = new int[number];
141 int i, max = wxMin(number, m_nFields);
142
143 // copy old styles
144 for (i = 0; i < max; ++i)
145 m_statusStyles[i] = oldStyles[i];
146
147 // initialize new styles to wxSB_NORMAL
148 for (i = max; i < number; ++i)
149 m_statusStyles[i] = wxSB_NORMAL;
150
151 // free old styles
152 delete [] oldStyles;
153 }
154
155
71e03035
VZ
156 m_nFields = number;
157
158 ReinitWidths();
159
d775fa82 160 refresh = true;
71e03035
VZ
161 }
162 //else: keep the old m_statusWidths if we had them
163
164 if ( widths )
165 {
166 SetStatusWidths(number, widths);
167
168 // already done from SetStatusWidths()
d775fa82 169 refresh = false;
71e03035
VZ
170 }
171
172 if ( refresh )
173 Refresh();
174}
175
176void wxStatusBarBase::SetStatusWidths(int WXUNUSED_UNLESS_DEBUG(n),
177 const int widths[])
178{
179 wxCHECK_RET( widths, _T("NULL pointer in SetStatusWidths") );
180
181 wxASSERT_MSG( n == m_nFields, _T("field number mismatch") );
182
183 if ( !m_statusWidths )
184 m_statusWidths = new int[m_nFields];
185
186 for ( int i = 0; i < m_nFields; i++ )
187 {
188 m_statusWidths[i] = widths[i];
189 }
190
191 // update the display after the widths changed
192 Refresh();
193}
194
c2919ab3
VZ
195void wxStatusBarBase::SetStatusStyles(int WXUNUSED_UNLESS_DEBUG(n),
196 const int styles[])
197{
198 wxCHECK_RET( styles, _T("NULL pointer in SetStatusStyles") );
199
200 wxASSERT_MSG( n == m_nFields, _T("field number mismatch") );
201
202 if ( !m_statusStyles )
203 m_statusStyles = new int[m_nFields];
204
205 for ( int i = 0; i < m_nFields; i++ )
206 {
207 m_statusStyles[i] = styles[i];
208 }
209
210 // update the display after the widths changed
211 Refresh();
212}
213
71e03035
VZ
214wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const
215{
216 wxArrayInt widths;
217
218 if ( m_statusWidths == NULL )
219 {
5057e659 220 if ( m_nFields )
71e03035 221 {
5057e659
VZ
222 // default: all fields have the same width
223 int nWidth = widthTotal / m_nFields;
224 for ( int i = 0; i < m_nFields; i++ )
225 {
226 widths.Add(nWidth);
227 }
71e03035 228 }
5057e659 229 //else: we're empty anyhow
71e03035
VZ
230 }
231 else // have explicit status widths
232 {
233 // calculate the total width of all the fixed width fields and the
234 // total number of var field widths counting with multiplicity
235 int nTotalWidth = 0,
236 nVarCount = 0,
237 i;
238 for ( i = 0; i < m_nFields; i++ )
239 {
240 if ( m_statusWidths[i] >= 0 )
241 {
242 nTotalWidth += m_statusWidths[i];
243 }
244 else
245 {
246 nVarCount += -m_statusWidths[i];
247 }
248 }
249
250 // the amount of extra width we have per each var width field
1a83b9bd 251 int widthExtra = widthTotal - nTotalWidth;
71e03035
VZ
252
253 // do fill the array
254 for ( i = 0; i < m_nFields; i++ )
255 {
256 if ( m_statusWidths[i] >= 0 )
257 {
258 widths.Add(m_statusWidths[i]);
259 }
260 else
261 {
1a83b9bd
VZ
262 int nVarWidth = widthExtra > 0 ? (widthExtra * -m_statusWidths[i]) / nVarCount : 0;
263 nVarCount += m_statusWidths[i];
264 widthExtra -= nVarWidth;
265 widths.Add(nVarWidth);
71e03035
VZ
266 }
267 }
268 }
269
270 return widths;
271}
272
1f361cdd
MB
273// ----------------------------------------------------------------------------
274// text stacks handling
275// ----------------------------------------------------------------------------
276
277void wxStatusBarBase::InitStacks()
278{
279 m_statusTextStacks = NULL;
280}
281
282void wxStatusBarBase::FreeStacks()
283{
97152f78
VZ
284 if ( !m_statusTextStacks )
285 return;
1f361cdd 286
97152f78 287 for ( size_t i = 0; i < (size_t)m_nFields; ++i )
1f361cdd 288 {
97152f78 289 if ( m_statusTextStacks[i] )
1f361cdd 290 {
222ed1d6
MB
291 wxListString& t = *m_statusTextStacks[i];
292 WX_CLEAR_LIST(wxListString, t);
1f361cdd
MB
293 delete m_statusTextStacks[i];
294 }
295 }
296
297 delete[] m_statusTextStacks;
298}
299
300// ----------------------------------------------------------------------------
301// text stacks
302// ----------------------------------------------------------------------------
303
304void wxStatusBarBase::PushStatusText(const wxString& text, int number)
305{
306 wxListString* st = GetOrCreateStatusStack(number);
7d2d5d81
JS
307 // This long-winded way around avoids an internal compiler error
308 // in VC++ 6 with RTTI enabled
309 wxString tmp1(GetStatusText(number));
310 wxString* tmp = new wxString(tmp1);
311 st->Insert(tmp);
1f361cdd
MB
312 SetStatusText(text, number);
313}
314
315void wxStatusBarBase::PopStatusText(int number)
316{
317 wxListString *st = GetStatusStack(number);
318 wxCHECK_RET( st, _T("Unbalanced PushStatusText/PopStatusText") );
222ed1d6 319 wxListString::compatibility_iterator top = st->GetFirst();
1f361cdd
MB
320
321 SetStatusText(*top->GetData(), number);
222ed1d6
MB
322 delete top->GetData();
323 st->Erase(top);
1f361cdd
MB
324 if(st->GetCount() == 0)
325 {
326 delete st;
327 m_statusTextStacks[number] = 0;
328 }
329}
330
331wxListString *wxStatusBarBase::GetStatusStack(int i) const
332{
333 if(!m_statusTextStacks)
334 return 0;
335 return m_statusTextStacks[i];
336}
337
338wxListString *wxStatusBarBase::GetOrCreateStatusStack(int i)
339{
340 if(!m_statusTextStacks)
341 {
342 m_statusTextStacks = new wxListString*[m_nFields];
343
344 size_t j;
345 for(j = 0; j < (size_t)m_nFields; ++j) m_statusTextStacks[j] = 0;
346 }
347
348 if(!m_statusTextStacks[i])
349 {
350 m_statusTextStacks[i] = new wxListString();
1f361cdd
MB
351 }
352
353 return m_statusTextStacks[i];
354}
355
71e03035
VZ
356#endif // wxUSE_STATUSBAR
357