X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e28c2d151b92823e2375d264a66ee4ed61ffd2e9..1b27b2bd2b6e290645516c180566222c6aa22149:/src/univ/textctrl.cpp diff --git a/src/univ/textctrl.cpp b/src/univ/textctrl.cpp index 1ac457b944..487fb2fca0 100644 --- a/src/univ/textctrl.cpp +++ b/src/univ/textctrl.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: univ/textctrl.cpp +// Name: src/univ/textctrl.cpp // Purpose: wxTextCtrl // Author: Vadim Zeitlin // Modified by: @@ -44,10 +44,10 @@ 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. @@ -117,10 +117,6 @@ // headers // ---------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "univtextctrl.h" -#endif - #include "wx/wxprec.h" #ifdef __BORLANDC__ @@ -129,14 +125,17 @@ #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 + #include "wx/clipbrd.h" #include "wx/textfile.h" @@ -150,10 +149,6 @@ #include "wx/cmdproc.h" -#if wxUSE_CLIPBOARD -#include "wx/dataobj.h" -#endif - // turn extra wxTextCtrl-specific debugging on/off #define WXDEBUG_TEXT @@ -170,6 +165,33 @@ #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 // ---------------------------------------------------------------------------- @@ -195,7 +217,7 @@ static inline void OrderPositions(wxTextPos& from, wxTextPos& to) // 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; @@ -205,7 +227,7 @@ 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; @@ -229,7 +251,7 @@ struct WXDLLEXPORT wxTextSingleLineData }; // the data only used by multi line text controls -struct WXDLLEXPORT wxTextMultiLineData +struct wxTextMultiLineData { // the lines of text wxArrayString m_lines; @@ -268,7 +290,7 @@ struct WXDLLEXPORT wxTextMultiLineData m_scrollRangeY = 0; m_updateScrollbarX = - m_updateScrollbarY = FALSE; + m_updateScrollbarY = false; m_widthMax = -1; m_lineLongest = 0; @@ -278,7 +300,7 @@ struct WXDLLEXPORT wxTextMultiLineData }; // 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, @@ -365,14 +387,14 @@ public: // 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, @@ -398,7 +420,7 @@ public: // caller got it wrong wxFAIL_MSG( _T("this column is not in the start of the row!") ); - return FALSE; + return false; } #endif // 0 @@ -438,7 +460,7 @@ WX_DECLARE_OBJARRAY(wxWrappedLineData, wxArrayWrappedLinesData); #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 @@ -485,7 +507,7 @@ struct WXDLLEXPORT wxTextWrappedData : public wxTextMultiLineData // ---------------------------------------------------------------------------- /* - 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 @@ -499,12 +521,12 @@ struct WXDLLEXPORT wxTextWrappedData : public wxTextMultiLineData 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; @@ -526,6 +548,8 @@ public: 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: @@ -549,6 +573,8 @@ public: 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: @@ -566,7 +592,7 @@ class wxTextCtrlCommandProcessor : public wxCommandProcessor public: wxTextCtrlCommandProcessor(wxTextCtrl *text) { - m_compressInserts = FALSE; + m_compressInserts = false; m_text = text; } @@ -575,7 +601,7 @@ public: 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; } @@ -595,7 +621,7 @@ private: // 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; }; @@ -604,13 +630,13 @@ private: // 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 @@ -622,8 +648,9 @@ void wxTextCtrl::Init() m_selStart = m_selEnd = -1; - m_isModified = FALSE; - m_isEditable = TRUE; + m_isModified = false; + m_isEditable = true; + m_wrapLines = false; m_posLast = m_curPos = @@ -633,9 +660,6 @@ void wxTextCtrl::Init() m_heightLine = m_widthAvg = -1; - // init wxScrollHelper - SetWindow(this); - // init the undo manager m_cmdProcessor = new wxTextCtrlCommandProcessor(this); @@ -663,23 +687,27 @@ bool wxTextCtrl::Create(wxWindow *parent, 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 { @@ -689,7 +717,7 @@ bool wxTextCtrl::Create(wxWindow *parent, // create data object for single line controls m_data.sdata = new wxTextSingleLineData; } - + #if wxUSE_TWO_WINDOWS if ((style & wxBORDER_MASK) == 0) style |= wxBORDER_SUNKEN; @@ -698,7 +726,7 @@ bool wxTextCtrl::Create(wxWindow *parent, if ( !wxControl::Create(parent, id, pos, size, style, validator, name) ) { - return FALSE; + return false; } SetCursor(wxCURSOR_IBEAM); @@ -722,7 +750,7 @@ bool wxTextCtrl::Create(wxWindow *parent, RecalcFontMetrics(); SetValue(value); - SetBestSize(size); + SetInitialSize(size); m_isEditable = !(style & wxTE_READONLY); @@ -731,14 +759,14 @@ bool wxTextCtrl::Create(wxWindow *parent, // 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); wxSizeEvent sizeEvent(GetSize(), GetId()); GetEventHandler()->ProcessEvent(sizeEvent); - return TRUE; + return true; } wxTextCtrl::~wxTextCtrl() @@ -760,7 +788,7 @@ wxTextCtrl::~wxTextCtrl() // set/get the value // ---------------------------------------------------------------------------- -void wxTextCtrl::SetValue(const wxString& value) +void wxTextCtrl::DoSetValue(const wxString& value, int flags) { if ( IsSingleLine() && (value == GetValue()) ) { @@ -775,7 +803,8 @@ void wxTextCtrl::SetValue(const wxString& value) SetInsertionPoint(0); } - // TODO: should we generate the event or not, finally? + if ( flags & SetValue_SendEvent ) + SendTextUpdatedEvent(); } const wxArrayString& wxTextCtrl::GetLines() const @@ -815,7 +844,7 @@ wxString wxTextCtrl::GetValue() const void wxTextCtrl::Clear() { - SetValue(_T("")); + SetValue(wxEmptyString); } bool wxTextCtrl::ReplaceLine(wxTextCoord line, @@ -871,7 +900,7 @@ bool wxTextCtrl::ReplaceLine(wxTextCoord line, } // the number of rows changed - return TRUE; + return true; } } else // no line wrap @@ -880,7 +909,7 @@ bool wxTextCtrl::ReplaceLine(wxTextCoord line, } // the number of rows didn't change - return FALSE; + return false; } void wxTextCtrl::RemoveLine(wxTextCoord line) @@ -997,7 +1026,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text) // 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(); @@ -1105,7 +1134,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text) // we have the replacement line for this one if ( ReplaceLine(line, lines[nReplaceLine]) ) { - rowsNumberChanged = TRUE; + rowsNumberChanged = true; } UpdateMaxWidth(line); @@ -1114,13 +1143,13 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text) { // (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); @@ -1132,7 +1161,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text) } // even the line number changed - rowsNumberChanged = TRUE; + rowsNumberChanged = true; // update line to exit the loop line = lineEnd + 1; @@ -1143,7 +1172,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text) if ( nReplaceLine < nReplaceCount ) { // even the line number changed - rowsNumberChanged = TRUE; + rowsNumberChanged = true; do { @@ -1201,7 +1230,7 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text) RefreshLineRange(lineEnd + 1, 0); // the vert scrollbar might [dis]appear - MData().m_updateScrollbarY = TRUE; + MData().m_updateScrollbarY = true; } // must recalculate it - will do later @@ -1243,7 +1272,7 @@ void wxTextCtrl::Remove(wxTextPos from, wxTextPos to) // if necessary OrderPositions(from, to); - Replace(from, to, _T("")); + Replace(from, to, wxEmptyString); } void wxTextCtrl::WriteText(const wxString& text) @@ -1415,8 +1444,12 @@ wxString wxTextCtrl::GetSelectionText() const 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(); } @@ -1520,7 +1553,7 @@ bool wxTextCtrl::GetSelectedPartOfLine(wxTextCoord line, if ( !HasSelection() ) { // no selection at all, hence no selection in this line - return FALSE; + return false; } wxTextCoord lineStart, colStart; @@ -1528,7 +1561,7 @@ bool wxTextCtrl::GetSelectedPartOfLine(wxTextCoord line, if ( lineStart > line ) { // this line is entirely above the selection - return FALSE; + return false; } wxTextCoord lineEnd, colEnd; @@ -1536,7 +1569,7 @@ bool wxTextCtrl::GetSelectedPartOfLine(wxTextCoord line, if ( lineEnd < line ) { // this line is entirely below the selection - return FALSE; + return false; } if ( line == lineStart ) @@ -1561,7 +1594,7 @@ bool wxTextCtrl::GetSelectedPartOfLine(wxTextCoord line, *end = GetLineLength(line); } - return TRUE; + return true; } // ---------------------------------------------------------------------------- @@ -1579,9 +1612,14 @@ bool wxTextCtrl::IsEditable() const return m_isEditable && IsEnabled(); } +void wxTextCtrl::MarkDirty() +{ + m_isModified = true; +} + void wxTextCtrl::DiscardEdits() { - m_isModified = FALSE; + m_isModified = false; } void wxTextCtrl::SetEditable(bool editable) @@ -1637,7 +1675,10 @@ wxString wxTextCtrl::GetLineText(wxTextCoord line) const } 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]; @@ -1656,7 +1697,7 @@ wxTextPos wxTextCtrl::XYToPosition(wxTextCoord x, wxTextCoord y) const // if they are out of range if ( IsSingleLine() ) { - return x > GetLastPosition() || y > 0 ? -1 : x; + return ( x > GetLastPosition() || y > 0 ) ? wxOutOfRangeTextCoord : x; } else // multiline { @@ -1691,14 +1732,14 @@ bool wxTextCtrl::PositionToXY(wxTextPos pos, 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 { @@ -1723,7 +1764,7 @@ bool wxTextCtrl::PositionToXY(wxTextPos pos, _T("XYToPosition() or PositionToXY() broken") ); #endif // WXDEBUG_TEXT - return TRUE; + return true; } else // go further down { @@ -1732,7 +1773,7 @@ bool wxTextCtrl::PositionToXY(wxTextPos pos, } // beyond the last line - return FALSE; + return false; } } @@ -1806,7 +1847,7 @@ bool wxTextCtrl::PositionToLogicalXY(wxTextPos pos, else // must really calculate col/line from pos { if ( !PositionToXY(pos, &col, &line) ) - return FALSE; + return false; } int hLine = GetLineHeight(); @@ -1835,7 +1876,7 @@ bool wxTextCtrl::PositionToLogicalXY(wxTextPos pos, if ( yOut ) *yOut = y; - return TRUE; + return true; } bool wxTextCtrl::PositionToDeviceXY(wxTextPos pos, @@ -1844,13 +1885,13 @@ 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 @@ -2124,13 +2165,13 @@ void wxTextCtrl::Cut() bool wxTextCtrl::DoCut() { if ( !HasSelection() ) - return FALSE; + return false; Copy(); RemoveSelection(); - return TRUE; + return true; } void wxTextCtrl::Paste() @@ -2154,12 +2195,12 @@ bool wxTextCtrl::DoPaste() { WriteText(text); - return TRUE; + return true; } } #endif // wxUSE_CLIPBOARD - return FALSE; + return false; } // ---------------------------------------------------------------------------- @@ -2199,7 +2240,7 @@ void wxTextCtrlCommandProcessor::Store(wxCommand *command) } // append the following insert commands to this one - m_compressInserts = TRUE; + m_compressInserts = true; // let the base class version will do the job normally } @@ -2234,17 +2275,17 @@ bool wxTextCtrlInsertCommand::Do(wxTextCtrl *text) // 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 @@ -2259,7 +2300,7 @@ bool wxTextCtrlRemoveCommand::Do(wxTextCtrl *text) m_textDeleted = text->GetSelectionText(); text->RemoveSelection(); - return TRUE; + return true; } bool wxTextCtrlRemoveCommand::Undo(wxTextCtrl *text) @@ -2270,7 +2311,7 @@ bool wxTextCtrlRemoveCommand::Undo(wxTextCtrl *text) text->SetInsertionPoint(m_from > posLast ? posLast : m_from); text->WriteText(m_textDeleted); - return TRUE; + return true; } void wxTextCtrl::Undo() @@ -2334,7 +2375,7 @@ wxSize wxTextCtrl::DoGetBestClientSize() const lines = 5; else if ( lines > 10 ) lines = 10; - h *= 10; + h *= lines; } wxRect rectText; @@ -2346,7 +2387,7 @@ wxSize wxTextCtrl::DoGetBestClientSize() const 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); @@ -2467,7 +2508,7 @@ void wxTextCtrl::OnSize(wxSizeEvent& event) #endif // 0 MData().m_updateScrollbarX = - MData().m_updateScrollbarY = TRUE; + MData().m_updateScrollbarY = true; } event.Skip(); @@ -2651,7 +2692,7 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text, wxString s(text); wxTextCoord col; - wxCoord wReal = -1; + wxCoord wReal = wxDefaultCoord; switch ( HitTestLine(s, m_rectText.width, &col) ) { /* @@ -2676,12 +2717,12 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text, 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; @@ -2695,7 +2736,7 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text, if ( colWordStart != col ) { // will have to recalc the real width - wReal = -1; + wReal = wxDefaultCoord; col = colWordStart; } @@ -2718,7 +2759,7 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text, if ( widthReal ) { - if ( wReal == -1 ) + if ( wReal == wxDefaultCoord ) { // calc it if not done yet wReal = GetTextWidth(s.Truncate(col)); @@ -2938,6 +2979,18 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line, 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 @@ -2949,7 +3002,7 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLogical(const wxPoint& pos, 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, @@ -3153,7 +3206,7 @@ bool wxTextCtrl::GetLineAndRow(wxTextCoord row, rowInLine = 0; if ( row < 0 ) - return FALSE; + return false; int nLines = GetNumberOfLines(); if ( WrapLines() ) @@ -3176,13 +3229,13 @@ bool wxTextCtrl::GetLineAndRow(wxTextCoord row, 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; } @@ -3192,7 +3245,7 @@ bool wxTextCtrl::GetLineAndRow(wxTextCoord row, if ( rowInLineOut ) *rowInLineOut = rowInLine; - return TRUE; + return true; } // ---------------------------------------------------------------------------- @@ -3337,7 +3390,7 @@ void wxTextCtrl::ScrollText(wxTextCoord col) 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; @@ -3350,7 +3403,7 @@ void wxTextCtrl::ScrollText(wxTextCoord col) 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 @@ -3518,7 +3571,7 @@ void wxTextCtrl::UpdateScrollbars() // just to suppress compiler warnings about using uninit vars below charWidth = maxWidth = 0; - showScrollbarX = FALSE; + showScrollbarX = false; } // calc the scrollbars ranges @@ -3555,7 +3608,7 @@ void wxTextCtrl::UpdateScrollbars() SetScrollbars(charWidth, lineHeight, scrollRangeX, scrollRangeY, x, y, - TRUE /* no refresh */); + true /* no refresh */); if ( scrollRangeXOld ) { @@ -3572,7 +3625,7 @@ void wxTextCtrl::UpdateScrollbars() } MData().m_updateScrollbarX = - MData().m_updateScrollbarY = FALSE; + MData().m_updateScrollbarY = false; } void wxTextCtrl::OnInternalIdle() @@ -3693,7 +3746,7 @@ void wxTextCtrl::RefreshTextRange(wxTextPos start, wxTextPos end) { // 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 { @@ -3811,7 +3864,7 @@ void wxTextCtrl::RefreshTextRect(const wxRect& rectClient, bool textOnly) 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() ) @@ -3848,7 +3901,7 @@ void wxTextCtrl::RefreshTextRect(const wxRect& rectClient, bool textOnly) 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, @@ -3862,7 +3915,7 @@ 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 */); } } @@ -4120,7 +4173,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer) // 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; @@ -4189,7 +4242,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer) { ShowCaret(); - m_hasCaret = TRUE; + m_hasCaret = true; } } @@ -4200,7 +4253,7 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer) bool wxTextCtrl::SetFont(const wxFont& font) { if ( !wxControl::SetFont(font) ) - return FALSE; + return false; // and refresh everything, of course InitInsertionPoint(); @@ -4220,20 +4273,20 @@ bool wxTextCtrl::SetFont(const wxFont& font) Refresh(); - return TRUE; + return true; } bool wxTextCtrl::Enable(bool enable) { if ( !wxTextCtrlBase::Enable(enable) ) - return FALSE; + return false; if (FindFocus() == this && GetCaret() && ((enable && !GetCaret()->IsVisible()) || (!enable && GetCaret()->IsVisible()))) ShowCaret(enable); - return TRUE; + return true; } void wxTextCtrl::CreateCaret() @@ -4244,9 +4297,6 @@ void wxTextCtrl::CreateCaret() { // FIXME use renderer caret = new wxCaret(this, 1, GetLineHeight()); -#ifndef __WXMSW__ - caret->SetBlinkTime(0); -#endif // __WXMSW__ } else { @@ -4361,28 +4411,28 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig, 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 { @@ -4422,7 +4472,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig, if ( newPos != INVALID_POS_VALUE ) { // remember where the cursor original had been - rememberAbscissa = TRUE; + rememberAbscissa = true; } } } @@ -4435,7 +4485,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig, if ( newPos != INVALID_POS_VALUE ) { // remember where the cursor original had been - rememberAbscissa = TRUE; + rememberAbscissa = true; } } } @@ -4462,7 +4512,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig, // inserting text can be undone command = new wxTextCtrlInsertCommand(strArg); - textChanged = TRUE; + textChanged = true; } } else if ( (action == wxACTION_TEXT_PAGE_UP) || @@ -4479,7 +4529,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig, } // 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++ ) @@ -4526,7 +4576,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig, } // scroll vertically only - Scroll(-1, y); + Scroll(wxDefaultCoord, y); } } else if ( action == wxACTION_TEXT_SEL_WORD ) @@ -4641,7 +4691,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig, m_cmdProcessor->Submit(command); // undoable commands always change text - textChanged = TRUE; + textChanged = true; } else // no undoable command { @@ -4654,14 +4704,13 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig, 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) @@ -4670,6 +4719,9 @@ 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) ) @@ -4691,6 +4743,14 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) // 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 @@ -4701,6 +4761,14 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) event.Skip(); } +/* static */ +wxInputHandler *wxTextCtrl::GetStdInputHandler(wxInputHandler *handlerDef) +{ + static wxStdTextCtrlInputHandler s_handler(handlerDef); + + return &s_handler; +} + // ---------------------------------------------------------------------------- // wxStdTextCtrlInputHandler // ---------------------------------------------------------------------------- @@ -4736,7 +4804,7 @@ bool wxStdTextCtrlInputHandler::HandleKey(wxInputConsumer *consumer, { // we're only interested in key presses if ( !pressed ) - return FALSE; + return false; int keycode = event.GetKeyCode(); @@ -4790,14 +4858,12 @@ bool wxStdTextCtrlInputHandler::HandleKey(wxInputConsumer *consumer, 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; @@ -4849,7 +4915,7 @@ bool wxStdTextCtrlInputHandler::HandleKey(wxInputConsumer *consumer, { consumer->PerformAction(action, -1, str); - return TRUE; + return true; } return wxStdInputHandler::HandleKey(consumer, event, pressed); @@ -4932,7 +4998,7 @@ wxStdTextCtrlInputHandler::HandleFocus(wxInputConsumer *consumer, } // never refresh entirely - return FALSE; + return false; } #endif // wxUSE_TEXTCTRL