1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
11 #pragma implementation "textctrl.h"
14 #include "wx/textctrl.h"
19 #include "wx/settings.h"
21 #include "wx/clipbrd.h"
22 #include "wx/tokenzr.h"
23 #include "wx/dcclient.h"
25 #include "wx/univ/inphand.h"
26 #include "wx/univ/renderer.h"
27 #include "wx/univ/colschem.h"
28 #include "wx/univ/theme.h"
30 //-----------------------------------------------------------------------------
32 //-----------------------------------------------------------------------------
34 wxSourceUndoStep::wxSourceUndoStep( wxSourceUndo type
, int y1
, int y2
, wxTextCtrl
*owner
)
41 m_cursorX
= m_owner
->GetCursorX();
42 m_cursorY
= m_owner
->GetCursorY();
44 if (m_type
== wxSOURCE_UNDO_LINE
)
46 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
48 if (m_type
== wxSOURCE_UNDO_ENTER
)
50 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
52 if (m_type
== wxSOURCE_UNDO_BACK
)
54 for (int i
= m_y1
; i
< m_y2
+2; i
++)
56 if (i
>= (int)m_owner
->m_lines
.GetCount())
57 m_lines
.Add( wxT("") );
59 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
62 if (m_type
== wxSOURCE_UNDO_DELETE
)
64 for (int i
= m_y1
; i
< m_y2
+1; i
++)
66 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
69 if (m_type
== wxSOURCE_UNDO_PASTE
)
71 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
75 void wxSourceUndoStep::Undo()
77 if (m_type
== wxSOURCE_UNDO_LINE
)
79 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
80 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
81 m_owner
->RefreshLine( m_y1
);
83 if (m_type
== wxSOURCE_UNDO_ENTER
)
85 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
86 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
87 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
88 m_owner
->RefreshDown( m_y1
);
90 if (m_type
== wxSOURCE_UNDO_BACK
)
92 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
93 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[1] ), m_y1
+1 );
94 m_owner
->MyAdjustScrollbars();
95 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
96 m_owner
->RefreshDown( m_y1
);
98 if (m_type
== wxSOURCE_UNDO_DELETE
)
100 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
101 for (int i
= 1; i
< (int)m_lines
.GetCount(); i
++)
102 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[i
] ), m_y1
+i
);
103 m_owner
->MyAdjustScrollbars();
104 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
105 m_owner
->RefreshDown( m_y1
);
107 if (m_type
== wxSOURCE_UNDO_PASTE
)
109 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
110 for (int i
= 0; i
< m_y2
-m_y1
; i
++)
111 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
112 m_owner
->MyAdjustScrollbars();
113 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
114 m_owner
->RefreshDown( m_y1
);
116 if (m_type
== wxSOURCE_UNDO_INSERT_LINE
)
118 m_owner
->m_lines
.RemoveAt( m_y1
);
119 m_owner
->MyAdjustScrollbars();
120 m_owner
->MoveCursor( 0, m_y1
);
121 m_owner
->RefreshDown( m_y1
);
125 #include "wx/arrimpl.cpp"
126 WX_DEFINE_OBJARRAY(wxSourceLineArray
);
128 //-----------------------------------------------------------------------------
130 //-----------------------------------------------------------------------------
132 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
,wxControl
)
134 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
135 EVT_PAINT(wxTextCtrl::OnPaint
)
136 EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground
)
137 EVT_CHAR(wxTextCtrl::OnChar
)
138 EVT_MOUSE_EVENTS(wxTextCtrl::OnMouse
)
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_lang
= wxSOURCE_LANG_NONE
;
173 m_ignoreInput
= false;
177 m_keywordColour
= wxColour( 10, 140, 10 );
179 m_defineColour
= *wxRED
;
181 m_variableColour
= wxColour( 50, 120, 150 );
183 m_commentColour
= wxColour( 130, 130, 130 );
185 m_stringColour
= wxColour( 10, 140, 10 );
188 wxTextCtrl::wxTextCtrl( wxWindow
*parent
,
190 const wxString
&value
,
194 const wxValidator
& validator
,
195 const wxString
&name
)
196 : wxScrollHelper(this)
200 Create( parent
, id
, value
, pos
, size
, style
, validator
, name
);
203 wxTextCtrl::~wxTextCtrl()
205 WX_CLEAR_LIST(wxList
, m_undos
);
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
, pos
/* wxDefaultPosition */, size
,
224 style
| wxVSCROLL
| wxHSCROLL
);
226 SetBackgroundColour( *wxWHITE
);
228 SetCursor( wxCursor( wxCURSOR_IBEAM
) );
230 m_editable
= ((m_windowStyle
& wxTE_READONLY
) == 0);
232 if (HasFlag(wxTE_PASSWORD
))
233 m_sourceFont
= wxFont( 12, wxMODERN
, wxNORMAL
, wxNORMAL
);
235 m_sourceFont
= GetFont();
238 dc
.SetFont( m_sourceFont
);
239 m_lineHeight
= dc
.GetCharHeight();
240 m_charWidth
= dc
.GetCharWidth();
244 wxSize
size_best( DoGetBestSize() );
245 wxSize
new_size( size
);
246 if (new_size
.x
== -1)
247 new_size
.x
= size_best
.x
;
248 if (new_size
.y
== -1)
249 new_size
.y
= size_best
.y
;
250 if ((new_size
.x
!= size
.x
) || (new_size
.y
!= size
.y
))
251 SetSize( new_size
.x
, new_size
.y
);
253 // We create an input handler since it might be useful
254 CreateInputHandler(wxINP_HANDLER_TEXTCTRL
);
256 MyAdjustScrollbars();
261 //-----------------------------------------------------------------------------
263 //-----------------------------------------------------------------------------
265 wxString
wxTextCtrl::GetValue() const
268 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
270 ret
+= m_lines
[i
].m_text
;
271 if (i
+1 < m_lines
.GetCount())
278 void wxTextCtrl::SetValue(const wxString
& value
)
282 wxString oldValue
= GetValue();
292 m_lines
.Add( new wxSourceLine( wxT("") ) );
300 pos
= value
.find( wxT('\n'), begin
);
303 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, value
.Len()-begin
) );
306 // if (sl->m_text.Len() > m_longestLine)
307 // m_longestLine = sl->m_text.Len();
309 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
311 if (ww
> m_longestLine
)
318 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, pos
-begin
) );
321 // if (sl->m_text.Len() > m_longestLine)
322 // m_longestLine = sl->m_text.Len();
324 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
326 if (ww
> m_longestLine
)
334 // Don't need to refresh if the value hasn't changed
335 if ((GetWindowStyle() & wxTE_MULTILINE
) == 0)
337 if (value
== oldValue
)
341 MyAdjustScrollbars();
346 int wxTextCtrl::GetLineLength(long lineNo
) const
348 if (lineNo
>= (long)m_lines
.GetCount())
351 return m_lines
[lineNo
].m_text
.Len();
354 wxString
wxTextCtrl::GetLineText(long lineNo
) const
356 if (lineNo
>= (long)m_lines
.GetCount())
359 return m_lines
[lineNo
].m_text
;
362 int wxTextCtrl::GetNumberOfLines() const
364 return m_lines
.GetCount();
367 bool wxTextCtrl::IsModified() const
372 bool wxTextCtrl::IsEditable() const
377 void wxTextCtrl::GetSelection(long* from
, long* to
) const
379 if (m_selStartX
== -1 || m_selStartY
== -1 ||
380 m_selEndX
== -1 || m_selEndY
== -1)
382 *from
= GetInsertionPoint();
383 *to
= GetInsertionPoint();
387 *from
= XYToPosition(m_selStartX
, m_selStartY
);
388 *to
= XYToPosition(m_selEndX
, m_selEndY
);
392 void wxTextCtrl::Clear()
400 m_lines
.Add( new wxSourceLine( wxT("") ) );
402 SetScrollbars( m_charWidth
, m_lineHeight
, 0, 0, 0, 0 );
404 WX_CLEAR_LIST(wxList
, m_undos
);
407 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
411 void wxTextCtrl::Remove(long from
, long to
)
415 void wxTextCtrl::DiscardEdits()
421 void wxTextCtrl::SetMaxLength(unsigned long len
)
425 int wxTextCtrl::PosToPixel( int line
, int pos
)
427 // TODO add support for Tabs
429 if (line
>= (int)m_lines
.GetCount()) return 0;
430 if (pos
< 0) return 0;
432 wxString text
= m_lines
[line
].m_text
;
434 if (text
.empty()) return 0;
436 if (pos
< (int)text
.Len())
437 text
.Remove( pos
, text
.Len()-pos
);
441 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
446 int wxTextCtrl::PixelToPos( int line
, int pixel
)
448 if (pixel
< 2) return 0;
450 if (line
>= (int)m_lines
.GetCount()) return 0;
452 wxString text
= m_lines
[line
].m_text
;
455 int res
= text
.Len();
458 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
464 text
.Remove( res
,1 );
470 void wxTextCtrl::SetLanguage( wxSourceLanguage lang
)
477 void wxTextCtrl::WriteText(const wxString
& text2
)
479 if (text2
.empty()) return;
483 wxString
text( text2
);
486 while ( (pos
= text
.Find('\n')) != -1 )
488 lines
.Add( text
.Left( pos
) );
489 text
.Remove( 0, pos
+1 );
492 int count
= (int)lines
.GetCount();
494 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
495 wxString
tmp2( tmp1
);
496 int len
= (int)tmp1
.Len();
501 for (int i
= 0; i
< m_cursorX
-len
; i
++)
503 m_lines
[m_cursorY
].m_text
.Append( tmp
);
508 tmp1
.Remove( m_cursorX
);
509 tmp2
.Remove( 0, m_cursorX
);
510 tmp1
.Append( lines
[0] );
514 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
517 m_lines
[m_cursorY
].m_text
= tmp1
;
518 RefreshLine( m_cursorY
);
522 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
524 m_lines
[m_cursorY
].m_text
= tmp1
;
526 for (i
= 1; i
< count
; i
++)
527 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
528 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
530 MyAdjustScrollbars();
531 RefreshDown( m_cursorY
);
535 void wxTextCtrl::AppendText(const wxString
& text2
)
537 if (text2
.empty()) return;
541 wxString
text( text2
);
544 while ( (pos
= text
.Find('\n')) != -1 )
546 lines
.Add( text
.Left( pos
) );
547 text
.Remove( 0, pos
+1 );
550 int count
= (int)lines
.GetCount();
552 size_t y
= m_lines
.GetCount()-1;
554 wxString
tmp( m_lines
[y
].m_text
);
555 tmp
.Append( lines
[0] );
559 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, y
, y
, this ) );
561 m_lines
[y
].m_text
= tmp
;
566 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, y
, y
+count
-1, this ) );
568 m_lines
[y
].m_text
= tmp
;
570 for (i
= 1; i
< count
; i
++)
571 m_lines
.Insert( new wxSourceLine( lines
[i
] ), y
+i
);
573 MyAdjustScrollbars();
578 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
583 long wxTextCtrl::XYToPosition(long x
, long y
) const
587 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
591 // Add one for the end-of-line character
592 ret
+= m_lines
[i
].m_text
.Len() + 1;
596 if ((size_t)x
< (m_lines
[i
].m_text
.Len()+1))
599 return (ret
+ m_lines
[i
].m_text
.Len() + 1);
605 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
607 if (m_lines
.GetCount() == 0)
618 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
620 //pos -= m_lines[i].m_text.Len();
623 // Add one for the end-of-line character. (In Windows,
624 // there are _two_ positions for each end of line.)
625 if (pos
<= ((int)m_lines
[i
].m_text
.Len()))
632 pos
-= (m_lines
[i
].m_text
.Len() + 1);
637 //xx = m_lines[ m_lines.GetCount()-1 ].m_text.Len();
645 void wxTextCtrl::ShowPosition(long pos
)
649 void wxTextCtrl::Copy()
651 if (!HasSelection()) return;
655 int selStartY
= m_selStartY
;
656 int selEndY
= m_selEndY
;
657 int selStartX
= m_selStartX
;
658 int selEndX
= m_selEndX
;
660 if ((selStartY
> selEndY
) ||
661 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
671 if (selStartY
== selEndY
)
673 sel
= m_lines
[selStartY
].m_text
;
675 if (selStartX
>= (int)sel
.Len()) return;
676 if (selEndX
> (int)sel
.Len())
679 sel
.Remove( selEndX
, sel
.Len()-selEndX
);
680 sel
.Remove( 0, selStartX
);
684 wxString
tmp( m_lines
[selStartY
].m_text
);
686 if (selStartX
< (int)tmp
.Len())
688 tmp
.Remove( 0, selStartX
);
690 sel
.Append( wxT("\n") );
692 for (int i
= selStartY
+1; i
< selEndY
; i
++)
694 sel
.Append( m_lines
[i
].m_text
);
695 sel
.Append( wxT("\n") );
697 tmp
= m_lines
[selEndY
].m_text
;
698 if (selEndX
> (int)tmp
.Len())
702 tmp
.Remove( selEndX
, tmp
.Len()-selEndX
);
707 if (wxTheClipboard
->Open())
709 wxTheClipboard
->SetData( new wxTextDataObject( sel
) );
710 wxTheClipboard
->Close();
714 void wxTextCtrl::Cut()
721 void wxTextCtrl::Paste()
725 if (!wxTheClipboard
->Open()) return;
727 if (!wxTheClipboard
->IsSupported( wxDF_TEXT
))
729 wxTheClipboard
->Close();
734 wxTextDataObject data
;
736 bool ret
= wxTheClipboard
->GetData( data
);
738 wxTheClipboard
->Close();
744 wxString
text( data
.GetText() );
747 while ( (pos
= text
.Find('\n')) != -1 )
749 lines
.Add( text
.Left( pos
) );
750 text
.Remove( 0, pos
+1 );
753 int count
= (int)lines
.GetCount();
755 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
756 wxString
tmp2( tmp1
);
757 int len
= (int)tmp1
.Len();
762 for (int i
= 0; i
< m_cursorX
-len
; i
++)
764 m_lines
[m_cursorY
].m_text
.Append( tmp
);
769 tmp1
.Remove( m_cursorX
);
770 tmp2
.Remove( 0, m_cursorX
);
771 tmp1
.Append( lines
[0] );
775 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
778 m_lines
[m_cursorY
].m_text
= tmp1
;
779 RefreshLine( m_cursorY
);
783 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
785 m_lines
[m_cursorY
].m_text
= tmp1
;
787 for (i
= 1; i
< count
; i
++)
788 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
789 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
791 MyAdjustScrollbars();
792 RefreshDown( m_cursorY
);
796 void wxTextCtrl::Undo()
798 if (m_undos
.GetCount() == 0) return;
800 wxList::compatibility_iterator node
= m_undos
.Item( m_undos
.GetCount()-1 );
801 wxSourceUndoStep
*undo
= (wxSourceUndoStep
*) node
->GetData();
806 m_undos
.Erase( node
);
811 void wxTextCtrl::SetInsertionPoint(long pos
)
815 PositionToXY(pos
, & x
, & y
);
818 // TODO: scroll to this position if necessary
822 void wxTextCtrl::SetInsertionPointEnd()
824 SetInsertionPoint(GetLastPosition());
827 long wxTextCtrl::GetInsertionPoint() const
829 return XYToPosition( m_cursorX
, m_cursorY
);
832 wxTextPos
wxTextCtrl::GetLastPosition() const
834 size_t lineCount
= m_lines
.GetCount() - 1;
835 // It's the length of the line, not the length - 1,
836 // because there's a position after the last character.
837 return XYToPosition( m_lines
[lineCount
].m_text
.Len(), lineCount
);
840 void wxTextCtrl::SetSelection(long from
, long to
)
844 void wxTextCtrl::SetEditable(bool editable
)
846 m_editable
= editable
;
849 bool wxTextCtrl::Enable( bool enable
)
854 bool wxTextCtrl::SetFont(const wxFont
& font
)
856 wxTextCtrlBase::SetFont( font
);
861 dc
.SetFont( m_sourceFont
);
862 m_lineHeight
= dc
.GetCharHeight();
863 m_charWidth
= dc
.GetCharWidth();
865 // TODO: recalc longest lines
867 MyAdjustScrollbars();
872 bool wxTextCtrl::SetForegroundColour(const wxColour
& colour
)
874 return wxWindow::SetForegroundColour( colour
);
877 bool wxTextCtrl::SetBackgroundColour(const wxColour
& colour
)
879 return wxWindow::SetBackgroundColour( colour
);
882 //-----------------------------------------------------------------------------
883 // private code and handlers
884 //-----------------------------------------------------------------------------
886 void wxTextCtrl::SearchForBrackets()
888 int oldBracketY
= m_bracketY
;
889 int oldBracketX
= m_bracketX
;
891 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()) return;
893 wxString current
= m_lines
[m_cursorY
].m_text
;
895 // reverse search first
900 bracket
= current
[(size_t) (m_cursorX
-1)];
902 if (bracket
== ')' || bracket
== ']' || bracket
== '}')
904 char antibracket
= '(';
905 if (bracket
== ']') antibracket
= '[';
906 if (bracket
== '}') antibracket
= '{';
910 int endY
= m_cursorY
-60;
911 if (endY
< 0) endY
= 0;
912 for (int y
= m_cursorY
; y
>= endY
; y
--)
914 current
= m_lines
[y
].m_text
;
916 current
.erase(m_cursorX
-1,current
.Len()-m_cursorX
+1);
918 for (int n
= current
.Len()-1; n
>= 0; n
--)
921 if (current
[(size_t) (n
)] == '\'')
923 for (int m
= n
-1; m
>= 0; m
--)
925 if (current
[(size_t) (m
)] == '\'')
927 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
936 if (current
[(size_t) (n
)] == '\"')
938 for (int m
= n
-1; m
>= 0; m
--)
940 if (current
[(size_t) (m
)] == '\"')
942 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
950 if (current
[(size_t) (n
)] == antibracket
)
957 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
958 RefreshLine( oldBracketY
);
959 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
960 RefreshLine( m_bracketY
);
964 else if (current
[(size_t) (n
)] == bracket
)
975 if ((int)current
.Len() > m_cursorX
)
976 bracket
= current
[(size_t) (m_cursorX
)];
977 if (bracket
== '(' || bracket
== '[' || bracket
== '{')
979 char antibracket
= ')';
980 if (bracket
== '[') antibracket
= ']';
981 if (bracket
== '{') antibracket
= '}';
985 int endY
= m_cursorY
+60;
986 if (endY
> (int)(m_lines
.GetCount()-1)) endY
= m_lines
.GetCount()-1;
987 for (int y
= m_cursorY
; y
<= endY
; y
++)
989 current
= m_lines
[y
].m_text
;
994 for (int n
= start
; n
< (int)current
.Len(); n
++)
997 if (current
[(size_t) (n
)] == '\'')
999 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
1001 if (current
[(size_t) (m
)] == '\'')
1003 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1012 if (current
[(size_t) (n
)] == '\"')
1014 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
1016 if (current
[(size_t) (m
)] == '\"')
1018 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1026 if (current
[(size_t) (n
)] == antibracket
)
1033 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
1034 RefreshLine( oldBracketY
);
1035 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
1036 RefreshLine( m_bracketY
);
1040 else if (current
[(size_t) (n
)] == bracket
)
1048 if (oldBracketY
!= -1)
1051 RefreshLine( oldBracketY
);
1055 void wxTextCtrl::Delete()
1057 if (!HasSelection()) return;
1061 int selStartY
= m_selStartY
;
1062 int selEndY
= m_selEndY
;
1063 int selStartX
= m_selStartX
;
1064 int selEndX
= m_selEndX
;
1066 if ((selStartY
> selEndY
) ||
1067 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1069 int tmp
= selStartX
;
1070 selStartX
= selEndX
;
1073 selStartY
= selEndY
;
1077 int len
= (int)m_lines
[selStartY
].m_text
.Len();
1079 if (selStartY
== selEndY
)
1081 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, selStartY
, selStartY
, this ) );
1083 wxString
tmp( m_lines
[selStartY
].m_text
);
1084 if (selStartX
< len
)
1088 tmp
.Remove( selStartX
, selEndX
-selStartX
);
1089 m_lines
[selStartY
].m_text
= tmp
;
1092 m_cursorX
= selStartX
;
1093 RefreshLine( selStartY
);
1097 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, selStartY
, selEndY
, this ) );
1099 if (selStartX
< len
)
1100 m_lines
[selStartY
].m_text
.Remove( selStartX
);
1102 for (int i
= 0; i
< selEndY
-selStartY
-1; i
++)
1103 m_lines
.RemoveAt( selStartY
+1 );
1105 if (selEndX
< (int)m_lines
[selStartY
+1].m_text
.Len())
1106 m_lines
[selStartY
+1].m_text
.Remove( 0, selEndX
);
1108 m_lines
[selStartY
+1].m_text
.Remove( 0 );
1110 m_lines
[selStartY
].m_text
.Append( m_lines
[selStartY
+1].m_text
);
1111 m_lines
.RemoveAt( selStartY
+1 );
1114 MoveCursor( selStartX
, selStartY
);
1115 MyAdjustScrollbars();
1117 RefreshDown( selStartY
);
1121 void wxTextCtrl::DeleteLine()
1123 if (HasSelection()) return;
1125 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()-1) return; // TODO
1127 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1129 m_lines
.RemoveAt( m_cursorY
);
1131 if (m_cursorY
>= (int)m_lines
.GetCount()) m_cursorY
--;
1133 MyAdjustScrollbars();
1134 RefreshDown( m_cursorY
);
1137 void wxTextCtrl::DoChar( char c
)
1141 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1143 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1145 if (m_cursorX
>= (int)tmp
.Len())
1147 int len
= tmp
.Len();
1148 for (int i
= 0; i
< m_cursorX
- len
; i
++)
1155 tmp
.SetChar( m_cursorX
, c
);
1157 tmp
.insert( m_cursorX
, 1, c
);
1160 m_lines
[m_cursorY
].m_text
= tmp
;
1162 // if (tmp.Len() > m_longestLine)
1164 // m_longestLine = tmp.Len();
1165 // MyAdjustScrollbars();
1169 GetTextExtent( tmp
, &ww
, NULL
, NULL
, NULL
);
1171 if (ww
> m_longestLine
)
1174 MyAdjustScrollbars();
1179 int y
= m_cursorY
*m_lineHeight
;
1180 // int x = (m_cursorX-1)*m_charWidth;
1181 int x
= PosToPixel( m_cursorY
, m_cursorX
-1 );
1182 CalcScrolledPosition( x
, y
, &x
, &y
);
1183 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1184 Refresh( true, &rect
);
1185 // refresh whole line for syntax colour highlighting
1187 Refresh( false, &rect
);
1191 GetClientSize( &size_x
, &size_y
);
1192 size_x
/= m_charWidth
;
1196 GetViewStart( &view_x
, &view_y
);
1198 //int xx = m_cursorX;
1199 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
1203 else if (xx
> view_x
+size_x
-1)
1204 Scroll( xx
-size_x
+1, -1 );
1207 void wxTextCtrl::DoBack()
1213 if (m_cursorY
== 0) return;
1215 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_BACK
, m_cursorY
-1, m_cursorY
, this ) );
1217 wxString
tmp1( m_lines
[m_cursorY
-1].m_text
);
1219 wxString
tmp2( m_lines
[m_cursorY
].m_text
);
1221 m_cursorX
= tmp1
.Len();
1223 tmp1
.Append( tmp2
);
1224 m_lines
[m_cursorY
].m_text
= tmp1
;
1225 m_lines
.RemoveAt( m_cursorY
+1 );
1227 MyAdjustScrollbars();
1228 RefreshDown( m_cursorY
-1 );
1232 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1234 if (m_cursorX
<= (int)m_lines
[m_cursorY
].m_text
.Len())
1235 m_lines
[m_cursorY
].m_text
.Remove( m_cursorX
-1, 1 );
1238 int y
= m_cursorY
*m_lineHeight
;
1239 // int x = m_cursorX*m_charWidth;
1240 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1241 CalcScrolledPosition( x
, y
, &x
, &y
);
1242 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1243 Refresh( true, &rect
);
1244 // refresh whole line for syntax colour highlighting
1246 Refresh( false, &rect
);
1250 void wxTextCtrl::DoDelete()
1254 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1256 int len
= (int)tmp
.Len();
1257 if (m_cursorX
>= len
)
1259 if (m_cursorY
== (int)m_lines
.GetCount()-1) return;
1261 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1263 for (int i
= 0; i
< (m_cursorX
-len
); i
++)
1266 tmp
+= m_lines
[m_cursorY
+1].m_text
;
1268 m_lines
[m_cursorY
] = tmp
;
1269 m_lines
.RemoveAt( m_cursorY
+1 );
1271 MyAdjustScrollbars();
1272 RefreshDown( m_cursorY
);
1276 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1278 tmp
.Remove( m_cursorX
, 1 );
1279 m_lines
[m_cursorY
].m_text
= tmp
;
1281 int y
= m_cursorY
*m_lineHeight
;
1282 // int x = m_cursorX*m_charWidth;
1283 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1284 CalcScrolledPosition( x
, y
, &x
, &y
);
1285 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1286 Refresh( true, &rect
);
1287 // refresh whole line for syntax colour highlighting
1289 Refresh( false, &rect
);
1293 void wxTextCtrl::DoReturn()
1297 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_ENTER
, m_cursorY
, m_cursorY
, this ) );
1299 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1300 size_t indent
= tmp
.find_first_not_of( ' ' );
1301 if (indent
== wxSTRING_MAXLEN
) indent
= 0;
1303 if (m_cursorX
>= (int)tmp
.Len())
1305 int cursorX
= indent
;
1306 int cursorY
= m_cursorY
+ 1;
1309 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1310 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1312 MyAdjustScrollbars();
1313 MoveCursor( cursorX
, cursorY
);
1314 RefreshDown( m_cursorY
);
1318 wxString
tmp1( tmp
);
1319 tmp1
.Remove( m_cursorX
, tmp
.Len()-m_cursorX
);
1320 m_lines
[m_cursorY
].m_text
= tmp1
;
1322 wxString
tmp2( tmp
);
1323 tmp2
.Remove( 0, m_cursorX
);
1325 int cursorX
= indent
;
1326 int cursorY
= m_cursorY
+ 1;
1329 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1330 new_tmp
.Append( tmp2
);
1331 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1333 MyAdjustScrollbars();
1334 MoveCursor( cursorX
, cursorY
);
1335 RefreshDown( m_cursorY
-1 );
1339 void wxTextCtrl::DoDClick()
1341 wxString
line( m_lines
[ m_cursorY
].m_text
);
1342 if (m_cursorX
>= (int)line
.Len()) return;
1344 char ch
= line
[(size_t) (p
)];
1345 if (((ch
>= 'a') && (ch
<= 'z')) ||
1346 ((ch
>= 'A') && (ch
<= 'Z')) ||
1347 ((ch
>= '0') && (ch
<= '9')) ||
1350 m_selStartY
= m_cursorY
;
1351 m_selEndY
= m_cursorY
;
1354 ch
= line
[(size_t) (p
-1)];
1355 while (((ch
>= 'a') && (ch
<= 'z')) ||
1356 ((ch
>= 'A') && (ch
<= 'Z')) ||
1357 ((ch
>= '0') && (ch
<= '9')) ||
1362 ch
= line
[(size_t) (p
-1)];
1368 if (p
< (int)line
.Len())
1370 ch
= line
[(size_t) (p
)];
1371 while (((ch
>= 'a') && (ch
<= 'z')) ||
1372 ((ch
>= 'A') && (ch
<= 'Z')) ||
1373 ((ch
>= '0') && (ch
<= '9')) ||
1376 if (p
>= (int)line
.Len()) break;
1378 ch
= line
[(size_t) (p
)];
1382 RefreshLine( m_cursorY
);
1386 wxString
wxTextCtrl::GetNextToken( wxString
&line
, size_t &pos
)
1389 size_t len
= line
.Len();
1390 for (size_t p
= pos
; p
< len
; p
++)
1392 if ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
))
1396 for (size_t q
= p
; q
< len
; q
++)
1397 ret
.Append( line
[q
] );
1404 if ((line
[p
] == '/') && (p
+1 < len
) && (line
[(size_t) (p
+1)] == '/'))
1406 for (size_t q
= p
; q
< len
; q
++)
1407 ret
.Append( line
[q
] );
1415 ret
.Append( line
[p
] );
1416 for (size_t q
= p
+1; q
< len
; q
++)
1418 ret
.Append( line
[q
] );
1419 if ((line
[q
] == '"') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1426 if (line
[p
] == '\'')
1428 ret
.Append( line
[p
] );
1429 for (size_t q
= p
+1; q
< len
; q
++)
1431 ret
.Append( line
[q
] );
1432 if ((line
[q
] == '\'') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1439 if (((line
[p
] >= 'a') && (line
[p
] <= 'z')) ||
1440 ((line
[p
] >= 'A') && (line
[p
] <= 'Z')) ||
1444 ret
.Append( line
[p
] );
1445 for (size_t q
= p
+1; q
< len
; q
++)
1447 if (((line
[q
] >= 'a') && (line
[q
] <= 'z')) ||
1448 ((line
[q
] >= 'A') && (line
[q
] <= 'Z')) ||
1449 ((line
[q
] >= '0') && (line
[q
] <= '9')) ||
1452 ret
.Append( line
[q
] );
1469 void wxTextCtrl::OnEraseBackground( wxEraseEvent
&event
)
1474 void wxTextCtrl::DrawLinePart( wxDC
&dc
, int x
, int y
, const wxString
&toDraw
, const wxString
&origin
, const wxColour
&colour
)
1477 size_t len
= origin
.Len();
1478 dc
.SetTextForeground( colour
);
1481 while (toDraw
[pos
] == wxT(' '))
1484 if (pos
== len
) return;
1490 current
+= toDraw
[pos
];
1492 while ( (toDraw
[pos
] == origin
[pos
]) && (pos
< len
))
1494 current
+= toDraw
[pos
];
1499 wxString tmp
= origin
.Left( start
);
1500 GetTextExtent( tmp
, &xx
, NULL
, NULL
, NULL
);
1503 dc
.DrawText( current
, xx
, yy
);
1507 void wxTextCtrl::DrawLine( wxDC
&dc
, int x
, int y
, const wxString
&line2
, int lineNum
)
1509 int selStartY
= m_selStartY
;
1510 int selEndY
= m_selEndY
;
1511 int selStartX
= m_selStartX
;
1512 int selEndX
= m_selEndX
;
1514 if ((selStartY
> selEndY
) ||
1515 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1517 int tmp
= selStartX
;
1518 selStartX
= selEndX
;
1521 selStartY
= selEndY
;
1525 wxString
line( line2
);
1526 if (HasFlag(wxTE_PASSWORD
))
1528 size_t len
= line
.Len();
1529 line
= wxString( wxT('*'), len
);
1532 wxString
keyword( ' ', line
.Len() );
1533 wxString
define( ' ', line
.Len() );
1534 wxString
variable( ' ', line
.Len() );
1535 wxString
comment( ' ', line
.Len() );
1536 wxString
my_string( ' ', line
.Len() );
1537 wxString
selection( ' ', line
.Len() );
1539 if (m_lang
!= wxSOURCE_LANG_NONE
)
1541 if (lineNum
== m_bracketY
)
1543 wxString
red( ' ', line
.Len() );
1544 if (m_bracketX
< (int)line
.Len())
1546 red
.SetChar( m_bracketX
, line
[(size_t) (m_bracketX
)] );
1547 line
.SetChar( m_bracketX
, ' ' );
1548 dc
.SetTextForeground( *wxRED
);
1549 dc
.DrawText( red
, x
, y
);
1550 dc
.SetTextForeground( *wxBLACK
);
1555 wxString
token( GetNextToken( line
, pos
) );
1556 while (!token
.IsNull())
1558 if (m_keywords
.Index( token
) != wxNOT_FOUND
)
1560 size_t end_pos
= pos
+ token
.Len();
1561 for (size_t i
= pos
; i
< end_pos
; i
++)
1563 keyword
[i
] = line
[i
];
1567 if (m_defines
.Index( token
) != wxNOT_FOUND
)
1569 size_t end_pos
= pos
+ token
.Len();
1570 for (size_t i
= pos
; i
< end_pos
; i
++)
1572 define
[i
] = line
[i
];
1576 if ((m_variables
.Index( token
) != wxNOT_FOUND
) ||
1577 ((token
.Len() > 2) && (token
[(size_t) (0)] == 'w') && (token
[(size_t) (1)] == 'x')))
1579 size_t end_pos
= pos
+ token
.Len();
1580 for (size_t i
= pos
; i
< end_pos
; i
++)
1582 variable
[i
] = line
[i
];
1586 if ((token
.Len() >= 2) && (token
[(size_t) (0)] == '/') && (token
[(size_t) (1)] == '/') && (m_lang
== wxSOURCE_LANG_CPP
))
1588 size_t end_pos
= pos
+ token
.Len();
1589 for (size_t i
= pos
; i
< end_pos
; i
++)
1591 comment
[i
] = line
[i
];
1595 if ((token
[(size_t) (0)] == '#') &&
1596 ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
)))
1598 size_t end_pos
= pos
+ token
.Len();
1599 for (size_t i
= pos
; i
< end_pos
; i
++)
1601 comment
[i
] = line
[i
];
1605 if ((token
[(size_t) (0)] == '"') || (token
[(size_t) (0)] == '\''))
1607 size_t end_pos
= pos
+ token
.Len();
1608 for (size_t i
= pos
; i
< end_pos
; i
++)
1610 my_string
[i
] = line
[i
];
1615 token
= GetNextToken( line
, pos
);
1619 if ((lineNum
< selStartY
) || (lineNum
> selEndY
))
1621 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1622 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1623 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1624 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1625 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1626 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1627 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1631 if (selStartY
== selEndY
)
1633 // int xx = selStartX*m_charWidth;
1634 int xx
= PosToPixel( lineNum
, selStartX
);
1635 // int ww = (selEndX-selStartX)*m_charWidth;
1636 int ww
= PosToPixel( lineNum
, selEndX
) - xx
;
1637 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1639 for (size_t i
= (size_t)selStartX
; i
< (size_t)selEndX
; i
++)
1641 selection
[i
] = line
[i
];
1645 if ((lineNum
> selStartY
) && (lineNum
< selEndY
))
1647 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1649 for (size_t i
= 0; i
< line
.Len(); i
++)
1651 selection
[i
] = line
[i
];
1655 if (lineNum
== selStartY
)
1657 // int xx = selStartX*m_charWidth;
1658 int xx
= PosToPixel( lineNum
, selStartX
);
1659 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1661 for (size_t i
= (size_t)selStartX
; i
< line
.Len(); i
++)
1663 selection
[i
] = line
[i
];
1667 if (lineNum
== selEndY
)
1669 // int ww = selEndX*m_charWidth;
1670 int ww
= PosToPixel( lineNum
, selEndX
);
1671 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1673 for (size_t i
= 0; i
< (size_t)selEndX
; i
++)
1675 selection
[i
] = line
[i
];
1680 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1681 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1682 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1683 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1684 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1685 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1686 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1689 void wxTextCtrl::OnPaint( wxPaintEvent
&event
)
1693 if (m_lines
.GetCount() == 0) return;
1697 dc
.SetFont( m_sourceFont
);
1700 GetViewStart( NULL
, &scroll_y
);
1702 // We have a inner border of two pixels
1703 // around the text, so scroll units do
1704 // not correspond to lines.
1705 if (scroll_y
> 0) scroll_y
--;
1709 GetClientSize( &size_x
, &size_y
);
1711 dc
.SetPen( *wxTRANSPARENT_PEN
);
1712 dc
.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT
), wxSOLID
) );
1713 int upper
= wxMin( (int)m_lines
.GetCount(), scroll_y
+(size_y
/m_lineHeight
)+2 );
1714 for (int i
= scroll_y
; i
< upper
; i
++)
1717 int y
= i
*m_lineHeight
+2;
1719 int h
= m_lineHeight
;
1720 CalcScrolledPosition( x
,y
,&x
,&y
);
1721 if (IsExposed(x
,y
,w
,h
))
1722 DrawLine( dc
, 0+2, i
*m_lineHeight
+2, m_lines
[i
].m_text
, i
);
1725 if (m_editable
&& (FindFocus() == this))
1727 ///dc.SetBrush( *wxRED_BRUSH );
1728 dc
.SetBrush( *wxBLACK_BRUSH
);
1729 // int xx = m_cursorX*m_charWidth;
1730 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
1731 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
1735 void wxTextCtrl::OnMouse( wxMouseEvent
&event
)
1737 if (m_lines
.GetCount() == 0) return;
1740 #if 0 // there is no middle button on iPAQs
1741 if (event
.MiddleDown())
1748 if (event
.LeftDClick())
1754 if (event
.LeftDown())
1762 m_capturing
= false;
1766 if (event
.LeftDown() ||
1767 (event
.LeftIsDown() && m_capturing
))
1769 int x
= event
.GetX();
1770 int y
= event
.GetY();
1771 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1773 // x /= m_charWidth;
1774 x
= PixelToPos( y
, x
);
1776 wxMin( 1000, wxMax( 0, x
) ),
1777 wxMin( (int)m_lines
.GetCount()-1, wxMax( 0, y
) ),
1778 event
.ShiftDown() || !event
.LeftDown() );
1782 void wxTextCtrl::OnChar( wxKeyEvent
&event
)
1784 if (m_lines
.GetCount() == 0) return;
1786 if (!m_editable
) return;
1790 GetClientSize( &size_x
, &size_y
);
1791 size_x
/= m_charWidth
;
1792 size_y
/= m_lineHeight
;
1795 if (event
.ShiftDown())
1797 switch (event
.GetKeyCode())
1799 case '4': event
.m_keyCode
= WXK_LEFT
; break;
1800 case '8': event
.m_keyCode
= WXK_UP
; break;
1801 case '6': event
.m_keyCode
= WXK_RIGHT
; break;
1802 case '2': event
.m_keyCode
= WXK_DOWN
; break;
1803 case '9': event
.m_keyCode
= WXK_PRIOR
; break;
1804 case '3': event
.m_keyCode
= WXK_NEXT
; break;
1805 case '7': event
.m_keyCode
= WXK_HOME
; break;
1806 case '1': event
.m_keyCode
= WXK_END
; break;
1807 case '0': event
.m_keyCode
= WXK_INSERT
; break;
1811 switch (event
.GetKeyCode())
1815 if (m_ignoreInput
) return;
1817 MoveCursor( m_cursorX
, m_cursorY
-1, event
.ShiftDown() );
1818 m_ignoreInput
= true;
1823 if (m_ignoreInput
) return;
1824 if (m_cursorY
< (int)(m_lines
.GetCount()-1))
1825 MoveCursor( m_cursorX
, m_cursorY
+1, event
.ShiftDown() );
1826 m_ignoreInput
= true;
1831 if (m_ignoreInput
) return;
1834 MoveCursor( m_cursorX
-1, m_cursorY
, event
.ShiftDown() );
1839 MoveCursor( m_lines
[m_cursorY
-1].m_text
.Len(), m_cursorY
-1, event
.ShiftDown() );
1841 m_ignoreInput
= true;
1846 if (m_ignoreInput
) return;
1847 if (m_cursorX
< 1000)
1848 MoveCursor( m_cursorX
+1, m_cursorY
, event
.ShiftDown() );
1849 m_ignoreInput
= true;
1854 if (event
.ControlDown())
1855 MoveCursor( 0, 0, event
.ShiftDown() );
1857 MoveCursor( 0, m_cursorY
, event
.ShiftDown() );
1862 if (event
.ControlDown())
1863 MoveCursor( 0, m_lines
.GetCount()-1, event
.ShiftDown() );
1865 MoveCursor( m_lines
[m_cursorY
].m_text
.Len(), m_cursorY
, event
.ShiftDown() );
1870 if (m_ignoreInput
) return;
1871 MoveCursor( m_cursorX
, wxMin( (int)(m_lines
.GetCount()-1), m_cursorY
+size_y
), event
.ShiftDown() );
1872 m_ignoreInput
= true;
1877 if (m_ignoreInput
) return;
1878 MoveCursor( m_cursorX
, wxMax( 0, m_cursorY
-size_y
), event
.ShiftDown() );
1879 m_ignoreInput
= true;
1884 if (event
.ShiftDown())
1886 else if (event
.ControlDown())
1889 m_overwrite
= !m_overwrite
;
1894 if (m_windowStyle
& wxPROCESS_ENTER
)
1896 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1897 event
.SetEventObject(this);
1898 event
.SetString(GetValue());
1899 if (GetEventHandler()->ProcessEvent(event
)) return;
1917 bool save_overwrite
= m_overwrite
;
1918 m_overwrite
= false;
1919 int i
= 4-(m_cursorX
% 4);
1921 for (int c
= 0; c
< i
; c
++)
1923 m_overwrite
= save_overwrite
;
1944 if ( (event
.GetKeyCode() >= 'a') &&
1945 (event
.GetKeyCode() <= 'z') &&
1953 if ( (event
.GetKeyCode() >= 32) &&
1954 (event
.GetKeyCode() <= 255) &&
1955 !(event
.ControlDown() && !event
.AltDown()) ) // filters out Ctrl-X but leaves Alt-Gr
1959 DoChar( (char) event
.GetKeyCode() );
1968 void wxTextCtrl::OnInternalIdle()
1970 wxControl::OnInternalIdle();
1972 m_ignoreInput
= false;
1974 if (m_lang
!= wxSOURCE_LANG_NONE
)
1975 SearchForBrackets();
1978 void wxTextCtrl::Indent()
1980 int startY
= m_cursorY
;
1981 int endY
= m_cursorY
;
1984 startY
= m_selStartY
;
1994 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1996 for (int i
= startY
; i
<= endY
; i
++)
1998 m_lines
[i
].m_text
.insert( 0u, wxT(" ") );
2003 void wxTextCtrl::Unindent()
2005 int startY
= m_cursorY
;
2006 int endY
= m_cursorY
;
2009 startY
= m_selStartY
;
2019 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
2021 for (int i
= startY
; i
<= endY
; i
++)
2023 for (int n
= 0; n
< 4; n
++)
2025 if (m_lines
[i
].m_text
[0u] == wxT(' '))
2026 m_lines
[i
].m_text
.erase(0u,1u);
2031 bool wxTextCtrl::HasSelection()
2033 return ((m_selStartY
!= m_selEndY
) || (m_selStartX
!= m_selEndX
));
2036 void wxTextCtrl::ClearSelection()
2044 void wxTextCtrl::RefreshLine( int n
)
2046 int y
= n
*m_lineHeight
;
2048 CalcScrolledPosition( x
, y
, &x
, &y
);
2049 wxRect
rect( 0+2, y
+2, 10000, m_lineHeight
);
2050 Refresh( true, &rect
);
2053 void wxTextCtrl::RefreshDown( int n
)
2057 GetClientSize( &size_x
, &size_y
);
2061 GetViewStart( &view_x
, &view_y
);
2069 int y
= n
*m_lineHeight
;
2071 CalcScrolledPosition( x
, y
, &x
, &y
);
2073 wxRect
rect( 0+2, y
+2, 10000, size_y
);
2074 Refresh( true, &rect
);
2078 void wxTextCtrl::MoveCursor( int new_x
, int new_y
, bool shift
, bool centre
)
2080 if (!m_editable
) return;
2082 // if (IsSingleLine() || (m_lang == wxSOURCE_LANG_NONE))
2084 if (new_x
> (int) (m_lines
[new_y
].m_text
.Len()))
2085 new_x
= m_lines
[new_y
].m_text
.Len();
2088 if ((new_x
== m_cursorX
) && (new_y
== m_cursorY
)) return;
2090 bool no_cursor_refresh
= false;
2091 bool has_selection
= HasSelection();
2096 bool erase_background
= true;
2100 m_selStartX
= m_cursorX
;
2101 m_selStartY
= m_cursorY
;
2105 if (new_y
> m_selStartY
)
2107 y
= m_selStartY
*m_lineHeight
;
2108 h
= (new_y
-m_selStartY
+1)*m_lineHeight
;
2110 else if (new_y
== m_selStartY
)
2112 x
= PosToPixel( new_y
, m_selStartX
);
2113 w
= PosToPixel( new_y
, new_x
) - x
;
2117 w
= -w
+ 2; // +2 for the cursor
2119 y
= m_selStartY
*m_lineHeight
;
2124 y
= new_y
*m_lineHeight
;
2125 h
= (-new_y
+m_selStartY
+1)*m_lineHeight
;
2128 no_cursor_refresh
= true;
2134 if (new_y
== m_selEndY
)
2136 y
= new_y
*m_lineHeight
;
2138 if (m_selEndX
> new_x
)
2140 // x = new_x*m_charWidth;
2141 x
= PosToPixel( new_y
, new_x
);
2142 // w = (m_selEndX-new_x)*m_charWidth;
2143 w
= PosToPixel( new_y
, m_selEndX
) - x
;
2147 // x = m_selEndX*m_charWidth;
2148 x
= PosToPixel( new_y
, m_selEndX
);
2149 // w = (-m_selEndX+new_x)*m_charWidth;
2150 w
= PosToPixel( new_y
, new_x
) - x
;
2157 if (new_y
> m_selEndY
)
2159 y
= m_selEndY
*m_lineHeight
;
2160 h
= (new_y
-m_selEndY
+1) * m_lineHeight
;
2162 erase_background
= ((m_selEndY
< m_selStartY
) ||
2163 ((m_selEndY
== m_selStartY
) && (m_selEndX
< m_selStartX
)));
2167 y
= new_y
*m_lineHeight
;
2168 h
= (-new_y
+m_selEndY
+1) * m_lineHeight
;
2170 erase_background
= ((m_selEndY
> m_selStartY
) ||
2171 ((m_selEndY
== m_selStartY
) && (m_selEndX
> m_selStartX
)));
2173 no_cursor_refresh
= true;
2182 CalcScrolledPosition( x
, y
, &x
, &y
);
2183 wxRect
rect( x
+2, y
+2, w
, h
);
2184 Refresh( erase_background
, &rect
);
2190 int ry1
= m_selEndY
;
2191 int ry2
= m_selStartY
;
2205 int y
= ry1
*m_lineHeight
;
2206 CalcScrolledPosition( x
, y
, &x
, &y
);
2207 wxRect
rect( 0, y
+2, 10000, (ry2
-ry1
+1)*m_lineHeight
);
2209 Refresh( true, &rect
);
2214 printf( "startx %d starty %d endx %d endy %d\n",
2215 m_selStartX, m_selStartY, m_selEndX, m_selEndY );
2217 printf( "has %d\n", (int)HasSelection() );
2220 if (!no_cursor_refresh
)
2222 // int x = m_cursorX*m_charWidth;
2223 int x
= PosToPixel( m_cursorY
, m_cursorX
);
2224 int y
= m_cursorY
*m_lineHeight
;
2225 CalcScrolledPosition( x
, y
, &x
, &y
);
2226 wxRect
rect( x
+2, y
+2, 4, m_lineHeight
+2 );
2231 Refresh( true, &rect
);
2233 if (FindFocus() == this)
2235 wxClientDC
dc(this);
2237 dc
.SetPen( *wxTRANSPARENT_PEN
);
2238 //dc.SetBrush( *wxRED_BRUSH );
2239 dc
.SetBrush( *wxBLACK_BRUSH
);
2240 // int xx = m_cursorX*m_charWidth;
2241 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
2242 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
2248 GetClientSize( &size_x
, &size_y
);
2249 size_x
/= m_charWidth
;
2250 size_y
/= m_lineHeight
;
2254 GetViewStart( &view_x
, &view_y
);
2258 int sy
= m_cursorY
- (size_y
/2);
2264 if (m_cursorY
< view_y
)
2265 Scroll( -1, m_cursorY
);
2266 else if (m_cursorY
> view_y
+size_y
-1)
2267 Scroll( -1, m_cursorY
-size_y
+1 );
2270 //int xx = m_cursorX;
2271 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
2275 else if (xx
> view_x
+size_x
-1)
2276 Scroll( xx
-size_x
+1, -1 );
2279 void wxTextCtrl::MyAdjustScrollbars()
2284 int y_range
= m_lines
.GetCount();
2287 GetClientSize( NULL
, &height
);
2289 if (height
>= (int)m_lines
.GetCount() *m_lineHeight
)
2294 GetViewStart( &view_x
, &view_y
);
2296 SetScrollbars( m_charWidth
, m_lineHeight
, m_longestLine
+2, y_range
, view_x
, view_y
);
2299 //-----------------------------------------------------------------------------
2300 // clipboard handlers
2301 //-----------------------------------------------------------------------------
2303 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
2308 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
2313 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
2318 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
2323 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
2328 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2330 event
.Enable( CanCut() );
2333 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2335 event
.Enable( CanCopy() );
2338 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2340 event
.Enable( CanPaste() );
2343 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2345 event
.Enable( CanUndo() );
2348 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2350 event
.Enable( CanRedo() );
2353 wxSize
wxTextCtrl::DoGetBestSize() const
2357 wxSize
ret(80, m_lineHeight
+ 4);
2359 if (HasFlag(wxBORDER_SUNKEN
) || HasFlag(wxBORDER_RAISED
))
2362 if (HasFlag(wxBORDER_SIMPLE
))
2369 return wxSize(80, 60);
2373 // ----------------------------------------------------------------------------
2375 // ----------------------------------------------------------------------------
2377 void wxTextCtrl::Freeze()
2381 void wxTextCtrl::Thaw()
2385 void wxTextCtrl::OnSetFocus( wxFocusEvent
& event
)
2387 // To hide or show caret, as appropriate
2391 void wxTextCtrl::OnKillFocus( wxFocusEvent
& event
)
2393 // To hide or show caret, as appropriate
2397 // ----------------------------------------------------------------------------
2398 // text control scrolling
2399 // ----------------------------------------------------------------------------
2401 bool wxTextCtrl::ScrollLines(int lines
)
2403 wxFAIL_MSG( "wxTextCtrl::ScrollLines not implemented");
2408 bool wxTextCtrl::ScrollPages(int pages
)
2410 wxFAIL_MSG( "wxTextCtrl::ScrollPages not implemented");