1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        wx/univ/textctrl.h 
   3 // Purpose:     wxTextCtrl class 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com) 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #ifndef _WX_UNIV_TEXTCTRL_H_ 
  13 #define _WX_UNIV_TEXTCTRL_H_ 
  16     #pragma interface "univtextctrl.h" 
  19 class WXDLLEXPORT wxCaret
; 
  20 class WXDLLEXPORT wxTextCtrlCommandProcessor
; 
  22 #include "wx/scrolwin.h"    // for wxScrollHelper 
  24 #include "wx/univ/inphand.h" 
  26 // ---------------------------------------------------------------------------- 
  28 // ---------------------------------------------------------------------------- 
  30 // cursor movement and also selection and delete operations 
  31 #define wxACTION_TEXT_GOTO          _T("goto")  // to pos in numArg 
  32 #define wxACTION_TEXT_FIRST         _T("first") // go to pos 0 
  33 #define wxACTION_TEXT_LAST          _T("last")  // go to last pos 
  34 #define wxACTION_TEXT_HOME          _T("home") 
  35 #define wxACTION_TEXT_END           _T("end") 
  36 #define wxACTION_TEXT_LEFT          _T("left") 
  37 #define wxACTION_TEXT_RIGHT         _T("right") 
  38 #define wxACTION_TEXT_UP            _T("up") 
  39 #define wxACTION_TEXT_DOWN          _T("down") 
  40 #define wxACTION_TEXT_WORD_LEFT     _T("wordleft") 
  41 #define wxACTION_TEXT_WORD_RIGHT    _T("wordright") 
  42 #define wxACTION_TEXT_PAGE_UP       _T("pageup") 
  43 #define wxACTION_TEXT_PAGE_DOWN     _T("pagedown") 
  45 // clipboard operations 
  46 #define wxACTION_TEXT_COPY          _T("copy") 
  47 #define wxACTION_TEXT_CUT           _T("cut") 
  48 #define wxACTION_TEXT_PASTE         _T("paste") 
  50 // insert text at the cursor position: the text is in strArg of PerformAction 
  51 #define wxACTION_TEXT_INSERT        _T("insert") 
  53 // if the action starts with either of these prefixes and the rest of the 
  54 // string is one of the movement commands, it means to select/delete text from 
  55 // the current cursor position to the new one 
  56 #define wxACTION_TEXT_PREFIX_SEL    _T("sel") 
  57 #define wxACTION_TEXT_PREFIX_DEL    _T("del") 
  60 #define wxACTION_TEXT_ANCHOR_SEL    _T("anchorsel") 
  61 #define wxACTION_TEXT_EXTEND_SEL    _T("extendsel") 
  62 #define wxACTION_TEXT_SEL_WORD      _T("wordsel") 
  63 #define wxACTION_TEXT_SEL_LINE      _T("linesel") 
  66 #define wxACTION_TEXT_UNDO          _T("undo") 
  67 #define wxACTION_TEXT_REDO          _T("redo") 
  69 // ---------------------------------------------------------------------------- 
  71 // ---------------------------------------------------------------------------- 
  73 // wxTextPos is the position in the text 
  74 typedef long wxTextPos
; 
  76 // wxTextCoord is the line or row number (which should have been unsigned but 
  77 // is long for backwards compatibility) 
  78 typedef long wxTextCoord
; 
  80 // ---------------------------------------------------------------------------- 
  81 // wxTextCtrl::HitTest return values 
  82 // ---------------------------------------------------------------------------- 
  84 // the point asked is ... 
  85 enum wxTextCtrlHitTestResult
 
  87     wxTE_HT_BEFORE 
= -1,    // either to the left or upper 
  88     wxTE_HT_ON_TEXT
,        // directly on 
  89     wxTE_HT_BELOW
,          // below [the last line] 
  90     wxTE_HT_BEYOND          
// after [the end of line] 
  92 // ... the character returned 
  94 // ---------------------------------------------------------------------------- 
  96 // ---------------------------------------------------------------------------- 
  98 class WXDLLEXPORT wxTextCtrl 
