+bool wxRichTextCtrl::SetFocusObject(wxRichTextParagraphLayoutBox* obj, bool setCaretPosition)
+{
+ if (obj && !obj->AcceptsFocus())
+ return false;
+
+ wxRichTextParagraphLayoutBox* oldContainer = GetFocusObject();
+ bool changingContainer = (m_focusObject != obj);
+
+ if (changingContainer && HasSelection())
+ SelectNone();
+
+ m_focusObject = obj;
+
+ if (!obj)
+ m_focusObject = & m_buffer;
+
+ if (setCaretPosition && changingContainer)
+ {
+ m_selection.Reset();
+ m_selectionAnchor = -2;
+ m_selectionAnchorObject = NULL;
+ m_selectionState = wxRichTextCtrlSelectionState_Normal;
+
+ long pos = -1;
+
+ m_caretAtLineStart = false;
+ MoveCaret(pos, m_caretAtLineStart);
+ SetDefaultStyleToCursorStyle();
+
+ wxRichTextEvent cmdEvent(
+ wxEVT_RICHTEXT_FOCUS_OBJECT_CHANGED,
+ GetId());
+ cmdEvent.SetEventObject(this);
+ cmdEvent.SetPosition(m_caretPosition+1);
+ cmdEvent.SetOldContainer(oldContainer);
+ cmdEvent.SetContainer(m_focusObject);
+
+ GetEventHandler()->ProcessEvent(cmdEvent);
+ }
+ return true;
+}
+
+#if wxUSE_DRAG_AND_DROP
+void wxRichTextCtrl::OnDrop(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult def, wxDataObject* DataObj)
+{
+ m_preDrag = false;
+
+ if ((def != wxDragCopy) && (def != wxDragMove))
+ {
+ return;
+ }
+
+ if (!GetSelection().IsValid())
+ {
+ return;
+ }
+
+ wxRichTextParagraphLayoutBox* originContainer = GetSelection().GetContainer();
+ wxRichTextParagraphLayoutBox* destContainer = GetFocusObject(); // This will be the drop container, not necessarily the same as the origin one
+
+ wxRichTextBuffer* richTextBuffer = ((wxRichTextBufferDataObject*)DataObj)->GetRichTextBuffer();
+ if (richTextBuffer)
+ {
+ long position = GetCaretPosition();
+ wxRichTextRange selectionrange = GetInternalSelectionRange();
+ if (selectionrange.Contains(position) && (def == wxDragMove))
+ {
+ // It doesn't make sense to move onto itself
+ return;
+ }
+
+ // If we're moving, and the data is being moved forward, we need to drop first, then delete the selection
+ // If moving backwards, we need to delete then drop. If we're copying (or doing nothing) we don't delete anyway
+ bool DeleteAfter = (def == wxDragMove) && (position > selectionrange.GetEnd());
+ if ((def == wxDragMove) && !DeleteAfter)
+ {
+ // We can't use e.g. DeleteSelectedContent() as it uses the focus container
+ originContainer->DeleteRangeWithUndo(selectionrange, this, &GetBuffer());
+ }
+
+ destContainer->InsertParagraphsWithUndo(&GetBuffer(), position+1, *richTextBuffer, this, 0);
+ ShowPosition(position + richTextBuffer->GetOwnRange().GetEnd());
+
+ delete richTextBuffer;
+
+ if (DeleteAfter)
+ {
+ // We can't use e.g. DeleteSelectedContent() as it uses the focus container
+ originContainer->DeleteRangeWithUndo(selectionrange, this, &GetBuffer());
+ }
+
+ SelectNone();
+ Refresh();
+ }
+}
+#endif // wxUSE_DRAG_AND_DROP
+
+
+#if wxUSE_DRAG_AND_DROP
+bool wxRichTextDropSource::GiveFeedback(wxDragResult WXUNUSED(effect))
+{
+ wxCHECK_MSG(m_rtc, false, wxT("NULL m_rtc"));
+
+ long position = 0;
+ int hit = 0;
+ wxRichTextObject* hitObj = NULL;
+ wxRichTextParagraphLayoutBox* container = m_rtc->FindContainerAtPoint(m_rtc->GetUnscaledPoint(m_rtc->ScreenToClient(wxGetMousePosition())), position, hit, hitObj);
+
+ if (!(hit & wxRICHTEXT_HITTEST_NONE) && container && container->AcceptsFocus())
+ {
+ m_rtc->StoreFocusObject(container);
+ m_rtc->SetCaretPositionAfterClick(container, position, hit);
+ }
+
+ return false; // so that the base-class sets a cursor
+}
+#endif // wxUSE_DRAG_AND_DROP
+
+bool wxRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox& WXUNUSED(container), const wxRichTextRange& WXUNUSED(range)) const
+{
+ return true;
+}
+
+bool wxRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox& WXUNUSED(container), long WXUNUSED(pos)) const
+{
+ return true;
+}
+
+void wxRichTextCtrl::EnableVerticalScrollbar(bool enable)
+{
+ m_verticalScrollbarEnabled = enable;
+ SetupScrollbars();
+}
+
+void wxRichTextCtrl::SetFontScale(double fontScale, bool refresh)
+{
+ GetBuffer().SetFontScale(fontScale);
+ if (refresh)
+ {
+ GetBuffer().Invalidate(wxRICHTEXT_ALL);
+ Refresh();
+ }
+}
+
+void wxRichTextCtrl::SetDimensionScale(double dimScale, bool refresh)
+{
+ GetBuffer().SetDimensionScale(dimScale);
+ if (refresh)
+ {
+ GetBuffer().Invalidate(wxRICHTEXT_ALL);
+ Refresh();
+ }
+}
+
+// Sets an overall scale factor for displaying and editing the content.
+void wxRichTextCtrl::SetScale(double scale, bool refresh)
+{
+ m_scale = scale;
+ if (refresh)
+ {
+ GetBuffer().Invalidate(wxRICHTEXT_ALL);
+ Refresh();
+ }
+}
+
+// Get an unscaled point
+wxPoint wxRichTextCtrl::GetUnscaledPoint(const wxPoint& pt) const
+{
+ if (GetScale() == 1.0)
+ return pt;
+ else
+ return wxPoint((int) (0.5 + double(pt.x) / GetScale()), (int) (0.5 + double(pt.y) / GetScale()));
+}
+
+// Get a scaled point
+wxPoint wxRichTextCtrl::GetScaledPoint(const wxPoint& pt) const
+{
+ if (GetScale() == 1.0)
+ return pt;
+ else
+ return wxPoint((int) (0.5 + double(pt.x) * GetScale()), (int) (0.5 + double(pt.y) * GetScale()));
+}
+
+// Get an unscaled size
+wxSize wxRichTextCtrl::GetUnscaledSize(const wxSize& sz) const
+{
+ if (GetScale() == 1.0)
+ return sz;
+ else
+ return wxSize((int) (0.5 + double(sz.x) / GetScale()), (int) (0.5 + double(sz.y) / GetScale()));
+}
+
+// Get a scaled size
+wxSize wxRichTextCtrl::GetScaledSize(const wxSize& sz) const
+{
+ if (GetScale() == 1.0)
+ return sz;
+ else
+ return wxSize((int) (0.5 + double(sz.x) * GetScale()), (int) (0.5 + double(sz.y) * GetScale()));
+}
+
+// Get an unscaled rect
+wxRect wxRichTextCtrl::GetUnscaledRect(const wxRect& rect) const
+{
+ if (GetScale() == 1.0)
+ return rect;
+ else
+ return wxRect((int) (0.5 + double(rect.x) / GetScale()), (int) (0.5 + double(rect.y) / GetScale()),
+ (int) (0.5 + double(rect.width) / GetScale()), (int) (0.5 + double(rect.height) / GetScale()));
+}
+
+// Get a scaled rect
+wxRect wxRichTextCtrl::GetScaledRect(const wxRect& rect) const
+{
+ if (GetScale() == 1.0)
+ return rect;
+ else
+ return wxRect((int) (0.5 + double(rect.x) * GetScale()), (int) (0.5 + double(rect.y) * GetScale()),
+ (int) (0.5 + double(rect.width) * GetScale()), (int) (0.5 + double(rect.height) * GetScale()));
+}
+
+#if wxRICHTEXT_USE_OWN_CARET
+
+// ----------------------------------------------------------------------------
+// initialization and destruction
+// ----------------------------------------------------------------------------
+
+void wxRichTextCaret::Init()
+{
+ m_hasFocus = true;
+ m_refreshEnabled = true;
+
+ m_xOld =
+ m_yOld = -1;
+ m_richTextCtrl = NULL;
+ m_needsUpdate = false;
+ m_flashOn = true;
+}
+
+wxRichTextCaret::~wxRichTextCaret()
+{
+ if (m_timer.IsRunning())
+ m_timer.Stop();
+}
+
+// ----------------------------------------------------------------------------
+// showing/hiding/moving the caret (base class interface)
+// ----------------------------------------------------------------------------
+
+void wxRichTextCaret::DoShow()
+{
+ m_flashOn = true;
+
+ if (!m_timer.IsRunning() && GetBlinkTime() > 0)
+ m_timer.Start(GetBlinkTime());
+
+ Refresh();
+}
+
+void wxRichTextCaret::DoHide()
+{
+ if (m_timer.IsRunning())
+ m_timer.Stop();
+
+ Refresh();
+}
+
+void wxRichTextCaret::DoMove()
+{
+ if (IsVisible())
+ {
+ Refresh();
+
+ if (m_xOld != -1 && m_yOld != -1)
+ {
+ if (m_richTextCtrl && m_refreshEnabled)
+ {
+ wxRect rect(wxPoint(m_xOld, m_yOld), GetSize());
+ wxRect scaledRect = m_richTextCtrl->GetScaledRect(rect);
+ m_richTextCtrl->RefreshRect(scaledRect, false);
+ }
+ }
+ }
+
+ m_xOld = m_x;
+ m_yOld = m_y;
+}
+
+void wxRichTextCaret::DoSize()
+{
+ int countVisible = m_countVisible;
+ if (countVisible > 0)
+ {
+ m_countVisible = 0;
+ DoHide();
+ }
+
+ if (countVisible > 0)
+ {
+ m_countVisible = countVisible;
+ DoShow();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// handling the focus
+// ----------------------------------------------------------------------------
+
+void wxRichTextCaret::OnSetFocus()
+{
+ m_hasFocus = true;
+
+ if ( IsVisible() )
+ Refresh();
+}
+
+void wxRichTextCaret::OnKillFocus()
+{
+ m_hasFocus = false;
+}
+
+// ----------------------------------------------------------------------------
+// drawing the caret
+// ----------------------------------------------------------------------------
+
+void wxRichTextCaret::Refresh()
+{
+ if (m_richTextCtrl && m_refreshEnabled)
+ {
+ wxRect rect(GetPosition(), GetSize());
+ wxRect rectScaled = m_richTextCtrl->GetScaledRect(rect);
+ m_richTextCtrl->RefreshRect(rectScaled, false);
+ }
+}
+
+void wxRichTextCaret::DoDraw(wxDC *dc)
+{
+ wxBrush brush(m_caretBrush);
+ wxPen pen(m_caretPen);
+ if (m_richTextCtrl && m_richTextCtrl->GetBasicStyle().HasTextColour())
+ {
+ brush = wxBrush(m_richTextCtrl->GetBasicStyle().GetTextColour());
+ pen = wxPen(m_richTextCtrl->GetBasicStyle().GetTextColour());
+ }
+ dc->SetBrush((m_hasFocus ? brush : *wxTRANSPARENT_BRUSH));
+ dc->SetPen(pen);
+
+ wxPoint pt(m_x, m_y);
+
+ if (m_richTextCtrl)
+ {
+ pt = m_richTextCtrl->GetLogicalPoint(pt);
+ }
+ if (IsVisible() && m_flashOn)
+ dc->DrawRectangle(pt.x, pt.y, m_width, m_height);
+}
+
+void wxRichTextCaret::Notify()
+{
+ m_flashOn = !m_flashOn;
+ Refresh();
+}
+
+void wxRichTextCaretTimer::Notify()
+{
+ m_caret->Notify();
+}