1 ////////////////////////////////////////////////////////////////////////////
2 // Name: ScintillaWX.cxx
3 // Purpose: A wxWidgets implementation of Scintilla. A class derived
4 // from ScintillaBase that uses the "wx platform" defined in
5 // PlatformWX.cxx This class is one end of a bridge between
6 // the wx world and the Scintilla world. It needs a peer
7 // object of type wxStyledTextCtrl to function.
11 // Created: 13-Jan-2000
13 // Copyright: (c) 2000 by Total Control Software
14 // Licence: wxWindows license
15 /////////////////////////////////////////////////////////////////////////////
18 #include "ScintillaWX.h"
19 #include "ExternalLexer.h"
20 #include "wx/stc/stc.h"
22 #include <wx/textbuf.h>
24 //----------------------------------------------------------------------
27 class wxSTCTimer
: public wxTimer
{
29 wxSTCTimer(ScintillaWX
* swx
) {
42 #if wxUSE_DRAG_AND_DROP
43 bool wxSTCDropTarget
::OnDropText(wxCoord x
, wxCoord y
, const wxString
& data
) {
44 return swx
->DoDropText(x
, y
, data
);
47 wxDragResult wxSTCDropTarget
::OnEnter(wxCoord x
, wxCoord y
, wxDragResult def
) {
48 return swx
->DoDragEnter(x
, y
, def
);
51 wxDragResult wxSTCDropTarget
::OnDragOver(wxCoord x
, wxCoord y
, wxDragResult def
) {
52 return swx
->DoDragOver(x
, y
, def
);
55 void wxSTCDropTarget
::OnLeave() {
61 #if wxUSE_POPUPWIN && wxSTC_USE_POPUP
62 #include <wx/popupwin.h>
63 #define wxSTCCallTipBase wxPopupWindow
64 #define param2 wxBORDER_NONE // popup's 2nd param is flags
66 #define wxSTCCallTipBase wxWindow
67 #define param2 -1 // wxWindow's 2nd param is ID
70 #include <wx/dcbuffer.h>
72 class wxSTCCallTip
: public wxSTCCallTipBase
{
74 wxSTCCallTip(wxWindow
* parent
, CallTip
* ct
, ScintillaWX
* swx
)
75 : wxSTCCallTipBase(parent
, param2
),
76 m_ct(ct
), m_swx(swx
), m_cx(wxDefaultCoord
), m_cy(wxDefaultCoord
)
81 #if wxUSE_POPUPWIN && wxSTC_USE_POPUP && defined(__WXGTK__)
82 wxRect rect
= GetRect();
85 GetParent()->Refresh(false, &rect
);
89 bool AcceptsFocus() const { return false; }
91 void OnPaint(wxPaintEvent
& WXUNUSED(evt
)) {
92 wxBufferedPaintDC
dc(this);
93 Surface
* surfaceWindow
= Surface
::Allocate();
94 surfaceWindow
->Init(&dc
, m_ct
->wDraw
.GetID());
95 m_ct
->PaintCT(surfaceWindow
);
96 surfaceWindow
->Release();
100 void OnFocus(wxFocusEvent
& event
) {
101 GetParent()->SetFocus();
105 void OnLeftDown(wxMouseEvent
& event
) {
106 wxPoint pt
= event
.GetPosition();
109 m_swx
->CallTipClick();
112 #if wxUSE_POPUPWIN && wxSTC_USE_POPUP
113 virtual void DoSetSize(int x
, int y
,
114 int width
, int height
,
115 int sizeFlags
= wxSIZE_AUTO
) {
116 if (x
!= wxDefaultCoord
) {
118 GetParent()->ClientToScreen(&x
, NULL
);
120 if (y
!= wxDefaultCoord
) {
122 GetParent()->ClientToScreen(NULL
, &y
);
124 wxSTCCallTipBase
::DoSetSize(x
, y
, width
, height
, sizeFlags
);
128 wxPoint
GetMyPosition() {
129 return wxPoint(m_cx
, m_cy
);
136 DECLARE_EVENT_TABLE()
139 BEGIN_EVENT_TABLE(wxSTCCallTip
, wxSTCCallTipBase
)
140 EVT_PAINT(wxSTCCallTip
::OnPaint
)
141 EVT_SET_FOCUS(wxSTCCallTip
::OnFocus
)
142 EVT_LEFT_DOWN(wxSTCCallTip
::OnLeftDown
)
146 //----------------------------------------------------------------------
148 static wxTextFileType
wxConvertEOLMode(int scintillaMode
)
152 switch (scintillaMode
) {
154 type
= wxTextFileType_Dos
;
158 type
= wxTextFileType_Mac
;
162 type
= wxTextFileType_Unix
;
166 type
= wxTextBuffer
::typeDefault
;
173 //----------------------------------------------------------------------
174 // Constructor/Destructor
177 ScintillaWX
::ScintillaWX(wxStyledTextCtrl
* win
) {
178 capturedMouse
= false;
187 ScintillaWX
::~ScintillaWX() {
191 //----------------------------------------------------------------------
192 // base class virtuals
195 void ScintillaWX
::Initialise() {
196 //ScintillaBase::Initialise();
197 #if wxUSE_DRAG_AND_DROP
198 dropTarget
= new wxSTCDropTarget
;
199 dropTarget
->SetScintilla(this);
200 stc
->SetDropTarget(dropTarget
);
203 vs
.extraFontFlag
= false; // UseAntiAliasing
205 vs
.extraFontFlag
= true; // UseAntiAliasing
210 void ScintillaWX
::Finalise() {
211 ScintillaBase
::Finalise();
214 DestroySystemCaret();
218 void ScintillaWX
::StartDrag() {
219 #if wxUSE_DRAG_AND_DROP
220 wxString dragText
= stc2wx(drag
.s
, drag
.len
);
222 // Send an event to allow the drag text to be changed
223 wxStyledTextEvent
evt(wxEVT_STC_START_DRAG
, stc
->GetId());
224 evt
.SetEventObject(stc
);
225 evt
.SetDragText(dragText
);
226 evt
.SetDragAllowMove(true);
227 evt
.SetPosition(wxMin(stc
->GetSelectionStart(),
228 stc
->GetSelectionEnd()));
229 stc
->GetEventHandler()->ProcessEvent(evt
);
230 dragText
= evt
.GetDragText();
232 if (dragText
.Length()) {
233 wxDropSource
source(stc
);
234 wxTextDataObject
data(dragText
);
237 source
.SetData(data
);
238 dropWentOutside
= true;
239 result
= source
.DoDragDrop(evt
.GetDragAllowMove());
240 if (result
== wxDragMove
&& dropWentOutside
)
243 SetDragPosition(invalidPosition
);
249 bool ScintillaWX
::SetIdle(bool on
) {
250 if (idler
.state
!= on
) {
251 // connect or disconnect the EVT_IDLE handler
253 stc
->Connect(wxID_ANY
, wxEVT_IDLE
,
254 (wxObjectEventFunction
) (wxEventFunction
) (wxIdleEventFunction
) &wxStyledTextCtrl
::OnIdle
);
256 stc
->Disconnect(wxID_ANY
, wxEVT_IDLE
,
257 (wxObjectEventFunction
) (wxEventFunction
) (wxIdleEventFunction
) &wxStyledTextCtrl
::OnIdle
);
264 void ScintillaWX
::SetTicking(bool on
) {
265 wxSTCTimer
* steTimer
;
266 if (timer
.ticking
!= on
) {
269 steTimer
= new wxSTCTimer(this);
270 steTimer
->Start(timer
.tickSize
);
271 timer
.tickerID
= steTimer
;
273 steTimer
= (wxSTCTimer
*)timer
.tickerID
;
279 timer
.ticksToWait
= caret
.period
;
283 void ScintillaWX
::SetMouseCapture(bool on
) {
284 if (mouseDownCaptures
) {
285 if (on
&& !capturedMouse
)
287 else if (!on
&& capturedMouse
&& stc
->HasCapture())
294 bool ScintillaWX
::HaveMouseCapture() {
295 return capturedMouse
;
299 void ScintillaWX
::ScrollText(int linesToMove
) {
300 int dy
= vs
.lineHeight
* (linesToMove
);
301 stc
->ScrollWindow(0, dy
);
305 void ScintillaWX
::SetVerticalScrollPos() {
306 if (stc
->m_vScrollBar
== NULL
) { // Use built-in scrollbar
307 stc
->SetScrollPos(wxVERTICAL
, topLine
);
309 else { // otherwise use the one that's been given to us
310 stc
->m_vScrollBar
->SetThumbPosition(topLine
);
314 void ScintillaWX
::SetHorizontalScrollPos() {
315 if (stc
->m_hScrollBar
== NULL
) { // Use built-in scrollbar
316 stc
->SetScrollPos(wxHORIZONTAL
, xOffset
);
318 else { // otherwise use the one that's been given to us
319 stc
->m_hScrollBar
->SetThumbPosition(xOffset
);
324 const int H_SCROLL_STEP
= 20;
326 bool ScintillaWX
::ModifyScrollBars(int nMax
, int nPage
) {
327 bool modified
= false;
330 if (!verticalScrollBarVisible
)
333 // Check the vertical scrollbar
334 if (stc
->m_vScrollBar
== NULL
) { // Use built-in scrollbar
335 int sbMax
= stc
->GetScrollRange(wxVERTICAL
);
336 int sbThumb
= stc
->GetScrollThumb(wxVERTICAL
);
337 int sbPos
= stc
->GetScrollPos(wxVERTICAL
);
338 if (sbMax
!= vertEnd
|| sbThumb
!= nPage
) {
339 stc
->SetScrollbar(wxVERTICAL
, sbPos
, nPage
, vertEnd
+1);
343 else { // otherwise use the one that's been given to us
344 int sbMax
= stc
->m_vScrollBar
->GetRange();
345 int sbPage
= stc
->m_vScrollBar
->GetPageSize();
346 int sbPos
= stc
->m_vScrollBar
->GetThumbPosition();
347 if (sbMax
!= vertEnd
|| sbPage
!= nPage
) {
348 stc
->m_vScrollBar
->SetScrollbar(sbPos
, nPage
, vertEnd
+1, nPage
);
354 // Check the horizontal scrollbar
355 PRectangle rcText
= GetTextRectangle();
356 int horizEnd
= scrollWidth
;
359 if (!horizontalScrollBarVisible
|| (wrapState
!= eWrapNone
))
361 int pageWidth
= rcText
.Width();
363 if (stc
->m_hScrollBar
== NULL
) { // Use built-in scrollbar
364 int sbMax
= stc
->GetScrollRange(wxHORIZONTAL
);
365 int sbThumb
= stc
->GetScrollThumb(wxHORIZONTAL
);
366 int sbPos
= stc
->GetScrollPos(wxHORIZONTAL
);
367 if ((sbMax
!= horizEnd
) || (sbThumb
!= pageWidth
) || (sbPos
!= 0)) {
368 stc
->SetScrollbar(wxHORIZONTAL
, sbPos
, pageWidth
, horizEnd
);
370 if (scrollWidth
< pageWidth
) {
371 HorizontalScrollTo(0);
375 else { // otherwise use the one that's been given to us
376 int sbMax
= stc
->m_hScrollBar
->GetRange();
377 int sbThumb
= stc
->m_hScrollBar
->GetPageSize();
378 int sbPos
= stc
->m_hScrollBar
->GetThumbPosition();
379 if ((sbMax
!= horizEnd
) || (sbThumb
!= pageWidth
) || (sbPos
!= 0)) {
380 stc
->m_hScrollBar
->SetScrollbar(sbPos
, pageWidth
, horizEnd
, pageWidth
);
382 if (scrollWidth
< pageWidth
) {
383 HorizontalScrollTo(0);
392 void ScintillaWX
::NotifyChange() {
397 void ScintillaWX
::NotifyParent(SCNotification scn
) {
398 stc
->NotifyParent(&scn
);
402 // This method is overloaded from ScintillaBase in order to prevent the
403 // AutoComplete window from being destroyed when it gets the focus. There is
404 // a side effect that the AutoComp will also not be destroyed when switching
405 // to another window, but I think that is okay.
406 void ScintillaWX
::CancelModes() {
408 AutoCompleteCancel();
410 Editor
::CancelModes();
415 void ScintillaWX
::Copy() {
416 if (currentPos
!= anchor
) {
418 CopySelectionRange(&st
);
424 void ScintillaWX
::Paste() {
425 pdoc
->BeginUndoAction();
428 wxTextDataObject data
;
429 bool gotData
= false;
431 if (wxTheClipboard
->Open()) {
432 wxTheClipboard
->UsePrimarySelection(false);
433 gotData
= wxTheClipboard
->GetData(data
);
434 wxTheClipboard
->Close();
437 wxString text
= wxTextBuffer
::Translate(data
.GetText(),
438 wxConvertEOLMode(pdoc
->eolMode
));
439 wxWX2MBbuf buf
= (wxWX2MBbuf
)wx2stc(text
);
440 int len
= strlen(buf
);
441 pdoc
->InsertString(currentPos
, buf
, len
);
442 SetEmptySelection(currentPos
+ len
);
445 pdoc
->EndUndoAction();
451 void ScintillaWX
::CopyToClipboard(const SelectionText
& st
) {
452 if (wxTheClipboard
->Open()) {
453 wxTheClipboard
->UsePrimarySelection(false);
454 wxString text
= wxTextBuffer
::Translate(stc2wx(st
.s
, st
.len
));
455 wxTheClipboard
->SetData(new wxTextDataObject(text
));
456 wxTheClipboard
->Close();
461 bool ScintillaWX
::CanPaste() {
462 bool canPaste
= false;
465 if (Editor
::CanPaste()) {
466 didOpen
= !wxTheClipboard
->IsOpened();
468 wxTheClipboard
->Open();
470 if (wxTheClipboard
->IsOpened()) {
471 wxTheClipboard
->UsePrimarySelection(false);
472 canPaste
= wxTheClipboard
->IsSupported(wxUSE_UNICODE ? wxDF_UNICODETEXT
: wxDF_TEXT
);
474 wxTheClipboard
->Close();
480 void ScintillaWX
::CreateCallTipWindow(PRectangle
) {
481 if (! ct
.wCallTip
.Created() ) {
482 ct
.wCallTip
= new wxSTCCallTip(stc
, &ct
, this);
483 ct
.wDraw
= ct
.wCallTip
;
488 void ScintillaWX
::AddToPopUp(const char *label
, int cmd
, bool enabled
) {
490 ((wxMenu
*)popup
.GetID())->AppendSeparator();
492 ((wxMenu
*)popup
.GetID())->Append(cmd
, wxGetTranslation(stc2wx(label
)));
495 ((wxMenu
*)popup
.GetID())->Enable(cmd
, enabled
);
499 // This is called by the Editor base class whenever something is selected
500 void ScintillaWX
::ClaimSelection() {
502 // Until wxGTK is able to support using both the primary selection and the
503 // clipboard at the same time I think it causes more problems than it is
504 // worth to implement this method. Selecting text should not clear the
505 // clipboard. --Robin
507 // Put the selected text in the PRIMARY selection
508 if (currentPos
!= anchor
) {
510 CopySelectionRange(&st
);
511 if (wxTheClipboard
->Open()) {
512 wxTheClipboard
->UsePrimarySelection(true);
513 wxString text
= stc2wx(st
.s
, st
.len
);
514 wxTheClipboard
->SetData(new wxTextDataObject(text
));
515 wxTheClipboard
->UsePrimarySelection(false);
516 wxTheClipboard
->Close();
524 void ScintillaWX
::UpdateSystemCaret() {
527 if (HasCaretSizeChanged()) {
528 DestroySystemCaret();
531 Point pos
= LocationFromPosition(currentPos
);
532 ::SetCaretPos(pos
.x
, pos
.y
);
538 bool ScintillaWX
::HasCaretSizeChanged() {
540 if (( (0 != vs
.caretWidth
) && (sysCaretWidth
!= vs
.caretWidth
) )
541 || (0 != vs
.lineHeight
) && (sysCaretHeight
!= vs
.lineHeight
)) {
548 bool ScintillaWX
::CreateSystemCaret() {
550 sysCaretWidth
= vs
.caretWidth
;
551 if (0 == sysCaretWidth
) {
554 sysCaretHeight
= vs
.lineHeight
;
555 int bitmapSize
= (((sysCaretWidth
+ 15) & ~15) >> 3) * sysCaretHeight
;
556 char *bits
= new char[bitmapSize
];
557 memset(bits
, 0, bitmapSize
);
558 sysCaretBitmap
= ::CreateBitmap(sysCaretWidth
, sysCaretHeight
, 1,
559 1, reinterpret_cast<BYTE
*>(bits
));
561 BOOL retval
= ::CreateCaret(GetHwndOf(stc
), sysCaretBitmap
,
562 sysCaretWidth
, sysCaretHeight
);
563 ::ShowCaret(GetHwndOf(stc
));
570 bool ScintillaWX
::DestroySystemCaret() {
572 ::HideCaret(GetHwndOf(stc
));
573 BOOL retval
= ::DestroyCaret();
574 if (sysCaretBitmap
) {
575 ::DeleteObject(sysCaretBitmap
);
585 //----------------------------------------------------------------------
588 long ScintillaWX
::DefWndProc(unsigned int /*iMessage*/, unsigned long /*wParam*/, long /*lParam*/) {
592 long ScintillaWX
::WndProc(unsigned int iMessage
, unsigned long wParam
, long lParam
) {
594 case SCI_CALLTIPSHOW
: {
595 // NOTE: This is copied here from scintilla/src/ScintillaBase.cxx
596 // because of the little tweak that needs done below for wxGTK.
597 // When updating new versions double check that this is still
598 // needed, and that any new code there is copied here too.
599 Point pt
= LocationFromPosition(wParam
);
600 char* defn
= reinterpret_cast<char *>(lParam
);
601 AutoCompleteCancel();
602 pt
.y
+= vs
.lineHeight
;
603 PRectangle rc
= ct
.CallTipStart(currentPos
, pt
,
605 vs
.styles
[STYLE_DEFAULT
].fontName
,
606 vs
.styles
[STYLE_DEFAULT
].sizeZoomed
,
608 vs
.styles
[STYLE_DEFAULT
].characterSet
,
610 // If the call-tip window would be out of the client
611 // space, adjust so it displays above the text.
612 PRectangle rcClient
= GetClientRectangle();
613 if (rc
.bottom
> rcClient
.bottom
) {
615 int offset
= int(vs
.lineHeight
* 1.25) + rc
.Height();
617 int offset
= vs
.lineHeight
+ rc
.Height();
622 // Now display the window.
623 CreateCallTipWindow(rc
);
624 ct
.wCallTip
.SetPositionRelative(rc
, wMain
);
630 case SCI_LOADLEXERLIBRARY
:
631 LexerManager
::GetInstance()->Load((const char*)lParam
);
635 return ScintillaBase
::WndProc(iMessage
, wParam
, lParam
);
642 //----------------------------------------------------------------------
645 void ScintillaWX
::DoPaint(wxDC
* dc
, wxRect rect
) {
647 paintState
= painting
;
648 Surface
* surfaceWindow
= Surface
::Allocate();
649 surfaceWindow
->Init(dc
, wMain
.GetID());
650 rcPaint
= PRectangleFromwxRect(rect
);
651 PRectangle rcClient
= GetClientRectangle();
652 paintingAllText
= rcPaint
.Contains(rcClient
);
655 ClipChildren(*dc
, rcPaint
);
656 Paint(surfaceWindow
, rcPaint
);
658 delete surfaceWindow
;
659 if (paintState
== paintAbandoned
) {
660 // Painting area was insufficient to cover new styling or brace
661 // highlight positions
664 paintState
= notPainting
;
669 void ScintillaWX
::DoHScroll(int type
, int pos
) {
671 PRectangle rcText
= GetTextRectangle();
672 int pageWidth
= rcText
.Width() * 2 / 3;
673 if (type
== wxEVT_SCROLLWIN_LINEUP
|| type
== wxEVT_SCROLL_LINEUP
)
674 xPos
-= H_SCROLL_STEP
;
675 else if (type
== wxEVT_SCROLLWIN_LINEDOWN
|| type
== wxEVT_SCROLL_LINEDOWN
)
676 xPos
+= H_SCROLL_STEP
;
677 else if (type
== wxEVT_SCROLLWIN_PAGEUP
|| type
== wxEVT_SCROLL_PAGEUP
)
679 else if (type
== wxEVT_SCROLLWIN_PAGEDOWN
|| type
== wxEVT_SCROLL_PAGEDOWN
) {
681 if (xPos
> scrollWidth
- rcText
.Width()) {
682 xPos
= scrollWidth
- rcText
.Width();
685 else if (type
== wxEVT_SCROLLWIN_TOP
|| type
== wxEVT_SCROLL_TOP
)
687 else if (type
== wxEVT_SCROLLWIN_BOTTOM
|| type
== wxEVT_SCROLL_BOTTOM
)
689 else if (type
== wxEVT_SCROLLWIN_THUMBTRACK
|| type
== wxEVT_SCROLL_THUMBTRACK
)
692 HorizontalScrollTo(xPos
);
695 void ScintillaWX
::DoVScroll(int type
, int pos
) {
696 int topLineNew
= topLine
;
697 if (type
== wxEVT_SCROLLWIN_LINEUP
|| type
== wxEVT_SCROLL_LINEUP
)
699 else if (type
== wxEVT_SCROLLWIN_LINEDOWN
|| type
== wxEVT_SCROLL_LINEDOWN
)
701 else if (type
== wxEVT_SCROLLWIN_PAGEUP
|| type
== wxEVT_SCROLL_PAGEUP
)
702 topLineNew
-= LinesToScroll();
703 else if (type
== wxEVT_SCROLLWIN_PAGEDOWN
|| type
== wxEVT_SCROLL_PAGEDOWN
)
704 topLineNew
+= LinesToScroll();
705 else if (type
== wxEVT_SCROLLWIN_TOP
|| type
== wxEVT_SCROLL_TOP
)
707 else if (type
== wxEVT_SCROLLWIN_BOTTOM
|| type
== wxEVT_SCROLL_BOTTOM
)
708 topLineNew
= MaxScrollPos();
709 else if (type
== wxEVT_SCROLLWIN_THUMBTRACK
|| type
== wxEVT_SCROLL_THUMBTRACK
)
712 ScrollTo(topLineNew
);
715 void ScintillaWX
::DoMouseWheel(int rotation
, int delta
,
716 int linesPerAction
, int ctrlDown
,
717 bool isPageScroll
) {
718 int topLineNew
= topLine
;
721 if (ctrlDown
) { // Zoom the fonts if Ctrl key down
723 KeyCommand(SCI_ZOOMIN
);
726 KeyCommand(SCI_ZOOMOUT
);
729 else { // otherwise just scroll the window
732 wheelRotation
+= rotation
;
733 lines
= wheelRotation
/ delta
;
734 wheelRotation
-= lines
* delta
;
737 lines
= lines
* LinesOnScreen(); // lines is either +1 or -1
739 lines
*= linesPerAction
;
741 ScrollTo(topLineNew
);
747 void ScintillaWX
::DoSize(int WXUNUSED(width
), int WXUNUSED(height
)) {
751 void ScintillaWX
::DoLoseFocus(){
753 SetFocusState(false);
755 DestroySystemCaret();
758 void ScintillaWX
::DoGainFocus(){
762 DestroySystemCaret();
766 void ScintillaWX
::DoSysColourChange() {
767 InvalidateStyleData();
770 void ScintillaWX
::DoLeftButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
) {
771 ButtonDown(pt
, curTime
, shift
, ctrl
, alt
);
774 void ScintillaWX
::DoLeftButtonUp(Point pt
, unsigned int curTime
, bool ctrl
) {
775 ButtonUp(pt
, curTime
, ctrl
);
778 void ScintillaWX
::DoLeftButtonMove(Point pt
) {
783 void ScintillaWX
::DoMiddleButtonUp(Point pt
) {
784 // Set the current position to the mouse click point and
785 // then paste in the PRIMARY selection, if any. wxGTK only.
786 int newPos
= PositionFromLocation(pt
);
787 MovePositionTo(newPos
, noSel
, true);
789 pdoc
->BeginUndoAction();
790 wxTextDataObject data
;
791 bool gotData
= false;
792 if (wxTheClipboard
->Open()) {
793 wxTheClipboard
->UsePrimarySelection(true);
794 gotData
= wxTheClipboard
->GetData(data
);
795 wxTheClipboard
->UsePrimarySelection(false);
796 wxTheClipboard
->Close();
799 wxString text
= wxTextBuffer
::Translate(data
.GetText(),
800 wxConvertEOLMode(pdoc
->eolMode
));
801 wxWX2MBbuf buf
= (wxWX2MBbuf
)wx2stc(text
);
802 int len
= strlen(buf
);
803 pdoc
->InsertString(currentPos
, buf
, len
);
804 SetEmptySelection(currentPos
+ len
);
806 pdoc
->EndUndoAction();
810 ShowCaretAtCurrentPosition();
811 EnsureCaretVisible();
814 void ScintillaWX
::DoMiddleButtonUp(Point
WXUNUSED(pt
)) {
819 void ScintillaWX
::DoAddChar(int key
) {
822 wszChars
[0] = (wxChar
)key
;
824 wxWX2MBbuf buf
= (wxWX2MBbuf
)wx2stc(wszChars
);
825 AddCharUTF((char*)buf
.data(), strlen(buf
));
832 int ScintillaWX
::DoKeyDown(const wxKeyEvent
& evt
, bool* consumed
)
834 int key
= evt
.GetKeyCode();
835 bool shift
= evt
.ShiftDown(),
836 ctrl
= evt
.ControlDown(),
839 if (ctrl
&& key
>= 1 && key
<= 26)
843 case WXK_DOWN
: key
= SCK_DOWN
; break;
844 case WXK_UP
: key
= SCK_UP
; break;
845 case WXK_LEFT
: key
= SCK_LEFT
; break;
846 case WXK_RIGHT
: key
= SCK_RIGHT
; break;
847 case WXK_HOME
: key
= SCK_HOME
; break;
848 case WXK_END
: key
= SCK_END
; break;
849 case WXK_PAGEUP
: // fall through
850 case WXK_PRIOR
: key
= SCK_PRIOR
; break;
851 case WXK_PAGEDOWN
: // fall through
852 case WXK_NEXT
: key
= SCK_NEXT
; break;
853 case WXK_DELETE
: key
= SCK_DELETE
; break;
854 case WXK_INSERT
: key
= SCK_INSERT
; break;
855 case WXK_ESCAPE
: key
= SCK_ESCAPE
; break;
856 case WXK_BACK
: key
= SCK_BACK
; break;
857 case WXK_TAB
: key
= SCK_TAB
; break;
858 case WXK_RETURN
: key
= SCK_RETURN
; break;
859 case WXK_ADD
: // fall through
860 case WXK_NUMPAD_ADD
: key
= SCK_ADD
; break;
861 case WXK_SUBTRACT
: // fall through
862 case WXK_NUMPAD_SUBTRACT
: key
= SCK_SUBTRACT
; break;
863 case WXK_DIVIDE
: // fall through
864 case WXK_NUMPAD_DIVIDE
: key
= SCK_DIVIDE
; break;
865 case WXK_CONTROL
: key
= 0; break;
866 case WXK_ALT
: key
= 0; break;
867 case WXK_SHIFT
: key
= 0; break;
868 case WXK_MENU
: key
= 0; break;
872 if ( evt
.MetaDown() ) {
873 // check for a few common Mac Meta-key combos and remap them to Ctrl
880 case 'A': // Select All
887 int rv
= KeyDown(key
, shift
, ctrl
, alt
, consumed
);
896 void ScintillaWX
::DoCommand(int ID
) {
901 void ScintillaWX
::DoContextMenu(Point pt
) {
902 if (displayPopupMenu
)
906 void ScintillaWX
::DoOnListBox() {
907 AutoCompleteCompleted();
911 void ScintillaWX
::DoOnIdle(wxIdleEvent
& evt
) {
919 //----------------------------------------------------------------------
921 #if wxUSE_DRAG_AND_DROP
922 bool ScintillaWX
::DoDropText(long x
, long y
, const wxString
& data
) {
923 SetDragPosition(invalidPosition
);
925 wxString text
= wxTextBuffer
::Translate(data
,
926 wxConvertEOLMode(pdoc
->eolMode
));
928 // Send an event to allow the drag details to be changed
929 wxStyledTextEvent
evt(wxEVT_STC_DO_DROP
, stc
->GetId());
930 evt
.SetEventObject(stc
);
931 evt
.SetDragResult(dragResult
);
934 evt
.SetPosition(PositionFromLocation(Point(x
,y
)));
935 evt
.SetDragText(text
);
936 stc
->GetEventHandler()->ProcessEvent(evt
);
938 dragResult
= evt
.GetDragResult();
939 if (dragResult
== wxDragMove
|| dragResult
== wxDragCopy
) {
940 DropAt(evt
.GetPosition(),
941 wx2stc(evt
.GetDragText()),
942 dragResult
== wxDragMove
,
943 false); // TODO: rectangular?
950 wxDragResult ScintillaWX
::DoDragEnter(wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
), wxDragResult def
) {
956 wxDragResult ScintillaWX
::DoDragOver(wxCoord x
, wxCoord y
, wxDragResult def
) {
957 SetDragPosition(PositionFromLocation(Point(x
, y
)));
959 // Send an event to allow the drag result to be changed
960 wxStyledTextEvent
evt(wxEVT_STC_DRAG_OVER
, stc
->GetId());
961 evt
.SetEventObject(stc
);
962 evt
.SetDragResult(def
);
965 evt
.SetPosition(PositionFromLocation(Point(x
,y
)));
966 stc
->GetEventHandler()->ProcessEvent(evt
);
968 dragResult
= evt
.GetDragResult();
973 void ScintillaWX
::DoDragLeave() {
974 SetDragPosition(invalidPosition
);
977 //----------------------------------------------------------------------
979 // Force the whole window to be repainted
980 void ScintillaWX
::FullPaint() {
986 void ScintillaWX
::DoScrollToLine(int line
) {
991 void ScintillaWX
::DoScrollToColumn(int column
) {
992 HorizontalScrollTo(column
* vs
.spaceWidth
);
996 void ScintillaWX
::ClipChildren(wxDC
& dc
, PRectangle rect
) {
997 wxRegion
rgn(wxRectFromPRectangle(rect
));
999 wxRect childRect
= ((wxWindow
*)ac
.lb
->GetID())->GetRect();
1000 rgn
.Subtract(childRect
);
1002 if (ct
.inCallTipMode
) {
1003 wxSTCCallTip
* tip
= (wxSTCCallTip
*)ct
.wCallTip
.GetID();
1004 wxRect childRect
= tip
->GetRect();
1005 #if wxUSE_POPUPWIN && wxSTC_USE_POPUP
1006 childRect
.SetPosition(tip
->GetMyPosition());
1008 rgn
.Subtract(childRect
);
1011 dc
.SetClippingRegion(rgn
);
1014 void ScintillaWX
::ClipChildren(wxDC
& WXUNUSED(dc
), PRectangle
WXUNUSED(rect
)) {
1019 void ScintillaWX
::SetUseAntiAliasing(bool useAA
) {
1020 vs
.extraFontFlag
= useAA
;
1021 InvalidateStyleRedraw();
1024 bool ScintillaWX
::GetUseAntiAliasing() {
1025 return vs
.extraFontFlag
;
1028 //----------------------------------------------------------------------
1029 //----------------------------------------------------------------------