: public wxTextCtrlBase
, public wxScrollHelper
 
 104     wxTextCtrl() { Init(); } 
 106     wxTextCtrl(wxWindow 
*parent
, 
 108                const wxString
& value 
= wxEmptyString
, 
 109                const wxPoint
& pos 
= wxDefaultPosition
, 
 110                const wxSize
& size 
= wxDefaultSize
, 
 112                const wxValidator
& validator 
= wxDefaultValidator
, 
 113                const wxString
& name 
= wxTextCtrlNameStr
) 
 117         Create(parent
, id
, value
, pos
, size
, style
, validator
, name
); 
 120     bool Create(wxWindow 
*parent
, 
 122                 const wxString
& value 
= wxEmptyString
, 
 123                 const wxPoint
& pos 
= wxDefaultPosition
, 
 124                 const wxSize
& size 
= wxDefaultSize
, 
 126                 const wxValidator
& validator 
= wxDefaultValidator
, 
 127                 const wxString
& name 
= wxTextCtrlNameStr
); 
 129     virtual ~wxTextCtrl(); 
 131     // implement base class pure virtuals 
 132     // ---------------------------------- 
 134     virtual wxString 
GetValue() const; 
 135     virtual void SetValue(const wxString
& value
); 
 137     virtual int GetLineLength(wxTextCoord lineNo
) const; 
 138     virtual wxString 
GetLineText(wxTextCoord lineNo
) const; 
 139     virtual int GetNumberOfLines() const; 
 141     virtual bool IsModified() const; 
 142     virtual bool IsEditable() const; 
 144     // If the return values from and to are the same, there is no selection. 
 145     virtual void GetSelection(wxTextPos
* from
, wxTextPos
* to
) const; 
 151     virtual void Clear(); 
 152     virtual void Replace(wxTextPos from
, wxTextPos to
, const wxString
& value
); 
 153     virtual void Remove(wxTextPos from
, wxTextPos to
); 
 155     // clears the dirty flag 
 156     virtual void DiscardEdits(); 
 158     // writing text inserts it at the current position, appending always 
 159     // inserts it at the end 
 160     virtual void WriteText(const wxString
& text
); 
 161     virtual void AppendText(const wxString
& text
); 
 163     // translate between the position (which is just an index in the text ctrl 
 164     // considering all its contents as a single strings) and (x, y) coordinates 
 165     // which represent (logical, i.e. unwrapped) column and line. 
 166     virtual wxTextPos 
XYToPosition(wxTextCoord x
, wxTextCoord y
) const; 
 167     virtual bool PositionToXY(wxTextPos pos
, 
 168                               wxTextCoord 
*x
, wxTextCoord 
*y
) const; 
 170     // wxUniv-specific: find a screen position (in client coordinates) of the 
 171     // given text position or of the caret 
 172     bool PositionToLogicalXY(wxTextPos pos
, wxCoord 
*x
, wxCoord 
*y
) const; 
 173     bool PositionToDeviceXY(wxTextPos pos
, wxCoord 
*x
, wxCoord 
*y
) const; 
 174     wxPoint 
GetCaretPosition() const; 
 176     virtual void ShowPosition(wxTextPos pos
); 
 178     // Clipboard operations 
 181     virtual void Paste(); 
 187     virtual bool CanUndo() const; 
 188     virtual bool CanRedo() const; 
 191     virtual void SetInsertionPoint(wxTextPos pos
); 
 192     virtual void SetInsertionPointEnd(); 
 193     virtual wxTextPos 
GetInsertionPoint() const; 
 194     virtual wxTextPos 
GetLastPosition() const; 
 196     virtual void SetSelection(wxTextPos from
, wxTextPos to
); 
 197     virtual void SetEditable(bool editable
); 
 199     // wxUniv-specific methods 
 200     // ----------------------- 
 203     virtual void ShowCaret(bool show 
= TRUE
); 
 204     void HideCaret() { ShowCaret(FALSE
); } 
 205     void CreateCaret(); // for the current font size 
 207     // helpers for cursor movement 
 208     wxTextPos 
GetWordStart() const; 
 209     wxTextPos 
GetWordEnd() const; 
 212     bool HasSelection() const 
 213         { return m_selStart 
!= -1 && m_selEnd 
> m_selStart
; } 
 214     void ClearSelection(); 
 215     void RemoveSelection(); 
 216     wxString 
GetSelectionText() const; 
 218     // find the character at this position, return 0 if the character is 
 219     // really there, -1 if the point is before the beginning of the text/line 
 220     // and the returned character is the first one to follow it or +1 if it the 
 221     // position is beyond the end of line/text and the returned character is 
 224     // NB: pt is in device coords (not adjusted for the client area origin nor 
 225     //     for the scrolling) 
 226     wxTextCtrlHitTestResult 
