1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/x11/textctrl.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // for compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  13 #include "wx/textctrl.h" 
  20     #include "wx/dcclient.h" 
  21     #include "wx/settings.h" 
  24 #include "wx/clipbrd.h" 
  25 #include "wx/tokenzr.h" 
  27 #include "wx/univ/inphand.h" 
  28 #include "wx/univ/renderer.h" 
  29 #include "wx/univ/colschem.h" 
  30 #include "wx/univ/theme.h" 
  32 //----------------------------------------------------------------------------- 
  34 //----------------------------------------------------------------------------- 
  36 wxSourceUndoStep::wxSourceUndoStep( wxSourceUndo type
, int y1
, int y2
, wxTextCtrl 
*owner 
) 
  43     m_cursorX 
= m_owner
->GetCursorX(); 
  44     m_cursorY 
= m_owner
->GetCursorY(); 
  46     if (m_type 
== wxSOURCE_UNDO_LINE
) 
  48         m_text 
= m_owner
->m_lines
[m_y1
].m_text
; 
  50     if (m_type 
== wxSOURCE_UNDO_ENTER
) 
  52         m_text 
= m_owner
->m_lines
[m_y1
].m_text
; 
  54     if (m_type 
== wxSOURCE_UNDO_BACK
) 
  56         for (int i 
= m_y1
; i 
< m_y2
+2; i
++) 
  58             if (i 
>= (int)m_owner
->m_lines
.GetCount()) 
  59                 m_lines
.Add( wxEmptyString 
); 
  61                 m_lines
.Add( m_owner
->m_lines
[i
].m_text 
); 
  64     if (m_type 
== wxSOURCE_UNDO_DELETE
) 
  66         for (int i 
= m_y1
; i 
< m_y2
+1; i
++) 
  68             m_lines
.Add( m_owner
->m_lines
[i
].m_text 
); 
  71     if (m_type 
== wxSOURCE_UNDO_PASTE
) 
  73         m_text 
= m_owner
->m_lines
[m_y1
].m_text
; 
  77 void wxSourceUndoStep::Undo() 
  79     if (m_type 
== wxSOURCE_UNDO_LINE
) 
  81         m_owner
->m_lines
[m_y1
].m_text 
= m_text
; 
  82         m_owner
->MoveCursor( m_cursorX
, m_cursorY 
); 
  83         m_owner
->RefreshLine( m_y1 
); 
  85     if (m_type 
== wxSOURCE_UNDO_ENTER
) 
  87         m_owner
->m_lines
[m_y1
].m_text 
= m_text
; 
  88         m_owner
->m_lines
.RemoveAt( m_y1
+1 ); 
  89         m_owner
->MoveCursor( m_cursorX
, m_cursorY 
); 
  90         m_owner
->RefreshDown( m_y1 
); 
  92     if (m_type 
== wxSOURCE_UNDO_BACK
) 
  94         m_owner
->m_lines
[m_y1
].m_text 
= m_lines
[0]; 
  95         m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[1] ), m_y1
+1 ); 
  96         m_owner
->MyAdjustScrollbars(); 
  97         m_owner
->MoveCursor( m_cursorX
, m_cursorY 
); 
  98         m_owner
->RefreshDown( m_y1 
); 
 100     if (m_type 
== wxSOURCE_UNDO_DELETE
) 
 102         m_owner
->m_lines
[m_y1
].m_text 
= m_lines
[0]; 
 103         for (int i 
= 1; i 
< (int)m_lines
.GetCount(); i
++) 
 104             m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[i
] ), m_y1
+i 
); 
 105         m_owner
->MyAdjustScrollbars(); 
 106         m_owner
->MoveCursor( m_cursorX
, m_cursorY 
); 
 107         m_owner
->RefreshDown( m_y1 
); 
 109     if (m_type 
== wxSOURCE_UNDO_PASTE
) 
 111         m_owner
->m_lines
[m_y1
].m_text 
= m_text
; 
 112         for (int i 
= 0; i 
< m_y2
-m_y1
; i
++) 
 113             m_owner
->m_lines
.RemoveAt( m_y1
+1 ); 
 114         m_owner
->MyAdjustScrollbars(); 
 115         m_owner
->MoveCursor( m_cursorX
, m_cursorY 
); 
 116         m_owner
->RefreshDown( m_y1 
); 
 118     if (m_type 
== wxSOURCE_UNDO_INSERT_LINE
) 
 120         m_owner
->m_lines
.RemoveAt( m_y1 
); 
 121         m_owner
->MyAdjustScrollbars(); 
 122         m_owner
->MoveCursor( 0, m_y1 
); 
 123         m_owner
->RefreshDown( m_y1 
); 
 127 #include "wx/arrimpl.cpp" 
 128 WX_DEFINE_OBJARRAY(wxSourceLineArray
); 
 130 //----------------------------------------------------------------------------- 
 132 //----------------------------------------------------------------------------- 
 134 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxTextCtrlBase
) 
 136 BEGIN_EVENT_TABLE(wxTextCtrl
, wxTextCtrlBase
) 
 137     EVT_PAINT(wxTextCtrl::OnPaint
) 
 138     EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground
) 
 139     EVT_CHAR(wxTextCtrl::OnChar
) 
 140     EVT_MOUSE_EVENTS(wxTextCtrl::OnMouse
) 
 141     EVT_KILL_FOCUS(wxTextCtrl::OnKillFocus
) 
 142     EVT_SET_FOCUS(wxTextCtrl::OnSetFocus
) 
 144     EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
) 
 145     EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
) 
 146     EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
) 
 147     EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
) 
 148     EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
) 
 150     EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
) 
 151     EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
) 
 152     EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
) 
 153     EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
) 
 154     EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
) 
 157 void wxTextCtrl::Init() 
 162     m_lang 
= wxSOURCE_LANG_NONE
; 
 175     m_ignoreInput 
= false; 
 179     m_keywordColour 
= wxColour( 10, 140, 10 ); 
 181     m_defineColour 
= *wxRED
; 
 183     m_variableColour 
= wxColour( 50, 120, 150 ); 
 185     m_commentColour 
= wxColour( 130, 130, 130 ); 
 187     m_stringColour 
= wxColour( 10, 140, 10 ); 
 190 wxTextCtrl::wxTextCtrl( wxWindow 
*parent
, 
 192                         const wxString 
&value
, 
 196                         const wxValidator
& validator
, 
 197                         const wxString 
&name 
) 
 198     : wxScrollHelper(this) 
 202     Create( parent
, id
, value
, pos
, size
, style
, validator
, name 
); 
 205 wxTextCtrl::~wxTextCtrl() 
 207     WX_CLEAR_LIST(wxList
, m_undos
); 
 210 bool wxTextCtrl::Create( wxWindow 
*parent
, 
 212                          const wxString 
&value
, 
 216                          const wxValidator
& validator
, 
 217                          const wxString 
&name 
) 
 219     if ((style 
& wxBORDER_MASK
) == 0) 
 220         style 
|= wxBORDER_SUNKEN
; 
 222     if ((style 
& wxTE_MULTILINE
) != 0) 
 223         style 
|= wxALWAYS_SHOW_SB
; 
 225     wxTextCtrlBase::Create( parent
, id
, pos 
/* wxDefaultPosition */, size
, 
 226                             style 
| wxVSCROLL 
| wxHSCROLL
); 
 228     SetBackgroundColour( *wxWHITE 
); 
 230     SetCursor( wxCursor( wxCURSOR_IBEAM 
) ); 
 232     m_editable 
= ((m_windowStyle 
& wxTE_READONLY
) == 0); 
 234     if (HasFlag(wxTE_PASSWORD
)) 
 235         m_sourceFont 
= wxFont( 12, wxMODERN
, wxNORMAL
, wxNORMAL 
); 
 237         m_sourceFont 
= GetFont(); 
 240     dc
.SetFont( m_sourceFont 
); 
 241     m_lineHeight 
= dc
.GetCharHeight(); 
 242     m_charWidth 
