File/dir dialog styles and other changes (patch 1488371):
[wxWidgets.git] / src / common / statbar.cpp
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 // 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
28 #include "wx/frame.h"
29 #include "wx/statusbr.h"
30 #endif //WX_PRECOMP
31
32 #if wxUSE_STATUSBAR
33
34 #include "wx/listimpl.cpp"
35 WX_DEFINE_LIST(wxListString)
36
37 // ============================================================================
38 // wxStatusBarBase implementation
39 // ============================================================================
40
41 IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
42
43 // ----------------------------------------------------------------------------
44 // ctor/dtor
45 // ----------------------------------------------------------------------------
46
47 wxStatusBarBase::wxStatusBarBase()
48 {
49 m_nFields = 0;
50
51 InitWidths();
52 InitStacks();
53 InitStyles();
54 }
55
56 wxStatusBarBase::~wxStatusBarBase()
57 {
58 FreeWidths();
59 FreeStacks();
60 FreeStyles();
61
62 // notify the frame that it doesn't have a status bar any longer to avoid
63 // dangling pointers
64 wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
65 if ( frame && frame->GetStatusBar() == this )
66 {
67 frame->SetStatusBar(NULL);
68 }
69 }
70
71 // ----------------------------------------------------------------------------
72 // widths array handling
73 // ----------------------------------------------------------------------------
74
75 void wxStatusBarBase::InitWidths()
76 {
77 m_statusWidths = NULL;
78 }
79
80 void wxStatusBarBase::FreeWidths()
81 {
82 delete [] m_statusWidths;
83 }
84
85 // ----------------------------------------------------------------------------
86 // styles array handling
87 // ----------------------------------------------------------------------------
88
89 void wxStatusBarBase::InitStyles()
90 {
91 m_statusStyles = NULL;
92 }
93
94 void wxStatusBarBase::FreeStyles()
95 {
96 delete [] m_statusStyles;
97 }
98
99 // ----------------------------------------------------------------------------
100 // field widths
101 // ----------------------------------------------------------------------------
102
103 void wxStatusBarBase::SetFieldsCount(int number, const int *widths)
104 {
105 wxCHECK_RET( number > 0, _T("invalid field number in SetFieldsCount") );
106
107 bool refresh = false;
108
109 if ( number != m_nFields )
110 {
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
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
156 m_nFields = number;
157
158 ReinitWidths();
159
160 refresh = true;
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()
169 refresh = false;
170 }
171
172 if ( refresh )
173 Refresh();
174 }
175
176 void 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
195 void 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
214 wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const
215 {
216 wxArrayInt widths;
217
218 if ( m_statusWidths == NULL )
219 {
220 if ( m_nFields )
221 {
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 }
228 }
229 //else: we're empty anyhow
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
251 int widthExtra = widthTotal - nTotalWidth;
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 {
262 int nVarWidth = widthExtra > 0 ? (widthExtra * -m_statusWidths[i]) / nVarCount : 0;
263 nVarCount += m_statusWidths[i];
264 widthExtra -= nVarWidth;
265 widths.Add(nVarWidth);
266 }
267 }
268 }
269
270 return widths;
271 }
272
273 // ----------------------------------------------------------------------------
274 // text stacks handling
275 // ----------------------------------------------------------------------------
276
277 void wxStatusBarBase::InitStacks()
278 {
279 m_statusTextStacks = NULL;
280 }
281
282 void wxStatusBarBase::FreeStacks()
283 {
284 if ( !m_statusTextStacks )
285 return;
286
287 for ( size_t i = 0; i < (size_t)m_nFields; ++i )
288 {
289 if ( m_statusTextStacks[i] )
290 {
291 wxListString& t = *m_statusTextStacks[i];
292 WX_CLEAR_LIST(wxListString, t);
293 delete m_statusTextStacks[i];
294 }
295 }
296
297 delete[] m_statusTextStacks;
298 }
299
300 // ----------------------------------------------------------------------------
301 // text stacks
302 // ----------------------------------------------------------------------------
303
304 void wxStatusBarBase::PushStatusText(const wxString& text, int number)
305 {
306 wxListString* st = GetOrCreateStatusStack(number);
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);
312 SetStatusText(text, number);
313 }
314
315 void wxStatusBarBase::PopStatusText(int number)
316 {
317 wxListString *st = GetStatusStack(number);
318 wxCHECK_RET( st, _T("Unbalanced PushStatusText/PopStatusText") );
319 wxListString::compatibility_iterator top = st->GetFirst();
320
321 SetStatusText(*top->GetData(), number);
322 delete top->GetData();
323 st->Erase(top);
324 if(st->GetCount() == 0)
325 {
326 delete st;
327 m_statusTextStacks[number] = 0;
328 }
329 }
330
331 wxListString *wxStatusBarBase::GetStatusStack(int i) const
332 {
333 if(!m_statusTextStacks)
334 return 0;
335 return m_statusTextStacks[i];
336 }
337
338 wxListString *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();
351 }
352
353 return m_statusTextStacks[i];
354 }
355
356 #endif // wxUSE_STATUSBAR
357