1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 #include "wx/textctrl.h"
15 #include "wx/settings.h"
17 #include "wx/clipbrd.h"
18 #include "wx/tokenzr.h"
19 #include "wx/dcclient.h"
21 #include "wx/univ/inphand.h"
22 #include "wx/univ/renderer.h"
23 #include "wx/univ/colschem.h"
24 #include "wx/univ/theme.h"
26 //-----------------------------------------------------------------------------
28 //-----------------------------------------------------------------------------
30 wxSourceUndoStep::wxSourceUndoStep( wxSourceUndo type
, int y1
, int y2
, wxTextCtrl
*owner
)
37 m_cursorX
= m_owner
->GetCursorX();
38 m_cursorY
= m_owner
->GetCursorY();
40 if (m_type
== wxSOURCE_UNDO_LINE
)
42 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
44 if (m_type
== wxSOURCE_UNDO_ENTER
)
46 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
48 if (m_type
== wxSOURCE_UNDO_BACK
)
50 for (int i
= m_y1
; i
< m_y2
+2; i
++)
52 if (i
>= (int)m_owner
->m_lines
.GetCount())
53 m_lines
.Add( wxT("") );
55 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
58 if (m_type
== wxSOURCE_UNDO_DELETE
)
60 for (int i
= m_y1
; i
< m_y2
+1; i
++)
62 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
65 if (m_type
== wxSOURCE_UNDO_PASTE
)
67 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
71 void wxSourceUndoStep::Undo()
73 if (m_type
== wxSOURCE_UNDO_LINE
)
75 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
76 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
77 m_owner
->RefreshLine( m_y1
);
79 if (m_type
== wxSOURCE_UNDO_ENTER
)
81 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
82 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
83 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
84 m_owner
->RefreshDown( m_y1
);
86 if (m_type
== wxSOURCE_UNDO_BACK
)
88 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
89 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[1] ), m_y1
+1 );
90 m_owner
->MyAdjustScrollbars();
91 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
92 m_owner
->RefreshDown( m_y1
);
94 if (m_type
== wxSOURCE_UNDO_DELETE
)
96 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
97 for (int i
= 1; i
< (int)m_lines
.GetCount(); i
++)
98 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[i
] ), m_y1
+i
);
99 m_owner
->MyAdjustScrollbars();
100 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
101 m_owner
->RefreshDown( m_y1
);
103 if (m_type
== wxSOURCE_UNDO_PASTE
)
105 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
106 for (int i
= 0; i
< m_y2
-m_y1
; i
++)
107 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
108 m_owner
->MyAdjustScrollbars();
109 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
110 m_owner
->RefreshDown( m_y1
);
112 if (m_type
== wxSOURCE_UNDO_INSERT_LINE
)
114 m_owner
->m_lines
.RemoveAt( m_y1
);
115 m_owner
->MyAdjustScrollbars();
116 m_owner
->MoveCursor( 0, m_y1
);
117 m_owner
->RefreshDown( m_y1
);
121 #include "wx/arrimpl.cpp"
122 WX_DEFINE_OBJARRAY(wxSourceLineArray
);
124 //-----------------------------------------------------------------------------
126 //-----------------------------------------------------------------------------
128 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
,wxControl
)
130 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
131 EVT_PAINT(wxTextCtrl::OnPaint
)
132 EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground
)
133 EVT_CHAR(wxTextCtrl::OnChar
)
134 EVT_MOUSE_EVENTS(wxTextCtrl::OnMouse
)
135 EVT_KILL_FOCUS(wxTextCtrl::OnKillFocus
)
136 EVT_SET_FOCUS(wxTextCtrl::OnSetFocus
)
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_lang
= wxSOURCE_LANG_NONE
;
169 m_ignoreInput
= false;
173 m_keywordColour
= wxColour( 10, 140, 10 );
175 m_defineColour
= *wxRED
;
177 m_variableColour
= wxColour( 50, 120, 150 );
179 m_commentColour
= wxColour( 130, 130, 130 );
181 m_stringColour
= wxColour( 10, 140, 10 );
184 wxTextCtrl::wxTextCtrl( wxWindow
*parent
,
186 const wxString
&value
,
190 const wxValidator
& validator
,
191 const wxString
&name
)
192 : wxScrollHelper(this)
196 Create( parent
, id
, value
, pos
, size
, style
, validator
, name
);
199 wxTextCtrl::~wxTextCtrl()
201 WX_CLEAR_LIST(wxList
, m_undos
);
204 bool wxTextCtrl::Create( wxWindow
*parent
,
206 const wxString
&value
,
210 const wxValidator
& validator
,
211 const wxString
&name
)
213 if ((style
& wxBORDER_MASK
) == 0)
214 style
|= wxBORDER_SUNKEN
;
216 if ((style
& wxTE_MULTILINE
) != 0)
217 style
|= wxALWAYS_SHOW_SB
;
219 wxTextCtrlBase::Create( parent
, id
, pos
/* wxDefaultPosition */, size
,
220 style
| wxVSCROLL
| wxHSCROLL
);
222 SetBackgroundColour( *wxWHITE
);
224 SetCursor( wxCursor( wxCURSOR_IBEAM
) );
226 m_editable
= ((m_windowStyle
& wxTE_READONLY
) == 0);
228 if (HasFlag(wxTE_PASSWORD
))
229 m_sourceFont
= wxFont( 12, wxMODERN
, wxNORMAL
, wxNORMAL
);
231 m_sourceFont
= GetFont();
234 dc
.SetFont( m_sourceFont
);
235 m_lineHeight
= dc
.GetCharHeight();
236 m_charWidth
= dc
.GetCharWidth();
240 wxSize
size_best( DoGetBestSize() );
241 wxSize
new_size( size
);
242 if (new_size
.x
== -1)
243 new_size
.x
= size_best
.x
;
244 if (new_size
.y
== -1)
245 new_size
.y
= size_best
.y
;
246 if ((new_size
.x
!= size
.x
) || (new_size
.y
!= size
.y
))
247 SetSize( new_size
.x
, new_size
.y
);
249 // We create an input handler since it might be useful
250 CreateInputHandler(wxINP_HANDLER_TEXTCTRL
);
252 MyAdjustScrollbars();
257 //-----------------------------------------------------------------------------
259 //-----------------------------------------------------------------------------
261 wxString
wxTextCtrl::GetValue() const
264 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
266 ret
+= m_lines
[i
].m_text
;
267 if (i
+1 < m_lines
.GetCount())
274 void wxTextCtrl::SetValue(const wxString
& value
)
278 wxString oldValue
= GetValue();
288 m_lines
.Add( new wxSourceLine( wxT("") ) );
296 pos
= value
.find( wxT('\n'), begin
);
299 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, value
.Len()-begin
) );
302 // if (sl->m_text.Len() > m_longestLine)
303 // m_longestLine = sl->m_text.Len();
305 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
307 if (ww
> m_longestLine
)
314 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, pos
-begin
) );
317 // if (sl->m_text.Len() > m_longestLine)
318 // m_longestLine = sl->m_text.Len();
320 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
322 if (ww
> m_longestLine
)
330 // Don't need to refresh if the value hasn't changed
331 if ((GetWindowStyle() & wxTE_MULTILINE
) == 0)
333 if (value
== oldValue
)
337 MyAdjustScrollbars();
342 int wxTextCtrl::GetLineLength(long lineNo
) const
344 if (lineNo
>= (long)m_lines
.GetCount())
347 return m_lines
[lineNo
].m_text
.Len();
350 wxString
wxTextCtrl::GetLineText(long lineNo
) const
352 if (lineNo
>= (long)m_lines
.GetCount())
355 return m_lines
[lineNo
].m_text
;
358 int wxTextCtrl::GetNumberOfLines() const
360 return m_lines
.GetCount();
363 bool wxTextCtrl::IsModified() const
368 bool wxTextCtrl::IsEditable() const
373 void wxTextCtrl::GetSelection(long* from
, long* to
) const
375 if (m_selStartX
== -1 || m_selStartY
== -1 ||
376 m_selEndX
== -1 || m_selEndY
== -1)
378 *from
= GetInsertionPoint();
379 *to
= GetInsertionPoint();
383 *from
= XYToPosition(m_selStartX
, m_selStartY
);
384 *to
= XYToPosition(m_selEndX
, m_selEndY
);
388 void wxTextCtrl::Clear()
396 m_lines
.Add( new wxSourceLine( wxT("") ) );
398 SetScrollbars( m_charWidth
, m_lineHeight
, 0, 0, 0, 0 );
400 WX_CLEAR_LIST(wxList
, m_undos
);
403 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
407 void wxTextCtrl::Remove(long from
, long to
)
411 void wxTextCtrl::DiscardEdits()
417 void wxTextCtrl::SetMaxLength(unsigned long len
)
421 int wxTextCtrl::PosToPixel( int line
, int pos
)
423 // TODO add support for Tabs
425 if (line
>= (int)m_lines
.GetCount()) return 0;
426 if (pos
< 0) return 0;
428 wxString text
= m_lines
[line
].m_text
;
430 if (text
.empty()) return 0;
432 if (pos
< (int)text
.Len())
433 text
.Remove( pos
, text
.Len()-pos
);
437 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
442 int wxTextCtrl::PixelToPos( int line
, int pixel
)
444 if (pixel
< 2) return 0;
446 if (line
>= (int)m_lines
.GetCount()) return 0;
448 wxString text
= m_lines
[line
].m_text
;
451 int res
= text
.Len();
454 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
460 text
.Remove( res
,1 );
466 void wxTextCtrl::SetLanguage( wxSourceLanguage lang
)
473 void wxTextCtrl::WriteText(const wxString
& text2
)
475 if (text2
.empty()) return;
479 wxString
text( text2
);
482 while ( (pos
= text
.Find('\n')) != -1 )
484 lines
.Add( text
.Left( pos
) );
485 text
.Remove( 0, pos
+1 );
488 int count
= (int)lines
.GetCount();
490 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
491 wxString
tmp2( tmp1
);
492 int len
= (int)tmp1
.Len();
497 for (int i
= 0; i
< m_cursorX
-len
; i
++)
499 m_lines
[m_cursorY
].m_text
.Append( tmp
);
504 tmp1
.Remove( m_cursorX
);
505 tmp2
.Remove( 0, m_cursorX
);
506 tmp1
.Append( lines
[0] );
510 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
513 m_lines
[m_cursorY
].m_text
= tmp1
;
514 RefreshLine( m_cursorY
);
518 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
520 m_lines
[m_cursorY
].m_text
= tmp1
;
522 for (i
= 1; i
< count
; i
++)
523 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
524 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
526 MyAdjustScrollbars();
527 RefreshDown( m_cursorY
);
531 void wxTextCtrl::AppendText(const wxString
& text2
)
533 if (text2
.empty()) return;
537 wxString
text( text2
);
540 while ( (pos
= text
.Find('\n')) != -1 )
542 lines
.Add( text
.Left( pos
) );
543 text
.Remove( 0, pos
+1 );
546 int count
= (int)lines
.GetCount();
548 size_t y
= m_lines
.GetCount()-1;
550 wxString
tmp( m_lines
[y
].m_text
);
551 tmp
.Append( lines
[0] );
555 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, y
, y
, this ) );
557 m_lines
[y
].m_text
= tmp
;
562 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, y
, y
+count
-1, this ) );
564 m_lines
[y
].m_text
= tmp
;
566 for (i
= 1; i
< count
; i
++)
567 m_lines
.Insert( new wxSourceLine( lines
[i
] ), y
+i
);
569 MyAdjustScrollbars();
574 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
579 long wxTextCtrl::XYToPosition(long x
, long y
) const
583 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
587 // Add one for the end-of-line character
588 ret
+= m_lines
[i
].m_text
.Len() + 1;
592 if ((size_t)x
< (m_lines
[i
].m_text
.Len()+1))
595 return (ret
+ m_lines
[i
].m_text
.Len() + 1);
601 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
603 if (m_lines
.GetCount() == 0)
614 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
616 //pos -= m_lines[i].m_text.Len();
619 // Add one for the end-of-line character. (In Windows,
620 // there are _two_ positions for each end of line.)
621 if (pos
<= ((int)m_lines
[i
].m_text
.Len()))
628 pos
-= (m_lines
[i
].m_text
.Len() + 1);
633 //xx = m_lines[ m_lines.GetCount()-1 ].m_text.Len();
641 void wxTextCtrl::ShowPosition(long pos
)
645 void wxTextCtrl::Copy()
647 if (!HasSelection()) return;
651 int selStartY
= m_selStartY
;
652 int selEndY
= m_selEndY
;
653 int selStartX
= m_selStartX
;
654 int selEndX
= m_selEndX
;
656 if ((selStartY
> selEndY
) ||
657 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
667 if (selStartY
== selEndY
)
669 sel
= m_lines
[selStartY
].m_text
;
671 if (selStartX
>= (int)sel
.Len()) return;
672 if (selEndX
> (int)sel
.Len())
675 sel
.Remove( selEndX
, sel
.Len()-selEndX
);
676 sel
.Remove( 0, selStartX
);
680 wxString
tmp( m_lines
[selStartY
].m_text
);
682 if (selStartX
< (int)tmp
.Len())
684 tmp
.Remove( 0, selStartX
);
686 sel
.Append( wxT("\n") );
688 for (int i
= selStartY
+1; i
< selEndY
; i
++)
690 sel
.Append( m_lines
[i
].m_text
);
691 sel
.Append( wxT("\n") );
693 tmp
= m_lines
[selEndY
].m_text
;
694 if (selEndX
> (int)tmp
.Len())
698 tmp
.Remove( selEndX
, tmp
.Len()-selEndX
);
703 if (wxTheClipboard
->Open())
705 wxTheClipboard
->SetData( new wxTextDataObject( sel
) );
706 wxTheClipboard
->Close();
710 void wxTextCtrl::Cut()
717 void wxTextCtrl::Paste()
721 if (!wxTheClipboard
->Open()) return;
723 if (!wxTheClipboard
->IsSupported( wxDF_TEXT
))
725 wxTheClipboard
->Close();
730 wxTextDataObject data
;
732 bool ret
= wxTheClipboard
->GetData( data
);
734 wxTheClipboard
->Close();
740 wxString
text( data
.GetText() );
743 while ( (pos
= text
.Find('\n')) != -1 )
745 lines
.Add( text
.Left( pos
) );
746 text
.Remove( 0, pos
+1 );
749 int count
= (int)lines
.GetCount();
751 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
752 wxString
tmp2( tmp1
);
753 int len
= (int)tmp1
.Len();
758 for (int i
= 0; i
< m_cursorX
-len
; i
++)
760 m_lines
[m_cursorY
].m_text
.Append( tmp
);
765 tmp1
.Remove( m_cursorX
);
766 tmp2
.Remove( 0, m_cursorX
);
767 tmp1
.Append( lines
[0] );
771 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
774 m_lines
[m_cursorY
].m_text
= tmp1
;
775 RefreshLine( m_cursorY
);
779 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
781 m_lines
[m_cursorY
].m_text
= tmp1
;
783 for (i
= 1; i
< count
; i
++)
784 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
785 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
787 MyAdjustScrollbars();
788 RefreshDown( m_cursorY
);
792 void wxTextCtrl::Undo()
794 if (m_undos
.GetCount() == 0) return;
796 wxList::compatibility_iterator node
= m_undos
.Item( m_undos
.GetCount()-1 );
797 wxSourceUndoStep
*undo
= (wxSourceUndoStep
*) node
->GetData();
802 m_undos
.Erase( node
);
807 void wxTextCtrl::SetInsertionPoint(long pos
)
811 PositionToXY(pos
, & x
, & y
);
814 // TODO: scroll to this position if necessary
818 void wxTextCtrl::SetInsertionPointEnd()
820 SetInsertionPoint(GetLastPosition());
823 long wxTextCtrl::GetInsertionPoint() const
825 return XYToPosition( m_cursorX
, m_cursorY
);
828 wxTextPos
wxTextCtrl::GetLastPosition() const
830 size_t lineCount
= m_lines
.GetCount() - 1;
831 // It's the length of the line, not the length - 1,
832 // because there's a position after the last character.
833 return XYToPosition( m_lines
[lineCount
].m_text
.Len(), lineCount
);
836 void wxTextCtrl::SetSelection(long from
, long to
)
840 void wxTextCtrl::SetEditable(bool editable
)
842 m_editable
= editable
;
845 bool wxTextCtrl::Enable( bool enable
)
850 bool wxTextCtrl::SetFont(const wxFont
& font
)
852 wxTextCtrlBase::SetFont( font
);
857 dc
.SetFont( m_sourceFont
);
858 m_lineHeight
= dc
.GetCharHeight();
859 m_charWidth
= dc
.GetCharWidth();
861 // TODO: recalc longest lines
863 MyAdjustScrollbars();
868 bool wxTextCtrl::SetForegroundColour(const wxColour
& colour
)
870 return wxWindow::SetForegroundColour( colour
);
873 bool wxTextCtrl::SetBackgroundColour(const wxColour
& colour
)
875 return wxWindow::SetBackgroundColour( colour
);
878 //-----------------------------------------------------------------------------
879 // private code and handlers
880 //-----------------------------------------------------------------------------
882 void wxTextCtrl::SearchForBrackets()
884 int oldBracketY
= m_bracketY
;
885 int oldBracketX
= m_bracketX
;
887 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()) return;
889 wxString current
= m_lines
[m_cursorY
].m_text
;
891 // reverse search first
896 bracket
= current
[(size_t) (m_cursorX
-1)];
898 if (bracket
== ')' || bracket
== ']' || bracket
== '}')
900 char antibracket
= '(';
901 if (bracket
== ']') antibracket
= '[';
902 if (bracket
== '}') antibracket
= '{';
906 int endY
= m_cursorY
-60;
907 if (endY
< 0) endY
= 0;
908 for (int y
= m_cursorY
; y
>= endY
; y
--)
910 current
= m_lines
[y
].m_text
;
912 current
.erase(m_cursorX
-1,current
.Len()-m_cursorX
+1);
914 for (int n
= current
.Len()-1; n
>= 0; n
--)
917 if (current
[(size_t) (n
)] == '\'')
919 for (int m
= n
-1; m
>= 0; m
--)
921 if (current
[(size_t) (m
)] == '\'')
923 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
932 if (current
[(size_t) (n
)] == '\"')
934 for (int m
= n
-1; m
>= 0; m
--)
936 if (current
[(size_t) (m
)] == '\"')
938 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
946 if (current
[(size_t) (n
)] == antibracket
)
953 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
954 RefreshLine( oldBracketY
);
955 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
956 RefreshLine( m_bracketY
);
960 else if (current
[(size_t) (n
)] == bracket
)
971 if ((int)current
.Len() > m_cursorX
)
972 bracket
= current
[(size_t) (m_cursorX
)];
973 if (bracket
== '(' || bracket
== '[' || bracket
== '{')
975 char antibracket
= ')';
976 if (bracket
== '[') antibracket
= ']';
977 if (bracket
== '{') antibracket
= '}';
981 int endY
= m_cursorY
+60;
982 if (endY
> (int)(m_lines
.GetCount()-1)) endY
= m_lines
.GetCount()-1;
983 for (int y
= m_cursorY
; y
<= endY
; y
++)
985 current
= m_lines
[y
].m_text
;
990 for (int n
= start
; n
< (int)current
.Len(); n
++)
993 if (current
[(size_t) (n
)] == '\'')
995 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
997 if (current
[(size_t) (m
)] == '\'')
999 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1008 if (current
[(size_t) (n
)] == '\"')
1010 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
1012 if (current
[(size_t) (m
)] == '\"')
1014 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1022 if (current
[(size_t) (n
)] == antibracket
)
1029 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
1030 RefreshLine( oldBracketY
);
1031 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
1032 RefreshLine( m_bracketY
);
1036 else if (current
[(size_t) (n
)] == bracket
)
1044 if (oldBracketY
!= -1)
1047 RefreshLine( oldBracketY
);
1051 void wxTextCtrl::Delete()
1053 if (!HasSelection()) return;
1057 int selStartY
= m_selStartY
;
1058 int selEndY
= m_selEndY
;
1059 int selStartX
= m_selStartX
;
1060 int selEndX
= m_selEndX
;
1062 if ((selStartY
> selEndY
) ||
1063 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1065 int tmp
= selStartX
;
1066 selStartX
= selEndX
;
1069 selStartY
= selEndY
;
1073 int len
= (int)m_lines
[selStartY
].m_text
.Len();
1075 if (selStartY
== selEndY
)
1077 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, selStartY
, selStartY
, this ) );
1079 wxString
tmp( m_lines
[selStartY
].m_text
);
1080 if (selStartX
< len
)
1084 tmp
.Remove( selStartX
, selEndX
-selStartX
);
1085 m_lines
[selStartY
].m_text
= tmp
;
1088 m_cursorX
= selStartX
;
1089 RefreshLine( selStartY
);
1093 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, selStartY
, selEndY
, this ) );
1095 if (selStartX
< len
)
1096 m_lines
[selStartY
].m_text
.Remove( selStartX
);
1098 for (int i
= 0; i
< selEndY
-selStartY
-1; i
++)
1099 m_lines
.RemoveAt( selStartY
+1 );
1101 if (selEndX
< (int)m_lines
[selStartY
+1].m_text
.Len())
1102 m_lines
[selStartY
+1].m_text
.Remove( 0, selEndX
);
1104 m_lines
[selStartY
+1].m_text
.Remove( 0 );
1106 m_lines
[selStartY
].m_text
.Append( m_lines
[selStartY
+1].m_text
);
1107 m_lines
.RemoveAt( selStartY
+1 );
1110 MoveCursor( selStartX
, selStartY
);
1111 MyAdjustScrollbars();
1113 RefreshDown( selStartY
);
1117 void wxTextCtrl::DeleteLine()
1119 if (HasSelection()) return;
1121 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()-1) return; // TODO
1123 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1125 m_lines
.RemoveAt( m_cursorY
);
1127 if (m_cursorY
>= (int)m_lines
.GetCount()) m_cursorY
--;
1129 MyAdjustScrollbars();
1130 RefreshDown( m_cursorY
);
1133 void wxTextCtrl::DoChar( char c
)
1137 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1139 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1141 if (m_cursorX
>= (int)tmp
.Len())
1143 int len
= tmp
.Len();
1144 for (int i
= 0; i
< m_cursorX
- len
; i
++)
1151 tmp
.SetChar( m_cursorX
, c
);
1153 tmp
.insert( m_cursorX
, 1, c
);
1156 m_lines
[m_cursorY
].m_text
= tmp
;
1158 // if (tmp.Len() > m_longestLine)
1160 // m_longestLine = tmp.Len();
1161 // MyAdjustScrollbars();
1165 GetTextExtent( tmp
, &ww
, NULL
, NULL
, NULL
);
1167 if (ww
> m_longestLine
)
1170 MyAdjustScrollbars();
1175 int y
= m_cursorY
*m_lineHeight
;
1176 // int x = (m_cursorX-1)*m_charWidth;
1177 int x
= PosToPixel( m_cursorY
, m_cursorX
-1 );
1178 CalcScrolledPosition( x
, y
, &x
, &y
);
1179 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1180 Refresh( true, &rect
);
1181 // refresh whole line for syntax colour highlighting
1183 Refresh( false, &rect
);
1187 GetClientSize( &size_x
, &size_y
);
1188 size_x
/= m_charWidth
;
1192 GetViewStart( &view_x
, &view_y
);
1194 //int xx = m_cursorX;
1195 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
1199 else if (xx
> view_x
+size_x
-1)
1200 Scroll( xx
-size_x
+1, -1 );
1203 void wxTextCtrl::DoBack()
1209 if (m_cursorY
== 0) return;
1211 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_BACK
, m_cursorY
-1, m_cursorY
, this ) );
1213 wxString
tmp1( m_lines
[m_cursorY
-1].m_text
);
1215 wxString
tmp2( m_lines
[m_cursorY
].m_text
);
1217 m_cursorX
= tmp1
.Len();
1219 tmp1
.Append( tmp2
);
1220 m_lines
[m_cursorY
].m_text
= tmp1
;
1221 m_lines
.RemoveAt( m_cursorY
+1 );
1223 MyAdjustScrollbars();
1224 RefreshDown( m_cursorY
-1 );
1228 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1230 if (m_cursorX
<= (int)m_lines
[m_cursorY
].m_text
.Len())
1231 m_lines
[m_cursorY
].m_text
.Remove( m_cursorX
-1, 1 );
1234 int y
= m_cursorY
*m_lineHeight
;
1235 // int x = m_cursorX*m_charWidth;
1236 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1237 CalcScrolledPosition( x
, y
, &x
, &y
);
1238 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1239 Refresh( true, &rect
);
1240 // refresh whole line for syntax colour highlighting
1242 Refresh( false, &rect
);
1246 void wxTextCtrl::DoDelete()
1250 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1252 int len
= (int)tmp
.Len();
1253 if (m_cursorX
>= len
)
1255 if (m_cursorY
== (int)m_lines
.GetCount()-1) return;
1257 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1259 for (int i
= 0; i
< (m_cursorX
-len
); i
++)
1262 tmp
+= m_lines
[m_cursorY
+1].m_text
;
1264 m_lines
[m_cursorY
] = tmp
;
1265 m_lines
.RemoveAt( m_cursorY
+1 );
1267 MyAdjustScrollbars();
1268 RefreshDown( m_cursorY
);
1272 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1274 tmp
.Remove( m_cursorX
, 1 );
1275 m_lines
[m_cursorY
].m_text
= tmp
;
1277 int y
= m_cursorY
*m_lineHeight
;
1278 // int x = m_cursorX*m_charWidth;
1279 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1280 CalcScrolledPosition( x
, y
, &x
, &y
);
1281 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1282 Refresh( true, &rect
);
1283 // refresh whole line for syntax colour highlighting
1285 Refresh( false, &rect
);
1289 void wxTextCtrl::DoReturn()
1293 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_ENTER
, m_cursorY
, m_cursorY
, this ) );
1295 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1296 size_t indent
= tmp
.find_first_not_of( ' ' );
1297 if (indent
== wxSTRING_MAXLEN
) indent
= 0;
1299 if (m_cursorX
>= (int)tmp
.Len())
1301 int cursorX
= indent
;
1302 int cursorY
= m_cursorY
+ 1;
1305 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1306 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1308 MyAdjustScrollbars();
1309 MoveCursor( cursorX
, cursorY
);
1310 RefreshDown( m_cursorY
);
1314 wxString
tmp1( tmp
);
1315 tmp1
.Remove( m_cursorX
, tmp
.Len()-m_cursorX
);
1316 m_lines
[m_cursorY
].m_text
= tmp1
;
1318 wxString
tmp2( tmp
);
1319 tmp2
.Remove( 0, m_cursorX
);
1321 int cursorX
= indent
;
1322 int cursorY
= m_cursorY
+ 1;
1325 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1326 new_tmp
.Append( tmp2
);
1327 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1329 MyAdjustScrollbars();
1330 MoveCursor( cursorX
, cursorY
);
1331 RefreshDown( m_cursorY
-1 );
1335 void wxTextCtrl::DoDClick()
1337 wxString
line( m_lines
[ m_cursorY
].m_text
);
1338 if (m_cursorX
>= (int)line
.Len()) return;
1340 char ch
= line
[(size_t) (p
)];
1341 if (((ch
>= 'a') && (ch
<= 'z')) ||
1342 ((ch
>= 'A') && (ch
<= 'Z')) ||
1343 ((ch
>= '0') && (ch
<= '9')) ||
1346 m_selStartY
= m_cursorY
;
1347 m_selEndY
= m_cursorY
;
1350 ch
= line
[(size_t) (p
-1)];
1351 while (((ch
>= 'a') && (ch
<= 'z')) ||
1352 ((ch
>= 'A') && (ch
<= 'Z')) ||
1353 ((ch
>= '0') && (ch
<= '9')) ||
1358 ch
= line
[(size_t) (p
-1)];
1364 if (p
< (int)line
.Len())
1366 ch
= line
[(size_t) (p
)];
1367 while (((ch
>= 'a') && (ch
<= 'z')) ||
1368 ((ch
>= 'A') && (ch
<= 'Z')) ||
1369 ((ch
>= '0') && (ch
<= '9')) ||
1372 if (p
>= (int)line
.Len()) break;
1374 ch
= line
[(size_t) (p
)];
1378 RefreshLine( m_cursorY
);
1382 wxString
wxTextCtrl::GetNextToken( wxString
&line
, size_t &pos
)
1385 size_t len
= line
.Len();
1386 for (size_t p
= pos
; p
< len
; p
++)
1388 if ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
))
1392 for (size_t q
= p
; q
< len
; q
++)
1393 ret
.Append( line
[q
] );
1400 if ((line
[p
] == '/') && (p
+1 < len
) && (line
[(size_t) (p
+1)] == '/'))
1402 for (size_t q
= p
; q
< len
; q
++)
1403 ret
.Append( line
[q
] );
1411 ret
.Append( line
[p
] );
1412 for (size_t q
= p
+1; q
< len
; q
++)
1414 ret
.Append( line
[q
] );
1415 if ((line
[q
] == '"') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1422 if (line
[p
] == '\'')
1424 ret
.Append( line
[p
] );
1425 for (size_t q
= p
+1; q
< len
; q
++)
1427 ret
.Append( line
[q
] );
1428 if ((line
[q
] == '\'') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1435 if (((line
[p
] >= 'a') && (line
[p
] <= 'z')) ||
1436 ((line
[p
] >= 'A') && (line
[p
] <= 'Z')) ||
1440 ret
.Append( line
[p
] );
1441 for (size_t q
= p
+1; q
< len
; q
++)
1443 if (((line
[q
] >= 'a') && (line
[q
] <= 'z')) ||
1444 ((line
[q
] >= 'A') && (line
[q
] <= 'Z')) ||
1445 ((line
[q
] >= '0') && (line
[q
] <= '9')) ||
1448 ret
.Append( line
[q
] );
1465 void wxTextCtrl::OnEraseBackground( wxEraseEvent
&event
)
1470 void wxTextCtrl::DrawLinePart( wxDC
&dc
, int x
, int y
, const wxString
&toDraw
, const wxString
&origin
, const wxColour
&colour
)
1473 size_t len
= origin
.Len();
1474 dc
.SetTextForeground( colour
);
1477 while (toDraw
[pos
] == wxT(' '))
1480 if (pos
== len
) return;
1486 current
+= toDraw
[pos
];
1488 while ( (toDraw
[pos
] == origin
[pos
]) && (pos
< len
))
1490 current
+= toDraw
[pos
];
1495 wxString tmp
= origin
.Left( start
);
1496 GetTextExtent( tmp
, &xx
, NULL
, NULL
, NULL
);
1499 dc
.DrawText( current
, xx
, yy
);
1503 void wxTextCtrl::DrawLine( wxDC
&dc
, int x
, int y
, const wxString
&line2
, int lineNum
)
1505 int selStartY
= m_selStartY
;
1506 int selEndY
= m_selEndY
;
1507 int selStartX
= m_selStartX
;
1508 int selEndX
= m_selEndX
;
1510 if ((selStartY
> selEndY
) ||
1511 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1513 int tmp
= selStartX
;
1514 selStartX
= selEndX
;
1517 selStartY
= selEndY
;
1521 wxString
line( line2
);
1522 if (HasFlag(wxTE_PASSWORD
))
1524 size_t len
= line
.Len();
1525 line
= wxString( wxT('*'), len
);
1528 wxString
keyword( ' ', line
.Len() );
1529 wxString
define( ' ', line
.Len() );
1530 wxString
variable( ' ', line
.Len() );
1531 wxString
comment( ' ', line
.Len() );
1532 wxString
my_string( ' ', line
.Len() );
1533 wxString
selection( ' ', line
.Len() );
1535 if (m_lang
!= wxSOURCE_LANG_NONE
)
1537 if (lineNum
== m_bracketY
)
1539 wxString
red( ' ', line
.Len() );
1540 if (m_bracketX
< (int)line
.Len())
1542 red
.SetChar( m_bracketX
, line
[(size_t) (m_bracketX
)] );
1543 line
.SetChar( m_bracketX
, ' ' );
1544 dc
.SetTextForeground( *wxRED
);
1545 dc
.DrawText( red
, x
, y
);
1546 dc
.SetTextForeground( *wxBLACK
);
1551 wxString
token( GetNextToken( line
, pos
) );
1552 while (!token
.IsNull())
1554 if (m_keywords
.Index( token
) != wxNOT_FOUND
)
1556 size_t end_pos
= pos
+ token
.Len();
1557 for (size_t i
= pos
; i
< end_pos
; i
++)
1559 keyword
[i
] = line
[i
];
1563 if (m_defines
.Index( token
) != wxNOT_FOUND
)
1565 size_t end_pos
= pos
+ token
.Len();
1566 for (size_t i
= pos
; i
< end_pos
; i
++)
1568 define
[i
] = line
[i
];
1572 if ((m_variables
.Index( token
) != wxNOT_FOUND
) ||
1573 ((token
.Len() > 2) && (token
[(size_t) (0)] == 'w') && (token
[(size_t) (1)] == 'x')))
1575 size_t end_pos
= pos
+ token
.Len();
1576 for (size_t i
= pos
; i
< end_pos
; i
++)
1578 variable
[i
] = line
[i
];
1582 if ((token
.Len() >= 2) && (token
[(size_t) (0)] == '/') && (token
[(size_t) (1)] == '/') && (m_lang
== wxSOURCE_LANG_CPP
))
1584 size_t end_pos
= pos
+ token
.Len();
1585 for (size_t i
= pos
; i
< end_pos
; i
++)
1587 comment
[i
] = line
[i
];
1591 if ((token
[(size_t) (0)] == '#') &&
1592 ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
)))
1594 size_t end_pos
= pos
+ token
.Len();
1595 for (size_t i
= pos
; i
< end_pos
; i
++)
1597 comment
[i
] = line
[i
];
1601 if ((token
[(size_t) (0)] == '"') || (token
[(size_t) (0)] == '\''))
1603 size_t end_pos
= pos
+ token
.Len();
1604 for (size_t i
= pos
; i
< end_pos
; i
++)
1606 my_string
[i
] = line
[i
];
1611 token
= GetNextToken( line
, pos
);
1615 if ((lineNum
< selStartY
) || (lineNum
> selEndY
))
1617 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1618 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1619 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1620 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1621 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1622 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1623 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1627 if (selStartY
== selEndY
)
1629 // int xx = selStartX*m_charWidth;
1630 int xx
= PosToPixel( lineNum
, selStartX
);
1631 // int ww = (selEndX-selStartX)*m_charWidth;
1632 int ww
= PosToPixel( lineNum
, selEndX
) - xx
;
1633 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1635 for (size_t i
= (size_t)selStartX
; i
< (size_t)selEndX
; i
++)
1637 selection
[i
] = line
[i
];
1641 if ((lineNum
> selStartY
) && (lineNum
< selEndY
))
1643 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1645 for (size_t i
= 0; i
< line
.Len(); i
++)
1647 selection
[i
] = line
[i
];
1651 if (lineNum
== selStartY
)
1653 // int xx = selStartX*m_charWidth;
1654 int xx
= PosToPixel( lineNum
, selStartX
);
1655 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1657 for (size_t i
= (size_t)selStartX
; i
< line
.Len(); i
++)
1659 selection
[i
] = line
[i
];
1663 if (lineNum
== selEndY
)
1665 // int ww = selEndX*m_charWidth;
1666 int ww
= PosToPixel( lineNum
, selEndX
);
1667 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1669 for (size_t i
= 0; i
< (size_t)selEndX
; i
++)
1671 selection
[i
] = line
[i
];
1676 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1677 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1678 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1679 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1680 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1681 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1682 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1685 void wxTextCtrl::OnPaint( wxPaintEvent
&event
)
1689 if (m_lines
.GetCount() == 0) return;
1693 dc
.SetFont( m_sourceFont
);
1696 GetViewStart( NULL
, &scroll_y
);
1698 // We have a inner border of two pixels
1699 // around the text, so scroll units do
1700 // not correspond to lines.
1701 if (scroll_y
> 0) scroll_y
--;
1705 GetClientSize( &size_x
, &size_y
);
1707 dc
.SetPen( *wxTRANSPARENT_PEN
);
1708 dc
.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT
), wxSOLID
) );
1709 int upper
= wxMin( (int)m_lines
.GetCount(), scroll_y
+(size_y
/m_lineHeight
)+2 );
1710 for (int i
= scroll_y
; i
< upper
; i
++)
1713 int y
= i
*m_lineHeight
+2;
1715 int h
= m_lineHeight
;
1716 CalcScrolledPosition( x
,y
,&x
,&y
);
1717 if (IsExposed(x
,y
,w
,h
))
1718 DrawLine( dc
, 0+2, i
*m_lineHeight
+2, m_lines
[i
].m_text
, i
);
1721 if (m_editable
&& (FindFocus() == this))
1723 ///dc.SetBrush( *wxRED_BRUSH );
1724 dc
.SetBrush( *wxBLACK_BRUSH
);
1725 // int xx = m_cursorX*m_charWidth;
1726 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
1727 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
1731 void wxTextCtrl::OnMouse( wxMouseEvent
&event
)
1733 if (m_lines
.GetCount() == 0) return;
1736 #if 0 // there is no middle button on iPAQs
1737 if (event
.MiddleDown())
1744 if (event
.LeftDClick())
1750 if (event
.LeftDown())
1758 m_capturing
= false;
1762 if (event
.LeftDown() ||
1763 (event
.LeftIsDown() && m_capturing
))
1765 int x
= event
.GetX();
1766 int y
= event
.GetY();
1767 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1769 // x /= m_charWidth;
1770 x
= PixelToPos( y
, x
);
1772 wxMin( 1000, wxMax( 0, x
) ),
1773 wxMin( (int)m_lines
.GetCount()-1, wxMax( 0, y
) ),
1774 event
.ShiftDown() || !event
.LeftDown() );
1778 void wxTextCtrl::OnChar( wxKeyEvent
&event
)
1780 if (m_lines
.GetCount() == 0) return;
1782 if (!m_editable
) return;
1786 GetClientSize( &size_x
, &size_y
);
1787 size_x
/= m_charWidth
;
1788 size_y
/= m_lineHeight
;
1791 if (event
.ShiftDown())
1793 switch (event
.GetKeyCode())
1795 case '4': event
.m_keyCode
= WXK_LEFT
; break;
1796 case '8': event
.m_keyCode
= WXK_UP
; break;
1797 case '6': event
.m_keyCode
= WXK_RIGHT
; break;
1798 case '2': event
.m_keyCode
= WXK_DOWN
; break;
1799 case '9': event
.m_keyCode
= WXK_PRIOR
; break;
1800 case '3': event
.m_keyCode
= WXK_NEXT
; break;
1801 case '7': event
.m_keyCode
= WXK_HOME
; break;
1802 case '1': event
.m_keyCode
= WXK_END
; break;
1803 case '0': event
.m_keyCode
= WXK_INSERT
; break;
1807 switch (event
.GetKeyCode())
1811 if (m_ignoreInput
) return;
1813 MoveCursor( m_cursorX
, m_cursorY
-1, event
.ShiftDown() );
1814 m_ignoreInput
= true;
1819 if (m_ignoreInput
) return;
1820 if (m_cursorY
< (int)(m_lines
.GetCount()-1))
1821 MoveCursor( m_cursorX
, m_cursorY
+1, event
.ShiftDown() );
1822 m_ignoreInput
= true;
1827 if (m_ignoreInput
) return;
1830 MoveCursor( m_cursorX
-1, m_cursorY
, event
.ShiftDown() );
1835 MoveCursor( m_lines
[m_cursorY
-1].m_text
.Len(), m_cursorY
-1, event
.ShiftDown() );
1837 m_ignoreInput
= true;
1842 if (m_ignoreInput
) return;
1843 if (m_cursorX
< 1000)
1844 MoveCursor( m_cursorX
+1, m_cursorY
, event
.ShiftDown() );
1845 m_ignoreInput
= true;
1850 if (event
.ControlDown())
1851 MoveCursor( 0, 0, event
.ShiftDown() );
1853 MoveCursor( 0, m_cursorY
, event
.ShiftDown() );
1858 if (event
.ControlDown())
1859 MoveCursor( 0, m_lines
.GetCount()-1, event
.ShiftDown() );
1861 MoveCursor( m_lines
[m_cursorY
].m_text
.Len(), m_cursorY
, event
.ShiftDown() );
1866 if (m_ignoreInput
) return;
1867 MoveCursor( m_cursorX
, wxMin( (int)(m_lines
.GetCount()-1), m_cursorY
+size_y
), event
.ShiftDown() );
1868 m_ignoreInput
= true;
1873 if (m_ignoreInput
) return;
1874 MoveCursor( m_cursorX
, wxMax( 0, m_cursorY
-size_y
), event
.ShiftDown() );
1875 m_ignoreInput
= true;
1880 if (event
.ShiftDown())
1882 else if (event
.ControlDown())
1885 m_overwrite
= !m_overwrite
;
1890 if (m_windowStyle
& wxPROCESS_ENTER
)
1892 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1893 event
.SetEventObject(this);
1894 event
.SetString(GetValue());
1895 if (GetEventHandler()->ProcessEvent(event
)) return;
1913 bool save_overwrite
= m_overwrite
;
1914 m_overwrite
= false;
1915 int i
= 4-(m_cursorX
% 4);
1917 for (int c
= 0; c
< i
; c
++)
1919 m_overwrite
= save_overwrite
;
1940 if ( (event
.GetKeyCode() >= 'a') &&
1941 (event
.GetKeyCode() <= 'z') &&
1949 if ( (event
.GetKeyCode() >= 32) &&
1950 (event
.GetKeyCode() <= 255) &&
1951 !(event
.ControlDown() && !event
.AltDown()) ) // filters out Ctrl-X but leaves Alt-Gr
1955 DoChar( (char) event
.GetKeyCode() );
1964 void wxTextCtrl::OnInternalIdle()
1966 wxControl::OnInternalIdle();
1968 m_ignoreInput
= false;
1970 if (m_lang
!= wxSOURCE_LANG_NONE
)
1971 SearchForBrackets();
1974 void wxTextCtrl::Indent()
1976 int startY
= m_cursorY
;
1977 int endY
= m_cursorY
;
1980 startY
= m_selStartY
;
1990 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1992 for (int i
= startY
; i
<= endY
; i
++)
1994 m_lines
[i
].m_text
.insert( 0u, wxT(" ") );
1999 void wxTextCtrl::Unindent()
2001 int startY
= m_cursorY
;
2002 int endY
= m_cursorY
;
2005 startY
= m_selStartY
;
2015 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
2017 for (int i
= startY
; i
<= endY
; i
++)
2019 for (int n
= 0; n
< 4; n
++)
2021 if (m_lines
[i
].m_text
[0u] == wxT(' '))
2022 m_lines
[i
].m_text
.erase(0u,1u);
2027 bool wxTextCtrl::HasSelection()
2029 return ((m_selStartY
!= m_selEndY
) || (m_selStartX
!= m_selEndX
));
2032 void wxTextCtrl::ClearSelection()
2040 void wxTextCtrl::RefreshLine( int n
)
2042 int y
= n
*m_lineHeight
;
2044 CalcScrolledPosition( x
, y
, &x
, &y
);
2045 wxRect
rect( 0+2, y
+2, 10000, m_lineHeight
);
2046 Refresh( true, &rect
);
2049 void wxTextCtrl::RefreshDown( int n
)
2053 GetClientSize( &size_x
, &size_y
);
2057 GetViewStart( &view_x
, &view_y
);
2065 int y
= n
*m_lineHeight
;
2067 CalcScrolledPosition( x
, y
, &x
, &y
);
2069 wxRect
rect( 0+2, y
+2, 10000, size_y
);
2070 Refresh( true, &rect
);
2074 void wxTextCtrl::MoveCursor( int new_x
, int new_y
, bool shift
, bool centre
)
2076 if (!m_editable
) return;
2078 // if (IsSingleLine() || (m_lang == wxSOURCE_LANG_NONE))
2080 if (new_x
> (int) (m_lines
[new_y
].m_text
.Len()))
2081 new_x
= m_lines
[new_y
].m_text
.Len();
2084 if ((new_x
== m_cursorX
) && (new_y
== m_cursorY
)) return;
2086 bool no_cursor_refresh
= false;
2087 bool has_selection
= HasSelection();
2092 bool erase_background
= true;
2096 m_selStartX
= m_cursorX
;
2097 m_selStartY
= m_cursorY
;
2101 if (new_y
> m_selStartY
)
2103 y
= m_selStartY
*m_lineHeight
;
2104 h
= (new_y
-m_selStartY
+1)*m_lineHeight
;
2106 else if (new_y
== m_selStartY
)
2108 x
= PosToPixel( new_y
, m_selStartX
);
2109 w
= PosToPixel( new_y
, new_x
) - x
;
2113 w
= -w
+ 2; // +2 for the cursor
2115 y
= m_selStartY
*m_lineHeight
;
2120 y
= new_y
*m_lineHeight
;
2121 h
= (-new_y
+m_selStartY
+1)*m_lineHeight
;
2124 no_cursor_refresh
= true;
2130 if (new_y
== m_selEndY
)
2132 y
= new_y
*m_lineHeight
;
2134 if (m_selEndX
> new_x
)
2136 // x = new_x*m_charWidth;
2137 x
= PosToPixel( new_y
, new_x
);
2138 // w = (m_selEndX-new_x)*m_charWidth;
2139 w
= PosToPixel( new_y
, m_selEndX
) - x
;
2143 // x = m_selEndX*m_charWidth;
2144 x
= PosToPixel( new_y
, m_selEndX
);
2145 // w = (-m_selEndX+new_x)*m_charWidth;
2146 w
= PosToPixel( new_y
, new_x
) - x
;
2153 if (new_y
> m_selEndY
)
2155 y
= m_selEndY
*m_lineHeight
;
2156 h
= (new_y
-m_selEndY
+1) * m_lineHeight
;
2158 erase_background
= ((m_selEndY
< m_selStartY
) ||
2159 ((m_selEndY
== m_selStartY
) && (m_selEndX
< m_selStartX
)));
2163 y
= new_y
*m_lineHeight
;
2164 h
= (-new_y
+m_selEndY
+1) * m_lineHeight
;
2166 erase_background
= ((m_selEndY
> m_selStartY
) ||
2167 ((m_selEndY
== m_selStartY
) && (m_selEndX
> m_selStartX
)));
2169 no_cursor_refresh
= true;
2178 CalcScrolledPosition( x
, y
, &x
, &y
);
2179 wxRect
rect( x
+2, y
+2, w
, h
);
2180 Refresh( erase_background
, &rect
);
2186 int ry1
= m_selEndY
;
2187 int ry2
= m_selStartY
;
2201 int y
= ry1
*m_lineHeight
;
2202 CalcScrolledPosition( x
, y
, &x
, &y
);
2203 wxRect
rect( 0, y
+2, 10000, (ry2
-ry1
+1)*m_lineHeight
);
2205 Refresh( true, &rect
);
2210 printf( "startx %d starty %d endx %d endy %d\n",
2211 m_selStartX, m_selStartY, m_selEndX, m_selEndY );
2213 printf( "has %d\n", (int)HasSelection() );
2216 if (!no_cursor_refresh
)
2218 // int x = m_cursorX*m_charWidth;
2219 int x
= PosToPixel( m_cursorY
, m_cursorX
);
2220 int y
= m_cursorY
*m_lineHeight
;
2221 CalcScrolledPosition( x
, y
, &x
, &y
);
2222 wxRect
rect( x
+2, y
+2, 4, m_lineHeight
+2 );
2227 Refresh( true, &rect
);
2229 if (FindFocus() == this)
2231 wxClientDC
dc(this);
2233 dc
.SetPen( *wxTRANSPARENT_PEN
);
2234 //dc.SetBrush( *wxRED_BRUSH );
2235 dc
.SetBrush( *wxBLACK_BRUSH
);
2236 // int xx = m_cursorX*m_charWidth;
2237 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
2238 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
2244 GetClientSize( &size_x
, &size_y
);
2245 size_x
/= m_charWidth
;
2246 size_y
/= m_lineHeight
;
2250 GetViewStart( &view_x
, &view_y
);
2254 int sy
= m_cursorY
- (size_y
/2);
2260 if (m_cursorY
< view_y
)
2261 Scroll( -1, m_cursorY
);
2262 else if (m_cursorY
> view_y
+size_y
-1)
2263 Scroll( -1, m_cursorY
-size_y
+1 );
2266 //int xx = m_cursorX;
2267 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
2271 else if (xx
> view_x
+size_x
-1)
2272 Scroll( xx
-size_x
+1, -1 );
2275 void wxTextCtrl::MyAdjustScrollbars()
2280 int y_range
= m_lines
.GetCount();
2283 GetClientSize( NULL
, &height
);
2285 if (height
>= (int)m_lines
.GetCount() *m_lineHeight
)
2290 GetViewStart( &view_x
, &view_y
);
2292 SetScrollbars( m_charWidth
, m_lineHeight
, m_longestLine
+2, y_range
, view_x
, view_y
);
2295 //-----------------------------------------------------------------------------
2296 // clipboard handlers
2297 //-----------------------------------------------------------------------------
2299 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
2304 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
2309 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
2314 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
2319 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
2324 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2326 event
.Enable( CanCut() );
2329 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2331 event
.Enable( CanCopy() );
2334 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2336 event
.Enable( CanPaste() );
2339 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2341 event
.Enable( CanUndo() );
2344 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2346 event
.Enable( CanRedo() );
2349 wxSize
wxTextCtrl::DoGetBestSize() const
2353 wxSize
ret(80, m_lineHeight
+ 4);
2355 if (HasFlag(wxBORDER_SUNKEN
) || HasFlag(wxBORDER_RAISED
))
2358 if (HasFlag(wxBORDER_SIMPLE
))
2365 return wxSize(80, 60);
2369 // ----------------------------------------------------------------------------
2371 // ----------------------------------------------------------------------------
2373 void wxTextCtrl::Freeze()
2377 void wxTextCtrl::Thaw()
2381 void wxTextCtrl::OnSetFocus( wxFocusEvent
& event
)
2383 // To hide or show caret, as appropriate
2387 void wxTextCtrl::OnKillFocus( wxFocusEvent
& event
)
2389 // To hide or show caret, as appropriate
2393 // ----------------------------------------------------------------------------
2394 // text control scrolling
2395 // ----------------------------------------------------------------------------
2397 bool wxTextCtrl::ScrollLines(int lines
)
2399 wxFAIL_MSG( "wxTextCtrl::ScrollLines not implemented");
2404 bool wxTextCtrl::ScrollPages(int pages
)
2406 wxFAIL_MSG( "wxTextCtrl::ScrollPages not implemented");