= dc
.GetCharWidth(); 
 246     wxSize 
size_best( DoGetBestSize() ); 
 247     wxSize 
new_size( size 
); 
 248     if (new_size
.x 
== -1) 
 249         new_size
.x 
= size_best
.x
; 
 250     if (new_size
.y 
== -1) 
 251         new_size
.y 
= size_best
.y
; 
 252     if ((new_size
.x 
!= size
.x
) || (new_size
.y 
!= size
.y
)) 
 253         SetSize( new_size
.x
, new_size
.y 
); 
 255     // We create an input handler since it might be useful 
 256     CreateInputHandler(wxINP_HANDLER_TEXTCTRL
); 
 258     MyAdjustScrollbars(); 
 263 //----------------------------------------------------------------------------- 
 265 //----------------------------------------------------------------------------- 
 267 wxString 
wxTextCtrl::GetValue() const 
 270     for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
 272         ret 
+= m_lines
[i
].m_text
; 
 273         if (i
+1 < m_lines
.GetCount()) 
 280 void wxTextCtrl::DoSetValue(const wxString
& value
, int flags
) 
 284     wxString oldValue 
= GetValue(); 
 294         m_lines
.Add( new wxSourceLine( wxEmptyString 
) ); 
 302             pos 
= value
.find( wxT('\n'), begin 
); 
 305                 wxSourceLine 
*sl 
= new wxSourceLine( value
.Mid( begin
, value
.Len()-begin 
) ); 
 308                 // if (sl->m_text.Len() > m_longestLine) 
 309                 //    m_longestLine = sl->m_text.Len(); 
 311                 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL 
); 
 313                 if (ww 
> m_longestLine
) 
 320                 wxSourceLine 
*sl 
= new wxSourceLine( value
.Mid( begin
, pos
-begin 
) ); 
 323                 // if (sl->m_text.Len() > m_longestLine) 
 324                 //      m_longestLine = sl->m_text.Len(); 
 326                 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL 
); 
 328                 if (ww 
> m_longestLine
) 
 336     // Don't need to refresh if the value hasn't changed 
 337     if ((GetWindowStyle() & wxTE_MULTILINE
) == 0) 
 339         if (value 
== oldValue
) 
 343     MyAdjustScrollbars(); 
 347     if ( flags 
& SetValue_SendEvent 
) 
 348         SendTextUpdatedEvent(); 
 351 int wxTextCtrl::GetLineLength(long lineNo
) const 
 353     if (lineNo 
>= (long)m_lines
.GetCount()) 
 356     return m_lines
[lineNo
].m_text
.Len(); 
 359 wxString 
wxTextCtrl::GetLineText(long lineNo
) const 
 361     if (lineNo 
>= (long)m_lines
.GetCount()) 
 362         return wxEmptyString
; 
 364     return m_lines
[lineNo
].m_text
; 
 367 int wxTextCtrl::GetNumberOfLines() const 
 369     return  m_lines
.GetCount(); 
 372 bool wxTextCtrl::IsModified() const 
 377 bool wxTextCtrl::IsEditable() const 
 382 void wxTextCtrl::GetSelection(long* from
, long* to
) const 
 384     if (m_selStartX 
== -1 || m_selStartY 
== -1 || 
 385         m_selEndX 
== -1 || m_selEndY 
== -1) 
 387         *from 
= GetInsertionPoint(); 
 388         *to 
= GetInsertionPoint(); 
 392         *from 
= XYToPosition(m_selStartX
, m_selStartY
); 
 393         *to 
= XYToPosition(m_selEndX
, m_selEndY
); 
 397 void wxTextCtrl::Clear() 
 405     m_lines
.Add( new wxSourceLine( wxEmptyString 
) ); 
 407     SetScrollbars( m_charWidth
, m_lineHeight
, 0, 0, 0, 0 ); 
 409     WX_CLEAR_LIST(wxList
, m_undos
); 
 412 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
) 
 416 void wxTextCtrl::Remove(long from
, long to
) 
 420 void wxTextCtrl::DiscardEdits() 
 426 void wxTextCtrl::SetMaxLength(unsigned long len
) 
 430 int wxTextCtrl::PosToPixel( int line
, int pos 
) 
 432     // TODO add support for Tabs 
 434     if (line 
>= (int)m_lines
.GetCount()) return 0; 
 435     if (pos 
< 0) return 0; 
 437     wxString text 
= m_lines
[line
].m_text
; 
 439     if (text
.empty()) return 0; 
 441     if (pos 
< (int)text
.Len()) 
 442         text
.Remove( pos
, text
.Len()-pos 
); 
 446     GetTextExtent( text
, &w
, NULL
, NULL
, NULL 
); 
 451 int wxTextCtrl::PixelToPos( int line
, int pixel 
) 
 453     if (pixel 
< 2) return 0; 
 455     if (line 
>= (int)m_lines
.GetCount()) return 0; 
 457     wxString text 
= m_lines
[line
].m_text
; 
 460     int res 
= text
.Len(); 
 463         GetTextExtent( text
, &w
, NULL
, NULL
, NULL 
); 
 469         text
.Remove( res
,1 ); 
 475 void wxTextCtrl::SetLanguage( wxSourceLanguage lang 
) 
 482 void wxTextCtrl::WriteText(const wxString
& text2
) 
 484     if (text2
.empty()) return; 
 488     wxString 
text( text2 
); 
 491     while ( (pos 
= text
.Find('\n')) != -1 ) 
 493        lines
.Add( text
.Left( pos 
) ); 
 494        text
.Remove( 0, pos
+1 ); 
 497     int count 
= (int)lines
.GetCount(); 
 499     wxString 
tmp1( m_lines
[m_cursorY
].m_text 
); 
 500     wxString 
tmp2( tmp1 
); 
 501     int len 
= (int)tmp1
.Len(); 
 506         for (int i 
= 0; i 
< m_cursorX
-len
; i
++) 
 508         m_lines
[m_cursorY
].m_text
.Append( tmp 
); 
 513     tmp1
.Remove( m_cursorX 
); 
 514     tmp2
.Remove( 0, m_cursorX 
); 
 515     tmp1
.Append( lines
[0] ); 
 519         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) ); 
 522         m_lines
[m_cursorY
].m_text 
= tmp1
; 
 523         RefreshLine( m_cursorY 
); 
 527         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) ); 
 529         m_lines
[m_cursorY
].m_text 
= tmp1
; 
 531         for (i 
= 1; i 
< count
; i
++) 
 532             m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i 
); 
 533         m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2 
); 
 535         MyAdjustScrollbars(); 
 536         RefreshDown( m_cursorY 
); 
 540 void wxTextCtrl::AppendText(const wxString
& text2
) 
 542     if (text2
.empty()) return; 
 546     wxString 
text( text2 
); 
 549     while ( (pos 
= text
.Find('\n')) != -1 ) 
 551        lines
.Add( text
.Left( pos 
) ); 
 552        text
.Remove( 0, pos
+1 ); 
 555     int count 
= (int)lines
.GetCount(); 
 557     size_t y 
= m_lines
.GetCount()-1; 
 559     wxString 
tmp( m_lines
[y
].m_text 
); 
 560     tmp
.Append( lines
[0] ); 
 564         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, y
, y
, this ) ); 
 566         m_lines
[y
].m_text 
= tmp
; 
 571         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, y
, y
+count
-1, this ) ); 
 573         m_lines
[y
].m_text 
= tmp
; 
 575         for (i 
= 1; i 
< count
; i
++) 
 576             m_lines
.Insert( new wxSourceLine( lines
[i
] ), y
+i 
); 
 578         MyAdjustScrollbars(); 
 583 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
) 
 588 long wxTextCtrl::XYToPosition(long x
, long y
) const 
 592     for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
 596             // Add one for the end-of-line character 
 597             ret 