HitTest(const wxPoint
& pt
, 
 227                                     wxTextCoord 
*col
, wxTextCoord 
*row
) const; 
 229     // find the character at this position in the given line, return value as 
 232     // NB: x is the logical coord (client and unscrolled) 
 233     wxTextCtrlHitTestResult 
HitTestLine(const wxString
& line
, 
 235                                         wxTextCoord 
*colOut
) const; 
 237     // bring the given position into view 
 238     void ShowHorzPosition(wxCoord pos
); 
 240     // scroll the window horizontally so that the first character shown is in 
 242     void ScrollText(wxTextCoord col
); 
 244     // adjust the DC for horz text control scrolling too 
 245     virtual void DoPrepareDC(wxDC
& dc
); 
 247     // implementation only from now on 
 248     // ------------------------------- 
 250     // override this to take into account our scrollbar-less scrolling 
 251     virtual void CalcUnscrolledPosition(int x
, int y
, int *xx
, int *yy
) const; 
 252     virtual void CalcScrolledPosition(int x
, int y
, int *xx
, int *yy
) const; 
 254     // set the right colours and border 
 255     virtual bool IsContainerWindow() const { return TRUE
; } 
 256     virtual wxBorder 
GetDefaultBorder() const { return wxBORDER_SUNKEN
; } 
 259     virtual bool PerformAction(const wxControlAction
& action
, 
 261                                const wxString
& strArg 
= wxEmptyString
); 
 263     // override these methods to handle the caret 
 264     virtual bool SetFont(const wxFont 
&font
); 
 265     virtual bool Enable(bool enable 
= TRUE
); 
 267     // more readable flag testing methods 
 268     bool IsPassword() const { return (GetWindowStyle() & wxTE_PASSWORD
) != 0; } 
 269     bool WrapLines() const 
 270         { return !IsSingleLine() && !(GetWindowStyle() & wxHSCROLL
); } 
 272     // only for wxStdTextCtrlInputHandler 
 273     void RefreshSelection(); 
 276     // override base class methods 
 277     virtual void DoDrawBorder(wxDC
& dc
, const wxRect
& rect
); 
 278     virtual void DoDraw(wxControlRenderer 
*renderer
); 
 280     // calc the size from the text extent 
 281     virtual wxSize 
DoGetBestClientSize() const; 
 283     // common part of all ctors 
 289     // draw the text in the given rectangle 
 290     void DoDrawTextInRect(wxDC
& dc
, const wxRect
& rectUpdate
); 
 292     // draw the line wrap marks in this rect 
 293     void DoDrawLineWrapMarks(wxDC
& dc
, const wxRect
& rectUpdate
); 
 295     // line/row geometry calculations 
 296     // ------------------------------ 
 298     // get the extent (width) of the text 
 299     wxCoord 
GetTextWidth(const wxString
& text
) const; 
 301     // get the logical text width (accounting for scrolling) 
 302     wxCoord 
GetTotalWidth() const; 
 304     // get total number of rows (different from number of lines if the lines 
 306     wxTextCoord 
GetRowCount() const; 
 308     // find the number of rows in this line (only if WrapLines()) 
 309     wxTextCoord 
GetRowsPerLine(wxTextCoord line
) const; 
 311     // get the starting row of the given line 
 312     wxTextCoord 
GetFirstRowOfLine(wxTextCoord line
) const; 
 314     // get the row following this line 
 315     wxTextCoord 
GetRowAfterLine(wxTextCoord line
) const; 
 320     // the text area is the part of the window in which the text can be 
 321     // displayed, i.e. part of it inside the margins and the real text area is 
 322     // the area in which the text *is* currently displayed: for example, in the 
 323     // multiline control case the text area can have extra space at the bottom 
 324     // which is not tall enough for another line and which is then not included 
 325     // into the real text area 
 326     wxRect 
