avoid gcc warning
[wxWidgets.git] / src / common / dlgcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/dlgcmn.cpp
3 // Purpose: common (to all ports) wxDialog functions
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 28.06.99
7 // RCS-ID: $Id$
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: 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 "dialogbase.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/button.h"
33 #include "wx/dialog.h"
34 #include "wx/dcclient.h"
35 #include "wx/intl.h"
36 #include "wx/settings.h"
37 #include "wx/stattext.h"
38 #include "wx/sizer.h"
39 #include "wx/button.h"
40 #include "wx/containr.h"
41 #endif
42
43 #if wxUSE_STATTEXT
44
45 // ----------------------------------------------------------------------------
46 // wxTextWrapper
47 // ----------------------------------------------------------------------------
48
49 // this class is used to wrap the text on word boundary: wrapping is done by
50 // calling OnStartLine() and OnOutputLine() functions
51 class wxTextWrapper
52 {
53 public:
54 wxTextWrapper() { m_eol = false; }
55
56 // win is used for getting the font, text is the text to wrap, width is the
57 // max line width or -1 to disable wrapping
58 void Wrap(wxWindow *win, const wxString& text, int widthMax);
59
60 // we don't need it, but just to avoid compiler warnings
61 virtual ~wxTextWrapper() { }
62
63 protected:
64 // line may be empty
65 virtual void OnOutputLine(const wxString& line) = 0;
66
67 // called at the start of every new line (except the very first one)
68 virtual void OnNewLine() { }
69
70 private:
71 // call OnOutputLine() and set m_eol to true
72 void DoOutputLine(const wxString& line)
73 {
74 OnOutputLine(line);
75
76 m_eol = true;
77 }
78
79 // this function is a destructive inspector: when it returns true it also
80 // resets the flag to false so calling it again woulnd't return true any
81 // more
82 bool IsStartOfNewLine()
83 {
84 if ( !m_eol )
85 return false;
86
87 m_eol = false;
88
89 return true;
90 }
91
92
93 bool m_eol;
94 };
95
96 #endif // wxUSE_STATTEXT
97
98 // ----------------------------------------------------------------------------
99 // wxDialogBase
100 // ----------------------------------------------------------------------------
101
102 // FIXME - temporary hack in absence of wxTopLevelWindow, should be always used
103 #ifdef wxTopLevelWindowNative
104 BEGIN_EVENT_TABLE(wxDialogBase, wxTopLevelWindow)
105 WX_EVENT_TABLE_CONTROL_CONTAINER(wxDialogBase)
106 END_EVENT_TABLE()
107
108 WX_DELEGATE_TO_CONTROL_CONTAINER(wxDialogBase)
109 #endif
110
111 void wxDialogBase::Init()
112 {
113 m_returnCode = 0;
114 m_affirmativeId = wxID_OK;
115
116 // the dialogs have this flag on by default to prevent the events from the
117 // dialog controls from reaching the parent frame which is usually
118 // undesirable and can lead to unexpected and hard to find bugs
119 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
120
121 #ifdef wxTopLevelWindowNative // FIXME - temporary hack, should be always used!
122 m_container.SetContainerWindow(this);
123 #endif
124 }
125
126 #if wxUSE_STATTEXT
127
128 void wxTextWrapper::Wrap(wxWindow *win, const wxString& text, int widthMax)
129 {
130 const wxChar *lastSpace = NULL;
131 wxString line;
132
133 const wxChar *lineStart = text.c_str();
134 for ( const wxChar *p = lineStart; ; p++ )
135 {
136 if ( IsStartOfNewLine() )
137 {
138 OnNewLine();
139
140 lastSpace = NULL;
141 line.clear();
142 lineStart = p;
143 }
144
145 if ( *p == _T('\n') || *p == _T('\0') )
146 {
147 DoOutputLine(line);
148
149 if ( *p == _T('\0') )
150 break;
151 }
152 else // not EOL
153 {
154 if ( *p == _T(' ') )
155 lastSpace = p;
156
157 line += *p;
158
159 if ( widthMax >= 0 && lastSpace )
160 {
161 int width;
162 win->GetTextExtent(line, &width, NULL);
163
164 if ( width > widthMax )
165 {
166 // remove the last word from this line
167 line.erase(lastSpace - lineStart, p + 1 - lineStart);
168 DoOutputLine(line);
169
170 // go back to the last word of this line which we didn't
171 // output yet
172 p = lastSpace;
173 }
174 }
175 //else: no wrapping at all or impossible to wrap
176 }
177 }
178 }
179
180 wxSizer *wxDialogBase::CreateTextSizer(const wxString& message)
181 {
182 // I admit that this is complete bogus, but it makes
183 // message boxes work for pda screens temporarily..
184 int widthMax = -1;
185 const bool is_pda = wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA;
186 if (is_pda)
187 {
188 widthMax = wxSystemSettings::GetMetric( wxSYS_SCREEN_X ) - 25;
189 }
190
191 // '&' is used as accel mnemonic prefix in the wxWidgets controls but in
192 // the static messages created by CreateTextSizer() (used by wxMessageBox,
193 // for example), we don't want this special meaning, so we need to quote it
194 wxString text(message);
195 text.Replace(_T("&"), _T("&&"));
196
197
198 class TextSizerWrapper : public wxTextWrapper
199 {
200 public:
201 TextSizerWrapper(wxWindow *win)
202 {
203 m_win = win;
204 m_hLine = 0;
205 }
206
207 wxSizer *CreateSizer(const wxString& text, int widthMax)
208 {
209 m_sizer = new wxBoxSizer(wxVERTICAL);
210 Wrap(m_win, text, widthMax);
211 return m_sizer;
212 }
213
214 protected:
215 virtual void OnOutputLine(const wxString& line)
216 {
217 if ( !line.empty() )
218 {
219 m_sizer->Add(new wxStaticText(m_win, wxID_ANY, line));
220 }
221 else // empty line, no need to create a control for it
222 {
223 if ( !m_hLine )
224 m_hLine = m_win->GetCharHeight();
225
226 m_sizer->Add(5, m_hLine);
227 }
228 }
229
230 private:
231 wxWindow *m_win;
232 wxSizer *m_sizer;
233 int m_hLine;
234 };
235
236 TextSizerWrapper wrapper(this);
237
238 return wrapper.CreateSizer(text, widthMax);
239 }
240
241 void wxStaticTextBase::Wrap(int width)
242 {
243 class LabelWrapper : public wxTextWrapper
244 {
245 public:
246 void WrapLabel(wxStaticTextBase *text, int widthMax)
247 {
248 m_text.clear();
249 Wrap(text, text->GetLabel(), widthMax);
250 text->SetLabel(m_text);
251 }
252
253 protected:
254 virtual void OnOutputLine(const wxString& line)
255 {
256 m_text += line;
257 }
258
259 virtual void OnNewLine()
260 {
261 m_text += _T('\n');
262 }
263
264 private:
265 wxString m_text;
266 };
267
268 LabelWrapper wrapper;
269 wrapper.WrapLabel(this, width);
270 }
271
272 #endif // wxUSE_STATTEXT
273
274 #if wxUSE_BUTTON
275
276 wxSizer *wxDialogBase::CreateButtonSizer( long flags )
277 {
278 #ifdef __SMARTPHONE__
279 wxDialog* dialog = (wxDialog*) this;
280 if (flags & wxOK){
281 dialog->SetLeftMenu(wxID_OK);
282 }
283
284 if (flags & wxCANCEL){
285 dialog->SetRightMenu(wxID_CANCEL);
286 }
287
288 if (flags & wxYES){
289 dialog->SetLeftMenu(wxID_YES);
290 }
291
292 if (flags & wxNO){
293 dialog->SetLeftMenu(wxID_NO);
294 }
295 wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
296 return sizer;
297 #else
298 return CreateStdDialogButtonSizer( flags );
299 #endif
300 }
301
302 wxStdDialogButtonSizer *wxDialogBase::CreateStdDialogButtonSizer( long flags )
303 {
304 wxStdDialogButtonSizer *sizer = new wxStdDialogButtonSizer();
305 wxButton *ok = NULL;
306 wxButton *yes = NULL;
307 wxButton *no = NULL;
308
309 if (flags & wxOK){
310 ok = new wxButton(this, wxID_OK);
311 sizer->AddButton(ok);
312 }
313
314 if (flags & wxCANCEL){
315 wxButton *cancel = new wxButton(this, wxID_CANCEL);
316 sizer->AddButton(cancel);
317 }
318
319 if (flags & wxYES){
320 yes = new wxButton(this, wxID_YES);
321 sizer->AddButton(yes);
322 }
323
324 if (flags & wxNO){
325 no = new wxButton(this, wxID_NO);
326 sizer->AddButton(no);
327 }
328
329 if (flags & wxHELP){
330 wxButton *help = new wxButton(this, wxID_HELP);
331 sizer->AddButton(help);
332 }
333
334 sizer->Realize();
335
336 if (flags & wxNO_DEFAULT)
337 {
338 if (no)
339 {
340 no->SetDefault();
341 no->SetFocus();
342 }
343 }
344 else
345 {
346 if (ok)
347 {
348 ok->SetDefault();
349 ok->SetFocus();
350 }
351 else if (yes)
352 {
353 yes->SetDefault();
354 yes->SetFocus();
355 }
356 }
357
358 if (flags & wxOK)
359 SetAffirmativeId(wxID_OK);
360 else if (flags & wxYES)
361 SetAffirmativeId(wxID_YES);
362
363 return sizer;
364 }
365
366
367 #endif // wxUSE_BUTTON