]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/statbar.cpp
fix for always terminating intermediate UniChar String for 4 bytes wchar_t
[wxWidgets.git] / src / common / statbar.cpp
... / ...
CommitLineData
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>
9// License: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "statbar.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/statusbr.h"
33#endif //WX_PRECOMP
34
35#if wxUSE_STATUSBAR
36
37#include "wx/listimpl.cpp"
38WX_DEFINE_LIST(wxListString);
39
40// ============================================================================
41// wxStatusBarBase implementation
42// ============================================================================
43
44IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
45
46// ----------------------------------------------------------------------------
47// ctor/dtor
48// ----------------------------------------------------------------------------
49
50wxStatusBarBase::wxStatusBarBase()
51{
52 m_nFields = 0;
53
54 InitWidths();
55 InitStacks();
56}
57
58wxStatusBarBase::~wxStatusBarBase()
59{
60 FreeWidths();
61 FreeStacks();
62}
63
64// ----------------------------------------------------------------------------
65// widths array handling
66// ----------------------------------------------------------------------------
67
68void wxStatusBarBase::InitWidths()
69{
70 m_statusWidths = NULL;
71}
72
73void wxStatusBarBase::FreeWidths()
74{
75 delete [] m_statusWidths;
76}
77
78// ----------------------------------------------------------------------------
79// field widths
80// ----------------------------------------------------------------------------
81
82void wxStatusBarBase::SetFieldsCount(int number, const int *widths)
83{
84 wxCHECK_RET( number > 0, _T("invalid field number in SetFieldsCount") );
85
86 bool refresh = FALSE;
87
88 if ( number != m_nFields )
89 {
90 // copy stacks if present
91 if(m_statusTextStacks)
92 {
93 wxListString **newStacks = new wxListString*[number];
94 size_t i, j, max = wxMin(number, m_nFields);
95
96 // copy old stacks
97 for(i = 0; i < max; ++i)
98 newStacks[i] = m_statusTextStacks[i];
99 // free old stacks in excess
100 for(j = i; j < (size_t)m_nFields; ++j)
101 {
102 if(m_statusTextStacks[j])
103 {
104 m_statusTextStacks[j]->Clear();
105 delete m_statusTextStacks[j];
106 }
107 }
108 // initialize new stacks to NULL
109 for(j = i; j < (size_t)number; ++j)
110 newStacks[j] = 0;
111
112 m_statusTextStacks = newStacks;
113 }
114
115 m_nFields = number;
116
117 ReinitWidths();
118
119 refresh = TRUE;
120 }
121 //else: keep the old m_statusWidths if we had them
122
123 if ( widths )
124 {
125 SetStatusWidths(number, widths);
126
127 // already done from SetStatusWidths()
128 refresh = FALSE;
129 }
130
131 if ( refresh )
132 Refresh();
133}
134
135void wxStatusBarBase::SetStatusWidths(int WXUNUSED_UNLESS_DEBUG(n),
136 const int widths[])
137{
138 wxCHECK_RET( widths, _T("NULL pointer in SetStatusWidths") );
139
140 wxASSERT_MSG( n == m_nFields, _T("field number mismatch") );
141
142 if ( !m_statusWidths )
143 m_statusWidths = new int[m_nFields];
144
145 for ( int i = 0; i < m_nFields; i++ )
146 {
147 m_statusWidths[i] = widths[i];
148 }
149
150 // update the display after the widths changed
151 Refresh();
152}
153
154wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const
155{
156 wxArrayInt widths;
157
158 if ( m_statusWidths == NULL )
159 {
160 if ( m_nFields )
161 {
162 // default: all fields have the same width
163 int nWidth = widthTotal / m_nFields;
164 for ( int i = 0; i < m_nFields; i++ )
165 {
166 widths.Add(nWidth);
167 }
168 }
169 //else: we're empty anyhow
170 }
171 else // have explicit status widths
172 {
173 // calculate the total width of all the fixed width fields and the
174 // total number of var field widths counting with multiplicity
175 int nTotalWidth = 0,
176 nVarCount = 0,
177 i;
178 for ( i = 0; i < m_nFields; i++ )
179 {
180 if ( m_statusWidths[i] >= 0 )
181 {
182 nTotalWidth += m_statusWidths[i];
183 }
184 else
185 {
186 nVarCount += -m_statusWidths[i];
187 }
188 }
189
190 // the amount of extra width we have per each var width field
191 int nVarWidth;
192 if ( nVarCount )
193 {
194 int widthExtra = widthTotal - nTotalWidth;
195 nVarWidth = widthExtra > 0 ? widthExtra / nVarCount : 0;
196 }
197 else // no var width fields at all
198 {
199 nVarWidth = 0;
200 }
201
202 // do fill the array
203 for ( i = 0; i < m_nFields; i++ )
204 {
205 if ( m_statusWidths[i] >= 0 )
206 {
207 widths.Add(m_statusWidths[i]);
208 }
209 else
210 {
211 widths.Add(-m_statusWidths[i]*nVarWidth);
212 }
213 }
214 }
215
216 return widths;
217}
218
219// ----------------------------------------------------------------------------
220// text stacks handling
221// ----------------------------------------------------------------------------
222
223void wxStatusBarBase::InitStacks()
224{
225 m_statusTextStacks = NULL;
226}
227
228void wxStatusBarBase::FreeStacks()
229{
230 if(!m_statusTextStacks) return;
231 size_t i;
232
233 for(i = 0; i < (size_t)m_nFields; ++i)
234 {
235 if(m_statusTextStacks[i])
236 {
237 wxListString& t = *m_statusTextStacks[i];
238 WX_CLEAR_LIST(wxListString, t);
239 delete m_statusTextStacks[i];
240 }
241 }
242
243 delete[] m_statusTextStacks;
244}
245
246// ----------------------------------------------------------------------------
247// text stacks
248// ----------------------------------------------------------------------------
249
250void wxStatusBarBase::PushStatusText(const wxString& text, int number)
251{
252 wxListString* st = GetOrCreateStatusStack(number);
253 // This long-winded way around avoids an internal compiler error
254 // in VC++ 6 with RTTI enabled
255 wxString tmp1(GetStatusText(number));
256 wxString* tmp = new wxString(tmp1);
257 st->Insert(tmp);
258 SetStatusText(text, number);
259}
260
261void wxStatusBarBase::PopStatusText(int number)
262{
263 wxListString *st = GetStatusStack(number);
264 wxCHECK_RET( st, _T("Unbalanced PushStatusText/PopStatusText") );
265 wxListString::compatibility_iterator top = st->GetFirst();
266
267 SetStatusText(*top->GetData(), number);
268 delete top->GetData();
269 st->Erase(top);
270 if(st->GetCount() == 0)
271 {
272 delete st;
273 m_statusTextStacks[number] = 0;
274 }
275}
276
277wxListString *wxStatusBarBase::GetStatusStack(int i) const
278{
279 if(!m_statusTextStacks)
280 return 0;
281 return m_statusTextStacks[i];
282}
283
284wxListString *wxStatusBarBase::GetOrCreateStatusStack(int i)
285{
286 if(!m_statusTextStacks)
287 {
288 m_statusTextStacks = new wxListString*[m_nFields];
289
290 size_t j;
291 for(j = 0; j < (size_t)m_nFields; ++j) m_statusTextStacks[j] = 0;
292 }
293
294 if(!m_statusTextStacks[i])
295 {
296 m_statusTextStacks[i] = new wxListString();
297 }
298
299 return m_statusTextStacks[i];
300}
301
302#endif // wxUSE_STATUSBAR
303