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"
22 #include "wx/dcclient.h"
24 #include "wx/univ/inphand.h"
25 #include "wx/univ/renderer.h"
26 #include "wx/univ/colschem.h"
27 #include "wx/univ/theme.h"
29 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
33 wxSourceUndoStep::wxSourceUndoStep( wxSourceUndo type
, int y1
, int y2
, wxTextCtrl
*owner
)
40 m_cursorX
= m_owner
->GetCursorX();
41 m_cursorY
= m_owner
->GetCursorY();
43 if (m_type
== wxSOURCE_UNDO_LINE
)
45 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
47 if (m_type
== wxSOURCE_UNDO_ENTER
)
49 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
51 if (m_type
== wxSOURCE_UNDO_BACK
)
53 for (int i
= m_y1
; i
< m_y2
+2; i
++)
55 if (i
>= (int)m_owner
->m_lines
.GetCount())
56 m_lines
.Add( wxT("") );
58 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
61 if (m_type
== wxSOURCE_UNDO_DELETE
)
63 for (int i
= m_y1
; i
< m_y2
+1; i
++)
65 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
68 if (m_type
== wxSOURCE_UNDO_PASTE
)
70 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
74 void wxSourceUndoStep::Undo()
76 if (m_type
== wxSOURCE_UNDO_LINE
)
78 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
79 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
80 m_owner
->RefreshLine( m_y1
);
82 if (m_type
== wxSOURCE_UNDO_ENTER
)
84 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
85 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
86 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
87 m_owner
->RefreshDown( m_y1
);
89 if (m_type
== wxSOURCE_UNDO_BACK
)
91 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
92 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[1] ), m_y1
+1 );
93 m_owner
->MyAdjustScrollbars();
94 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
95 m_owner
->RefreshDown( m_y1
);
97 if (m_type
== wxSOURCE_UNDO_DELETE
)
99 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
100 for (int i
= 1; i
< (int)m_lines
.GetCount(); i
++)
101 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[i
] ), m_y1
+i
);
102 m_owner
->MyAdjustScrollbars();
103 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
104 m_owner
->RefreshDown( m_y1
);
106 if (m_type
== wxSOURCE_UNDO_PASTE
)
108 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
109 for (int i
= 0; i
< m_y2
-m_y1
; i
++)
110 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
111 m_owner
->MyAdjustScrollbars();
112 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
113 m_owner
->RefreshDown( m_y1
);
115 if (m_type
== wxSOURCE_UNDO_INSERT_LINE
)
117 m_owner
->m_lines
.RemoveAt( m_y1
);
118 m_owner
->MyAdjustScrollbars();
119 m_owner
->MoveCursor( 0, m_y1
);
120 m_owner
->RefreshDown( m_y1
);
124 #include "wx/arrimpl.cpp"
125 WX_DEFINE_OBJARRAY(wxSourceLineArray
);
127 //-----------------------------------------------------------------------------
129 //-----------------------------------------------------------------------------
131 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
,wxControl
)
133 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
134 EVT_PAINT(wxTextCtrl::OnPaint
)
135 EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground
)
136 EVT_CHAR(wxTextCtrl::OnChar
)
137 EVT_MOUSE_EVENTS(wxTextCtrl::OnMouse
)
138 EVT_IDLE(wxTextCtrl::OnIdle
)
139 EVT_KILL_FOCUS(wxTextCtrl::OnKillFocus
)
140 EVT_SET_FOCUS(wxTextCtrl::OnSetFocus
)
142 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
143 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
144 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
145 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
146 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
148 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
149 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
150 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
151 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
152 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
155 void wxTextCtrl::Init()
160 m_undos
.DeleteContents( TRUE
);
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 bool wxTextCtrl::Create( wxWindow
*parent
,
207 const wxString
&value
,
211 const wxValidator
& validator
,
212 const wxString
&name
)
214 if ((style
& wxBORDER_MASK
) == 0)
215 style
|= wxBORDER_SUNKEN
;
217 if ((style
& wxTE_MULTILINE
) != 0)
218 style
|= wxALWAYS_SHOW_SB
;
220 wxTextCtrlBase::Create( parent
, id
, pos
/* wxDefaultPosition */, size
,
221 style
|wxVSCROLL
|wxHSCROLL
|wxNO_FULL_REPAINT_ON_RESIZE
);
223 SetBackgroundColour( *wxWHITE
);
225 SetCursor( wxCursor( wxCURSOR_IBEAM
) );
227 m_editable
= ((m_windowStyle
& wxTE_READONLY
) == 0);
229 if (HasFlag(wxTE_PASSWORD
))
230 m_sourceFont
= wxFont( 12, wxMODERN
, wxNORMAL
, wxNORMAL
);
232 m_sourceFont
= GetFont();
235 dc
.SetFont( m_sourceFont
);
236 m_lineHeight
= dc
.GetCharHeight();
237 m_charWidth
= dc
.GetCharWidth();
241 wxSize
size_best( DoGetBestSize() );
242 wxSize
new_size( size
);
243 if (new_size
.x
== -1)
244 new_size
.x
= size_best
.x
;
245 if (new_size
.y
== -1)
246 new_size
.y
= size_best
.y
;
247 if ((new_size
.x
!= size
.x
) || (new_size
.y
!= size
.y
))
248 SetSize( new_size
.x
, new_size
.y
);
250 // We create an input handler since it might be useful
251 CreateInputHandler(wxINP_HANDLER_TEXTCTRL
);
253 MyAdjustScrollbars();
258 //-----------------------------------------------------------------------------
260 //-----------------------------------------------------------------------------
262 wxString
wxTextCtrl::GetValue() const
265 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
267 ret
+= m_lines
[i
].m_text
;
268 if (i
+1 < m_lines
.GetCount())
275 void wxTextCtrl::SetValue(const wxString
& value
)
279 wxString oldValue
= GetValue();
289 m_lines
.Add( new wxSourceLine( wxT("") ) );
297 pos
= value
.find( wxT('\n'), begin
);
300 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, value
.Len()-begin
) );
303 // if (sl->m_text.Len() > m_longestLine)
304 // m_longestLine = sl->m_text.Len();
306 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
308 if (ww
> m_longestLine
)
315 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, pos
-begin
) );
318 // if (sl->m_text.Len() > m_longestLine)
319 // m_longestLine = sl->m_text.Len();
321 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
323 if (ww
> m_longestLine
)
331 // Don't need to refresh if the value hasn't changed
332 if ((GetWindowStyle() & wxTE_MULTILINE
) == 0)
334 if (value
== oldValue
)
338 MyAdjustScrollbars();
343 int wxTextCtrl::GetLineLength(long lineNo
) const
345 if (lineNo
>= (long)m_lines
.GetCount())
348 return m_lines
[lineNo
].m_text
.Len();
351 wxString
wxTextCtrl::GetLineText(long lineNo
) const
353 if (lineNo
>= (long)m_lines
.GetCount())
356 return m_lines
[lineNo
].m_text
;
359 int wxTextCtrl::GetNumberOfLines() const
361 return m_lines
.GetCount();
364 bool wxTextCtrl::IsModified() const
369 bool wxTextCtrl::IsEditable() const
374 void wxTextCtrl::GetSelection(long* from
, long* to
) const
376 if (m_selStartX
== -1 || m_selStartY
== -1 ||
377 m_selEndX
== -1 || m_selEndY
== -1)
379 *from
= GetInsertionPoint();
380 *to
= GetInsertionPoint();
384 *from
= XYToPosition(m_selStartX
, m_selStartY
);
385 *to
= XYToPosition(m_selEndX
, m_selEndY
);
389 void wxTextCtrl::Clear()
397 m_lines
.Add( new wxSourceLine( wxT("") ) );
399 SetScrollbars( m_charWidth
, m_lineHeight
, 0, 0, 0, 0 );
404 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
408 void wxTextCtrl::Remove(long from
, long to
)
413 void wxTextCtrl::DiscardEdits()
419 void wxTextCtrl::SetMaxLength(unsigned long len
)
423 int wxTextCtrl::PosToPixel( int line
, int pos
)
425 // TODO add support for Tabs
427 if (line
>= (int)m_lines
.GetCount()) return 0;
428 if (pos
< 0) return 0;
430 wxString text
= m_lines
[line
].m_text
;
432 if (text
.IsEmpty()) return 0;
434 if (pos
< (int)text
.Len())
435 text
.Remove( pos
, text
.Len()-pos
);
439 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
444 int wxTextCtrl::PixelToPos( int line
, int pixel
)
446 if (pixel
< 2) return 0;
448 if (line
>= (int)m_lines
.GetCount()) return 0;
450 wxString text
= m_lines
[line
].m_text
;
453 int res
= text
.Len();
456 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
462 text
.Remove( res
,1 );
468 void wxTextCtrl::SetLanguage( wxSourceLanguage lang
)
475 void wxTextCtrl::WriteText(const wxString
& text2
)
477 if (text2
.IsEmpty()) return;
481 wxString
text( text2
);
484 while ( (pos
= text
.Find('\n')) != -1 )
486 lines
.Add( text
.Left( pos
) );
487 text
.Remove( 0, pos
+1 );
490 int count
= (int)lines
.GetCount();
492 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
493 wxString
tmp2( tmp1
);
494 int len
= (int)tmp1
.Len();
499 for (int i
= 0; i
< m_cursorX
-len
; i
++)
501 m_lines
[m_cursorY
].m_text
.Append( tmp
);
506 tmp1
.Remove( m_cursorX
);
507 tmp2
.Remove( 0, m_cursorX
);
508 tmp1
.Append( lines
[0] );
512 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
515 m_lines
[m_cursorY
].m_text
= tmp1
;
516 RefreshLine( m_cursorY
);
520 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
522 m_lines
[m_cursorY
].m_text
= tmp1
;
524 for (i
= 1; i
< count
; i
++)
525 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
526 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
528 MyAdjustScrollbars();
529 RefreshDown( m_cursorY
);
533 void wxTextCtrl::AppendText(const wxString
& text2
)
535 if (text2
.IsEmpty()) return;
539 wxString
text( text2
);
542 while ( (pos
= text
.Find('\n')) != -1 )
544 lines
.Add( text
.Left( pos
) );
545 text
.Remove( 0, pos
+1 );
548 int count
= (int)lines
.GetCount();
550 size_t y
= m_lines
.GetCount()-1;
552 wxString
tmp( m_lines
[y
].m_text
);
553 tmp
.Append( lines
[0] );
557 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, y
, y
, this ) );
559 m_lines
[y
].m_text
= tmp
;
564 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, y
, y
+count
-1, this ) );
566 m_lines
[y
].m_text
= tmp
;
568 for (i
= 1; i
< count
; i
++)
569 m_lines
.Insert( new wxSourceLine( lines
[i
] ), y
+i
);
571 MyAdjustScrollbars();
576 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
581 long wxTextCtrl::XYToPosition(long x
, long y
) const
585 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
589 // Add one for the end-of-line character
590 ret
+= m_lines
[i
].m_text
.Len() + 1;
594 if ((size_t)x
< (m_lines
[i
].m_text
.Len()+1))
597 return (ret
+ m_lines
[i
].m_text
.Len() + 1);
603 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
605 if (m_lines
.GetCount() == 0)
616 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
618 //pos -= m_lines[i].m_text.Len();
621 // Add one for the end-of-line character. (In Windows,
622 // there are _two_ positions for each end of line.)
623 if (pos
<= ((int)m_lines
[i
].m_text
.Len()))
630 pos
-= (m_lines
[i
].m_text
.Len() + 1);
635 //xx = m_lines[ m_lines.GetCount()-1 ].m_text.Len();
643 void wxTextCtrl::ShowPosition(long pos
)
647 void wxTextCtrl::Copy()
649 if (!HasSelection()) return;
653 int selStartY
= m_selStartY
;
654 int selEndY
= m_selEndY
;
655 int selStartX
= m_selStartX
;
656 int selEndX
= m_selEndX
;
658 if ((selStartY
> selEndY
) ||
659 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
669 if (selStartY
== selEndY
)
671 sel
= m_lines
[selStartY
].m_text
;
673 if (selStartX
>= (int)sel
.Len()) return;
674 if (selEndX
> (int)sel
.Len())
677 sel
.Remove( selEndX
, sel
.Len()-selEndX
);
678 sel
.Remove( 0, selStartX
);
682 wxString
tmp( m_lines
[selStartY
].m_text
);
684 if (selStartX
< (int)tmp
.Len())
686 tmp
.Remove( 0, selStartX
);
688 sel
.Append( wxT("\n") );
690 for (int i
= selStartY
+1; i
< selEndY
; i
++)
692 sel
.Append( m_lines
[i
].m_text
);
693 sel
.Append( wxT("\n") );
695 tmp
= m_lines
[selEndY
].m_text
;
696 if (selEndX
> (int)tmp
.Len())
700 tmp
.Remove( selEndX
, tmp
.Len()-selEndX
);
705 if (wxTheClipboard
->Open())
707 wxTheClipboard
->SetData( new wxTextDataObject( sel
) );
708 wxTheClipboard
->Close();
712 void wxTextCtrl::Cut()
719 void wxTextCtrl::Paste()
723 if (!wxTheClipboard
->Open()) return;
725 if (!wxTheClipboard
->IsSupported( wxDF_TEXT
))
727 wxTheClipboard
->Close();
732 wxTextDataObject data
;
734 bool ret
= wxTheClipboard
->GetData( data
);
736 wxTheClipboard
->Close();
742 wxString
text( data
.GetText() );
745 while ( (pos
= text
.Find('\n')) != -1 )
747 lines
.Add( text
.Left( pos
) );
748 text
.Remove( 0, pos
+1 );
751 int count
= (int)lines
.GetCount();
753 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
754 wxString
tmp2( tmp1
);
755 int len
= (int)tmp1
.Len();
760 for (int i
= 0; i
< m_cursorX
-len
; i
++)
762 m_lines
[m_cursorY
].m_text
.Append( tmp
);
767 tmp1
.Remove( m_cursorX
);
768 tmp2
.Remove( 0, m_cursorX
);
769 tmp1
.Append( lines
[0] );
773 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
776 m_lines
[m_cursorY
].m_text
= tmp1
;
777 RefreshLine( m_cursorY
);
781 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
783 m_lines
[m_cursorY
].m_text
= tmp1
;
785 for (i
= 1; i
< count
; i
++)
786 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
787 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
789 MyAdjustScrollbars();
790 RefreshDown( m_cursorY
);
794 void wxTextCtrl::Undo()
796 if (m_undos
.GetCount() == 0) return;
798 wxList::Node
*node
= m_undos
.Item( m_undos
.GetCount()-1 );
799 wxSourceUndoStep
*undo
= (wxSourceUndoStep
*) node
->GetData();
808 void wxTextCtrl::SetInsertionPoint(long pos
)
812 PositionToXY(pos
, & x
, & y
);
815 // TODO: scroll to this position if necessary
819 void wxTextCtrl::SetInsertionPointEnd()
821 SetInsertionPoint(GetLastPosition());
824 long wxTextCtrl::GetInsertionPoint() const
826 return XYToPosition( m_cursorX
, m_cursorY
);
829 long wxTextCtrl::GetLastPosition() const
831 size_t lineCount
= m_lines
.GetCount() - 1;
832 // It's the length of the line, not the length - 1,
833 // because there's a position after the last character.
834 return XYToPosition( m_lines
[lineCount
].m_text
.Len(), lineCount
);
837 void wxTextCtrl::SetSelection(long from
, long to
)
841 void wxTextCtrl::SetEditable(bool editable
)
843 m_editable
= editable
;
846 bool wxTextCtrl::Enable( bool enable
)
851 bool wxTextCtrl::SetFont(const wxFont
& font
)
853 wxTextCtrlBase::SetFont( font
);
858 dc
.SetFont( m_sourceFont
);
859 m_lineHeight
= dc
.GetCharHeight();
860 m_charWidth
= dc
.GetCharWidth();
862 // TODO: recalc longest lines
864 MyAdjustScrollbars();
869 bool wxTextCtrl::SetForegroundColour(const wxColour
& colour
)
871 return wxWindow::SetForegroundColour( colour
);
874 bool wxTextCtrl::SetBackgroundColour(const wxColour
& colour
)
876 return wxWindow::SetBackgroundColour( colour
);
879 //-----------------------------------------------------------------------------
880 // private code and handlers
881 //-----------------------------------------------------------------------------
883 void wxTextCtrl::SearchForBrackets()
885 int oldBracketY
= m_bracketY
;
886 int oldBracketX
= m_bracketX
;
888 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()) return;
890 wxString current
= m_lines
[m_cursorY
].m_text
;
892 // reverse search first
897 bracket
= current
[(size_t) (m_cursorX
-1)];
899 if (bracket
== ')' || bracket
== ']' || bracket
== '}')
901 char antibracket
= '(';
902 if (bracket
== ']') antibracket
= '[';
903 if (bracket
== '}') antibracket
= '{';
907 int endY
= m_cursorY
-60;
908 if (endY
< 0) endY
= 0;
909 for (int y
= m_cursorY
; y
>= endY
; y
--)
911 current
= m_lines
[y
].m_text
;
913 current
.erase(m_cursorX
-1,current
.Len()-m_cursorX
+1);
915 for (int n
= current
.Len()-1; n
>= 0; n
--)
918 if (current
[(size_t) (n
)] == '\'')
920 for (int m
= n
-1; m
>= 0; m
--)
922 if (current
[(size_t) (m
)] == '\'')
924 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
933 if (current
[(size_t) (n
)] == '\"')
935 for (int m
= n
-1; m
>= 0; m
--)
937 if (current
[(size_t) (m
)] == '\"')
939 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
947 if (current
[(size_t) (n
)] == antibracket
)
954 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
955 RefreshLine( oldBracketY
);
956 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
957 RefreshLine( m_bracketY
);
961 else if (current
[(size_t) (n
)] == bracket
)
972 if ((int)current
.Len() > m_cursorX
)
973 bracket
= current
[(size_t) (m_cursorX
)];
974 if (bracket
== '(' || bracket
== '[' || bracket
== '{')
976 char antibracket
= ')';
977 if (bracket
== '[') antibracket
= ']';
978 if (bracket
== '{') antibracket
= '}';
982 int endY
= m_cursorY
+60;
983 if (endY
> (int)(m_lines
.GetCount()-1)) endY
= m_lines
.GetCount()-1;
984 for (int y
= m_cursorY
; y
<= endY
; y
++)
986 current
= m_lines
[y
].m_text
;
991 for (int n
= start
; n
< (int)current
.Len(); n
++)
994 if (current
[(size_t) (n
)] == '\'')
996 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
998 if (current
[(size_t) (m
)] == '\'')
1000 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1009 if (current
[(size_t) (n
)] == '\"')
1011 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
1013 if (current
[(size_t) (m
)] == '\"')
1015 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1023 if (current
[(size_t) (n
)] == antibracket
)
1030 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
1031 RefreshLine( oldBracketY
);
1032 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
1033 RefreshLine( m_bracketY
);
1037 else if (current
[(size_t) (n
)] == bracket
)
1045 if (oldBracketY
!= -1)
1048 RefreshLine( oldBracketY
);
1052 void wxTextCtrl::Delete()
1054 if (!HasSelection()) return;
1058 int selStartY
= m_selStartY
;
1059 int selEndY
= m_selEndY
;
1060 int selStartX
= m_selStartX
;
1061 int selEndX
= m_selEndX
;
1063 if ((selStartY
> selEndY
) ||
1064 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1066 int tmp
= selStartX
;
1067 selStartX
= selEndX
;
1070 selStartY
= selEndY
;
1074 int len
= (int)m_lines
[selStartY
].m_text
.Len();
1076 if (selStartY
== selEndY
)
1078 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, selStartY
, selStartY
, this ) );
1080 wxString
tmp( m_lines
[selStartY
].m_text
);
1081 if (selStartX
< len
)
1085 tmp
.Remove( selStartX
, selEndX
-selStartX
);
1086 m_lines
[selStartY
].m_text
= tmp
;
1089 m_cursorX
= selStartX
;
1090 RefreshLine( selStartY
);
1094 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, selStartY
, selEndY
, this ) );
1096 if (selStartX
< len
)
1097 m_lines
[selStartY
].m_text
.Remove( selStartX
);
1099 for (int i
= 0; i
< selEndY
-selStartY
-1; i
++)
1100 m_lines
.RemoveAt( selStartY
+1 );
1102 if (selEndX
< (int)m_lines
[selStartY
+1].m_text
.Len())
1103 m_lines
[selStartY
+1].m_text
.Remove( 0, selEndX
);
1105 m_lines
[selStartY
+1].m_text
.Remove( 0 );
1107 m_lines
[selStartY
].m_text
.Append( m_lines
[selStartY
+1].m_text
);
1108 m_lines
.RemoveAt( selStartY
+1 );
1111 MoveCursor( selStartX
, selStartY
);
1112 MyAdjustScrollbars();
1114 RefreshDown( selStartY
);
1118 void wxTextCtrl::DeleteLine()
1120 if (HasSelection()) return;
1122 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()-1) return; // TODO
1124 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1126 m_lines
.RemoveAt( m_cursorY
);
1128 if (m_cursorY
>= (int)m_lines
.GetCount()) m_cursorY
--;
1130 MyAdjustScrollbars();
1131 RefreshDown( m_cursorY
);
1134 void wxTextCtrl::DoChar( char c
)
1138 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1140 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1142 if (m_cursorX
>= (int)tmp
.Len())
1144 int len
= tmp
.Len();
1145 for (int i
= 0; i
< m_cursorX
- len
; i
++)
1152 tmp
.SetChar( m_cursorX
, c
);
1154 tmp
.insert( m_cursorX
, 1, c
);
1157 m_lines
[m_cursorY
].m_text
= tmp
;
1159 // if (tmp.Len() > m_longestLine)
1161 // m_longestLine = tmp.Len();
1162 // MyAdjustScrollbars();
1166 GetTextExtent( tmp
, &ww
, NULL
, NULL
, NULL
);
1168 if (ww
> m_longestLine
)
1171 MyAdjustScrollbars();
1176 int y
= m_cursorY
*m_lineHeight
;
1177 // int x = (m_cursorX-1)*m_charWidth;
1178 int x
= PosToPixel( m_cursorY
, m_cursorX
-1 );
1179 CalcScrolledPosition( x
, y
, &x
, &y
);
1180 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1181 Refresh( TRUE
, &rect
);
1182 // refresh whole line for syntax colour highlighting
1184 Refresh( FALSE
, &rect
);
1188 GetClientSize( &size_x
, &size_y
);
1189 size_x
/= m_charWidth
;
1193 GetViewStart( &view_x
, &view_y
);
1195 //int xx = m_cursorX;
1196 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
1200 else if (xx
> view_x
+size_x
-1)
1201 Scroll( xx
-size_x
+1, -1 );
1204 void wxTextCtrl::DoBack()
1210 if (m_cursorY
== 0) return;
1212 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_BACK
, m_cursorY
-1, m_cursorY
, this ) );
1214 wxString
tmp1( m_lines
[m_cursorY
-1].m_text
);
1216 wxString
tmp2( m_lines
[m_cursorY
].m_text
);
1218 m_cursorX
= tmp1
.Len();
1220 tmp1
.Append( tmp2
);
1221 m_lines
[m_cursorY
].m_text
= tmp1
;
1222 m_lines
.RemoveAt( m_cursorY
+1 );
1224 MyAdjustScrollbars();
1225 RefreshDown( m_cursorY
-1 );
1229 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1231 if (m_cursorX
<= (int)m_lines
[m_cursorY
].m_text
.Len())
1232 m_lines
[m_cursorY
].m_text
.Remove( m_cursorX
-1, 1 );
1235 int y
= m_cursorY
*m_lineHeight
;
1236 // int x = m_cursorX*m_charWidth;
1237 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1238 CalcScrolledPosition( x
, y
, &x
, &y
);
1239 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1240 Refresh( TRUE
, &rect
);
1241 // refresh whole line for syntax colour highlighting
1243 Refresh( FALSE
, &rect
);
1247 void wxTextCtrl::DoDelete()
1251 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1253 int len
= (int)tmp
.Len();
1254 if (m_cursorX
>= len
)
1256 if (m_cursorY
== (int)m_lines
.GetCount()-1) return;
1258 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1260 for (int i
= 0; i
< (m_cursorX
-len
); i
++)
1263 tmp
+= m_lines
[m_cursorY
+1].m_text
;
1265 m_lines
[m_cursorY
] = tmp
;
1266 m_lines
.RemoveAt( m_cursorY
+1 );
1268 MyAdjustScrollbars();
1269 RefreshDown( m_cursorY
);
1273 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1275 tmp
.Remove( m_cursorX
, 1 );
1276 m_lines
[m_cursorY
].m_text
= tmp
;
1278 int y
= m_cursorY
*m_lineHeight
;
1279 // int x = m_cursorX*m_charWidth;
1280 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1281 CalcScrolledPosition( x
, y
, &x
, &y
);
1282 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1283 Refresh( TRUE
, &rect
);
1284 // refresh whole line for syntax colour highlighting
1286 Refresh( FALSE
, &rect
);
1290 void wxTextCtrl::DoReturn()
1294 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_ENTER
, m_cursorY
, m_cursorY
, this ) );
1296 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1297 size_t indent
= tmp
.find_first_not_of( ' ' );
1298 if (indent
== wxSTRING_MAXLEN
) indent
= 0;
1300 if (m_cursorX
>= (int)tmp
.Len())
1302 int cursorX
= indent
;
1303 int cursorY
= m_cursorY
+ 1;
1306 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1307 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1309 MyAdjustScrollbars();
1310 MoveCursor( cursorX
, cursorY
);
1311 RefreshDown( m_cursorY
);
1315 wxString
tmp1( tmp
);
1316 tmp1
.Remove( m_cursorX
, tmp
.Len()-m_cursorX
);
1317 m_lines
[m_cursorY
].m_text
= tmp1
;
1319 wxString
tmp2( tmp
);
1320 tmp2
.Remove( 0, m_cursorX
);
1322 int cursorX
= indent
;
1323 int cursorY
= m_cursorY
+ 1;
1326 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1327 new_tmp
.Append( tmp2
);
1328 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1330 MyAdjustScrollbars();
1331 MoveCursor( cursorX
, cursorY
);
1332 RefreshDown( m_cursorY
-1 );
1336 void wxTextCtrl::DoDClick()
1338 wxString
line( m_lines
[ m_cursorY
].m_text
);
1339 if (m_cursorX
>= (int)line
.Len()) return;
1341 char ch
= line
[(size_t) (p
)];
1342 if (((ch
>= 'a') && (ch
<= 'z')) ||
1343 ((ch
>= 'A') && (ch
<= 'Z')) ||
1344 ((ch
>= '0') && (ch
<= '9')) ||
1347 m_selStartY
= m_cursorY
;
1348 m_selEndY
= m_cursorY
;
1351 ch
= line
[(size_t) (p
-1)];
1352 while (((ch
>= 'a') && (ch
<= 'z')) ||
1353 ((ch
>= 'A') && (ch
<= 'Z')) ||
1354 ((ch
>= '0') && (ch
<= '9')) ||
1359 ch
= line
[(size_t) (p
-1)];
1365 if (p
< (int)line
.Len())
1367 ch
= line
[(size_t) (p
)];
1368 while (((ch
>= 'a') && (ch
<= 'z')) ||
1369 ((ch
>= 'A') && (ch
<= 'Z')) ||
1370 ((ch
>= '0') && (ch
<= '9')) ||
1373 if (p
>= (int)line
.Len()) break;
1375 ch
= line
[(size_t) (p
)];
1379 RefreshLine( m_cursorY
);
1383 wxString
wxTextCtrl::GetNextToken( wxString
&line
, size_t &pos
)
1386 size_t len
= line
.Len();
1387 for (size_t p
= pos
; p
< len
; p
++)
1389 if ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
))
1393 for (size_t q
= p
; q
< len
; q
++)
1394 ret
.Append( line
[q
] );
1401 if ((line
[p
] == '/') && (p
+1 < len
) && (line
[(size_t) (p
+1)] == '/'))
1403 for (size_t q
= p
; q
< len
; q
++)
1404 ret
.Append( line
[q
] );
1412 ret
.Append( line
[p
] );
1413 for (size_t q
= p
+1; q
< len
; q
++)
1415 ret
.Append( line
[q
] );
1416 if ((line
[q
] == '"') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1423 if (line
[p
] == '\'')
1425 ret
.Append( line
[p
] );
1426 for (size_t q
= p
+1; q
< len
; q
++)
1428 ret
.Append( line
[q
] );
1429 if ((line
[q
] == '\'') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1436 if (((line
[p
] >= 'a') && (line
[p
] <= 'z')) ||
1437 ((line
[p
] >= 'A') && (line
[p
] <= 'Z')) ||
1441 ret
.Append( line
[p
] );
1442 for (size_t q
= p
+1; q
< len
; q
++)
1444 if (((line
[q
] >= 'a') && (line
[q
] <= 'z')) ||
1445 ((line
[q
] >= 'A') && (line
[q
] <= 'Z')) ||
1446 ((line
[q
] >= '0') && (line
[q
] <= '9')) ||
1449 ret
.Append( line
[q
] );
1466 void wxTextCtrl::OnEraseBackground( wxEraseEvent
&event
)
1471 void wxTextCtrl::DrawLinePart( wxDC
&dc
, int x
, int y
, const wxString
&toDraw
, const wxString
&origin
, const wxColour
&colour
)
1474 size_t len
= origin
.Len();
1475 dc
.SetTextForeground( colour
);
1478 while (toDraw
[pos
] == wxT(' '))
1481 if (pos
== len
) return;
1487 current
+= toDraw
[pos
];
1489 while ( (toDraw
[pos
] == origin
[pos
]) && (pos
< len
))
1491 current
+= toDraw
[pos
];
1496 wxString tmp
= origin
.Left( start
);
1497 GetTextExtent( tmp
, &xx
, NULL
, NULL
, NULL
);
1500 dc
.DrawText( current
, xx
, yy
);
1504 void wxTextCtrl::DrawLine( wxDC
&dc
, int x
, int y
, const wxString
&line2
, int lineNum
)
1506 int selStartY
= m_selStartY
;
1507 int selEndY
= m_selEndY
;
1508 int selStartX
= m_selStartX
;
1509 int selEndX
= m_selEndX
;
1511 if ((selStartY
> selEndY
) ||
1512 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1514 int tmp
= selStartX
;
1515 selStartX
= selEndX
;
1518 selStartY
= selEndY
;
1522 wxString
line( line2
);
1523 if (HasFlag(wxTE_PASSWORD
))
1525 size_t len
= line
.Len();
1526 line
= wxString( wxT('*'), len
);
1529 wxString
keyword( ' ', line
.Len() );
1530 wxString
define( ' ', line
.Len() );
1531 wxString
variable( ' ', line
.Len() );
1532 wxString
comment( ' ', line
.Len() );
1533 wxString
my_string( ' ', line
.Len() );
1534 wxString
selection( ' ', line
.Len() );
1536 if (m_lang
!= wxSOURCE_LANG_NONE
)
1538 if (lineNum
== m_bracketY
)
1540 wxString
red( ' ', line
.Len() );
1541 if (m_bracketX
< (int)line
.Len())
1543 red
.SetChar( m_bracketX
, line
[(size_t) (m_bracketX
)] );
1544 line
.SetChar( m_bracketX
, ' ' );
1545 dc
.SetTextForeground( *wxRED
);
1546 dc
.DrawText( red
, x
, y
);
1547 dc
.SetTextForeground( *wxBLACK
);
1552 wxString
token( GetNextToken( line
, pos
) );
1553 while (!token
.IsNull())
1555 if (m_keywords
.Index( token
) != wxNOT_FOUND
)
1557 size_t end_pos
= pos
+ token
.Len();
1558 for (size_t i
= pos
; i
< end_pos
; i
++)
1560 keyword
[i
] = line
[i
];
1564 if (m_defines
.Index( token
) != wxNOT_FOUND
)
1566 size_t end_pos
= pos
+ token
.Len();
1567 for (size_t i
= pos
; i
< end_pos
; i
++)
1569 define
[i
] = line
[i
];
1573 if ((m_variables
.Index( token
) != wxNOT_FOUND
) ||
1574 ((token
.Len() > 2) && (token
[(size_t) (0)] == 'w') && (token
[(size_t) (1)] == 'x')))
1576 size_t end_pos
= pos
+ token
.Len();
1577 for (size_t i
= pos
; i
< end_pos
; i
++)
1579 variable
[i
] = line
[i
];
1583 if ((token
.Len() >= 2) && (token
[(size_t) (0)] == '/') && (token
[(size_t) (1)] == '/') && (m_lang
== wxSOURCE_LANG_CPP
))
1585 size_t end_pos
= pos
+ token
.Len();
1586 for (size_t i
= pos
; i
< end_pos
; i
++)
1588 comment
[i
] = line
[i
];
1592 if ((token
[(size_t) (0)] == '#') &&
1593 ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
)))
1595 size_t end_pos
= pos
+ token
.Len();
1596 for (size_t i
= pos
; i
< end_pos
; i
++)
1598 comment
[i
] = line
[i
];
1602 if ((token
[(size_t) (0)] == '"') || (token
[(size_t) (0)] == '\''))
1604 size_t end_pos
= pos
+ token
.Len();
1605 for (size_t i
= pos
; i
< end_pos
; i
++)
1607 my_string
[i
] = line
[i
];
1612 token
= GetNextToken( line
, pos
);
1616 if ((lineNum
< selStartY
) || (lineNum
> selEndY
))
1618 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1619 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1620 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1621 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1622 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1623 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1624 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1628 if (selStartY
== selEndY
)
1630 // int xx = selStartX*m_charWidth;
1631 int xx
= PosToPixel( lineNum
, selStartX
);
1632 // int ww = (selEndX-selStartX)*m_charWidth;
1633 int ww
= PosToPixel( lineNum
, selEndX
) - xx
;
1634 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1636 for (size_t i
= (size_t)selStartX
; i
< (size_t)selEndX
; i
++)
1638 selection
[i
] = line
[i
];
1642 if ((lineNum
> selStartY
) && (lineNum
< selEndY
))
1644 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1646 for (size_t i
= 0; i
< line
.Len(); i
++)
1648 selection
[i
] = line
[i
];
1652 if (lineNum
== selStartY
)
1654 // int xx = selStartX*m_charWidth;
1655 int xx
= PosToPixel( lineNum
, selStartX
);
1656 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1658 for (size_t i
= (size_t)selStartX
; i
< line
.Len(); i
++)
1660 selection
[i
] = line
[i
];
1664 if (lineNum
== selEndY
)
1666 // int ww = selEndX*m_charWidth;
1667 int ww
= PosToPixel( lineNum
, selEndX
);
1668 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1670 for (size_t i
= 0; i
< (size_t)selEndX
; i
++)
1672 selection
[i
] = line
[i
];
1677 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1678 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1679 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1680 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1681 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1682 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1683 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1686 void wxTextCtrl::OnPaint( wxPaintEvent
&event
)
1690 if (m_lines
.GetCount() == 0) return;
1694 dc
.SetFont( m_sourceFont
);
1697 GetViewStart( NULL
, &scroll_y
);
1699 // We have a inner border of two pixels
1700 // around the text, so scroll units do
1701 // not correspond to lines.
1702 if (scroll_y
> 0) scroll_y
--;
1706 GetClientSize( &size_x
, &size_y
);
1708 dc
.SetPen( *wxTRANSPARENT_PEN
);
1709 dc
.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT
), wxSOLID
) );
1710 int upper
= wxMin( (int)m_lines
.GetCount(), scroll_y
+(size_y
/m_lineHeight
)+2 );
1711 for (int i
= scroll_y
; i
< upper
; i
++)
1714 int y
= i
*m_lineHeight
+2;
1716 int h
= m_lineHeight
;
1717 CalcScrolledPosition( x
,y
,&x
,&y
);
1718 if (IsExposed(x
,y
,w
,h
))
1719 DrawLine( dc
, 0+2, i
*m_lineHeight
+2, m_lines
[i
].m_text
, i
);
1722 if (m_editable
&& (FindFocus() == this))
1724 ///dc.SetBrush( *wxRED_BRUSH );
1725 dc
.SetBrush( *wxBLACK_BRUSH
);
1726 // int xx = m_cursorX*m_charWidth;
1727 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
1728 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
1732 void wxTextCtrl::OnMouse( wxMouseEvent
&event
)
1734 if (m_lines
.GetCount() == 0) return;
1737 #if 0 // there is no middle button on iPAQs
1738 if (event
.MiddleDown())
1745 if (event
.LeftDClick())
1751 if (event
.LeftDown())
1759 m_capturing
= FALSE
;
1763 if (event
.LeftDown() ||
1764 (event
.LeftIsDown() && m_capturing
))
1766 int x
= event
.GetX();
1767 int y
= event
.GetY();
1768 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1770 // x /= m_charWidth;
1771 x
= PixelToPos( y
, x
);
1773 wxMin( 1000, wxMax( 0, x
) ),
1774 wxMin( (int)m_lines
.GetCount()-1, wxMax( 0, y
) ),
1775 event
.ShiftDown() || !event
.LeftDown() );
1779 void wxTextCtrl::OnChar( wxKeyEvent
&event
)
1781 if (m_lines
.GetCount() == 0) return;
1783 if (!m_editable
) return;
1787 GetClientSize( &size_x
, &size_y
);
1788 size_x
/= m_charWidth
;
1789 size_y
/= m_lineHeight
;
1792 if (event
.ShiftDown())
1794 switch (event
.GetKeyCode())
1796 case '4': event
.m_keyCode
= WXK_LEFT
; break;
1797 case '8': event
.m_keyCode
= WXK_UP
; break;
1798 case '6': event
.m_keyCode
= WXK_RIGHT
; break;
1799 case '2': event
.m_keyCode
= WXK_DOWN
; break;
1800 case '9': event
.m_keyCode
= WXK_PRIOR
; break;
1801 case '3': event
.m_keyCode
= WXK_NEXT
; break;
1802 case '7': event
.m_keyCode
= WXK_HOME
; break;
1803 case '1': event
.m_keyCode
= WXK_END
; break;
1804 case '0': event
.m_keyCode
= WXK_INSERT
; break;
1808 switch (event
.GetKeyCode())
1812 if (m_ignoreInput
) return;
1814 MoveCursor( m_cursorX
, m_cursorY
-1, event
.ShiftDown() );
1815 m_ignoreInput
= TRUE
;
1820 if (m_ignoreInput
) return;
1821 if (m_cursorY
< (int)(m_lines
.GetCount()-1))
1822 MoveCursor( m_cursorX
, m_cursorY
+1, event
.ShiftDown() );
1823 m_ignoreInput
= TRUE
;
1828 if (m_ignoreInput
) return;
1831 MoveCursor( m_cursorX
-1, m_cursorY
, event
.ShiftDown() );
1836 MoveCursor( m_lines
[m_cursorY
-1].m_text
.Len(), m_cursorY
-1, event
.ShiftDown() );
1838 m_ignoreInput
= TRUE
;
1843 if (m_ignoreInput
) return;
1844 if (m_cursorX
< 1000)
1845 MoveCursor( m_cursorX
+1, m_cursorY
, event
.ShiftDown() );
1846 m_ignoreInput
= TRUE
;
1851 if (event
.ControlDown())
1852 MoveCursor( 0, 0, event
.ShiftDown() );
1854 MoveCursor( 0, m_cursorY
, event
.ShiftDown() );
1859 if (event
.ControlDown())
1860 MoveCursor( 0, m_lines
.GetCount()-1, event
.ShiftDown() );
1862 MoveCursor( m_lines
[m_cursorY
].m_text
.Len(), m_cursorY
, event
.ShiftDown() );
1867 if (m_ignoreInput
) return;
1868 MoveCursor( m_cursorX
, wxMin( (int)(m_lines
.GetCount()-1), m_cursorY
+size_y
), event
.ShiftDown() );
1869 m_ignoreInput
= TRUE
;
1874 if (m_ignoreInput
) return;
1875 MoveCursor( m_cursorX
, wxMax( 0, m_cursorY
-size_y
), event
.ShiftDown() );
1876 m_ignoreInput
= TRUE
;
1881 if (event
.ShiftDown())
1883 else if (event
.ControlDown())
1886 m_overwrite
= !m_overwrite
;
1891 if (m_windowStyle
& wxPROCESS_ENTER
)
1893 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1894 event
.SetEventObject(this);
1895 event
.SetString(GetValue());
1896 if (GetEventHandler()->ProcessEvent(event
)) return;
1914 bool save_overwrite
= m_overwrite
;
1915 m_overwrite
= FALSE
;
1916 int i
= 4-(m_cursorX
% 4);
1918 for (int c
= 0; c
< i
; c
++)
1920 m_overwrite
= save_overwrite
;
1941 if ( (event
.GetKeyCode() >= 'a') &&
1942 (event
.GetKeyCode() <= 'z') &&
1950 if ( (event
.GetKeyCode() >= 32) &&
1951 (event
.GetKeyCode() <= 255) &&
1952 !(event
.ControlDown() && !event
.AltDown()) ) // filters out Ctrl-X but leaves Alt-Gr
1956 DoChar( (char) event
.GetKeyCode() );
1965 void wxTextCtrl::OnIdle( wxIdleEvent
&event
)
1967 m_ignoreInput
= FALSE
;
1969 if (m_lang
!= wxSOURCE_LANG_NONE
)
1970 SearchForBrackets();
1975 void wxTextCtrl::Indent()
1977 int startY
= m_cursorY
;
1978 int endY
= m_cursorY
;
1981 startY
= m_selStartY
;
1991 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1993 for (int i
= startY
; i
<= endY
; i
++)
1995 m_lines
[i
].m_text
.insert( 0u, wxT(" ") );
2000 void wxTextCtrl::Unindent()
2002 int startY
= m_cursorY
;
2003 int endY
= m_cursorY
;
2006 startY
= m_selStartY
;
2016 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
2018 for (int i
= startY
; i
<= endY
; i
++)
2020 for (int n
= 0; n
< 4; n
++)
2022 if (m_lines
[i
].m_text
[0u] == wxT(' '))
2023 m_lines
[i
].m_text
.erase(0u,1u);
2028 bool wxTextCtrl::HasSelection()
2030 return ((m_selStartY
!= m_selEndY
) || (m_selStartX
!= m_selEndX
));
2033 void wxTextCtrl::ClearSelection()
2041 void wxTextCtrl::RefreshLine( int n
)
2043 int y
= n
*m_lineHeight
;
2045 CalcScrolledPosition( x
, y
, &x
, &y
);
2046 wxRect
rect( 0+2, y
+2, 10000, m_lineHeight
);
2047 Refresh( TRUE
, &rect
);
2050 void wxTextCtrl::RefreshDown( int n
)
2054 GetClientSize( &size_x
, &size_y
);
2058 GetViewStart( &view_x
, &view_y
);
2066 int y
= n
*m_lineHeight
;
2068 CalcScrolledPosition( x
, y
, &x
, &y
);
2070 wxRect
rect( 0+2, y
+2, 10000, size_y
);
2071 Refresh( TRUE
, &rect
);
2075 void wxTextCtrl::MoveCursor( int new_x
, int new_y
, bool shift
, bool centre
)
2077 if (!m_editable
) return;
2079 // if (IsSingleLine() || (m_lang == wxSOURCE_LANG_NONE))
2081 if (new_x
> (int) (m_lines
[new_y
].m_text
.Len()))
2082 new_x
= m_lines
[new_y
].m_text
.Len();
2085 if ((new_x
== m_cursorX
) && (new_y
== m_cursorY
)) return;
2087 bool no_cursor_refresh
= FALSE
;
2088 bool has_selection
= HasSelection();
2093 bool erase_background
= TRUE
;
2097 m_selStartX
= m_cursorX
;
2098 m_selStartY
= m_cursorY
;
2102 if (new_y
> m_selStartY
)
2104 y
= m_selStartY
*m_lineHeight
;
2105 h
= (new_y
-m_selStartY
+1)*m_lineHeight
;
2107 else if (new_y
== m_selStartY
)
2109 x
= PosToPixel( new_y
, m_selStartX
);
2110 w
= PosToPixel( new_y
, new_x
) - x
;
2114 w
= -w
+ 2; // +2 for the cursor
2116 y
= m_selStartY
*m_lineHeight
;
2121 y
= new_y
*m_lineHeight
;
2122 h
= (-new_y
+m_selStartY
+1)*m_lineHeight
;
2125 no_cursor_refresh
= TRUE
;
2131 if (new_y
== m_selEndY
)
2133 y
= new_y
*m_lineHeight
;
2135 if (m_selEndX
> new_x
)
2137 // x = new_x*m_charWidth;
2138 x
= PosToPixel( new_y
, new_x
);
2139 // w = (m_selEndX-new_x)*m_charWidth;
2140 w
= PosToPixel( new_y
, m_selEndX
) - x
;
2144 // x = m_selEndX*m_charWidth;
2145 x
= PosToPixel( new_y
, m_selEndX
);
2146 // w = (-m_selEndX+new_x)*m_charWidth;
2147 w
= PosToPixel( new_y
, new_x
) - x
;
2154 if (new_y
> m_selEndY
)
2156 y
= m_selEndY
*m_lineHeight
;
2157 h
= (new_y
-m_selEndY
+1) * m_lineHeight
;
2159 erase_background
= ((m_selEndY
< m_selStartY
) ||
2160 ((m_selEndY
== m_selStartY
) && (m_selEndX
< m_selStartX
)));
2164 y
= new_y
*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
)));
2170 no_cursor_refresh
= TRUE
;
2179 CalcScrolledPosition( x
, y
, &x
, &y
);
2180 wxRect
rect( x
+2, y
+2, w
, h
);
2181 Refresh( erase_background
, &rect
);
2187 int ry1
= m_selEndY
;
2188 int ry2
= m_selStartY
;
2202 int y
= ry1
*m_lineHeight
;
2203 CalcScrolledPosition( x
, y
, &x
, &y
);
2204 wxRect
rect( 0, y
+2, 10000, (ry2
-ry1
+1)*m_lineHeight
);
2206 Refresh( TRUE
, &rect
);
2211 printf( "startx %d starty %d endx %d endy %d\n",
2212 m_selStartX, m_selStartY, m_selEndX, m_selEndY );
2214 printf( "has %d\n", (int)HasSelection() );
2217 if (!no_cursor_refresh
)
2219 // int x = m_cursorX*m_charWidth;
2220 int x
= PosToPixel( m_cursorY
, m_cursorX
);
2221 int y
= m_cursorY
*m_lineHeight
;
2222 CalcScrolledPosition( x
, y
, &x
, &y
);
2223 wxRect
rect( x
+2, y
+2, 4, m_lineHeight
+2 );
2228 Refresh( TRUE
, &rect
);
2230 if (FindFocus() == this)
2232 wxClientDC
dc(this);
2234 dc
.SetPen( *wxTRANSPARENT_PEN
);
2235 //dc.SetBrush( *wxRED_BRUSH );
2236 dc
.SetBrush( *wxBLACK_BRUSH
);
2237 // int xx = m_cursorX*m_charWidth;
2238 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
2239 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
2245 GetClientSize( &size_x
, &size_y
);
2246 size_x
/= m_charWidth
;
2247 size_y
/= m_lineHeight
;
2251 GetViewStart( &view_x
, &view_y
);
2255 int sy
= m_cursorY
- (size_y
/2);
2261 if (m_cursorY
< view_y
)
2262 Scroll( -1, m_cursorY
);
2263 else if (m_cursorY
> view_y
+size_y
-1)
2264 Scroll( -1, m_cursorY
-size_y
+1 );
2267 //int xx = m_cursorX;
2268 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
2272 else if (xx
> view_x
+size_x
-1)
2273 Scroll( xx
-size_x
+1, -1 );
2276 void wxTextCtrl::MyAdjustScrollbars()
2281 int y_range
= m_lines
.GetCount();
2284 GetClientSize( NULL
, &height
);
2286 if (height
>= (int)m_lines
.GetCount() *m_lineHeight
)
2291 GetViewStart( &view_x
, &view_y
);
2293 SetScrollbars( m_charWidth
, m_lineHeight
, m_longestLine
+2, y_range
, view_x
, view_y
);
2296 //-----------------------------------------------------------------------------
2297 // clipboard handlers
2298 //-----------------------------------------------------------------------------
2300 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
2305 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
2310 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
2315 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
2320 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
2325 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2327 event
.Enable( CanCut() );
2330 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2332 event
.Enable( CanCopy() );
2335 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2337 event
.Enable( CanPaste() );
2340 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2342 event
.Enable( CanUndo() );
2345 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2347 event
.Enable( CanRedo() );
2350 wxSize
wxTextCtrl::DoGetBestSize() const
2354 wxSize
ret(80, m_lineHeight
+ 4);
2356 if (HasFlag(wxBORDER_SUNKEN
) || HasFlag(wxBORDER_RAISED
))
2359 if (HasFlag(wxBORDER_SIMPLE
))
2366 return wxSize(80, 60);
2370 // ----------------------------------------------------------------------------
2372 // ----------------------------------------------------------------------------
2374 void wxTextCtrl::Freeze()
2378 void wxTextCtrl::Thaw()
2382 void wxTextCtrl::OnSetFocus( wxFocusEvent
& event
)
2384 // To hide or show caret, as appropriate
2388 void wxTextCtrl::OnKillFocus( wxFocusEvent
& event
)
2390 // To hide or show caret, as appropriate
2394 // ----------------------------------------------------------------------------
2395 // text control scrolling
2396 // ----------------------------------------------------------------------------
2398 bool wxTextCtrl::ScrollLines(int lines
)
2400 wxFAIL_MSG( "wxTextCtrl::ScrollLines not implemented");
2405 bool wxTextCtrl::ScrollPages(int pages
)
2407 wxFAIL_MSG( "wxTextCtrl::ScrollPages not implemented");