+= m_lines
[i
].m_text
.Len() + 1; 
 601         if ((size_t)x 
< (m_lines
[i
].m_text
.Len()+1)) 
 604             return (ret 
+ m_lines
[i
].m_text
.Len() + 1); 
 610 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const 
 612     if (m_lines
.GetCount() == 0) 
 623     for (size_t i 
= 0; i 
< m_lines
.GetCount(); i
++) 
 625         //pos -= m_lines[i].m_text.Len(); 
 628         // Add one for the end-of-line character. (In Windows, 
 629         // there are _two_ positions for each end of line.) 
 630         if (pos 
<= ((int)m_lines
[i
].m_text
.Len())) 
 637         pos 
-= (m_lines
[i
].m_text
.Len() + 1); 
 642     //xx = m_lines[ m_lines.GetCount()-1 ].m_text.Len(); 
 650 void wxTextCtrl::ShowPosition(long pos
) 
 654 void wxTextCtrl::Copy() 
 656     if (!HasSelection()) return; 
 660     int selStartY 
= m_selStartY
; 
 661     int selEndY 
= m_selEndY
; 
 662     int selStartX 
= m_selStartX
; 
 663     int selEndX 
= m_selEndX
; 
 665     if ((selStartY 
> selEndY
) || 
 666         ((selStartY 
== selEndY
) && (selStartX 
> selEndX
))) 
 676     if (selStartY 
== selEndY
) 
 678         sel 
= m_lines
[selStartY
].m_text
; 
 680         if (selStartX 
>= (int)sel
.Len()) return; 
 681         if (selEndX 
> (int)sel
.Len()) 
 684         sel
.Remove( selEndX
, sel
.Len()-selEndX 
); 
 685         sel
.Remove( 0, selStartX 
); 
 689         wxString 
tmp( m_lines
[selStartY
].m_text 
); 
 691         if (selStartX 
< (int)tmp
.Len()) 
 693             tmp
.Remove( 0, selStartX 
); 
 695             sel
.Append( wxT("\n") ); 
 697         for (int i 
= selStartY
+1; i 
< selEndY
; i
++) 
 699             sel
.Append( m_lines
[i
].m_text 
); 
 700             sel
.Append( wxT("\n") ); 
 702         tmp 
= m_lines
[selEndY
].m_text
; 
 703         if (selEndX 
> (int)tmp
.Len()) 
 707             tmp
.Remove( selEndX
, tmp
.Len()-selEndX 
); 
 712     if (wxTheClipboard
->Open()) 
 714         wxTheClipboard
->SetData( new wxTextDataObject( sel 
) ); 
 715         wxTheClipboard
->Close(); 
 719 void wxTextCtrl::Cut() 
 726 void wxTextCtrl::Paste() 
 730     if (!wxTheClipboard
->Open()) return; 
 732     if (!wxTheClipboard
->IsSupported( wxDF_TEXT 
)) 
 734         wxTheClipboard
->Close(); 
 739     wxTextDataObject data
; 
 741     bool ret 
= wxTheClipboard
->GetData( data 
); 
 743     wxTheClipboard
->Close(); 
 749     wxString 
text( data
.GetText() ); 
 752     while ( (pos 
= text
.Find('\n')) != -1 ) 
 754        lines
.Add( text
.Left( pos 
) ); 
 755        text
.Remove( 0, pos
+1 ); 
 758     int count 
= (int)lines
.GetCount(); 
 760     wxString 
tmp1( m_lines
[m_cursorY
].m_text 
); 
 761     wxString 
tmp2( tmp1 
); 
 762     int len 
= (int)tmp1
.Len(); 
 767         for (int i 
= 0; i 
< m_cursorX
-len
; i
++) 
 769         m_lines
[m_cursorY
].m_text
.Append( tmp 
); 
 774     tmp1
.Remove( m_cursorX 
); 
 775     tmp2
.Remove( 0, m_cursorX 
); 
 776     tmp1
.Append( lines
[0] ); 
 780         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) ); 
 783         m_lines
[m_cursorY
].m_text 
= tmp1
; 
 784         RefreshLine( m_cursorY 
); 
 788         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) ); 
 790         m_lines
[m_cursorY
].m_text 
= tmp1
; 
 792         for (i 
= 1; i 
< count
; i
++) 
 793             m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i 
); 
 794         m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2 
); 
 796         MyAdjustScrollbars(); 
 797         RefreshDown( m_cursorY 
); 
 801 void wxTextCtrl::Undo() 
 803     if (m_undos
.GetCount() == 0) return; 
 805     wxList::compatibility_iterator node 
= m_undos
.Item( m_undos
.GetCount()-1 ); 
 806     wxSourceUndoStep 
*undo 
= (wxSourceUndoStep
*) node
->GetData(); 
 811     m_undos
.Erase( node 
); 
 816 void wxTextCtrl::SetInsertionPoint(long pos
) 
 820     PositionToXY(pos
, & x
, & y
); 
 823     // TODO: scroll to this position if necessary 
 827 void wxTextCtrl::SetInsertionPointEnd() 
 829     SetInsertionPoint(GetLastPosition()); 
 832 long wxTextCtrl::GetInsertionPoint() const 
 834     return XYToPosition( m_cursorX
, m_cursorY 
); 
 837 wxTextPos 
wxTextCtrl::GetLastPosition() const 
 839     size_t lineCount 
= m_lines
.GetCount() - 1; 
 840     // It's the length of the line, not the length - 1, 
 841     // because there's a position after the last character. 
 842     return XYToPosition( m_lines
[lineCount
].m_text
.Len(), lineCount 
); 
 845 void wxTextCtrl::SetSelection(long from
, long to
) 
 849 void wxTextCtrl::SetEditable(bool editable
) 
 851     m_editable 
= editable
; 
 854 bool wxTextCtrl::Enable( bool enable 
) 
 859 bool wxTextCtrl::SetFont(const wxFont
& font
) 
 861     wxTextCtrlBase::SetFont( font 
); 
 866     dc
.SetFont( m_sourceFont 
); 
 867     m_lineHeight 
= dc
.GetCharHeight(); 
 868     m_charWidth 
= dc
.GetCharWidth(); 
 870     // TODO: recalc longest lines 
 872     MyAdjustScrollbars(); 
 877 bool wxTextCtrl::SetForegroundColour(const wxColour
& colour
) 
 879     return wxWindow::SetForegroundColour( colour 
); 
 882 bool wxTextCtrl::SetBackgroundColour(const wxColour
& colour
) 
 884     return wxWindow::SetBackgroundColour( colour 
); 
 887 //----------------------------------------------------------------------------- 
 888 //  private code and handlers 
 889 //----------------------------------------------------------------------------- 
 891 void wxTextCtrl::SearchForBrackets() 
 893     int oldBracketY 
= m_bracketY
; 
 894     int oldBracketX 
= m_bracketX
; 
 896     if (m_cursorY 
< 0 || m_cursorY 
>= (int)m_lines
.GetCount()) return; 
 898     wxString current 
= m_lines
[m_cursorY
].m_text
; 
 900     // reverse search first 
 905         bracket 
= current
[(size_t) (m_cursorX
-1)]; 
 907     if (bracket 
== ')' || bracket 
== ']' || bracket 
== '}') 
 909         char antibracket 
= '('; 
 910         if (bracket 
== ']') antibracket 
= '['; 
 911         if (bracket 
== '}') antibracket 
= '{'; 
 915         int endY 
= m_cursorY
-60; 
 916         if (endY 
< 0) endY 
= 0; 
 917         for (int y 
= m_cursorY
; y 
>= endY
; y
--) 
 919             current 
= m_lines
[y
].m_text
; 
 921                 current
