1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "textctrl.h"
14 #include "wx/textctrl.h"
18 #include "wx/settings.h"
20 #include "wx/clipbrd.h"
21 #include "wx/tokenzr.h"
23 #include "wx/univ/inphand.h"
24 #include "wx/univ/renderer.h"
25 #include "wx/univ/colschem.h"
26 #include "wx/univ/theme.h"
28 //-----------------------------------------------------------------------------
30 //-----------------------------------------------------------------------------
32 wxSourceUndoStep::wxSourceUndoStep( wxSourceUndo type
, int y1
, int y2
, wxTextCtrl
*owner
)
39 m_cursorX
= m_owner
->GetCursorX();
40 m_cursorY
= m_owner
->GetCursorY();
42 if (m_type
== wxSOURCE_UNDO_LINE
)
44 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
46 if (m_type
== wxSOURCE_UNDO_ENTER
)
48 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
50 if (m_type
== wxSOURCE_UNDO_BACK
)
52 for (int i
= m_y1
; i
< m_y2
+2; i
++)
54 if (i
>= (int)m_owner
->m_lines
.GetCount())
57 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
60 if (m_type
== wxSOURCE_UNDO_DELETE
)
62 for (int i
= m_y1
; i
< m_y2
+1; i
++)
64 m_lines
.Add( m_owner
->m_lines
[i
].m_text
);
67 if (m_type
== wxSOURCE_UNDO_PASTE
)
69 m_text
= m_owner
->m_lines
[m_y1
].m_text
;
73 void wxSourceUndoStep::Undo()
75 if (m_type
== wxSOURCE_UNDO_LINE
)
77 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
78 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
79 m_owner
->RefreshLine( m_y1
);
81 if (m_type
== wxSOURCE_UNDO_ENTER
)
83 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
84 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
85 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
86 m_owner
->RefreshDown( m_y1
);
88 if (m_type
== wxSOURCE_UNDO_BACK
)
90 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
91 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[1] ), m_y1
+1 );
92 m_owner
->MyAdjustScrollbars();
93 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
94 m_owner
->RefreshDown( m_y1
);
96 if (m_type
== wxSOURCE_UNDO_DELETE
)
98 m_owner
->m_lines
[m_y1
].m_text
= m_lines
[0];
99 for (int i
= 1; i
< (int)m_lines
.GetCount(); i
++)
100 m_owner
->m_lines
.Insert( new wxSourceLine( m_lines
[i
] ), m_y1
+i
);
101 m_owner
->MyAdjustScrollbars();
102 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
103 m_owner
->RefreshDown( m_y1
);
105 if (m_type
== wxSOURCE_UNDO_PASTE
)
107 m_owner
->m_lines
[m_y1
].m_text
= m_text
;
108 for (int i
= 0; i
< m_y2
-m_y1
; i
++)
109 m_owner
->m_lines
.RemoveAt( m_y1
+1 );
110 m_owner
->MyAdjustScrollbars();
111 m_owner
->MoveCursor( m_cursorX
, m_cursorY
);
112 m_owner
->RefreshDown( m_y1
);
114 if (m_type
== wxSOURCE_UNDO_INSERT_LINE
)
116 m_owner
->m_lines
.RemoveAt( m_y1
);
117 m_owner
->MyAdjustScrollbars();
118 m_owner
->MoveCursor( 0, m_y1
);
119 m_owner
->RefreshDown( m_y1
);
123 #include "wx/arrimpl.cpp"
124 WX_DEFINE_OBJARRAY(wxSourceLineArray
);
126 //-----------------------------------------------------------------------------
128 //-----------------------------------------------------------------------------
130 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
,wxControl
)
132 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
133 EVT_PAINT(wxTextCtrl::OnPaint
)
134 EVT_CHAR(wxTextCtrl::OnChar
)
135 EVT_MOUSE_EVENTS(wxTextCtrl::OnMouse
)
136 EVT_IDLE(wxTextCtrl::OnIdle
)
138 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
139 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
140 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
141 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
142 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
144 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
145 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
146 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
147 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
148 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
151 void wxTextCtrl::Init()
156 m_undos
.DeleteContents( TRUE
);
158 m_lang
= wxSOURCE_LANG_NONE
;
171 m_ignoreInput
= FALSE
;
175 m_keywordColour
= wxColour( 10, 140, 10 );
177 m_defineColour
= *wxRED
;
179 m_variableColour
= wxColour( 50, 120, 150 );
181 m_commentColour
= wxColour( 130, 130, 130 );
183 m_stringColour
= wxColour( 10, 140, 10 );
186 wxTextCtrl::wxTextCtrl( wxWindow
*parent
,
188 const wxString
&value
,
192 const wxValidator
& validator
,
193 const wxString
&name
)
194 : wxScrollHelper(this)
198 Create( parent
, id
, value
, pos
, size
, style
, validator
, name
);
201 bool wxTextCtrl::Create( wxWindow
*parent
,
203 const wxString
&value
,
207 const wxValidator
& validator
,
208 const wxString
&name
)
210 if ((style
& wxBORDER_MASK
) == 0)
211 style
|= wxBORDER_SUNKEN
;
213 if ((style
& wxTE_MULTILINE
) != 0)
214 style
|= wxALWAYS_SHOW_SB
;
216 wxTextCtrlBase::Create( parent
, id
, wxDefaultPosition
, size
,
217 style
|wxVSCROLL
|wxHSCROLL
|wxNO_FULL_REPAINT_ON_RESIZE
);
219 SetBackgroundColour( *wxWHITE
);
221 SetCursor( wxCursor( wxCURSOR_IBEAM
) );
223 if (HasFlag(wxTE_PASSWORD
))
224 m_sourceFont
= wxFont( 12, wxMODERN
, wxNORMAL
, wxNORMAL
);
226 m_sourceFont
= GetFont();
229 dc
.SetFont( m_sourceFont
);
230 m_lineHeight
= dc
.GetCharHeight();
231 m_charWidth
= dc
.GetCharWidth();
235 wxSize
size_best( DoGetBestSize() );
236 wxSize
new_size( size
);
237 if (new_size
.x
== -1)
238 new_size
.x
= size_best
.x
;
239 if (new_size
.y
== -1)
240 new_size
.y
= size_best
.y
;
241 if ((new_size
.x
!= size
.x
) || (new_size
.y
!= size
.y
))
242 SetSize( new_size
.x
, new_size
.y
);
244 // We create an input handler since it might be useful
245 CreateInputHandler(wxINP_HANDLER_TEXTCTRL
);
250 //-----------------------------------------------------------------------------
252 //-----------------------------------------------------------------------------
254 wxString
wxTextCtrl::GetValue() const
257 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
259 ret
+= m_lines
[i
].m_text
;
260 if (i
< m_lines
.GetCount())
267 void wxTextCtrl::SetValue(const wxString
& value
)
278 m_lines
.Add( new wxSourceLine( wxT("") ) );
286 pos
= value
.find( wxT('\n'), begin
);
289 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, value
.Len()-begin
) );
292 // if (sl->m_text.Len() > m_longestLine)
293 // m_longestLine = sl->m_text.Len();
295 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
297 if (ww
> m_longestLine
)
304 wxSourceLine
*sl
= new wxSourceLine( value
.Mid( begin
, pos
-begin
) );
307 // if (sl->m_text.Len() > m_longestLine)
308 // m_longestLine = sl->m_text.Len();
310 GetTextExtent( sl
->m_text
, &ww
, NULL
, NULL
, NULL
);
312 if (ww
> m_longestLine
)
320 MyAdjustScrollbars();
325 int wxTextCtrl::GetLineLength(long lineNo
) const
327 if (lineNo
>= (long)m_lines
.GetCount())
330 return m_lines
[lineNo
].m_text
.Len();
333 wxString
wxTextCtrl::GetLineText(long lineNo
) const
335 if (lineNo
>= (long)m_lines
.GetCount())
338 return m_lines
[lineNo
].m_text
;
341 int wxTextCtrl::GetNumberOfLines() const
343 return m_lines
.GetCount();
346 bool wxTextCtrl::IsModified() const
351 bool wxTextCtrl::IsEditable() const
356 void wxTextCtrl::GetSelection(long* from
, long* to
) const
360 void wxTextCtrl::Clear()
368 m_lines
.Add( new wxSourceLine( wxT("") ) );
370 SetScrollbars( m_charWidth
, m_lineHeight
, 0, 0, 0, 0 );
375 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
379 void wxTextCtrl::Remove(long from
, long to
)
384 void wxTextCtrl::DiscardEdits()
390 void wxTextCtrl::SetMaxLength(unsigned long len
)
394 int wxTextCtrl::PosToPixel( int line
, int pos
)
396 // TODO add support for Tabs
398 if (line
>= m_lines
.GetCount()) return 0;
400 wxString text
= m_lines
[line
].m_text
;
402 if (text
.IsEmpty()) return 0;
404 if (pos
< text
.Len())
405 text
.Remove( pos
, text
.Len()-pos
);
409 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
414 int wxTextCtrl::PixelToPos( int line
, int pixel
)
416 if (pixel
< 2) return 0;
418 if (line
>= m_lines
.GetCount()) return 0;
420 wxString text
= m_lines
[line
].m_text
;
423 int res
= text
.Len();
426 GetTextExtent( text
, &w
, NULL
, NULL
, NULL
);
432 text
.Remove( res
,1 );
438 void wxTextCtrl::WriteText(const wxString
& text2
)
440 if (text2
.IsEmpty()) return;
444 wxString
text( text2
);
447 while ( (pos
= text
.Find('\n')) != -1 )
449 lines
.Add( text
.Left( pos
) );
450 text
.Remove( 0, pos
+1 );
453 int count
= (int)lines
.GetCount();
455 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
456 wxString
tmp2( tmp1
);
457 int len
= (int)tmp1
.Len();
462 for (int i
= 0; i
< m_cursorX
-len
; i
++)
464 m_lines
[m_cursorY
].m_text
.Append( tmp
);
469 tmp1
.Remove( m_cursorX
);
470 tmp2
.Remove( 0, m_cursorX
);
471 tmp1
.Append( lines
[0] );
475 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
478 m_lines
[m_cursorY
].m_text
= tmp1
;
479 RefreshLine( m_cursorY
);
483 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
485 m_lines
[m_cursorY
].m_text
= tmp1
;
487 for (i
= 1; i
< count
; i
++)
488 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
489 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
491 MyAdjustScrollbars();
492 RefreshDown( m_cursorY
);
496 void wxTextCtrl::AppendText(const wxString
& text2
)
498 if (text2
.IsEmpty()) return;
502 wxString
text( text2
);
505 while ( (pos
= text
.Find('\n')) != -1 )
507 lines
.Add( text
.Left( pos
) );
508 text
.Remove( 0, pos
+1 );
511 int count
= (int)lines
.GetCount();
513 size_t y
= m_lines
.GetCount()-1;
515 wxString
tmp( m_lines
[y
].m_text
);
516 tmp
.Append( lines
[0] );
520 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, y
, y
, this ) );
522 m_lines
[y
].m_text
= tmp
;
527 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, y
, y
+count
-1, this ) );
529 m_lines
[y
].m_text
= tmp
;
531 for (i
= 1; i
< count
; i
++)
532 m_lines
.Insert( new wxSourceLine( lines
[i
] ), y
+i
);
534 MyAdjustScrollbars();
539 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
544 long wxTextCtrl::XYToPosition(long x
, long y
) const
548 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
552 ret
+= m_lines
[i
].m_text
.Len();
556 if ((size_t)x
< m_lines
[i
].m_text
.Len())
559 return (ret
+ m_lines
[i
].m_text
.Len());
565 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
567 if (m_lines
.GetCount() == 0)
578 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
580 pos
-= m_lines
[i
].m_text
.Len();
592 xx
= m_lines
[ m_lines
.GetCount()-1 ].m_text
.Len();
599 void wxTextCtrl::ShowPosition(long pos
)
603 void wxTextCtrl::Copy()
605 if (!HasSelection()) return;
609 int selStartY
= m_selStartY
;
610 int selEndY
= m_selEndY
;
611 int selStartX
= m_selStartX
;
612 int selEndX
= m_selEndX
;
614 if ((selStartY
> selEndY
) ||
615 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
625 if (selStartY
== selEndY
)
627 sel
= m_lines
[selStartY
].m_text
;
629 if (selStartX
>= (int)sel
.Len()) return;
630 if (selEndX
> (int)sel
.Len())
633 sel
.Remove( selEndX
, sel
.Len()-selEndX
);
634 sel
.Remove( 0, selStartX
);
638 wxString
tmp( m_lines
[selStartY
].m_text
);
640 if (selStartX
< (int)tmp
.Len())
642 tmp
.Remove( 0, selStartX
);
646 for (int i
= selStartY
+1; i
< selEndY
; i
++)
648 sel
.Append( m_lines
[i
].m_text
);
651 tmp
= m_lines
[selEndY
].m_text
;
652 if (selEndX
> (int)tmp
.Len())
656 tmp
.Remove( selEndX
, tmp
.Len()-selEndX
);
661 if (wxTheClipboard
->Open())
663 wxTheClipboard
->SetData( new wxTextDataObject( sel
) );
664 wxTheClipboard
->Close();
668 void wxTextCtrl::Cut()
675 void wxTextCtrl::Paste()
679 if (!wxTheClipboard
->Open()) return;
681 if (!wxTheClipboard
->IsSupported( wxDF_TEXT
))
683 wxTheClipboard
->Close();
688 wxTextDataObject data
;
690 bool ret
= wxTheClipboard
->GetData( data
);
692 wxTheClipboard
->Close();
698 wxString
text( data
.GetText() );
701 while ( (pos
= text
.Find('\n')) != -1 )
703 lines
.Add( text
.Left( pos
) );
704 text
.Remove( 0, pos
+1 );
707 int count
= (int)lines
.GetCount();
709 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
710 wxString
tmp2( tmp1
);
711 int len
= (int)tmp1
.Len();
716 for (int i
= 0; i
< m_cursorX
-len
; i
++)
718 m_lines
[m_cursorY
].m_text
.Append( tmp
);
723 tmp1
.Remove( m_cursorX
);
724 tmp2
.Remove( 0, m_cursorX
);
725 tmp1
.Append( lines
[0] );
729 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
732 m_lines
[m_cursorY
].m_text
= tmp1
;
733 RefreshLine( m_cursorY
);
737 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
739 m_lines
[m_cursorY
].m_text
= tmp1
;
741 for (i
= 1; i
< count
; i
++)
742 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
743 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
745 MyAdjustScrollbars();
746 RefreshDown( m_cursorY
);
750 void wxTextCtrl::Undo()
752 if (m_undos
.GetCount() == 0) return;
754 wxNode
*node
= m_undos
.Nth( m_undos
.GetCount()-1 );
755 wxSourceUndoStep
*undo
= (wxSourceUndoStep
*) node
->Data();
764 void wxTextCtrl::SetInsertionPoint(long pos
)
768 void wxTextCtrl::SetInsertionPointEnd()
772 long wxTextCtrl::GetInsertionPoint() const
774 return XYToPosition( m_cursorX
, m_cursorY
);
777 long wxTextCtrl::GetLastPosition() const
779 size_t lineCount
= m_lines
.GetCount() - 1;
780 return XYToPosition( m_lines
[lineCount
].m_text
.Len()-1, lineCount
);
783 void wxTextCtrl::SetSelection(long from
, long to
)
787 void wxTextCtrl::SetEditable(bool editable
)
789 m_editable
= editable
;
792 bool wxTextCtrl::Enable( bool enable
)
797 bool wxTextCtrl::SetFont(const wxFont
& font
)
802 bool wxTextCtrl::SetForegroundColour(const wxColour
& colour
)
804 return wxWindow::SetForegroundColour( colour
);
807 bool wxTextCtrl::SetBackgroundColour(const wxColour
& colour
)
809 return wxWindow::SetBackgroundColour( colour
);
812 //-----------------------------------------------------------------------------
813 // private code and handlers
814 //-----------------------------------------------------------------------------
816 void wxTextCtrl::SearchForBrackets()
818 int oldBracketY
= m_bracketY
;
819 int oldBracketX
= m_bracketX
;
821 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()) return;
823 wxString current
= m_lines
[m_cursorY
].m_text
;
825 // reverse search first
830 bracket
= current
[m_cursorX
-1];
832 if (bracket
== ')' || bracket
== ']' || bracket
== '}')
834 char antibracket
= '(';
835 if (bracket
== ']') antibracket
= '[';
836 if (bracket
== '}') antibracket
= '{';
840 int endY
= m_cursorY
-60;
841 if (endY
< 0) endY
= 0;
842 for (int y
= m_cursorY
; y
>= endY
; y
--)
844 current
= m_lines
[y
].m_text
;
846 current
.erase(m_cursorX
-1,current
.Len()-m_cursorX
+1);
848 for (int n
= current
.Len()-1; n
>= 0; n
--)
851 if (current
[n
] == '\'')
853 for (int m
= n
-1; m
>= 0; m
--)
855 if (current
[m
] == '\'')
857 if (m
== 0 || current
[m
-1] != '\\')
866 if (current
[n
] == '\"')
868 for (int m
= n
-1; m
>= 0; m
--)
870 if (current
[m
] == '\"')
872 if (m
== 0 || current
[m
-1] != '\\')
880 if (current
[n
] == antibracket
)
887 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
888 RefreshLine( oldBracketY
);
889 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
890 RefreshLine( m_bracketY
);
894 else if (current
[n
] == bracket
)
905 if ((int)current
.Len() > m_cursorX
)
906 bracket
= current
[m_cursorX
];
907 if (bracket
== '(' || bracket
== '[' || bracket
== '{')
909 char antibracket
= ')';
910 if (bracket
== '[') antibracket
= ']';
911 if (bracket
== '{') antibracket
= '}';
915 int endY
= m_cursorY
+60;
916 if (endY
> (int)(m_lines
.GetCount()-1)) endY
= m_lines
.GetCount()-1;
917 for (int y
= m_cursorY
; y
<= endY
; y
++)
919 current
= m_lines
[y
].m_text
;
924 for (int n
= start
; n
< (int)current
.Len(); n
++)
927 if (current
[n
] == '\'')
929 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
931 if (current
[m
] == '\'')
933 if (m
== 0 || (current
[m
-1] != '\\') || (m
>= 2 && current
[m
-2] == '\\'))
942 if (current
[n
] == '\"')
944 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
946 if (current
[m
] == '\"')
948 if (m
== 0 || (current
[m
-1] != '\\') || (m
>= 2 && current
[m
-2] == '\\'))
956 if (current
[n
] == antibracket
)
963 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
964 RefreshLine( oldBracketY
);
965 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
966 RefreshLine( m_bracketY
);
970 else if (current
[n
] == bracket
)
978 if (oldBracketY
!= -1)
981 RefreshLine( oldBracketY
);
985 void wxTextCtrl::Delete()
987 if (!HasSelection()) return;
991 int selStartY
= m_selStartY
;
992 int selEndY
= m_selEndY
;
993 int selStartX
= m_selStartX
;
994 int selEndX
= m_selEndX
;
996 if ((selStartY
> selEndY
) ||
997 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1000 selStartX
= selEndX
;
1003 selStartY
= selEndY
;
1007 int len
= (int)m_lines
[selStartY
].m_text
.Len();
1009 if (selStartY
== selEndY
)
1011 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, selStartY
, selStartY
, this ) );
1013 wxString
tmp( m_lines
[selStartY
].m_text
);
1014 if (selStartX
< len
)
1018 tmp
.Remove( selStartX
, selEndX
-selStartX
);
1019 m_lines
[selStartY
].m_text
= tmp
;
1022 m_cursorX
= selStartX
;
1023 RefreshLine( selStartY
);
1027 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, selStartY
, selEndY
, this ) );
1029 if (selStartX
< len
)
1030 m_lines
[selStartY
].m_text
.Remove( selStartX
);
1032 for (int i
= 0; i
< selEndY
-selStartY
-1; i
++)
1033 m_lines
.RemoveAt( selStartY
+1 );
1035 if (selEndX
< (int)m_lines
[selStartY
+1].m_text
.Len())
1036 m_lines
[selStartY
+1].m_text
.Remove( 0, selEndX
);
1038 m_lines
[selStartY
+1].m_text
.Remove( 0 );
1040 m_lines
[selStartY
].m_text
.Append( m_lines
[selStartY
+1].m_text
);
1041 m_lines
.RemoveAt( selStartY
+1 );
1044 MoveCursor( selStartX
, selStartY
);
1045 MyAdjustScrollbars();
1047 RefreshDown( selStartY
);
1051 void wxTextCtrl::DeleteLine()
1053 if (HasSelection()) return;
1055 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()-1) return; // TODO
1057 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1059 m_lines
.RemoveAt( m_cursorY
);
1061 if (m_cursorY
>= (int)m_lines
.GetCount()) m_cursorY
--;
1063 MyAdjustScrollbars();
1064 RefreshDown( m_cursorY
);
1067 void wxTextCtrl::DoChar( char c
)
1071 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1073 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1075 if (m_cursorX
>= (int)tmp
.Len())
1077 int len
= tmp
.Len();
1078 for (int i
= 0; i
< m_cursorX
- len
; i
++)
1085 tmp
.SetChar( m_cursorX
, c
);
1087 tmp
.insert( m_cursorX
, 1, c
);
1090 m_lines
[m_cursorY
].m_text
= tmp
;
1092 // if (tmp.Len() > m_longestLine)
1094 // m_longestLine = tmp.Len();
1095 // MyAdjustScrollbars();
1099 GetTextExtent( tmp
, &ww
, NULL
, NULL
, NULL
);
1101 if (ww
> m_longestLine
)
1104 MyAdjustScrollbars();
1109 int y
= m_cursorY
*m_lineHeight
;
1110 // int x = (m_cursorX-1)*m_charWidth;
1111 int x
= PosToPixel( m_cursorY
, m_cursorX
-1 );
1112 CalcScrolledPosition( x
, y
, &x
, &y
);
1113 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1114 Refresh( TRUE
, &rect
);
1118 GetClientSize( &size_x
, &size_y
);
1119 size_x
/= m_charWidth
;
1123 GetViewStart( &view_x
, &view_y
);
1125 //int xx = m_cursorX;
1126 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
1130 else if (xx
> view_x
+size_x
-1)
1131 Scroll( xx
-size_x
+1, -1 );
1134 void wxTextCtrl::DoBack()
1140 if (m_cursorY
== 0) return;
1142 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_BACK
, m_cursorY
-1, m_cursorY
, this ) );
1144 wxString
tmp1( m_lines
[m_cursorY
-1].m_text
);
1146 wxString
tmp2( m_lines
[m_cursorY
].m_text
);
1148 m_cursorX
= tmp1
.Len();
1150 tmp1
.Append( tmp2
);
1151 m_lines
[m_cursorY
].m_text
= tmp1
;
1152 m_lines
.RemoveAt( m_cursorY
+1 );
1154 MyAdjustScrollbars();
1155 RefreshDown( m_cursorY
-1 );
1159 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1161 if (m_cursorX
<= (int)m_lines
[m_cursorY
].m_text
.Len())
1162 m_lines
[m_cursorY
].m_text
.Remove( m_cursorX
-1, 1 );
1165 int y
= m_cursorY
*m_lineHeight
;
1166 // int x = m_cursorX*m_charWidth;
1167 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1168 CalcScrolledPosition( x
, y
, &x
, &y
);
1169 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1170 Refresh( TRUE
, &rect
);
1174 void wxTextCtrl::DoDelete()
1178 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1180 int len
= (int)tmp
.Len();
1181 if (m_cursorX
>= len
)
1183 if (m_cursorY
== (int)m_lines
.GetCount()-1) return;
1185 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1187 for (int i
= 0; i
< (m_cursorX
-len
); i
++)
1190 tmp
+= m_lines
[m_cursorY
+1].m_text
;
1192 m_lines
[m_cursorY
] = tmp
;
1193 m_lines
.RemoveAt( m_cursorY
+1 );
1195 MyAdjustScrollbars();
1196 RefreshDown( m_cursorY
);
1200 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1202 tmp
.Remove( m_cursorX
, 1 );
1203 m_lines
[m_cursorY
].m_text
= tmp
;
1205 int y
= m_cursorY
*m_lineHeight
;
1206 // int x = m_cursorX*m_charWidth;
1207 int x
= PosToPixel( m_cursorY
, m_cursorX
);
1208 CalcScrolledPosition( x
, y
, &x
, &y
);
1209 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1210 Refresh( TRUE
, &rect
);
1214 void wxTextCtrl::DoReturn()
1218 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_ENTER
, m_cursorY
, m_cursorY
, this ) );
1220 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1221 size_t indent
= tmp
.find_first_not_of( ' ' );
1222 if (indent
== wxSTRING_MAXLEN
) indent
= 0;
1224 if (m_cursorX
>= (int)tmp
.Len())
1226 int cursorX
= indent
;
1227 int cursorY
= m_cursorY
+ 1;
1230 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1231 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1233 MyAdjustScrollbars();
1234 MoveCursor( cursorX
, cursorY
);
1235 RefreshDown( m_cursorY
);
1239 wxString
tmp1( tmp
);
1240 tmp1
.Remove( m_cursorX
, tmp
.Len()-m_cursorX
);
1241 m_lines
[m_cursorY
].m_text
= tmp1
;
1243 wxString
tmp2( tmp
);
1244 tmp2
.Remove( 0, m_cursorX
);
1246 int cursorX
= indent
;
1247 int cursorY
= m_cursorY
+ 1;
1250 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1251 new_tmp
.Append( tmp2
);
1252 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1254 MyAdjustScrollbars();
1255 MoveCursor( cursorX
, cursorY
);
1256 RefreshDown( m_cursorY
-1 );
1260 void wxTextCtrl::DoDClick()
1262 wxString
line( m_lines
[ m_cursorY
].m_text
);
1263 if (m_cursorX
>= (int)line
.Len()) return;
1266 if (((ch
>= 'a') && (ch
<= 'z')) ||
1267 ((ch
>= 'A') && (ch
<= 'Z')) ||
1268 ((ch
>= '0') && (ch
<= '9')) ||
1271 m_selStartY
= m_cursorY
;
1272 m_selEndY
= m_cursorY
;
1276 while (((ch
>= 'a') && (ch
<= 'z')) ||
1277 ((ch
>= 'A') && (ch
<= 'Z')) ||
1278 ((ch
>= '0') && (ch
<= '9')) ||
1289 if (p
< (int)line
.Len())
1292 while (((ch
>= 'a') && (ch
<= 'z')) ||
1293 ((ch
>= 'A') && (ch
<= 'Z')) ||
1294 ((ch
>= '0') && (ch
<= '9')) ||
1297 if (p
>= (int)line
.Len()) break;
1303 RefreshLine( m_cursorY
);
1307 wxString
wxTextCtrl::GetNextToken( wxString
&line
, int &pos
)
1310 int len
= (int)line
.Len();
1311 for (int p
= pos
; p
< len
; p
++)
1313 if ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
))
1317 for (int q
= p
; q
< len
; q
++)
1318 ret
.Append( line
[q
] );
1325 if ((line
[p
] == '/') && (p
+1 < len
) && (line
[p
+1] == '/'))
1327 for (int q
= p
; q
< len
; q
++)
1328 ret
.Append( line
[q
] );
1336 ret
.Append( line
[p
] );
1337 for (int q
= p
+1; q
< len
; q
++)
1339 ret
.Append( line
[q
] );
1340 if ((line
[q
] == '"') && ((line
[q
-1] != '\\') || (q
>= 2 && line
[q
-2] == '\\')))
1347 if (line
[p
] == '\'')
1349 ret
.Append( line
[p
] );
1350 for (int q
= p
+1; q
< len
; q
++)
1352 ret
.Append( line
[q
] );
1353 if ((line
[q
] == '\'') && ((line
[q
-1] != '\\') || (q
>= 2 && line
[q
-2] == '\\')))
1360 if (((line
[p
] >= 'a') && (line
[p
] <= 'z')) ||
1361 ((line
[p
] >= 'A') && (line
[p
] <= 'Z')) ||
1365 ret
.Append( line
[p
] );
1366 for (int q
= p
+1; q
< len
; q
++)
1368 if (((line
[q
] >= 'a') && (line
[q
] <= 'z')) ||
1369 ((line
[q
] >= 'A') && (line
[q
] <= 'Z')) ||
1370 ((line
[q
] >= '0') && (line
[q
] <= '9')) ||
1373 ret
.Append( line
[q
] );
1390 void wxTextCtrl::DrawLine( wxDC
&dc
, int x
, int y
, const wxString
&line2
, int lineNum
)
1392 int selStartY
= m_selStartY
;
1393 int selEndY
= m_selEndY
;
1394 int selStartX
= m_selStartX
;
1395 int selEndX
= m_selEndX
;
1397 if ((selStartY
> selEndY
) ||
1398 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1400 int tmp
= selStartX
;
1401 selStartX
= selEndX
;
1404 selStartY
= selEndY
;
1408 wxString
line( line2
);
1409 if (HasFlag(wxTE_PASSWORD
))
1411 size_t len
= line
.Len();
1412 line
= wxString( wxT('*'), len
);
1415 wxString
keyword( ' ', line
.Len() );
1416 wxString
define( ' ', line
.Len() );
1417 wxString
variable( ' ', line
.Len() );
1418 wxString
comment( ' ', line
.Len() );
1419 wxString
my_string( ' ', line
.Len() );
1421 if (m_lang
!= wxSOURCE_LANG_NONE
)
1423 if (lineNum
== m_bracketY
)
1425 wxString
red( ' ', line
.Len() );
1426 if (m_bracketX
< (int)line
.Len())
1428 red
.SetChar( m_bracketX
, line
[m_bracketX
] );
1429 line
.SetChar( m_bracketX
, ' ' );
1430 dc
.SetTextForeground( *wxRED
);
1431 dc
.DrawText( red
, x
, y
);
1432 dc
.SetTextForeground( *wxBLACK
);
1437 wxString
token( GetNextToken( line
, pos
) );
1438 while (!token
.IsNull())
1440 if (m_keywords
.Index( token
) != wxNOT_FOUND
)
1442 int end_pos
= pos
+ (int)token
.Len();
1443 for (int i
= pos
; i
< end_pos
; i
++)
1445 keyword
.SetChar( i
, line
[i
] );
1446 line
.SetChar( i
, ' ' );
1449 if (m_defines
.Index( token
) != wxNOT_FOUND
)
1451 int end_pos
= pos
+ (int)token
.Len();
1452 for (int i
= pos
; i
< end_pos
; i
++)
1454 define
.SetChar( i
, line
[i
] );
1455 line
.SetChar( i
, ' ' );
1458 if ((m_variables
.Index( token
) != wxNOT_FOUND
) ||
1459 ((token
.Len() > 2) && (token
[0] == 'w') && (token
[1] == 'x')))
1461 int end_pos
= pos
+ (int)token
.Len();
1462 for (int i
= pos
; i
< end_pos
; i
++)
1464 variable
.SetChar( i
, line
[i
] );
1465 line
.SetChar( i
, ' ' );
1468 if ((token
.Len() >= 2) && (token
[0] == '/') && (token
[1] == '/') && (m_lang
== wxSOURCE_LANG_CPP
))
1470 int end_pos
= pos
+ (int)token
.Len();
1471 for (int i
= pos
; i
< end_pos
; i
++)
1473 comment
.SetChar( i
, line
[i
] );
1474 line
.SetChar( i
, ' ' );
1477 if ((token
[0] == '#') &&
1478 ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
)))
1480 int end_pos
= pos
+ (int)token
.Len();
1481 for (int i
= pos
; i
< end_pos
; i
++)
1483 comment
.SetChar( i
, line
[i
] );
1484 line
.SetChar( i
, ' ' );
1488 if ((token
[0] == '"') || (token
[0] == '\''))
1490 int end_pos
= pos
+ (int)token
.Len();
1491 for (int i
= pos
; i
< end_pos
; i
++)
1493 my_string
.SetChar( i
, line
[i
] );
1494 line
.SetChar( i
, ' ' );
1498 token
= GetNextToken( line
, pos
);
1502 if ((lineNum
< selStartY
) || (lineNum
> selEndY
))
1504 dc
.DrawText( line
, x
, y
);
1505 if (m_lang
!= wxSOURCE_LANG_NONE
)
1507 dc
.SetTextForeground( m_keywordColour
);
1508 dc
.DrawText( keyword
, x
, y
);
1509 dc
.SetTextForeground( m_defineColour
);
1510 dc
.DrawText( define
, x
, y
);
1511 dc
.SetTextForeground( m_variableColour
);
1512 dc
.DrawText( variable
, x
, y
);
1513 dc
.SetTextForeground( m_commentColour
);
1514 dc
.DrawText( comment
, x
, y
);
1515 dc
.SetTextForeground( m_stringColour
);
1516 dc
.DrawText( my_string
, x
, y
);
1517 dc
.SetTextForeground( *wxBLACK
);
1522 if (selStartY
== selEndY
)
1524 // int xx = selStartX*m_charWidth;
1525 int xx
= PosToPixel( lineNum
, selStartX
);
1526 // int ww = (selEndX-selStartX)*m_charWidth;
1527 int ww
= PosToPixel( lineNum
, selEndX
) - xx
;
1528 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1530 if (m_lang
!= wxSOURCE_LANG_NONE
)
1533 wxString
tmp1( line
);
1534 wxString
tmp2( line
);
1536 for (i
= selStartX
; i
< selEndX
; i
++)
1537 if ((int)tmp1
.Len() > i
)
1538 tmp1
.SetChar( i
, ' ' );
1539 dc
.DrawText( tmp1
, x
, y
);
1540 for (i
= 0; i
< selStartX
; i
++)
1541 if ((int)tmp2
.Len() > i
)
1542 tmp2
.SetChar( i
, ' ' );
1543 for (i
= selEndX
; i
< (int)tmp2
.Len(); i
++)
1544 if ((int)tmp2
.Len() > i
)
1545 tmp2
.SetChar( i
, ' ' );
1546 dc
.SetTextForeground( *wxWHITE
);
1547 dc
.DrawText( tmp2
, x
, y
);
1548 dc
.SetTextForeground( *wxBLACK
);
1551 if ((lineNum
> selStartY
) && (lineNum
< selEndY
))
1553 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1554 if (m_lang
!= wxSOURCE_LANG_NONE
)
1556 dc
.SetTextForeground( *wxWHITE
);
1557 dc
.DrawText( line
, x
, y
);
1558 dc
.SetTextForeground( *wxBLACK
);
1561 if (lineNum
== selStartY
)
1563 // int xx = selStartX*m_charWidth;
1564 int xx
= PosToPixel( lineNum
, selStartX
);
1565 dc
.DrawRectangle( xx
+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1567 if (m_lang
!= wxSOURCE_LANG_NONE
)
1570 wxString
tmp1( line
);
1571 wxString
tmp2( line
);
1572 for (i
= selStartX
; i
< (int)tmp1
.Len(); i
++)
1573 tmp1
.SetChar( i
, ' ' );
1574 dc
.DrawText( tmp1
, x
, y
);
1575 for (i
= 0; i
< selStartX
; i
++)
1576 if ((int)tmp2
.Len() > i
)
1577 tmp2
.SetChar( i
, ' ' );
1578 dc
.SetTextForeground( *wxWHITE
);
1579 dc
.DrawText( tmp2
, x
, y
);
1580 dc
.SetTextForeground( *wxBLACK
);
1583 if (lineNum
== selEndY
)
1585 // int ww = selEndX*m_charWidth;
1586 int ww
= PosToPixel( lineNum
, selEndX
);
1587 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, ww
, m_lineHeight
);
1589 if (m_lang
!= wxSOURCE_LANG_NONE
)
1592 wxString
tmp1( line
);
1593 wxString
tmp2( line
);
1594 for (i
= 0; i
< selEndX
; i
++)
1595 if ((int)tmp1
.Len() > i
)
1596 tmp1
.SetChar( i
, ' ' );
1597 dc
.DrawText( tmp1
, x
, y
);
1598 for (i
= selEndX
; i
< (int)tmp2
.Len(); i
++)
1599 tmp2
.SetChar( i
, ' ' );
1600 dc
.SetTextForeground( *wxWHITE
);
1601 dc
.DrawText( tmp2
, x
, y
);
1602 dc
.SetTextForeground( *wxBLACK
);
1606 if (m_lang
== wxSOURCE_LANG_NONE
)
1608 dc
.DrawText( line
, x
, y
);
1612 dc
.SetTextForeground( m_keywordColour
);
1613 dc
.DrawText( keyword
, x
, y
);
1614 dc
.SetTextForeground( m_defineColour
);
1615 dc
.DrawText( define
, x
, y
);
1616 dc
.SetTextForeground( m_variableColour
);
1617 dc
.DrawText( variable
, x
, y
);
1618 dc
.SetTextForeground( m_commentColour
);
1619 dc
.DrawText( comment
, x
, y
);
1620 dc
.SetTextForeground( m_stringColour
);
1621 dc
.DrawText( my_string
, x
, y
);
1622 dc
.SetTextForeground( *wxBLACK
);
1626 void wxTextCtrl::OnPaint( wxPaintEvent
&event
)
1630 if (m_lines
.GetCount() == 0) return;
1634 dc
.SetFont( m_sourceFont
);
1637 GetViewStart( NULL
, &scroll_y
);
1641 GetClientSize( &size_x
, &size_y
);
1643 dc
.SetPen( *wxTRANSPARENT_PEN
);
1644 dc
.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT
), wxSOLID
) );
1645 int upper
= wxMin( (int)m_lines
.GetCount(), scroll_y
+(size_y
/m_lineHeight
)+1 );
1646 for (int i
= scroll_y
; i
< upper
; i
++)
1649 int y
= i
*m_lineHeight
+2;
1651 int h
= m_lineHeight
;
1652 CalcScrolledPosition( x
,y
,&x
,&y
);
1653 if (IsExposed(x
,y
,w
,h
))
1654 DrawLine( dc
, 0+2, i
*m_lineHeight
+2, m_lines
[i
].m_text
, i
);
1657 dc
.SetBrush( *wxRED_BRUSH
);
1658 // int xx = m_cursorX*m_charWidth;
1659 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
1660 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
1663 void wxTextCtrl::OnMouse( wxMouseEvent
&event
)
1665 if (m_lines
.GetCount() == 0) return;
1668 #if 0 // there is no middle button on iPAQs
1669 if (event
.MiddleDown())
1676 if (event
.LeftDClick())
1682 if (event
.LeftDown())
1690 m_capturing
= FALSE
;
1694 if (event
.LeftDown() ||
1695 (event
.LeftIsDown() && m_capturing
))
1697 int x
= event
.GetX();
1698 int y
= event
.GetY();
1699 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1701 // x /= m_charWidth;
1702 x
= PixelToPos( y
, x
);
1704 wxMin( 1000, wxMax( 0, x
) ),
1705 wxMin( (int)m_lines
.GetCount()-1, wxMax( 0, y
) ),
1706 event
.ShiftDown() || !event
.LeftDown() );
1710 void wxTextCtrl::OnChar( wxKeyEvent
&event
)
1712 if (m_lines
.GetCount() == 0) return;
1716 GetClientSize( &size_x
, &size_y
);
1717 size_x
/= m_charWidth
;
1718 size_y
/= m_lineHeight
;
1721 if (event
.ShiftDown())
1723 switch (event
.GetKeyCode())
1725 case '4': event
.m_keyCode
= WXK_LEFT
; break;
1726 case '8': event
.m_keyCode
= WXK_UP
; break;
1727 case '6': event
.m_keyCode
= WXK_RIGHT
; break;
1728 case '2': event
.m_keyCode
= WXK_DOWN
; break;
1729 case '9': event
.m_keyCode
= WXK_PRIOR
; break;
1730 case '3': event
.m_keyCode
= WXK_NEXT
; break;
1731 case '7': event
.m_keyCode
= WXK_HOME
; break;
1732 case '1': event
.m_keyCode
= WXK_END
; break;
1733 case '0': event
.m_keyCode
= WXK_INSERT
; break;
1737 switch (event
.GetKeyCode())
1741 if (m_ignoreInput
) return;
1743 MoveCursor( m_cursorX
, m_cursorY
-1, event
.ShiftDown() );
1744 m_ignoreInput
= TRUE
;
1749 if (m_ignoreInput
) return;
1750 if (m_cursorY
< (int)(m_lines
.GetCount()-1))
1751 MoveCursor( m_cursorX
, m_cursorY
+1, event
.ShiftDown() );
1752 m_ignoreInput
= TRUE
;
1757 if (m_ignoreInput
) return;
1760 MoveCursor( m_cursorX
-1, m_cursorY
, event
.ShiftDown() );
1765 MoveCursor( m_lines
[m_cursorY
-1].m_text
.Len(), m_cursorY
-1, event
.ShiftDown() );
1767 m_ignoreInput
= TRUE
;
1772 if (m_ignoreInput
) return;
1773 if (m_cursorX
< 1000)
1774 MoveCursor( m_cursorX
+1, m_cursorY
, event
.ShiftDown() );
1775 m_ignoreInput
= TRUE
;
1780 if (event
.ControlDown())
1781 MoveCursor( 0, 0, event
.ShiftDown() );
1783 MoveCursor( 0, m_cursorY
, event
.ShiftDown() );
1788 if (event
.ControlDown())
1789 MoveCursor( 0, m_lines
.GetCount()-1, event
.ShiftDown() );
1791 MoveCursor( m_lines
[m_cursorY
].m_text
.Len(), m_cursorY
, event
.ShiftDown() );
1796 if (m_ignoreInput
) return;
1797 MoveCursor( m_cursorX
, wxMin( (int)(m_lines
.GetCount()-1), m_cursorY
+size_y
), event
.ShiftDown() );
1798 m_ignoreInput
= TRUE
;
1803 if (m_ignoreInput
) return;
1804 MoveCursor( m_cursorX
, wxMax( 0, m_cursorY
-size_y
), event
.ShiftDown() );
1805 m_ignoreInput
= TRUE
;
1810 if (event
.ShiftDown())
1812 else if (event
.ControlDown())
1815 m_overwrite
= !m_overwrite
;
1835 bool save_overwrite
= m_overwrite
;
1836 m_overwrite
= FALSE
;
1837 int i
= 4-(m_cursorX
% 4);
1839 for (int c
= 0; c
< i
; c
++)
1841 m_overwrite
= save_overwrite
;
1862 if ( (event
.KeyCode() >= 'a') &&
1863 (event
.KeyCode() <= 'z') &&
1871 if ( (event
.KeyCode() >= 32) &&
1872 (event
.KeyCode() <= 255) &&
1873 !(event
.ControlDown() && !event
.AltDown()) ) // filters out Ctrl-X but leaves Alt-Gr
1877 DoChar( (char) event
.KeyCode() );
1886 void wxTextCtrl::OnIdle( wxIdleEvent
&event
)
1888 m_ignoreInput
= FALSE
;
1890 if (m_lang
!= wxSOURCE_LANG_NONE
)
1891 SearchForBrackets();
1896 void wxTextCtrl::Indent()
1898 int startY
= m_cursorY
;
1899 int endY
= m_cursorY
;
1902 startY
= m_selStartY
;
1912 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1914 for (int i
= startY
; i
<= endY
; i
++)
1916 m_lines
[i
].m_text
.insert( 0u, " " );
1921 void wxTextCtrl::Unindent()
1923 int startY
= m_cursorY
;
1924 int endY
= m_cursorY
;
1927 startY
= m_selStartY
;
1937 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1939 for (int i
= startY
; i
<= endY
; i
++)
1941 for (int n
= 0; n
< 4; n
++)
1943 if (m_lines
[i
].m_text
[0u] == ' ')
1944 m_lines
[i
].m_text
.erase(0u,1u);
1949 bool wxTextCtrl::HasSelection()
1951 return ((m_selStartY
!= m_selEndY
) || (m_selStartX
!= m_selEndX
));
1954 void wxTextCtrl::ClearSelection()
1962 void wxTextCtrl::RefreshLine( int n
)
1964 int y
= n
*m_lineHeight
;
1966 CalcScrolledPosition( x
, y
, &x
, &y
);
1967 wxRect
rect( 0+2, y
+2, 10000, m_lineHeight
);
1968 Refresh( TRUE
, &rect
);
1971 void wxTextCtrl::RefreshDown( int n
)
1975 GetClientSize( &size_x
, &size_y
);
1979 GetViewStart( &view_x
, &view_y
);
1987 int y
= n
*m_lineHeight
;
1989 CalcScrolledPosition( x
, y
, &x
, &y
);
1991 wxRect
rect( 0+2, y
+2, 10000, size_y
);
1992 Refresh( TRUE
, &rect
);
1996 void wxTextCtrl::MoveCursor( int new_x
, int new_y
, bool shift
, bool centre
)
1998 // if (IsSingleLine())
2000 if (new_x
> m_lines
[new_y
].m_text
.Len())
2001 new_x
= m_lines
[new_y
].m_text
.Len();
2004 if ((new_x
== m_cursorX
) && (new_y
== m_cursorY
)) return;
2006 bool no_cursor_refresh
= FALSE
;
2012 if (!HasSelection())
2014 m_selStartX
= m_cursorX
;
2015 m_selStartY
= m_cursorY
;
2019 if (new_y
> m_selStartY
)
2021 y
= m_selStartY
*m_lineHeight
;
2022 h
= (new_y
-m_selStartY
+1)*m_lineHeight
;
2024 else if (new_y
== m_selStartY
)
2026 y
= m_selStartY
*m_lineHeight
;
2031 y
= new_y
*m_lineHeight
;
2032 h
= (-new_y
+m_selStartY
+1)*m_lineHeight
;
2035 no_cursor_refresh
= TRUE
;
2041 if (new_y
== m_selEndY
)
2043 y
= new_y
*m_lineHeight
;
2045 if (m_selEndX
> new_x
)
2047 // x = new_x*m_charWidth;
2048 x
= PosToPixel( new_y
, new_x
);
2049 // w = (m_selEndX-new_x)*m_charWidth;
2050 w
= PosToPixel( new_y
, m_selEndX
) - x
;
2054 // x = m_selEndX*m_charWidth;
2055 x
= PosToPixel( new_y
, m_selEndX
);
2056 // w = (-m_selEndX+new_x)*m_charWidth;
2057 w
= PosToPixel( new_y
, new_x
) - x
;
2064 if (new_y
> m_selEndY
)
2066 y
= m_selEndY
*m_lineHeight
;
2067 h
= (new_y
-m_selEndY
+1) * m_lineHeight
;
2071 y
= new_y
*m_lineHeight
;
2072 h
= (-new_y
+m_selEndY
+1) * m_lineHeight
;
2074 no_cursor_refresh
= TRUE
;
2083 CalcScrolledPosition( x
, y
, &x
, &y
);
2084 wxRect
rect( x
+2, y
+2, w
, h
);
2085 Refresh( TRUE
, &rect
);
2091 int ry1
= m_selEndY
;
2092 int ry2
= m_selStartY
;
2106 int y
= ry1
*m_lineHeight
;
2107 CalcScrolledPosition( x
, y
, &x
, &y
);
2108 wxRect
rect( 0, y
+2, 10000, (ry2
-ry1
+1)*m_lineHeight
);
2110 Refresh( TRUE
, &rect
);
2115 printf( "startx %d starty %d endx %d endy %d\n",
2116 m_selStartX, m_selStartY, m_selEndX, m_selEndY );
2118 printf( "has %d\n", (int)HasSelection() );
2121 if (!no_cursor_refresh
)
2123 // int x = m_cursorX*m_charWidth;
2124 int x
= PosToPixel( m_cursorY
, m_cursorX
);
2125 int y
= m_cursorY
*m_lineHeight
;
2126 CalcScrolledPosition( x
, y
, &x
, &y
);
2127 wxRect
rect( x
+2, y
+2, 4, m_lineHeight
+2 );
2132 Refresh( TRUE
, &rect
);
2134 wxClientDC
dc(this);
2136 dc
.SetPen( *wxTRANSPARENT_PEN
);
2137 dc
.SetBrush( *wxRED_BRUSH
);
2138 // int xx = m_cursorX*m_charWidth;
2139 int xx
= PosToPixel( m_cursorY
, m_cursorX
);
2140 dc
.DrawRectangle( xx
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
2145 GetClientSize( &size_x
, &size_y
);
2146 size_x
/= m_charWidth
;
2147 size_y
/= m_lineHeight
;
2151 GetViewStart( &view_x
, &view_y
);
2155 int sy
= m_cursorY
- (size_y
/2);
2161 if (m_cursorY
< view_y
)
2162 Scroll( -1, m_cursorY
);
2163 else if (m_cursorY
> view_y
+size_y
-1)
2164 Scroll( -1, m_cursorY
-size_y
+1 );
2167 //int xx = m_cursorX;
2168 int xx
= PosToPixel( m_cursorY
, m_cursorX
) / m_charWidth
;
2172 else if (xx
> view_x
+size_x
-1)
2173 Scroll( xx
-size_x
+1, -1 );
2176 void wxTextCtrl::MyAdjustScrollbars()
2181 int y_range
= m_lines
.GetCount();
2184 GetClientSize( NULL
, &height
);
2186 if (height
>= m_lines
.GetCount() *m_lineHeight
)
2191 GetViewStart( &view_x
, &view_y
);
2193 SetScrollbars( m_charWidth
, m_lineHeight
, m_longestLine
+2, y_range
, view_x
, view_y
);
2196 //-----------------------------------------------------------------------------
2197 // clipboard handlers
2198 //-----------------------------------------------------------------------------
2200 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
2205 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
2210 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
2215 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
2220 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
2225 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2227 event
.Enable( CanCut() );
2230 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2232 event
.Enable( CanCopy() );
2235 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2237 event
.Enable( CanPaste() );
2240 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2242 event
.Enable( CanUndo() );
2245 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2247 event
.Enable( CanRedo() );
2250 wxSize
wxTextCtrl::DoGetBestSize() const
2254 wxSize
ret(80, m_lineHeight
+ 4);
2256 if (HasFlag(wxBORDER_SUNKEN
) || HasFlag(wxBORDER_RAISED
))
2259 if (HasFlag(wxBORDER_SIMPLE
))
2266 return wxSize(80, 60);
2270 // ----------------------------------------------------------------------------
2272 // ----------------------------------------------------------------------------
2274 void wxTextCtrl::Freeze()
2278 void wxTextCtrl::Thaw()
2282 // ----------------------------------------------------------------------------
2283 // text control scrolling
2284 // ----------------------------------------------------------------------------
2286 bool wxTextCtrl::ScrollLines(int lines
)
2288 wxFAIL_MSG( "wxTextCtrl::ScrollLines not implemented");
2293 bool wxTextCtrl::ScrollPages(int pages
)
2295 wxFAIL_MSG( "wxTextCtrl::ScrollPages not implemented");