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