.erase(m_cursorX
-1,current
.Len()-m_cursorX
+1); 
 923             for (int n 
= current
.Len()-1; n 
>= 0; n
--) 
 926                 if (current
[(size_t) (n
)] == '\'') 
 928                     for (int m 
= n
-1; m 
>= 0; m
--) 
 930                         if (current
[(size_t) (m
)] == '\'') 
 932                             if (m 
== 0 || current
[(size_t) (m
-1)] != '\\') 
 941                 if (current
[(size_t) (n
)] == '\"') 
 943                     for (int m 
= n
-1; m 
>= 0; m
--) 
 945                         if (current
[(size_t) (m
)] == '\"') 
 947                             if (m 
== 0 || current
[(size_t) (m
-1)] != '\\') 
 955                 if (current
[(size_t) (n
)] == antibracket
) 
 962                         if (oldBracketY 
!= m_bracketY 
&& oldBracketY 
!= -1) 
 963                             RefreshLine( oldBracketY 
); 
 964                         if (m_bracketY 
!= oldBracketY 
|| m_bracketX 
!= oldBracketX
) 
 965                             RefreshLine( m_bracketY 
); 
 969                 else if (current
[(size_t) (n
)] == bracket
) 
 980     if ((int)current
.Len() > m_cursorX
) 
 981         bracket 
= current
[(size_t) (m_cursorX
)]; 
 982     if (bracket 
== '(' || bracket 
== '[' || bracket 
== '{') 
 984         char antibracket 
= ')'; 
 985         if (bracket 
== '[') antibracket 
= ']'; 
 986         if (bracket 
== '{') antibracket 
= '}'; 
 990         int endY 
= m_cursorY
+60; 
 991         if (endY 
> (int)(m_lines
.GetCount()-1)) endY 
= m_lines
.GetCount()-1; 
 992         for (int y 
= m_cursorY
; y 
<= endY
; y
++) 
 994             current 
