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
)
416 void wxTextCtrl::DiscardEdits()
422 void wxTextCtrl::SetMaxLength(unsigned long len
)
426 int wxTextCtrl::PosToPixel( int line
, int pos
)
428 // TODO add support for Tabs
430 if (line
>= (int)m_lines
.GetCount()) return 0;
431 if (pos
< 0) return 0;
433 wxString text
= m_lines
[line
].m_text
;
435 if (text
.IsEmpty()) return 0;
437 if (pos
< (int)text
.Len())
438 text
.Remove( pos
, text
.Len()-pos
);
442 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
447 int wxTextCtrl::PixelToPos( int line
, int pixel
)
449 if (pixel
< 2) return 0;
451 if (line
>= (int)m_lines
.GetCount()) return 0;
453 wxString text
= m_lines
[line
].m_text
;
456 int res
= text
.Len();
459 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
465 text
.Remove( res
,1 );
471 void wxTextCtrl::SetLanguage( wxSourceLanguage lang
)
478 void wxTextCtrl::WriteText(const wxString
& text2
)
480 if (text2
.IsEmpty()) return;
484 wxString
text( text2
);
487 while ( (pos
= text
.Find('\n')) != -1 )
489 lines
.Add( text
.Left( pos
) );
490 text
.Remove( 0, pos
+1 );
493 int count
= (int)lines
.GetCount();
495 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
496 wxString
tmp2( tmp1
);
497 int len
= (int)tmp1
.Len();
502 for (int i
= 0; i
< m_cursorX
-len
; i
++)
504 m_lines
[m_cursorY
].m_text
.Append( tmp
);
509 tmp1
.Remove( m_cursorX
);
510 tmp2
.Remove( 0, m_cursorX
);
511 tmp1
.Append( lines
[0] );
515 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
518 m_lines
[m_cursorY
].m_text
= tmp1
;
519 RefreshLine( m_cursorY
);
523 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
525 m_lines
[m_cursorY
].m_text
= tmp1
;
527 for (i
= 1; i
< count
; i
++)
528 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
529 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
531 MyAdjustScrollbars();
532 RefreshDown( m_cursorY
);
536 void wxTextCtrl::AppendText(const wxString
& text2
)
538 if (text2
.IsEmpty()) return;
542 wxString
text( text2
);
545 while ( (pos
= text
.Find('\n')) != -1 )
547 lines
.Add( text
.Left( pos
) );
548 text
.Remove( 0, pos
+1 );
551 int count
= (int)lines
.GetCount();
553 size_t y
= m_lines
.GetCount()-1;
555 wxString
tmp( m_lines
[y
].m_text
);
556 tmp
.Append( lines
[0] );
560 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, y
, y
, this ) );
562 m_lines
[y
].m_text
= tmp
;
567 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, y
, y
+count
-1, this ) );
569 m_lines
[y
].m_text
= tmp
;
571 for (i
= 1; i
< count
; i
++)
572 m_lines
.Insert( new wxSourceLine( lines
[i
] ), y
+i
);
574 MyAdjustScrollbars();
579 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
584 long wxTextCtrl::XYToPosition(long x
, long y
) const
588 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
592 // Add one for the end-of-line character
593 ret
+= m_lines
[i
].m_text
.Len() + 1;
597 if ((size_t)x
< (m_lines
[i
].m_text
.Len()+1))
600 return (ret
+ m_lines
[i
].m_text
.Len() + 1);
606 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
608 if (m_lines
.GetCount() == 0)
619 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
621 //pos -= m_lines[i].m_text.Len();
624 // Add one for the end-of-line character. (In Windows,
625 // there are _two_ positions for each end of line.)
626 if (pos
<= ((int)m_lines
[i
].m_text
.Len()))
633 pos
-= (m_lines
[i
].m_text
.Len() + 1);
638 //xx = m_lines[ m_lines.GetCount()-1 ].m_text.Len();
646 void wxTextCtrl::ShowPosition(long pos
)
650 void wxTextCtrl::Copy()
652 if (!HasSelection()) return;
656 int selStartY
= m_selStartY
;
657 int selEndY
= m_selEndY
;
658 int selStartX
= m_selStartX
;
659 int selEndX
= m_selEndX
;
661 if ((selStartY
> selEndY
) ||
662 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
672 if (selStartY
== selEndY
)
674 sel
= m_lines
[selStartY
].m_text
;
676 if (selStartX
>= (int)sel
.Len()) return;
677 if (selEndX
> (int)sel
.Len())
680 sel
.Remove( selEndX
, sel
.Len()-selEndX
);
681 sel
.Remove( 0, selStartX
);
685 wxString
tmp( m_lines
[selStartY
].m_text
);
687 if (selStartX
< (int)tmp
.Len())
689 tmp
.Remove( 0, selStartX
);
691 sel
.Append( wxT("\n") );
693 for (int i
= selStartY
+1; i
< selEndY
; i
++)
695 sel
.Append( m_lines
[i
].m_text
);
696 sel
.Append( wxT("\n") );
698 tmp
= m_lines
[selEndY
].m_text
;
699 if (selEndX
> (int)tmp
.Len())
703 tmp
.Remove( selEndX
, tmp
.Len()-selEndX
);
708 if (wxTheClipboard
->Open())
710 wxTheClipboard
->SetData( new wxTextDataObject( sel
) );
711 wxTheClipboard
->Close();
715 void wxTextCtrl::Cut()
722 void wxTextCtrl::Paste()
726 if (!wxTheClipboard
->Open()) return;
728 if (!wxTheClipboard
->IsSupported( wxDF_TEXT
))
730 wxTheClipboard
->Close();
735 wxTextDataObject data
;
737 bool ret
= wxTheClipboard
->GetData( data
);
739 wxTheClipboard
->Close();
745 wxString
text( data
.GetText() );
748 while ( (pos
= text
.Find('\n')) != -1 )
750 lines
.Add( text
.Left( pos
) );
751 text
.Remove( 0, pos
+1 );
754 int count
= (int)lines
.GetCount();
756 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
757 wxString
tmp2( tmp1
);
758 int len
= (int)tmp1
.Len();
763 for (int i
= 0; i
< m_cursorX
-len
; i
++)
765 m_lines
[m_cursorY
].m_text
.Append( tmp
);
770 tmp1
.Remove( m_cursorX
);
771 tmp2
.Remove( 0, m_cursorX
);
772 tmp1
.Append( lines
[0] );
776 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
779 m_lines
[m_cursorY
].m_text
= tmp1
;
780 RefreshLine( m_cursorY
);
784 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
786 m_lines
[m_cursorY
].m_text
= tmp1
;
788 for (i
= 1; i
< count
; i
++)
789 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
790 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
792 MyAdjustScrollbars();
793 RefreshDown( m_cursorY
);
797 void wxTextCtrl::Undo()
799 if (m_undos
.GetCount() == 0) return;
801 wxList::compatibility_iterator node
= m_undos
.Item( m_undos
.GetCount()-1 );
802 wxSourceUndoStep
*undo
= (wxSourceUndoStep
*) node
->GetData();
807 m_undos
.Erase( node
);
812 void wxTextCtrl::SetInsertionPoint(long pos
)
816 PositionToXY(pos
, & x
, & y
);
819 // TODO: scroll to this position if necessary
823 void wxTextCtrl::SetInsertionPointEnd()
825 SetInsertionPoint(GetLastPosition());
828 long wxTextCtrl::GetInsertionPoint() const
830 return XYToPosition( m_cursorX
, m_cursorY
);
833 long wxTextCtrl::GetLastPosition() const
835 size_t lineCount
= m_lines
.GetCount() - 1;
836 // It's the length of the line, not the length - 1,
837 // because there's a position after the last character.
838 return XYToPosition( m_lines
[lineCount
].m_text
.Len(), lineCount
);
841 void wxTextCtrl::SetSelection(long from
, long to
)
845 void wxTextCtrl::SetEditable(bool editable
)
847 m_editable
= editable
;
850 bool wxTextCtrl::Enable( bool enable
)
855 bool wxTextCtrl::SetFont(const wxFont
& font
)
857 wxTextCtrlBase::SetFont( font
);
862 dc
.SetFont( m_sourceFont
);
863 m_lineHeight
= dc
.GetCharHeight();
864 m_charWidth
= dc
.GetCharWidth();
866 // TODO: recalc longest lines
868 MyAdjustScrollbars();
873 bool wxTextCtrl::SetForegroundColour(const wxColour
& colour
)
875 return wxWindow::SetForegroundColour( colour
);
878 bool wxTextCtrl::SetBackgroundColour(const wxColour
& colour
)
880 return wxWindow::SetBackgroundColour( colour
);
883 //-----------------------------------------------------------------------------
884 // private code and handlers
885 //-----------------------------------------------------------------------------
887 void wxTextCtrl::SearchForBrackets()
889 int oldBracketY
= m_bracketY
;
890 int oldBracketX
= m_bracketX
;
892 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()) return;
894 wxString current
= m_lines
[m_cursorY
].m_text
;
896 // reverse search first
901 bracket
= current
[(size_t) (m_cursorX
-1)];
903 if (bracket
== ')' || bracket
== ']' || bracket
== '}')
905 char antibracket
= '(';
906 if (bracket
== ']') antibracket
= '[';
907 if (bracket
== '}') antibracket
= '{';
911 int endY
= m_cursorY
-60;
912 if (endY
< 0) endY
= 0;
913 for (int y
= m_cursorY
; y
>= endY
; y
--)
915 current
= m_lines
[y
].m_text
;
917 current
.erase(m_cursorX
-1,current
.Len()-m_cursorX
+1);
919 for (int n
= current
.Len()-1; n
>= 0; n
--)
922 if (current
[(size_t) (n
)] == '\'')
924 for (int m
= n
-1; m
>= 0; m
--)
926 if (current
[(size_t) (m
)] == '\'')
928 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
937 if (current
[(size_t) (n
)] == '\"')
939 for (int m
= n
-1; m
>= 0; m
--)
941 if (current
[(size_t) (m
)] == '\"')
943 if (m
== 0 || current
[(size_t) (m
-1)] != '\\')
951 if (current
[(size_t) (n
)] == antibracket
)
958 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
959 RefreshLine( oldBracketY
);
960 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
961 RefreshLine( m_bracketY
);
965 else if (current
[(size_t) (n
)] == bracket
)
976 if ((int)current
.Len() > m_cursorX
)
977 bracket
= current
[(size_t) (m_cursorX
)];
978 if (bracket
== '(' || bracket
== '[' || bracket
== '{')
980 char antibracket
= ')';
981 if (bracket
== '[') antibracket
= ']';
982 if (bracket
== '{') antibracket
= '}';
986 int endY
= m_cursorY
+60;
987 if (endY
> (int)(m_lines
.GetCount()-1)) endY
= m_lines
.GetCount()-1;
988 for (int y
= m_cursorY
; y
<= endY
; y
++)
990 current
= m_lines
[y
].m_text
;
995 for (int n
= start
; n
< (int)current
.Len(); n
++)
998 if (current
[(size_t) (n
)] == '\'')
1000 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
1002 if (current
[(size_t) (m
)] == '\'')
1004 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1013 if (current
[(size_t) (n
)] == '\"')
1015 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
1017 if (current
[(size_t) (m
)] == '\"')
1019 if (m
== 0 || (current
[(size_t) (m
-1)] != '\\') || (m
>= 2 && current
[(size_t) (m
-2)] == '\\'))
1027 if (current
[(size_t) (n
)] == antibracket
)
1034 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
1035 RefreshLine( oldBracketY
);
1036 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
1037 RefreshLine( m_bracketY
);
1041 else if (current
[(size_t) (n
)] == bracket
)
1049 if (oldBracketY
!= -1)
1052 RefreshLine( oldBracketY
);
1056 void wxTextCtrl::Delete()
1058 if (!HasSelection()) return;
1062 int selStartY
= m_selStartY
;
1063 int selEndY
= m_selEndY
;
1064 int selStartX
= m_selStartX
;
1065 int selEndX
= m_selEndX
;
1067 if ((selStartY
> selEndY
) ||
1068 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1070 int tmp
= selStartX
;
1071 selStartX
= selEndX
;
1074 selStartY
= selEndY
;
1078 int len
= (int)m_lines
[selStartY
].m_text
.Len();
1080 if (selStartY
== selEndY
)
1082 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, selStartY
, selStartY
, this ) );
1084 wxString
tmp( m_lines
[selStartY
].m_text
);
1085 if (selStartX
< len
)
1089 tmp
.Remove( selStartX
, selEndX
-selStartX
);
1090 m_lines
[selStartY
].m_text
= tmp
;
1093 m_cursorX
= selStartX
;
1094 RefreshLine( selStartY
);
1098 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, selStartY
, selEndY
, this ) );
1100 if (selStartX
< len
)
1101 m_lines
[selStartY
].m_text
.Remove( selStartX
);
1103 for (int i
= 0; i
< selEndY
-selStartY
-1; i
++)
1104 m_lines
.RemoveAt( selStartY
+1 );
1106 if (selEndX
< (int)m_lines
[selStartY
+1].m_text
.Len())
1107 m_lines
[selStartY
+1].m_text
.Remove( 0, selEndX
);
1109 m_lines
[selStartY
+1].m_text
.Remove( 0 );
1111 m_lines
[selStartY
].m_text
.Append( m_lines
[selStartY
+1].m_text
);
1112 m_lines
.RemoveAt( selStartY
+1 );
1115 MoveCursor( selStartX
, selStartY
);
1116 MyAdjustScrollbars();
1118 RefreshDown( selStartY
);
1122 void wxTextCtrl::DeleteLine()
1124 if (HasSelection()) return;
1126 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()-1) return; // TODO
1128 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1130 m_lines
.RemoveAt( m_cursorY
);
1132 if (m_cursorY
>= (int)m_lines
.GetCount()) m_cursorY
--;
1134 MyAdjustScrollbars();
1135 RefreshDown( m_cursorY
);
1138 void wxTextCtrl::DoChar( char c
)
1142 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1144 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1146 if (m_cursorX
>= (int)tmp
.Len())
1148 int len
= tmp
.Len();
1149 for (int i
= 0; i
< m_cursorX
- len
; i
++)
1156 tmp
.SetChar( m_cursorX
, c
);
1158 tmp
.insert( m_cursorX
, 1, c
);
1161 m_lines
[m_cursorY
].m_text
= tmp
;
1163 // if (tmp.Len() > m_longestLine)
1165 // m_longestLine = tmp.Len();
1166 // MyAdjustScrollbars();
1170 GetTextExtent( tmp
, &ww
, NULL
, NULL
, NULL
);
1172 if (ww
> m_longestLine
)
1175 MyAdjustScrollbars();
1180 int y
= m_cursorY
*m_lineHeight
;
1181 // int x = (m_cursorX-1)*m_charWidth;
1182 int x
= PosToPixel( m_cursorY
, m_cursorX
-1 );
1183 CalcScrolledPosition( x
, y
, &x
, &y
);
1184 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1185 Refresh( TRUE
, &rect
);
1186 // refresh whole line for syntax colour highlighting
1188 Refresh( FALSE
, &rect
);
1192 GetClientSize( &size_x
, &size_y
);
1193 size_x
/= m_charWidth
;
1197 GetViewStart( &view_x
, &view_y
);
1199 //int xx = m_cursorX;
1200 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
1204 else if (xx
> view_x
+size_x
-1)
1205 Scroll( xx
-size_x
+1, -1 );
1208 void wxTextCtrl::DoBack()
1214 if (m_cursorY
== 0) return;
1216 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_BACK
, m_cursorY
-1, m_cursorY
, this ) );
1218 wxString
tmp1( m_lines
[m_cursorY
-1].m_text
);
1220 wxString
tmp2( m_lines
[m_cursorY
].m_text
);
1222 m_cursorX
= tmp1
.Len();
1224 tmp1
.Append( tmp2
);
1225 m_lines
[m_cursorY
].m_text
= tmp1
;
1226 m_lines
.RemoveAt( m_cursorY
+1 );
1228 MyAdjustScrollbars();
1229 RefreshDown( m_cursorY
-1 );
1233 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1235 if (m_cursorX
<= (int)m_lines
[m_cursorY
].m_text
.Len())
1236 m_lines
[m_cursorY
].m_text
.Remove( m_cursorX
-1, 1 );
1239 int y
= m_cursorY
*m_lineHeight
;
1240 // int x = m_cursorX*m_charWidth;
1241 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1242 CalcScrolledPosition( x
, y
, &x
, &y
);
1243 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1244 Refresh( TRUE
, &rect
);
1245 // refresh whole line for syntax colour highlighting
1247 Refresh( FALSE
, &rect
);
1251 void wxTextCtrl::DoDelete()
1255 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1257 int len
= (int)tmp
.Len();
1258 if (m_cursorX
>= len
)
1260 if (m_cursorY
== (int)m_lines
.GetCount()-1) return;
1262 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1264 for (int i
= 0; i
< (m_cursorX
-len
); i
++)
1267 tmp
+= m_lines
[m_cursorY
+1].m_text
;
1269 m_lines
[m_cursorY
] = tmp
;
1270 m_lines
.RemoveAt( m_cursorY
+1 );
1272 MyAdjustScrollbars();
1273 RefreshDown( m_cursorY
);
1277 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1279 tmp
.Remove( m_cursorX
, 1 );
1280 m_lines
[m_cursorY
].m_text
= tmp
;
1282 int y
= m_cursorY
*m_lineHeight
;
1283 // int x = m_cursorX*m_charWidth;
1284 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1285 CalcScrolledPosition( x
, y
, &x
, &y
);
1286 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1287 Refresh( TRUE
, &rect
);
1288 // refresh whole line for syntax colour highlighting
1290 Refresh( FALSE
, &rect
);
1294 void wxTextCtrl::DoReturn()
1298 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_ENTER
, m_cursorY
, m_cursorY
, this ) );
1300 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1301 size_t indent
= tmp
.find_first_not_of( ' ' );
1302 if (indent
== wxSTRING_MAXLEN
) indent
= 0;
1304 if (m_cursorX
>= (int)tmp
.Len())
1306 int cursorX
= indent
;
1307 int cursorY
= m_cursorY
+ 1;
1310 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1311 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1313 MyAdjustScrollbars();
1314 MoveCursor( cursorX
, cursorY
);
1315 RefreshDown( m_cursorY
);
1319 wxString
tmp1( tmp
);
1320 tmp1
.Remove( m_cursorX
, tmp
.Len()-m_cursorX
);
1321 m_lines
[m_cursorY
].m_text
= tmp1
;
1323 wxString
tmp2( tmp
);
1324 tmp2
.Remove( 0, m_cursorX
);
1326 int cursorX
= indent
;
1327 int cursorY
= m_cursorY
+ 1;
1330 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1331 new_tmp
.Append( tmp2
);
1332 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1334 MyAdjustScrollbars();
1335 MoveCursor( cursorX
, cursorY
);
1336 RefreshDown( m_cursorY
-1 );
1340 void wxTextCtrl::DoDClick()
1342 wxString
line( m_lines
[ m_cursorY
].m_text
);
1343 if (m_cursorX
>= (int)line
.Len()) return;
1345 char ch
= line
[(size_t) (p
)];
1346 if (((ch
>= 'a') && (ch
<= 'z')) ||
1347 ((ch
>= 'A') && (ch
<= 'Z')) ||
1348 ((ch
>= '0') && (ch
<= '9')) ||
1351 m_selStartY
= m_cursorY
;
1352 m_selEndY
= m_cursorY
;
1355 ch
= line
[(size_t) (p
-1)];
1356 while (((ch
>= 'a') && (ch
<= 'z')) ||
1357 ((ch
>= 'A') && (ch
<= 'Z')) ||
1358 ((ch
>= '0') && (ch
<= '9')) ||
1363 ch
= line
[(size_t) (p
-1)];
1369 if (p
< (int)line
.Len())
1371 ch
= line
[(size_t) (p
)];
1372 while (((ch
>= 'a') && (ch
<= 'z')) ||
1373 ((ch
>= 'A') && (ch
<= 'Z')) ||
1374 ((ch
>= '0') && (ch
<= '9')) ||
1377 if (p
>= (int)line
.Len()) break;
1379 ch
= line
[(size_t) (p
)];
1383 RefreshLine( m_cursorY
);
1387 wxString
wxTextCtrl::GetNextToken( wxString
&line
, size_t &pos
)
1390 size_t len
= line
.Len();
1391 for (size_t p
= pos
; p
< len
; p
++)
1393 if ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
))
1397 for (size_t q
= p
; q
< len
; q
++)
1398 ret
.Append( line
[q
] );
1405 if ((line
[p
] == '/') && (p
+1 < len
) && (line
[(size_t) (p
+1)] == '/'))
1407 for (size_t q
= p
; q
< len
; q
++)
1408 ret
.Append( line
[q
] );
1416 ret
.Append( line
[p
] );
1417 for (size_t q
= p
+1; q
< len
; q
++)
1419 ret
.Append( line
[q
] );
1420 if ((line
[q
] == '"') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1427 if (line
[p
] == '\'')
1429 ret
.Append( line
[p
] );
1430 for (size_t q
= p
+1; q
< len
; q
++)
1432 ret
.Append( line
[q
] );
1433 if ((line
[q
] == '\'') && ((line
[(size_t) (q
-1)] != '\\') || (q
>= 2 && line
[(size_t) (q
-2)] == '\\')))
1440 if (((line
[p
] >= 'a') && (line
[p
] <= 'z')) ||
1441 ((line
[p
] >= 'A') && (line
[p
] <= 'Z')) ||
1445 ret
.Append( line
[p
] );
1446 for (size_t q
= p
+1; q
< len
; q
++)
1448 if (((line
[q
] >= 'a') && (line
[q
] <= 'z')) ||
1449 ((line
[q
] >= 'A') && (line
[q
] <= 'Z')) ||
1450 ((line
[q
] >= '0') && (line
[q
] <= '9')) ||
1453 ret
.Append( line
[q
] );
1470 void wxTextCtrl::OnEraseBackground( wxEraseEvent
&event
)
1475 void wxTextCtrl::DrawLinePart( wxDC
&dc
, int x
, int y
, const wxString
&toDraw
, const wxString
&origin
, const wxColour
&colour
)
1478 size_t len
= origin
.Len();
1479 dc
.SetTextForeground( colour
);
1482 while (toDraw
[pos
] == wxT(' '))
1485 if (pos
== len
) return;
1491 current
+= toDraw
[pos
];
1493 while ( (toDraw
[pos
] == origin
[pos
]) && (pos
< len
))
1495 current
+= toDraw
[pos
];
1500 wxString tmp
= origin
.Left( start
);
1501 GetTextExtent( tmp
, &xx
, NULL
, NULL
, NULL
);
1504 dc
.DrawText( current
, xx
, yy
);
1508 void wxTextCtrl::DrawLine( wxDC
&dc
, int x
, int y
, const wxString
&line2
, int lineNum
)
1510 int selStartY
= m_selStartY
;
1511 int selEndY
= m_selEndY
;
1512 int selStartX
= m_selStartX
;
1513 int selEndX
= m_selEndX
;
1515 if ((selStartY
> selEndY
) ||
1516 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1518 int tmp
= selStartX
;
1519 selStartX
= selEndX
;
1522 selStartY
= selEndY
;
1526 wxString
line( line2
);
1527 if (HasFlag(wxTE_PASSWORD
))
1529 size_t len
= line
.Len();
1530 line
= wxString( wxT('*'), len
);
1533 wxString
keyword( ' ', line
.Len() );
1534 wxString
define( ' ', line
.Len() );
1535 wxString
variable( ' ', line
.Len() );
1536 wxString
comment( ' ', line
.Len() );
1537 wxString
my_string( ' ', line
.Len() );
1538 wxString
selection( ' ', line
.Len() );
1540 if (m_lang
!= wxSOURCE_LANG_NONE
)
1542 if (lineNum
== m_bracketY
)
1544 wxString
red( ' ', line
.Len() );
1545 if (m_bracketX
< (int)line
.Len())
1547 red
.SetChar( m_bracketX
, line
[(size_t) (m_bracketX
)] );
1548 line
.SetChar( m_bracketX
, ' ' );
1549 dc
.SetTextForeground( *wxRED
);
1550 dc
.DrawText( red
, x
, y
);
1551 dc
.SetTextForeground( *wxBLACK
);
1556 wxString
token( GetNextToken( line
, pos
) );
1557 while (!token
.IsNull())
1559 if (m_keywords
.Index( token
) != wxNOT_FOUND
)
1561 size_t end_pos
= pos
+ token
.Len();
1562 for (size_t i
= pos
; i
< end_pos
; i
++)
1564 keyword
[i
] = line
[i
];
1568 if (m_defines
.Index( token
) != wxNOT_FOUND
)
1570 size_t end_pos
= pos
+ token
.Len();
1571 for (size_t i
= pos
; i
< end_pos
; i
++)
1573 define
[i
] = line
[i
];
1577 if ((m_variables
.Index( token
) != wxNOT_FOUND
) ||
1578 ((token
.Len() > 2) && (token
[(size_t) (0)] == 'w') && (token
[(size_t) (1)] == 'x')))
1580 size_t end_pos
= pos
+ token
.Len();
1581 for (size_t i
= pos
; i
< end_pos
; i
++)
1583 variable
[i
] = line
[i
];
1587 if ((token
.Len() >= 2) && (token
[(size_t) (0)] == '/') && (token
[(size_t) (1)] == '/') && (m_lang
== wxSOURCE_LANG_CPP
))
1589 size_t end_pos
= pos
+ token
.Len();
1590 for (size_t i
= pos
; i
< end_pos
; i
++)
1592 comment
[i
] = line
[i
];
1596 if ((token
[(size_t) (0)] == '#') &&
1597 ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
)))
1599 size_t end_pos
= pos
+ token
.Len();
1600 for (size_t i
= pos
; i
< end_pos
; i
++)
1602 comment
[i
] = line
[i
];
1606 if ((token
[(size_t) (0)] == '"') || (token
[(size_t) (0)] == '\''))
1608 size_t end_pos
= pos
+ token
.Len();
1609 for (size_t i
= pos
; i
< end_pos
; i
++)
1611 my_string
[i
] = line
[i
];
1616 token
= GetNextToken( line
, pos
);
1620 if ((lineNum
< selStartY
) || (lineNum
> selEndY
))
1622 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1623 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1624 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1625 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1626 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1627 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1628 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1632 if (selStartY
== selEndY
)
1634 // int xx = selStartX*m_charWidth;
1635 int xx
= PosToPixel( lineNum
, selStartX
);
1636 // int ww = (selEndX-selStartX)*m_charWidth;
1637 int ww
= PosToPixel( lineNum
, selEndX
) - xx
;
1638 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1640 for (size_t i
= (size_t)selStartX
; i
< (size_t)selEndX
; i
++)
1642 selection
[i
] = line
[i
];
1646 if ((lineNum
> selStartY
) && (lineNum
< selEndY
))
1648 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1650 for (size_t i
= 0; i
< line
.Len(); i
++)
1652 selection
[i
] = line
[i
];
1656 if (lineNum
== selStartY
)
1658 // int xx = selStartX*m_charWidth;
1659 int xx
= PosToPixel( lineNum
, selStartX
);
1660 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1662 for (size_t i
= (size_t)selStartX
; i
< line
.Len(); i
++)
1664 selection
[i
] = line
[i
];
1668 if (lineNum
== selEndY
)
1670 // int ww = selEndX*m_charWidth;
1671 int ww
= PosToPixel( lineNum
, selEndX
);
1672 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1674 for (size_t i
= 0; i
< (size_t)selEndX
; i
++)
1676 selection
[i
] = line
[i
];
1681 DrawLinePart( dc
, x
, y
, line
, line2
, *wxBLACK
);
1682 DrawLinePart( dc
, x
, y
, selection
, line2
, *wxWHITE
);
1683 DrawLinePart( dc
, x
, y
, keyword
, line2
, m_keywordColour
);
1684 DrawLinePart( dc
, x
, y
, define
, line2
, m_defineColour
);
1685 DrawLinePart( dc
, x
, y
, variable
, line2
, m_variableColour
);
1686 DrawLinePart( dc
, x
, y
, comment
, line2
, m_commentColour
);
1687 DrawLinePart( dc
, x
, y
, my_string
, line2
, m_stringColour
);
1690 void wxTextCtrl::OnPaint( wxPaintEvent
&event
)
1694 if (m_lines
.GetCount() == 0) return;
1698 dc
.SetFont( m_sourceFont
);
1701 GetViewStart( NULL
, &scroll_y
);
1703 // We have a inner border of two pixels
1704 // around the text, so scroll units do
1705 // not correspond to lines.
1706 if (scroll_y
> 0) scroll_y
--;
1710 GetClientSize( &size_x
, &size_y
);
1712 dc
.SetPen( *wxTRANSPARENT_PEN
);
1713 dc
.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT
), wxSOLID
) );
1714 int upper
= wxMin( (int)m_lines
.GetCount(), scroll_y
+(size_y
/m_lineHeight
)+2 );
1715 for (int i
= scroll_y
; i
< upper
; i
++)
1718 int y
= i
*m_lineHeight
+2;
1720 int h
= m_lineHeight
;
1721 CalcScrolledPosition( x
,y
,&x
,&y
);
1722 if (IsExposed(x
,y
,w
,h
))
1723 DrawLine( dc
, 0+2, i
*m_lineHeight
+2, m_lines
[i
].m_text
, i
);
1726 if (m_editable
&& (FindFocus() == this))
1728 ///dc.SetBrush( *wxRED_BRUSH );
1729 dc
.SetBrush( *wxBLACK_BRUSH
);
1730 // int xx = m_cursorX*m_charWidth;
1731 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
1732 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
1736 void wxTextCtrl::OnMouse( wxMouseEvent
&event
)
1738 if (m_lines
.GetCount() == 0) return;
1741 #if 0 // there is no middle button on iPAQs
1742 if (event
.MiddleDown())
1749 if (event
.LeftDClick())
1755 if (event
.LeftDown())
1763 m_capturing
= FALSE
;
1767 if (event
.LeftDown() ||
1768 (event
.LeftIsDown() && m_capturing
))
1770 int x
= event
.GetX();
1771 int y
= event
.GetY();
1772 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1774 // x /= m_charWidth;
1775 x
= PixelToPos( y
, x
);
1777 wxMin( 1000, wxMax( 0, x
) ),
1778 wxMin( (int)m_lines
.GetCount()-1, wxMax( 0, y
) ),
1779 event
.ShiftDown() || !event
.LeftDown() );
1783 void wxTextCtrl::OnChar( wxKeyEvent
&event
)
1785 if (m_lines
.GetCount() == 0) return;
1787 if (!m_editable
) return;
1791 GetClientSize( &size_x
, &size_y
);
1792 size_x
/= m_charWidth
;
1793 size_y
/= m_lineHeight
;
1796 if (event
.ShiftDown())
1798 switch (event
.GetKeyCode())
1800 case '4': event
.m_keyCode
= WXK_LEFT
; break;
1801 case '8': event
.m_keyCode
= WXK_UP
; break;
1802 case '6': event
.m_keyCode
= WXK_RIGHT
; break;
1803 case '2': event
.m_keyCode
= WXK_DOWN
; break;
1804 case '9': event
.m_keyCode
= WXK_PRIOR
; break;
1805 case '3': event
.m_keyCode
= WXK_NEXT
; break;
1806 case '7': event
.m_keyCode
= WXK_HOME
; break;
1807 case '1': event
.m_keyCode
= WXK_END
; break;
1808 case '0': event
.m_keyCode
= WXK_INSERT
; break;
1812 switch (event
.GetKeyCode())
1816 if (m_ignoreInput
) return;
1818 MoveCursor( m_cursorX
, m_cursorY
-1, event
.ShiftDown() );
1819 m_ignoreInput
= TRUE
;
1824 if (m_ignoreInput
) return;
1825 if (m_cursorY
< (int)(m_lines
.GetCount()-1))
1826 MoveCursor( m_cursorX
, m_cursorY
+1, event
.ShiftDown() );
1827 m_ignoreInput
= TRUE
;
1832 if (m_ignoreInput
) return;
1835 MoveCursor( m_cursorX
-1, m_cursorY
, event
.ShiftDown() );
1840 MoveCursor( m_lines
[m_cursorY
-1].m_text
.Len(), m_cursorY
-1, event
.ShiftDown() );
1842 m_ignoreInput
= TRUE
;
1847 if (m_ignoreInput
) return;
1848 if (m_cursorX
< 1000)
1849 MoveCursor( m_cursorX
+1, m_cursorY
, event
.ShiftDown() );
1850 m_ignoreInput
= TRUE
;
1855 if (event
.ControlDown())
1856 MoveCursor( 0, 0, event
.ShiftDown() );
1858 MoveCursor( 0, m_cursorY
, event
.ShiftDown() );
1863 if (event
.ControlDown())
1864 MoveCursor( 0, m_lines
.GetCount()-1, event
.ShiftDown() );
1866 MoveCursor( m_lines
[m_cursorY
].m_text
.Len(), m_cursorY
, event
.ShiftDown() );
1871 if (m_ignoreInput
) return;
1872 MoveCursor( m_cursorX
, wxMin( (int)(m_lines
.GetCount()-1), m_cursorY
+size_y
), event
.ShiftDown() );
1873 m_ignoreInput
= TRUE
;
1878 if (m_ignoreInput
) return;
1879 MoveCursor( m_cursorX
, wxMax( 0, m_cursorY
-size_y
), event
.ShiftDown() );
1880 m_ignoreInput
= TRUE
;
1885 if (event
.ShiftDown())
1887 else if (event
.ControlDown())
1890 m_overwrite
= !m_overwrite
;
1895 if (m_windowStyle
& wxPROCESS_ENTER
)
1897 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
1898 event
.SetEventObject(this);
1899 event
.SetString(GetValue());
1900 if (GetEventHandler()->ProcessEvent(event
)) return;
1918 bool save_overwrite
= m_overwrite
;
1919 m_overwrite
= FALSE
;
1920 int i
= 4-(m_cursorX
% 4);
1922 for (int c
= 0; c
< i
; c
++)
1924 m_overwrite
= save_overwrite
;
1945 if ( (event
.GetKeyCode() >= 'a') &&
1946 (event
.GetKeyCode() <= 'z') &&
1954 if ( (event
.GetKeyCode() >= 32) &&
1955 (event
.GetKeyCode() <= 255) &&
1956 !(event
.ControlDown() && !event
.AltDown()) ) // filters out Ctrl-X but leaves Alt-Gr
1960 DoChar( (char) event
.GetKeyCode() );
1969 void wxTextCtrl::OnInternalIdle()
1971 wxControl::OnInternalIdle();
1973 m_ignoreInput
= FALSE
;
1975 if (m_lang
!= wxSOURCE_LANG_NONE
)
1976 SearchForBrackets();
1979 void wxTextCtrl::Indent()
1981 int startY
= m_cursorY
;
1982 int endY
= m_cursorY
;
1985 startY
= m_selStartY
;
1995 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1997 for (int i
= startY
; i
<= endY
; i
++)
1999 m_lines
[i
].m_text
.insert( 0u, wxT(" ") );
2004 void wxTextCtrl::Unindent()
2006 int startY
= m_cursorY
;
2007 int endY
= m_cursorY
;
2010 startY
= m_selStartY
;
2020 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
2022 for (int i
= startY
; i
<= endY
; i
++)
2024 for (int n
= 0; n
< 4; n
++)
2026 if (m_lines
[i
].m_text
[0u] == wxT(' '))
2027 m_lines
[i
].m_text
.erase(0u,1u);
2032 bool wxTextCtrl::HasSelection()
2034 return ((m_selStartY
!= m_selEndY
) || (m_selStartX
!= m_selEndX
));
2037 void wxTextCtrl::ClearSelection()
2045 void wxTextCtrl::RefreshLine( int n
)
2047 int y
= n
*m_lineHeight
;
2049 CalcScrolledPosition( x
, y
, &x
, &y
);
2050 wxRect
rect( 0+2, y
+2, 10000, m_lineHeight
);
2051 Refresh( TRUE
, &rect
);
2054 void wxTextCtrl::RefreshDown( int n
)
2058 GetClientSize( &size_x
, &size_y
);
2062 GetViewStart( &view_x
, &view_y
);
2070 int y
= n
*m_lineHeight
;
2072 CalcScrolledPosition( x
, y
, &x
, &y
);
2074 wxRect
rect( 0+2, y
+2, 10000, size_y
);
2075 Refresh( TRUE
, &rect
);
2079 void wxTextCtrl::MoveCursor( int new_x
, int new_y
, bool shift
, bool centre
)
2081 if (!m_editable
) return;
2083 // if (IsSingleLine() || (m_lang == wxSOURCE_LANG_NONE))
2085 if (new_x
> (int) (m_lines
[new_y
].m_text
.Len()))
2086 new_x
= m_lines
[new_y
].m_text
.Len();
2089 if ((new_x
== m_cursorX
) && (new_y
== m_cursorY
)) return;
2091 bool no_cursor_refresh
= FALSE
;
2092 bool has_selection
= HasSelection();
2097 bool erase_background
= TRUE
;
2101 m_selStartX
= m_cursorX
;
2102 m_selStartY
= m_cursorY
;
2106 if (new_y
> m_selStartY
)
2108 y
= m_selStartY
*m_lineHeight
;
2109 h
= (new_y
-m_selStartY
+1)*m_lineHeight
;
2111 else if (new_y
== m_selStartY
)
2113 x
= PosToPixel( new_y
, m_selStartX
);
2114 w
= PosToPixel( new_y
, new_x
) - x
;
2118 w
= -w
+ 2; // +2 for the cursor
2120 y
= m_selStartY
*m_lineHeight
;
2125 y
= new_y
*m_lineHeight
;
2126 h
= (-new_y
+m_selStartY
+1)*m_lineHeight
;
2129 no_cursor_refresh
= TRUE
;
2135 if (new_y
== m_selEndY
)
2137 y
= new_y
*m_lineHeight
;
2139 if (m_selEndX
> new_x
)
2141 // x = new_x*m_charWidth;
2142 x
= PosToPixel( new_y
, new_x
);
2143 // w = (m_selEndX-new_x)*m_charWidth;
2144 w
= PosToPixel( new_y
, m_selEndX
) - x
;
2148 // x = m_selEndX*m_charWidth;
2149 x
= PosToPixel( new_y
, m_selEndX
);
2150 // w = (-m_selEndX+new_x)*m_charWidth;
2151 w
= PosToPixel( new_y
, new_x
) - x
;
2158 if (new_y
> m_selEndY
)
2160 y
= m_selEndY
*m_lineHeight
;
2161 h
= (new_y
-m_selEndY
+1) * m_lineHeight
;
2163 erase_background
= ((m_selEndY
< m_selStartY
) ||
2164 ((m_selEndY
== m_selStartY
) && (m_selEndX
< m_selStartX
)));
2168 y
= new_y
*m_lineHeight
;
2169 h
= (-new_y
+m_selEndY
+1) * m_lineHeight
;
2171 erase_background
= ((m_selEndY
> m_selStartY
) ||
2172 ((m_selEndY
== m_selStartY
) && (m_selEndX
> m_selStartX
)));
2174 no_cursor_refresh
= TRUE
;
2183 CalcScrolledPosition( x
, y
, &x
, &y
);
2184 wxRect
rect( x
+2, y
+2, w
, h
);
2185 Refresh( erase_background
, &rect
);
2191 int ry1
= m_selEndY
;
2192 int ry2
= m_selStartY
;
2206 int y
= ry1
*m_lineHeight
;
2207 CalcScrolledPosition( x
, y
, &x
, &y
);
2208 wxRect
rect( 0, y
+2, 10000, (ry2
-ry1
+1)*m_lineHeight
);
2210 Refresh( TRUE
, &rect
);
2215 printf( "startx %d starty %d endx %d endy %d\n",
2216 m_selStartX, m_selStartY, m_selEndX, m_selEndY );
2218 printf( "has %d\n", (int)HasSelection() );
2221 if (!no_cursor_refresh
)
2223 // int x = m_cursorX*m_charWidth;
2224 int x
= PosToPixel( m_cursorY
, m_cursorX
);
2225 int y
= m_cursorY
*m_lineHeight
;
2226 CalcScrolledPosition( x
, y
, &x
, &y
);
2227 wxRect
rect( x
+2, y
+2, 4, m_lineHeight
+2 );
2232 Refresh( TRUE
, &rect
);
2234 if (FindFocus() == this)
2236 wxClientDC
dc(this);
2238 dc
.SetPen( *wxTRANSPARENT_PEN
);
2239 //dc.SetBrush( *wxRED_BRUSH );
2240 dc
.SetBrush( *wxBLACK_BRUSH
);
2241 // int xx = m_cursorX*m_charWidth;
2242 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
2243 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
2249 GetClientSize( &size_x
, &size_y
);
2250 size_x
/= m_charWidth
;
2251 size_y
/= m_lineHeight
;
2255 GetViewStart( &view_x
, &view_y
);
2259 int sy
= m_cursorY
- (size_y
/2);
2265 if (m_cursorY
< view_y
)
2266 Scroll( -1, m_cursorY
);
2267 else if (m_cursorY
> view_y
+size_y
-1)
2268 Scroll( -1, m_cursorY
-size_y
+1 );
2271 //int xx = m_cursorX;
2272 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
2276 else if (xx
> view_x
+size_x
-1)
2277 Scroll( xx
-size_x
+1, -1 );
2280 void wxTextCtrl::MyAdjustScrollbars()
2285 int y_range
= m_lines
.GetCount();
2288 GetClientSize( NULL
, &height
);
2290 if (height
>= (int)m_lines
.GetCount() *m_lineHeight
)
2295 GetViewStart( &view_x
, &view_y
);
2297 SetScrollbars( m_charWidth
, m_lineHeight
, m_longestLine
+2, y_range
, view_x
, view_y
);
2300 //-----------------------------------------------------------------------------
2301 // clipboard handlers
2302 //-----------------------------------------------------------------------------
2304 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
2309 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
2314 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
2319 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
2324 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
2329 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2331 event
.Enable( CanCut() );
2334 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2336 event
.Enable( CanCopy() );
2339 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2341 event
.Enable( CanPaste() );
2344 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2346 event
.Enable( CanUndo() );
2349 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2351 event
.Enable( CanRedo() );
2354 wxSize
wxTextCtrl::DoGetBestSize() const
2358 wxSize
ret(80, m_lineHeight
+ 4);
2360 if (HasFlag(wxBORDER_SUNKEN
) || HasFlag(wxBORDER_RAISED
))
2363 if (HasFlag(wxBORDER_SIMPLE
))
2370 return wxSize(80, 60);
2374 // ----------------------------------------------------------------------------
2376 // ----------------------------------------------------------------------------
2378 void wxTextCtrl::Freeze()
2382 void wxTextCtrl::Thaw()
2386 void wxTextCtrl::OnSetFocus( wxFocusEvent
& event
)
2388 // To hide or show caret, as appropriate
2392 void wxTextCtrl::OnKillFocus( wxFocusEvent
& event
)
2394 // To hide or show caret, as appropriate
2398 // ----------------------------------------------------------------------------
2399 // text control scrolling
2400 // ----------------------------------------------------------------------------
2402 bool wxTextCtrl::ScrollLines(int lines
)
2404 wxFAIL_MSG( "wxTextCtrl::ScrollLines not implemented");
2409 bool wxTextCtrl::ScrollPages(int pages
)
2411 wxFAIL_MSG( "wxTextCtrl::ScrollPages not implemented");