1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/x11/textctrl.cpp
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // for compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
13 #include "wx/textctrl.h"
21 #include "wx/settings.h"
23 #include "wx/clipbrd.h"
24 #include "wx/tokenzr.h"
25 #include "wx/dcclient.h"
27 #include "wx/univ/inphand.h"
28 #include "wx/univ/renderer.h"
29 #include "wx/univ/colschem.h"
30 #include "wx/univ/theme.h"
32 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
36 wxSourceUndoStep::wxSourceUndoStep( wxSourceUndo type
, int y1
, int y2
, wxTextCtrl
*owner
)
43 m_cursorX
= m_owner
->GetCursorX();
44 m_cursorY
= m_owner
->GetCursorY();
46 if (m_type
== wxSOURCE_UNDO_LINE
)
48 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
50 if (m_type
== wxSOURCE_UNDO_ENTER
)
52 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
54 if (m_type
== wxSOURCE_UNDO_BACK
)
56 for (int i
= m_y1
; i
< m_y2
+2; i
++)
58 if (i
>= (int)m_owner
->m_lines
.GetCount())
59 m_lines
.Add( wxEmptyString
);
61 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
64 if (m_type
== wxSOURCE_UNDO_DELETE
)
66 for (int i
= m_y1
; i
< m_y2
+1; i
++)
68 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
71 if (m_type
== wxSOURCE_UNDO_PASTE
)
73 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
77 void wxSourceUndoStep::Undo()
79 if (m_type
== wxSOURCE_UNDO_LINE
)
81 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
82 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
83 m_owner
->RefreshLine( m_y1
);
85 if (m_type
== wxSOURCE_UNDO_ENTER
)
87 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
88 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
89 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
90 m_owner
->RefreshDown( m_y1
);
92 if (m_type
== wxSOURCE_UNDO_BACK
)
94 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
95 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[1] ), m_y1
+1 );
96 m_owner
->MyAdjustScrollbars();
97 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
98 m_owner
->RefreshDown( m_y1
);
100 if (m_type
== wxSOURCE_UNDO_DELETE
)
102 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
103 for (int i
= 1; i
< (int)m_lines
.GetCount(); i
++)
104 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[i
] ), m_y1
+i
);
105 m_owner
->MyAdjustScrollbars();
106 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
107 m_owner
->RefreshDown( m_y1
);
109 if (m_type
== wxSOURCE_UNDO_PASTE
)
111 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
112 for (int i
= 0; i
< m_y2
-m_y1
; i
++)
113 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
114 m_owner
->MyAdjustScrollbars();
115 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
116 m_owner
->RefreshDown( m_y1
);
118 if (m_type
== wxSOURCE_UNDO_INSERT_LINE
)
120 m_owner
->m_lines
.RemoveAt( m_y1
);
121 m_owner
->MyAdjustScrollbars();
122 m_owner
->MoveCursor( 0, m_y1
);
123 m_owner
->RefreshDown( m_y1
);
127 #include "wx/arrimpl.cpp"
128 WX_DEFINE_OBJARRAY(wxSourceLineArray
);
130 //-----------------------------------------------------------------------------
132 //-----------------------------------------------------------------------------
134 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
,wxControl
)
136 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
137 EVT_PAINT(wxTextCtrl::OnPaint
)
138 EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground
)
139 EVT_CHAR(wxTextCtrl::OnChar
)
140 EVT_MOUSE_EVENTS(wxTextCtrl::OnMouse
)
141 EVT_KILL_FOCUS(wxTextCtrl::OnKillFocus
)
142 EVT_SET_FOCUS(wxTextCtrl::OnSetFocus
)
144 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
145 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
146 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
147 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
148 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
150 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
151 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
152 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
153 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
154 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
157 void wxTextCtrl::Init()
162 m_lang
= wxSOURCE_LANG_NONE
;
175 m_ignoreInput
= false;
179 m_keywordColour
= wxColour( 10, 140, 10 );
181 m_defineColour
= *wxRED
;
183 m_variableColour
= wxColour( 50, 120, 150 );
185 m_commentColour
= wxColour( 130, 130, 130 );
187 m_stringColour
= wxColour( 10, 140, 10 );
190 wxTextCtrl::wxTextCtrl( wxWindow
*parent
,
192 const wxString
&value
,
196 const wxValidator
& validator
,
197 const wxString
&name
)
198 : wxScrollHelper(this)
202 Create( parent
, id
, value
, pos
, size
, style
, validator
, name
);
205 wxTextCtrl::~wxTextCtrl()
207 WX_CLEAR_LIST(wxList
, m_undos
);
210 bool wxTextCtrl::Create( wxWindow
*parent
,
212 const wxString
&value
,
216 const wxValidator
& validator
,
217 const wxString
&name
)
219 if ((style
& wxBORDER_MASK
) == 0)
220 style
|= wxBORDER_SUNKEN
;
222 if ((style
& wxTE_MULTILINE
) != 0)
223 style
|= wxALWAYS_SHOW_SB
;
225 wxTextCtrlBase::Create( parent
, id
, pos
/* wxDefaultPosition */, size
,
226 style
| wxVSCROLL
| wxHSCROLL
);
228 SetBackgroundColour( *wxWHITE
);
230 SetCursor( wxCursor( wxCURSOR_IBEAM
) );
232 m_editable
= ((m_windowStyle
& wxTE_READONLY
) == 0);
234 if (HasFlag(wxTE_PASSWORD
))
235 m_sourceFont
= wxFont( 12, wxMODERN
, wxNORMAL
, wxNORMAL
);
237 m_sourceFont
= GetFont();
240 dc
.SetFont( m_sourceFont
);
241 m_lineHeight
= dc
.GetCharHeight();
242 m_charWidth
= dc
.GetCharWidth();
246 wxSize
size_best( DoGetBestSize() );
247 wxSize
new_size( size
);
248 if (new_size
.x
== -1)
249 new_size
.x
= size_best
.x
;
250 if (new_size
.y
== -1)
251 new_size
.y
= size_best
.y
;
252 if ((new_size
.x
!= size
.x
) || (new_size
.y
!= size
.y
))
253 SetSize( new_size
.x
, new_size
.y
);
255 // We create an input handler since it might be useful
256 CreateInputHandler(wxINP_HANDLER_TEXTCTRL
);
258 MyAdjustScrollbars();
263 //-----------------------------------------------------------------------------
265 //-----------------------------------------------------------------------------
267 wxString
wxTextCtrl::GetValue() const
270 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
272 ret
+= m_lines
[i
].m_text
;
273 if (i
+1 < m_lines
.GetCount())
280 void wxTextCtrl::SetValue(const wxString
& value
)
284 wxString oldValue
= GetValue();
294 m_lines
.Add( new wxSourceLine( wxEmptyString
) );
302 pos
= value
.find( wxT('\n'), begin
);
305 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, value
.Len()-begin
) );
308 // if (sl->m_text.Len() > m_longestLine)
309 // m_longestLine = sl->m_text.Len();
311 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
313 if (ww
> m_longestLine
)
320 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, pos
-begin
) );
323 // if (sl->m_text.Len() > m_longestLine)
324 // m_longestLine = sl->m_text.Len();
326 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
328 if (ww
> m_longestLine
)
336 // Don't need to refresh if the value hasn't changed
337 if ((GetWindowStyle() & wxTE_MULTILINE
) == 0)
339 if (value
== oldValue
)
343 MyAdjustScrollbars();
348 int wxTextCtrl::GetLineLength(long lineNo
) const
350 if (lineNo
>= (long)m_lines
.GetCount())
353 return m_lines
[lineNo
].m_text
.Len();
356 wxString
wxTextCtrl::GetLineText(long lineNo
) const
358 if (lineNo
>= (long)m_lines
.GetCount())
359 return wxEmptyString
;
361 return m_lines
[lineNo
].m_text
;
364 int wxTextCtrl::GetNumberOfLines() const
366 return m_lines
.GetCount();
369 bool wxTextCtrl::IsModified() const
374 bool wxTextCtrl::IsEditable() const
379 void wxTextCtrl::GetSelection(long* from
, long* to
) const
381 if (m_selStartX
== -1 || m_selStartY
== -1 ||
382 m_selEndX
== -1 || m_selEndY
== -1)
384 *from
= GetInsertionPoint();
385 *to
= GetInsertionPoint();
389 *from
= XYToPosition(m_selStartX
, m_selStartY
);
390 *to
= XYToPosition(m_selEndX
, m_selEndY
);
394 void wxTextCtrl::Clear()
402 m_lines
.Add( new wxSourceLine( wxEmptyString
) );
404 SetScrollbars( m_charWidth
, m_lineHeight
, 0, 0, 0, 0 );
406 WX_CLEAR_LIST(wxList
, m_undos
);
409 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
413 void wxTextCtrl::Remove(long from
, long to
)
417 void wxTextCtrl::DiscardEdits()
423 void wxTextCtrl::SetMaxLength(unsigned long len
)
427 int wxTextCtrl::PosToPixel( int line
, int pos
)
429 // TODO add support for Tabs
431 if (line
>= (int)m_lines
.GetCount()) return 0;
432 if (pos
< 0) return 0;
434 wxString text
= m_lines
[line
].m_text
;
436 if (text
.empty()) return 0;
438 if (pos
< (int)text
.Len())
439 text
.Remove( pos
, text
.Len()-pos
);
443 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
448 int wxTextCtrl::PixelToPos( int line
, int pixel
)
450 if (pixel
< 2) return 0;
452 if (line
>= (int)m_lines
.GetCount()) return 0;
454 wxString text
= m_lines
[line
].m_text
;
457 int res
= text
.Len();
460 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
466 text
.Remove( res
,1 );
472 void wxTextCtrl::SetLanguage( wxSourceLanguage lang
)
479 void wxTextCtrl::WriteText(const wxString
& text2
)
481 if (text2
.empty()) return;
485 wxString
text( text2
);
488 while ( (pos
= text
.Find('\n')) != -1 )
490 lines
.Add( text
.Left( pos
) );
491 text
.Remove( 0, pos
+1 );
494 int count
= (int)lines
.GetCount();
496 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
497 wxString
tmp2( tmp1
);
498 int len
= (int)tmp1
.Len();
503 for (int i
= 0; i
< m_cursorX
-len
; i
++)
505 m_lines
[m_cursorY
].m_text
.Append( tmp
);
510 tmp1
.Remove( m_cursorX
);
511 tmp2
.Remove( 0, m_cursorX
);
512 tmp1
.Append( lines
[0] );
516 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
519 m_lines
[m_cursorY
].m_text
= tmp1
;
520 RefreshLine( m_cursorY
);
524 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
526 m_lines
[m_cursorY
].m_text
= tmp1
;
528 for (i
= 1; i
< count
; i
++)
529 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
530 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
532 MyAdjustScrollbars();
533 RefreshDown( m_cursorY
);
537 void wxTextCtrl::AppendText(const wxString
& text2
)
539 if (text2
.empty()) return;
543 wxString
text( text2
);
546 while ( (pos
= text
.Find('\n')) != -1 )
548 lines
.Add( text
.Left( pos
) );
549 text
.Remove( 0, pos
+1 );
552 int count
= (int)lines
.GetCount();
554 size_t y
= m_lines
.GetCount()-1;
556 wxString
tmp( m_lines
[y
].m_text
);
557 tmp
.Append( lines
[0] );
561 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, y
, y
, this ) );
563 m_lines
[y
].m_text
= tmp
;
568 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, y
, y
+count
-1, this ) );
570 m_lines
[y
].m_text
= tmp
;
572 for (i
= 1; i
< count
; i
++)
573 m_lines
.Insert( new wxSourceLine( lines
[i
] ), y
+i
);
575 MyAdjustScrollbars();
580 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
585 long wxTextCtrl::XYToPosition(long x
, long y
) const
589 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
593 // Add one for the end-of-line character
594 ret
+= m_lines
[i
].m_text
.Len() + 1;
598 if ((size_t)x
< (m_lines
[i
].m_text
.Len()+1))
601 return (ret
+ m_lines
[i
].m_text
.Len() + 1);
607 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
609 if (m_lines
.GetCount() == 0)
620 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
622 //pos -= m_lines[i].m_text.Len();
625 // Add one for the end-of-line character. (In Windows,
626 // there are _two_ positions for each end of line.)
627 if (pos
<= ((int)m_lines
[i
].m_text
.Len()))
634 pos
-= (m_lines
[i
].m_text
.Len() + 1);
639 //xx = m_lines[ m_lines.GetCount()-1 ].m_text.Len();
647 void wxTextCtrl::ShowPosition(long pos
)
651 void wxTextCtrl::Copy()
653 if (!HasSelection()) return;
657 int selStartY
= m_selStartY
;
658 int selEndY
= m_selEndY
;
659 int selStartX
= m_selStartX
;
660 int selEndX
= m_selEndX
;
662 if ((selStartY
> selEndY
) ||
663 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
673 if (selStartY
== selEndY
)
675 sel
= m_lines
[selStartY
].m_text
;
677 if (selStartX
>= (int)sel
.Len()) return;
678 if (selEndX
> (int)sel
.Len())
681 sel
.Remove( selEndX
, sel
.Len()-selEndX
);
682 sel
.Remove( 0, selStartX
);
686 wxString
tmp( m_lines
[selStartY
].m_text
);
688 if (selStartX
< (int)tmp
.Len())
690 tmp
.Remove( 0, selStartX
);
692 sel
.Append( wxT("\n") );
694 for (int i
= selStartY
+1; i
< selEndY
; i
++)
696 sel
.Append( m_lines
[i
].m_text
);
697 sel
.Append( wxT("\n") );
699 tmp
= m_lines
[selEndY
].m_text
;
700 if (selEndX
> (int)tmp
.Len())
704 tmp
.Remove( selEndX
, tmp
.Len()-selEndX
);
709 if (wxTheClipboard
->Open())
711 wxTheClipboard
->SetData( new wxTextDataObject( sel
) );
712 wxTheClipboard
->Close();
716 void wxTextCtrl::Cut()
723 void wxTextCtrl::Paste()
727 if (!wxTheClipboard
->Open()) return;
729 if (!wxTheClipboard
->IsSupported( wxDF_TEXT
))
731 wxTheClipboard
->Close();
736 wxTextDataObject data
;
738 bool ret
= wxTheClipboard
->GetData( data
);
740 wxTheClipboard
->Close();
746 wxString
text( data
.GetText() );
749 while ( (pos
= text
.Find('\n')) != -1 )
751 lines
.Add( text
.Left( pos
) );
752 text
.Remove( 0, pos
+1 );
755 int count
= (int)lines
.GetCount();
757 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
758 wxString
tmp2( tmp1
);
759 int len
= (int)tmp1
.Len();
764 for (int i
= 0; i
< m_cursorX
-len
; i
++)
766 m_lines
[m_cursorY
].m_text
.Append( tmp
);
771 tmp1
.Remove( m_cursorX
);
772 tmp2
.Remove( 0, m_cursorX
);
773 tmp1
.Append( lines
[0] );
777 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
780 m_lines
[m_cursorY
].m_text
= tmp1
;
781 RefreshLine( m_cursorY
);
785 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
787 m_lines
[m_cursorY
].m_text
= tmp1
;
789 for (i
= 1; i
< count
; i
++)
790 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
791 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
793 MyAdjustScrollbars();
794 RefreshDown( m_cursorY
);
798 void wxTextCtrl::Undo()
800 if (m_undos
.GetCount() == 0) return;
802 wxList::compatibility_iterator node
= m_undos
.Item( m_undos
.GetCount()-1 );
803 wxSourceUndoStep
*undo
= (wxSourceUndoStep
*) node
->GetData();
808 m_undos
.Erase( node
);
813 void wxTextCtrl::SetInsertionPoint(long pos
)
817 PositionToXY(pos
, & x
, & y
);
820 // TODO: scroll to this position if necessary
824 void wxTextCtrl::SetInsertionPointEnd()
826 SetInsertionPoint(GetLastPosition());
829 long wxTextCtrl::GetInsertionPoint() const
831 return XYToPosition( m_cursorX
, m_cursorY
);
834 wxTextPos
wxTextCtrl::GetLastPosition() const
836 size_t lineCount
= m_lines
.GetCount() - 1;
837 // It's the length of the line, not the length - 1,
838 // because there's a position after the last character.
839 return XYToPosition( m_lines
[lineCount
].m_text
.Len(), lineCount
);
842 void wxTextCtrl::SetSelection(long from
, long to
)
846 void wxTextCtrl::SetEditable(bool editable
)
848 m_editable
= editable
;
851 bool wxTextCtrl::Enable( bool enable
)
856 bool wxTextCtrl::SetFont(const wxFont
& font
)
858 wxTextCtrlBase::SetFont( font
);
863 dc
.SetFont( m_sourceFont
);
864 m_lineHeight
= dc
.GetCharHeight();
865 m_charWidth
= dc
.GetCharWidth();
867 // TODO: recalc longest lines
869 MyAdjustScrollbars();
874 bool wxTextCtrl::SetForegroundColour(const wxColour
& colour
)
876 return wxWindow::SetForegroundColour( colour
);
879 bool wxTextCtrl::SetBackgroundColour(const wxColour
& colour
)
881 return wxWindow::SetBackgroundColour( colour
);
884 //-----------------------------------------------------------------------------
885 // private code and handlers
886 //-----------------------------------------------------------------------------
888 void wxTextCtrl::SearchForBrackets()
890 int oldBracketY
= m_bracketY
;
891 int oldBracketX
= m_bracketX
;
893 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()) return;
895 wxString current
= m_lines
[m_cursorY
].m_text
;
897 // reverse search first
902 bracket
= current
[(size_t) (m_cursorX
-1)];
904 if (bracket
== ')' || bracket
== ']' || bracket
== '}')
906 char antibracket
= '(';
907 if (bracket
== ']') antibracket
= '[';
908 if (bracket
== '}') antibracket
= '{';
912 int endY
= m_cursorY
-60;
913 if (endY
< 0) endY
= 0;
914 for (int y
= m_cursorY
; y
>= endY
; y
--)
916 current
= m_lines
[y
].m_text
;
918 current
.erase(m_cursorX
-1,current
.Len()-m_cursorX
+1);
920 for (int n
= current
.Len()-1; n
>= 0; n
--)
923 if (current
[(size_t) (n
)] == '\'')
925 for (int m
= n
-1; m
>= 0; m
--)
927 if (current
[(size_t) (m
)] == '\'')
929 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
938 if (current
[(size_t) (n
)] == '\"')
940 for (int m
= n
-1; m
>= 0; m
--)
942 if (current
[(size_t) (m
)] == '\"')
944 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
952 if (current
[(size_t) (n
)] == antibracket
)
959 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
960 RefreshLine( oldBracketY
);
961 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
962 RefreshLine( m_bracketY
);
966 else if (current
[(size_t) (n
)] == bracket
)
977 if ((int)current
.Len() > m_cursorX
)
978 bracket
= current
[(size_t) (m_cursorX
)];
979 if (bracket
== '(' || bracket
== '[' || bracket
== '{')
981 char antibracket
= ')';
982 if (bracket
== '[') antibracket
= ']';
983 if (bracket
== '{') antibracket
= '}';
987 int endY
= m_cursorY
+60;
988 if (endY
> (int)(m_lines
.GetCount()-1)) endY
= m_lines
.GetCount()-1;
989 for (int y
= m_cursorY
; y
<= endY
; y
++)
991 current
= m_lines
[y
].m_text
;
996 for (int n
= start
; n
< (int)current
.Len(); n
++)
999 if (current
[(size_t) (n
)] == '\'')
1001 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
1003 if (current
[(size_t) (m
)] == '\'')
1005 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1014 if (current
[(size_t) (n
)] == '\"')
1016 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
1018 if (current
[(size_t) (m
)] == '\"')
1020 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1028 if (current
[(size_t) (n
)] == antibracket
)
1035 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
1036 RefreshLine( oldBracketY
);
1037 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
1038 RefreshLine( m_bracketY
);
1042 else if (current
[(size_t) (n
)] == bracket
)
1050 if (oldBracketY
!= -1)
1053 RefreshLine( oldBracketY
);
1057 void wxTextCtrl::Delete()
1059 if (!HasSelection()) return;
1063 int selStartY
= m_selStartY
;
1064 int selEndY
= m_selEndY
;
1065 int selStartX
= m_selStartX
;
1066 int selEndX
= m_selEndX
;
1068 if ((selStartY
> selEndY
) ||
1069 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1071 int tmp
= selStartX
;
1072 selStartX
= selEndX
;
1075 selStartY
= selEndY
;
1079 int len
= (int)m_lines
[selStartY
].m_text
.Len();
1081 if (selStartY
== selEndY
)
1083 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, selStartY
, selStartY
, this ) );
1085 wxString
tmp( m_lines
[selStartY
].m_text
);
1086 if (selStartX
< len
)
1090 tmp
.Remove( selStartX
, selEndX
-selStartX
);
1091 m_lines
[selStartY
].m_text
= tmp
;
1094 m_cursorX
= selStartX
;
1095 RefreshLine( selStartY
);
1099 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, selStartY
, selEndY
, this ) );
1101 if (selStartX
< len
)
1102 m_lines
[selStartY
].m_text
.Remove( selStartX
);
1104 for (int i
= 0; i
< selEndY
-selStartY
-1; i
++)
1105 m_lines
.RemoveAt( selStartY
+1 );
1107 if (selEndX
< (int)m_lines
[selStartY
+1].m_text
.Len())
1108 m_lines
[selStartY
+1].m_text
.Remove( 0, selEndX
);
1110 m_lines
[selStartY
+1].m_text
.Remove( 0 );
1112 m_lines
[selStartY
].m_text
.Append( m_lines
[selStartY
+1].m_text
);
1113 m_lines
.RemoveAt( selStartY
+1 );
1116 MoveCursor( selStartX
, selStartY
);
1117 MyAdjustScrollbars();
1119 RefreshDown( selStartY
);
1123 void wxTextCtrl::DeleteLine()
1125 if (HasSelection()) return;
1127 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()-1) return; // TODO
1129 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1131 m_lines
.RemoveAt( m_cursorY
);
1133 if (m_cursorY
>= (int)m_lines
.GetCount()) m_cursorY
--;
1135 MyAdjustScrollbars();
1136 RefreshDown( m_cursorY
);
1139 void wxTextCtrl::DoChar( char c
)
1143 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1145 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1147 if (m_cursorX
>= (int)tmp
.Len())
1149 int len
= tmp
.Len();
1150 for (int i
= 0; i
< m_cursorX
- len
; i
++)
1157 tmp
.SetChar( m_cursorX
, c
);
1159 tmp
.insert( m_cursorX
, 1, c
);
1162 m_lines
[m_cursorY
].m_text
= tmp
;
1164 // if (tmp.Len() > m_longestLine)
1166 // m_longestLine = tmp.Len();
1167 // MyAdjustScrollbars();
1171 GetTextExtent( tmp
, &ww
, NULL
, NULL
, NULL
);
1173 if (ww
> m_longestLine
)
1176 MyAdjustScrollbars();
1181 int y
= m_cursorY
*m_lineHeight
;
1182 // int x = (m_cursorX-1)*m_charWidth;
1183 int x
= PosToPixel( m_cursorY
, m_cursorX
-1 );
1184 CalcScrolledPosition( x
, y
, &x
, &y
);
1185 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1186 Refresh( true, &rect
);
1187 // refresh whole line for syntax colour highlighting
1189 Refresh( false, &rect
);
1193 GetClientSize( &size_x
, &size_y
);
1194 size_x
/= m_charWidth
;
1198 GetViewStart( &view_x
, &view_y
);
1200 //int xx = m_cursorX;
1201 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
1205 else if (xx
> view_x
+size_x
-1)
1206 Scroll( xx
-size_x
+1, -1 );
1209 void wxTextCtrl::DoBack()
1215 if (m_cursorY
== 0) return;
1217 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_BACK
, m_cursorY
-1, m_cursorY
, this ) );
1219 wxString
tmp1( m_lines
[m_cursorY
-1].m_text
);
1221 wxString
tmp2( m_lines
[m_cursorY
].m_text
);
1223 m_cursorX
= tmp1
.Len();
1225 tmp1
.Append( tmp2
);
1226 m_lines
[m_cursorY
].m_text
= tmp1
;
1227 m_lines
.RemoveAt( m_cursorY
+1 );
1229 MyAdjustScrollbars();
1230 RefreshDown( m_cursorY
-1 );
1234 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1236 if (m_cursorX
<= (int)m_lines
[m_cursorY
].m_text
.Len())
1237 m_lines
[m_cursorY
].m_text
.Remove( m_cursorX
-1, 1 );
1240 int y
= m_cursorY
*m_lineHeight
;
1241 // int x = m_cursorX*m_charWidth;
1242 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1243 CalcScrolledPosition( x
, y
, &x
, &y
);
1244 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1245 Refresh( true, &rect
);
1246 // refresh whole line for syntax colour highlighting
1248 Refresh( false, &rect
);
1252 void wxTextCtrl::DoDelete()
1256 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1258 int len
= (int)tmp
.Len();
1259 if (m_cursorX
>= len
)
1261 if (m_cursorY
== (int)m_lines
.GetCount()-1) return;
1263 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1265 for (int i
= 0; i
< (m_cursorX
-len
); i
++)
1268 tmp
+= m_lines
[m_cursorY
+1].m_text
;
1270 m_lines
[m_cursorY
] = tmp
;
1271 m_lines
.RemoveAt( m_cursorY
+1 );
1273 MyAdjustScrollbars();
1274 RefreshDown( m_cursorY
);
1278 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1280 tmp
.Remove( m_cursorX
, 1 );
1281 m_lines
[m_cursorY
].m_text
= tmp
;
1283 int y
= m_cursorY
*m_lineHeight
;
1284 // int x = m_cursorX*m_charWidth;
1285 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1286 CalcScrolledPosition( x
, y
, &x
, &y
);
1287 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1288 Refresh( true, &rect
);
1289 // refresh whole line for syntax colour highlighting
1291 Refresh( false, &rect
);
1295 void wxTextCtrl::DoReturn()
1299 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_ENTER
, m_cursorY
, m_cursorY
, this ) );
1301 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1302 size_t indent
= tmp
.find_first_not_of( ' ' );
1303 if (indent
== wxSTRING_MAXLEN
) indent
= 0;
1305 if (m_cursorX
>= (int)tmp
.Len())
1307 int cursorX
= indent
;
1308 int cursorY
= m_cursorY
+ 1;
1311 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1312 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1314 MyAdjustScrollbars();
1315 MoveCursor( cursorX
, cursorY
);
1316 RefreshDown( m_cursorY
);
1320 wxString
tmp1( tmp
);
1321 tmp1
.Remove( m_cursorX
, tmp
.Len()-m_cursorX
);
1322 m_lines
[m_cursorY
].m_text
= tmp1
;
1324 wxString
tmp2( tmp
);
1325 tmp2
.Remove( 0, m_cursorX
);
1327 int cursorX
= indent
;
1328 int cursorY
= m_cursorY
+ 1;
1331 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1332 new_tmp
.Append( tmp2
);
1333 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1335 MyAdjustScrollbars();
1336 MoveCursor( cursorX
, cursorY
);
1337 RefreshDown( m_cursorY
-1 );
1341 void wxTextCtrl::DoDClick()
1343 wxString
line( m_lines
[ m_cursorY
].m_text
);
1344 if (m_cursorX
>= (int)line
.Len()) return;
1346 char ch
= line
[(size_t) (p
)];
1347 if (((ch
>= 'a') && (ch
<= 'z')) ||
1348 ((ch
>= 'A') && (ch
<= 'Z')) ||
1349 ((ch
>= '0') && (ch
<= '9')) ||
1352 m_selStartY
= m_cursorY
;
1353 m_selEndY
= m_cursorY
;
1356 ch
= line
[(size_t) (p
-1)];
1357 while (((ch
>= 'a') && (ch
<= 'z')) ||
1358 ((ch
>= 'A') && (ch
<= 'Z')) ||
1359 ((ch
>= '0') && (ch
<= '9')) ||
1364 ch
= line
[(size_t) (p
-1)];
1370 if (p
< (int)line
.Len())
1372 ch
= line
[(size_t) (p
)];
1373 while (((ch
>= 'a') && (ch
<= 'z')) ||
1374 ((ch
>= 'A') && (ch
<= 'Z')) ||
1375 ((ch
>= '0') && (ch
<= '9')) ||
1378 if (p
>= (int)line
.Len()) break;
1380 ch
= line
[(size_t) (p
)];
1384 RefreshLine( m_cursorY
);
1388 wxString
wxTextCtrl::GetNextToken( wxString
&line
, size_t &pos
)
1391 size_t len
= line
.Len();
1392 for (size_t p
= pos
; p
< len
; p
++)
1394 if ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
))
1398 for (size_t q
= p
; q
< len
; q
++)
1399 ret
.Append( line
[q
] );
1406 if ((line
[p
] == '/') && (p
+1 < len
) && (line
[(size_t) (p
+1)] == '/'))
1408 for (size_t q
= p
; q
< len
; q
++)
1409 ret
.Append( line
[q
] );
1417 ret
.Append( line
[p
] );
1418 for (size_t q
= p
+1; q
< len
; q
++)
1420 ret
.Append( line
[q
] );
1421 if ((line
[q
] == '"') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1428 if (line
[p
] == '\'')
1430 ret
.Append( line
[p
] );
1431 for (size_t q
= p
+1; q
< len
; q
++)
1433 ret
.Append( line
[q
] );
1434 if ((line
[q
] == '\'') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1441 if (((line
[p
] >= 'a') && (line
[p
] <= 'z')) ||
1442 ((line
[p
] >= 'A') && (line
[p
] <= 'Z')) ||
1446 ret
.Append( line
[p
] );
1447 for (size_t q
= p
+1; q
< len
; q
++)
1449 if (((line
[q
] >= 'a') && (line
[q
] <= 'z')) ||
1450 ((line
[q
] >= 'A') && (line
[q
] <= 'Z')) ||
1451 ((line
[q
] >= '0') && (line
[q
] <= '9')) ||
1454 ret
.Append( line
[q
] );
1471 void wxTextCtrl::OnEraseBackground( wxEraseEvent
&event
)
1476 void wxTextCtrl::DrawLinePart( wxDC
&dc
, int x
, int y
, const wxString
&toDraw
, const wxString
&origin
, const wxColour
&colour
)
1479 size_t len
= origin
.Len();
1480 dc
.SetTextForeground( colour
);
1483 while (toDraw
[pos
] == wxT(' '))
1486 if (pos
== len
) return;
1492 current
+= toDraw
[pos
];
1494 while ( (toDraw
[pos
] == origin
[pos
]) && (pos
< len
))
1496 current
+= toDraw
[pos
];
1501 wxString tmp
= origin
.Left( start
);
1502 GetTextExtent( tmp
, &xx
, NULL
, NULL
, NULL
);
1505 dc
.DrawText( current
, xx
, yy
);
1509 void wxTextCtrl::DrawLine( wxDC
&dc
, int x
, int y
, const wxString
&line2
, int lineNum
)
1511 int selStartY
= m_selStartY
;
1512 int selEndY
= m_selEndY
;
1513 int selStartX
= m_selStartX
;
1514 int selEndX
= m_selEndX
;
1516 if ((selStartY
> selEndY
) ||
1517 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1519 int tmp
= selStartX
;
1520 selStartX
= selEndX
;
1523 selStartY
= selEndY
;
1527 wxString
line( line2
);
1528 if (HasFlag(wxTE_PASSWORD
))
1530 size_t len
= line
.Len();
1531 line
= wxString( wxT('*'), len
);
1534 wxString
keyword( ' ', line
.Len() );
1535 wxString
define( ' ', line
.Len() );
1536 wxString
variable( ' ', line
.Len() );
1537 wxString
comment( ' ', line
.Len() );
1538 wxString
my_string( ' ', line
.Len() );
1539 wxString
selection( ' ', line
.Len() );
1541 if (m_lang
!= wxSOURCE_LANG_NONE
)
1543 if (lineNum
== m_bracketY
)
1545 wxString
red( ' ', line
.Len() );
1546 if (m_bracketX
< (int)line
.Len())
1548 red
.SetChar( m_bracketX
, line
[(size_t) (m_bracketX
)] );
1549 line
.SetChar( m_bracketX
, ' ' );
1550 dc
.SetTextForeground( *wxRED
);
1551 dc
.DrawText( red
, x
, y
);
1552 dc
.SetTextForeground( *wxBLACK
);
1557 wxString
token( GetNextToken( line
, pos
) );
1558 while (!token
.IsNull())
1560 if (m_keywords
.Index( token
) != wxNOT_FOUND
)
1562 size_t end_pos
= pos
+ token
.Len();
1563 for (size_t i
= pos
; i
< end_pos
; i
++)
1565 keyword
[i
] = line
[i
];
1569 if (m_defines
.Index( token
) != wxNOT_FOUND
)
1571 size_t end_pos
= pos
+ token
.Len();
1572 for (size_t i
= pos
; i
< end_pos
; i
++)
1574 define
[i
] = line
[i
];
1578 if ((m_variables
.Index( token
) != wxNOT_FOUND
) ||
1579 ((token
.Len() > 2) && (token
[(size_t) (0)] == 'w') && (token
[(size_t) (1)] == 'x')))
1581 size_t end_pos
= pos
+ token
.Len();
1582 for (size_t i
= pos
; i
< end_pos
; i
++)
1584 variable
[i
] = line
[i
];
1588 if ((token
.Len() >= 2) && (token
[(size_t) (0)] == '/') && (token
[(size_t) (1)] == '/') && (m_lang
== wxSOURCE_LANG_CPP
))
1590 size_t end_pos
= pos
+ token
.Len();
1591 for (size_t i
= pos
; i
< end_pos
; i
++)
1593 comment
[i
] = line
[i
];
1597 if ((token
[(size_t) (0)] == '#') &&
1598 ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
)))
1600 size_t end_pos
= pos
+ token
.Len();
1601 for (size_t i
= pos
; i
< end_pos
; i
++)
1603 comment
[i
] = line
[i
];
1607 if ((token
[(size_t) (0)] == '"') || (token
[(size_t) (0)] == '\''))
1609 size_t end_pos
= pos
+ token
.Len();
1610 for (size_t i
= pos
; i
< end_pos
; i
++)
1612 my_string
[i
] = line
[i
];
1617 token
= GetNextToken( line
, pos
);
1621 if ((lineNum
< selStartY
) || (lineNum
> selEndY
))
1623 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1624 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1625 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1626 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1627 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1628 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1629 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1633 if (selStartY
== selEndY
)
1635 // int xx = selStartX*m_charWidth;
1636 int xx
= PosToPixel( lineNum
, selStartX
);
1637 // int ww = (selEndX-selStartX)*m_charWidth;
1638 int ww
= PosToPixel( lineNum
, selEndX
) - xx
;
1639 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1641 for (size_t i
= (size_t)selStartX
; i
< (size_t)selEndX
; i
++)
1643 selection
[i
] = line
[i
];
1647 if ((lineNum
> selStartY
) && (lineNum
< selEndY
))
1649 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1651 for (size_t i
= 0; i
< line
.Len(); i
++)
1653 selection
[i
] = line
[i
];
1657 if (lineNum
== selStartY
)
1659 // int xx = selStartX*m_charWidth;
1660 int xx
= PosToPixel( lineNum
, selStartX
);
1661 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1663 for (size_t i
= (size_t)selStartX
; i
< line
.Len(); i
++)
1665 selection
[i
] = line
[i
];
1669 if (lineNum
== selEndY
)
1671 // int ww = selEndX*m_charWidth;
1672 int ww
= PosToPixel( lineNum
, selEndX
);
1673 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1675 for (size_t i
= 0; i
< (size_t)selEndX
; i
++)
1677 selection
[i
] = line
[i
];
1682 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1683 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1684 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1685 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1686 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1687 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1688 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1691 void wxTextCtrl::OnPaint( wxPaintEvent
&event
)
1695 if (m_lines
.GetCount() == 0) return;
1699 dc
.SetFont( m_sourceFont
);
1702 GetViewStart( NULL
, &scroll_y
);
1704 // We have a inner border of two pixels
1705 // around the text, so scroll units do
1706 // not correspond to lines.
1707 if (scroll_y
> 0) scroll_y
--;
1711 GetClientSize( &size_x
, &size_y
);
1713 dc
.SetPen( *wxTRANSPARENT_PEN
);
1714 dc
.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT
), wxSOLID
) );
1715 int upper
= wxMin( (int)m_lines
.GetCount(), scroll_y
+(size_y
/m_lineHeight
)+2 );
1716 for (int i
= scroll_y
; i
< upper
; i
++)
1719 int y
= i
*m_lineHeight
+2;
1721 int h
= m_lineHeight
;
1722 CalcScrolledPosition( x
,y
,&x
,&y
);
1723 if (IsExposed(x
,y
,w
,h
))
1724 DrawLine( dc
, 0+2, i
*m_lineHeight
+2, m_lines
[i
].m_text
, i
);
1727 if (m_editable
&& (FindFocus() == this))
1729 ///dc.SetBrush( *wxRED_BRUSH );
1730 dc
.SetBrush( *wxBLACK_BRUSH
);
1731 // int xx = m_cursorX*m_charWidth;
1732 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
1733 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
1737 void wxTextCtrl::OnMouse( wxMouseEvent
&event
)
1739 if (m_lines
.GetCount() == 0) return;
1742 #if 0 // there is no middle button on iPAQs
1743 if (event
.MiddleDown())
1750 if (event
.LeftDClick())
1756 if (event
.LeftDown())
1764 m_capturing
= false;
1768 if (event
.LeftDown() ||
1769 (event
.LeftIsDown() && m_capturing
))
1771 int x
= event
.GetX();
1772 int y
= event
.GetY();
1773 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1775 // x /= m_charWidth;
1776 x
= PixelToPos( y
, x
);
1778 wxMin( 1000, wxMax( 0, x
) ),
1779 wxMin( (int)m_lines
.GetCount()-1, wxMax( 0, y
) ),
1780 event
.ShiftDown() || !event
.LeftDown() );
1784 void wxTextCtrl::OnChar( wxKeyEvent
&event
)
1786 if (m_lines
.GetCount() == 0) return;
1788 if (!m_editable
) return;
1792 GetClientSize( &size_x
, &size_y
);
1793 size_x
/= m_charWidth
;
1794 size_y
/= m_lineHeight
;
1797 if (event
.ShiftDown())
1799 switch (event
.GetKeyCode())
1801 case '4': event
.m_keyCode
= WXK_LEFT
; break;
1802 case '8': event
.m_keyCode
= WXK_UP
; break;
1803 case '6': event
.m_keyCode
= WXK_RIGHT
; break;
1804 case '2': event
.m_keyCode
= WXK_DOWN
; break;
1805 case '9': event
.m_keyCode
= WXK_PAGEUP
; break;
1806 case '3': event
.m_keyCode
= WXK_PAGEDOWN
; break;
1807 case '7': event
.m_keyCode
= WXK_HOME
; break;
1808 case '1': event
.m_keyCode
= WXK_END
; break;
1809 case '0': event
.m_keyCode
= WXK_INSERT
; break;
1813 switch (event
.GetKeyCode())
1817 if (m_ignoreInput
) return;
1819 MoveCursor( m_cursorX
, m_cursorY
-1, event
.ShiftDown() );
1820 m_ignoreInput
= true;
1825 if (m_ignoreInput
) return;
1826 if (m_cursorY
< (int)(m_lines
.GetCount()-1))
1827 MoveCursor( m_cursorX
, m_cursorY
+1, event
.ShiftDown() );
1828 m_ignoreInput
= true;
1833 if (m_ignoreInput
) return;
1836 MoveCursor( m_cursorX
-1, m_cursorY
, event
.ShiftDown() );
1841 MoveCursor( m_lines
[m_cursorY
-1].m_text
.Len(), m_cursorY
-1, event
.ShiftDown() );
1843 m_ignoreInput
= true;
1848 if (m_ignoreInput
) return;
1849 if (m_cursorX
< 1000)
1850 MoveCursor( m_cursorX
+1, m_cursorY
, event
.ShiftDown() );
1851 m_ignoreInput
= true;
1856 if (event
.ControlDown())
1857 MoveCursor( 0, 0, event
.ShiftDown() );
1859 MoveCursor( 0, m_cursorY
, event
.ShiftDown() );
1864 if (event
.ControlDown())
1865 MoveCursor( 0, m_lines
.GetCount()-1, event
.ShiftDown() );
1867 MoveCursor( m_lines
[m_cursorY
].m_text
.Len(), m_cursorY
, event
.ShiftDown() );
1872 if (m_ignoreInput
) return;
1873 MoveCursor( m_cursorX
, wxMin( (int)(m_lines
.GetCount()-1), m_cursorY
+size_y
), event
.ShiftDown() );
1874 m_ignoreInput
= true;
1879 if (m_ignoreInput
) return;
1880 MoveCursor( m_cursorX
, wxMax( 0, m_cursorY
-size_y
), event
.ShiftDown() );
1881 m_ignoreInput
= true;
1886 if (event
.ShiftDown())
1888 else if (event
.ControlDown())
1891 m_overwrite
= !m_overwrite
;
1896 if (m_windowStyle
& wxTE_PROCESS_ENTER
)
1898 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1899 event
.SetEventObject(this);
1900 event
.SetString(GetValue());
1901 if (GetEventHandler()->ProcessEvent(event
)) return;
1919 bool save_overwrite
= m_overwrite
;
1920 m_overwrite
= false;
1921 int i
= 4-(m_cursorX
% 4);
1923 for (int c
= 0; c
< i
; c
++)
1925 m_overwrite
= save_overwrite
;
1946 if ( (event
.GetKeyCode() >= 'a') &&
1947 (event
.GetKeyCode() <= 'z') &&
1955 if ( (event
.GetKeyCode() >= 32) &&
1956 (event
.GetKeyCode() <= 255) &&
1957 !(event
.ControlDown() && !event
.AltDown()) ) // filters out Ctrl-X but leaves Alt-Gr
1961 DoChar( (char) event
.GetKeyCode() );
1970 void wxTextCtrl::OnInternalIdle()
1972 wxControl::OnInternalIdle();
1974 m_ignoreInput
= false;
1976 if (m_lang
!= wxSOURCE_LANG_NONE
)
1977 SearchForBrackets();
1980 void wxTextCtrl::Indent()
1982 int startY
= m_cursorY
;
1983 int endY
= m_cursorY
;
1986 startY
= m_selStartY
;
1996 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1998 for (int i
= startY
; i
<= endY
; i
++)
2000 m_lines
[i
].m_text
.insert( 0u, wxT(" ") );
2005 void wxTextCtrl::Unindent()
2007 int startY
= m_cursorY
;
2008 int endY
= m_cursorY
;
2011 startY
= m_selStartY
;
2021 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
2023 for (int i
= startY
; i
<= endY
; i
++)
2025 for (int n
= 0; n
< 4; n
++)
2027 if (m_lines
[i
].m_text
[0u] == wxT(' '))
2028 m_lines
[i
].m_text
.erase(0u,1u);
2033 bool wxTextCtrl::HasSelection()
2035 return ((m_selStartY
!= m_selEndY
) || (m_selStartX
!= m_selEndX
));
2038 void wxTextCtrl::ClearSelection()
2046 void wxTextCtrl::RefreshLine( int n
)
2048 int y
= n
*m_lineHeight
;
2050 CalcScrolledPosition( x
, y
, &x
, &y
);
2051 wxRect
rect( 0+2, y
+2, 10000, m_lineHeight
);
2052 Refresh( true, &rect
);
2055 void wxTextCtrl::RefreshDown( int n
)
2059 GetClientSize( &size_x
, &size_y
);
2063 GetViewStart( &view_x
, &view_y
);
2071 int y
= n
*m_lineHeight
;
2073 CalcScrolledPosition( x
, y
, &x
, &y
);
2075 wxRect
rect( 0+2, y
+2, 10000, size_y
);
2076 Refresh( true, &rect
);
2080 void wxTextCtrl::MoveCursor( int new_x
, int new_y
, bool shift
, bool centre
)
2082 if (!m_editable
) return;
2084 // if (IsSingleLine() || (m_lang == wxSOURCE_LANG_NONE))
2086 if (new_x
> (int) (m_lines
[new_y
].m_text
.Len()))
2087 new_x
= m_lines
[new_y
].m_text
.Len();
2090 if ((new_x
== m_cursorX
) && (new_y
== m_cursorY
)) return;
2092 bool no_cursor_refresh
= false;
2093 bool has_selection
= HasSelection();
2098 bool erase_background
= true;
2102 m_selStartX
= m_cursorX
;
2103 m_selStartY
= m_cursorY
;
2107 if (new_y
> m_selStartY
)
2109 y
= m_selStartY
*m_lineHeight
;
2110 h
= (new_y
-m_selStartY
+1)*m_lineHeight
;
2112 else if (new_y
== m_selStartY
)
2114 x
= PosToPixel( new_y
, m_selStartX
);
2115 w
= PosToPixel( new_y
, new_x
) - x
;
2119 w
= -w
+ 2; // +2 for the cursor
2121 y
= m_selStartY
*m_lineHeight
;
2126 y
= new_y
*m_lineHeight
;
2127 h
= (-new_y
+m_selStartY
+1)*m_lineHeight
;
2130 no_cursor_refresh
= true;
2136 if (new_y
== m_selEndY
)
2138 y
= new_y
*m_lineHeight
;
2140 if (m_selEndX
> new_x
)
2142 // x = new_x*m_charWidth;
2143 x
= PosToPixel( new_y
, new_x
);
2144 // w = (m_selEndX-new_x)*m_charWidth;
2145 w
= PosToPixel( new_y
, m_selEndX
) - x
;
2149 // x = m_selEndX*m_charWidth;
2150 x
= PosToPixel( new_y
, m_selEndX
);
2151 // w = (-m_selEndX+new_x)*m_charWidth;
2152 w
= PosToPixel( new_y
, new_x
) - x
;
2159 if (new_y
> m_selEndY
)
2161 y
= m_selEndY
*m_lineHeight
;
2162 h
= (new_y
-m_selEndY
+1) * m_lineHeight
;
2164 erase_background
= ((m_selEndY
< m_selStartY
) ||
2165 ((m_selEndY
== m_selStartY
) && (m_selEndX
< m_selStartX
)));
2169 y
= new_y
*m_lineHeight
;
2170 h
= (-new_y
+m_selEndY
+1) * m_lineHeight
;
2172 erase_background
= ((m_selEndY
> m_selStartY
) ||
2173 ((m_selEndY
== m_selStartY
) && (m_selEndX
> m_selStartX
)));
2175 no_cursor_refresh
= true;
2184 CalcScrolledPosition( x
, y
, &x
, &y
);
2185 wxRect
rect( x
+2, y
+2, w
, h
);
2186 Refresh( erase_background
, &rect
);
2192 int ry1
= m_selEndY
;
2193 int ry2
= m_selStartY
;
2207 int y
= ry1
*m_lineHeight
;
2208 CalcScrolledPosition( x
, y
, &x
, &y
);
2209 wxRect
rect( 0, y
+2, 10000, (ry2
-ry1
+1)*m_lineHeight
);
2211 Refresh( true, &rect
);
2216 printf( "startx %d starty %d endx %d endy %d\n",
2217 m_selStartX, m_selStartY, m_selEndX, m_selEndY );
2219 printf( "has %d\n", (int)HasSelection() );
2222 if (!no_cursor_refresh
)
2224 // int x = m_cursorX*m_charWidth;
2225 int x
= PosToPixel( m_cursorY
, m_cursorX
);
2226 int y
= m_cursorY
*m_lineHeight
;
2227 CalcScrolledPosition( x
, y
, &x
, &y
);
2228 wxRect
rect( x
+2, y
+2, 4, m_lineHeight
+2 );
2233 Refresh( true, &rect
);
2235 if (FindFocus() == this)
2237 wxClientDC
dc(this);
2239 dc
.SetPen( *wxTRANSPARENT_PEN
);
2240 //dc.SetBrush( *wxRED_BRUSH );
2241 dc
.SetBrush( *wxBLACK_BRUSH
);
2242 // int xx = m_cursorX*m_charWidth;
2243 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
2244 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
2250 GetClientSize( &size_x
, &size_y
);
2251 size_x
/= m_charWidth
;
2252 size_y
/= m_lineHeight
;
2256 GetViewStart( &view_x
, &view_y
);
2260 int sy
= m_cursorY
- (size_y
/2);
2266 if (m_cursorY
< view_y
)
2267 Scroll( -1, m_cursorY
);
2268 else if (m_cursorY
> view_y
+size_y
-1)
2269 Scroll( -1, m_cursorY
-size_y
+1 );
2272 //int xx = m_cursorX;
2273 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
2277 else if (xx
> view_x
+size_x
-1)
2278 Scroll( xx
-size_x
+1, -1 );
2281 void wxTextCtrl::MyAdjustScrollbars()
2286 int y_range
= m_lines
.GetCount();
2289 GetClientSize( NULL
, &height
);
2291 if (height
>= (int)m_lines
.GetCount() *m_lineHeight
)
2296 GetViewStart( &view_x
, &view_y
);
2298 SetScrollbars( m_charWidth
, m_lineHeight
, m_longestLine
+2, y_range
, view_x
, view_y
);
2301 //-----------------------------------------------------------------------------
2302 // clipboard handlers
2303 //-----------------------------------------------------------------------------
2305 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
2310 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
2315 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
2320 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
2325 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
2330 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2332 event
.Enable( CanCut() );
2335 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2337 event
.Enable( CanCopy() );
2340 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2342 event
.Enable( CanPaste() );
2345 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2347 event
.Enable( CanUndo() );
2350 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2352 event
.Enable( CanRedo() );
2355 wxSize
wxTextCtrl::DoGetBestSize() const
2359 wxSize
ret(80, m_lineHeight
+ 4);
2361 if (HasFlag(wxBORDER_SUNKEN
) || HasFlag(wxBORDER_RAISED
))
2364 if (HasFlag(wxBORDER_SIMPLE
))
2371 return wxSize(80, 60);
2375 // ----------------------------------------------------------------------------
2377 // ----------------------------------------------------------------------------
2379 void wxTextCtrl::Freeze()
2383 void wxTextCtrl::Thaw()
2387 void wxTextCtrl::OnSetFocus( wxFocusEvent
& event
)
2389 // To hide or show caret, as appropriate
2393 void wxTextCtrl::OnKillFocus( wxFocusEvent
& event
)
2395 // To hide or show caret, as appropriate
2399 // ----------------------------------------------------------------------------
2400 // text control scrolling
2401 // ----------------------------------------------------------------------------
2403 bool wxTextCtrl::ScrollLines(int lines
)
2405 wxFAIL_MSG( "wxTextCtrl::ScrollLines not implemented");
2410 bool wxTextCtrl::ScrollPages(int pages
)
2412 wxFAIL_MSG( "wxTextCtrl::ScrollPages not implemented");