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 "wx/textbuf.h" 
  19 #include "wx/dataobj.h" 
  20 #include "wx/clipbrd.h" 
  23 #include "ScintillaWX.h" 
  24 #include "ExternalLexer.h" 
  25 #include "wx/stc/stc.h" 
  30     #include "wx/msw/private.h" 
  33 //---------------------------------------------------------------------- 
  36 class wxSTCTimer 
: public wxTimer 
{ 
  38     wxSTCTimer(ScintillaWX
* swx
) { 
  51 #if wxUSE_DRAG_AND_DROP 
  52 bool wxSTCDropTarget::OnDropText(wxCoord x
, wxCoord y
, const wxString
& data
) { 
  53     return swx
->DoDropText(x
, y
, data
); 
  56 wxDragResult  
wxSTCDropTarget::OnEnter(wxCoord x
, wxCoord y
, wxDragResult def
) { 
  57     return swx
->DoDragEnter(x
, y
, def
); 
  60 wxDragResult  
wxSTCDropTarget::OnDragOver(wxCoord x
, wxCoord y
, wxDragResult def
) { 
  61     return swx
->DoDragOver(x
, y
, def
); 
  64 void  wxSTCDropTarget::OnLeave() { 
  70 #if wxUSE_POPUPWIN && wxSTC_USE_POPUP 
  71 #include <wx/popupwin.h> 
  72 #define wxSTCCallTipBase wxPopupWindow 
  73 #define param2  wxBORDER_NONE  // popup's 2nd param is flags 
  75 #define wxSTCCallTipBase wxWindow 
  76 #define param2 -1 // wxWindow's 2nd param is ID 
  79 #include <wx/dcbuffer.h> 
  81 class wxSTCCallTip 
: public wxSTCCallTipBase 
{ 
  83     wxSTCCallTip(wxWindow
* parent
, CallTip
* ct
, ScintillaWX
* swx
) 
  84         : wxSTCCallTipBase(parent
, param2
), 
  85           m_ct(ct
), m_swx(swx
), m_cx(wxDefaultCoord
), m_cy(wxDefaultCoord
) 
  90 #if wxUSE_POPUPWIN && wxSTC_USE_POPUP && defined(__WXGTK__) 
  91         wxRect rect 
= GetRect(); 
  94         GetParent()->Refresh(false, &rect
); 
  98     bool AcceptsFocus() const { return false; } 
 100     void OnPaint(wxPaintEvent
& WXUNUSED(evt
)) { 
 101         wxBufferedPaintDC 
dc(this); 
 102         Surface
* surfaceWindow 
= Surface::Allocate(); 
 103         surfaceWindow
->Init(&dc
, m_ct
->wDraw
.GetID()); 
 104         m_ct
->PaintCT(surfaceWindow
); 
 105         surfaceWindow
->Release(); 
 106         delete surfaceWindow
; 
 109     void OnFocus(wxFocusEvent
& event
) { 
 110         GetParent()->SetFocus(); 
 114     void OnLeftDown(wxMouseEvent
& event
) { 
 115         wxPoint pt 
= event
.GetPosition(); 
 118         m_swx
->CallTipClick(); 
 121 #if wxUSE_POPUPWIN && wxSTC_USE_POPUP 
 122     virtual void DoSetSize(int x
, int y
, 
 123                            int width
, int height
, 
 124                            int sizeFlags 
= wxSIZE_AUTO
) { 
 125         if (x 
!= wxDefaultCoord
) { 
 127             GetParent()->ClientToScreen(&x
, NULL
); 
 129         if (y 
!= wxDefaultCoord
) { 
 131             GetParent()->ClientToScreen(NULL
, &y
); 
 133         wxSTCCallTipBase::DoSetSize(x
, y
, width
, height
, sizeFlags
); 
 137     wxPoint 
GetMyPosition() { 
 138         return wxPoint(m_cx
, m_cy
); 
 145     DECLARE_EVENT_TABLE() 
 148 BEGIN_EVENT_TABLE(wxSTCCallTip
, wxSTCCallTipBase
) 
 149     EVT_PAINT(wxSTCCallTip::OnPaint
) 
 150     EVT_SET_FOCUS(wxSTCCallTip::OnFocus
) 
 151     EVT_LEFT_DOWN(wxSTCCallTip::OnLeftDown
) 
 155 //---------------------------------------------------------------------- 
 158 static wxTextFileType 
wxConvertEOLMode(int scintillaMode
) 
 162     switch (scintillaMode
) { 
 164             type 
= wxTextFileType_Dos
; 
 168             type 
= wxTextFileType_Mac
; 
 172             type 
= wxTextFileType_Unix
; 
 176             type 
= wxTextBuffer::typeDefault
; 
 181 #endif // wxUSE_DATAOBJ 
 184 //---------------------------------------------------------------------- 
 185 // Constructor/Destructor 
 188 ScintillaWX::ScintillaWX(wxStyledTextCtrl
* win
) { 
 189     capturedMouse 
= false; 
 203 ScintillaWX::~ScintillaWX() { 
 207 //---------------------------------------------------------------------- 
 208 // base class virtuals 
 211 void ScintillaWX::Initialise() { 
 212     //ScintillaBase::Initialise(); 
 213 #if wxUSE_DRAG_AND_DROP 
 214     dropTarget 
= new wxSTCDropTarget
; 
 215     dropTarget
->SetScintilla(this); 
 216     stc
->SetDropTarget(dropTarget
); 
 219     vs
.extraFontFlag 
= false;  // UseAntiAliasing 
 221     vs
.extraFontFlag 
= true;   // UseAntiAliasing 
 226 void ScintillaWX::Finalise() { 
 227     ScintillaBase::Finalise(); 
 230     DestroySystemCaret(); 
 234 void ScintillaWX::StartDrag() { 
 235 #if wxUSE_DRAG_AND_DROP 
 236     wxString dragText 
= stc2wx(drag
.s
, drag
.len
); 
 238     // Send an event to allow the drag text to be changed 
 239     wxStyledTextEvent 
evt(wxEVT_STC_START_DRAG
, stc
->GetId()); 
 240     evt
.SetEventObject(stc
); 
 241     evt
.SetDragText(dragText
); 
 242     evt
.SetDragAllowMove(true); 
 243     evt
.SetPosition(wxMin(stc
->GetSelectionStart(), 
 244                           stc
->GetSelectionEnd())); 
 245     stc
->GetEventHandler()->ProcessEvent(evt
); 
 246     dragText 
= evt
.GetDragText(); 
 248     if (dragText
.Length()) { 
 249         wxDropSource        
source(stc
); 
 250         wxTextDataObject    
data(dragText
); 
 253         source
.SetData(data
); 
 254         dropWentOutside 
= true; 
 255         result 
= source
.DoDragDrop(evt
.GetDragAllowMove()); 
 256         if (result 
== wxDragMove 
&& dropWentOutside
) 
 259         SetDragPosition(invalidPosition
); 
 265 bool ScintillaWX::SetIdle(bool on
) { 
 266     if (idler
.state 
!= on
) { 
 267         // connect or disconnect the EVT_IDLE handler 
 269             stc
->Connect(wxID_ANY
, wxEVT_IDLE
, 
 270                          (wxObjectEventFunction
) (wxEventFunction
) (wxIdleEventFunction
) &wxStyledTextCtrl::OnIdle
); 
 272             stc
->Disconnect(wxID_ANY
, wxEVT_IDLE
, 
 273                             (wxObjectEventFunction
) (wxEventFunction
) (wxIdleEventFunction
) &wxStyledTextCtrl::OnIdle
); 
 280 void ScintillaWX::SetTicking(bool on
) { 
 281     wxSTCTimer
* steTimer
; 
 282     if (timer
.ticking 
!= on
) { 
 285             steTimer 
= new wxSTCTimer(this); 
 286             steTimer
->Start(timer
.tickSize
); 
 287             timer
.tickerID 
= steTimer
; 
 289             steTimer 
= (wxSTCTimer
*)timer
.tickerID
; 
 295     timer
.ticksToWait 
= caret
.period
; 
 299 void ScintillaWX::SetMouseCapture(bool on
) { 
 300     if (mouseDownCaptures
) { 
 301         if (on 
&& !capturedMouse
) 
 303         else if (!on 
&& capturedMouse 
&& stc
->HasCapture()) 
 310 bool ScintillaWX::HaveMouseCapture() { 
 311     return capturedMouse
; 
 315 void ScintillaWX::ScrollText(int linesToMove
) { 
 316     int dy 
= vs
.lineHeight 
* (linesToMove
); 
 317     stc
->ScrollWindow(0, dy
); 
 321 void ScintillaWX::SetVerticalScrollPos() { 
 322     if (stc
->m_vScrollBar 
== NULL
) {  // Use built-in scrollbar 
 323         stc
->SetScrollPos(wxVERTICAL
, topLine
); 
 325     else { // otherwise use the one that's been given to us 
 326         stc
->m_vScrollBar
->SetThumbPosition(topLine
); 
 330 void ScintillaWX::SetHorizontalScrollPos() { 
 331     if (stc
->m_hScrollBar 
== NULL
) {  // Use built-in scrollbar 
 332         stc
->SetScrollPos(wxHORIZONTAL
, xOffset
); 
 334     else { // otherwise use the one that's been given to us 
 335         stc
->m_hScrollBar
->SetThumbPosition(xOffset
); 
 340 const int H_SCROLL_STEP 
= 20; 
 342 bool ScintillaWX::ModifyScrollBars(int nMax
, int nPage
) { 
 343     bool modified 
= false; 
 346     if (!verticalScrollBarVisible
) 
 349     // Check the vertical scrollbar 
 350     if (stc
->m_vScrollBar 
== NULL
) {  // Use built-in scrollbar 
 351         int  sbMax    
= stc
->GetScrollRange(wxVERTICAL
); 
 352         int  sbThumb  
= stc
->GetScrollThumb(wxVERTICAL
); 
 353         int  sbPos    
= stc
->GetScrollPos(wxVERTICAL
); 
 354         if (sbMax 
!= vertEnd 
|| sbThumb 
!= nPage
) { 
 355             stc
->SetScrollbar(wxVERTICAL
, sbPos
, nPage
, vertEnd
+1); 
 359     else { // otherwise use the one that's been given to us 
 360         int  sbMax    
= stc
->m_vScrollBar
->GetRange(); 
 361         int  sbPage   
= stc
->m_vScrollBar
->GetPageSize(); 
 362         int  sbPos    
= stc
->m_vScrollBar
->GetThumbPosition(); 
 363         if (sbMax 
!= vertEnd 
|| sbPage 
!= nPage
) { 
 364             stc
->m_vScrollBar
->SetScrollbar(sbPos
, nPage
, vertEnd
+1, nPage
); 
 370     // Check the horizontal scrollbar 
 371     PRectangle rcText 
= GetTextRectangle(); 
 372     int horizEnd 
= scrollWidth
; 
 375     if (!horizontalScrollBarVisible 
|| (wrapState 
!= eWrapNone
)) 
 377     int pageWidth 
= rcText
.Width(); 
 379     if (stc
->m_hScrollBar 
== NULL
) {  // Use built-in scrollbar 
 380         int sbMax    
= stc
->GetScrollRange(wxHORIZONTAL
); 
 381         int sbThumb  
= stc
->GetScrollThumb(wxHORIZONTAL
); 
 382         int sbPos    
= stc
->GetScrollPos(wxHORIZONTAL
); 
 383         if ((sbMax 
!= horizEnd
) || (sbThumb 
!= pageWidth
) || (sbPos 
!= 0)) { 
 384             stc
->SetScrollbar(wxHORIZONTAL
, sbPos
, pageWidth
, horizEnd
); 
 386             if (scrollWidth 
< pageWidth
) { 
 387                 HorizontalScrollTo(0); 
 391     else { // otherwise use the one that's been given to us 
 392         int sbMax    
= stc
->m_hScrollBar
->GetRange(); 
 393         int sbThumb  
= stc
->m_hScrollBar
->GetPageSize(); 
 394         int sbPos    
= stc
->m_hScrollBar
->GetThumbPosition(); 
 395         if ((sbMax 
!= horizEnd
) || (sbThumb 
!= pageWidth
) || (sbPos 
!= 0)) { 
 396             stc
->m_hScrollBar
->SetScrollbar(sbPos
, pageWidth
, horizEnd
, pageWidth
); 
 398             if (scrollWidth 
< pageWidth
) { 
 399                 HorizontalScrollTo(0); 
 408 void ScintillaWX::NotifyChange() { 
 413 void ScintillaWX::NotifyParent(SCNotification scn
) { 
 414     stc
->NotifyParent(&scn
); 
 418 // This method is overloaded from ScintillaBase in order to prevent the 
 419 // AutoComplete window from being destroyed when it gets the focus.  There is 
 420 // a side effect that the AutoComp will also not be destroyed when switching 
 421 // to another window, but I think that is okay. 
 422 void ScintillaWX::CancelModes() { 
 424         AutoCompleteCancel(); 
 426     Editor::CancelModes(); 
 431 void ScintillaWX::Copy() { 
 432     if (currentPos 
!= anchor
) { 
 434         CopySelectionRange(&st
); 
 440 void ScintillaWX::Paste() { 
 441     pdoc
->BeginUndoAction(); 
 445     wxTextDataObject data
; 
 446     bool gotData 
= false; 
 448     if (wxTheClipboard
->Open()) { 
 449         wxTheClipboard
->UsePrimarySelection(false); 
 450         gotData 
= wxTheClipboard
->GetData(data
); 
 451         wxTheClipboard
->Close(); 
 454         wxString   text 
= wxTextBuffer::Translate(data
.GetText(), 
 455                                                   wxConvertEOLMode(pdoc
->eolMode
)); 
 456         wxWX2MBbuf buf 
= (wxWX2MBbuf
)wx2stc(text
); 
 457         int        len 
= strlen(buf
); 
 458         pdoc
->InsertString(currentPos
, buf
, len
); 
 459         SetEmptySelection(currentPos 
+ len
); 
 461 #endif // wxUSE_DATAOBJ 
 463     pdoc
->EndUndoAction(); 
 469 void ScintillaWX::CopyToClipboard(const SelectionText
& st
) { 
 471     if (wxTheClipboard
->Open()) { 
 472         wxTheClipboard
->UsePrimarySelection(false); 
 473         wxString text 
= wxTextBuffer::Translate(stc2wx(st
.s
, st
.len
-1)); 
 474         wxTheClipboard
->SetData(new wxTextDataObject(text
)); 
 475         wxTheClipboard
->Close(); 
 479 #endif // wxUSE_CLIPBOARD 
 483 bool ScintillaWX::CanPaste() { 
 485     bool canPaste 
= false; 
 488     if (Editor::CanPaste()) { 
 489         didOpen 
= !wxTheClipboard
->IsOpened(); 
 491             wxTheClipboard
->Open(); 
 493         if (wxTheClipboard
->IsOpened()) { 
 494             wxTheClipboard
->UsePrimarySelection(false); 
 495             canPaste 
= wxTheClipboard
->IsSupported(wxUSE_UNICODE 
? wxDF_UNICODETEXT 
: wxDF_TEXT
); 
 497                 wxTheClipboard
->Close(); 
 503 #endif // wxUSE_CLIPBOARD 
 506 void ScintillaWX::CreateCallTipWindow(PRectangle
) { 
 507     if (! ct
.wCallTip
.Created() ) { 
 508         ct
.wCallTip 
= new wxSTCCallTip(stc
, &ct
, this); 
 509         ct
.wDraw 
= ct
.wCallTip
; 
 514 void ScintillaWX::AddToPopUp(const char *label
, int cmd
, bool enabled
) { 
 516         ((wxMenu
*)popup
.GetID())->AppendSeparator(); 
 518         ((wxMenu
*)popup
.GetID())->Append(cmd
, wxGetTranslation(stc2wx(label
))); 
 521         ((wxMenu
*)popup
.GetID())->Enable(cmd
, enabled
); 
 525 // This is called by the Editor base class whenever something is selected 
 526 void ScintillaWX::ClaimSelection() { 
 528     // Until wxGTK is able to support using both the primary selection and the 
 529     // clipboard at the same time I think it causes more problems than it is 
 530     // worth to implement this method.  Selecting text should not clear the 
 531     // clipboard.  --Robin 
 533     // Put the selected text in the PRIMARY selection 
 534     if (currentPos 
!= anchor
) { 
 536         CopySelectionRange(&st
); 
 537         if (wxTheClipboard
->Open()) { 
 538             wxTheClipboard
->UsePrimarySelection(true); 
 539             wxString text 
= stc2wx(st
.s
, st
.len
); 
 540             wxTheClipboard
->SetData(new wxTextDataObject(text
)); 
 541             wxTheClipboard
->UsePrimarySelection(false); 
 542             wxTheClipboard
->Close(); 
 550 void ScintillaWX::UpdateSystemCaret() { 
 553         if (HasCaretSizeChanged()) { 
 554             DestroySystemCaret(); 
 557         Point pos 
= LocationFromPosition(currentPos
); 
 558         ::SetCaretPos(pos
.x
, pos
.y
); 
 564 bool ScintillaWX::HasCaretSizeChanged() { 
 566     if (( (0 != vs
.caretWidth
) && (sysCaretWidth 
!= vs
.caretWidth
) ) 
 567         || (0 != vs
.lineHeight
) && (sysCaretHeight 
!= vs
.lineHeight
)) { 
 574 bool ScintillaWX::CreateSystemCaret() { 
 576     sysCaretWidth 
= vs
.caretWidth
; 
 577     if (0 == sysCaretWidth
) { 
 580     sysCaretHeight 
= vs
.lineHeight
; 
 581     int bitmapSize 
= (((sysCaretWidth 
+ 15) & ~15) >> 3) * sysCaretHeight
; 
 582     char *bits 
= new char[bitmapSize
]; 
 583     memset(bits
, 0, bitmapSize
); 
 584     sysCaretBitmap 
= ::CreateBitmap(sysCaretWidth
, sysCaretHeight
, 1, 
 585                                     1, reinterpret_cast<BYTE 
*>(bits
)); 
 587     BOOL retval 
= ::CreateCaret(GetHwndOf(stc
), sysCaretBitmap
, 
 588                                 sysCaretWidth
, sysCaretHeight
); 
 589     ::ShowCaret(GetHwndOf(stc
)); 
 596 bool ScintillaWX::DestroySystemCaret() { 
 598     ::HideCaret(GetHwndOf(stc
)); 
 599     BOOL retval 
= ::DestroyCaret(); 
 600     if (sysCaretBitmap
) { 
 601         ::DeleteObject(sysCaretBitmap
); 
 611 //---------------------------------------------------------------------- 
 614 long ScintillaWX::DefWndProc(unsigned int /*iMessage*/, unsigned long /*wParam*/, long /*lParam*/) { 
 618 long ScintillaWX::WndProc(unsigned int iMessage
, unsigned long wParam
, long lParam
) { 
 620       case SCI_CALLTIPSHOW
: { 
 621           // NOTE: This is copied here from scintilla/src/ScintillaBase.cxx 
 622           // because of the little tweak that needs done below for wxGTK. 
 623           // When updating new versions double check that this is still 
 624           // needed, and that any new code there is copied here too. 
 625           Point pt 
= LocationFromPosition(wParam
); 
 626           char* defn 
= reinterpret_cast<char *>(lParam
); 
 627           AutoCompleteCancel(); 
 628           pt
.y 
+= vs
.lineHeight
; 
 629           PRectangle rc 
= ct
.CallTipStart(currentPos
, pt
, 
 631                                           vs
.styles
[STYLE_DEFAULT
].fontName
, 
 632                                           vs
.styles
[STYLE_DEFAULT
].sizeZoomed
, 
 634                                           vs
.styles
[STYLE_DEFAULT
].characterSet
, 
 636           // If the call-tip window would be out of the client 
 637           // space, adjust so it displays above the text. 
 638           PRectangle rcClient 
= GetClientRectangle(); 
 639           if (rc
.bottom 
> rcClient
.bottom
) { 
 641               int offset 
= int(vs
.lineHeight 
* 1.25)  + rc
.Height(); 
 643               int offset 
= vs
.lineHeight 
+ rc
.Height(); 
 648           // Now display the window. 
 649           CreateCallTipWindow(rc
); 
 650           ct
.wCallTip
.SetPositionRelative(rc
, wMain
); 
 656       case SCI_LOADLEXERLIBRARY
: 
 657             LexerManager::GetInstance()->Load((const char*)lParam
); 
 662           return ScintillaBase::WndProc(iMessage
, wParam
, lParam
); 
 669 //---------------------------------------------------------------------- 
 672 void ScintillaWX::DoPaint(wxDC
* dc
, wxRect rect
) { 
 674     paintState 
= painting
; 
 675     Surface
* surfaceWindow 
= Surface::Allocate(); 
 676     surfaceWindow
->Init(dc
, wMain
.GetID()); 
 677     rcPaint 
= PRectangleFromwxRect(rect
); 
 678     PRectangle rcClient 
= GetClientRectangle(); 
 679     paintingAllText 
= rcPaint
.Contains(rcClient
); 
 681     ClipChildren(*dc
, rcPaint
); 
 682     Paint(surfaceWindow
, rcPaint
); 
 684     delete surfaceWindow
; 
 685     if (paintState 
== paintAbandoned
) { 
 686         // Painting area was insufficient to cover new styling or brace 
 687         // highlight positions 
 690     paintState 
= notPainting
; 
 694 void ScintillaWX::DoHScroll(int type
, int pos
) { 
 696     PRectangle rcText 
= GetTextRectangle(); 
 697     int pageWidth 
= rcText
.Width() * 2 / 3; 
 698     if (type 
== wxEVT_SCROLLWIN_LINEUP 
|| type 
== wxEVT_SCROLL_LINEUP
) 
 699         xPos 
-= H_SCROLL_STEP
; 
 700     else if (type 
== wxEVT_SCROLLWIN_LINEDOWN 
|| type 
== wxEVT_SCROLL_LINEDOWN
) 
 701         xPos 
+= H_SCROLL_STEP
; 
 702     else if (type 
== wxEVT_SCROLLWIN_PAGEUP 
|| type 
== wxEVT_SCROLL_PAGEUP
) 
 704     else if (type 
== wxEVT_SCROLLWIN_PAGEDOWN 
|| type 
== wxEVT_SCROLL_PAGEDOWN
) { 
 706         if (xPos 
> scrollWidth 
- rcText
.Width()) { 
 707             xPos 
= scrollWidth 
- rcText
.Width(); 
 710     else if (type 
== wxEVT_SCROLLWIN_TOP 
|| type 
== wxEVT_SCROLL_TOP
) 
 712     else if (type 
== wxEVT_SCROLLWIN_BOTTOM 
|| type 
== wxEVT_SCROLL_BOTTOM
) 
 714     else if (type 
== wxEVT_SCROLLWIN_THUMBTRACK 
|| type 
== wxEVT_SCROLL_THUMBTRACK
) 
 717     HorizontalScrollTo(xPos
); 
 720 void ScintillaWX::DoVScroll(int type
, int pos
) { 
 721     int topLineNew 
= topLine
; 
 722     if (type 
== wxEVT_SCROLLWIN_LINEUP 
|| type 
== wxEVT_SCROLL_LINEUP
) 
 724     else if (type 
== wxEVT_SCROLLWIN_LINEDOWN 
|| type 
== wxEVT_SCROLL_LINEDOWN
) 
 726     else if (type 
==  wxEVT_SCROLLWIN_PAGEUP 
|| type 
== wxEVT_SCROLL_PAGEUP
) 
 727         topLineNew 
-= LinesToScroll(); 
 728     else if (type 
==  wxEVT_SCROLLWIN_PAGEDOWN 
|| type 
== wxEVT_SCROLL_PAGEDOWN
) 
 729         topLineNew 
+= LinesToScroll(); 
 730     else if (type 
==  wxEVT_SCROLLWIN_TOP 
|| type 
== wxEVT_SCROLL_TOP
) 
 732     else if (type 
==  wxEVT_SCROLLWIN_BOTTOM 
|| type 
== wxEVT_SCROLL_BOTTOM
) 
 733         topLineNew 
= MaxScrollPos(); 
 734     else if (type 
==   wxEVT_SCROLLWIN_THUMBTRACK 
|| type 
== wxEVT_SCROLL_THUMBTRACK
) 
 737     ScrollTo(topLineNew
); 
 740 void ScintillaWX::DoMouseWheel(int rotation
, int delta
, 
 741                                int linesPerAction
, int ctrlDown
, 
 742                                bool isPageScroll 
) { 
 743     int topLineNew 
= topLine
; 
 746     if (ctrlDown
) {  // Zoom the fonts if Ctrl key down 
 748             KeyCommand(SCI_ZOOMIN
); 
 751             KeyCommand(SCI_ZOOMOUT
); 
 754     else { // otherwise just scroll the window 
 757         wheelRotation 
+= rotation
; 
 758         lines 
= wheelRotation 
/ delta
; 
 759         wheelRotation 
-= lines 
* delta
; 
 762                 lines 
= lines 
* LinesOnScreen();  // lines is either +1 or -1 
 764                 lines 
*= linesPerAction
; 
 766             ScrollTo(topLineNew
); 
 772 void ScintillaWX::DoSize(int WXUNUSED(width
), int WXUNUSED(height
)) { 
 776 void ScintillaWX::DoLoseFocus(){ 
 778     SetFocusState(false); 
 780     DestroySystemCaret(); 
 783 void ScintillaWX::DoGainFocus(){ 
 787     DestroySystemCaret(); 
 791 void ScintillaWX::DoSysColourChange() { 
 792     InvalidateStyleData(); 
 795 void ScintillaWX::DoLeftButtonDown(Point pt
, unsigned int curTime
, bool shift
, bool ctrl
, bool alt
) { 
 796     ButtonDown(pt
, curTime
, shift
, ctrl
, alt
); 
 799 void ScintillaWX::DoLeftButtonUp(Point pt
, unsigned int curTime
, bool ctrl
) { 
 800     ButtonUp(pt
, curTime
, ctrl
); 
 803 void ScintillaWX::DoLeftButtonMove(Point pt
) { 
 808 void ScintillaWX::DoMiddleButtonUp(Point pt
) { 
 809     // Set the current position to the mouse click point and 
 810     // then paste in the PRIMARY selection, if any.  wxGTK only. 
 811     int newPos 
= PositionFromLocation(pt
); 
 812     MovePositionTo(newPos
, noSel
, true); 
 814     pdoc
->BeginUndoAction(); 
 815     wxTextDataObject data
; 
 816     bool gotData 
= false; 
 817     if (wxTheClipboard
->Open()) { 
 818         wxTheClipboard
->UsePrimarySelection(true); 
 819         gotData 
= wxTheClipboard
->GetData(data
); 
 820         wxTheClipboard
->UsePrimarySelection(false); 
 821         wxTheClipboard
->Close(); 
 824         wxString   text 
= wxTextBuffer::Translate(data
.GetText(), 
 825                                                   wxConvertEOLMode(pdoc
->eolMode
)); 
 826         wxWX2MBbuf buf 
= (wxWX2MBbuf
)wx2stc(text
); 
 827         int        len 
= strlen(buf
); 
 828         pdoc
->InsertString(currentPos
, buf
, len
); 
 829         SetEmptySelection(currentPos 
+ len
); 
 831     pdoc
->EndUndoAction(); 
 835     ShowCaretAtCurrentPosition(); 
 836     EnsureCaretVisible(); 
 839 void ScintillaWX::DoMiddleButtonUp(Point 
WXUNUSED(pt
)) { 
 844 void ScintillaWX::DoAddChar(int key
) { 
 847     wszChars
[0] = (wxChar
)key
; 
 849     wxWX2MBbuf buf 
= (wxWX2MBbuf
)wx2stc(wszChars
); 
 850     AddCharUTF((char*)buf
.data(), strlen(buf
)); 
 857 int  ScintillaWX::DoKeyDown(const wxKeyEvent
& evt
, bool* consumed
) 
 859     int key 
= evt
.GetKeyCode(); 
 860     bool shift 
= evt
.ShiftDown(), 
 861          ctrl  
= evt
.ControlDown(), 
 864     if (ctrl 
&& key 
>= 1 && key 
<= 26 && key 
!= WXK_BACK
) 
 868     case WXK_DOWN
:              key 
= SCK_DOWN
;     break; 
 869     case WXK_UP
:                key 
= SCK_UP
;       break; 
 870     case WXK_LEFT
:              key 
= SCK_LEFT
;     break; 
 871     case WXK_RIGHT
:             key 
= SCK_RIGHT
;    break; 
 872     case WXK_HOME
:              key 
= SCK_HOME
;     break; 
 873     case WXK_END
:               key 
= SCK_END
;      break; 
 874     case WXK_PAGEUP
:            // fall through 
 875     case WXK_PRIOR
:             key 
= SCK_PRIOR
;    break; 
 876     case WXK_PAGEDOWN
:          // fall through 
 877     case WXK_NEXT
:              key 
= SCK_NEXT
;     break; 
 878     case WXK_DELETE
:            key 
= SCK_DELETE
;   break; 
 879     case WXK_INSERT
:            key 
= SCK_INSERT
;   break; 
 880     case WXK_ESCAPE
:            key 
= SCK_ESCAPE
;   break; 
 881     case WXK_BACK
:              key 
= SCK_BACK
;     break; 
 882     case WXK_TAB
:               key 
= SCK_TAB
;      break; 
 883     case WXK_NUMPAD_ENTER
:      // fall through 
 884     case WXK_RETURN
:            key 
= SCK_RETURN
;   break; 
 885     case WXK_ADD
:               // fall through 
 886     case WXK_NUMPAD_ADD
:        key 
= SCK_ADD
;      break; 
 887     case WXK_SUBTRACT
:          // fall through 
 888     case WXK_NUMPAD_SUBTRACT
:   key 
= SCK_SUBTRACT
; break; 
 889     case WXK_DIVIDE
:            // fall through 
 890     case WXK_NUMPAD_DIVIDE
:     key 
= SCK_DIVIDE
;   break; 
 891     case WXK_CONTROL
:           key 
= 0; break; 
 892     case WXK_ALT
:               key 
= 0; break; 
 893     case WXK_SHIFT
:             key 
= 0; break; 
 894     case WXK_MENU
:              key 
= 0; break; 
 898     if ( evt
.MetaDown() ) { 
 899         // check for a few common Mac Meta-key combos and remap them to Ctrl 
 906         case 'A':       // Select All 
 913     int rv 
= KeyDown(key
, shift
, ctrl
, alt
, consumed
); 
 922 void ScintillaWX::DoCommand(int ID
) { 
 927 void ScintillaWX::DoContextMenu(Point pt
) { 
 928     if (displayPopupMenu
) 
 932 void ScintillaWX::DoOnListBox() { 
 933     AutoCompleteCompleted(); 
 937 void ScintillaWX::DoOnIdle(wxIdleEvent
& evt
) { 
 945 //---------------------------------------------------------------------- 
 947 #if wxUSE_DRAG_AND_DROP 
 948 bool ScintillaWX::DoDropText(long x
, long y
, const wxString
& data
) { 
 949     SetDragPosition(invalidPosition
); 
 951     wxString text 
= wxTextBuffer::Translate(data
, 
 952                                             wxConvertEOLMode(pdoc
->eolMode
)); 
 954     // Send an event to allow the drag details to be changed 
 955     wxStyledTextEvent 
evt(wxEVT_STC_DO_DROP
, stc
->GetId()); 
 956     evt
.SetEventObject(stc
); 
 957     evt
.SetDragResult(dragResult
); 
 960     evt
.SetPosition(PositionFromLocation(Point(x
,y
))); 
 961     evt
.SetDragText(text
); 
 962     stc
->GetEventHandler()->ProcessEvent(evt
); 
 964     dragResult 
= evt
.GetDragResult(); 
 965     if (dragResult 
== wxDragMove 
|| dragResult 
== wxDragCopy
) { 
 966         DropAt(evt
.GetPosition(), 
 967                wx2stc(evt
.GetDragText()), 
 968                dragResult 
== wxDragMove
, 
 969                false); // TODO: rectangular? 
 976 wxDragResult 
ScintillaWX::DoDragEnter(wxCoord 
WXUNUSED(x
), wxCoord 
WXUNUSED(y
), wxDragResult def
) { 
 982 wxDragResult 
ScintillaWX::DoDragOver(wxCoord x
, wxCoord y
, wxDragResult def
) { 
 983     SetDragPosition(PositionFromLocation(Point(x
, y
))); 
 985     // Send an event to allow the drag result to be changed 
 986     wxStyledTextEvent 
evt(wxEVT_STC_DRAG_OVER
, stc
->GetId()); 
 987     evt
.SetEventObject(stc
); 
 988     evt
.SetDragResult(def
); 
 991     evt
.SetPosition(PositionFromLocation(Point(x
,y
))); 
 992     stc
->GetEventHandler()->ProcessEvent(evt
); 
 994     dragResult 
= evt
.GetDragResult(); 
 999 void ScintillaWX::DoDragLeave() { 
1000     SetDragPosition(invalidPosition
); 
1003 //---------------------------------------------------------------------- 
1005 // Force the whole window to be repainted 
1006 void ScintillaWX::FullPaint() { 
1008     stc
->Refresh(false); 
1014 void ScintillaWX::DoScrollToLine(int line
) { 
1019 void ScintillaWX::DoScrollToColumn(int column
) { 
1020     HorizontalScrollTo(column 
* vs
.spaceWidth
); 
1023 // wxGTK doesn't appear to need this explicit clipping code any longer, but I 
1024 // will leave it here commented out for a while just in case... 
1025 void ScintillaWX::ClipChildren(wxDC
& WXUNUSED(dc
), PRectangle 
WXUNUSED(rect
)) 
1027 //     wxRegion rgn(wxRectFromPRectangle(rect)); 
1028 //     if (ac.Active()) { 
1029 //         wxRect childRect = ((wxWindow*)ac.lb->GetID())->GetRect(); 
1030 //         rgn.Subtract(childRect); 
1032 //     if (ct.inCallTipMode) { 
1033 //         wxSTCCallTip* tip = (wxSTCCallTip*)ct.wCallTip.GetID(); 
1034 //         wxRect childRect = tip->GetRect(); 
1035 // #if wxUSE_POPUPWIN && wxSTC_USE_POPUP 
1036 //         childRect.SetPosition(tip->GetMyPosition()); 
1038 //         rgn.Subtract(childRect); 
1040 //     dc.SetClippingRegion(rgn); 
1044 void ScintillaWX::SetUseAntiAliasing(bool useAA
) { 
1045     vs
.extraFontFlag 
= useAA
; 
1046     InvalidateStyleRedraw(); 
1049 bool ScintillaWX::GetUseAntiAliasing() { 
1050     return vs
.extraFontFlag
; 
1053 //---------------------------------------------------------------------- 
1054 //----------------------------------------------------------------------