GetRealTextArea() const; 
 328     // refresh the text in the given (in logical coords) rect 
 329     void RefreshTextRect(const wxRect
& rect
, bool textOnly 
= TRUE
); 
 331     // refresh the line wrap marks for the given range of lines (inclusive) 
 332     void RefreshLineWrapMarks(wxTextCoord rowFirst
, wxTextCoord rowLast
); 
 334     // refresh the text in the given range (in logical coords) of this line, if 
 335     // width is 0, refresh to the end of line 
 336     void RefreshPixelRange(wxTextCoord line
, wxCoord start
, wxCoord width
); 
 338     // refresh the text in the given range (in text coords) in this line 
 339     void RefreshColRange(wxTextCoord line
, wxTextPos start
, size_t count
); 
 341     // refresh the text from in the given line range (inclusive) 
 342     void RefreshLineRange(wxTextCoord lineFirst
, wxTextCoord lineLast
); 
 344     // refresh the text in the given range which can span multiple lines 
 345     // (this method accepts arguments in any order) 
 346     void RefreshTextRange(wxTextPos start
, wxTextPos end
); 
 348     // get the text to show: either the text itself or the text replaced with 
 349     // starts for wxTE_PASSWORD control 
 350     wxString 
GetTextToShow(const wxString
& text
) const; 
 352     // find the row in this line where the given position (counted from the 
 354     wxTextCoord 
GetRowInLine(wxTextCoord line
, 
 356                              wxTextCoord 
*colRowStart 
= NULL
) const; 
 358     // find the number of characters of a line before it wraps 
 359     // (and optionally also the real width of the line) 
 360     size_t GetPartOfWrappedLine(const wxChar
* text
, 
 361                                 wxCoord 
*widthReal 
= NULL
) const; 
 363     // get the start and end of the selection for this line: if the line is 
 364     // outside the selection, both will be -1 and FALSE will be returned 
 365     bool GetSelectedPartOfLine(wxTextCoord line
, 
 366                                wxTextPos 
*start
, wxTextPos 
*end
) const; 
 368     // update the text rect: the zone inside our client rect (its coords are 
 369     // client coords) which contains the text 
 370     void UpdateTextRect(); 
 372     // calculate the last visible position 
 373     void UpdateLastVisible(); 
 375     // move caret to the given position unconditionally 
 376     // (SetInsertionPoint() does nothing if the position didn't change) 
 377     void DoSetInsertionPoint(wxTextPos pos
); 
 379     // move caret to the new position without updating the display (for 
 380     // internal use only) 
 381     void MoveInsertionPoint(wxTextPos pos
); 
 383     // set the caret to its initial (default) position 
 384     void InitInsertionPoint(); 
 386     // get the width of the longest line in pixels 
 387     wxCoord 
GetMaxWidth() const; 
 389     // force recalculation of the max line width 
 390     void RecalcMaxWidth(); 
 392     // update the max width after the given line was modified 
 393     void UpdateMaxWidth(wxTextCoord line
); 
 398     // HitTest2() is more efficient than 2 consecutive HitTest()s with the same 
 399     // line (i.e. y) and it also returns the offset of the starting position in 
 402     // as the last hack, this function accepts either logical or device (by 
 403     // default) coords depending on devCoords flag 
 404     wxTextCtrlHitTestResult 
HitTest2(wxCoord y
, 
 408                                      wxTextCoord 
*colStart
, 
 410                                      wxTextCoord 
*colRowStart
, 
 411                                      bool devCoords 
= TRUE
) const; 
 413     // HitTest() version which takes the logical text coordinates and not the 
 415     wxTextCtrlHitTestResult 
HitTestLogical(const wxPoint
& pos
, 
 417                                            wxTextCoord 
*row
) const; 
 419     // get the line and the row in this line corresponding to the given row, 
 420     // return TRUE if ok and FALSE if row is out of range 
 422     // NB: this function can only be called for controls which wrap lines 
 423     bool GetLineAndRow(wxTextCoord row
, 
 425                        wxTextCoord 
*rowInLine
) const; 
 427     // get the height of one line (the same for all lines) 
 428     wxCoord 
GetLineHeight() const 
 430         // this one should be already precalculated 
 431         wxASSERT_MSG( m_heightLine 
!= -1, _T("should have line height") ); 
 436     // get the average char width 
 437     wxCoord 
GetAverageWidth() const { return m_widthAvg
; } 
 439     // recalc the line height and char width (to call when the font changes) 
 440     void RecalcFontMetrics(); 
 442     // vertical scrolling helpers 
 443     // -------------------------- 
 445     // all these functions are for multi line controls only 
 447     // get the number of visible lines 
 448     size_t GetLinesPerPage() const; 
 450     // return the position above the cursor or INVALID_POS_VALUE 
 451     wxTextPos 
