]> git.saurik.com Git - wxWidgets.git/blame - samples/widgets/textctrl.cpp
Don't move the insertion point if text didn't change in wxTextEntry.
[wxWidgets.git] / samples / widgets / textctrl.cpp
CommitLineData
32b8ec41 1/////////////////////////////////////////////////////////////////////////////
be5a51fb 2// Program: wxWidgets Widgets Sample
32b8ec41
VZ
3// Name: textctrl.cpp
4// Purpose: part of the widgets sample showing wxTextCtrl
5// Author: Vadim Zeitlin
6// Created: 27.03.01
7// Id: $Id$
8// Copyright: (c) 2001 Vadim Zeitlin
526954c5 9// Licence: wxWindows licence
32b8ec41
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// for compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27// for all others, include the necessary headers
28#ifndef WX_PRECOMP
29 #include "wx/log.h"
30 #include "wx/timer.h"
31
3bb70c40 32 #include "wx/bitmap.h"
32b8ec41
VZ
33 #include "wx/button.h"
34 #include "wx/checkbox.h"
35 #include "wx/radiobox.h"
36 #include "wx/statbox.h"
37 #include "wx/stattext.h"
38 #include "wx/textctrl.h"
286ff306 39 #include "wx/msgdlg.h"
32b8ec41
VZ
40#endif
41
42#include "wx/sizer.h"
15cdc341 43#include "wx/ioswrap.h"
32b8ec41
VZ
44
45#include "widgets.h"
46
47#include "icons/text.xpm"
48
49// ----------------------------------------------------------------------------
50// constants
51// ----------------------------------------------------------------------------
52
53// control ids
54enum
55{
f0fa4312 56 TextPage_Reset = wxID_HIGHEST,
32b8ec41
VZ
57
58 TextPage_Set,
59 TextPage_Add,
60 TextPage_Insert,
61 TextPage_Clear,
62 TextPage_Load,
63
286ff306
WS
64 TextPage_StreamRedirector,
65
32b8ec41
VZ
66 TextPage_Password,
67 TextPage_WrapLines,
68 TextPage_Textctrl
69};
70
71// textctrl line number radiobox values
72enum TextLines
73{
74 TextLines_Single,
fb4888a6
VZ
75 TextLines_Multi,
76 TextLines_Max
77};
78
79// wrap style radio box
80enum WrapStyle
81{
82 WrapStyle_None,
83 WrapStyle_Word,
84 WrapStyle_Char,
85 WrapStyle_Best,
86 WrapStyle_Max
32b8ec41
VZ
87};
88
64b54de8
VZ
89#ifdef __WXMSW__
90
91// textctrl kind values
92enum TextKind
93{
94 TextKind_Plain,
95 TextKind_Rich,
fb4888a6
VZ
96 TextKind_Rich2,
97 TextKind_Max
64b54de8
VZ
98};
99
100#endif // __WXMSW__
101
32b8ec41
VZ
102// default values for the controls
103static const struct ControlValues
104{
105 TextLines textLines;
fb4888a6 106
32b8ec41 107 bool password;
32b8ec41 108 bool readonly;
2d1e63c0 109 bool processEnter;
5f6475c1 110 bool filename;
fb4888a6
VZ
111
112 WrapStyle wrapStyle;
113
64b54de8
VZ
114#ifdef __WXMSW__
115 TextKind textKind;
116#endif // __WXMSW__
32b8ec41
VZ
117} DEFAULTS =
118{
119 TextLines_Multi, // multiline
206d3a16 120 false, // not password
206d3a16 121 false, // not readonly
2d1e63c0 122 true, // do process enter
5f6475c1 123 false, // not filename
fb4888a6 124 WrapStyle_Word, // wrap on word boundaries
64b54de8
VZ
125#ifdef __WXMSW__
126 TextKind_Plain // plain EDIT control
127#endif // __WXMSW__
32b8ec41
VZ
128};
129
130// ----------------------------------------------------------------------------
131// TextWidgetsPage
132// ----------------------------------------------------------------------------
133
134// Define a new frame type: this is going to be our main frame
135class TextWidgetsPage : public WidgetsPage
136{
137public:
138 // ctor(s) and dtor
f2fdc4d5 139 TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
8f6eaec9 140 virtual ~TextWidgetsPage(){};
32b8ec41 141
195df7a7 142 virtual wxControl *GetWidget() const { return m_text; }
6a8d7937 143 virtual wxTextEntryBase *GetTextEntry() const { return m_text; }
1301e228 144 virtual void RecreateWidget() { CreateText(); }
195df7a7 145
453535a7
WS
146 // lazy creation of the content
147 virtual void CreateContent();
148
32b8ec41
VZ
149protected:
150 // create an info text contorl
151 wxTextCtrl *CreateInfoText();
152
153 // create a horz sizer holding a static text and this text control
154 wxSizer *CreateTextWithLabelSizer(const wxString& label,
155 wxTextCtrl *text,
156 const wxString& label2 = wxEmptyString,
157 wxTextCtrl *text2 = NULL);
158
159 // event handlers
160 void OnButtonReset(wxCommandEvent& event);
161 void OnButtonClearLog(wxCommandEvent& event);
162
163 void OnButtonSet(wxCommandEvent& event);
164 void OnButtonAdd(wxCommandEvent& event);
165 void OnButtonInsert(wxCommandEvent& event);
166 void OnButtonClear(wxCommandEvent& event);
167 void OnButtonLoad(wxCommandEvent& event);
168
286ff306 169 void OnStreamRedirector(wxCommandEvent& event);
32b8ec41
VZ
170 void OnButtonQuit(wxCommandEvent& event);
171
172 void OnText(wxCommandEvent& event);
173 void OnTextEnter(wxCommandEvent& event);
10434560 174 void OnTextPasted(wxClipboardTextEvent& event);
32b8ec41
VZ
175
176 void OnCheckOrRadioBox(wxCommandEvent& event);
177
178 void OnUpdateUIClearButton(wxUpdateUIEvent& event);
179
180 void OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event);
181 void OnUpdateUIWrapLinesCheckbox(wxUpdateUIEvent& event);
182
183 void OnUpdateUIResetButton(wxUpdateUIEvent& event);
184
185 void OnIdle(wxIdleEvent& event);
186
187 // reset the textctrl parameters
188 void Reset();
189
190 // (re)create the textctrl
191 void CreateText();
192
193 // is the control currently single line?
194 bool IsSingleLine() const
195 {
196 return m_radioTextLines->GetSelection() == TextLines_Single;
197 }
198
199 // the controls
200 // ------------
201
202 // the radiobox to choose between single and multi line
203 wxRadioBox *m_radioTextLines;
204
fb4888a6
VZ
205 // and another one to choose the wrapping style
206 wxRadioBox *m_radioWrap;
207
32b8ec41
VZ
208 // the checkboxes controlling text ctrl styles
209 wxCheckBox *m_chkPassword,
5f6475c1 210 *m_chkReadonly,
2d1e63c0 211 *m_chkProcessEnter,
5f6475c1 212 *m_chkFilename;
32b8ec41 213
64b54de8
VZ
214 // under MSW we test rich edit controls as well here
215#ifdef __WXMSW__
216 wxRadioBox *m_radioKind;
217#endif // __WXMSW__
218
32b8ec41
VZ
219 // the textctrl itself and the sizer it is in
220 wxTextCtrl *m_text;
221 wxSizer *m_sizerText;
222
223 // the information text zones
224 wxTextCtrl *m_textPosCur,
225 *m_textRowCur,
226 *m_textColCur,
227 *m_textPosLast,
228 *m_textLineLast,
229 *m_textSelFrom,
64b54de8
VZ
230 *m_textSelTo,
231 *m_textRange;
32b8ec41
VZ
232
233 // and the data to show in them
234 long m_posCur,
235 m_posLast,
236 m_selFrom,
237 m_selTo;
238
626117f7
VZ
239 wxString m_range10_20;
240
32b8ec41 241private:
be5a51fb 242 // any class wishing to process wxWidgets events must use this macro
5e173f35
GD
243 DECLARE_EVENT_TABLE()
244 DECLARE_WIDGETS_PAGE(TextWidgetsPage)
32b8ec41
VZ
245};
246
efe66bbc
VZ
247// ----------------------------------------------------------------------------
248// WidgetsTextCtrl
249// ----------------------------------------------------------------------------
250
251class WidgetsTextCtrl : public wxTextCtrl
252{
253public:
254 WidgetsTextCtrl(wxWindow *parent,
255 wxWindowID id,
256 const wxString& value,
257 int flags)
258 : wxTextCtrl(parent, id, value, wxDefaultPosition, wxDefaultSize, flags)
259 {
260 }
261
262protected:
263 void OnRightClick(wxMouseEvent& event)
264 {
265 wxString where;
266 wxTextCoord x, y;
267 switch ( HitTest(event.GetPosition(), &x, &y) )
268 {
269 default:
9a83f860 270 wxFAIL_MSG( wxT("unexpected HitTest() result") );
efe66bbc
VZ
271 // fall through
272
273 case wxTE_HT_UNKNOWN:
274 x = y = -1;
9a83f860 275 where = wxT("nowhere near");
efe66bbc
VZ
276 break;
277
278 case wxTE_HT_BEFORE:
9a83f860 279 where = wxT("before");
efe66bbc
VZ
280 break;
281
282 case wxTE_HT_BELOW:
9a83f860 283 where = wxT("below");
efe66bbc
VZ
284 break;
285
286 case wxTE_HT_BEYOND:
9a83f860 287 where = wxT("beyond");
efe66bbc
VZ
288 break;
289
290 case wxTE_HT_ON_TEXT:
9a83f860 291 where = wxT("at");
efe66bbc
VZ
292 break;
293 }
294
9a83f860 295 wxLogMessage(wxT("Mouse is %s (%ld, %ld)"), where.c_str(), x, y);
efe66bbc
VZ
296
297 event.Skip();
298 }
299
300private:
301 DECLARE_EVENT_TABLE()
302};
303
32b8ec41
VZ
304// ----------------------------------------------------------------------------
305// event tables
306// ----------------------------------------------------------------------------
307
308BEGIN_EVENT_TABLE(TextWidgetsPage, WidgetsPage)
309 EVT_IDLE(TextWidgetsPage::OnIdle)
310
311 EVT_BUTTON(TextPage_Reset, TextWidgetsPage::OnButtonReset)
312
286ff306
WS
313 EVT_BUTTON(TextPage_StreamRedirector, TextWidgetsPage::OnStreamRedirector)
314
32b8ec41
VZ
315 EVT_BUTTON(TextPage_Clear, TextWidgetsPage::OnButtonClear)
316 EVT_BUTTON(TextPage_Set, TextWidgetsPage::OnButtonSet)
317 EVT_BUTTON(TextPage_Add, TextWidgetsPage::OnButtonAdd)
318 EVT_BUTTON(TextPage_Insert, TextWidgetsPage::OnButtonInsert)
319 EVT_BUTTON(TextPage_Load, TextWidgetsPage::OnButtonLoad)
320
321 EVT_UPDATE_UI(TextPage_Clear, TextWidgetsPage::OnUpdateUIClearButton)
322
323 EVT_UPDATE_UI(TextPage_Password, TextWidgetsPage::OnUpdateUIPasswordCheckbox)
324 EVT_UPDATE_UI(TextPage_WrapLines, TextWidgetsPage::OnUpdateUIWrapLinesCheckbox)
325
326 EVT_UPDATE_UI(TextPage_Reset, TextWidgetsPage::OnUpdateUIResetButton)
327
328 EVT_TEXT(TextPage_Textctrl, TextWidgetsPage::OnText)
329 EVT_TEXT_ENTER(TextPage_Textctrl, TextWidgetsPage::OnTextEnter)
10434560 330 EVT_TEXT_PASTE(TextPage_Textctrl, TextWidgetsPage::OnTextPasted)
32b8ec41 331
206d3a16
JS
332 EVT_CHECKBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
333 EVT_RADIOBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
32b8ec41
VZ
334END_EVENT_TABLE()
335
efe66bbc
VZ
336BEGIN_EVENT_TABLE(WidgetsTextCtrl, wxTextCtrl)
337 EVT_RIGHT_UP(WidgetsTextCtrl::OnRightClick)
338END_EVENT_TABLE()
339
32b8ec41
VZ
340// ============================================================================
341// implementation
342// ============================================================================
343
f0fa4312
WS
344#if defined(__WXX11__)
345 #define FAMILY_CTRLS NATIVE_CTRLS
346#elif defined(__WXUNIVERSAL__)
347 #define FAMILY_CTRLS UNIVERSAL_CTRLS
348#else
349 #define FAMILY_CTRLS NATIVE_CTRLS
350#endif
351
9a83f860 352IMPLEMENT_WIDGETS_PAGE(TextWidgetsPage, wxT("Text"),
f0fa4312 353 FAMILY_CTRLS | EDITABLE_CTRLS
f2fdc4d5 354 );
32b8ec41
VZ
355
356// ----------------------------------------------------------------------------
357// TextWidgetsPage creation
358// ----------------------------------------------------------------------------
359
f2fdc4d5 360TextWidgetsPage::TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist)
261357eb 361 : WidgetsPage(book, imaglist, text_xpm)
32b8ec41 362{
32b8ec41 363 // init everything
64b54de8
VZ
364#ifdef __WXMSW__
365 m_radioKind =
366#endif // __WXMSW__
fb4888a6 367 m_radioWrap =
32b8ec41
VZ
368 m_radioTextLines = (wxRadioBox *)NULL;
369
370 m_chkPassword =
5f6475c1 371 m_chkReadonly =
2d1e63c0 372 m_chkProcessEnter =
5f6475c1 373 m_chkFilename = (wxCheckBox *)NULL;
32b8ec41
VZ
374
375 m_text =
376 m_textPosCur =
377 m_textRowCur =
378 m_textColCur =
379 m_textPosLast =
380 m_textLineLast =
381 m_textSelFrom =
64b54de8
VZ
382 m_textSelTo =
383 m_textRange = (wxTextCtrl *)NULL;
384
32b8ec41
VZ
385 m_sizerText = (wxSizer *)NULL;
386
387 m_posCur =
388 m_posLast =
389 m_selFrom =
390 m_selTo = -2; // not -1 which means "no selection"
453535a7 391}
32b8ec41 392
453535a7
WS
393void TextWidgetsPage::CreateContent()
394{
32b8ec41
VZ
395 // left pane
396 static const wxString modes[] =
397 {
9a83f860
VZ
398 wxT("single line"),
399 wxT("multi line"),
32b8ec41
VZ
400 };
401
9a83f860
VZ
402 wxStaticBox *box = new wxStaticBox(this, wxID_ANY, wxT("&Set textctrl parameters"));
403 m_radioTextLines = new wxRadioBox(this, wxID_ANY, wxT("&Number of lines:"),
32b8ec41
VZ
404 wxDefaultPosition, wxDefaultSize,
405 WXSIZEOF(modes), modes,
406 1, wxRA_SPECIFY_COLS);
407
408 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
409
410 sizerLeft->Add(m_radioTextLines, 0, wxGROW | wxALL, 5);
fb4888a6 411 sizerLeft->AddSpacer(5);
32b8ec41
VZ
412
413 m_chkPassword = CreateCheckBoxAndAddToSizer(
9a83f860 414 sizerLeft, wxT("&Password control"), TextPage_Password
32b8ec41 415 );
32b8ec41 416 m_chkReadonly = CreateCheckBoxAndAddToSizer(
9a83f860 417 sizerLeft, wxT("&Read-only mode")
32b8ec41 418 );
2d1e63c0
VZ
419 m_chkProcessEnter = CreateCheckBoxAndAddToSizer(
420 sizerLeft, wxT("Process &Enter")
421 );
5f6475c1 422 m_chkFilename = CreateCheckBoxAndAddToSizer(
9a83f860 423 sizerLeft, wxT("&Filename control")
5f6475c1 424 );
55b43eaa 425 m_chkFilename->Disable(); // not implemented yet
fb4888a6
VZ
426 sizerLeft->AddSpacer(5);
427
428 static const wxString wrap[] =
429 {
9a83f860
VZ
430 wxT("no wrap"),
431 wxT("word wrap"),
432 wxT("char wrap"),
433 wxT("best wrap"),
fb4888a6
VZ
434 };
435
9a83f860 436 m_radioWrap = new wxRadioBox(this, wxID_ANY, wxT("&Wrap style:"),
fb4888a6
VZ
437 wxDefaultPosition, wxDefaultSize,
438 WXSIZEOF(wrap), wrap,
439 1, wxRA_SPECIFY_COLS);
440 sizerLeft->Add(m_radioWrap, 0, wxGROW | wxALL, 5);
32b8ec41 441
64b54de8
VZ
442#ifdef __WXMSW__
443 static const wxString kinds[] =
444 {
9a83f860
VZ
445 wxT("plain edit"),
446 wxT("rich edit"),
447 wxT("rich edit 2.0"),
64b54de8
VZ
448 };
449
9a83f860 450 m_radioKind = new wxRadioBox(this, wxID_ANY, wxT("Control &kind"),
64b54de8
VZ
451 wxDefaultPosition, wxDefaultSize,
452 WXSIZEOF(kinds), kinds,
453 1, wxRA_SPECIFY_COLS);
454
fb4888a6 455 sizerLeft->AddSpacer(5);
64b54de8
VZ
456 sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
457#endif // __WXMSW__
458
9a83f860 459 wxButton *btn = new wxButton(this, TextPage_Reset, wxT("&Reset"));
7b127900 460 sizerLeft->Add(2, 2, 0, wxGROW | wxALL, 1); // spacer
32b8ec41
VZ
461 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
462
463 // middle pane
9a83f860 464 wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, wxT("&Change contents:"));
32b8ec41
VZ
465 wxSizer *sizerMiddleUp = new wxStaticBoxSizer(box2, wxVERTICAL);
466
9a83f860 467 btn = new wxButton(this, TextPage_Set, wxT("&Set text value"));
7b127900 468 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
32b8ec41 469
9a83f860 470 btn = new wxButton(this, TextPage_Add, wxT("&Append text"));
7b127900 471 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
32b8ec41 472
9a83f860 473 btn = new wxButton(this, TextPage_Insert, wxT("&Insert text"));
7b127900 474 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
32b8ec41 475
9a83f860 476 btn = new wxButton(this, TextPage_Load, wxT("&Load file"));
7b127900 477 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
32b8ec41 478
9a83f860 479 btn = new wxButton(this, TextPage_Clear, wxT("&Clear"));
7b127900 480 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
32b8ec41 481
9a83f860 482 btn = new wxButton(this, TextPage_StreamRedirector, wxT("St&ream redirection"));
286ff306
WS
483 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
484
9a83f860 485 wxStaticBox *box4 = new wxStaticBox(this, wxID_ANY, wxT("&Info:"));
32b8ec41
VZ
486 wxSizer *sizerMiddleDown = new wxStaticBoxSizer(box4, wxVERTICAL);
487
488 m_textPosCur = CreateInfoText();
489 m_textRowCur = CreateInfoText();
490 m_textColCur = CreateInfoText();
491
492 wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
493 sizerRow->Add(CreateTextWithLabelSizer
494 (
9a83f860 495 wxT("Current pos:"),
32b8ec41
VZ
496 m_textPosCur
497 ),
498 0, wxRIGHT, 5);
499 sizerRow->Add(CreateTextWithLabelSizer
500 (
9a83f860 501 wxT("Col:"),
32b8ec41
VZ
502 m_textColCur
503 ),
504 0, wxLEFT | wxRIGHT, 5);
505 sizerRow->Add(CreateTextWithLabelSizer
506 (
9a83f860 507 wxT("Row:"),
32b8ec41
VZ
508 m_textRowCur
509 ),
510 0, wxLEFT, 5);
511 sizerMiddleDown->Add(sizerRow, 0, wxALL, 5);
512
513 m_textLineLast = CreateInfoText();
514 m_textPosLast = CreateInfoText();
515 sizerMiddleDown->Add
516 (
517 CreateTextWithLabelSizer
518 (
9a83f860 519 wxT("Number of lines:"),
32b8ec41 520 m_textLineLast,
9a83f860 521 wxT("Last position:"),
32b8ec41
VZ
522 m_textPosLast
523 ),
524 0, wxALL, 5
525 );
526
527 m_textSelFrom = CreateInfoText();
528 m_textSelTo = CreateInfoText();
529 sizerMiddleDown->Add
530 (
531 CreateTextWithLabelSizer
532 (
9a83f860 533 wxT("Selection: from"),
32b8ec41 534 m_textSelFrom,
9a83f860 535 wxT("to"),
32b8ec41
VZ
536 m_textSelTo
537 ),
538 0, wxALL, 5
539 );
64b54de8 540
206d3a16 541 m_textRange = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
64b54de8
VZ
542 wxDefaultPosition, wxDefaultSize,
543 wxTE_READONLY);
544 sizerMiddleDown->Add
545 (
546 CreateTextWithLabelSizer
547 (
9a83f860 548 wxT("Range 10..20:"),
64b54de8
VZ
549 m_textRange
550 ),
551 0, wxALL, 5
552 );
553
32b8ec41
VZ
554 wxSizer *sizerMiddle = new wxBoxSizer(wxVERTICAL);
555 sizerMiddle->Add(sizerMiddleUp, 0, wxGROW);
556 sizerMiddle->Add(sizerMiddleDown, 1, wxGROW | wxTOP, 5);
557
558 // right pane
9a83f860 559 wxStaticBox *box3 = new wxStaticBox(this, wxID_ANY, wxT("&Text:"));
32b8ec41
VZ
560 m_sizerText = new wxStaticBoxSizer(box3, wxHORIZONTAL);
561 Reset();
562 CreateText();
7b127900 563 m_sizerText->SetMinSize(150, 0);
32b8ec41
VZ
564
565 // the 3 panes panes compose the upper part of the window
566 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
567 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
568 sizerTop->Add(sizerMiddle, 0, wxGROW | wxALL, 10);
569 sizerTop->Add(m_sizerText, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
570
32b8ec41 571 SetSizer(sizerTop);
32b8ec41
VZ
572}
573
32b8ec41
VZ
574// ----------------------------------------------------------------------------
575// creation helpers
576// ----------------------------------------------------------------------------
577
578wxTextCtrl *TextWidgetsPage::CreateInfoText()
579{
580 static int s_maxWidth = 0;
581 if ( !s_maxWidth )
582 {
583 // calc it once only
9a83f860 584 GetTextExtent(wxT("9999999"), &s_maxWidth, NULL);
32b8ec41
VZ
585 }
586
206d3a16 587 wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
32b8ec41 588 wxDefaultPosition,
15cdc341 589 wxSize(s_maxWidth, wxDefaultCoord),
32b8ec41
VZ
590 wxTE_READONLY);
591 return text;
592}
593
594wxSizer *TextWidgetsPage::CreateTextWithLabelSizer(const wxString& label,
595 wxTextCtrl *text,
596 const wxString& label2,
597 wxTextCtrl *text2)
598{
599 wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
206d3a16 600 sizerRow->Add(new wxStaticText(this, wxID_ANY, label), 0,
32b8ec41
VZ
601 wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
602 sizerRow->Add(text, 0, wxALIGN_CENTRE_VERTICAL);
603 if ( text2 )
604 {
206d3a16 605 sizerRow->Add(new wxStaticText(this, wxID_ANY, label2), 0,
32b8ec41
VZ
606 wxALIGN_CENTRE_VERTICAL | wxLEFT | wxRIGHT, 5);
607 sizerRow->Add(text2, 0, wxALIGN_CENTRE_VERTICAL);
608 }
609
610 return sizerRow;
611}
612
613// ----------------------------------------------------------------------------
614// operations
615// ----------------------------------------------------------------------------
616
617void TextWidgetsPage::Reset()
618{
619 m_radioTextLines->SetSelection(DEFAULTS.textLines);
fb4888a6 620
32b8ec41 621 m_chkPassword->SetValue(DEFAULTS.password);
32b8ec41 622 m_chkReadonly->SetValue(DEFAULTS.readonly);
2d1e63c0 623 m_chkProcessEnter->SetValue(DEFAULTS.processEnter);
5f6475c1 624 m_chkFilename->SetValue(DEFAULTS.filename);
fb4888a6
VZ
625
626 m_radioWrap->SetSelection(DEFAULTS.wrapStyle);
627
64b54de8
VZ
628#ifdef __WXMSW__
629 m_radioKind->SetSelection(DEFAULTS.textKind);
630#endif // __WXMSW__
32b8ec41
VZ
631}
632
633void TextWidgetsPage::CreateText()
634{
1301e228 635 int flags = ms_defaultFlags;
32b8ec41
VZ
636 switch ( m_radioTextLines->GetSelection() )
637 {
638 default:
9a83f860 639 wxFAIL_MSG( wxT("unexpected lines radio box selection") );
32b8ec41
VZ
640
641 case TextLines_Single:
642 break;
643
644 case TextLines_Multi:
645 flags |= wxTE_MULTILINE;
206d3a16 646 m_chkPassword->SetValue(false);
32b8ec41
VZ
647 break;
648 }
649
650 if ( m_chkPassword->GetValue() )
651 flags |= wxTE_PASSWORD;
652 if ( m_chkReadonly->GetValue() )
653 flags |= wxTE_READONLY;
2d1e63c0
VZ
654 if ( m_chkProcessEnter->GetValue() )
655 flags |= wxTE_PROCESS_ENTER;
fb4888a6
VZ
656
657 switch ( m_radioWrap->GetSelection() )
658 {
659 default:
9a83f860 660 wxFAIL_MSG( wxT("unexpected wrap style radio box selection") );
fb4888a6
VZ
661
662 case WrapStyle_None:
663 flags |= wxTE_DONTWRAP; // same as wxHSCROLL
664 break;
665
666 case WrapStyle_Word:
667 flags |= wxTE_WORDWRAP;
668 break;
669
670 case WrapStyle_Char:
40ff126a 671 flags |= wxTE_CHARWRAP;
fb4888a6
VZ
672 break;
673
674 case WrapStyle_Best:
675 // this is default but use symbolic file name for consistency
676 flags |= wxTE_BESTWRAP;
677 break;
678 }
32b8ec41 679
64b54de8
VZ
680#ifdef __WXMSW__
681 switch ( m_radioKind->GetSelection() )
682 {
683 default:
9a83f860 684 wxFAIL_MSG( wxT("unexpected kind radio box selection") );
64b54de8
VZ
685
686 case TextKind_Plain:
687 break;
688
689 case TextKind_Rich:
690 flags |= wxTE_RICH;
691 break;
692
693 case TextKind_Rich2:
694 flags |= wxTE_RICH2;
695 break;
696 }
697#endif // __WXMSW__
698
32b8ec41
VZ
699 wxString valueOld;
700 if ( m_text )
701 {
702 valueOld = m_text->GetValue();
703
12a3f227 704 m_sizerText->Detach( m_text );
32b8ec41
VZ
705 delete m_text;
706 }
707 else
708 {
9a83f860 709 valueOld = wxT("Hello, Universe!");
32b8ec41
VZ
710 }
711
efe66bbc 712 m_text = new WidgetsTextCtrl(this, TextPage_Textctrl, valueOld, flags);
72383a72 713
55b43eaa
VZ
714#if 0
715 if ( m_chkFilename->GetValue() )
716 ;
717#endif // TODO
718
72383a72 719 // cast to int needed to silence gcc warning about different enums
32b8ec41 720 m_sizerText->Add(m_text, 1, wxALL |
72383a72 721 (flags & wxTE_MULTILINE ? (int)wxGROW
32b8ec41
VZ
722 : wxALIGN_TOP), 5);
723 m_sizerText->Layout();
724}
725
726// ----------------------------------------------------------------------------
727// event handlers
728// ----------------------------------------------------------------------------
729
730void TextWidgetsPage::OnIdle(wxIdleEvent& WXUNUSED(event))
731{
732 // update all info texts
733
734 if ( m_textPosCur )
735 {
736 long posCur = m_text->GetInsertionPoint();
737 if ( posCur != m_posCur )
738 {
739 m_textPosCur->Clear();
740 m_textRowCur->Clear();
741 m_textColCur->Clear();
742
743 long col, row;
744 m_text->PositionToXY(posCur, &col, &row);
745
746 *m_textPosCur << posCur;
747 *m_textRowCur << row;
748 *m_textColCur << col;
749
750 m_posCur = posCur;
751 }
752 }
753
754 if ( m_textPosLast )
755 {
756 long posLast = m_text->GetLastPosition();
757 if ( posLast != m_posLast )
758 {
759 m_textPosLast->Clear();
760 *m_textPosLast << posLast;
761
762 m_posLast = posLast;
763 }
764 }
765
766 if ( m_textLineLast )
767 {
768 m_textLineLast->SetValue(
9a83f860 769 wxString::Format(wxT("%d"), m_text->GetNumberOfLines()) );
32b8ec41
VZ
770 }
771
772 if ( m_textSelFrom && m_textSelTo )
773 {
774 long selFrom, selTo;
775 m_text->GetSelection(&selFrom, &selTo);
776 if ( selFrom != m_selFrom )
777 {
778 m_textSelFrom->Clear();
779 *m_textSelFrom << selFrom;
780
781 m_selFrom = selFrom;
782 }
783
784 if ( selTo != m_selTo )
785 {
786 m_textSelTo->Clear();
787 *m_textSelTo << selTo;
788
789 m_selTo = selTo;
790 }
791 }
64b54de8
VZ
792
793 if ( m_textRange )
794 {
626117f7
VZ
795 wxString range = m_text->GetRange(10, 20);
796 if ( range != m_range10_20 )
797 {
798 m_range10_20 = range;
799 m_textRange->SetValue(range);
800 }
64b54de8 801 }
32b8ec41
VZ
802}
803
804void TextWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
805{
806 Reset();
807
808 CreateText();
809}
810
811void TextWidgetsPage::OnButtonSet(wxCommandEvent& WXUNUSED(event))
812{
64b54de8 813 m_text->SetValue(m_text->GetWindowStyle() & wxTE_MULTILINE
9a83f860
VZ
814 ? wxT("Here,\nthere and\neverywhere")
815 : wxT("Yellow submarine"));
64b54de8 816
32b8ec41
VZ
817 m_text->SetFocus();
818}
819
820void TextWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
821{
64b54de8
VZ
822 if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
823 {
9a83f860 824 m_text->AppendText(wxT("We all live in a\n"));
64b54de8
VZ
825 }
826
9a83f860 827 m_text->AppendText(wxT("Yellow submarine"));
32b8ec41
VZ
828}
829
830void TextWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
831{
9a83f860 832 m_text->WriteText(wxT("Is there anybody going to listen to my story"));
64b54de8
VZ
833 if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
834 {
9a83f860 835 m_text->WriteText(wxT("\nall about the girl who came to stay"));
64b54de8 836 }
32b8ec41
VZ
837}
838
839void TextWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
840{
841 m_text->Clear();
842 m_text->SetFocus();
843}
844
845void TextWidgetsPage::OnButtonLoad(wxCommandEvent& WXUNUSED(event))
846{
847 // search for the file in several dirs where it's likely to be
848 wxPathList pathlist;
9a83f860
VZ
849 pathlist.Add(wxT("."));
850 pathlist.Add(wxT(".."));
851 pathlist.Add(wxT("../../../samples/widgets"));
32b8ec41 852
9a83f860 853 wxString filename = pathlist.FindValidPath(wxT("textctrl.cpp"));
32b8ec41
VZ
854 if ( !filename )
855 {
9a83f860 856 wxLogError(wxT("File textctrl.cpp not found."));
32b8ec41
VZ
857 }
858 else // load it
859 {
860 wxStopWatch sw;
861 if ( !m_text->LoadFile(filename) )
862 {
863 // this is not supposed to happen ...
9a83f860 864 wxLogError(wxT("Error loading file."));
32b8ec41
VZ
865 }
866 else
867 {
868 long elapsed = sw.Time();
9a83f860 869 wxLogMessage(wxT("Loaded file '%s' in %lu.%us"),
8b1d8f36
VZ
870 filename.c_str(), elapsed / 1000,
871 (unsigned int) elapsed % 1000);
32b8ec41
VZ
872 }
873 }
874}
875
876void TextWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
877{
878 event.Enable(!m_text->GetValue().empty());
879}
880
881void TextWidgetsPage::OnUpdateUIWrapLinesCheckbox(wxUpdateUIEvent& event)
882{
883 event.Enable( !IsSingleLine() );
884}
885
886void TextWidgetsPage::OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event)
887{
888 // can't put multiline control in password mode
889 event.Enable( IsSingleLine() );
890}
891
892void TextWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
893{
894 event.Enable( (m_radioTextLines->GetSelection() != DEFAULTS.textLines) ||
64b54de8
VZ
895#ifdef __WXMSW__
896 (m_radioKind->GetSelection() != DEFAULTS.textKind) ||
897#endif // __WXMSW__
32b8ec41 898 (m_chkPassword->GetValue() != DEFAULTS.password) ||
5f6475c1 899 (m_chkReadonly->GetValue() != DEFAULTS.readonly) ||
2d1e63c0 900 (m_chkProcessEnter->GetValue() != DEFAULTS.processEnter) ||
5f6475c1 901 (m_chkFilename->GetValue() != DEFAULTS.filename) ||
fb4888a6 902 (m_radioWrap->GetSelection() != DEFAULTS.wrapStyle) );
32b8ec41
VZ
903}
904
c02e5a31 905void TextWidgetsPage::OnText(wxCommandEvent& WXUNUSED(event))
32b8ec41
VZ
906{
907 // small hack to suppress the very first message: by then the logging is
908 // not yet redirected and so initial setting of the text value results in
909 // an annoying message box
206d3a16 910 static bool s_firstTime = true;
32b8ec41
VZ
911 if ( s_firstTime )
912 {
206d3a16 913 s_firstTime = false;
32b8ec41
VZ
914 return;
915 }
916
9a83f860 917 wxLogMessage(wxT("Text ctrl value changed"));
32b8ec41
VZ
918}
919
920void TextWidgetsPage::OnTextEnter(wxCommandEvent& event)
921{
9a83f860 922 wxLogMessage(wxT("Text entered: '%s'"), event.GetString().c_str());
cd2e10d6 923 event.Skip();
32b8ec41
VZ
924}
925
10434560
VZ
926void TextWidgetsPage::OnTextPasted(wxClipboardTextEvent& event)
927{
928 wxLogMessage("Text pasted from clipboard.");
929 event.Skip();
930}
931
c02e5a31 932void TextWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
32b8ec41
VZ
933{
934 CreateText();
935}
72383a72 936
286ff306
WS
937void TextWidgetsPage::OnStreamRedirector(wxCommandEvent& WXUNUSED(event))
938{
15cdc341 939#if wxHAS_TEXT_WINDOW_STREAM
286ff306 940 wxStreamToTextRedirector redirect(m_text);
9a83f860 941 wxString str( wxT("Outputed to cout, appears in wxTextCtrl!") );
05772b84 942 wxSTD cout << str << wxSTD endl;
15cdc341 943#else
9a83f860 944 wxMessageBox(wxT("This wxWidgets build does not support wxStreamToTextRedirector"));
286ff306
WS
945#endif
946}