wxWidgets/samples/widgets/textctrl.cpp
Vadim Zeitlin e34823a0c4 Stop using wx/ioswrap.h in the samples
This is not necessary any longer after wxUSE_IOSTREAMH removal and it
makes the sample code more clear.
2019-10-22 02:42:33 +02:00

1071 lines
30 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Program: wxWidgets Widgets Sample
// Name: textctrl.cpp
// Purpose: part of the widgets sample showing wxTextCtrl
// Author: Vadim Zeitlin
// Created: 27.03.01
// Copyright: (c) 2001 Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// for compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/log.h"
#include "wx/timer.h"
#include "wx/bitmap.h"
#include "wx/button.h"
#include "wx/checkbox.h"
#include "wx/dcclient.h"
#include "wx/radiobox.h"
#include "wx/statbox.h"
#include "wx/stattext.h"
#include "wx/textctrl.h"
#include "wx/msgdlg.h"
#endif
#include "wx/sizer.h"
#include "widgets.h"
#include "icons/text.xpm"
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// control ids
enum
{
TextPage_Reset = wxID_HIGHEST,
TextPage_Set,
TextPage_Add,
TextPage_Insert,
TextPage_Clear,
TextPage_Load,
TextPage_StreamRedirector,
TextPage_Password,
TextPage_NoVertScrollbar,
TextPage_WrapLines,
TextPage_Textctrl
};
// textctrl line number radiobox values
enum TextLines
{
TextLines_Single,
TextLines_Multi,
TextLines_Max
};
// wrap style radio box
enum WrapStyle
{
WrapStyle_None,
WrapStyle_Word,
WrapStyle_Char,
WrapStyle_Best,
WrapStyle_Max
};
// Alignment style radio box
enum AlignmentStyle
{
Align_Left,
Align_Center,
Align_Right,
};
#ifdef __WXMSW__
// textctrl kind values
enum TextKind
{
TextKind_Plain,
TextKind_Rich,
TextKind_Rich2,
TextKind_Max
};
#endif // __WXMSW__
// default values for the controls
static const struct ControlValues
{
TextLines textLines;
bool password;
bool readonly;
bool processEnter;
bool processTab;
bool filename;
bool noVertScrollbar;
WrapStyle wrapStyle;
AlignmentStyle alignmentStyle;
#ifdef __WXMSW__
TextKind textKind;
#endif // __WXMSW__
} DEFAULTS =
{
TextLines_Multi, // multiline
false, // not password
false, // not readonly
true, // do process enter
false, // do not process Tab
false, // not filename
false, // don't hide vertical scrollbar
WrapStyle_Word, // wrap on word boundaries
Align_Left, // leading-alignment
#ifdef __WXMSW__
TextKind_Plain // plain EDIT control
#endif // __WXMSW__
};
// ----------------------------------------------------------------------------
// TextWidgetsPage
// ----------------------------------------------------------------------------
// Define a new frame type: this is going to be our main frame
class TextWidgetsPage : public WidgetsPage
{
public:
// ctor(s) and dtor
TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
virtual wxWindow *GetWidget() const wxOVERRIDE { return m_text; }
virtual wxTextEntryBase *GetTextEntry() const wxOVERRIDE { return m_text; }
virtual void RecreateWidget() wxOVERRIDE { CreateText(); }
// lazy creation of the content
virtual void CreateContent() wxOVERRIDE;
protected:
// create an info text contorl
wxTextCtrl *CreateInfoText();
// create a horz sizer holding a static text and this text control
wxSizer *CreateTextWithLabelSizer(const wxString& label,
wxTextCtrl *text,
const wxString& label2 = wxEmptyString,
wxTextCtrl *text2 = NULL);
// event handlers
void OnButtonReset(wxCommandEvent& event);
void OnButtonClearLog(wxCommandEvent& event);
void OnButtonSet(wxCommandEvent& event);
void OnButtonAdd(wxCommandEvent& event);
void OnButtonInsert(wxCommandEvent& event);
void OnButtonClear(wxCommandEvent& event);
void OnButtonLoad(wxCommandEvent& event);
void OnStreamRedirector(wxCommandEvent& event);
void OnButtonQuit(wxCommandEvent& event);
void OnText(wxCommandEvent& event);
void OnTextEnter(wxCommandEvent& event);
void OnTextPasted(wxClipboardTextEvent& event);
void OnCheckOrRadioBox(wxCommandEvent& event);
void OnUpdateUIClearButton(wxUpdateUIEvent& event);
void OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event);
void OnUpdateUINoVertScrollbarCheckbox(wxUpdateUIEvent& event);
void OnUpdateUIWrapLinesRadiobox(wxUpdateUIEvent& event);
void OnUpdateUIResetButton(wxUpdateUIEvent& event);
void OnIdle(wxIdleEvent& event);
// reset the textctrl parameters
void Reset();
// (re)create the textctrl
void CreateText();
// is the control currently single line?
bool IsSingleLine() const
{
return m_radioTextLines->GetSelection() == TextLines_Single;
}
// the controls
// ------------
// the radiobox to choose between single and multi line
wxRadioBox *m_radioTextLines;
// and another one to choose the wrapping style
wxRadioBox *m_radioWrap;
// and yet another one to choose the alignment style
wxRadioBox *m_radioAlign;
// the checkboxes controlling text ctrl styles
wxCheckBox *m_chkPassword,
*m_chkReadonly,
*m_chkProcessEnter,
*m_chkProcessTab,
*m_chkFilename,
*m_chkNoVertScrollbar;
// under MSW we test rich edit controls as well here
#ifdef __WXMSW__
wxRadioBox *m_radioKind;
#endif // __WXMSW__
// the textctrl itself and the sizer it is in
wxTextCtrl *m_text;
wxSizer *m_sizerText;
// the information text zones
wxTextCtrl *m_textPosCur,
*m_textRowCur,
*m_textColCur,
*m_textPosLast,
*m_textLineLast,
*m_textSelFrom,
*m_textSelTo,
*m_textRange;
// and the data to show in them
long m_posCur,
m_posLast,
m_selFrom,
m_selTo;
wxString m_range10_20;
private:
// any class wishing to process wxWidgets events must use this macro
wxDECLARE_EVENT_TABLE();
DECLARE_WIDGETS_PAGE(TextWidgetsPage)
};
// ----------------------------------------------------------------------------
// WidgetsTextCtrl
// ----------------------------------------------------------------------------
class WidgetsTextCtrl : public wxTextCtrl
{
public:
WidgetsTextCtrl(wxWindow *parent,
wxWindowID id,
const wxString& value,
int flags)
: wxTextCtrl(parent, id, value, wxDefaultPosition, wxDefaultSize, flags)
{
Bind(wxEVT_LEFT_DOWN, &WidgetsTextCtrl::OnLeftClick, this);
}
private:
// Show the result of HitTest() at the mouse position if Alt is pressed.
void OnLeftClick(wxMouseEvent& event)
{
event.Skip();
if ( !event.AltDown() )
return;
wxString where;
wxTextCoord x, y;
switch ( HitTest(event.GetPosition(), &x, &y) )
{
default:
wxFAIL_MSG( "unexpected HitTest() result" );
wxFALLTHROUGH;
case wxTE_HT_UNKNOWN:
x = y = -1;
where = "nowhere near";
break;
case wxTE_HT_BEFORE:
where = "before";
break;
case wxTE_HT_BELOW:
where = "below";
break;
case wxTE_HT_BEYOND:
where = "beyond";
break;
case wxTE_HT_ON_TEXT:
where = "at";
break;
}
wxLogMessage("Mouse is %s (%ld, %ld)", where, x, y);
}
};
// ----------------------------------------------------------------------------
// event tables
// ----------------------------------------------------------------------------
wxBEGIN_EVENT_TABLE(TextWidgetsPage, WidgetsPage)
EVT_IDLE(TextWidgetsPage::OnIdle)
EVT_BUTTON(TextPage_Reset, TextWidgetsPage::OnButtonReset)
EVT_BUTTON(TextPage_StreamRedirector, TextWidgetsPage::OnStreamRedirector)
EVT_BUTTON(TextPage_Clear, TextWidgetsPage::OnButtonClear)
EVT_BUTTON(TextPage_Set, TextWidgetsPage::OnButtonSet)
EVT_BUTTON(TextPage_Add, TextWidgetsPage::OnButtonAdd)
EVT_BUTTON(TextPage_Insert, TextWidgetsPage::OnButtonInsert)
EVT_BUTTON(TextPage_Load, TextWidgetsPage::OnButtonLoad)
EVT_UPDATE_UI(TextPage_Clear, TextWidgetsPage::OnUpdateUIClearButton)
EVT_UPDATE_UI(TextPage_Password, TextWidgetsPage::OnUpdateUIPasswordCheckbox)
EVT_UPDATE_UI(TextPage_NoVertScrollbar, TextWidgetsPage::OnUpdateUINoVertScrollbarCheckbox)
EVT_UPDATE_UI(TextPage_WrapLines, TextWidgetsPage::OnUpdateUIWrapLinesRadiobox)
EVT_UPDATE_UI(TextPage_Reset, TextWidgetsPage::OnUpdateUIResetButton)
EVT_TEXT(TextPage_Textctrl, TextWidgetsPage::OnText)
EVT_TEXT_ENTER(TextPage_Textctrl, TextWidgetsPage::OnTextEnter)
EVT_TEXT_PASTE(TextPage_Textctrl, TextWidgetsPage::OnTextPasted)
EVT_CHECKBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
EVT_RADIOBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
wxEND_EVENT_TABLE()
// ============================================================================
// implementation
// ============================================================================
#if defined(__WXX11__)
#define FAMILY_CTRLS NATIVE_CTRLS
#elif defined(__WXUNIVERSAL__)
#define FAMILY_CTRLS UNIVERSAL_CTRLS
#else
#define FAMILY_CTRLS NATIVE_CTRLS
#endif
IMPLEMENT_WIDGETS_PAGE(TextWidgetsPage, "Text",
FAMILY_CTRLS | EDITABLE_CTRLS
);
// ----------------------------------------------------------------------------
// TextWidgetsPage creation
// ----------------------------------------------------------------------------
TextWidgetsPage::TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist)
: WidgetsPage(book, imaglist, text_xpm)
{
// init everything
#ifdef __WXMSW__
m_radioKind =
#endif // __WXMSW__
m_radioWrap =
m_radioAlign =
m_radioTextLines = (wxRadioBox *)NULL;
m_chkPassword =
m_chkReadonly =
m_chkProcessEnter =
m_chkProcessTab =
m_chkFilename =
m_chkNoVertScrollbar = (wxCheckBox *)NULL;
m_text =
m_textPosCur =
m_textRowCur =
m_textColCur =
m_textPosLast =
m_textLineLast =
m_textSelFrom =
m_textSelTo =
m_textRange = (wxTextCtrl *)NULL;
m_sizerText = (wxSizer *)NULL;
m_posCur =
m_posLast =
m_selFrom =
m_selTo = -2; // not -1 which means "no selection"
}
void TextWidgetsPage::CreateContent()
{
// left pane
static const wxString modes[] =
{
"single line",
"multi line",
};
wxStaticBox *box = new wxStaticBox(this, wxID_ANY, "&Set textctrl parameters");
m_radioTextLines = new wxRadioBox(this, wxID_ANY, "&Number of lines:",
wxDefaultPosition, wxDefaultSize,
WXSIZEOF(modes), modes,
1, wxRA_SPECIFY_COLS);
wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
sizerLeft->Add(m_radioTextLines, 0, wxGROW | wxALL, 5);
sizerLeft->AddSpacer(5);
m_chkPassword = CreateCheckBoxAndAddToSizer(
sizerLeft, "&Password control", TextPage_Password
);
m_chkReadonly = CreateCheckBoxAndAddToSizer(
sizerLeft, "&Read-only mode"
);
m_chkProcessEnter = CreateCheckBoxAndAddToSizer(
sizerLeft, "Process &Enter"
);
m_chkProcessTab = CreateCheckBoxAndAddToSizer(
sizerLeft, "Process &Tab"
);
m_chkFilename = CreateCheckBoxAndAddToSizer(
sizerLeft, "&Filename control"
);
m_chkNoVertScrollbar = CreateCheckBoxAndAddToSizer(
sizerLeft, "No &vertical scrollbar",
TextPage_NoVertScrollbar
);
m_chkFilename->Disable(); // not implemented yet
sizerLeft->AddSpacer(5);
static const wxString wrap[] =
{
"no wrap",
"word wrap",
"char wrap",
"best wrap",
};
m_radioWrap = new wxRadioBox(this, TextPage_WrapLines, "&Wrap style:",
wxDefaultPosition, wxDefaultSize,
WXSIZEOF(wrap), wrap,
1, wxRA_SPECIFY_COLS);
sizerLeft->Add(m_radioWrap, 0, wxGROW | wxALL, 5);
static const wxString halign[] =
{
"left",
"centre",
"right",
};
m_radioAlign = new wxRadioBox(this, wxID_ANY, "&Text alignment",
wxDefaultPosition, wxDefaultSize,
WXSIZEOF(halign), halign, 1);
sizerLeft->Add(m_radioAlign, 0, wxGROW | wxALL, 5);
#ifdef __WXMSW__
static const wxString kinds[] =
{
"plain edit",
"rich edit",
"rich edit 2.0",
};
m_radioKind = new wxRadioBox(this, wxID_ANY, "Control &kind",
wxDefaultPosition, wxDefaultSize,
WXSIZEOF(kinds), kinds,
1, wxRA_SPECIFY_COLS);
sizerLeft->AddSpacer(5);
sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
#endif // __WXMSW__
wxButton *btn = new wxButton(this, TextPage_Reset, "&Reset");
sizerLeft->Add(2, 2, 0, wxGROW | wxALL, 1); // spacer
sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
// middle pane
wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, "&Change contents:");
wxSizer *sizerMiddleUp = new wxStaticBoxSizer(box2, wxVERTICAL);
btn = new wxButton(this, TextPage_Set, "&Set text value");
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
btn = new wxButton(this, TextPage_Add, "&Append text");
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
btn = new wxButton(this, TextPage_Insert, "&Insert text");
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
btn = new wxButton(this, TextPage_Load, "&Load file");
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
btn = new wxButton(this, TextPage_Clear, "&Clear");
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
btn = new wxButton(this, TextPage_StreamRedirector, "St&ream redirection");
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
wxStaticBox *box4 = new wxStaticBox(this, wxID_ANY, "&Info:");
wxSizer *sizerMiddleDown = new wxStaticBoxSizer(box4, wxVERTICAL);
m_textPosCur = CreateInfoText();
m_textRowCur = CreateInfoText();
m_textColCur = CreateInfoText();
wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
sizerRow->Add(CreateTextWithLabelSizer
(
"Current pos:",
m_textPosCur
),
0, wxRIGHT, 5);
sizerRow->Add(CreateTextWithLabelSizer
(
"Col:",
m_textColCur
),
0, wxLEFT | wxRIGHT, 5);
sizerRow->Add(CreateTextWithLabelSizer
(
"Row:",
m_textRowCur
),
0, wxLEFT, 5);
sizerMiddleDown->Add(sizerRow, 0, wxALL, 5);
m_textLineLast = CreateInfoText();
m_textPosLast = CreateInfoText();
sizerMiddleDown->Add
(
CreateTextWithLabelSizer
(
"Number of lines:",
m_textLineLast,
"Last position:",
m_textPosLast
),
0, wxALL, 5
);
m_textSelFrom = CreateInfoText();
m_textSelTo = CreateInfoText();
sizerMiddleDown->Add
(
CreateTextWithLabelSizer
(
"Selection: from",
m_textSelFrom,
"to",
m_textSelTo
),
0, wxALL, 5
);
m_textRange = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_READONLY);
sizerMiddleDown->Add
(
CreateTextWithLabelSizer
(
"Range 10..20:",
m_textRange
),
0, wxALL, 5
);
sizerMiddleDown->Add
(
new wxStaticText
(
this,
wxID_ANY,
"Alt-click in the text to see HitTest() result"
),
wxSizerFlags().Border()
);
wxSizer *sizerMiddle = new wxBoxSizer(wxVERTICAL);
sizerMiddle->Add(sizerMiddleUp, 0, wxGROW);
sizerMiddle->Add(sizerMiddleDown, 1, wxGROW | wxTOP, 5);
// right pane
wxStaticBox *box3 = new wxStaticBox(this, wxID_ANY, "&Text:");
m_sizerText = new wxStaticBoxSizer(box3, wxHORIZONTAL);
Reset();
CreateText();
m_sizerText->SetMinSize(150, 0);
// the 3 panes panes compose the upper part of the window
wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
sizerTop->Add(sizerMiddle, 0, wxGROW | wxALL, 10);
sizerTop->Add(m_sizerText, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
SetSizer(sizerTop);
}
// ----------------------------------------------------------------------------
// creation helpers
// ----------------------------------------------------------------------------
wxTextCtrl *TextWidgetsPage::CreateInfoText()
{
static int s_maxWidth = 0;
if ( !s_maxWidth )
{
// calc it once only
GetTextExtent("9999999", &s_maxWidth, NULL);
}
wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
wxDefaultPosition,
wxSize(s_maxWidth, wxDefaultCoord),
wxTE_READONLY);
return text;
}
wxSizer *TextWidgetsPage::CreateTextWithLabelSizer(const wxString& label,
wxTextCtrl *text,
const wxString& label2,
wxTextCtrl *text2)
{
wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
sizerRow->Add(new wxStaticText(this, wxID_ANY, label), 0,
wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
sizerRow->Add(text, 0, wxALIGN_CENTRE_VERTICAL);
if ( text2 )
{
sizerRow->Add(new wxStaticText(this, wxID_ANY, label2), 0,
wxALIGN_CENTRE_VERTICAL | wxLEFT | wxRIGHT, 5);
sizerRow->Add(text2, 0, wxALIGN_CENTRE_VERTICAL);
}
return sizerRow;
}
// ----------------------------------------------------------------------------
// operations
// ----------------------------------------------------------------------------
void TextWidgetsPage::Reset()
{
m_radioTextLines->SetSelection(DEFAULTS.textLines);
m_chkPassword->SetValue(DEFAULTS.password);
m_chkReadonly->SetValue(DEFAULTS.readonly);
m_chkProcessEnter->SetValue(DEFAULTS.processEnter);
m_chkProcessTab->SetValue(DEFAULTS.processTab);
m_chkFilename->SetValue(DEFAULTS.filename);
m_chkNoVertScrollbar->SetValue(DEFAULTS.noVertScrollbar);
m_radioWrap->SetSelection(DEFAULTS.wrapStyle);
m_radioAlign->SetSelection(DEFAULTS.alignmentStyle);
#ifdef __WXMSW__
m_radioKind->SetSelection(DEFAULTS.textKind);
#endif // __WXMSW__
}
void TextWidgetsPage::CreateText()
{
int flags = GetAttrs().m_defaultFlags;
switch ( m_radioTextLines->GetSelection() )
{
default:
wxFAIL_MSG( "unexpected lines radio box selection" );
wxFALLTHROUGH;
case TextLines_Single:
break;
case TextLines_Multi:
flags |= wxTE_MULTILINE;
m_chkPassword->SetValue(false);
break;
}
if ( m_chkPassword->GetValue() )
flags |= wxTE_PASSWORD;
if ( m_chkReadonly->GetValue() )
flags |= wxTE_READONLY;
if ( m_chkProcessEnter->GetValue() )
flags |= wxTE_PROCESS_ENTER;
if ( m_chkProcessTab->GetValue() )
flags |= wxTE_PROCESS_TAB;
if ( m_chkNoVertScrollbar->GetValue() )
flags |= wxTE_NO_VSCROLL;
switch ( m_radioWrap->GetSelection() )
{
default:
wxFAIL_MSG( "unexpected wrap style radio box selection" );
wxFALLTHROUGH;
case WrapStyle_None:
flags |= wxTE_DONTWRAP; // same as wxHSCROLL
break;
case WrapStyle_Word:
flags |= wxTE_WORDWRAP;
break;
case WrapStyle_Char:
flags |= wxTE_CHARWRAP;
break;
case WrapStyle_Best:
// this is default but use symbolic file name for consistency
flags |= wxTE_BESTWRAP;
break;
}
switch ( m_radioAlign->GetSelection() )
{
case Align_Left:
flags |= wxTE_LEFT;
break;
case Align_Center:
flags |= wxTE_CENTER;
break;
case Align_Right:
flags |= wxTE_RIGHT;
break;
default:
wxFAIL_MSG( "unexpected alignment style radio box selection" );
}
#ifdef __WXMSW__
switch ( m_radioKind->GetSelection() )
{
default:
wxFAIL_MSG( "unexpected kind radio box selection" );
wxFALLTHROUGH;
case TextKind_Plain:
break;
case TextKind_Rich:
flags |= wxTE_RICH;
break;
case TextKind_Rich2:
flags |= wxTE_RICH2;
break;
}
#endif // __WXMSW__
wxString valueOld;
if ( m_text )
{
valueOld = m_text->GetValue();
m_sizerText->Detach( m_text );
delete m_text;
}
else
{
valueOld = "Hello, Universe!";
}
m_text = new WidgetsTextCtrl(this, TextPage_Textctrl, valueOld, flags);
#if 0
if ( m_chkFilename->GetValue() )
;
#endif // TODO
// cast to int needed to silence gcc warning about different enums
m_sizerText->Add(m_text, 1, wxALL |
(flags & wxTE_MULTILINE ? (int)wxGROW
: wxALIGN_TOP), 5);
m_sizerText->Layout();
}
// ----------------------------------------------------------------------------
// event handlers
// ----------------------------------------------------------------------------
void TextWidgetsPage::OnIdle(wxIdleEvent& WXUNUSED(event))
{
// update all info texts
if ( m_textPosCur )
{
long posCur = m_text->GetInsertionPoint();
if ( posCur != m_posCur )
{
m_textPosCur->Clear();
m_textRowCur->Clear();
m_textColCur->Clear();
long col, row;
m_text->PositionToXY(posCur, &col, &row);
*m_textPosCur << posCur;
*m_textRowCur << row;
*m_textColCur << col;
m_posCur = posCur;
}
}
if ( m_textPosLast )
{
long posLast = m_text->GetLastPosition();
if ( posLast != m_posLast )
{
m_textPosLast->Clear();
*m_textPosLast << posLast;
m_posLast = posLast;
}
}
if ( m_textLineLast )
{
m_textLineLast->SetValue(
wxString::Format("%d", m_text->GetNumberOfLines()) );
}
if ( m_textSelFrom && m_textSelTo )
{
long selFrom, selTo;
m_text->GetSelection(&selFrom, &selTo);
if ( selFrom != m_selFrom )
{
m_textSelFrom->Clear();
*m_textSelFrom << selFrom;
m_selFrom = selFrom;
}
if ( selTo != m_selTo )
{
m_textSelTo->Clear();
*m_textSelTo << selTo;
m_selTo = selTo;
}
}
if ( m_textRange )
{
wxString range = m_text->GetRange(10, 20);
if ( range != m_range10_20 )
{
m_range10_20 = range;
m_textRange->SetValue(range);
}
}
}
void TextWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
{
Reset();
CreateText();
}
void TextWidgetsPage::OnButtonSet(wxCommandEvent& WXUNUSED(event))
{
m_text->SetValue(m_text->GetWindowStyle() & wxTE_MULTILINE
? "Here,\nthere and\neverywhere"
: "Yellow submarine");
m_text->SetFocus();
}
void TextWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
{
if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
{
m_text->AppendText("We all live in a\n");
}
m_text->AppendText("Yellow submarine");
}
void TextWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
{
m_text->WriteText("Is there anybody going to listen to my story");
if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
{
m_text->WriteText("\nall about the girl who came to stay");
}
}
void TextWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
{
m_text->Clear();
m_text->SetFocus();
}
void TextWidgetsPage::OnButtonLoad(wxCommandEvent& WXUNUSED(event))
{
// search for the file in several dirs where it's likely to be
wxPathList pathlist;
pathlist.Add(".");
pathlist.Add("..");
pathlist.Add("../widgets");
pathlist.Add("../../../samples/widgets");
wxString filename = pathlist.FindValidPath("textctrl.cpp");
if ( !filename )
{
wxLogError("File textctrl.cpp not found.");
}
else // load it
{
wxStopWatch sw;
if ( !m_text->LoadFile(filename) )
{
// this is not supposed to happen ...
wxLogError("Error loading file.");
}
else
{
long elapsed = sw.Time();
wxLogMessage("Loaded file '%s' in %lu.%us",
filename, elapsed / 1000,
(unsigned int) elapsed % 1000);
}
}
}
void TextWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
{
event.Enable(!m_text->GetValue().empty());
}
void TextWidgetsPage::OnUpdateUIWrapLinesRadiobox(wxUpdateUIEvent& event)
{
event.Enable( !IsSingleLine() );
}
void TextWidgetsPage::OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event)
{
// can't put multiline control in password mode
event.Enable( IsSingleLine() );
}
void TextWidgetsPage::OnUpdateUINoVertScrollbarCheckbox(wxUpdateUIEvent& event)
{
// Vertical scrollbar creation can be blocked only in multiline control
event.Enable( !IsSingleLine());
}
void TextWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
{
event.Enable( (m_radioTextLines->GetSelection() != DEFAULTS.textLines) ||
#ifdef __WXMSW__
(m_radioKind->GetSelection() != DEFAULTS.textKind) ||
#endif // __WXMSW__
(m_chkPassword->GetValue() != DEFAULTS.password) ||
(m_chkReadonly->GetValue() != DEFAULTS.readonly) ||
(m_chkProcessEnter->GetValue() != DEFAULTS.processEnter) ||
(m_chkProcessTab->GetValue() != DEFAULTS.processTab) ||
(m_chkFilename->GetValue() != DEFAULTS.filename) ||
(m_chkNoVertScrollbar->GetValue() != DEFAULTS.noVertScrollbar) ||
(m_radioWrap->GetSelection() != DEFAULTS.wrapStyle) );
}
void TextWidgetsPage::OnText(wxCommandEvent& event)
{
if ( !IsUsingLogWindow() )
return;
// Replace middle of long text with ellipsis just to avoid filling up the
// log control with too much unnecessary stuff.
wxLogMessage("Text control value changed (now '%s')",
wxControl::Ellipsize
(
event.GetString(),
wxClientDC(this),
wxELLIPSIZE_MIDDLE,
GetTextExtent('W').x*100
));
}
void TextWidgetsPage::OnTextEnter(wxCommandEvent& event)
{
wxLogMessage("Text entered: '%s'", event.GetString());
event.Skip();
}
void TextWidgetsPage::OnTextPasted(wxClipboardTextEvent& event)
{
wxLogMessage("Text pasted from clipboard.");
event.Skip();
}
void TextWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
{
#if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOSX__)
// We should be able to change text alignment
// dynamically, without recreating the control.
if( event.GetEventObject() == m_radioAlign )
{
long flags = m_text->GetWindowStyle();
flags &= ~(wxTE_LEFT|wxTE_CENTER|wxTE_RIGHT);
switch ( event.GetSelection() )
{
case Align_Left:
flags |= wxTE_LEFT;
break;
case Align_Center:
flags |= wxTE_CENTER;
break;
case Align_Right:
flags |= wxTE_RIGHT;
break;
default:
wxFAIL_MSG( "unexpected alignment style radio box selection" );
return;
}
m_text->SetWindowStyle(flags);
m_text->Refresh();
flags = m_text->GetWindowStyle();
wxLogMessage(wxString::Format("Text alignment: %s",
(flags & wxTE_RIGHT) ? "Right" :
(flags & wxTE_CENTER) ? "Center" : "Left"));
}
else
#else
wxUnusedVar(event);
#endif // WXMSW || WXGTK || WXOSX
{
CreateText();
}
}
void TextWidgetsPage::OnStreamRedirector(wxCommandEvent& WXUNUSED(event))
{
#if wxHAS_TEXT_WINDOW_STREAM
wxStreamToTextRedirector redirect(m_text);
wxString str( "Outputed to cout, appears in wxTextCtrl!" );
wxSTD cout << str << wxSTD endl;
#else
wxMessageBox("This wxWidgets build does not support wxStreamToTextRedirector");
#endif
}