GetPositionAbove(); 
 453     // return the position below the cursor or INVALID_POS_VALUE 
 454     wxTextPos 
GetPositionBelow(); 
 458     void OnChar(wxKeyEvent
& event
); 
 459     void OnSize(wxSizeEvent
& event
); 
 461     // overrdie wxScrollHelper method to prevent (auto)scrolling beyond the end 
 463     virtual bool SendAutoScrollEvents(wxScrollWinEvent
& event
) const; 
 465     // return the struct containing control-type dependent data 
 466     struct wxTextSingleLineData
& SData() { return *m_data
.sdata
; } 
 467     struct wxTextMultiLineData
& MData() { return *m_data
.mdata
; } 
 468     struct wxTextWrappedData
& WData() { return *m_data
.wdata
; } 
 469     const wxTextSingleLineData
& SData() const { return *m_data
.sdata
; } 
 470     const wxTextMultiLineData
& MData() const { return *m_data
.mdata
; } 
 471     const wxTextWrappedData
& WData() const { return *m_data
.wdata
; } 
 473     // clipboard operations (unlike the versions without Do prefix, they have a 
 479     virtual void OnInternalIdle(); 
 481     // all these methods are for multiline text controls only 
 483     // update the scrollbars (only called from OnIdle) 
 484     void UpdateScrollbars(); 
 486     // get read only access to the lines of multiline control 
 487     inline const wxArrayString
& GetLines() const; 
 488     inline size_t GetLineCount() const; 
 490     // replace a line (returns TRUE if the number of rows in thel ine changed) 
 491     bool ReplaceLine(wxTextCoord line
, const wxString
& text
); 
 494     void RemoveLine(wxTextCoord line
); 
 496     // insert a line at this position 
 497     void InsertLine(wxTextCoord line
, const wxString
& text
); 
 499     // calculate geometry of this line 
 500     void LayoutLine(wxTextCoord line
, class wxWrappedLineData
& lineData
) const; 
 502     // calculate geometry of all lines until the given one 
 503     void LayoutLines(wxTextCoord lineLast
) const; 
 505     // the initially specified control size 
 506     wxSize m_sizeInitial
; 
 508     // the global control text 
 513     wxTextCoord m_curCol
, 
 516     // last position (only used by GetLastPosition()) 
 520     wxTextPos m_selAnchor
, 
 529     // the rectangle (in client coordinates) to draw text inside 
 532     // the height of one line (cached value of GetCharHeight) 
 533     wxCoord m_heightLine
; 
 535     // and the average char width (cached value of GetCharWidth) 
 538     // we have some data which depends on the kind of control (single or multi 
 542         wxTextSingleLineData 
*sdata
; 
 543         wxTextMultiLineData 
*mdata
; 
 544         wxTextWrappedData 
*wdata
; 
 548     // the object to which we delegate our undo/redo implementation 
 549     wxTextCtrlCommandProcessor 
*m_cmdProcessor
; 
 551     DECLARE_EVENT_TABLE() 
 552     DECLARE_DYNAMIC_CLASS(wxTextCtrl
) 
 555 // ---------------------------------------------------------------------------- 
 556 // wxStdTextCtrlInputHandler: this control handles only the mouse/kbd actions 
 557 // common to Win32 and GTK, platform-specific things are implemented elsewhere 
 558 // ---------------------------------------------------------------------------- 
 560 class WXDLLEXPORT wxStdTextCtrlInputHandler 
: public wxStdInputHandler
 
 563     wxStdTextCtrlInputHandler(wxInputHandler 
*inphand
); 
 565     virtual bool HandleKey(wxInputConsumer 
*consumer
, 
 566                            const wxKeyEvent
& event
, 
 568     virtual bool HandleMouse(wxInputConsumer 
*consumer
, 
 569                              const wxMouseEvent
& event
); 
 570     virtual bool HandleMouseMove(wxInputConsumer 
*consumer
, 
 571                                  const wxMouseEvent
& event
); 
 572     virtual bool HandleFocus(wxInputConsumer 
*consumer
, const wxFocusEvent
& event
); 
 575     // get the position of the mouse click 
 576     static wxTextPos 
HitTest(const wxTextCtrl 
*text
, const wxPoint
& pos
); 
 579     wxTextCtrl 
*m_winCapture
; 
 582 #endif // _WX_UNIV_TEXTCTRL_H_