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_sourceFont
= wxFont( 12, wxMODERN
, wxNORMAL
, wxNORMAL
);
158 m_undos
.DeleteContents( TRUE
);
160 m_lang
= wxSOURCE_LANG_NONE
;
165 dc
.SetFont( m_sourceFont
);
166 m_lineHeight
= dc
.GetCharHeight();
167 m_charWidth
= dc
.GetCharWidth();
178 m_ignoreInput
= FALSE
;
182 m_keywordColour
= wxColour( 10, 140, 10 );
184 m_defineColour
= *wxRED
;
186 m_variableColour
= wxColour( 50, 120, 150 );
188 m_commentColour
= wxColour( 130, 130, 130 );
190 m_stringColour
= wxColour( 10, 140, 10 );
193 wxTextCtrl::wxTextCtrl( wxWindow
*parent
,
195 const wxString
&value
,
199 const wxValidator
& validator
,
200 const wxString
&name
)
201 : wxScrollHelper(this)
205 Create( parent
, id
, value
, pos
, size
, style
, validator
, name
);
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
, wxDefaultPosition
, size
,
224 style
|wxVSCROLL
|wxHSCROLL
|wxNO_FULL_REPAINT_ON_RESIZE
);
226 SetBackgroundColour( *wxWHITE
);
228 SetCursor( wxCursor( wxCURSOR_IBEAM
) );
232 wxSize
size_best( DoGetBestSize() );
233 wxSize
new_size( size
);
234 if (new_size
.x
== -1)
235 new_size
.x
= size_best
.x
;
236 if (new_size
.y
== -1)
237 new_size
.y
= size_best
.y
;
238 if ((new_size
.x
!= size
.x
) || (new_size
.y
!= size
.y
))
239 SetSize( new_size
.x
, new_size
.y
);
241 // We create an input handler since it might be useful
242 CreateInputHandler(wxINP_HANDLER_TEXTCTRL
);
247 //-----------------------------------------------------------------------------
249 //-----------------------------------------------------------------------------
251 wxString
wxTextCtrl::GetValue() const
254 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
256 ret
+= m_lines
[i
].m_text
;
257 if (i
< m_lines
.GetCount())
264 void wxTextCtrl::SetValue(const wxString
& value
)
276 // TODO make more efficient
277 wxString tmp
= value
;
278 tmp
.Remove( 0, pos
);
279 pos
= tmp
.Find( '\n' );
282 if (tmp
.Len() > m_longestLine
)
283 m_longestLine
= tmp
.Len();
285 m_lines
.Add( new wxSourceLine( tmp
) );
291 if (pos
> m_longestLine
)
294 tmp
.Remove( pos
, tmp
.Len()-pos
);
295 m_lines
.Add( new wxSourceLine( tmp
) );
299 MyAdjustScrollbars();
304 int wxTextCtrl::GetLineLength(long lineNo
) const
306 if (lineNo
>= (long)m_lines
.GetCount())
309 return m_lines
[lineNo
].m_text
.Len();
312 wxString
wxTextCtrl::GetLineText(long lineNo
) const
314 if (lineNo
>= (long)m_lines
.GetCount())
317 return m_lines
[lineNo
].m_text
;
320 int wxTextCtrl::GetNumberOfLines() const
322 return m_lines
.GetCount();
325 bool wxTextCtrl::IsModified() const
330 bool wxTextCtrl::IsEditable() const
335 void wxTextCtrl::GetSelection(long* from
, long* to
) const
339 void wxTextCtrl::Clear()
346 SetScrollbars( m_charWidth
, m_lineHeight
, 0, 0, 0, 0 );
351 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
355 void wxTextCtrl::Remove(long from
, long to
)
360 void wxTextCtrl::DiscardEdits()
366 void wxTextCtrl::SetMaxLength(unsigned long len
)
370 void wxTextCtrl::WriteText(const wxString
& text2
)
374 wxString
text( text2
);
377 while ( (pos
= text
.Find('\n')) != -1 )
379 lines
.Add( text
.Left( pos
) );
380 text
.Remove( 0, pos
+1 );
383 int count
= (int)lines
.GetCount();
385 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
386 wxString
tmp2( tmp1
);
387 int len
= (int)tmp1
.Len();
392 for (int i
= 0; i
< m_cursorX
-len
; i
++)
394 m_lines
[m_cursorY
].m_text
.Append( tmp
);
399 tmp1
.Remove( m_cursorX
);
400 tmp2
.Remove( 0, m_cursorX
);
401 tmp1
.Append( lines
[0] );
405 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
408 m_lines
[m_cursorY
].m_text
= tmp1
;
409 RefreshLine( m_cursorY
);
413 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
415 m_lines
[m_cursorY
].m_text
= tmp1
;
417 for (i
= 1; i
< count
; i
++)
418 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
419 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
421 MyAdjustScrollbars();
422 RefreshDown( m_cursorY
);
426 void wxTextCtrl::AppendText(const wxString
& text
)
428 // Leaves cursor garbage
430 m_cursorY
= m_lines
.GetCount()-1;
431 m_cursorX
= m_lines
[m_cursorY
].m_text
.Len();
438 bool wxTextCtrl::SetStyle(long start
, long end
, const wxTextAttr
& style
)
443 long wxTextCtrl::XYToPosition(long x
, long y
) const
447 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
451 ret
+= m_lines
[i
].m_text
.Len();
455 if ((size_t)x
< m_lines
[i
].m_text
.Len())
458 return (ret
+ m_lines
[i
].m_text
.Len());
464 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
466 if (m_lines
.GetCount() == 0)
477 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
479 pos
-= m_lines
[i
].m_text
.Len();
491 xx
= m_lines
[ m_lines
.GetCount()-1 ].m_text
.Len();
498 void wxTextCtrl::ShowPosition(long pos
)
502 void wxTextCtrl::Copy()
504 if (!HasSelection()) return;
508 int selStartY
= m_selStartY
;
509 int selEndY
= m_selEndY
;
510 int selStartX
= m_selStartX
;
511 int selEndX
= m_selEndX
;
513 if ((selStartY
> selEndY
) ||
514 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
524 if (selStartY
== selEndY
)
526 sel
= m_lines
[selStartY
].m_text
;
528 if (selStartX
>= (int)sel
.Len()) return;
529 if (selEndX
> (int)sel
.Len())
532 sel
.Remove( selEndX
, sel
.Len()-selEndX
);
533 sel
.Remove( 0, selStartX
);
537 wxString
tmp( m_lines
[selStartY
].m_text
);
539 if (selStartX
< (int)tmp
.Len())
541 tmp
.Remove( 0, selStartX
);
545 for (int i
= selStartY
+1; i
< selEndY
; i
++)
547 sel
.Append( m_lines
[i
].m_text
);
550 tmp
= m_lines
[selEndY
].m_text
;
551 if (selEndX
> (int)tmp
.Len())
555 tmp
.Remove( selEndX
, tmp
.Len()-selEndX
);
560 if (wxTheClipboard
->Open())
562 wxTheClipboard
->SetData( new wxTextDataObject( sel
) );
563 wxTheClipboard
->Close();
567 void wxTextCtrl::Cut()
574 void wxTextCtrl::Paste()
578 if (!wxTheClipboard
->Open()) return;
580 if (!wxTheClipboard
->IsSupported( wxDF_TEXT
))
582 wxTheClipboard
->Close();
587 wxTextDataObject data
;
589 bool ret
= wxTheClipboard
->GetData( data
);
591 wxTheClipboard
->Close();
597 wxString
text( data
.GetText() );
600 while ( (pos
= text
.Find('\n')) != -1 )
602 lines
.Add( text
.Left( pos
) );
603 text
.Remove( 0, pos
+1 );
606 int count
= (int)lines
.GetCount();
608 wxString
tmp1( m_lines
[m_cursorY
].m_text
);
609 wxString
tmp2( tmp1
);
610 int len
= (int)tmp1
.Len();
615 for (int i
= 0; i
< m_cursorX
-len
; i
++)
617 m_lines
[m_cursorY
].m_text
.Append( tmp
);
622 tmp1
.Remove( m_cursorX
);
623 tmp2
.Remove( 0, m_cursorX
);
624 tmp1
.Append( lines
[0] );
628 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
631 m_lines
[m_cursorY
].m_text
= tmp1
;
632 RefreshLine( m_cursorY
);
636 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_PASTE
, m_cursorY
, m_cursorY
+count
-1, this ) );
638 m_lines
[m_cursorY
].m_text
= tmp1
;
640 for (i
= 1; i
< count
; i
++)
641 m_lines
.Insert( new wxSourceLine( lines
[i
] ), m_cursorY
+i
);
642 m_lines
[m_cursorY
+i
-1].m_text
.Append( tmp2
);
644 MyAdjustScrollbars();
645 RefreshDown( m_cursorY
);
649 void wxTextCtrl::Undo()
651 if (m_undos
.GetCount() == 0) return;
653 wxNode
*node
= m_undos
.Nth( m_undos
.GetCount()-1 );
654 wxSourceUndoStep
*undo
= (wxSourceUndoStep
*) node
->Data();
663 void wxTextCtrl::SetInsertionPoint(long pos
)
667 void wxTextCtrl::SetInsertionPointEnd()
671 long wxTextCtrl::GetInsertionPoint() const
673 return XYToPosition( m_cursorX
, m_cursorY
);
676 long wxTextCtrl::GetLastPosition() const
678 size_t lineCount
= m_lines
.GetCount() - 1;
679 return XYToPosition( m_lines
[lineCount
].m_text
.Len()-1, lineCount
);
682 void wxTextCtrl::SetSelection(long from
, long to
)
686 void wxTextCtrl::SetEditable(bool editable
)
688 m_editable
= editable
;
691 bool wxTextCtrl::Enable( bool enable
)
696 bool wxTextCtrl::SetFont(const wxFont
& font
)
701 bool wxTextCtrl::SetForegroundColour(const wxColour
& colour
)
703 return wxWindow::SetForegroundColour( colour
);
706 bool wxTextCtrl::SetBackgroundColour(const wxColour
& colour
)
708 return wxWindow::SetBackgroundColour( colour
);
711 //-----------------------------------------------------------------------------
712 // private code and handlers
713 //-----------------------------------------------------------------------------
715 void wxTextCtrl::SearchForBrackets()
717 int oldBracketY
= m_bracketY
;
718 int oldBracketX
= m_bracketX
;
720 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()) return;
722 wxString current
= m_lines
[m_cursorY
].m_text
;
724 // reverse search first
729 bracket
= current
[m_cursorX
-1];
731 if (bracket
== ')' || bracket
== ']' || bracket
== '}')
733 char antibracket
= '(';
734 if (bracket
== ']') antibracket
= '[';
735 if (bracket
== '}') antibracket
= '{';
739 int endY
= m_cursorY
-60;
740 if (endY
< 0) endY
= 0;
741 for (int y
= m_cursorY
; y
>= endY
; y
--)
743 current
= m_lines
[y
].m_text
;
745 current
.erase(m_cursorX
-1,current
.Len()-m_cursorX
+1);
747 for (int n
= current
.Len()-1; n
>= 0; n
--)
750 if (current
[n
] == '\'')
752 for (int m
= n
-1; m
>= 0; m
--)
754 if (current
[m
] == '\'')
756 if (m
== 0 || current
[m
-1] != '\\')
765 if (current
[n
] == '\"')
767 for (int m
= n
-1; m
>= 0; m
--)
769 if (current
[m
] == '\"')
771 if (m
== 0 || current
[m
-1] != '\\')
779 if (current
[n
] == antibracket
)
786 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
787 RefreshLine( oldBracketY
);
788 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
789 RefreshLine( m_bracketY
);
793 else if (current
[n
] == bracket
)
804 if ((int)current
.Len() > m_cursorX
)
805 bracket
= current
[m_cursorX
];
806 if (bracket
== '(' || bracket
== '[' || bracket
== '{')
808 char antibracket
= ')';
809 if (bracket
== '[') antibracket
= ']';
810 if (bracket
== '{') antibracket
= '}';
814 int endY
= m_cursorY
+60;
815 if (endY
> (int)(m_lines
.GetCount()-1)) endY
= m_lines
.GetCount()-1;
816 for (int y
= m_cursorY
; y
<= endY
; y
++)
818 current
= m_lines
[y
].m_text
;
823 for (int n
= start
; n
< (int)current
.Len(); n
++)
826 if (current
[n
] == '\'')
828 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
830 if (current
[m
] == '\'')
832 if (m
== 0 || (current
[m
-1] != '\\') || (m
>= 2 && current
[m
-2] == '\\'))
841 if (current
[n
] == '\"')
843 for (int m
= n
+1; m
< (int)current
.Len(); m
++)
845 if (current
[m
] == '\"')
847 if (m
== 0 || (current
[m
-1] != '\\') || (m
>= 2 && current
[m
-2] == '\\'))
855 if (current
[n
] == antibracket
)
862 if (oldBracketY
!= m_bracketY
&& oldBracketY
!= -1)
863 RefreshLine( oldBracketY
);
864 if (m_bracketY
!= oldBracketY
|| m_bracketX
!= oldBracketX
)
865 RefreshLine( m_bracketY
);
869 else if (current
[n
] == bracket
)
877 if (oldBracketY
!= -1)
880 RefreshLine( oldBracketY
);
884 void wxTextCtrl::Delete()
886 if (!HasSelection()) return;
890 int selStartY
= m_selStartY
;
891 int selEndY
= m_selEndY
;
892 int selStartX
= m_selStartX
;
893 int selEndX
= m_selEndX
;
895 if ((selStartY
> selEndY
) ||
896 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
906 int len
= (int)m_lines
[selStartY
].m_text
.Len();
908 if (selStartY
== selEndY
)
910 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, selStartY
, selStartY
, this ) );
912 wxString
tmp( m_lines
[selStartY
].m_text
);
917 tmp
.Remove( selStartX
, selEndX
-selStartX
);
918 m_lines
[selStartY
].m_text
= tmp
;
921 m_cursorX
= selStartX
;
922 RefreshLine( selStartY
);
926 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, selStartY
, selEndY
, this ) );
929 m_lines
[selStartY
].m_text
.Remove( selStartX
);
931 for (int i
= 0; i
< selEndY
-selStartY
-1; i
++)
932 m_lines
.RemoveAt( selStartY
+1 );
934 if (selEndX
< (int)m_lines
[selStartY
+1].m_text
.Len())
935 m_lines
[selStartY
+1].m_text
.Remove( 0, selEndX
);
937 m_lines
[selStartY
+1].m_text
.Remove( 0 );
939 m_lines
[selStartY
].m_text
.Append( m_lines
[selStartY
+1].m_text
);
940 m_lines
.RemoveAt( selStartY
+1 );
943 MoveCursor( selStartX
, selStartY
);
944 MyAdjustScrollbars();
946 RefreshDown( selStartY
);
950 void wxTextCtrl::DeleteLine()
952 if (HasSelection()) return;
954 if (m_cursorY
< 0 || m_cursorY
>= (int)m_lines
.GetCount()-1) return; // TODO
956 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
958 m_lines
.RemoveAt( m_cursorY
);
960 if (m_cursorY
>= (int)m_lines
.GetCount()) m_cursorY
--;
962 MyAdjustScrollbars();
963 RefreshDown( m_cursorY
);
966 void wxTextCtrl::DoChar( char c
)
970 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
972 wxString
tmp( m_lines
[m_cursorY
].m_text
);
974 if (m_cursorX
>= (int)tmp
.Len())
977 for (int i
= 0; i
< m_cursorX
- len
; i
++)
984 tmp
.SetChar( m_cursorX
, c
);
986 tmp
.insert( m_cursorX
, 1, c
);
989 m_lines
[m_cursorY
].m_text
= tmp
;
991 if (tmp
.Len() > m_longestLine
)
993 m_longestLine
= tmp
.Len();
994 MyAdjustScrollbars();
999 int y
= m_cursorY
*m_lineHeight
;
1000 int x
= (m_cursorX
-1)*m_charWidth
;
1001 CalcScrolledPosition( x
, y
, &x
, &y
);
1002 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1003 Refresh( TRUE
, &rect
);
1007 GetClientSize( &size_x
, &size_y
);
1008 size_x
/= m_charWidth
;
1012 GetViewStart( &view_x
, &view_y
);
1014 if (m_cursorX
< view_x
)
1015 Scroll( m_cursorX
, -1 );
1016 else if (m_cursorX
> view_x
+size_x
-1)
1017 Scroll( m_cursorX
-size_x
+1, -1 );
1020 void wxTextCtrl::DoBack()
1026 if (m_cursorY
== 0) return;
1028 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_BACK
, m_cursorY
-1, m_cursorY
, this ) );
1030 wxString
tmp1( m_lines
[m_cursorY
-1].m_text
);
1032 wxString
tmp2( m_lines
[m_cursorY
].m_text
);
1034 m_cursorX
= tmp1
.Len();
1036 tmp1
.Append( tmp2
);
1037 m_lines
[m_cursorY
].m_text
= tmp1
;
1038 m_lines
.RemoveAt( m_cursorY
+1 );
1040 MyAdjustScrollbars();
1041 RefreshDown( m_cursorY
-1 );
1045 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1047 if (m_cursorX
<= (int)m_lines
[m_cursorY
].m_text
.Len())
1048 m_lines
[m_cursorY
].m_text
.Remove( m_cursorX
-1, 1 );
1051 int y
= m_cursorY
*m_lineHeight
;
1052 int x
= m_cursorX
*m_charWidth
;
1053 CalcScrolledPosition( x
, y
, &x
, &y
);
1054 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1055 Refresh( TRUE
, &rect
);
1059 void wxTextCtrl::DoDelete()
1063 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1065 int len
= (int)tmp
.Len();
1066 if (m_cursorX
>= len
)
1068 if (m_cursorY
== (int)m_lines
.GetCount()-1) return;
1070 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_DELETE
, m_cursorY
, m_cursorY
+1, this ) );
1072 for (int i
= 0; i
< (m_cursorX
-len
); i
++)
1075 tmp
+= m_lines
[m_cursorY
+1].m_text
;
1077 m_lines
[m_cursorY
] = tmp
;
1078 m_lines
.RemoveAt( m_cursorY
+1 );
1080 MyAdjustScrollbars();
1081 RefreshDown( m_cursorY
);
1085 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, m_cursorY
, m_cursorY
, this ) );
1087 tmp
.Remove( m_cursorX
, 1 );
1088 m_lines
[m_cursorY
].m_text
= tmp
;
1090 int y
= m_cursorY
*m_lineHeight
;
1091 int x
= m_cursorX
*m_charWidth
;
1092 CalcScrolledPosition( x
, y
, &x
, &y
);
1093 wxRect
rect( x
+2, y
+2, 10000, m_lineHeight
);
1094 Refresh( TRUE
, &rect
);
1098 void wxTextCtrl::DoReturn()
1102 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_ENTER
, m_cursorY
, m_cursorY
, this ) );
1104 wxString
tmp( m_lines
[m_cursorY
].m_text
);
1105 size_t indent
= tmp
.find_first_not_of( ' ' );
1106 if (indent
== wxSTRING_MAXLEN
) indent
= 0;
1108 if (m_cursorX
>= (int)tmp
.Len())
1110 int cursorX
= indent
;
1111 int cursorY
= m_cursorY
+ 1;
1114 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1115 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1117 MyAdjustScrollbars();
1118 MoveCursor( cursorX
, cursorY
);
1119 RefreshDown( m_cursorY
);
1123 wxString
tmp1( tmp
);
1124 tmp1
.Remove( m_cursorX
, tmp
.Len()-m_cursorX
);
1125 m_lines
[m_cursorY
].m_text
= tmp1
;
1127 wxString
tmp2( tmp
);
1128 tmp2
.Remove( 0, m_cursorX
);
1130 int cursorX
= indent
;
1131 int cursorY
= m_cursorY
+ 1;
1134 for (size_t i
= 0; i
< indent
; i
++) new_tmp
.Append( ' ' );
1135 new_tmp
.Append( tmp2
);
1136 m_lines
.Insert( new wxSourceLine( new_tmp
), cursorY
);
1138 MyAdjustScrollbars();
1139 MoveCursor( cursorX
, cursorY
);
1140 RefreshDown( m_cursorY
-1 );
1144 void wxTextCtrl::DoDClick()
1146 wxString
line( m_lines
[ m_cursorY
].m_text
);
1147 if (m_cursorX
>= (int)line
.Len()) return;
1150 if (((ch
>= 'a') && (ch
<= 'z')) ||
1151 ((ch
>= 'A') && (ch
<= 'Z')) ||
1152 ((ch
>= '0') && (ch
<= '9')) ||
1155 m_selStartY
= m_cursorY
;
1156 m_selEndY
= m_cursorY
;
1160 while (((ch
>= 'a') && (ch
<= 'z')) ||
1161 ((ch
>= 'A') && (ch
<= 'Z')) ||
1162 ((ch
>= '0') && (ch
<= '9')) ||
1173 if (p
< (int)line
.Len())
1176 while (((ch
>= 'a') && (ch
<= 'z')) ||
1177 ((ch
>= 'A') && (ch
<= 'Z')) ||
1178 ((ch
>= '0') && (ch
<= '9')) ||
1181 if (p
>= (int)line
.Len()) break;
1187 RefreshLine( m_cursorY
);
1191 wxString
wxTextCtrl::GetNextToken( wxString
&line
, int &pos
)
1194 int len
= (int)line
.Len();
1195 for (int p
= pos
; p
< len
; p
++)
1197 if ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
))
1201 for (int q
= p
; q
< len
; q
++)
1202 ret
.Append( line
[q
] );
1209 if ((line
[p
] == '/') && (p
+1 < len
) && (line
[p
+1] == '/'))
1211 for (int q
= p
; q
< len
; q
++)
1212 ret
.Append( line
[q
] );
1220 ret
.Append( line
[p
] );
1221 for (int q
= p
+1; q
< len
; q
++)
1223 ret
.Append( line
[q
] );
1224 if ((line
[q
] == '"') && ((line
[q
-1] != '\\') || (q
>= 2 && line
[q
-2] == '\\')))
1231 if (line
[p
] == '\'')
1233 ret
.Append( line
[p
] );
1234 for (int q
= p
+1; q
< len
; q
++)
1236 ret
.Append( line
[q
] );
1237 if ((line
[q
] == '\'') && ((line
[q
-1] != '\\') || (q
>= 2 && line
[q
-2] == '\\')))
1244 if (((line
[p
] >= 'a') && (line
[p
] <= 'z')) ||
1245 ((line
[p
] >= 'A') && (line
[p
] <= 'Z')) ||
1249 ret
.Append( line
[p
] );
1250 for (int q
= p
+1; q
< len
; q
++)
1252 if (((line
[q
] >= 'a') && (line
[q
] <= 'z')) ||
1253 ((line
[q
] >= 'A') && (line
[q
] <= 'Z')) ||
1254 ((line
[q
] >= '0') && (line
[q
] <= '9')) ||
1257 ret
.Append( line
[q
] );
1274 void wxTextCtrl::DrawLine( wxDC
&dc
, int x
, int y
, const wxString
&line2
, int lineNum
)
1276 int selStartY
= m_selStartY
;
1277 int selEndY
= m_selEndY
;
1278 int selStartX
= m_selStartX
;
1279 int selEndX
= m_selEndX
;
1281 if ((selStartY
> selEndY
) ||
1282 ((selStartY
== selEndY
) && (selStartX
> selEndX
)))
1284 int tmp
= selStartX
;
1285 selStartX
= selEndX
;
1288 selStartY
= selEndY
;
1292 wxString
line( line2
);
1293 if (HasFlag(wxTE_PASSWORD
))
1295 size_t len
= line
.Len();
1296 line
= wxString( wxT('*'), len
);
1299 wxString
keyword( ' ', line
.Len() );
1300 wxString
define( ' ', line
.Len() );
1301 wxString
variable( ' ', line
.Len() );
1302 wxString
comment( ' ', line
.Len() );
1303 wxString
my_string( ' ', line
.Len() );
1305 if (lineNum
== m_bracketY
)
1307 wxString
red( ' ', line
.Len() );
1308 if (m_bracketX
< (int)line
.Len())
1310 red
.SetChar( m_bracketX
, line
[m_bracketX
] );
1311 line
.SetChar( m_bracketX
, ' ' );
1312 dc
.SetTextForeground( *wxRED
);
1313 dc
.DrawText( red
, x
, y
);
1314 dc
.SetTextForeground( *wxBLACK
);
1319 wxString
token( GetNextToken( line
, pos
) );
1320 while (!token
.IsNull())
1322 if (m_keywords
.Index( token
) != wxNOT_FOUND
)
1324 int end_pos
= pos
+ (int)token
.Len();
1325 for (int i
= pos
; i
< end_pos
; i
++)
1327 keyword
.SetChar( i
, line
[i
] );
1328 line
.SetChar( i
, ' ' );
1331 if (m_defines
.Index( token
) != wxNOT_FOUND
)
1333 int end_pos
= pos
+ (int)token
.Len();
1334 for (int i
= pos
; i
< end_pos
; i
++)
1336 define
.SetChar( i
, line
[i
] );
1337 line
.SetChar( i
, ' ' );
1340 if ((m_variables
.Index( token
) != wxNOT_FOUND
) ||
1341 ((token
.Len() > 2) && (token
[0] == 'w') && (token
[1] == 'x')))
1343 int end_pos
= pos
+ (int)token
.Len();
1344 for (int i
= pos
; i
< end_pos
; i
++)
1346 variable
.SetChar( i
, line
[i
] );
1347 line
.SetChar( i
, ' ' );
1350 if ((token
.Len() >= 2) && (token
[0] == '/') && (token
[1] == '/') && (m_lang
== wxSOURCE_LANG_CPP
))
1352 int end_pos
= pos
+ (int)token
.Len();
1353 for (int i
= pos
; i
< end_pos
; i
++)
1355 comment
.SetChar( i
, line
[i
] );
1356 line
.SetChar( i
, ' ' );
1359 if ((token
[0] == '#') &&
1360 ((m_lang
== wxSOURCE_LANG_PYTHON
) || (m_lang
== wxSOURCE_LANG_PERL
)))
1362 int end_pos
= pos
+ (int)token
.Len();
1363 for (int i
= pos
; i
< end_pos
; i
++)
1365 comment
.SetChar( i
, line
[i
] );
1366 line
.SetChar( i
, ' ' );
1370 if ((token
[0] == '"') || (token
[0] == '\''))
1372 int end_pos
= pos
+ (int)token
.Len();
1373 for (int i
= pos
; i
< end_pos
; i
++)
1375 my_string
.SetChar( i
, line
[i
] );
1376 line
.SetChar( i
, ' ' );
1380 token
= GetNextToken( line
, pos
);
1383 if ((lineNum
< selStartY
) || (lineNum
> selEndY
))
1385 dc
.DrawText( line
, x
, y
);
1386 dc
.SetTextForeground( m_keywordColour
);
1387 dc
.DrawText( keyword
, x
, y
);
1388 dc
.SetTextForeground( m_defineColour
);
1389 dc
.DrawText( define
, x
, y
);
1390 dc
.SetTextForeground( m_variableColour
);
1391 dc
.DrawText( variable
, x
, y
);
1392 dc
.SetTextForeground( m_commentColour
);
1393 dc
.DrawText( comment
, x
, y
);
1394 dc
.SetTextForeground( m_stringColour
);
1395 dc
.DrawText( my_string
, x
, y
);
1396 dc
.SetTextForeground( *wxBLACK
);
1400 if (selStartY
== selEndY
)
1403 wxString
tmp1( line
);
1404 wxString
tmp2( line
);
1405 dc
.DrawRectangle( selStartX
*m_charWidth
+2, lineNum
*m_lineHeight
+2,
1406 (selEndX
-selStartX
)*m_charWidth
, m_lineHeight
);
1407 for (i
= selStartX
; i
< selEndX
; i
++)
1408 if ((int)tmp1
.Len() > i
)
1409 tmp1
.SetChar( i
, ' ' );
1410 dc
.DrawText( tmp1
, x
, y
);
1411 for (i
= 0; i
< selStartX
; i
++)
1412 if ((int)tmp2
.Len() > i
)
1413 tmp2
.SetChar( i
, ' ' );
1414 for (i
= selEndX
; i
< (int)tmp2
.Len(); i
++)
1415 if ((int)tmp2
.Len() > i
)
1416 tmp2
.SetChar( i
, ' ' );
1417 dc
.SetTextForeground( *wxWHITE
);
1418 dc
.DrawText( tmp2
, x
, y
);
1419 dc
.SetTextForeground( *wxBLACK
);
1421 if ((lineNum
> selStartY
) && (lineNum
< selEndY
))
1423 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2, 10000, m_lineHeight
);
1424 dc
.SetTextForeground( *wxWHITE
);
1425 dc
.DrawText( line
, x
, y
);
1426 dc
.SetTextForeground( *wxBLACK
);
1428 if (lineNum
== selStartY
)
1431 wxString
tmp1( line
);
1432 wxString
tmp2( line
);
1433 dc
.DrawRectangle( selStartX
*m_charWidth
+2, lineNum
*m_lineHeight
+2,
1434 10000, m_lineHeight
);
1435 for (i
= selStartX
; i
< (int)tmp1
.Len(); i
++)
1436 tmp1
.SetChar( i
, ' ' );
1437 dc
.DrawText( tmp1
, x
, y
);
1438 for (i
= 0; i
< selStartX
; i
++)
1439 if ((int)tmp2
.Len() > i
)
1440 tmp2
.SetChar( i
, ' ' );
1441 dc
.SetTextForeground( *wxWHITE
);
1442 dc
.DrawText( tmp2
, x
, y
);
1443 dc
.SetTextForeground( *wxBLACK
);
1445 if (lineNum
== selEndY
)
1448 wxString
tmp1( line
);
1449 wxString
tmp2( line
);
1450 dc
.DrawRectangle( 0+2, lineNum
*m_lineHeight
+2,
1451 selEndX
*m_charWidth
, m_lineHeight
);
1452 for (i
= 0; i
< selEndX
; i
++)
1453 if ((int)tmp1
.Len() > i
)
1454 tmp1
.SetChar( i
, ' ' );
1455 dc
.DrawText( tmp1
, x
, y
);
1456 for (i
= selEndX
; i
< (int)tmp2
.Len(); i
++)
1457 tmp2
.SetChar( i
, ' ' );
1458 dc
.SetTextForeground( *wxWHITE
);
1459 dc
.DrawText( tmp2
, x
, y
);
1460 dc
.SetTextForeground( *wxBLACK
);
1463 dc
.SetTextForeground( m_keywordColour
);
1464 dc
.DrawText( keyword
, x
, y
);
1465 dc
.SetTextForeground( m_defineColour
);
1466 dc
.DrawText( define
, x
, y
);
1467 dc
.SetTextForeground( m_variableColour
);
1468 dc
.DrawText( variable
, x
, y
);
1469 dc
.SetTextForeground( m_commentColour
);
1470 dc
.DrawText( comment
, x
, y
);
1471 dc
.SetTextForeground( m_stringColour
);
1472 dc
.DrawText( my_string
, x
, y
);
1473 dc
.SetTextForeground( *wxBLACK
);
1476 void wxTextCtrl::OnPaint( wxPaintEvent
&event
)
1480 if (m_lines
.GetCount() == 0) return;
1484 dc
.SetFont( m_sourceFont
);
1487 GetViewStart( NULL
, &scroll_y
);
1491 GetClientSize( &size_x
, &size_y
);
1493 dc
.SetPen( *wxTRANSPARENT_PEN
);
1494 dc
.SetBrush( wxBrush( wxTHEME_COLOUR(HIGHLIGHT
), wxSOLID
) );
1495 int upper
= wxMin( (int)m_lines
.GetCount(), scroll_y
+(size_y
/m_lineHeight
)+1 );
1496 for (int i
= scroll_y
; i
< upper
; i
++)
1499 int y
= i
*m_lineHeight
+2;
1501 int h
= m_lineHeight
;
1502 CalcScrolledPosition( x
,y
,&x
,&y
);
1503 if (IsExposed(x
,y
,w
,h
))
1504 DrawLine( dc
, 0+2, i
*m_lineHeight
+2, m_lines
[i
].m_text
, i
);
1507 dc
.SetBrush( *wxRED_BRUSH
);
1508 dc
.DrawRectangle( m_cursorX
*m_charWidth
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
1511 void wxTextCtrl::OnMouse( wxMouseEvent
&event
)
1513 if (m_lines
.GetCount() == 0) return;
1516 #if 0 // there is no middle button on iPAQs
1517 if (event
.MiddleDown())
1524 if (event
.LeftDClick())
1530 if (event
.LeftDown())
1538 m_capturing
= FALSE
;
1542 if (event
.LeftDown() ||
1543 (event
.LeftIsDown() && m_capturing
))
1545 int x
= event
.GetX();
1546 int y
= event
.GetY();
1547 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1551 wxMin( 1000, wxMax( 0, x
) ),
1552 wxMin( (int)m_lines
.GetCount()-1, wxMax( 0, y
) ),
1553 event
.ShiftDown() || !event
.LeftDown() );
1557 void wxTextCtrl::OnChar( wxKeyEvent
&event
)
1559 if (m_lines
.GetCount() == 0) return;
1563 GetClientSize( &size_x
, &size_y
);
1564 size_x
/= m_charWidth
;
1565 size_y
/= m_lineHeight
;
1568 if (event
.ShiftDown())
1570 switch (event
.GetKeyCode())
1572 case '4': event
.m_keyCode
= WXK_LEFT
; break;
1573 case '8': event
.m_keyCode
= WXK_UP
; break;
1574 case '6': event
.m_keyCode
= WXK_RIGHT
; break;
1575 case '2': event
.m_keyCode
= WXK_DOWN
; break;
1576 case '9': event
.m_keyCode
= WXK_PRIOR
; break;
1577 case '3': event
.m_keyCode
= WXK_NEXT
; break;
1578 case '7': event
.m_keyCode
= WXK_HOME
; break;
1579 case '1': event
.m_keyCode
= WXK_END
; break;
1580 case '0': event
.m_keyCode
= WXK_INSERT
; break;
1584 switch (event
.GetKeyCode())
1588 if (m_ignoreInput
) return;
1590 MoveCursor( m_cursorX
, m_cursorY
-1, event
.ShiftDown() );
1591 m_ignoreInput
= TRUE
;
1596 if (m_ignoreInput
) return;
1597 if (m_cursorY
< (int)(m_lines
.GetCount()-1))
1598 MoveCursor( m_cursorX
, m_cursorY
+1, event
.ShiftDown() );
1599 m_ignoreInput
= TRUE
;
1604 if (m_ignoreInput
) return;
1607 MoveCursor( m_cursorX
-1, m_cursorY
, event
.ShiftDown() );
1612 MoveCursor( m_lines
[m_cursorY
-1].m_text
.Len(), m_cursorY
-1, event
.ShiftDown() );
1614 m_ignoreInput
= TRUE
;
1619 if (m_ignoreInput
) return;
1620 if (m_cursorX
< 1000)
1621 MoveCursor( m_cursorX
+1, m_cursorY
, event
.ShiftDown() );
1622 m_ignoreInput
= TRUE
;
1627 if (event
.ControlDown())
1628 MoveCursor( 0, 0, event
.ShiftDown() );
1630 MoveCursor( 0, m_cursorY
, event
.ShiftDown() );
1635 if (event
.ControlDown())
1636 MoveCursor( 0, m_lines
.GetCount()-1, event
.ShiftDown() );
1638 MoveCursor( m_lines
[m_cursorY
].m_text
.Len(), m_cursorY
, event
.ShiftDown() );
1643 if (m_ignoreInput
) return;
1644 MoveCursor( m_cursorX
, wxMin( (int)(m_lines
.GetCount()-1), m_cursorY
+size_y
), event
.ShiftDown() );
1645 m_ignoreInput
= TRUE
;
1650 if (m_ignoreInput
) return;
1651 MoveCursor( m_cursorX
, wxMax( 0, m_cursorY
-size_y
), event
.ShiftDown() );
1652 m_ignoreInput
= TRUE
;
1657 if (event
.ShiftDown())
1659 else if (event
.ControlDown())
1662 m_overwrite
= !m_overwrite
;
1682 bool save_overwrite
= m_overwrite
;
1683 m_overwrite
= FALSE
;
1684 int i
= 4-(m_cursorX
% 4);
1686 for (int c
= 0; c
< i
; c
++)
1688 m_overwrite
= save_overwrite
;
1709 if ( (event
.KeyCode() >= 'a') &&
1710 (event
.KeyCode() <= 'z') &&
1718 if ( (event
.KeyCode() >= 32) &&
1719 (event
.KeyCode() <= 255) &&
1720 !(event
.ControlDown() && !event
.AltDown()) ) // filters out Ctrl-X but leaves Alt-Gr
1724 DoChar( (char) event
.KeyCode() );
1733 void wxTextCtrl::OnIdle( wxIdleEvent
&event
)
1735 m_ignoreInput
= FALSE
;
1737 SearchForBrackets();
1742 void wxTextCtrl::Indent()
1744 int startY
= m_cursorY
;
1745 int endY
= m_cursorY
;
1748 startY
= m_selStartY
;
1758 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1760 for (int i
= startY
; i
<= endY
; i
++)
1762 m_lines
[i
].m_text
.insert( 0u, " " );
1767 void wxTextCtrl::Unindent()
1769 int startY
= m_cursorY
;
1770 int endY
= m_cursorY
;
1773 startY
= m_selStartY
;
1783 m_undos
.Append( new wxSourceUndoStep( wxSOURCE_UNDO_LINE
, startY
, endY
, this ) );
1785 for (int i
= startY
; i
<= endY
; i
++)
1787 for (int n
= 0; n
< 4; n
++)
1789 if (m_lines
[i
].m_text
[0u] == ' ')
1790 m_lines
[i
].m_text
.erase(0u,1u);
1795 bool wxTextCtrl::HasSelection()
1797 return ((m_selStartY
!= m_selEndY
) || (m_selStartX
!= m_selEndX
));
1800 void wxTextCtrl::ClearSelection()
1808 void wxTextCtrl::RefreshLine( int n
)
1810 int y
= n
*m_lineHeight
;
1812 CalcScrolledPosition( x
, y
, &x
, &y
);
1813 wxRect
rect( 0+2, y
+2, 10000, m_lineHeight
);
1814 Refresh( TRUE
, &rect
);
1817 void wxTextCtrl::RefreshDown( int n
)
1821 GetClientSize( &size_x
, &size_y
);
1825 GetViewStart( &view_x
, &view_y
);
1833 int y
= n
*m_lineHeight
;
1835 CalcScrolledPosition( x
, y
, &x
, &y
);
1837 wxRect
rect( 0+2, y
+2, 10000, size_y
);
1838 Refresh( TRUE
, &rect
);
1842 void wxTextCtrl::MoveCursor( int new_x
, int new_y
, bool shift
, bool centre
)
1844 // if (IsSingleLine())
1846 if (new_x
> m_lines
[new_y
].m_text
.Len())
1847 new_x
= m_lines
[new_y
].m_text
.Len();
1850 if ((new_x
== m_cursorX
) && (new_y
== m_cursorY
)) return;
1852 bool no_cursor_refresh
= FALSE
;
1858 if (!HasSelection())
1860 m_selStartX
= m_cursorX
;
1861 m_selStartY
= m_cursorY
;
1865 if (new_y
> m_selStartY
)
1867 y
= m_selStartY
*m_lineHeight
;
1868 h
= (new_y
-m_selStartY
+1)*m_lineHeight
;
1870 else if (new_y
== m_selStartY
)
1872 y
= m_selStartY
*m_lineHeight
;
1877 y
= new_y
*m_lineHeight
;
1878 h
= (-new_y
+m_selStartY
+1)*m_lineHeight
;
1881 no_cursor_refresh
= TRUE
;
1887 if (new_y
== m_selEndY
)
1889 y
= new_y
*m_lineHeight
;
1891 if (m_selEndX
> new_x
)
1893 x
= new_x
*m_charWidth
;
1894 w
= (m_selEndX
-new_x
)*m_charWidth
;
1898 x
= m_selEndX
*m_charWidth
;
1899 w
= (-m_selEndX
+new_x
)*m_charWidth
;
1906 if (new_y
> m_selEndY
)
1908 y
= m_selEndY
*m_lineHeight
;
1909 h
= (new_y
-m_selEndY
+1) * m_lineHeight
;
1913 y
= new_y
*m_lineHeight
;
1914 h
= (-new_y
+m_selEndY
+1) * m_lineHeight
;
1916 no_cursor_refresh
= TRUE
;
1925 CalcScrolledPosition( x
, y
, &x
, &y
);
1926 wxRect
rect( x
+2, y
+2, w
, h
);
1927 Refresh( TRUE
, &rect
);
1933 int ry1
= m_selEndY
;
1934 int ry2
= m_selStartY
;
1948 int y
= ry1
*m_lineHeight
;
1949 CalcScrolledPosition( x
, y
, &x
, &y
);
1950 wxRect
rect( 0+2, y
+2, 10000, (ry2
-ry1
+1)*m_lineHeight
);
1952 Refresh( TRUE
, &rect
);
1957 printf( "startx %d starty %d endx %d endy %d\n",
1958 m_selStartX, m_selStartY, m_selEndX, m_selEndY );
1960 printf( "has %d\n", (int)HasSelection() );
1963 if (!no_cursor_refresh
)
1965 int x
= m_cursorX
*m_charWidth
;
1966 int y
= m_cursorY
*m_lineHeight
;
1967 CalcScrolledPosition( x
, y
, &x
, &y
);
1968 wxRect
rect( x
+2, y
+2, 4, m_lineHeight
+2 );
1973 Refresh( TRUE
, &rect
);
1975 wxClientDC
dc(this);
1977 dc
.SetPen( *wxTRANSPARENT_PEN
);
1978 dc
.SetBrush( *wxRED_BRUSH
);
1979 dc
.DrawRectangle( m_cursorX
*m_charWidth
+2, m_cursorY
*m_lineHeight
+2, 2, m_lineHeight
);
1984 GetClientSize( &size_x
, &size_y
);
1985 size_x
/= m_charWidth
;
1986 size_y
/= m_lineHeight
;
1990 GetViewStart( &view_x
, &view_y
);
1994 int sy
= m_cursorY
- (size_y
/2);
2000 if (m_cursorY
< view_y
)
2001 Scroll( -1, m_cursorY
);
2002 else if (m_cursorY
> view_y
+size_y
-1)
2003 Scroll( -1, m_cursorY
-size_y
+1 );
2006 if (m_cursorX
< view_x
)
2007 Scroll( m_cursorX
, -1 );
2008 else if (m_cursorX
> view_x
+size_x
-1)
2009 Scroll( m_cursorX
-size_x
+1, -1 );
2012 void wxTextCtrl::MyAdjustScrollbars()
2017 int y_range
= m_lines
.GetCount();
2020 GetClientSize( NULL
, &height
);
2022 if (height
>= m_lines
.GetCount() *m_lineHeight
)
2027 GetViewStart( &view_x
, &view_y
);
2029 SetScrollbars( m_charWidth
, m_lineHeight
, m_longestLine
+2, y_range
, view_x
, view_y
);
2032 //-----------------------------------------------------------------------------
2033 // clipboard handlers
2034 //-----------------------------------------------------------------------------
2036 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
))
2041 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
))
2046 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
))
2051 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
))
2056 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
))
2061 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
2063 event
.Enable( CanCut() );
2066 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
2068 event
.Enable( CanCopy() );
2071 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
2073 event
.Enable( CanPaste() );
2076 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
2078 event
.Enable( CanUndo() );
2081 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
2083 event
.Enable( CanRedo() );
2086 wxSize
wxTextCtrl::DoGetBestSize() const
2090 wxSize
ret(80, m_lineHeight
+ 4);
2092 if (HasFlag(wxBORDER_SUNKEN
) || HasFlag(wxBORDER_RAISED
))
2095 if (HasFlag(wxBORDER_SIMPLE
))
2102 return wxSize(80, 60);
2106 // ----------------------------------------------------------------------------
2108 // ----------------------------------------------------------------------------
2110 void wxTextCtrl::Freeze()
2114 void wxTextCtrl::Thaw()
2118 // ----------------------------------------------------------------------------
2119 // text control scrolling
2120 // ----------------------------------------------------------------------------
2122 bool wxTextCtrl::ScrollLines(int lines
)
2124 wxFAIL_MSG( "wxTextCtrl::ScrollLines not implemented");
2129 bool wxTextCtrl::ScrollPages(int pages
)
2131 wxFAIL_MSG( "wxTextCtrl::ScrollPages not implemented");