]> git.saurik.com Git - wxWidgets.git/blame - src/common/dlgcmn.cpp
Include wx/brush.h according to precompiled headers of wx/wx.h (with other minor...
[wxWidgets.git] / src / common / dlgcmn.cpp
CommitLineData
e37feda2 1/////////////////////////////////////////////////////////////////////////////
f1e01716 2// Name: src/common/dlgcmn.cpp
e37feda2
VZ
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
65571936 9// Licence: wxWindows licence
e37feda2
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
e37feda2
VZ
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
f6bcfd97 28 #include "wx/button.h"
e37feda2
VZ
29 #include "wx/dialog.h"
30 #include "wx/dcclient.h"
9f3a38fc 31 #include "wx/intl.h"
e37feda2 32 #include "wx/settings.h"
9f3a38fc 33 #include "wx/stattext.h"
92afa2b1 34 #include "wx/sizer.h"
7d9f12f3 35 #include "wx/containr.h"
e37feda2
VZ
36#endif
37
897b24cf
WS
38#include "wx/statline.h"
39#include "wx/sysopt.h"
40
5d1b4919
VZ
41#if wxUSE_STATTEXT
42
43// ----------------------------------------------------------------------------
44// wxTextWrapper
45// ----------------------------------------------------------------------------
46
47// this class is used to wrap the text on word boundary: wrapping is done by
48// calling OnStartLine() and OnOutputLine() functions
49class wxTextWrapper
50{
51public:
52 wxTextWrapper() { m_eol = false; }
53
54 // win is used for getting the font, text is the text to wrap, width is the
55 // max line width or -1 to disable wrapping
56 void Wrap(wxWindow *win, const wxString& text, int widthMax);
57
0db7dfb0
VZ
58 // we don't need it, but just to avoid compiler warnings
59 virtual ~wxTextWrapper() { }
60
5d1b4919
VZ
61protected:
62 // line may be empty
63 virtual void OnOutputLine(const wxString& line) = 0;
64
65 // called at the start of every new line (except the very first one)
66 virtual void OnNewLine() { }
67
68private:
69 // call OnOutputLine() and set m_eol to true
70 void DoOutputLine(const wxString& line)
71 {
72 OnOutputLine(line);
73
74 m_eol = true;
75 }
76
77 // this function is a destructive inspector: when it returns true it also
78 // resets the flag to false so calling it again woulnd't return true any
79 // more
80 bool IsStartOfNewLine()
81 {
82 if ( !m_eol )
83 return false;
84
85 m_eol = false;
86
87 return true;
88 }
89
90
91 bool m_eol;
92};
93
94#endif // wxUSE_STATTEXT
95
96// ----------------------------------------------------------------------------
92afa2b1 97// wxDialogBase
5d1b4919 98// ----------------------------------------------------------------------------
e37feda2 99
5d1b4919 100// FIXME - temporary hack in absence of wxTopLevelWindow, should be always used
7d9f12f3
VS
101#ifdef wxTopLevelWindowNative
102BEGIN_EVENT_TABLE(wxDialogBase, wxTopLevelWindow)
103 WX_EVENT_TABLE_CONTROL_CONTAINER(wxDialogBase)
104END_EVENT_TABLE()
105
106WX_DELEGATE_TO_CONTROL_CONTAINER(wxDialogBase)
107#endif
108
109void wxDialogBase::Init()
110{
111 m_returnCode = 0;
9ceeecb9 112 m_affirmativeId = wxID_OK;
c6ece595
VZ
113 m_escapeId = wxID_ANY;
114
e4b713a2
VZ
115 // the dialogs have this flag on by default to prevent the events from the
116 // dialog controls from reaching the parent frame which is usually
117 // undesirable and can lead to unexpected and hard to find bugs
118 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
119
7d9f12f3
VS
120#ifdef wxTopLevelWindowNative // FIXME - temporary hack, should be always used!
121 m_container.SetContainerWindow(this);
122#endif
123}
124
5d1b4919 125#if wxUSE_STATTEXT
1e6feb95 126
5d1b4919 127void wxTextWrapper::Wrap(wxWindow *win, const wxString& text, int widthMax)
e37feda2 128{
5d1b4919
VZ
129 const wxChar *lastSpace = NULL;
130 wxString line;
131
132 const wxChar *lineStart = text.c_str();
133 for ( const wxChar *p = lineStart; ; p++ )
134 {
135 if ( IsStartOfNewLine() )
136 {
137 OnNewLine();
138
139 lastSpace = NULL;
140 line.clear();
141 lineStart = p;
142 }
143
144 if ( *p == _T('\n') || *p == _T('\0') )
145 {
146 DoOutputLine(line);
147
148 if ( *p == _T('\0') )
149 break;
150 }
151 else // not EOL
152 {
153 if ( *p == _T(' ') )
154 lastSpace = p;
155
156 line += *p;
68379eaf 157
5d1b4919
VZ
158 if ( widthMax >= 0 && lastSpace )
159 {
160 int width;
161 win->GetTextExtent(line, &width, NULL);
68379eaf 162
5d1b4919
VZ
163 if ( width > widthMax )
164 {
165 // remove the last word from this line
166 line.erase(lastSpace - lineStart, p + 1 - lineStart);
167 DoOutputLine(line);
168
169 // go back to the last word of this line which we didn't
170 // output yet
171 p = lastSpace;
172 }
173 }
174 //else: no wrapping at all or impossible to wrap
175 }
176 }
177}
178
cfd1ac21
MW
179class wxTextSizerWrapper : public wxTextWrapper
180{
181public:
182 wxTextSizerWrapper(wxWindow *win)
183 {
184 m_win = win;
185 m_hLine = 0;
186 }
187
188 wxSizer *CreateSizer(const wxString& text, int widthMax)
189 {
190 m_sizer = new wxBoxSizer(wxVERTICAL);
191 Wrap(m_win, text, widthMax);
192 return m_sizer;
193 }
194
195protected:
196 virtual void OnOutputLine(const wxString& line)
197 {
198 if ( !line.empty() )
199 {
200 m_sizer->Add(new wxStaticText(m_win, wxID_ANY, line));
201 }
202 else // empty line, no need to create a control for it
203 {
204 if ( !m_hLine )
205 m_hLine = m_win->GetCharHeight();
206
207 m_sizer->Add(5, m_hLine);
208 }
209 }
210
211private:
212 wxWindow *m_win;
213 wxSizer *m_sizer;
214 int m_hLine;
215};
216
5d1b4919
VZ
217wxSizer *wxDialogBase::CreateTextSizer(const wxString& message)
218{
2b5f62a0
VZ
219 // I admit that this is complete bogus, but it makes
220 // message boxes work for pda screens temporarily..
5d1b4919
VZ
221 int widthMax = -1;
222 const bool is_pda = wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA;
2b5f62a0
VZ
223 if (is_pda)
224 {
5d1b4919 225 widthMax = wxSystemSettings::GetMetric( wxSYS_SCREEN_X ) - 25;
2b5f62a0 226 }
68379eaf 227
5d1b4919
VZ
228 // '&' is used as accel mnemonic prefix in the wxWidgets controls but in
229 // the static messages created by CreateTextSizer() (used by wxMessageBox,
230 // for example), we don't want this special meaning, so we need to quote it
231 wxString text(message);
232 text.Replace(_T("&"), _T("&&"));
68379eaf 233
cfd1ac21 234 wxTextSizerWrapper wrapper(this);
b730516c 235
cfd1ac21
MW
236 return wrapper.CreateSizer(text, widthMax);
237}
5d1b4919 238
cfd1ac21
MW
239class wxLabelWrapper : public wxTextWrapper
240{
241public:
242 void WrapLabel(wxWindow *text, int widthMax)
243 {
244 m_text.clear();
245 Wrap(text, text->GetLabel(), widthMax);
246 text->SetLabel(m_text);
247 }
a350a488 248
cfd1ac21
MW
249protected:
250 virtual void OnOutputLine(const wxString& line)
251 {
252 m_text += line;
253 }
a350a488 254
cfd1ac21
MW
255 virtual void OnNewLine()
256 {
257 m_text += _T('\n');
258 }
68379eaf 259
cfd1ac21
MW
260private:
261 wxString m_text;
262};
68379eaf 263
f20e3df6
VZ
264// NB: don't "factor out" the scope operator, SGI MIPSpro 7.3 (but not 7.4)
265// gets confused if it doesn't immediately follow the class name
dec48aa5 266void
a351409e 267#if defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
3f8e6923 268wxStaticText::
dec48aa5 269#else
3f8e6923 270wxStaticTextBase::
dec48aa5 271#endif
3f8e6923 272Wrap(int width)
5d1b4919 273{
cfd1ac21 274 wxLabelWrapper wrapper;
5d1b4919 275 wrapper.WrapLabel(this, width);
e37feda2 276}
b730516c 277
5d1b4919 278#endif // wxUSE_STATTEXT
1e6feb95 279
897b24cf 280wxSizer *wxDialogBase::CreateButtonSizer( long flags, bool separated, wxCoord distance )
e37feda2 281{
102c0454 282#ifdef __SMARTPHONE__
897b24cf
WS
283 wxUnusedVar(separated);
284 wxUnusedVar(distance);
285
102c0454
JS
286 wxDialog* dialog = (wxDialog*) this;
287 if (flags & wxOK){
288 dialog->SetLeftMenu(wxID_OK);
289 }
290
291 if (flags & wxCANCEL){
292 dialog->SetRightMenu(wxID_CANCEL);
293 }
294
295 if (flags & wxYES){
296 dialog->SetLeftMenu(wxID_YES);
297 }
298
299 if (flags & wxNO){
300 dialog->SetLeftMenu(wxID_NO);
301 }
302 wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
303 return sizer;
897b24cf
WS
304
305#else // !__SMARTPHONE__
306
307#ifdef __POCKETPC__
308 // PocketPC guidelines recommend for Ok/Cancel dialogs to use
309 // OK button located inside caption bar and implement Cancel functionality
310 // through Undo outside dialog. As native behaviour this will be default
311 // here but can be easily replaced with real wxButtons
312 // with "wince.dialog.real-ok-cancel" option set to 1
313 if ( ((flags & ~(wxCANCEL|wxNO_DEFAULT))== wxOK) &&
314 (wxSystemOptions::GetOptionInt(wxT("wince.dialog.real-ok-cancel"))==0)
315 )
316 {
317 wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
318 return sizer;
319 }
320#endif // __POCKETPC__
321
322#if wxUSE_BUTTON
323
324 wxSizer* buttonSizer = CreateStdDialogButtonSizer( flags );
325
326 // Mac Human Interface Guidelines recommend not to use static lines as grouping elements
327#if wxUSE_STATLINE && !defined(__WXMAC__)
328 if(!separated)
329 return buttonSizer;
330
331 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
332 topsizer->Add( new wxStaticLine( this, wxID_ANY ), 0, wxEXPAND | wxBOTTOM, distance );
333 topsizer->Add( buttonSizer, 0, wxEXPAND );
334 return topsizer;
335
336#else // !wxUSE_STATLINE
337
338 wxUnusedVar(separated);
339 wxUnusedVar(distance);
340 return buttonSizer;
341
342#endif // wxUSE_STATLINE/!wxUSE_STATLINE
343
344#else // !wxUSE_BUTTON
345
346 wxUnusedVar(separated);
347 wxUnusedVar(distance);
348 wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
349 return sizer;
350
351#endif // wxUSE_BUTTON/!wxUSE_BUTTON
352
353#endif // __SMARTPHONE__/!__SMARTPHONE__
acf2ac37 354}
68379eaf 355
897b24cf
WS
356#if wxUSE_BUTTON
357
acf2ac37
RR
358wxStdDialogButtonSizer *wxDialogBase::CreateStdDialogButtonSizer( long flags )
359{
360 wxStdDialogButtonSizer *sizer = new wxStdDialogButtonSizer();
897b24cf 361
acf2ac37 362 wxButton *ok = NULL;
acf2ac37
RR
363 wxButton *yes = NULL;
364 wxButton *no = NULL;
52069700 365
acf2ac37 366 if (flags & wxOK){
331c1816 367 ok = new wxButton(this, wxID_OK);
52069700 368 sizer->AddButton(ok);
2b5f62a0 369 }
52069700 370
acf2ac37 371 if (flags & wxCANCEL){
331c1816 372 wxButton *cancel = new wxButton(this, wxID_CANCEL);
52069700 373 sizer->AddButton(cancel);
b5b49e42 374 }
52069700 375
acf2ac37 376 if (flags & wxYES){
331c1816 377 yes = new wxButton(this, wxID_YES);
52069700 378 sizer->AddButton(yes);
e37feda2 379 }
52069700 380
acf2ac37 381 if (flags & wxNO){
331c1816 382 no = new wxButton(this, wxID_NO);
52069700 383 sizer->AddButton(no);
e37feda2 384 }
52069700 385
acf2ac37 386 if (flags & wxHELP){
331c1816 387 wxButton *help = new wxButton(this, wxID_HELP);
52069700 388 sizer->AddButton(help);
e37feda2 389 }
52069700 390
b730516c
RD
391 if (flags & wxNO_DEFAULT)
392 {
393 if (no)
394 {
395 no->SetDefault();
396 no->SetFocus();
397 }
398 }
399 else
92afa2b1
RR
400 {
401 if (ok)
402 {
403 ok->SetDefault();
404 ok->SetFocus();
405 }
406 else if (yes)
407 {
408 yes->SetDefault();
409 yes->SetFocus();
410 }
411 }
d30814cd 412
9ceeecb9
JS
413 if (flags & wxOK)
414 SetAffirmativeId(wxID_OK);
415 else if (flags & wxYES)
416 SetAffirmativeId(wxID_YES);
b730516c 417
d30814cd
MB
418 sizer->Realize();
419
acf2ac37 420 return sizer;
e37feda2
VZ
421}
422
1e6feb95 423#endif // wxUSE_BUTTON