No changes, just fix a typo in a comment in docview event handling code.
[wxWidgets.git] / src / common / statbar.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/statbar.cpp
3 // Purpose: wxStatusBarBase implementation
4 // Author: Vadim Zeitlin
5 // Modified by: Francesco Montorsi
6 // Created: 14.10.01
7 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_STATUSBAR
27
28 #include "wx/statusbr.h"
29
30 #ifndef WX_PRECOMP
31 #include "wx/frame.h"
32 #endif //WX_PRECOMP
33
34 const char wxStatusBarNameStr[] = "statusBar";
35
36 // ============================================================================
37 // wxStatusBarPane implementation
38 // ============================================================================
39
40 bool wxStatusBarPane::SetText(const wxString& text)
41 {
42 if ( text == m_text )
43 return false;
44
45 /*
46 If we have a message to restore on the stack, we update it to
47 correspond to the current one so that a sequence of calls such as
48
49 1. SetStatusText("foo")
50 2. PushStatusText("bar")
51 3. SetStatusText("new foo")
52 4. PopStatusText()
53
54 doesn't overwrite the "new foo" which should be shown at the end with
55 the old value "foo". This would be unexpected and hard to avoid,
56 especially when PushStatusText() is used internally by wxWidgets
57 without knowledge of the user program, as it is for showing the menu
58 and toolbar help strings.
59
60 By updating the top of the stack we ensure that the next call to
61 PopStatusText() basically becomes a NOP without breaking the balance
62 between the calls to push and pop as we would have done if we really
63 called PopStatusText() here.
64 */
65 if ( !m_arrStack.empty() )
66 {
67 m_arrStack.back() = text;
68 }
69
70 m_text = text;
71
72 return true;
73 }
74
75 bool wxStatusBarPane::PushText(const wxString& text)
76 {
77 // save the currently shown text
78 m_arrStack.push_back(m_text);
79
80 // and update the new one if necessary
81 if ( text == m_text )
82 return false;
83
84 m_text = text;
85
86 return true;
87 }
88
89 bool wxStatusBarPane::PopText()
90 {
91 wxCHECK_MSG( !m_arrStack.empty(), false, "no status message to pop" );
92
93 const wxString text = m_arrStack.back();
94
95 m_arrStack.pop_back();
96
97 if ( text == m_text )
98 return false;
99
100 m_text = text;
101
102 return true;
103 }
104
105 // ============================================================================
106 // wxStatusBarBase implementation
107 // ============================================================================
108
109 IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
110
111 #include "wx/arrimpl.cpp" // This is a magic incantation which must be done!
112 WX_DEFINE_EXPORTED_OBJARRAY(wxStatusBarPaneArray)
113
114
115 // ----------------------------------------------------------------------------
116 // ctor/dtor
117 // ----------------------------------------------------------------------------
118
119 wxStatusBarBase::wxStatusBarBase()
120 {
121 m_bSameWidthForAllPanes = true;
122 }
123
124 wxStatusBarBase::~wxStatusBarBase()
125 {
126 // notify the frame that it doesn't have a status bar any longer to avoid
127 // dangling pointers
128 wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
129 if ( frame && frame->GetStatusBar() == this )
130 frame->SetStatusBar(NULL);
131 }
132
133 // ----------------------------------------------------------------------------
134 // field widths
135 // ----------------------------------------------------------------------------
136
137 void wxStatusBarBase::SetFieldsCount(int number, const int *widths)
138 {
139 wxCHECK_RET( number > 0, wxT("invalid field number in SetFieldsCount") );
140
141 if ( (size_t)number > m_panes.GetCount() )
142 {
143 wxStatusBarPane newPane;
144
145 // add more entries with the default style and zero width
146 // (this will be set later)
147 for (size_t i = m_panes.GetCount(); i < (size_t)number; ++i)
148 m_panes.Add(newPane);
149 }
150 else if ( (size_t)number < m_panes.GetCount() )
151 {
152 // remove entries in excess
153 m_panes.RemoveAt(number, m_panes.GetCount()-number);
154 }
155
156 // SetStatusWidths will automatically refresh
157 SetStatusWidths(number, widths);
158 }
159
160 void wxStatusBarBase::SetStatusWidths(int WXUNUSED_UNLESS_DEBUG(n),
161 const int widths[])
162 {
163 wxASSERT_MSG( (size_t)n == m_panes.GetCount(), wxT("field number mismatch") );
164
165 if (widths == NULL)
166 {
167 // special value meaning: override explicit pane widths and make them all
168 // of the same size
169 m_bSameWidthForAllPanes = true;
170 }
171 else
172 {
173 for ( size_t i = 0; i < m_panes.GetCount(); i++ )
174 m_panes[i].SetWidth(widths[i]);
175
176 m_bSameWidthForAllPanes = false;
177 }
178
179 // update the display after the widths changed
180 Refresh();
181 }
182
183 void wxStatusBarBase::SetStatusStyles(int WXUNUSED_UNLESS_DEBUG(n),
184 const int styles[])
185 {
186 wxCHECK_RET( styles, wxT("NULL pointer in SetStatusStyles") );
187
188 wxASSERT_MSG( (size_t)n == m_panes.GetCount(), wxT("field number mismatch") );
189
190 for ( size_t i = 0; i < m_panes.GetCount(); i++ )
191 m_panes[i].SetStyle(styles[i]);
192
193 // update the display after the widths changed
194 Refresh();
195 }
196
197 wxArrayInt wxStatusBarBase::CalculateAbsWidths(wxCoord widthTotal) const
198 {
199 wxArrayInt widths;
200
201 if ( m_bSameWidthForAllPanes )
202 {
203 // Default: all fields have the same width. This is not always
204 // possible to do exactly (if widthTotal is not divisible by
205 // m_panes.GetCount()) - if that happens, we distribute the extra
206 // pixels among all fields:
207 int widthToUse = widthTotal;
208
209 for ( size_t i = m_panes.GetCount(); i > 0; i-- )
210 {
211 // divide the unassigned width evently between the
212 // not yet processed fields:
213 int w = widthToUse / i;
214 widths.Add(w);
215 widthToUse -= w;
216 }
217 }
218 else // do not override explicit pane widths
219 {
220 // calculate the total width of all the fixed width fields and the
221 // total number of var field widths counting with multiplicity
222 size_t nTotalWidth = 0,
223 nVarCount = 0,
224 i;
225
226 for ( i = 0; i < m_panes.GetCount(); i++ )
227 {
228 if ( m_panes[i].GetWidth() >= 0 )
229 nTotalWidth += m_panes[i].GetWidth();
230 else
231 nVarCount += -m_panes[i].GetWidth();
232 }
233
234 // the amount of extra width we have per each var width field
235 int widthExtra = widthTotal - nTotalWidth;
236
237 // do fill the array
238 for ( i = 0; i < m_panes.GetCount(); i++ )
239 {
240 if ( m_panes[i].GetWidth() >= 0 )
241 widths.Add(m_panes[i].GetWidth());
242 else
243 {
244 int nVarWidth = widthExtra > 0 ? (widthExtra * (-m_panes[i].GetWidth())) / nVarCount : 0;
245 nVarCount += m_panes[i].GetWidth();
246 widthExtra -= nVarWidth;
247 widths.Add(nVarWidth);
248 }
249 }
250 }
251
252 return widths;
253 }
254
255 // ----------------------------------------------------------------------------
256 // setting/getting status text
257 // ----------------------------------------------------------------------------
258
259 void wxStatusBarBase::SetStatusText(const wxString& text, int number)
260 {
261 wxCHECK_RET( (unsigned)number < m_panes.size(),
262 "invalid status bar field index" );
263
264 if ( m_panes[number].SetText(text) )
265 DoUpdateStatusText(number);
266 }
267
268 wxString wxStatusBarBase::GetStatusText(int number) const
269 {
270 wxCHECK_MSG( (unsigned)number < m_panes.size(), wxString(),
271 "invalid status bar field index" );
272
273 return m_panes[number].GetText();
274 }
275
276 void wxStatusBarBase::SetEllipsizedFlag(int number, bool isEllipsized)
277 {
278 wxCHECK_RET( (unsigned)number < m_panes.size(),
279 "invalid status bar field index" );
280
281 m_panes[number].SetIsEllipsized(isEllipsized);
282 }
283
284 // ----------------------------------------------------------------------------
285 // pushing/popping status text
286 // ----------------------------------------------------------------------------
287
288 void wxStatusBarBase::PushStatusText(const wxString& text, int number)
289 {
290 wxCHECK_RET( (unsigned)number < m_panes.size(),
291 "invalid status bar field index" );
292
293 if ( m_panes[number].PushText(text) )
294 DoUpdateStatusText(number);
295 }
296
297 void wxStatusBarBase::PopStatusText(int number)
298 {
299 wxCHECK_RET( (unsigned)number < m_panes.size(),
300 "invalid status bar field index" );
301
302 if ( m_panes[number].PopText() )
303 DoUpdateStatusText(number);
304 }
305
306 #endif // wxUSE_STATUSBAR