/////////////////////////////////////////////////////////////////////////////
-// Name: univ/textctrl.cpp
+// Name: src/univ/textctrl.cpp
// Purpose: wxTextCtrl
// Author: Vadim Zeitlin
// Modified by:
Everywhere in this file LINE refers to a logical line of text, and ROW to a
physical line of text on the display. They are the same unless WrapLines()
- is TRUE in which case a single LINE may correspond to multiple ROWs.
+ is true in which case a single LINE may correspond to multiple ROWs.
A text position is an unsigned int (which for reasons of compatibility is
- still a long) from 0 to GetLastPosition() inclusive. The positions
+ still a long as wxTextPos) from 0 to GetLastPosition() inclusive. The positions
correspond to the gaps between the letters so the position 0 is just
before the first character and the last position is the one beyond the last
character. For an empty text control GetLastPosition() returns 0.
// headers
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
- #pragma implementation "univtextctrl.h"
-#endif
-
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#if wxUSE_TEXTCTRL
+#include "wx/textctrl.h"
+
#ifndef WX_PRECOMP
#include "wx/log.h"
-
#include "wx/dcclient.h"
#include "wx/validate.h"
- #include "wx/textctrl.h"
+ #include "wx/dataobj.h"
#endif
+#include <ctype.h>
+
#include "wx/clipbrd.h"
#include "wx/textfile.h"
#include "wx/cmdproc.h"
-#if wxUSE_CLIPBOARD
-#include "wx/dataobj.h"
-#endif
-
// turn extra wxTextCtrl-specific debugging on/off
#define WXDEBUG_TEXT
#include "wx/tokenzr.h"
#endif // WXDEBUG_TEXT_REPLACE
+// ----------------------------------------------------------------------------
+// wxStdTextCtrlInputHandler: this control handles only the mouse/kbd actions
+// common to Win32 and GTK, platform-specific things are implemented elsewhere
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxStdTextCtrlInputHandler : public wxStdInputHandler
+{
+public:
+ wxStdTextCtrlInputHandler(wxInputHandler *inphand);
+
+ virtual bool HandleKey(wxInputConsumer *consumer,
+ const wxKeyEvent& event,
+ bool pressed);
+ virtual bool HandleMouse(wxInputConsumer *consumer,
+ const wxMouseEvent& event);
+ virtual bool HandleMouseMove(wxInputConsumer *consumer,
+ const wxMouseEvent& event);
+ virtual bool HandleFocus(wxInputConsumer *consumer, const wxFocusEvent& event);
+
+protected:
+ // get the position of the mouse click
+ static wxTextPos HitTest(const wxTextCtrl *text, const wxPoint& pos);
+
+ // capture data
+ wxTextCtrl *m_winCapture;
+};
+
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
// the value which is never used for text position, even not -1 which is
// sometimes used for some special meaning
-static const wxTextPos INVALID_POS_VALUE = -2;
+static const wxTextPos INVALID_POS_VALUE = wxInvalidTextCoord;
// overlap between pages (when using PageUp/Dn) in lines
static const size_t PAGE_OVERLAP_IN_LINES = 1;
// ----------------------------------------------------------------------------
// the data only used by single line text controls
-struct WXDLLEXPORT wxTextSingleLineData
+struct wxTextSingleLineData
{
// the position of the first visible pixel and the first visible column
wxCoord m_ofsHorz;
};
// the data only used by multi line text controls
-struct WXDLLEXPORT wxTextMultiLineData
+struct wxTextMultiLineData
{
// the lines of text
wxArrayString m_lines;
m_scrollRangeY = 0;
m_updateScrollbarX =
- m_updateScrollbarY = FALSE;
+ m_updateScrollbarY = false;
m_widthMax = -1;
m_lineLongest = 0;
};
// the data only used by multi line text controls in line wrap mode
-class WXDLLEXPORT wxWrappedLineData
+class wxWrappedLineData
{
// these functions set all our values, so give them access to them
friend void wxTextCtrl::LayoutLine(wxTextCoord line,
// this code is unused any longer
#if 0
- // return TRUE if the column is in the start of the last row (hence the row
+ // return true if the column is in the start of the last row (hence the row
// it is in is not wrapped)
bool IsLastRow(wxTextCoord colRowStart) const
{
return colRowStart == GetRowStart(m_rowsStart.GetCount());
}
- // return TRUE if the column is the last column of the row starting in
+ // return true if the column is the last column of the row starting in
// colRowStart
bool IsLastColInRow(wxTextCoord colRowStart,
wxTextCoord colRowEnd,
// caller got it wrong
wxFAIL_MSG( _T("this column is not in the start of the row!") );
- return FALSE;
+ return false;
}
#endif // 0
#include "wx/arrimpl.cpp"
WX_DEFINE_OBJARRAY(wxArrayWrappedLinesData);
-struct WXDLLEXPORT wxTextWrappedData : public wxTextMultiLineData
+struct wxTextWrappedData : public wxTextMultiLineData
{
// the width of the column to the right of the text rect used for the
// indicator mark display for the wrapped lines
// ----------------------------------------------------------------------------
/*
- We use custom versions of wxWindows command processor to implement undo/redo
+ We use custom versions of wxWidgets command processor to implement undo/redo
as we want to avoid storing the backpointer to wxTextCtrl in wxCommand
itself: this is a waste of memory as all commands in the given command
processor always have the same associated wxTextCtrl and so it makes sense
class wxTextCtrlCommand : public wxCommand
{
public:
- wxTextCtrlCommand(const wxString& name) : wxCommand(TRUE, name) { }
+ wxTextCtrlCommand(const wxString& name) : wxCommand(true, name) { }
// we don't use these methods as they don't make sense for us as we need a
// wxTextCtrl to be applied
- virtual bool Do() { wxFAIL_MSG(_T("shouldn't be called")); return FALSE; }
- virtual bool Undo() { wxFAIL_MSG(_T("shouldn't be called")); return FALSE; }
+ virtual bool Do() { wxFAIL_MSG(_T("shouldn't be called")); return false; }
+ virtual bool Undo() { wxFAIL_MSG(_T("shouldn't be called")); return false; }
// instead, our command processor uses these methods
virtual bool Do(wxTextCtrl *text) = 0;
virtual bool CanUndo() const;
virtual bool Do(wxTextCtrl *text);
+ virtual bool Do() { return wxTextCtrlCommand::Do(); }
+ virtual bool Undo() { return wxTextCtrlCommand::Undo(); }
virtual bool Undo(wxTextCtrl *text);
private:
virtual bool CanUndo() const;
virtual bool Do(wxTextCtrl *text);
+ virtual bool Do() { return wxTextCtrlCommand::Do(); }
+ virtual bool Undo() { return wxTextCtrlCommand::Undo(); }
virtual bool Undo(wxTextCtrl *text);
private:
public:
wxTextCtrlCommandProcessor(wxTextCtrl *text)
{
- m_compressInserts = FALSE;
+ m_compressInserts = false;
m_text = text;
}
virtual void Store(wxCommand *command);
// stop compressing insert commands when this is called
- void StopCompressing() { m_compressInserts = FALSE; }
+ void StopCompressing() { m_compressInserts = false; }
// accessors
wxTextCtrl *GetTextCtrl() const { return m_text; }
// the control we're associated with
wxTextCtrl *m_text;
- // if the flag is TRUE we're compressing subsequent insert commands into
+ // if the flag is true we're compressing subsequent insert commands into
// one so that the entire typing could be undone in one call to Undo()
bool m_compressInserts;
};
// implementation
// ============================================================================
-BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase)
EVT_CHAR(wxTextCtrl::OnChar)
EVT_SIZE(wxTextCtrl::OnSize)
END_EVENT_TABLE()
-IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxTextCtrlBase)
// ----------------------------------------------------------------------------
// creation
m_selStart =
m_selEnd = -1;
- m_isModified = FALSE;
- m_isEditable = TRUE;
+ m_isModified = false;
+ m_isEditable = true;
+ m_wrapLines = false;
m_posLast =
m_curPos =
m_heightLine =
m_widthAvg = -1;
- // init wxScrollHelper
- SetWindow(this);
-
// init the undo manager
m_cmdProcessor = new wxTextCtrlCommandProcessor(this);
style |= wxALWAYS_SHOW_SB;
}
- // wxTE_WORDWRAP is 0 for now so we don't need the code below
-#if 0
- if ( style & wxTE_WORDWRAP )
- {
- // wrapping words means wrapping, hence no horz scrollbar
- style &= ~wxHSCROLL;
- }
-#endif // 0
+ // wrapping style: wxTE_DONTWRAP == wxHSCROLL so if it's _not_ given,
+ // we won't have horizontal scrollbar automatically, no need to do
+ // anything
// TODO: support wxTE_NO_VSCROLL (?)
// create data object for normal multiline or for controls with line
// wrap as needed
if ( style & wxHSCROLL )
+ {
m_data.mdata = new wxTextMultiLineData;
- else
+ }
+ else // we must wrap lines if we don't have horizontal scrollbar
+ {
+ // NB: we can't rely on HasFlag(wxHSCROLL) as the flags can change
+ // later and even wxWindow::Create() itself temporarily resets
+ // wxHSCROLL in wxUniv, so remember that we have a wrapped data
+ // and not just a multi line data in a separate variable
+ m_wrapLines = true;
m_data.wdata = new wxTextWrappedData;
+ }
}
else
{
// create data object for single line controls
m_data.sdata = new wxTextSingleLineData;
}
-
+
#if wxUSE_TWO_WINDOWS
if ((style & wxBORDER_MASK) == 0)
style |= wxBORDER_SUNKEN;
if ( !wxControl::Create(parent, id, pos, size, style,
validator, name) )
{
- return FALSE;
+ return false;
}
SetCursor(wxCURSOR_IBEAM);
RecalcFontMetrics();
SetValue(value);
- SetBestSize(size);
+ SetInitialSize(size);
m_isEditable = !(style & wxTE_READONLY);
// we can't show caret right now as we're not shown yet and so it would
// result in garbage on the screen - we'll do it after first OnPaint()
- m_hasCaret = FALSE;
+ m_hasCaret = false;
CreateInputHandler(wxINP_HANDLER_TEXTCTRL);
- return TRUE;
+ wxSizeEvent sizeEvent(GetSize(), GetId());
+ GetEventHandler()->ProcessEvent(sizeEvent);
+
+ return true;
}
wxTextCtrl::~wxTextCtrl()
// set/get the value
// ----------------------------------------------------------------------------
-void wxTextCtrl::SetValue(const wxString& value)
+void wxTextCtrl::DoSetValue(const wxString& value, int flags)
{
if ( IsSingleLine() && (value == GetValue()) )
{
SetInsertionPoint(0);
}
- // TODO: should we generate the event or not, finally?
+ if ( flags & SetValue_SendEvent )
+ SendTextUpdatedEvent();
}
const wxArrayString& wxTextCtrl::GetLines() const
void wxTextCtrl::Clear()
{
- SetValue(_T(""));
+ SetValue(wxEmptyString);
}
bool wxTextCtrl::ReplaceLine(wxTextCoord line,
}
// the number of rows changed
- return TRUE;
+ return true;
}
}
else // no line wrap
}
// the number of rows didn't change
- return FALSE;
+ return false;
}
void wxTextCtrl::RemoveLine(wxTextCoord line)
// as if it does we need to refresh everything below the changed
// text (it will be shifted...) and we can avoid it if there is no
// row relayout
- bool rowsNumberChanged = FALSE;
+ bool rowsNumberChanged = false;
// (1) join lines
const wxArrayString& linesOld = GetLines();
// we have the replacement line for this one
if ( ReplaceLine(line, lines[nReplaceLine]) )
{
- rowsNumberChanged = TRUE;
+ rowsNumberChanged = true;
}
UpdateMaxWidth(line);
{
// (4b) delete all extra lines (note that we need to delete
// them backwards because indices shift while we do it)
- bool deletedLongestLine = FALSE;
+ bool deletedLongestLine = false;
for ( wxTextCoord lineDel = lineEnd; lineDel >= line; lineDel-- )
{
if ( lineDel == MData().m_lineLongest )
{
// we will need to recalc the max line width
- deletedLongestLine = TRUE;
+ deletedLongestLine = true;
}
RemoveLine(lineDel);
}
// even the line number changed
- rowsNumberChanged = TRUE;
+ rowsNumberChanged = true;
// update line to exit the loop
line = lineEnd + 1;
if ( nReplaceLine < nReplaceCount )
{
// even the line number changed
- rowsNumberChanged = TRUE;
+ rowsNumberChanged = true;
do
{
RefreshLineRange(lineEnd + 1, 0);
// the vert scrollbar might [dis]appear
- MData().m_updateScrollbarY = TRUE;
+ MData().m_updateScrollbarY = true;
}
// must recalculate it - will do later
// if necessary
OrderPositions(from, to);
- Replace(from, to, _T(""));
+ Replace(from, to, wxEmptyString);
}
void wxTextCtrl::WriteText(const wxString& text)
void wxTextCtrl::SetSelection(wxTextPos from, wxTextPos to)
{
// selecting till -1 is the same as selecting to the end
- if ( to == -1 && from != -1 )
+ if ( to == -1 )
{
+ // and selecting (-1, -1) range is the same as selecting everything, by
+ // convention
+ if ( from == -1 )
+ from = 0;
to = GetLastPosition();
}
if ( !HasSelection() )
{
// no selection at all, hence no selection in this line
- return FALSE;
+ return false;
}
wxTextCoord lineStart, colStart;
if ( lineStart > line )
{
// this line is entirely above the selection
- return FALSE;
+ return false;
}
wxTextCoord lineEnd, colEnd;
if ( lineEnd < line )
{
// this line is entirely below the selection
- return FALSE;
+ return false;
}
if ( line == lineStart )
*end = GetLineLength(line);
}
- return TRUE;
+ return true;
}
// ----------------------------------------------------------------------------
return m_isEditable && IsEnabled();
}
+void wxTextCtrl::MarkDirty()
+{
+ m_isModified = true;
+}
+
void wxTextCtrl::DiscardEdits()
{
- m_isModified = FALSE;
+ m_isModified = false;
}
void wxTextCtrl::SetEditable(bool editable)
}
else // multiline
{
- wxCHECK_MSG( (size_t)line < GetLineCount(), _T(""),
+ //this is called during DoGetBestSize
+ if (line == 0 && GetLineCount() == 0) return wxEmptyString ;
+
+ wxCHECK_MSG( (size_t)line < GetLineCount(), wxEmptyString,
_T("line index out of range") );
return GetLines()[line];
// if they are out of range
if ( IsSingleLine() )
{
- return x > GetLastPosition() || y > 0 ? -1 : x;
+ return ( x > GetLastPosition() || y > 0 ) ? wxOutOfRangeTextCoord : x;
}
else // multiline
{
if ( IsSingleLine() )
{
if ( (size_t)pos > m_value.length() )
- return FALSE;
+ return false;
if ( x )
*x = pos;
if ( y )
*y = 0;
- return TRUE;
+ return true;
}
else // multiline
{
_T("XYToPosition() or PositionToXY() broken") );
#endif // WXDEBUG_TEXT
- return TRUE;
+ return true;
}
else // go further down
{
}
// beyond the last line
- return FALSE;
+ return false;
}
}
else // must really calculate col/line from pos
{
if ( !PositionToXY(pos, &col, &line) )
- return FALSE;
+ return false;
}
int hLine = GetLineHeight();
if ( yOut )
*yOut = y;
- return TRUE;
+ return true;
}
bool wxTextCtrl::PositionToDeviceXY(wxTextPos pos,
{
wxCoord x, y;
if ( !PositionToLogicalXY(pos, &x, &y) )
- return FALSE;
+ return false;
// finally translate the logical text rect coords into physical client
// coords
CalcScrolledPosition(m_rectText.x + x, m_rectText.y + y, xOut, yOut);
- return TRUE;
+ return true;
}
wxPoint wxTextCtrl::GetCaretPosition() const
// pos may be -1 to show the current position
void wxTextCtrl::ShowPosition(wxTextPos pos)
{
- HideCaret();
+ bool showCaret = GetCaret() && GetCaret()->IsVisible();
+ if (showCaret)
+ HideCaret();
if ( IsSingleLine() )
{
}
//else: multiline but no scrollbars, hence nothing to do
- ShowCaret();
+ if (showCaret)
+ ShowCaret();
}
// ----------------------------------------------------------------------------
bool wxTextCtrl::DoCut()
{
if ( !HasSelection() )
- return FALSE;
+ return false;
Copy();
RemoveSelection();
- return TRUE;
+ return true;
}
void wxTextCtrl::Paste()
{
WriteText(text);
- return TRUE;
+ return true;
}
}
#endif // wxUSE_CLIPBOARD
- return FALSE;
+ return false;
}
// ----------------------------------------------------------------------------
}
// append the following insert commands to this one
- m_compressInserts = TRUE;
+ m_compressInserts = true;
// let the base class version will do the job normally
}
// and now do insert it
text->WriteText(m_text);
- return TRUE;
+ return true;
}
bool wxTextCtrlInsertCommand::Undo(wxTextCtrl *text)
{
- wxCHECK_MSG( CanUndo(), FALSE, _T("impossible to undo insert cmd") );
+ wxCHECK_MSG( CanUndo(), false, _T("impossible to undo insert cmd") );
// remove the text from where we inserted it
text->Remove(m_from, m_from + m_text.length());
- return TRUE;
+ return true;
}
bool wxTextCtrlRemoveCommand::CanUndo() const
m_textDeleted = text->GetSelectionText();
text->RemoveSelection();
- return TRUE;
+ return true;
}
bool wxTextCtrlRemoveCommand::Undo(wxTextCtrl *text)
text->SetInsertionPoint(m_from > posLast ? posLast : m_from);
text->WriteText(m_textDeleted);
- return TRUE;
+ return true;
}
void wxTextCtrl::Undo()
lines = 5;
else if ( lines > 10 )
lines = 10;
- h *= 10;
+ h *= lines;
}
wxRect rectText;
void wxTextCtrl::UpdateTextRect()
{
- wxRect rectTotal(wxPoint(0, 0), GetClientSize());
+ wxRect rectTotal(GetClientSize());
wxCoord *extraSpace = WrapLines() ? &WData().m_widthMark : NULL;
m_rectText = GetRenderer()->GetTextClientArea(this, rectTotal, extraSpace);
#endif // 0
MData().m_updateScrollbarX =
- MData().m_updateScrollbarY = TRUE;
+ MData().m_updateScrollbarY = true;
}
event.Skip();
wxString s(text);
wxTextCoord col;
- wxCoord wReal = -1;
+ wxCoord wReal = wxDefaultCoord;
switch ( HitTestLine(s, m_rectText.width, &col) )
{
/*
col--;
// recalc the width
- wReal = -1;
+ wReal = wxDefaultCoord;
}
//else: we can just see it
// wrap at any character or only at words boundaries?
- if ( !(GetWindowStyle() & wxTE_LINEWRAP) )
+ if ( !(GetWindowStyle() & wxTE_CHARWRAP) )
{
// find the (last) not word char before this word
wxTextCoord colWordStart;
if ( colWordStart != col )
{
// will have to recalc the real width
- wReal = -1;
+ wReal = wxDefaultCoord;
col = colWordStart;
}
if ( widthReal )
{
- if ( wReal == -1 )
+ if ( wReal == wxDefaultCoord )
{
// calc it if not done yet
wReal = GetTextWidth(s.Truncate(col));
return res;
}
+wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pt, long *pos) const
+{
+ wxTextCoord x, y;
+ wxTextCtrlHitTestResult rc = HitTest(pt, &x, &y);
+ if ( rc != wxTE_HT_UNKNOWN && pos )
+ {
+ *pos = XYToPosition(x, y);
+ }
+
+ return rc;
+}
+
wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pos,
wxTextCoord *colOut,
wxTextCoord *rowOut) const
wxTextCoord *colOut,
wxTextCoord *rowOut) const
{
- return HitTest2(pos.y, pos.x, 0, rowOut, colOut, NULL, NULL, FALSE);
+ return HitTest2(pos.y, pos.x, 0, rowOut, colOut, NULL, NULL, false);
}
wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
rowInLine = 0;
if ( row < 0 )
- return FALSE;
+ return false;
int nLines = GetNumberOfLines();
if ( WrapLines() )
if ( line == nLines )
{
// the row is out of range
- return FALSE;
+ return false;
}
}
else // no line wrapping, everything is easy
{
if ( row >= nLines )
- return FALSE;
+ return false;
line = row;
}
if ( rowInLineOut )
*rowInLineOut = rowInLine;
- return TRUE;
+ return true;
}
// ----------------------------------------------------------------------------
if ( dx > 0 )
{
// refresh the uncovered part on the left
- Refresh(TRUE, &rect);
+ Refresh(true, &rect);
// and now the area on the right
rect.x = m_rectText.x + posLastVisible;
rect.width += m_rectText.width - posLastVisible;
}
- Refresh(TRUE, &rect);
+ Refresh(true, &rect);
// I don't know exactly why is this needed here but without it we may
// scroll the window again (from the same method) before the previously
// just to suppress compiler warnings about using uninit vars below
charWidth = maxWidth = 0;
- showScrollbarX = FALSE;
+ showScrollbarX = false;
}
// calc the scrollbars ranges
SetScrollbars(charWidth, lineHeight,
scrollRangeX, scrollRangeY,
x, y,
- TRUE /* no refresh */);
+ true /* no refresh */);
if ( scrollRangeXOld )
{
}
MData().m_updateScrollbarX =
- MData().m_updateScrollbarY = FALSE;
+ MData().m_updateScrollbarY = false;
}
void wxTextCtrl::OnInternalIdle()
{
// intermediate line or the last one but we need to refresh it
// until the end anyhow - do it
- posCount = wxSTRING_MAXLEN;
+ posCount = wxString::npos;
}
else // last line
{
rect.Offset(m_rectText.GetPosition());
// don't refresh beyond the text area unless we're refreshing the line wrap
- // marks in which case textOnly is FALSE
+ // marks in which case textOnly is false
if ( textOnly )
{
if ( rect.GetRight() > m_rectText.GetRight() )
wxLogTrace(_T("text"), _T("Refreshing (%d, %d)-(%d, %d)"),
rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
- Refresh(TRUE, &rect);
+ Refresh(true, &rect);
}
void wxTextCtrl::RefreshLineWrapMarks(wxTextCoord rowFirst,
rectMarks.y = rowFirst*GetLineHeight();
rectMarks.height = (rowLast - rowFirst)*GetLineHeight();
- RefreshTextRect(rectMarks, FALSE /* don't limit to text area */);
+ RefreshTextRect(rectMarks, false /* don't limit to text area */);
}
}
// the update region is in window coords and text area is in the client
// ones, so it must be shifted before computing intersection
wxRegion rgnUpdate = GetUpdateRegion();
-
+
wxRect rectTextArea = GetRealTextArea();
wxPoint pt = GetClientAreaOrigin();
wxRect rectTextAreaAdjusted = rectTextArea;
// show caret first time only: we must show it after drawing the text or
// the display can be corrupted when it's hidden
- if ( !m_hasCaret && GetCaret() )
+ if ( !m_hasCaret && GetCaret() && (FindFocus() == this) )
{
ShowCaret();
- m_hasCaret = TRUE;
+ m_hasCaret = true;
}
}
bool wxTextCtrl::SetFont(const wxFont& font)
{
if ( !wxControl::SetFont(font) )
- return FALSE;
+ return false;
// and refresh everything, of course
InitInsertionPoint();
Refresh();
- return TRUE;
+ return true;
}
bool wxTextCtrl::Enable(bool enable)
{
if ( !wxTextCtrlBase::Enable(enable) )
- return FALSE;
+ return false;
- ShowCaret(enable);
+ if (FindFocus() == this && GetCaret() &&
+ ((enable && !GetCaret()->IsVisible()) ||
+ (!enable && GetCaret()->IsVisible())))
+ ShowCaret(enable);
- return TRUE;
+ return true;
}
void wxTextCtrl::CreateCaret()
{
// FIXME use renderer
caret = new wxCaret(this, 1, GetLineHeight());
-#ifndef __WXMSW__
- caret->SetBlinkTime(0);
-#endif // __WXMSW__
}
else
{
caret->Move(GetCaretPosition());
// and show it there
- caret->Show(show);
+ if ((show && !caret->IsVisible()) ||
+ (!show && caret->IsVisible()))
+ caret->Show(show);
}
}
const wxString& strArg)
{
// has the text changed as result of this action?
- bool textChanged = FALSE;
+ bool textChanged = false;
// the remembered cursor abscissa for multiline text controls is usually
// reset after each user action but for ones which do use it (UP and DOWN
// for example) we shouldn't do it - as indicated by this flag
- bool rememberAbscissa = FALSE;
+ bool rememberAbscissa = false;
// the command this action corresponds to or NULL if this action doesn't
// change text at all or can't be undone
wxTextCtrlCommand *command = (wxTextCtrlCommand *)NULL;
wxString action;
- bool del = FALSE,
- sel = FALSE;
+ bool del = false,
+ sel = false;
if ( actionOrig.StartsWith(wxACTION_TEXT_PREFIX_DEL, &action) )
{
if ( IsEditable() )
- del = TRUE;
+ del = true;
}
else if ( actionOrig.StartsWith(wxACTION_TEXT_PREFIX_SEL, &action) )
{
- sel = TRUE;
+ sel = true;
}
else // not selection nor delete action
{
if ( newPos != INVALID_POS_VALUE )
{
// remember where the cursor original had been
- rememberAbscissa = TRUE;
+ rememberAbscissa = true;
}
}
}
if ( newPos != INVALID_POS_VALUE )
{
// remember where the cursor original had been
- rememberAbscissa = TRUE;
+ rememberAbscissa = true;
}
}
}
// inserting text can be undone
command = new wxTextCtrlInsertCommand(strArg);
- textChanged = TRUE;
+ textChanged = true;
}
}
else if ( (action == wxACTION_TEXT_PAGE_UP) ||
}
// remember where the cursor original had been
- rememberAbscissa = TRUE;
+ rememberAbscissa = true;
bool goUp = action == wxACTION_TEXT_PAGE_UP;
for ( size_t line = 0; line < count; line++ )
}
// scroll vertically only
- Scroll(-1, y);
+ Scroll(wxDefaultCoord, y);
}
}
else if ( action == wxACTION_TEXT_SEL_WORD )
m_cmdProcessor->Submit(command);
// undoable commands always change text
- textChanged = TRUE;
+ textChanged = true;
}
else // no undoable command
{
wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
InitCommandEvent(event);
- event.SetString(GetValue());
GetEventHandler()->ProcessEvent(event);
// as the text changed...
- m_isModified = TRUE;
+ m_isModified = true;
}
- return TRUE;
+ return true;
}
void wxTextCtrl::OnChar(wxKeyEvent& event)
if ( !event.HasModifiers() )
{
int keycode = event.GetKeyCode();
+#if wxUSE_UNICODE
+ wxChar unicode = event.GetUnicodeKey();
+#endif
if ( keycode == WXK_RETURN )
{
if ( IsSingleLine() || (GetWindowStyle() & wxTE_PROCESS_ENTER) )
// skip event.Skip() below
return;
}
+#if wxUSE_UNICODE
+ else if (unicode > 0)
+ {
+ PerformAction(wxACTION_TEXT_INSERT, -1, unicode);
+
+ return;
+ }
+#endif
}
#ifdef __WXDEBUG__
// Ctrl-R refreshes the control in debug mode
event.Skip();
}
+/* static */
+wxInputHandler *wxTextCtrl::GetStdInputHandler(wxInputHandler *handlerDef)
+{
+ static wxStdTextCtrlInputHandler s_handler(handlerDef);
+
+ return &s_handler;
+}
+
// ----------------------------------------------------------------------------
// wxStdTextCtrlInputHandler
// ----------------------------------------------------------------------------
{
// we're only interested in key presses
if ( !pressed )
- return FALSE;
+ return false;
int keycode = event.GetKeyCode();
break;
case WXK_PAGEDOWN:
- case WXK_NEXT:
// we don't map Ctrl-PgUp/Dn to anything special - what should it
// to? for now, it's the same as without control
action << wxACTION_TEXT_PAGE_DOWN;
break;
case WXK_PAGEUP:
- case WXK_PRIOR:
action << wxACTION_TEXT_PAGE_UP;
break;
{
consumer->PerformAction(action, -1, str);
- return TRUE;
+ return true;
}
return wxStdInputHandler::HandleKey(consumer, event, pressed);
bool
wxStdTextCtrlInputHandler::HandleFocus(wxInputConsumer *consumer,
- const wxFocusEvent& WXUNUSED(event))
+ const wxFocusEvent& event)
{
wxTextCtrl *text = wxStaticCast(consumer->GetInputWindow(), wxTextCtrl);
// the selection appearance changes depending on whether we have the focus
text->RefreshSelection();
+ if (event.GetEventType() == wxEVT_SET_FOCUS)
+ {
+ if (text->GetCaret() && !text->GetCaret()->IsVisible())
+ text->ShowCaret();
+ }
+ else
+ {
+ if (text->GetCaret() && text->GetCaret()->IsVisible())
+ text->HideCaret();
+ }
+
// never refresh entirely
- return FALSE;
+ return false;
}
#endif // wxUSE_TEXTCTRL