1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "textctrl.h"
14 #include "wx/textctrl.h"
18 #include "wx/settings.h"
20 #include "wx/clipbrd.h"
21 #include "wx/tokenzr.h"
23 #include "wx/univ/inphand.h"
24 #include "wx/univ/renderer.h"
25 #include "wx/univ/colschem.h"
26 #include "wx/univ/theme.h"
28 //-----------------------------------------------------------------------------
30 //-----------------------------------------------------------------------------
32 wxSourceUndoStep::wxSourceUndoStep( wxSourceUndo type
, int y1
, int y2
, wxTextCtrl
*owner
)
39 m_cursorX
= m_owner
->GetCursorX();
40 m_cursorY
= m_owner
->GetCursorY();
42 if (m_type
== wxSOURCE_UNDO_LINE
)
44 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
46 if (m_type
== wxSOURCE_UNDO_ENTER
)
48 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
50 if (m_type
== wxSOURCE_UNDO_BACK
)
52 for (int i
= m_y1
; i
< m_y2
+2; i
++)
54 if (i
>= (int)m_owner
->m_lines
.GetCount())
57 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
60 if (m_type
== wxSOURCE_UNDO_DELETE
)
62 for (int i
= m_y1
; i
< m_y2
+1; i
++)
64 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
67 if (m_type
== wxSOURCE_UNDO_PASTE
)
69 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
73 void wxSourceUndoStep::Undo()
75 if (m_type
== wxSOURCE_UNDO_LINE
)
77 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
78 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
79 m_owner
->RefreshLine( m_y1
);
81 if (m_type
== wxSOURCE_UNDO_ENTER
)
83 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
84 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
85 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
86 m_owner
->RefreshDown( m_y1
);
88 if (m_type
== wxSOURCE_UNDO_BACK
)
90 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
91 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[1] ), m_y1
+1 );
92 m_owner
->MyAdjustScrollbars();
93 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
94 m_owner
->RefreshDown( m_y1
);
96 if (m_type
== wxSOURCE_UNDO_DELETE
)
98 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
99 for (int i
= 1; i
< (int)m_lines
.GetCount(); i
++)
100 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[i
] ), m_y1
+i
);
101 m_owner
->MyAdjustScrollbars();
102 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
103 m_owner
->RefreshDown( m_y1
);
105 if (m_type
== wxSOURCE_UNDO_PASTE
)
107 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
108 for (int i
= 0; i
< m_y2
-m_y1
; i
++)
109 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
110 m_owner
->MyAdjustScrollbars();
111 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
112 m_owner
->RefreshDown( m_y1
);
114 if (m_type
== wxSOURCE_UNDO_INSERT_LINE
)
116 m_owner
->m_lines
.RemoveAt( m_y1
);
117 m_owner
->MyAdjustScrollbars();
118 m_owner
->MoveCursor( 0, m_y1
);
119 m_owner
->RefreshDown( m_y1
);
123 #include "wx/arrimpl.cpp"
124 WX_DEFINE_OBJARRAY(wxSourceLineArray
);
126 //-----------------------------------------------------------------------------
128 //-----------------------------------------------------------------------------
130 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
,wxControl
)
132 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
133 EVT_PAINT(wxTextCtrl::OnPaint
)
134 EVT_CHAR(wxTextCtrl::OnChar
)
135 EVT_MOUSE_EVENTS(wxTextCtrl::OnMouse
)
136 EVT_IDLE(wxTextCtrl::OnIdle
)
138 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
139 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
140 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
141 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
142 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
144 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
145 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
146 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
147 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
148 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
151 void wxTextCtrl::Init()
156 m_sourceFont
= wxFont( 12, wxMODERN
, wxNORMAL
, wxNORMAL
);
158 m_undos
.DeleteContents( TRUE
);
160 m_lang
= wxSOURCE_LANG_NONE
;
165 dc
.SetFont( m_sourceFont
);
166 m_lineHeight
= dc
.GetCharHeight();
167 m_charWidth
= dc
.GetCharWidth();
178 m_ignoreInput
= FALSE
;
182 m_keywordColour
= wxColour( 10, 140, 10 );
184 m_defineColour
= *wxRED
;
186 m_variableColour
= wxColour( 50, 120, 150 );
188 m_commentColour
= wxColour( 130, 130, 130 );
190 m_stringColour
= wxColour( 10, 140, 10 );
193 wxTextCtrl::wxTextCtrl( wxWindow
*parent
,
195 const wxString
&value
,
199 const wxValidator
& validator
,
200 const wxString
&name
)
201 : wxScrollHelper(this)
205 Create( parent
, id
, value
, pos
, size
, style
, validator
, name
);
208 bool wxTextCtrl::Create( wxWindow
*parent
,
210 const wxString
&value
,
214 const wxValidator
& validator
,
215 const wxString
&name
)
217 if ((style
& wxBORDER_MASK
) == 0)
218 style
|= wxBORDER_SUNKEN
;
220 if ((style
& wxTE_MULTILINE
) != 0)
221 style
|= wxALWAYS_SHOW_SB
;
223 wxTextCtrlBase::Create( parent
, id
, wxDefaultPosition
, size
,
224 style
|wxVSCROLL
|wxHSCROLL
|wxNO_FULL_REPAINT_ON_RESIZE
);
226 SetBackgroundColour( *wxWHITE
);
228 SetCursor( wxCursor( wxCURSOR_IBEAM
) );
232 wxSize
size_best( DoGetBestSize() );
233 wxSize
new_size( size
);
234 if (new_size
.x
== -1)
235 new_size
.x
= size_best
.x
;
236 if (new_size
.y
== -1)
237 new_size
.y
= size_best
.y
;
238 if ((new_size
.x
!= size
.x
) || (new_size
.y
!= size
.y
))
239 SetSize( new_size
.x
, new_size
.y
);
241 // We create an input handler since it might be useful
242 CreateInputHandler(wxINP_HANDLER_TEXTCTRL
);
247 //-----------------------------------------------------------------------------
249 //-----------------------------------------------------------------------------
251 wxString
wxTextCtrl::GetValue() const
254 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
256 ret
+= m_lines
[i
].m_text
;
257 if (i
< m_lines
.GetCount())
264 void wxTextCtrl::SetValue(const wxString
& value
)
275 m_lines
.Add( new wxSourceLine( wxT("") ) );
283 pos
= value
.find( wxT('\n'), begin
);
286 if (value
.Len()-begin
> m_longestLine
)
287 m_longestLine
= value
.Len()-begin
;
289 m_lines
.Add( new wxSourceLine( value
.Mid( begin
, value
.Len()-begin
) ) );
295 if (pos
-begin
> m_longestLine
)
296 m_longestLine
= pos
-begin
;
298 m_lines
.Add( new wxSourceLine( value
.Mid( begin
, pos
-begin
) ) );
305 MyAdjustScrollbars();
310 int wxTextCtrl::GetLineLength(long lineNo
) const
312 if (lineNo
>= (long)m_lines
.GetCount())
315 return m_lines
[lineNo
].m_text
.Len();
318 wxString
wxTextCtrl::GetLineText(long lineNo
) const
320 if (lineNo
>= (long)m_lines
.GetCount())
323 return m_lines
[lineNo
].m_text
;
326 int wxTextCtrl::GetNumberOfLines() const
328 return m_lines
.GetCount();
331 bool wxTextCtrl::IsModified() const
336 bool wxTextCtrl::IsEditable() const
341 void wxTextCtrl::GetSelection(long* from
, long* to
) const
345 void wxTextCtrl::Clear()
353 m_lines
.Add( new wxSourceLine( wxT("") ) );
355 SetScrollbars( m_charWidth
, m_lineHeight
, 0, 0, 0, 0 );
360 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
364 void wxTextCtrl::Remove(long from
, long to
)
369 void wxTextCtrl::DiscardEdits()
375 void wxTextCtrl::SetMaxLength(unsigned long len
)
379 void wxTextCtrl::WriteText(const wxString
& text2
)
381 if (text2
.IsEmpty()) return;
385 wxString
text( text2
);
388 while ( (pos
= text
.Find('\n')) != -1 )
390 lines
.Add( text
.Left( pos
) );
391 text
.Remove( 0, pos
+1 );
394 int count
= (int)lines
.GetCount();
396 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
397 wxString
tmp2( tmp1
);
398 int len
= (int)tmp1
.Len();
403 for (int i
= 0; i
< m_cursorX
-len
; i
++)
405 m_lines
[m_cursorY
].m_text
.Append( tmp
);
410 tmp1
.Remove( m_cursorX
);
411 tmp2
.Remove( 0, m_cursorX
);
412 tmp1
.Append( lines
[0] );
416 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
419 m_lines
[m_cursorY
].m_text
= tmp1
;
420 RefreshLine( m_cursorY
);
424 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
426 m_lines
[m_cursorY
].m_text
= tmp1
;
428 for (i
= 1; i
< count
; i
++)
429 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
430 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
432 MyAdjustScrollbars();
433 RefreshDown( m_cursorY
);
437 void wxTextCtrl::AppendText(const wxString
& text2
)
439 if (text2
.IsEmpty()) return;
443 wxString
text( text2
);
446 while ( (pos
= text
.Find('\n')) != -1 )
448 lines
.Add( text
.Left( pos
) );
449 text
.Remove( 0, pos
+1 );
452 int count
= (int)lines
.GetCount();
454 size_t y
= m_lines
.GetCount()-1;
456 wxString
tmp( m_lines
[y
].m_text
);
457 tmp
.Append( lines
[0] );
461 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, y
, y
, this ) );
463 m_lines
[y
].m_text
= tmp
;
468 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, y
, y
+count
-1, this ) );
470 m_lines
[y
].m_text
= tmp
;
472 for (i
= 1; i
< count
; i
++)
473 m_lines
.Insert( new wxSourceLine( lines
[i
] ), y
+i
);
475 MyAdjustScrollbars();
480 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
485 long wxTextCtrl::XYToPosition(long x
, long y
) const
489 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
493 ret
+= m_lines
[i
].m_text
.Len();
497 if ((size_t)x
< m_lines
[i
].m_text
.Len())
500 return (ret
+ m_lines
[i
].m_text
.Len());
506 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
508 if (m_lines
.GetCount() == 0)
519 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
521 pos
-= m_lines
[i
].m_text
.Len();
533 xx
= m_lines
[ m_lines
.GetCount()-1 ].m_text
.Len();
540 void wxTextCtrl::ShowPosition(long pos
)
544 void wxTextCtrl::Copy()
546 if (!HasSelection()) return;
550 int selStartY
= m_selStartY
;
551 int selEndY
= m_selEndY
;
552 int selStartX
= m_selStartX
;
553 int selEndX
= m_selEndX
;
555 if ((selStartY
> selEndY
) ||
556 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
566 if (selStartY
== selEndY
)
568 sel
= m_lines
[selStartY
].m_text
;
570 if (selStartX
>= (int)sel
.Len()) return;
571 if (selEndX
> (int)sel
.Len())
574 sel
.Remove( selEndX
, sel
.Len()-selEndX
);
575 sel
.Remove( 0, selStartX
);
579 wxString
tmp( m_lines
[selStartY
].m_text
);
581 if (selStartX
< (int)tmp
.Len())
583 tmp
.Remove( 0, selStartX
);
587 for (int i
= selStartY
+1; i
< selEndY
; i
++)
589 sel
.Append( m_lines
[i
].m_text
);
592 tmp
= m_lines
[selEndY
].m_text
;
593 if (selEndX
> (int)tmp
.Len())
597 tmp
.Remove( selEndX
, tmp
.Len()-selEndX
);
602 if (wxTheClipboard
->Open())
604 wxTheClipboard
->SetData( new wxTextDataObject( sel
) );
605 wxTheClipboard
->Close();
609 void wxTextCtrl::Cut()
616 void wxTextCtrl::Paste()
620 if (!wxTheClipboard
->Open()) return;
622 if (!wxTheClipboard
->IsSupported( wxDF_TEXT
))
624 wxTheClipboard
->Close();
629 wxTextDataObject data
;
631 bool ret
= wxTheClipboard
->GetData( data
);
633 wxTheClipboard
->Close();
639 wxString
text( data
.GetText() );
642 while ( (pos
= text
.Find('\n')) != -1 )
644 lines
.Add( text
.Left( pos
) );
645 text
.Remove( 0, pos
+1 );
648 int count
= (int)lines
.GetCount();
650 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
651 wxString
tmp2( tmp1
);
652 int len
= (int)tmp1
.Len();
657 for (int i
= 0; i
< m_cursorX
-len
; i
++)
659 m_lines
[m_cursorY
].m_text
.Append( tmp
);
664 tmp1
.Remove( m_cursorX
);
665 tmp2
.Remove( 0, m_cursorX
);
666 tmp1
.Append( lines
[0] );
670 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
673 m_lines
[m_cursorY
].m_text
= tmp1
;
674 RefreshLine( m_cursorY
);
678 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
680 m_lines
[m_cursorY
].m_text
= tmp1
;
682 for (i
= 1; i
< count
; i
++)
683 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
684 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
686 MyAdjustScrollbars();
687 RefreshDown( m_cursorY
);
691 void wxTextCtrl::Undo()
693 if (m_undos
.GetCount() == 0) return;
695 wxNode
*node
= m_undos
.Nth( m_undos
.GetCount()-1 );
696 wxSourceUndoStep
*undo
= (wxSourceUndoStep
*) node
->Data();
705 void wxTextCtrl::SetInsertionPoint(long pos
)
709 void wxTextCtrl::SetInsertionPointEnd()
713 long wxTextCtrl::GetInsertionPoint() const
715 return XYToPosition( m_cursorX
, m_cursorY
);
718 long wxTextCtrl::GetLastPosition() const
720 size_t lineCount
= m_lines
.GetCount() - 1;
721 return XYToPosition( m_lines
[lineCount
].m_text
.Len()-1, lineCount
);
724 void wxTextCtrl::SetSelection(long from
, long to
)
728 void wxTextCtrl::SetEditable(bool editable
)
730 m_editable
= editable
;
733 bool wxTextCtrl::Enable( bool enable
)
738 bool wxTextCtrl::SetFont(const wxFont
& font
)
743 bool wxTextCtrl::SetForegroundColour(const wxColour
& colour
)
745 return wxWindow::SetForegroundColour( colour
);
748 bool wxTextCtrl::SetBackgroundColour(const wxColour
& colour
)
750 return wxWindow::SetBackgroundColour( colour
);
753 //-----------------------------------------------------------------------------
754 // private code and handlers
755 //-----------------------------------------------------------------------------
757 void wxTextCtrl::SearchForBrackets()
759 int oldBracketY
= m_bracketY
;
760 int oldBracketX
= m_bracketX
;
762 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()) return;
764 wxString current
= m_lines
[m_cursorY
].m_text
;
766 // reverse search first
771 bracket
= current
[m_cursorX
-1];
773 if (bracket
== ')' || bracket
== ']' || bracket
== '}')
775 char antibracket
= '(';
776 if (bracket
== ']') antibracket
= '[';
777 if (bracket
== '}') antibracket
= '{';
781 int endY
= m_cursorY
-60;
782 if (endY
< 0) endY
= 0;
783 for (int y
= m_cursorY
; y
>= endY
; y
--)
785 current
= m_lines
[y
].m_text
;
787 current
.erase(m_cursorX
-1,current
.Len()-m_cursorX
+1);
789 for (int n
= current
.Len()-1; n
>= 0; n
--)
792 if (current
[n
] == '\'')
794 for (int m
= n
-1; m
>= 0; m
--)
796 if (current
[m
] == '\'')
798 if (m
== 0 || current
[m
-1] != '\\')
807 if (current
[n
] == '\"')
809 for (int m
= n
-1; m
>= 0; m
--)
811 if (current
[m
] == '\"')
813 if (m
== 0 || current
[m
-1] != '\\')
821 if (current
[n
] == antibracket
)
828 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
829 RefreshLine( oldBracketY
);
830 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
831 RefreshLine( m_bracketY
);
835 else if (current
[n
] == bracket
)
846 if ((int)current
.Len() > m_cursorX
)
847 bracket
= current
[m_cursorX
];
848 if (bracket
== '(' || bracket
== '[' || bracket
== '{')
850 char antibracket
= ')';
851 if (bracket
== '[') antibracket
= ']';
852 if (bracket
== '{') antibracket
= '}';
856 int endY
= m_cursorY
+60;
857 if (endY
> (int)(m_lines
.GetCount()-1)) endY
= m_lines
.GetCount()-1;
858 for (int y
= m_cursorY
; y
<= endY
; y
++)
860 current
= m_lines
[y
].m_text
;
865 for (int n
= start
; n
< (int)current
.Len(); n
++)
868 if (current
[n
] == '\'')
870 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
872 if (current
[m
] == '\'')
874 if (m
== 0 || (current
[m
-1] != '\\') || (m
>= 2 && current
[m
-2] == '\\'))
883 if (current
[n
] == '\"')
885 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
887 if (current
[m
] == '\"')
889 if (m
== 0 || (current
[m
-1] != '\\') || (m
>= 2 && current
[m
-2] == '\\'))
897 if (current
[n
] == antibracket
)
904 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
905 RefreshLine( oldBracketY
);
906 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
907 RefreshLine( m_bracketY
);
911 else if (current
[n
] == bracket
)
919 if (oldBracketY
!= -1)
922 RefreshLine( oldBracketY
);
926 void wxTextCtrl::Delete()
928 if (!HasSelection()) return;
932 int selStartY
= m_selStartY
;
933 int selEndY
= m_selEndY
;
934 int selStartX
= m_selStartX
;
935 int selEndX
= m_selEndX
;
937 if ((selStartY
> selEndY
) ||
938 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
948 int len
= (int)m_lines
[selStartY
].m_text
.Len();
950 if (selStartY
== selEndY
)
952 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, selStartY
, selStartY
, this ) );
954 wxString
tmp( m_lines
[selStartY
].m_text
);
959 tmp
.Remove( selStartX
, selEndX
-selStartX
);
960 m_lines
[selStartY
].m_text
= tmp
;
963 m_cursorX
= selStartX
;
964 RefreshLine( selStartY
);
968 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, selStartY
, selEndY
, this ) );
971 m_lines
[selStartY
].m_text
.Remove( selStartX
);
973 for (int i
= 0; i
< selEndY
-selStartY
-1; i
++)
974 m_lines
.RemoveAt( selStartY
+1 );
976 if (selEndX
< (int)m_lines
[selStartY
+1].m_text
.Len())
977 m_lines
[selStartY
+1].m_text
.Remove( 0, selEndX
);
979 m_lines
[selStartY
+1].m_text
.Remove( 0 );
981 m_lines
[selStartY
].m_text
.Append( m_lines
[selStartY
+1].m_text
);
982 m_lines
.RemoveAt( selStartY
+1 );
985 MoveCursor( selStartX
, selStartY
);
986 MyAdjustScrollbars();
988 RefreshDown( selStartY
);
992 void wxTextCtrl::DeleteLine()
994 if (HasSelection()) return;
996 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()-1) return; // TODO
998 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1000 m_lines
.RemoveAt( m_cursorY
);
1002 if (m_cursorY
>= (int)m_lines
.GetCount()) m_cursorY
--;
1004 MyAdjustScrollbars();
1005 RefreshDown( m_cursorY
);
1008 void wxTextCtrl::DoChar( char c
)
1012 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1014 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1016 if (m_cursorX
>= (int)tmp
.Len())
1018 int len
= tmp
.Len();
1019 for (int i
= 0; i
< m_cursorX
- len
; i
++)
1026 tmp
.SetChar( m_cursorX
, c
);
1028 tmp
.insert( m_cursorX
, 1, c
);
1031 m_lines
[m_cursorY
].m_text
= tmp
;
1033 if (tmp
.Len() > m_longestLine
)
1035 m_longestLine
= tmp
.Len();
1036 MyAdjustScrollbars();
1041 int y
= m_cursorY
*m_lineHeight
;
1042 int x
= (m_cursorX
-1)*m_charWidth
;
1043 CalcScrolledPosition( x
, y
, &x
, &y
);
1044 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1045 Refresh( TRUE
, &rect
);
1049 GetClientSize( &size_x
, &size_y
);
1050 size_x
/= m_charWidth
;
1054 GetViewStart( &view_x
, &view_y
);
1056 if (m_cursorX
< view_x
)
1057 Scroll( m_cursorX
, -1 );
1058 else if (m_cursorX
> view_x
+size_x
-1)
1059 Scroll( m_cursorX
-size_x
+1, -1 );
1062 void wxTextCtrl::DoBack()
1068 if (m_cursorY
== 0) return;
1070 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_BACK
, m_cursorY
-1, m_cursorY
, this ) );
1072 wxString
tmp1( m_lines
[m_cursorY
-1].m_text
);
1074 wxString
tmp2( m_lines
[m_cursorY
].m_text
);
1076 m_cursorX
= tmp1
.Len();
1078 tmp1
.Append( tmp2
);
1079 m_lines
[m_cursorY
].m_text
= tmp1
;
1080 m_lines
.RemoveAt( m_cursorY
+1 );
1082 MyAdjustScrollbars();
1083 RefreshDown( m_cursorY
-1 );
1087 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1089 if (m_cursorX
<= (int)m_lines
[m_cursorY
].m_text
.Len())
1090 m_lines
[m_cursorY
].m_text
.Remove( m_cursorX
-1, 1 );
1093 int y
= m_cursorY
*m_lineHeight
;
1094 int x
= m_cursorX
*m_charWidth
;
1095 CalcScrolledPosition( x
, y
, &x
, &y
);
1096 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1097 Refresh( TRUE
, &rect
);
1101 void wxTextCtrl::DoDelete()
1105 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1107 int len
= (int)tmp
.Len();
1108 if (m_cursorX
>= len
)
1110 if (m_cursorY
== (int)m_lines
.GetCount()-1) return;
1112 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1114 for (int i
= 0; i
< (m_cursorX
-len
); i
++)
1117 tmp
+= m_lines
[m_cursorY
+1].m_text
;
1119 m_lines
[m_cursorY
] = tmp
;
1120 m_lines
.RemoveAt( m_cursorY
+1 );
1122 MyAdjustScrollbars();
1123 RefreshDown( m_cursorY
);
1127 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1129 tmp
.Remove( m_cursorX
, 1 );
1130 m_lines
[m_cursorY
].m_text
= tmp
;
1132 int y
= m_cursorY
*m_lineHeight
;
1133 int x
= m_cursorX
*m_charWidth
;
1134 CalcScrolledPosition( x
, y
, &x
, &y
);
1135 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1136 Refresh( TRUE
, &rect
);
1140 void wxTextCtrl::DoReturn()
1144 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_ENTER
, m_cursorY
, m_cursorY
, this ) );
1146 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1147 size_t indent
= tmp
.find_first_not_of( ' ' );
1148 if (indent
== wxSTRING_MAXLEN
) indent
= 0;
1150 if (m_cursorX
>= (int)tmp
.Len())
1152 int cursorX
= indent
;
1153 int cursorY
= m_cursorY
+ 1;
1156 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1157 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1159 MyAdjustScrollbars();
1160 MoveCursor( cursorX
, cursorY
);
1161 RefreshDown( m_cursorY
);
1165 wxString
tmp1( tmp
);
1166 tmp1
.Remove( m_cursorX
, tmp
.Len()-m_cursorX
);
1167 m_lines
[m_cursorY
].m_text
= tmp1
;
1169 wxString
tmp2( tmp
);
1170 tmp2
.Remove( 0, m_cursorX
);
1172 int cursorX
= indent
;
1173 int cursorY
= m_cursorY
+ 1;
1176 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1177 new_tmp
.Append( tmp2
);
1178 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1180 MyAdjustScrollbars();
1181 MoveCursor( cursorX
, cursorY
);
1182 RefreshDown( m_cursorY
-1 );
1186 void wxTextCtrl::DoDClick()
1188 wxString
line( m_lines
[ m_cursorY
].m_text
);
1189 if (m_cursorX
>= (int)line
.Len()) return;
1192 if (((ch
>= 'a') && (ch
<= 'z')) ||
1193 ((ch
>= 'A') && (ch
<= 'Z')) ||
1194 ((ch
>= '0') && (ch
<= '9')) ||
1197 m_selStartY
= m_cursorY
;
1198 m_selEndY
= m_cursorY
;
1202 while (((ch
>= 'a') && (ch
<= 'z')) ||
1203 ((ch
>= 'A') && (ch
<= 'Z')) ||
1204 ((ch
>= '0') && (ch
<= '9')) ||
1215 if (p
< (int)line
.Len())
1218 while (((ch
>= 'a') && (ch
<= 'z')) ||
1219 ((ch
>= 'A') && (ch
<= 'Z')) ||
1220 ((ch
>= '0') && (ch
<= '9')) ||
1223 if (p
>= (int)line
.Len()) break;
1229 RefreshLine( m_cursorY
);
1233 wxString
wxTextCtrl::GetNextToken( wxString
&line
, int &pos
)
1236 int len
= (int)line
.Len();
1237 for (int p
= pos
; p
< len
; p
++)
1239 if ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
))
1243 for (int q
= p
; q
< len
; q
++)
1244 ret
.Append( line
[q
] );
1251 if ((line
[p
] == '/') && (p
+1 < len
) && (line
[p
+1] == '/'))
1253 for (int q
= p
; q
< len
; q
++)
1254 ret
.Append( line
[q
] );
1262 ret
.Append( line
[p
] );
1263 for (int q
= p
+1; q
< len
; q
++)
1265 ret
.Append( line
[q
] );
1266 if ((line
[q
] == '"') && ((line
[q
-1] != '\\') || (q
>= 2 && line
[q
-2] == '\\')))
1273 if (line
[p
] == '\'')
1275 ret
.Append( line
[p
] );
1276 for (int q
= p
+1; q
< len
; q
++)
1278 ret
.Append( line
[q
] );
1279 if ((line
[q
] == '\'') && ((line
[q
-1] != '\\') || (q
>= 2 && line
[q
-2] == '\\')))
1286 if (((line
[p
] >= 'a') && (line
[p
] <= 'z')) ||
1287 ((line
[p
] >= 'A') && (line
[p
] <= 'Z')) ||
1291 ret
.Append( line
[p
] );
1292 for (int q
= p
+1; q
< len
; q
++)
1294 if (((line
[q
] >= 'a') && (line
[q
] <= 'z')) ||
1295 ((line
[q
] >= 'A') && (line
[q
] <= 'Z')) ||
1296 ((line
[q
] >= '0') && (line
[q
] <= '9')) ||
1299 ret
.Append( line
[q
] );
1316 void wxTextCtrl::DrawLine( wxDC
&dc
, int x
, int y
, const wxString
&line2
, int lineNum
)
1318 int selStartY
= m_selStartY
;
1319 int selEndY
= m_selEndY
;
1320 int selStartX
= m_selStartX
;
1321 int selEndX
= m_selEndX
;
1323 if ((selStartY
> selEndY
) ||
1324 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1326 int tmp
= selStartX
;
1327 selStartX
= selEndX
;
1330 selStartY
= selEndY
;
1334 wxString
line( line2
);
1335 if (HasFlag(wxTE_PASSWORD
))
1337 size_t len
= line
.Len();
1338 line
= wxString( wxT('*'), len
);
1341 wxString
keyword( ' ', line
.Len() );
1342 wxString
define( ' ', line
.Len() );
1343 wxString
variable( ' ', line
.Len() );
1344 wxString
comment( ' ', line
.Len() );
1345 wxString
my_string( ' ', line
.Len() );
1347 if (lineNum
== m_bracketY
)
1349 wxString
red( ' ', line
.Len() );
1350 if (m_bracketX
< (int)line
.Len())
1352 red
.SetChar( m_bracketX
, line
[m_bracketX
] );
1353 line
.SetChar( m_bracketX
, ' ' );
1354 dc
.SetTextForeground( *wxRED
);
1355 dc
.DrawText( red
, x
, y
);
1356 dc
.SetTextForeground( *wxBLACK
);
1361 wxString
token( GetNextToken( line
, pos
) );
1362 while (!token
.IsNull())
1364 if (m_keywords
.Index( token
) != wxNOT_FOUND
)
1366 int end_pos
= pos
+ (int)token
.Len();
1367 for (int i
= pos
; i
< end_pos
; i
++)
1369 keyword
.SetChar( i
, line
[i
] );
1370 line
.SetChar( i
, ' ' );
1373 if (m_defines
.Index( token
) != wxNOT_FOUND
)
1375 int end_pos
= pos
+ (int)token
.Len();
1376 for (int i
= pos
; i
< end_pos
; i
++)
1378 define
.SetChar( i
, line
[i
] );
1379 line
.SetChar( i
, ' ' );
1382 if ((m_variables
.Index( token
) != wxNOT_FOUND
) ||
1383 ((token
.Len() > 2) && (token
[0] == 'w') && (token
[1] == 'x')))
1385 int end_pos
= pos
+ (int)token
.Len();
1386 for (int i
= pos
; i
< end_pos
; i
++)
1388 variable
.SetChar( i
, line
[i
] );
1389 line
.SetChar( i
, ' ' );
1392 if ((token
.Len() >= 2) && (token
[0] == '/') && (token
[1] == '/') && (m_lang
== wxSOURCE_LANG_CPP
))
1394 int end_pos
= pos
+ (int)token
.Len();
1395 for (int i
= pos
; i
< end_pos
; i
++)
1397 comment
.SetChar( i
, line
[i
] );
1398 line
.SetChar( i
, ' ' );
1401 if ((token
[0] == '#') &&
1402 ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
)))
1404 int end_pos
= pos
+ (int)token
.Len();
1405 for (int i
= pos
; i
< end_pos
; i
++)
1407 comment
.SetChar( i
, line
[i
] );
1408 line
.SetChar( i
, ' ' );
1412 if ((token
[0] == '"') || (token
[0] == '\''))
1414 int end_pos
= pos
+ (int)token
.Len();
1415 for (int i
= pos
; i
< end_pos
; i
++)
1417 my_string
.SetChar( i
, line
[i
] );
1418 line
.SetChar( i
, ' ' );
1422 token
= GetNextToken( line
, pos
);
1425 if ((lineNum
< selStartY
) || (lineNum
> selEndY
))
1427 dc
.DrawText( line
, x
, y
);
1428 dc
.SetTextForeground( m_keywordColour
);
1429 dc
.DrawText( keyword
, x
, y
);
1430 dc
.SetTextForeground( m_defineColour
);
1431 dc
.DrawText( define
, x
, y
);
1432 dc
.SetTextForeground( m_variableColour
);
1433 dc
.DrawText( variable
, x
, y
);
1434 dc
.SetTextForeground( m_commentColour
);
1435 dc
.DrawText( comment
, x
, y
);
1436 dc
.SetTextForeground( m_stringColour
);
1437 dc
.DrawText( my_string
, x
, y
);
1438 dc
.SetTextForeground( *wxBLACK
);
1442 if (selStartY
== selEndY
)
1445 wxString
tmp1( line
);
1446 wxString
tmp2( line
);
1447 dc
.DrawRectangle( selStartX
*m_charWidth
+2, lineNum
*m_lineHeight
+2,
1448 (selEndX
-selStartX
)*m_charWidth
, m_lineHeight
);
1449 for (i
= selStartX
; i
< selEndX
; i
++)
1450 if ((int)tmp1
.Len() > i
)
1451 tmp1
.SetChar( i
, ' ' );
1452 dc
.DrawText( tmp1
, x
, y
);
1453 for (i
= 0; i
< selStartX
; i
++)
1454 if ((int)tmp2
.Len() > i
)
1455 tmp2
.SetChar( i
, ' ' );
1456 for (i
= selEndX
; i
< (int)tmp2
.Len(); i
++)
1457 if ((int)tmp2
.Len() > i
)
1458 tmp2
.SetChar( i
, ' ' );
1459 dc
.SetTextForeground( *wxWHITE
);
1460 dc
.DrawText( tmp2
, x
, y
);
1461 dc
.SetTextForeground( *wxBLACK
);
1463 if ((lineNum
> selStartY
) && (lineNum
< selEndY
))
1465 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1466 dc
.SetTextForeground( *wxWHITE
);
1467 dc
.DrawText( line
, x
, y
);
1468 dc
.SetTextForeground( *wxBLACK
);
1470 if (lineNum
== selStartY
)
1473 wxString
tmp1( line
);
1474 wxString
tmp2( line
);
1475 dc
.DrawRectangle( selStartX
*m_charWidth
+2, lineNum
*m_lineHeight
+2,
1476 10000, m_lineHeight
);
1477 for (i
= selStartX
; i
< (int)tmp1
.Len(); i
++)
1478 tmp1
.SetChar( i
, ' ' );
1479 dc
.DrawText( tmp1
, x
, y
);
1480 for (i
= 0; i
< selStartX
; i
++)
1481 if ((int)tmp2
.Len() > i
)
1482 tmp2
.SetChar( i
, ' ' );
1483 dc
.SetTextForeground( *wxWHITE
);
1484 dc
.DrawText( tmp2
, x
, y
);
1485 dc
.SetTextForeground( *wxBLACK
);
1487 if (lineNum
== selEndY
)
1490 wxString
tmp1( line
);
1491 wxString
tmp2( line
);
1492 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2,
1493 selEndX
*m_charWidth
, m_lineHeight
);
1494 for (i
= 0; i
< selEndX
; i
++)
1495 if ((int)tmp1
.Len() > i
)
1496 tmp1
.SetChar( i
, ' ' );
1497 dc
.DrawText( tmp1
, x
, y
);
1498 for (i
= selEndX
; i
< (int)tmp2
.Len(); i
++)
1499 tmp2
.SetChar( i
, ' ' );
1500 dc
.SetTextForeground( *wxWHITE
);
1501 dc
.DrawText( tmp2
, x
, y
);
1502 dc
.SetTextForeground( *wxBLACK
);
1505 dc
.SetTextForeground( m_keywordColour
);
1506 dc
.DrawText( keyword
, x
, y
);
1507 dc
.SetTextForeground( m_defineColour
);
1508 dc
.DrawText( define
, x
, y
);
1509 dc
.SetTextForeground( m_variableColour
);
1510 dc
.DrawText( variable
, x
, y
);
1511 dc
.SetTextForeground( m_commentColour
);
1512 dc
.DrawText( comment
, x
, y
);
1513 dc
.SetTextForeground( m_stringColour
);
1514 dc
.DrawText( my_string
, x
, y
);
1515 dc
.SetTextForeground( *wxBLACK
);
1518 void wxTextCtrl::OnPaint( wxPaintEvent
&event
)
1522 if (m_lines
.GetCount() == 0) return;
1526 dc
.SetFont( m_sourceFont
);
1529 GetViewStart( NULL
, &scroll_y
);
1533 GetClientSize( &size_x
, &size_y
);
1535 dc
.SetPen( *wxTRANSPARENT_PEN
);
1536 dc
.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT
), wxSOLID
) );
1537 int upper
= wxMin( (int)m_lines
.GetCount(), scroll_y
+(size_y
/m_lineHeight
)+1 );
1538 for (int i
= scroll_y
; i
< upper
; i
++)
1541 int y
= i
*m_lineHeight
+2;
1543 int h
= m_lineHeight
;
1544 CalcScrolledPosition( x
,y
,&x
,&y
);
1545 if (IsExposed(x
,y
,w
,h
))
1546 DrawLine( dc
, 0+2, i
*m_lineHeight
+2, m_lines
[i
].m_text
, i
);
1549 dc
.SetBrush( *wxRED_BRUSH
);
1550 dc
.DrawRectangle( m_cursorX
*m_charWidth
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
1553 void wxTextCtrl::OnMouse( wxMouseEvent
&event
)
1555 if (m_lines
.GetCount() == 0) return;
1558 #if 0 // there is no middle button on iPAQs
1559 if (event
.MiddleDown())
1566 if (event
.LeftDClick())
1572 if (event
.LeftDown())
1580 m_capturing
= FALSE
;
1584 if (event
.LeftDown() ||
1585 (event
.LeftIsDown() && m_capturing
))
1587 int x
= event
.GetX();
1588 int y
= event
.GetY();
1589 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1593 wxMin( 1000, wxMax( 0, x
) ),
1594 wxMin( (int)m_lines
.GetCount()-1, wxMax( 0, y
) ),
1595 event
.ShiftDown() || !event
.LeftDown() );
1599 void wxTextCtrl::OnChar( wxKeyEvent
&event
)
1601 if (m_lines
.GetCount() == 0) return;
1605 GetClientSize( &size_x
, &size_y
);
1606 size_x
/= m_charWidth
;
1607 size_y
/= m_lineHeight
;
1610 if (event
.ShiftDown())
1612 switch (event
.GetKeyCode())
1614 case '4': event
.m_keyCode
= WXK_LEFT
; break;
1615 case '8': event
.m_keyCode
= WXK_UP
; break;
1616 case '6': event
.m_keyCode
= WXK_RIGHT
; break;
1617 case '2': event
.m_keyCode
= WXK_DOWN
; break;
1618 case '9': event
.m_keyCode
= WXK_PRIOR
; break;
1619 case '3': event
.m_keyCode
= WXK_NEXT
; break;
1620 case '7': event
.m_keyCode
= WXK_HOME
; break;
1621 case '1': event
.m_keyCode
= WXK_END
; break;
1622 case '0': event
.m_keyCode
= WXK_INSERT
; break;
1626 switch (event
.GetKeyCode())
1630 if (m_ignoreInput
) return;
1632 MoveCursor( m_cursorX
, m_cursorY
-1, event
.ShiftDown() );
1633 m_ignoreInput
= TRUE
;
1638 if (m_ignoreInput
) return;
1639 if (m_cursorY
< (int)(m_lines
.GetCount()-1))
1640 MoveCursor( m_cursorX
, m_cursorY
+1, event
.ShiftDown() );
1641 m_ignoreInput
= TRUE
;
1646 if (m_ignoreInput
) return;
1649 MoveCursor( m_cursorX
-1, m_cursorY
, event
.ShiftDown() );
1654 MoveCursor( m_lines
[m_cursorY
-1].m_text
.Len(), m_cursorY
-1, event
.ShiftDown() );
1656 m_ignoreInput
= TRUE
;
1661 if (m_ignoreInput
) return;
1662 if (m_cursorX
< 1000)
1663 MoveCursor( m_cursorX
+1, m_cursorY
, event
.ShiftDown() );
1664 m_ignoreInput
= TRUE
;
1669 if (event
.ControlDown())
1670 MoveCursor( 0, 0, event
.ShiftDown() );
1672 MoveCursor( 0, m_cursorY
, event
.ShiftDown() );
1677 if (event
.ControlDown())
1678 MoveCursor( 0, m_lines
.GetCount()-1, event
.ShiftDown() );
1680 MoveCursor( m_lines
[m_cursorY
].m_text
.Len(), m_cursorY
, event
.ShiftDown() );
1685 if (m_ignoreInput
) return;
1686 MoveCursor( m_cursorX
, wxMin( (int)(m_lines
.GetCount()-1), m_cursorY
+size_y
), event
.ShiftDown() );
1687 m_ignoreInput
= TRUE
;
1692 if (m_ignoreInput
) return;
1693 MoveCursor( m_cursorX
, wxMax( 0, m_cursorY
-size_y
), event
.ShiftDown() );
1694 m_ignoreInput
= TRUE
;
1699 if (event
.ShiftDown())
1701 else if (event
.ControlDown())
1704 m_overwrite
= !m_overwrite
;
1724 bool save_overwrite
= m_overwrite
;
1725 m_overwrite
= FALSE
;
1726 int i
= 4-(m_cursorX
% 4);
1728 for (int c
= 0; c
< i
; c
++)
1730 m_overwrite
= save_overwrite
;
1751 if ( (event
.KeyCode() >= 'a') &&
1752 (event
.KeyCode() <= 'z') &&
1760 if ( (event
.KeyCode() >= 32) &&
1761 (event
.KeyCode() <= 255) &&
1762 !(event
.ControlDown() && !event
.AltDown()) ) // filters out Ctrl-X but leaves Alt-Gr
1766 DoChar( (char) event
.KeyCode() );
1775 void wxTextCtrl::OnIdle( wxIdleEvent
&event
)
1777 m_ignoreInput
= FALSE
;
1779 SearchForBrackets();
1784 void wxTextCtrl::Indent()
1786 int startY
= m_cursorY
;
1787 int endY
= m_cursorY
;
1790 startY
= m_selStartY
;
1800 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1802 for (int i
= startY
; i
<= endY
; i
++)
1804 m_lines
[i
].m_text
.insert( 0u, " " );
1809 void wxTextCtrl::Unindent()
1811 int startY
= m_cursorY
;
1812 int endY
= m_cursorY
;
1815 startY
= m_selStartY
;
1825 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1827 for (int i
= startY
; i
<= endY
; i
++)
1829 for (int n
= 0; n
< 4; n
++)
1831 if (m_lines
[i
].m_text
[0u] == ' ')
1832 m_lines
[i
].m_text
.erase(0u,1u);
1837 bool wxTextCtrl::HasSelection()
1839 return ((m_selStartY
!= m_selEndY
) || (m_selStartX
!= m_selEndX
));
1842 void wxTextCtrl::ClearSelection()
1850 void wxTextCtrl::RefreshLine( int n
)
1852 int y
= n
*m_lineHeight
;
1854 CalcScrolledPosition( x
, y
, &x
, &y
);
1855 wxRect
rect( 0+2, y
+2, 10000, m_lineHeight
);
1856 Refresh( TRUE
, &rect
);
1859 void wxTextCtrl::RefreshDown( int n
)
1863 GetClientSize( &size_x
, &size_y
);
1867 GetViewStart( &view_x
, &view_y
);
1875 int y
= n
*m_lineHeight
;
1877 CalcScrolledPosition( x
, y
, &x
, &y
);
1879 wxRect
rect( 0+2, y
+2, 10000, size_y
);
1880 Refresh( TRUE
, &rect
);
1884 void wxTextCtrl::MoveCursor( int new_x
, int new_y
, bool shift
, bool centre
)
1886 // if (IsSingleLine())
1888 if (new_x
> m_lines
[new_y
].m_text
.Len())
1889 new_x
= m_lines
[new_y
].m_text
.Len();
1892 if ((new_x
== m_cursorX
) && (new_y
== m_cursorY
)) return;
1894 bool no_cursor_refresh
= FALSE
;
1900 if (!HasSelection())
1902 m_selStartX
= m_cursorX
;
1903 m_selStartY
= m_cursorY
;
1907 if (new_y
> m_selStartY
)
1909 y
= m_selStartY
*m_lineHeight
;
1910 h
= (new_y
-m_selStartY
+1)*m_lineHeight
;
1912 else if (new_y
== m_selStartY
)
1914 y
= m_selStartY
*m_lineHeight
;
1919 y
= new_y
*m_lineHeight
;
1920 h
= (-new_y
+m_selStartY
+1)*m_lineHeight
;
1923 no_cursor_refresh
= TRUE
;
1929 if (new_y
== m_selEndY
)
1931 y
= new_y
*m_lineHeight
;
1933 if (m_selEndX
> new_x
)
1935 x
= new_x
*m_charWidth
;
1936 w
= (m_selEndX
-new_x
)*m_charWidth
;
1940 x
= m_selEndX
*m_charWidth
;
1941 w
= (-m_selEndX
+new_x
)*m_charWidth
;
1948 if (new_y
> m_selEndY
)
1950 y
= m_selEndY
*m_lineHeight
;
1951 h
= (new_y
-m_selEndY
+1) * m_lineHeight
;
1955 y
= new_y
*m_lineHeight
;
1956 h
= (-new_y
+m_selEndY
+1) * m_lineHeight
;
1958 no_cursor_refresh
= TRUE
;
1967 CalcScrolledPosition( x
, y
, &x
, &y
);
1968 wxRect
rect( x
+2, y
+2, w
, h
);
1969 Refresh( TRUE
, &rect
);
1975 int ry1
= m_selEndY
;
1976 int ry2
= m_selStartY
;
1990 int y
= ry1
*m_lineHeight
;
1991 CalcScrolledPosition( x
, y
, &x
, &y
);
1992 wxRect
rect( 0+2, y
+2, 10000, (ry2
-ry1
+1)*m_lineHeight
);
1994 Refresh( TRUE
, &rect
);
1999 printf( "startx %d starty %d endx %d endy %d\n",
2000 m_selStartX, m_selStartY, m_selEndX, m_selEndY );
2002 printf( "has %d\n", (int)HasSelection() );
2005 if (!no_cursor_refresh
)
2007 int x
= m_cursorX
*m_charWidth
;
2008 int y
= m_cursorY
*m_lineHeight
;
2009 CalcScrolledPosition( x
, y
, &x
, &y
);
2010 wxRect
rect( x
+2, y
+2, 4, m_lineHeight
+2 );
2015 Refresh( TRUE
, &rect
);
2017 wxClientDC
dc(this);
2019 dc
.SetPen( *wxTRANSPARENT_PEN
);
2020 dc
.SetBrush( *wxRED_BRUSH
);
2021 dc
.DrawRectangle( m_cursorX
*m_charWidth
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
2026 GetClientSize( &size_x
, &size_y
);
2027 size_x
/= m_charWidth
;
2028 size_y
/= m_lineHeight
;
2032 GetViewStart( &view_x
, &view_y
);
2036 int sy
= m_cursorY
- (size_y
/2);
2042 if (m_cursorY
< view_y
)
2043 Scroll( -1, m_cursorY
);
2044 else if (m_cursorY
> view_y
+size_y
-1)
2045 Scroll( -1, m_cursorY
-size_y
+1 );
2048 if (m_cursorX
< view_x
)
2049 Scroll( m_cursorX
, -1 );
2050 else if (m_cursorX
> view_x
+size_x
-1)
2051 Scroll( m_cursorX
-size_x
+1, -1 );
2054 void wxTextCtrl::MyAdjustScrollbars()
2059 int y_range
= m_lines
.GetCount();
2062 GetClientSize( NULL
, &height
);
2064 if (height
>= m_lines
.GetCount() *m_lineHeight
)
2069 GetViewStart( &view_x
, &view_y
);
2071 SetScrollbars( m_charWidth
, m_lineHeight
, m_longestLine
+2, y_range
, view_x
, view_y
);
2074 //-----------------------------------------------------------------------------
2075 // clipboard handlers
2076 //-----------------------------------------------------------------------------
2078 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
2083 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
2088 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
2093 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
2098 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
2103 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2105 event
.Enable( CanCut() );
2108 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2110 event
.Enable( CanCopy() );
2113 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2115 event
.Enable( CanPaste() );
2118 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2120 event
.Enable( CanUndo() );
2123 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2125 event
.Enable( CanRedo() );
2128 wxSize
wxTextCtrl::DoGetBestSize() const
2132 wxSize
ret(80, m_lineHeight
+ 4);
2134 if (HasFlag(wxBORDER_SUNKEN
) || HasFlag(wxBORDER_RAISED
))
2137 if (HasFlag(wxBORDER_SIMPLE
))
2144 return wxSize(80, 60);
2148 // ----------------------------------------------------------------------------
2150 // ----------------------------------------------------------------------------
2152 void wxTextCtrl::Freeze()
2156 void wxTextCtrl::Thaw()
2160 // ----------------------------------------------------------------------------
2161 // text control scrolling
2162 // ----------------------------------------------------------------------------
2164 bool wxTextCtrl::ScrollLines(int lines
)
2166 wxFAIL_MSG( "wxTextCtrl::ScrollLines not implemented");
2171 bool wxTextCtrl::ScrollPages(int pages
)
2173 wxFAIL_MSG( "wxTextCtrl::ScrollPages not implemented");