Applied #13819: wxRTC drag and drop, by dghart, with tweaks
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70253 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
606e096810
commit
0c0e063e66
@ -21,6 +21,10 @@
|
||||
|
||||
#include "wx/textctrl.h"
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
#include "wx/dnd.h"
|
||||
#endif
|
||||
|
||||
#if !defined(__WXGTK__) && !defined(__WXMAC__)
|
||||
#define wxRICHTEXT_BUFFERED_PAINTING 1
|
||||
#else
|
||||
@ -428,15 +432,40 @@ public:
|
||||
*/
|
||||
void SetDragging(bool dragging) { m_dragging = dragging; }
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
/**
|
||||
Returns the drag start position.
|
||||
Are we trying to start Drag'n'Drop?
|
||||
*/
|
||||
const wxPoint& GetDragStart() const { return m_dragStart; }
|
||||
bool GetPreDrag() const { return m_preDrag; }
|
||||
|
||||
/**
|
||||
Sets the drag start position.
|
||||
Set if we're trying to start Drag'n'Drop
|
||||
*/
|
||||
void SetDragStart(const wxPoint& pt) { m_dragStart = pt; }
|
||||
void SetPreDrag(bool pd) { m_preDrag = pd; }
|
||||
|
||||
/**
|
||||
Get the possible Drag'n'Drop start point
|
||||
*/
|
||||
const wxPoint GetDragStartPoint() const { return m_dragStartPoint; }
|
||||
|
||||
/**
|
||||
Set the possible Drag'n'Drop start point
|
||||
*/
|
||||
void SetDragStartPoint(wxPoint sp) { m_dragStartPoint = sp; }
|
||||
|
||||
#if wxUSE_DATETIME
|
||||
/**
|
||||
Get the possible Drag'n'Drop start time
|
||||
*/
|
||||
const wxDateTime GetDragStartTime() const { return m_dragStartTime; }
|
||||
|
||||
/**
|
||||
Set the possible Drag'n'Drop start time
|
||||
*/
|
||||
void SetDragStartTime(wxDateTime st) { m_dragStartTime = st; }
|
||||
#endif // wxUSE_DATETIME
|
||||
|
||||
#endif // wxUSE_DRAG_AND_DROP
|
||||
|
||||
#if wxRICHTEXT_BUFFERED_PAINTING
|
||||
//@{
|
||||
@ -498,6 +527,11 @@ public:
|
||||
*/
|
||||
wxRichTextParagraphLayoutBox* GetFocusObject() const { return m_focusObject; }
|
||||
|
||||
/**
|
||||
Sets m_focusObject without making any alterations.
|
||||
*/
|
||||
void StoreFocusObject(wxRichTextParagraphLayoutBox* obj) { m_focusObject = obj; }
|
||||
|
||||
/**
|
||||
Sets the wxRichTextObject object that currently has the editing focus.
|
||||
*/
|
||||
@ -840,8 +874,20 @@ public:
|
||||
virtual wxTextCtrlHitTestResult HitTest(const wxPoint& pt,
|
||||
wxTextCoord *col,
|
||||
wxTextCoord *row) const;
|
||||
|
||||
/**
|
||||
Finds the container at the given point, which is in screen coordinates.
|
||||
*/
|
||||
wxRichTextParagraphLayoutBox* FindContainerAtPoint(const wxPoint pt, long& position, int& hit, wxRichTextObject* hitObj, int flags = 0);
|
||||
//@}
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
/**
|
||||
Does the 'drop' of Drag'n'Drop.
|
||||
*/
|
||||
void OnDrop(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult def, wxDataObject* DataObj);
|
||||
#endif
|
||||
|
||||
// Clipboard operations
|
||||
|
||||
/**
|
||||
@ -2018,7 +2064,7 @@ protected:
|
||||
|
||||
|
||||
// Data members
|
||||
private:
|
||||
protected:
|
||||
#if wxRICHTEXT_BUFFERED_PAINTING
|
||||
/// Buffer bitmap
|
||||
wxBitmap m_bufferBitmap;
|
||||
@ -2057,11 +2103,21 @@ private:
|
||||
/// instead of at the end of the previous one?
|
||||
bool m_caretAtLineStart;
|
||||
|
||||
/// Are we dragging a selection?
|
||||
/// Are we dragging (i.e. extending) a selection?
|
||||
bool m_dragging;
|
||||
|
||||
/// Start position for drag
|
||||
wxPoint m_dragStart;
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
/// Are we trying to start Drag'n'Drop?
|
||||
bool m_preDrag;
|
||||
|
||||
/// Initial position when starting Drag'n'Drop
|
||||
wxPoint m_dragStartPoint;
|
||||
|
||||
#if wxUSE_DATETIME
|
||||
/// Initial time when starting Drag'n'Drop
|
||||
wxDateTime m_dragStartTime;
|
||||
#endif // wxUSE_DATETIME
|
||||
#endif // wxUSE_DRAG_AND_DROP
|
||||
|
||||
/// Do we need full layout in idle?
|
||||
bool m_fullLayoutRequired;
|
||||
@ -2083,6 +2139,38 @@ private:
|
||||
wxRichTextParagraphLayoutBox* m_focusObject;
|
||||
};
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
class WXDLLIMPEXP_RICHTEXT wxRichTextDropSource : public wxDropSource
|
||||
{
|
||||
public:
|
||||
wxRichTextDropSource(wxDataObject& data, wxRichTextCtrl* tc)
|
||||
: wxDropSource(data, tc), m_rtc(tc) {}
|
||||
|
||||
protected:
|
||||
bool GiveFeedback(wxDragResult effect);
|
||||
|
||||
wxRichTextCtrl* m_rtc;
|
||||
};
|
||||
|
||||
class WXDLLIMPEXP_RICHTEXT wxRichTextDropTarget : public wxDropTarget
|
||||
{
|
||||
public:
|
||||
wxRichTextDropTarget(wxRichTextCtrl* tc)
|
||||
: wxDropTarget(new wxRichTextBufferDataObject(new wxRichTextBuffer)), m_rtc(tc) {}
|
||||
|
||||
virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def)
|
||||
{
|
||||
if ( !GetData() )
|
||||
return wxDragNone;
|
||||
m_rtc->OnDrop(x, y, def, m_dataObject);
|
||||
return def;
|
||||
}
|
||||
|
||||
protected:
|
||||
wxRichTextCtrl* m_rtc;
|
||||
};
|
||||
#endif // wxUSE_DRAG_AND_DROP
|
||||
|
||||
/**
|
||||
@class wxRichTextEvent
|
||||
|
||||
|
@ -392,24 +392,44 @@ public:
|
||||
void SetCaretAtLineStart(bool atStart) { m_caretAtLineStart = atStart; }
|
||||
|
||||
/**
|
||||
Returns @true if we are dragging a selection.
|
||||
Returns @true if we are extending a selection.
|
||||
*/
|
||||
bool GetDragging() const { return m_dragging; }
|
||||
|
||||
/**
|
||||
Sets a flag to remember if we are dragging a selection.
|
||||
Sets a flag to remember if we are extending a selection.
|
||||
*/
|
||||
void SetDragging(bool dragging) { m_dragging = dragging; }
|
||||
|
||||
/**
|
||||
Returns the drag start position.
|
||||
Are we trying to start Drag'n'Drop?
|
||||
*/
|
||||
const wxPoint& GetDragStart() const { return m_dragStart; }
|
||||
bool GetPreDrag() const { return m_preDrag; }
|
||||
|
||||
/**
|
||||
Sets the drag start position.
|
||||
Set if we're trying to start Drag'n'Drop
|
||||
*/
|
||||
void SetDragStart(const wxPoint& pt) { m_dragStart = pt; }
|
||||
void SetPreDrag(bool pd) { m_preDrag = pd; }
|
||||
|
||||
/**
|
||||
Get the possible Drag'n'Drop start point
|
||||
*/
|
||||
const wxPoint GetDragStartPoint() const { return m_dragStartPoint; }
|
||||
|
||||
/**
|
||||
Set the possible Drag'n'Drop start point
|
||||
*/
|
||||
void SetDragStartPoint(wxPoint sp) { m_dragStartPoint = sp; }
|
||||
|
||||
/**
|
||||
Get the possible Drag'n'Drop start time
|
||||
*/
|
||||
const wxDateTime GetDragStartTime() const { return m_dragStartTime; }
|
||||
|
||||
/**
|
||||
Set the possible Drag'n'Drop start time
|
||||
*/
|
||||
void SetDragStartTime(wxDateTime st) { m_dragStartTime = st; }
|
||||
|
||||
#if wxRICHTEXT_BUFFERED_PAINTING
|
||||
//@{
|
||||
@ -471,8 +491,15 @@ public:
|
||||
*/
|
||||
wxRichTextParagraphLayoutBox* GetFocusObject() const { return m_focusObject; }
|
||||
|
||||
/**
|
||||
Setter for m_focusObject.
|
||||
*/
|
||||
void StoreFocusObject(wxRichTextParagraphLayoutBox* obj);
|
||||
|
||||
/**
|
||||
Sets the wxRichTextObject object that currently has the editing focus.
|
||||
@param setCaretPosition
|
||||
Optionally set the caret position.
|
||||
*/
|
||||
bool SetFocusObject(wxRichTextParagraphLayoutBox* obj, bool setCaretPosition = true);
|
||||
|
||||
@ -813,6 +840,11 @@ public:
|
||||
virtual wxTextCtrlHitTestResult HitTest(const wxPoint& pt,
|
||||
wxTextCoord *col,
|
||||
wxTextCoord *row) const;
|
||||
|
||||
/**
|
||||
Finds the container at the given point, which is assumed to be in client coordinates.
|
||||
*/
|
||||
wxRichTextParagraphLayoutBox* FindContainerAtPoint(const wxPoint pt, long& position, int& hit, wxRichTextObject* hitObj, int flags = 0);
|
||||
//@}
|
||||
|
||||
// Clipboard operations
|
||||
@ -1991,7 +2023,7 @@ protected:
|
||||
|
||||
|
||||
// Data members
|
||||
private:
|
||||
protected:
|
||||
#if wxRICHTEXT_BUFFERED_PAINTING
|
||||
/// Buffer bitmap
|
||||
wxBitmap m_bufferBitmap;
|
||||
@ -2033,9 +2065,6 @@ private:
|
||||
/// Are we dragging a selection?
|
||||
bool m_dragging;
|
||||
|
||||
/// Start position for drag
|
||||
wxPoint m_dragStart;
|
||||
|
||||
/// Do we need full layout in idle?
|
||||
bool m_fullLayoutRequired;
|
||||
wxLongLong m_fullLayoutTime;
|
||||
|
@ -227,6 +227,8 @@ wxRichTextCtrl::wxRichTextCtrl(wxWindow* parent,
|
||||
{
|
||||
Init();
|
||||
Create(parent, id, value, pos, size, style, validator, name);
|
||||
|
||||
SetDropTarget(new wxRichTextDropTarget(this));
|
||||
}
|
||||
|
||||
/// Creation
|
||||
@ -349,6 +351,7 @@ void wxRichTextCtrl::Init()
|
||||
m_editable = true;
|
||||
m_caretAtLineStart = false;
|
||||
m_dragging = false;
|
||||
m_preDrag = false;
|
||||
m_fullLayoutRequired = false;
|
||||
m_fullLayoutTime = 0;
|
||||
m_fullLayoutSavedPosition = 0;
|
||||
@ -559,6 +562,26 @@ void wxRichTextCtrl::OnLeftClick(wxMouseEvent& event)
|
||||
wxRichTextObject* contextObj = NULL;
|
||||
int hit = GetBuffer().HitTest(dc, event.GetLogicalPosition(dc), position, & hitObj, & contextObj);
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
// If there's no selection, or we're not inside it, this isn't an attempt to initiate Drag'n'Drop
|
||||
if (HasSelection() && GetSelectionRange().ToInternal().Contains(position))
|
||||
{
|
||||
// This might be an attempt at initiating Drag'n'Drop. So set the time & flags
|
||||
m_preDrag = true;
|
||||
m_dragStartPoint = event.GetPosition(); // No need to worry about logical positions etc, we only care about the distance from the original pt
|
||||
|
||||
#if wxUSE_DATETIME
|
||||
m_dragStartTime = wxDateTime::UNow();
|
||||
#endif // wxUSE_DATETIME
|
||||
|
||||
// Preserve behaviour of clicking on an object within the selection
|
||||
if (hit != wxRICHTEXT_HITTEST_NONE && hitObj)
|
||||
m_dragging = true;
|
||||
|
||||
return; // Don't skip the event, else the selection will be lost
|
||||
}
|
||||
#endif // wxUSE_DRAG_AND_DROP
|
||||
|
||||
if (hit != wxRICHTEXT_HITTEST_NONE && hitObj)
|
||||
{
|
||||
wxRichTextParagraphLayoutBox* oldFocusObject = GetFocusObject();
|
||||
@ -568,7 +591,6 @@ void wxRichTextCtrl::OnLeftClick(wxMouseEvent& event)
|
||||
SetFocusObject(container, false /* don't set caret position yet */);
|
||||
}
|
||||
|
||||
m_dragStart = event.GetLogicalPosition(dc);
|
||||
m_dragging = true;
|
||||
CaptureMouse();
|
||||
|
||||
@ -607,6 +629,36 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event)
|
||||
// Only get objects at this level, not nested, because otherwise we couldn't swipe text at a single level.
|
||||
int hit = GetFocusObject()->HitTest(dc, logicalPt, position, & hitObj, & contextObj, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS);
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
if (m_preDrag)
|
||||
{
|
||||
// Preserve the behaviour that would have happened without drag-and-drop detection, in OnLeftClick
|
||||
m_preDrag = false; // Tell DnD not to happen now: we are processing Left Up ourselves.
|
||||
|
||||
// Do the actions that would have been done in OnLeftClick if we hadn't tried to drag
|
||||
long position = 0;
|
||||
wxRichTextObject* hitObj = NULL;
|
||||
wxRichTextObject* contextObj = NULL;
|
||||
int hit = GetBuffer().HitTest(dc, event.GetLogicalPosition(dc), position, & hitObj, & contextObj);
|
||||
wxRichTextParagraphLayoutBox* oldFocusObject = GetFocusObject();
|
||||
wxRichTextParagraphLayoutBox* container = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox);
|
||||
if (container && container != GetFocusObject() && container->AcceptsFocus())
|
||||
{
|
||||
SetFocusObject(container, false /* don't set caret position yet */);
|
||||
}
|
||||
|
||||
long oldCaretPos = m_caretPosition;
|
||||
|
||||
SetCaretPositionAfterClick(container, position, hit);
|
||||
|
||||
// For now, don't handle shift-click when we're selecting multiple objects.
|
||||
if (event.ShiftDown() && GetFocusObject() == oldFocusObject && m_selectionState == wxRichTextCtrlSelectionState_Normal)
|
||||
ExtendSelection(oldCaretPos, m_caretPosition, wxRICHTEXT_SHIFT_DOWN);
|
||||
else
|
||||
SelectNone();
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((hit != wxRICHTEXT_HITTEST_NONE) && !(hit & wxRICHTEXT_HITTEST_OUTSIDE))
|
||||
{
|
||||
wxRichTextEvent cmdEvent(
|
||||
@ -650,6 +702,10 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event)
|
||||
}
|
||||
}
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
m_preDrag = false;
|
||||
#endif // wxUSE_DRAG_AND_DROP
|
||||
|
||||
#if wxUSE_CLIPBOARD && wxUSE_DATAOBJ && wxHAVE_PRIMARY_SELECTION
|
||||
if (HasSelection() && GetFocusObject() && GetFocusObject()->GetBuffer())
|
||||
{
|
||||
@ -664,9 +720,77 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event)
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Left-click
|
||||
/// Mouse-movements
|
||||
void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event)
|
||||
{
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
// See if we're starting Drag'n'Drop
|
||||
if (m_preDrag)
|
||||
{
|
||||
int x = m_dragStartPoint.x - event.GetPosition().x;
|
||||
int y = m_dragStartPoint.y - event.GetPosition().y;
|
||||
size_t distance = abs(x) + abs(y);
|
||||
#if wxUSE_DATETIME
|
||||
wxTimeSpan diff = wxDateTime::UNow() - m_dragStartTime;
|
||||
#endif
|
||||
if ((distance > 10)
|
||||
#if wxUSE_DATETIME
|
||||
&& (diff.GetMilliseconds() > 100)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
m_dragging = false;
|
||||
|
||||
// Start drag'n'drop
|
||||
wxRichTextRange range = GetInternalSelectionRange();
|
||||
if (range == wxRICHTEXT_NONE)
|
||||
{
|
||||
// Don't try to drag an empty range
|
||||
m_preDrag = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache the current situation, to be restored if Drag'n'Drop is cancelled
|
||||
long oldPos = GetCaretPosition();
|
||||
wxRichTextParagraphLayoutBox* oldFocus = GetFocusObject();
|
||||
|
||||
wxDataObjectComposite* compositeObject = new wxDataObjectComposite();
|
||||
wxString text = GetFocusObject()->GetTextForRange(range);
|
||||
#ifdef __WXMSW__
|
||||
text = wxTextFile::Translate(text, wxTextFileType_Dos);
|
||||
#endif
|
||||
compositeObject->Add(new wxTextDataObject(text), false /* not preferred */);
|
||||
|
||||
wxRichTextBuffer* richTextBuf = new wxRichTextBuffer;
|
||||
GetFocusObject()->CopyFragment(range, *richTextBuf);
|
||||
compositeObject->Add(new wxRichTextBufferDataObject(richTextBuf), true /* preferred */);
|
||||
|
||||
wxRichTextDropSource source(*compositeObject, this);
|
||||
// Use wxDrag_DefaultMove, not because it's the likelier choice but because pressing Ctrl for Copy obeys the principle of least surprise
|
||||
// The alternative, wxDrag_DefaultCopy, requires the user to know that Move needs the Shift key pressed
|
||||
BeginBatchUndo(_("Drag"));
|
||||
switch (source.DoDragDrop(wxDrag_AllowMove | wxDrag_DefaultMove))
|
||||
{
|
||||
case wxDragMove:
|
||||
case wxDragCopy: break;
|
||||
|
||||
case wxDragError:
|
||||
wxLogError(wxT("An error occurred during drag and drop operation"));
|
||||
case wxDragNone:
|
||||
case wxDragCancel:
|
||||
Refresh(); // This is needed in wxMSW, otherwise resetting the position doesn't 'take'
|
||||
SetCaretPosition(oldPos);
|
||||
SetFocusObject(oldFocus, false);
|
||||
default: break;
|
||||
}
|
||||
EndBatchUndo();
|
||||
|
||||
m_preDrag = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_DRAG_AND_DROP
|
||||
|
||||
wxClientDC dc(this);
|
||||
PrepareDC(dc);
|
||||
dc.SetFont(GetFont());
|
||||
@ -717,7 +841,11 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_dragging)
|
||||
if (m_dragging
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
&& !m_preDrag
|
||||
#endif
|
||||
)
|
||||
{
|
||||
wxRichTextParagraphLayoutBox* commonAncestor = NULL;
|
||||
wxRichTextParagraphLayoutBox* otherContainer = NULL;
|
||||
@ -790,7 +918,11 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event)
|
||||
}
|
||||
}
|
||||
|
||||
if (hitObj && m_dragging && hit != wxRICHTEXT_HITTEST_NONE && m_selectionState == wxRichTextCtrlSelectionState_Normal)
|
||||
if (hitObj && m_dragging && hit != wxRICHTEXT_HITTEST_NONE && m_selectionState == wxRichTextCtrlSelectionState_Normal
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
&& !m_preDrag
|
||||
#endif
|
||||
)
|
||||
{
|
||||
// TODO: test closeness
|
||||
SetCaretPositionAfterClick(container, position, hit, true /* extend selection */);
|
||||
@ -2592,6 +2724,23 @@ wxRichTextCtrl::HitTest(const wxPoint& pt,
|
||||
return wxTE_HT_UNKNOWN;
|
||||
}
|
||||
|
||||
wxRichTextParagraphLayoutBox*
|
||||
wxRichTextCtrl::FindContainerAtPoint(const wxPoint pt, long& position, int& hit, wxRichTextObject* hitObj, int flags/* = 0*/)
|
||||
{
|
||||
wxClientDC dc(this);
|
||||
PrepareDC(dc);
|
||||
dc.SetFont(GetFont());
|
||||
|
||||
wxPoint logicalPt = GetLogicalPoint(pt);
|
||||
|
||||
wxRichTextObject* contextObj = NULL;
|
||||
hit = GetBuffer().HitTest(dc, logicalPt, position, &hitObj, &contextObj, flags);
|
||||
wxRichTextParagraphLayoutBox* container = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// set/get the controls text
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -4176,6 +4325,85 @@ bool wxRichTextCtrl::SetFocusObject(wxRichTextParagraphLayoutBox* obj, bool setC
|
||||
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(position+1, *richTextBuffer, this, &GetBuffer(), 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->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
|
||||
|
||||
|
||||
#if wxRICHTEXT_USE_OWN_CARET
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user