= m_lines
[y
].m_text
; 
 999             for (int n 
= start
; n 
< (int)current
.Len(); n
++) 
1002                 if (current
[(size_t) (n
)] == '\'') 
1004                     for (int m 
= n
+1; m 
< (int)current
.Len(); m
++) 
1006                         if (current
[(size_t) (m
)] == '\'') 
1008                             if (m 
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m 
>= 2 && current
[(size_t) (m
-2)] == '\\')) 
1017                 if (current
[(size_t) (n
)] == '\"') 
1019                     for (int m 
= n
+1; m 
< (int)current
.Len(); m
++) 
1021                         if (current
[(size_t) (m
)] == '\"') 
1023                             if (m 
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m 
>= 2 && current
[(size_t) (m
-2)] == '\\')) 
1031                 if (current
[(size_t) (n
)] == antibracket
) 
1038                         if (oldBracketY 
!= m_bracketY 
&& oldBracketY 
!= -1) 
1039                             RefreshLine( oldBracketY 
); 
1040                         if (m_bracketY 
!= oldBracketY 
|| m_bracketX 
!= oldBracketX
) 
1041                             RefreshLine( m_bracketY 
); 
1045                 else if (current
[(size_t) (n
)] == bracket
) 
1053     if (oldBracketY 
!= -1) 
1056         RefreshLine( oldBracketY 
); 
1060 void wxTextCtrl::Delete() 
1062     if (!HasSelection()) return; 
1066     int selStartY 
= m_selStartY
; 
1067     int selEndY 
= m_selEndY
; 
1068     int selStartX 
= m_selStartX
; 
1069     int selEndX 
= m_selEndX
; 
1071     if ((selStartY 
> selEndY
) || 
1072         ((selStartY 
== selEndY
) && (selStartX 
> selEndX
))) 
1074         int tmp 
= selStartX
; 
1075         selStartX 
= selEndX
; 
1078         selStartY 
= selEndY
; 
1082     int len 
= (int)m_lines
[selStartY
].m_text
.Len(); 
1084     if (selStartY 
== selEndY
) 
1086         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, selStartY
, selStartY
, this ) ); 
1088         wxString 
tmp( m_lines
[selStartY
].m_text 
); 
1089         if (selStartX 
< len
) 
1093             tmp
.Remove( selStartX
, selEndX
-selStartX 
); 
1094             m_lines
[selStartY
].m_text 
= tmp
; 
1097         m_cursorX 
= selStartX
; 
1098         RefreshLine( selStartY 
); 
1102         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, selStartY
, selEndY
, this ) ); 
1104         if (selStartX 
< len
) 
1105             m_lines
[selStartY
].m_text
.Remove( selStartX 
); 
1107         for (int i 
= 0; i 
< selEndY
-selStartY
-1; i
++) 
1108             m_lines
.RemoveAt( selStartY
+1 ); 
1110         if (selEndX 
< (int)m_lines
[selStartY
+1].m_text
.Len()) 
1111             m_lines
[selStartY
+1].m_text
.Remove( 0, selEndX 
); 
1113             m_lines
[selStartY
+1].m_text
.Remove( 0 ); 
1115         m_lines
[selStartY
].m_text
.Append( m_lines
[selStartY
+1].m_text 
); 
1116         m_lines
.RemoveAt( selStartY
+1 ); 
1119         MoveCursor( selStartX
, selStartY 
); 
1120         MyAdjustScrollbars(); 
1122         RefreshDown( selStartY 
); 
1126 void wxTextCtrl::DeleteLine() 
1128     if (HasSelection()) return; 
1130     if (m_cursorY 
< 0 || m_cursorY 
>= (int)m_lines
.GetCount()-1) return;  // TODO 
1132     m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) ); 
1134     m_lines
.RemoveAt( m_cursorY 
); 
1136     if (m_cursorY 
>= (int)m_lines
.GetCount()) m_cursorY
--; 
1138     MyAdjustScrollbars(); 
1139     RefreshDown( m_cursorY 
); 
1142 void wxTextCtrl::DoChar( char c 
) 
1146     m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) ); 
1148     wxString 
tmp( m_lines
[m_cursorY
].m_text 
); 
1150     if (m_cursorX 
>= (int)tmp
.Len()) 
1152         int len 
= tmp
.Len(); 
1153         for (int i 
= 0; i 
< m_cursorX 
- len
; i
++) 
1160             tmp
.SetChar( m_cursorX
, c 
); 
1162             tmp
.insert( m_cursorX
, 1, c 
); 
1165     m_lines
[m_cursorY
].m_text 
= tmp
; 
1167 //    if (tmp.Len() > m_longestLine) 
1169 //        m_longestLine = tmp.Len(); 
1170 //        MyAdjustScrollbars(); 
1174     GetTextExtent( tmp
, &ww
, NULL
, NULL
, NULL 
); 
1176     if (ww 
> m_longestLine
) 
1179         MyAdjustScrollbars(); 
1184     int y 
= m_cursorY
*m_lineHeight
; 
1185     // int x = (m_cursorX-1)*m_charWidth; 
1186     int x 
= PosToPixel( m_cursorY
, m_cursorX
-1 ); 
1187     CalcScrolledPosition( x
, y
, &x
, &y 
); 
1188     wxRect 
rect( x
+2, y
+2, 10000, m_lineHeight 
); 
1189     Refresh( true, &rect 
); 
1190     // refresh whole line for syntax colour highlighting 
1192     Refresh( false, &rect 
); 
1196     GetClientSize( &size_x
, &size_y 
); 
1197     size_x 
/= m_charWidth
; 
1201     GetViewStart( &view_x
, &view_y 
); 
1203     //int xx = m_cursorX; 
1204     int xx 
= PosToPixel( m_cursorY
, m_cursorX 
) / m_charWidth
; 
1208     else if (xx 
> view_x
+size_x
-1) 
1209         Scroll( xx
-size_x
+1, -1 ); 
1212 void wxTextCtrl::DoBack() 
1218         if (m_cursorY 
== 0) return; 
1220         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_BACK
, m_cursorY
-1, m_cursorY
, this ) ); 
1222         wxString 
tmp1( m_lines
[m_cursorY
-1].m_text 
); 
1224         wxString 
tmp2( m_lines
[m_cursorY
].m_text 
); 
1226         m_cursorX 
= tmp1
.Len(); 
1228         tmp1
.Append( tmp2 
); 
1229         m_lines
[m_cursorY
].m_text 
= tmp1
; 
1230         m_lines
.RemoveAt( m_cursorY
+1 ); 
1232         MyAdjustScrollbars(); 
1233         RefreshDown( m_cursorY
-1 ); 
1237         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) ); 
1239         if (m_cursorX 
<= (int)m_lines
[m_cursorY
].m_text
.Len()) 
1240             m_lines
[m_cursorY
].m_text
.Remove( m_cursorX
-1, 1 ); 
1243         int y 
= m_cursorY
*m_lineHeight
; 
1244         // int x = m_cursorX*m_charWidth; 
1245         int x 
= PosToPixel( m_cursorY
, m_cursorX 
); 
1246         CalcScrolledPosition( x
, y
, &x
, &y 
); 
1247         wxRect 
rect( x
+2, y
+2, 10000, m_lineHeight 
); 
1248         Refresh( true, &rect 
); 
1249         // refresh whole line for syntax colour highlighting 
1251         Refresh( false, &rect 
); 
1255 void wxTextCtrl::DoDelete() 
1259     wxString 
tmp( m_lines
[m_cursorY
].m_text 
); 
1261     int len 
= (int)tmp
.Len(); 
1262     if (m_cursorX 
>= len
) 
1264         if (m_cursorY 
== (int)m_lines
.GetCount()-1) return; 
1266         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) ); 
1268         for (int i 
= 0; i 
< (m_cursorX
-len
); i
++) 
1271         tmp 
+= m_lines
[m_cursorY
+1].m_text
; 
1273         m_lines
[m_cursorY
] = tmp
; 
1274         m_lines
.RemoveAt( m_cursorY
+1 ); 
1276         MyAdjustScrollbars(); 
1277         RefreshDown( m_cursorY 
); 
1281         m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) ); 
1283         tmp
.Remove( m_cursorX
, 1 ); 
1284         m_lines
[m_cursorY
].m_text 
= tmp
; 
1286         int y 
= m_cursorY
*m_lineHeight
; 
1287         // int x = m_cursorX*m_charWidth; 
1288         int x 
= PosToPixel( m_cursorY
, m_cursorX 
); 
1289         CalcScrolledPosition( x
, y
, &x
, &y 
); 
1290         wxRect 
rect( x
+2, y
+2, 10000, m_lineHeight 
); 
1291         Refresh( true, &rect 
); 
1292         // refresh whole line for syntax colour highlighting 
1294         Refresh( false, &rect 
); 
1298 void wxTextCtrl::DoReturn() 
1302     m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_ENTER
, m_cursorY
, m_cursorY
, this ) ); 
1304     wxString 
tmp( m_lines
[m_cursorY
].m_text 
); 
1305     size_t indent 
= tmp
.find_first_not_of( ' ' ); 
1306     if (indent 
== wxSTRING_MAXLEN
) indent 
= 0; 
1308     if (m_cursorX 
>= (int)tmp
.Len()) 
1310         int cursorX 
= indent
; 
1311         int cursorY 
= m_cursorY 
+ 1; 
1314         for (size_t i 
= 0; i 
< indent
; i
++) new_tmp
.Append( ' ' ); 
1315         m_lines
.Insert( new wxSourceLine( new_tmp 
), cursorY 
); 
1317         MyAdjustScrollbars(); 
1318         MoveCursor( cursorX
, cursorY 
); 
1319         RefreshDown( m_cursorY 
); 
1323         wxString 
tmp1( tmp 
); 
1324         tmp1
.Remove( m_cursorX
, tmp
.Len()-m_cursorX 
); 
1325         m_lines
[m_cursorY
].m_text 
= tmp1
; 
1327         wxString 
tmp2( tmp 
); 
1328         tmp2
.Remove( 0, m_cursorX 
); 
1330         int cursorX 
= indent
; 
1331         int cursorY 
= m_cursorY 
+ 1; 
1334         for (size_t i 
= 0; i 
< indent
; i
++) new_tmp
.Append( ' ' ); 
1335         new_tmp
.Append( tmp2 
); 
1336         m_lines
.Insert( new wxSourceLine( new_tmp 
), cursorY 
); 
1338         MyAdjustScrollbars(); 
1339         MoveCursor( cursorX
, cursorY 
); 
1340         RefreshDown( m_cursorY
-1 ); 
1344 void wxTextCtrl::DoDClick() 
1346     wxString 
line( m_lines
[ m_cursorY 
].m_text 
); 
1347     if (m_cursorX 
>= (int)line
.Len()) return; 
1349     char ch 
= line
[(size_t) (p
)]; 
1350     if (((ch 
>= 'a') && (ch 
<= 'z')) || 
1351         ((ch 
>= 'A') && (ch 
<= 'Z')) || 
1352         ((ch 
>= '0') && (ch 
<= '9')) || 
1355         m_selStartY 
= m_cursorY
; 
1356         m_selEndY 
= m_cursorY
; 
1359             ch 
= line
[(size_t) (p
-1)]; 
1360             while (((ch 
>= 'a') && (ch 
<= 'z')) || 
1361                    ((ch 
>= 'A') && (ch 
<= 'Z')) || 
1362                    ((ch 
>= '0') && (ch 
<= '9')) || 
1367                 ch 
= line
[(size_t) (p
-1)]; 
1373         if (p 
< (int)line
.Len()) 
1375             ch 
= line
[(size_t) (p
)]; 
1376             while (((ch 
>= 'a') && (ch 
<= 'z')) || 
1377                    ((ch 
>= 'A') && (ch 
<= 'Z')) || 
1378                    ((ch 
>= '0') && (ch 
<= '9')) || 
1381                 if (p 
>= (int)line
.Len()) break; 
1383                 ch 
= line
[(size_t) (p
)]; 
1387         RefreshLine( m_cursorY 
); 
1391 wxString 
wxTextCtrl::GetNextToken( wxString 
&line
, size_t &pos 
) 
1394     size_t len 
= line
.Len(); 
1395     for (size_t p 
= pos
; p 
< len
; p
++) 
1397         if ((m_lang 
== wxSOURCE_LANG_PYTHON
) || (m_lang 
== wxSOURCE_LANG_PERL
)) 
1401                 for (size_t q 
= p
; q 
< len
; q
++) 
1402                     ret
.Append( line
[q
] ); 
1409             if ((line
[p
] == '/') && (p
+1 < len
) && (line
[(size_t) (p
+1)] == '/')) 
1411                 for (size_t q 
= p
; q 
< len
; q
++) 
1412                     ret
.Append( line
[q
] ); 
1420             ret
.Append( line
[p
] ); 
1421             for (size_t q 
= p
+1; q 
< len
; q
++) 
1423                 ret
.Append( line
[q
] ); 
1424                 if ((line
[q
] == '"') && ((line
[(size_t) (q
-1)] != '\\') || (q 
>= 2 && line
[(size_t) (q
-2)] == '\\'))) 
1431         if (line
[p
] == '\'') 
1433             ret
.Append( line
[p
] ); 
1434             for (size_t q 
= p
+1; q 
< len
; q
++) 
1436                 ret
.Append( line
[q
] ); 
1437                 if ((line
[q
] == '\'') && ((line
[(size_t) (q
-1)] != '\\') || (q 
>= 2 && line
[(size_t) (q
-2)] == '\\'))) 
1444         if (((line
[p
] >= 'a') && (line
[p
] <= 'z')) || 
1445             ((line
[p
] >= 'A') && (line
[p
] <= 'Z')) || 
1449            ret
.Append( line
[p
] ); 
1450            for (size_t q 
= p
+1; q 
< len
; q
++) 
1452                 if (((line
[q
] >= 'a') && (line
[q
] <= 'z')) || 
1453                    ((line
[q
] >= 'A') && (line
[q
] <= 'Z')) || 
1454                    ((line
[q
] >= '0') && (line
[q
] <= '9')) || 
1457                     ret
.Append( line
[q
] ); 
1474 void wxTextCtrl::OnEraseBackground( wxEraseEvent 
&event 
) 
1479 void wxTextCtrl::DrawLinePart( wxDC 
&dc
, int x
, int y
, const wxString 
&toDraw
, const wxString 
&origin
, const wxColour 
&colour 
) 
1482     size_t len 
= origin
.Len(); 
1483     dc
.SetTextForeground( colour 
); 
1486         while (toDraw
[pos
] == wxT(' ')) 
1489             if (pos 
== len
) return; 
1495         current 
+= toDraw
[pos
]; 
1497         while ( (toDraw
[pos
] == origin
[pos
]) && (pos 
< len
)) 
1499             current 
+= toDraw
[pos
]; 
1504         wxString tmp 
= origin
.Left( start 
); 
1505         GetTextExtent( tmp
, &xx
, NULL
, NULL
, NULL 
); 
1508         dc
.DrawText( current
, xx
, yy 
); 
1512 void wxTextCtrl::DrawLine( wxDC 
&dc
, int x
, int y
, const wxString 
&line2
, int lineNum 
) 
1514     int selStartY 
= m_selStartY
; 
1515     int selEndY 
= m_selEndY
; 
1516     int selStartX 
= m_selStartX
; 
1517     int selEndX 
= m_selEndX
; 
1519     if ((selStartY 
> selEndY
) || 
1520         ((selStartY 
== selEndY
) && (selStartX 
> selEndX
))) 
1522         int tmp 
= selStartX
; 
1523         selStartX 
= selEndX
; 
1526         selStartY 
= selEndY
; 
1530     wxString 
line( line2 
); 
1531     if (HasFlag(wxTE_PASSWORD
)) 
1533         size_t len 
= line
.Len(); 
1534         line 
= wxString( wxT('*'), len 
); 
1537     wxString 
keyword( ' ', line
.Len() ); 
1538     wxString 
define( ' ', line
.Len() ); 
1539     wxString 
variable( ' ', line
.Len() ); 
1540     wxString 
comment( ' ', line
.Len() ); 
1541     wxString 
my_string( ' ', line
.Len() ); 
1542     wxString 
selection( ' ', line
.Len() ); 
1544     if (m_lang 
!= wxSOURCE_LANG_NONE
) 
1546         if (lineNum 
== m_bracketY
) 
1548             wxString 
red( ' ', line
.Len() ); 
1549             if (m_bracketX 
< (int)line
.Len()) 
1551                 red
.SetChar( m_bracketX
, line
[(size_t) (m_bracketX
)] ); 
1552                 line
.SetChar( m_bracketX
, ' ' ); 
1553                 dc
.SetTextForeground( *wxRED 
); 
1554                 dc
.DrawText( red
, x
, y 
); 
1555                 dc
.SetTextForeground( *wxBLACK 
); 
1560         wxString 
token( GetNextToken( line
, pos 
) ); 
1561         while (!token
.IsNull()) 
1563             if (m_keywords
.Index( token 
) != wxNOT_FOUND
) 
1565                 size_t end_pos 
= pos 
+ token
.Len(); 
1566                 for (size_t i 
= pos
; i 
< end_pos
; i
++) 
1568                     keyword
[i
] = line
[i
]; 
1572             if (m_defines
.Index( token 
) != wxNOT_FOUND
) 
1574                 size_t end_pos 
= pos 
+ token
.Len(); 
1575                 for (size_t i 
= pos
; i 
< end_pos
; i
++) 
1577                     define
[i
] = line
[i
]; 
1581             if ((m_variables
.Index( token 
) != wxNOT_FOUND
) || 
1582                 ((token
.Len() > 2) && (token
[(size_t) (0)] == 'w') && (token
[(size_t) (1)] == 'x'))) 
1584                 size_t end_pos 
= pos 
+ token
.Len(); 
1585                 for (size_t i 
= pos
; i 
< end_pos
; i
++) 
1587                     variable
[i
] = line
[i
]; 
1591             if ((token
.Len() >= 2) && (token
[(size_t) (0)] == '/') && (token
[(size_t) (1)] == '/') && (m_lang 
== wxSOURCE_LANG_CPP
)) 
1593                 size_t end_pos 
= pos 
+ token
.Len(); 
1594                 for (size_t i 
= pos
; i 
< end_pos
; i
++) 
1596                     comment
[i
] = line
[i
]; 
1600             if ((token
[(size_t) (0)] == '#') && 
1601                 ((m_lang 
== wxSOURCE_LANG_PYTHON
) || (m_lang 
== wxSOURCE_LANG_PERL
))) 
1603                 size_t end_pos 
= pos 
+ token
.Len(); 
1604                 for (size_t i 
= pos
; i 
< end_pos
; i
++) 
1606                     comment
[i
] = line
[i
]; 
1610             if ((token
[(size_t) (0)] == '"') || (token
[(size_t) (0)] == '\'')) 
1612                 size_t end_pos 
= pos 
+ token
.Len(); 
1613                 for (size_t i 
= pos
; i 
< end_pos
; i
++) 
1615                     my_string
[i
] = line
[i
]; 
1620             token 
= GetNextToken( line
, pos 
); 
1624     if ((lineNum 
< selStartY
) || (lineNum 
> selEndY
)) 
1626         DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK 
); 
1627         DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE 
); 
1628         DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour 
); 
1629         DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour 
); 
1630         DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour 
); 
1631         DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour 
); 
1632         DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour 
); 
1636     if (selStartY 
== selEndY
) 
1638         // int xx = selStartX*m_charWidth; 
1639         int xx 
= PosToPixel( lineNum
, selStartX 
); 
1640         // int ww = (selEndX-selStartX)*m_charWidth; 
1641         int ww 
= PosToPixel( lineNum
, selEndX 
) - xx
; 
1642         dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight 
); 
1644         for (size_t i 
= (size_t)selStartX
; i 
< (size_t)selEndX
; i
++) 
1646             selection
[i
] = line
[i
]; 
1650     if ((lineNum 
> selStartY
) && (lineNum 
< selEndY
)) 
1652         dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight 
); 
1654         for (size_t i 
= 0; i 
< line
.Len(); i
++) 
1656             selection
[i
] = line
[i
]; 
1660     if (lineNum 
== selStartY
) 
1662         // int xx = selStartX*m_charWidth; 
1663         int xx 
= PosToPixel( lineNum
, selStartX 
); 
1664         dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight 
); 
1666         for (size_t i 
= (size_t)selStartX
; i 
< line
.Len(); i
++) 
1668             selection
[i
] = line
[i
]; 
1672     if (lineNum 
== selEndY
) 
1674         // int ww = selEndX*m_charWidth; 
1675         int ww 
= PosToPixel( lineNum
, selEndX 
); 
1676         dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight 
); 
1678         for (size_t i 
= 0; i 
< (size_t)selEndX
; i
++) 
1680             selection
[i
] = line
[i
]; 
1685     DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK 
); 
1686     DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE 
); 
1687     DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour 
); 
1688     DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour 
); 
1689     DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour 
); 
1690     DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour 
); 
1691     DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour 
); 
1694 void wxTextCtrl::OnPaint( wxPaintEvent 
&event 
) 
1698     if (m_lines
.GetCount() == 0) return; 
1702     dc
.SetFont( m_sourceFont 
); 
1705     GetViewStart( NULL
, &scroll_y 
); 
1707     // We have a inner border of two pixels 
1708     // around the text, so scroll units do 
1709     // not correspond to lines. 
1710     if (scroll_y 
> 0) scroll_y
--; 
1714     GetClientSize( &size_x
, &size_y 
); 
1716     dc
.SetPen( *wxTRANSPARENT_PEN 
); 
1717     dc
.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT
), wxSOLID 
) ); 
1718     int upper 
= wxMin( (int)m_lines
.GetCount(), scroll_y
+(size_y
/m_lineHeight
)+2 ); 
1719     for (int i 
= scroll_y
; i 
< upper
; i
++) 
1722         int y 
= i
*m_lineHeight
+2; 
1724         int h 
= m_lineHeight
; 
1725         CalcScrolledPosition( x
,y
,&x
,&y 
); 
1726         if (IsExposed(x
,y
,w
,h
)) 
1727             DrawLine( dc
, 0+2, i
*m_lineHeight
+2, m_lines
[i
].m_text
, i 
); 
1730     if (m_editable 
&& (FindFocus() == this)) 
1732         ///dc.SetBrush( *wxRED_BRUSH ); 
1733         dc
.SetBrush( *wxBLACK_BRUSH 
); 
1734         // int xx = m_cursorX*m_charWidth; 
1735         int xx 
= PosToPixel( m_cursorY
, m_cursorX 
); 
1736         dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight 
); 
1740 void wxTextCtrl::OnMouse( wxMouseEvent 
&event 
) 
1742     if (m_lines
.GetCount() == 0) return; 
1745 #if 0  // there is no middle button on iPAQs 
1746     if (event
.MiddleDown()) 
1753     if (event
.LeftDClick()) 
1759     if (event
.LeftDown()) 
1767         m_capturing 
= false; 
1771     if (event
.LeftDown() || 
1772         (event
.LeftIsDown() && m_capturing
)) 
1774         int x 
= event
.GetX(); 
1775         int y 
= event
.GetY(); 
1776         CalcUnscrolledPosition( x
, y
, &x
, &y 
); 
1778         // x /= m_charWidth; 
1779         x 
= PixelToPos( y
, x 
); 
1781             wxMin( 1000, wxMax( 0, x 
) ), 
1782             wxMin( (int)m_lines
.GetCount()-1, wxMax( 0, y 
) ), 
1783             event
.ShiftDown() || !event
.LeftDown() ); 
1787 void wxTextCtrl::OnChar( wxKeyEvent 
&event 
) 
1789     if (m_lines
.GetCount() == 0) return; 
1791     if (!m_editable
) return; 
1795     GetClientSize( &size_x
, &size_y 
); 
1796     size_x 
/= m_charWidth
; 
1797     size_y 
/= m_lineHeight
; 
1800     if (event
.ShiftDown()) 
1802         switch (event
.GetKeyCode()) 
1804             case '4': event
.m_keyCode 
= WXK_LEFT
;     break; 
1805             case '8': event
.m_keyCode 
= WXK_UP
;       break; 
1806             case '6': event
.m_keyCode 
= WXK_RIGHT
;    break; 
1807             case '2': event
.m_keyCode 
= WXK_DOWN
;     break; 
1808             case '9': event
.m_keyCode 
= WXK_PAGEUP
;   break; 
1809             case '3': event
.m_keyCode 
= WXK_PAGEDOWN
; break; 
1810             case '7': event
.m_keyCode 
= WXK_HOME
;     break; 
1811             case '1': event
.m_keyCode 
= WXK_END
;      break; 
1812             case '0': event
.m_keyCode 
= WXK_INSERT
;   break; 
1816     switch (event
.GetKeyCode()) 
1820             if (m_ignoreInput
) return; 
1822                 MoveCursor( m_cursorX
, m_cursorY
-1, event
.ShiftDown() ); 
1823             m_ignoreInput 
= true; 
1828             if (m_ignoreInput
) return; 
1829             if (m_cursorY 
< (int)(m_lines
.GetCount()-1)) 
1830                 MoveCursor( m_cursorX
, m_cursorY
+1, event
.ShiftDown() ); 
1831             m_ignoreInput 
= true; 
1836             if (m_ignoreInput
) return; 
1839                 MoveCursor( m_cursorX
-1, m_cursorY
, event
.ShiftDown() ); 
1844                     MoveCursor( m_lines
[m_cursorY
-1].m_text
.Len(), m_cursorY
-1, event
.ShiftDown() ); 
1846             m_ignoreInput 
= true; 
1851             if (m_ignoreInput
) return; 
1852             if (m_cursorX 
< 1000) 
1853                 MoveCursor( m_cursorX
+1, m_cursorY
, event
.ShiftDown() ); 
1854             m_ignoreInput 
= true; 
1859             if (event
.ControlDown()) 
1860                 MoveCursor( 0, 0, event
.ShiftDown() ); 
1862                 MoveCursor( 0, m_cursorY
, event
.ShiftDown() ); 
1867             if (event
.ControlDown()) 
1868                 MoveCursor( 0, m_lines
.GetCount()-1, event
.ShiftDown() ); 
1870                 MoveCursor( m_lines
[m_cursorY
].m_text
.Len(), m_cursorY
, event
.ShiftDown() ); 
1875             if (m_ignoreInput
) return; 
1876             MoveCursor( m_cursorX
, wxMin( (int)(m_lines
.GetCount()-1), m_cursorY
+size_y 
), event
.ShiftDown() ); 
1877             m_ignoreInput 
= true; 
1882             if (m_ignoreInput
) return; 
1883             MoveCursor( m_cursorX
, wxMax( 0, m_cursorY
-size_y 
), event
.ShiftDown() ); 
1884             m_ignoreInput 
= true; 
1889             if (event
.ShiftDown()) 
1891             else if (event
.ControlDown()) 
1894                 m_overwrite 
= !m_overwrite
; 
1899             if (m_windowStyle 
& wxTE_PROCESS_ENTER
) 
1901                 wxCommandEvent 
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
); 
1902                 event
.SetEventObject(this); 
1903                 event
.SetString(GetValue()); 
1904                 if (HandleWindowEvent(event
)) return; 
1922             bool save_overwrite 
= m_overwrite
; 
1923             m_overwrite 
= false; 
1924             int i 
= 4-(m_cursorX 
% 4); 
1926             for (int c 
= 0; c 
< i
; c
++) 
1928             m_overwrite 
= save_overwrite
; 
1949             if (  (event
.GetKeyCode() >= 'a') && 
1950                   (event
.GetKeyCode() <= 'z') && 
1958             if (  (event
.GetKeyCode() >= 32) && 
1959                   (event
.GetKeyCode() <= 255) && 
1960                  !(event
.ControlDown() && !event
.AltDown()) ) // filters out Ctrl-X but leaves Alt-Gr 
1964                 DoChar( (char) event
.GetKeyCode() ); 
1973 void wxTextCtrl::OnInternalIdle() 
1975     wxControl::OnInternalIdle(); 
1977     m_ignoreInput 
= false; 
1979     if (m_lang 
!= wxSOURCE_LANG_NONE
) 
1980         SearchForBrackets(); 
1983 void wxTextCtrl::Indent() 
1985     int startY 
= m_cursorY
; 
1986     int endY 
= m_cursorY
; 
1989         startY 
= m_selStartY
; 
1999     m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) ); 
2001     for (int i 
= startY
; i 
<= endY
; i
++) 
2003         m_lines
[i
].m_text
.insert( 0u, wxT("    ") ); 
2008 void wxTextCtrl::Unindent() 
2010     int startY 
= m_cursorY
; 
2011     int endY 
= m_cursorY
; 
2014         startY 
= m_selStartY
; 
2024     m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) ); 
2026     for (int i 
= startY
; i 
<= endY
; i
++) 
2028         for (int n 
= 0; n 
< 4; n
++) 
2030             if (m_lines
[i
].m_text
[0u] == wxT(' ')) 
2031                 m_lines
[i
].m_text
.erase(0u,1u); 
2036 bool wxTextCtrl::HasSelection() 
2038     return ((m_selStartY 
!= m_selEndY
) || (m_selStartX 
!= m_selEndX
)); 
2041 void wxTextCtrl::ClearSelection() 
2049 void wxTextCtrl::RefreshLine( int n 
) 
2051     int y 
= n
*m_lineHeight
; 
2053     CalcScrolledPosition( x
, y
, &x
, &y 
); 
2054     wxRect 
rect( 0+2, y
+2, 10000, m_lineHeight 
); 
2055     Refresh( true, &rect 
); 
2058 void wxTextCtrl::RefreshDown( int n 
) 
2062     GetClientSize( &size_x
, &size_y 
); 
2066     GetViewStart( &view_x
, &view_y 
); 
2074         int y 
= n
*m_lineHeight
; 
2076         CalcScrolledPosition( x
, y
, &x
, &y 
); 
2078         wxRect 
rect( 0+2, y
+2, 10000, size_y 
); 
2079         Refresh( true, &rect 
); 
2083 void wxTextCtrl::MoveCursor( int new_x
, int new_y
, bool shift
, bool centre 
) 
2085     if (!m_editable
) return; 
2087     // if (IsSingleLine() || (m_lang == wxSOURCE_LANG_NONE)) 
2089         if (new_x 
> (int) (m_lines
[new_y
].m_text
.Len())) 
2090             new_x 
= m_lines
[new_y
].m_text
.Len(); 
2093     if ((new_x 
== m_cursorX
) && (new_y 
== m_cursorY
)) return; 
2095     bool no_cursor_refresh 
= false; 
2096     bool has_selection 
= HasSelection(); 
2101         bool erase_background 
= true; 
2105             m_selStartX 
= m_cursorX
; 
2106             m_selStartY 
= m_cursorY
; 
2110             if (new_y 
> m_selStartY
) 
2112                 y 
= m_selStartY
*m_lineHeight
; 
2113                 h 
= (new_y
-m_selStartY
+1)*m_lineHeight
; 
2115             else if (new_y 
== m_selStartY
) 
2117                 x 
= PosToPixel( new_y
, m_selStartX 
); 
2118                 w 
= PosToPixel( new_y
, new_x 
) - x
; 
2122                     w 
= -w 
+ 2; // +2 for the cursor 
2124                 y 
= m_selStartY
*m_lineHeight
; 
2129                 y 
= new_y
*m_lineHeight
; 
2130                 h 
= (-new_y
+m_selStartY
+1)*m_lineHeight
; 
2133             no_cursor_refresh 
= true; 
2139             if (new_y 
== m_selEndY
) 
2141                 y 
= new_y 
*m_lineHeight
; 
2143                 if (m_selEndX 
> new_x
) 
2145                     // x = new_x*m_charWidth; 
2146                     x 
= PosToPixel( new_y
, new_x 
); 
2147                     // w = (m_selEndX-new_x)*m_charWidth; 
2148                     w 
= PosToPixel( new_y
, m_selEndX 
) - x
; 
2152                     // x = m_selEndX*m_charWidth; 
2153                     x 
= PosToPixel( new_y
, m_selEndX 
); 
2154                     // w = (-m_selEndX+new_x)*m_charWidth; 
2155                     w 
= PosToPixel( new_y
, new_x 
) - x
; 
2162                 if (new_y 
> m_selEndY
) 
2164                     y 
= m_selEndY
*m_lineHeight
; 
2165                     h 
= (new_y
-m_selEndY
+1) * m_lineHeight
; 
2167                     erase_background 
= ((m_selEndY 
< m_selStartY
) || 
2168                                         ((m_selEndY 
== m_selStartY
) && (m_selEndX 
< m_selStartX
))); 
2172                     y 
= new_y
*m_lineHeight
; 
2173                     h 
= (-new_y
+m_selEndY
+1) * m_lineHeight
; 
2175                     erase_background 
= ((m_selEndY 
> m_selStartY
) || 
2176                                         ((m_selEndY 
== m_selStartY
) && (m_selEndX 
> m_selStartX
))); 
2178                 no_cursor_refresh 
= true; 
2187         CalcScrolledPosition( x
, y
, &x
, &y 
); 
2188         wxRect 
rect( x
+2, y
+2, w
, h 
); 
2189         Refresh( erase_background
, &rect 
); 
2195             int ry1 
= m_selEndY
; 
2196             int ry2 
= m_selStartY
; 
2210             int y 
= ry1
*m_lineHeight
; 
2211             CalcScrolledPosition( x
, y
, &x
, &y 
); 
2212             wxRect 
rect( 0, y
+2, 10000, (ry2
-ry1
+1)*m_lineHeight 
); 
2214             Refresh( true, &rect 
); 
2219     printf( "startx %d starty %d endx %d endy %d\n", 
2220             m_selStartX, m_selStartY, m_selEndX, m_selEndY ); 
2222     printf( "has %d\n", (int)HasSelection() ); 
2225     if (!no_cursor_refresh
) 
2227         // int x = m_cursorX*m_charWidth; 
2228         int x 
= PosToPixel( m_cursorY
, m_cursorX 
); 
2229         int y 
= m_cursorY
*m_lineHeight
; 
2230         CalcScrolledPosition( x
, y
, &x
, &y 
); 
2231         wxRect 
rect( x
+2, y
+2, 4, m_lineHeight
+2 ); 
2236         Refresh( true, &rect 
); 
2238         if (FindFocus() == this) 
2240             wxClientDC 
dc(this); 
2242             dc
.SetPen( *wxTRANSPARENT_PEN 
); 
2243             //dc.SetBrush( *wxRED_BRUSH ); 
2244             dc
.SetBrush( *wxBLACK_BRUSH 
); 
2245             // int xx = m_cursorX*m_charWidth; 
2246             int xx 
= PosToPixel( m_cursorY
, m_cursorX 
); 
2247             dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight 
); 
2253     GetClientSize( &size_x
, &size_y 
); 
2254     size_x 
/= m_charWidth
; 
2255     size_y 
/= m_lineHeight
; 
2259     GetViewStart( &view_x
, &view_y 
); 
2263         int sy 
= m_cursorY 
- (size_y
/2); 
2269         if (m_cursorY 
< view_y
) 
2270             Scroll( -1, m_cursorY 
); 
2271         else if (m_cursorY 
> view_y
+size_y
-1) 
2272             Scroll( -1, m_cursorY
-size_y
+1 ); 
2275     //int xx = m_cursorX; 
2276     int xx 
= PosToPixel( m_cursorY
, m_cursorX 
) / m_charWidth
; 
2280     else if (xx 
> view_x
+size_x
-1) 
2281         Scroll( xx
-size_x
+1, -1 ); 
2284 void wxTextCtrl::MyAdjustScrollbars() 
2289     int y_range 
= m_lines
.GetCount(); 
2292     GetClientSize( NULL
, &height 
); 
2294     if (height 
>= (int)m_lines
.GetCount() *m_lineHeight
) 
2299     GetViewStart( &view_x
, &view_y 
); 
2301     SetScrollbars( m_charWidth
, m_lineHeight
, m_longestLine
+2, y_range
, view_x
, view_y 
); 
2304 //----------------------------------------------------------------------------- 
2305 //  clipboard handlers 
2306 //----------------------------------------------------------------------------- 
2308 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
)) 
2313 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
)) 
2318 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
)) 
2323 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
2328 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
2333 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
) 
2335     event
.Enable( CanCut() ); 
2338 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
) 
2340     event
.Enable( CanCopy() ); 
2343 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
) 
2345     event
.Enable( CanPaste() ); 
2348 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
) 
2350     event
.Enable( CanUndo() ); 
2353 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
) 
2355     event
.Enable( CanRedo() ); 
2358 wxSize 
wxTextCtrl::DoGetBestSize() const 
2362         wxSize 
ret(80, m_lineHeight 
+ 4); 
2364         if (HasFlag(wxBORDER_SUNKEN
) || HasFlag(wxBORDER_RAISED
)) 
2367         if (HasFlag(wxBORDER_SIMPLE
)) 
2374         return wxSize(80, 60); 
2378 void wxTextCtrl::OnSetFocus( wxFocusEvent
& event 
) 
2380     // To hide or show caret, as appropriate 
2384 void wxTextCtrl::OnKillFocus( wxFocusEvent
& event 
) 
2386     // To hide or show caret, as appropriate 
2390 // ---------------------------------------------------------------------------- 
2391 // text control scrolling 
2392 // ---------------------------------------------------------------------------- 
2394 bool wxTextCtrl::ScrollLines(int lines
) 
2396     wxFAIL_MSG( "wxTextCtrl::ScrollLines not implemented"); 
2401 bool wxTextCtrl::ScrollPages(int pages
) 
2403     wxFAIL_MSG( "wxTextCtrl::ScrollPages not implemented");