drawingArea.SetPosition(GetLogicalPoint(drawingArea.GetPosition()));
wxRect availableSpace(GetClientSize());
+ wxRichTextDrawingContext context(& GetBuffer());
if (GetBuffer().IsDirty())
{
- GetBuffer().Layout(dc, availableSpace, availableSpace, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT);
+ GetBuffer().Layout(dc, context, availableSpace, availableSpace, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT);
GetBuffer().Invalidate(wxRICHTEXT_NONE);
SetupScrollbars();
}
if ((GetExtraStyle() & wxRICHTEXT_EX_NO_GUIDELINES) == 0)
flags |= wxRICHTEXT_DRAW_GUIDELINES;
- GetBuffer().Draw(dc, GetBuffer().GetOwnRange(), GetSelection(), drawingArea, 0 /* descent */, flags);
+ GetBuffer().Draw(dc, context, GetBuffer().GetOwnRange(), GetSelection(), drawingArea, 0 /* descent */, flags);
dc.DestroyClippingRegion();
long position = 0;
wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL;
- int hit = GetBuffer().HitTest(dc, event.GetLogicalPosition(dc), position, & hitObj, & contextObj);
+ wxRichTextDrawingContext context(& GetBuffer());
+ int hit = GetBuffer().HitTest(dc, context, 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
wxPoint logicalPt = event.GetLogicalPosition(dc);
wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL;
+ wxRichTextDrawingContext context(& GetBuffer());
// 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);
+ int hit = GetFocusObject()->HitTest(dc, context, logicalPt, position, & hitObj, & contextObj, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS);
#if wxUSE_DRAG_AND_DROP
if (m_preDrag)
long position = 0;
wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL;
- int hit = GetBuffer().HitTest(dc, event.GetLogicalPosition(dc), position, & hitObj, & contextObj);
+ int hit = GetBuffer().HitTest(dc, context, event.GetLogicalPosition(dc), position, & hitObj, & contextObj);
wxRichTextParagraphLayoutBox* oldFocusObject = GetFocusObject();
wxRichTextParagraphLayoutBox* container = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox);
if (container && container != GetFocusObject() && container->AcceptsFocus())
flags = wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS;
container = GetFocusObject();
}
- int hit = container->HitTest(dc, logicalPt, position, & hitObj, & contextObj, flags);
+ wxRichTextDrawingContext context(& GetBuffer());
+ int hit = container->HitTest(dc, context, logicalPt, position, & hitObj, & contextObj, flags);
// See if we need to change the cursor
// Check for dragging across multiple containers
long position2 = 0;
wxRichTextObject* hitObj2 = NULL, *contextObj2 = NULL;
- int hit2 = GetBuffer().HitTest(dc, logicalPt, position2, & hitObj2, & contextObj2, 0);
+ wxRichTextDrawingContext context(& GetBuffer());
+ int hit2 = GetBuffer().HitTest(dc, context, logicalPt, position2, & hitObj2, & contextObj2, 0);
if (hit2 != wxRICHTEXT_HITTEST_NONE && !(hit2 & wxRICHTEXT_HITTEST_OUTSIDE) && hitObj2 && hitObj != hitObj2)
{
// See if we can find a common ancestor
wxPoint logicalPt = event.GetLogicalPosition(dc);
wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL;
- int hit = GetFocusObject()->HitTest(dc, logicalPt, position, & hitObj, & contextObj);
+ wxRichTextDrawingContext context(& GetBuffer());
+ int hit = GetFocusObject()->HitTest(dc, context, logicalPt, position, & hitObj, & contextObj);
if (hitObj && hitObj->GetContainer() != GetFocusObject())
{
// Must process this before translation, otherwise it's translated into a WXK_DELETE event.
if (event.CmdDown() && event.GetKeyCode() == WXK_BACK)
{
+ if (!IsEditable())
+ {
+ return;
+ }
+
+ if (HasSelection() && !CanDeleteRange(* GetFocusObject(), GetSelectionRange()))
+ {
+ return;
+ }
+
BeginBatchUndo(_("Delete Text"));
long newPos = m_caretPosition;
bool processed = DeleteSelectedContent(& newPos);
+ int deletions = 0;
+ if (processed)
+ deletions ++;
+
// Submit range in character positions, which are greater than caret positions,
// so subtract 1 for deleted character and add 1 for conversion to character position.
if (newPos > -1)
long pos = wxRichTextCtrl::FindNextWordPosition(-1);
if (pos < newPos)
{
- GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(pos+1, newPos), this, & GetBuffer());
+ wxRichTextRange range(pos+1, newPos);
+ if (CanDeleteRange(* GetFocusObject(), range.FromInternal()))
+ {
+ GetFocusObject()->DeleteRangeWithUndo(range, this, & GetBuffer());
+ deletions ++;
+ }
processed = true;
}
}
if (!processed)
- GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(newPos, newPos), this, & GetBuffer());
+ {
+ wxRichTextRange range(newPos, newPos);
+ if (CanDeleteRange(* GetFocusObject(), range.FromInternal()))
+ {
+ GetFocusObject()->DeleteRangeWithUndo(range, this, & GetBuffer());
+ deletions ++;
+ }
+ }
}
EndBatchUndo();
ScrollIntoView(m_caretPosition, WXK_LEFT);
- wxRichTextEvent cmdEvent(
- wxEVT_COMMAND_RICHTEXT_DELETE,
- GetId());
- cmdEvent.SetEventObject(this);
- cmdEvent.SetFlags(flags);
- cmdEvent.SetPosition(m_caretPosition+1);
- cmdEvent.SetContainer(GetFocusObject());
- GetEventHandler()->ProcessEvent(cmdEvent);
+ if (deletions > 0)
+ {
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_DELETE,
+ GetId());
+ cmdEvent.SetEventObject(this);
+ cmdEvent.SetFlags(flags);
+ cmdEvent.SetPosition(m_caretPosition+1);
+ cmdEvent.SetContainer(GetFocusObject());
+ GetEventHandler()->ProcessEvent(cmdEvent);
+ }
Update();
}
if (event.GetKeyCode() == WXK_RETURN)
{
- BeginBatchUndo(_("Insert Text"));
+ if (!CanInsertContent(* GetFocusObject(), m_caretPosition+1))
+ return;
long newPos = m_caretPosition;
+ if (HasSelection() && !CanDeleteRange(* GetFocusObject(), GetSelectionRange()))
+ {
+ return;
+ }
+
+ BeginBatchUndo(_("Insert Text"));
+
DeleteSelectedContent(& newPos);
if (event.ShiftDown())
}
else if (event.GetKeyCode() == WXK_BACK)
{
- BeginBatchUndo(_("Delete Text"));
-
long newPos = m_caretPosition;
+ if (HasSelection() && !CanDeleteRange(* GetFocusObject(), GetSelectionRange()))
+ {
+ return;
+ }
+
+ BeginBatchUndo(_("Delete Text"));
+
bool processed = DeleteSelectedContent(& newPos);
+ int deletions = 0;
+ if (processed)
+ deletions ++;
+
// Submit range in character positions, which are greater than caret positions,
// so subtract 1 for deleted character and add 1 for conversion to character position.
if (newPos > -1)
long pos = wxRichTextCtrl::FindNextWordPosition(-1);
if (pos < newPos)
{
- GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(pos+1, newPos), this, & GetBuffer());
+ wxRichTextRange range(pos+1, newPos);
+ if (CanDeleteRange(* GetFocusObject(), range.FromInternal()))
+ {
+ GetFocusObject()->DeleteRangeWithUndo(range, this, & GetBuffer());
+ deletions ++;
+ }
processed = true;
}
}
if (!processed)
- GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(newPos, newPos), this, & GetBuffer());
+ {
+ wxRichTextRange range(newPos, newPos);
+ if (CanDeleteRange(* GetFocusObject(), range.FromInternal()))
+ {
+ GetFocusObject()->DeleteRangeWithUndo(range, this, & GetBuffer());
+ deletions ++;
+ }
+ }
}
EndBatchUndo();
ScrollIntoView(m_caretPosition, WXK_LEFT);
- wxRichTextEvent cmdEvent(
- wxEVT_COMMAND_RICHTEXT_DELETE,
- GetId());
- cmdEvent.SetEventObject(this);
- cmdEvent.SetFlags(flags);
- cmdEvent.SetPosition(m_caretPosition+1);
- cmdEvent.SetContainer(GetFocusObject());
- GetEventHandler()->ProcessEvent(cmdEvent);
+ if (deletions > 0)
+ {
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_DELETE,
+ GetId());
+ cmdEvent.SetEventObject(this);
+ cmdEvent.SetFlags(flags);
+ cmdEvent.SetPosition(m_caretPosition+1);
+ cmdEvent.SetContainer(GetFocusObject());
+ GetEventHandler()->ProcessEvent(cmdEvent);
+ }
Update();
}
else if (event.GetKeyCode() == WXK_DELETE)
{
- BeginBatchUndo(_("Delete Text"));
-
long newPos = m_caretPosition;
+ if (HasSelection() && !CanDeleteRange(* GetFocusObject(), GetSelectionRange()))
+ {
+ return;
+ }
+
+ BeginBatchUndo(_("Delete Text"));
+
bool processed = DeleteSelectedContent(& newPos);
+ int deletions = 0;
+ if (processed)
+ deletions ++;
+
// Submit range in character positions, which are greater than caret positions,
if (newPos < GetFocusObject()->GetOwnRange().GetEnd()+1)
{
long pos = wxRichTextCtrl::FindNextWordPosition(1);
if (pos != -1 && (pos > newPos))
{
- GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(newPos+1, pos), this, & GetBuffer());
+ wxRichTextRange range(newPos+1, pos);
+ if (CanDeleteRange(* GetFocusObject(), range.FromInternal()))
+ {
+ GetFocusObject()->DeleteRangeWithUndo(range, this, & GetBuffer());
+ deletions ++;
+ }
processed = true;
}
}
if (!processed && newPos < (GetLastPosition()-1))
- GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(newPos+1, newPos+1), this, & GetBuffer());
+ {
+ wxRichTextRange range(newPos+1, newPos+1);
+ if (CanDeleteRange(* GetFocusObject(), range.FromInternal()))
+ {
+ GetFocusObject()->DeleteRangeWithUndo(range, this, & GetBuffer());
+ deletions ++;
+ }
+ }
}
EndBatchUndo();
ScrollIntoView(m_caretPosition, WXK_LEFT);
- wxRichTextEvent cmdEvent(
- wxEVT_COMMAND_RICHTEXT_DELETE,
- GetId());
- cmdEvent.SetEventObject(this);
- cmdEvent.SetFlags(flags);
- cmdEvent.SetPosition(m_caretPosition+1);
- cmdEvent.SetContainer(GetFocusObject());
- GetEventHandler()->ProcessEvent(cmdEvent);
+ if (deletions > 0)
+ {
+ wxRichTextEvent cmdEvent(
+ wxEVT_COMMAND_RICHTEXT_DELETE,
+ GetId());
+ cmdEvent.SetEventObject(this);
+ cmdEvent.SetFlags(flags);
+ cmdEvent.SetPosition(m_caretPosition+1);
+ cmdEvent.SetContainer(GetFocusObject());
+ GetEventHandler()->ProcessEvent(cmdEvent);
+ }
Update();
}
}
}
+ if (!CanInsertContent(* GetFocusObject(), m_caretPosition+1))
+ return;
+
+ if (HasSelection() && !CanDeleteRange(* GetFocusObject(), GetSelectionRange()))
+ return;
+
BeginBatchUndo(_("Insert Text"));
long newPos = m_caretPosition;
}
}
-bool wxRichTextCtrl::ProcessMouseMovement(wxRichTextParagraphLayoutBox* container, wxRichTextObject* obj, long position, const wxPoint& pos)
+bool wxRichTextCtrl::ProcessMouseMovement(wxRichTextParagraphLayoutBox* container, wxRichTextObject* WXUNUSED(obj), long position, const wxPoint& WXUNUSED(pos))
{
wxRichTextAttr attr;
if (container && GetStyle(position, attr, container))
wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL;
- int hitTest = container->HitTest(dc, pt, newPos, & hitObj, & contextObj, hitTestFlags);
+ wxRichTextDrawingContext context(& GetBuffer());
+ int hitTest = container->HitTest(dc, context, pt, newPos, & hitObj, & contextObj, hitTestFlags);
if (hitObj &&
((hitTest & wxRICHTEXT_HITTEST_NONE) == 0) &&
wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL;
- int hit = ((wxRichTextCtrl*)this)->GetFocusObject()->HitTest(dc, pt2, *pos, & hitObj, & contextObj, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS);
+ wxRichTextDrawingContext context((wxRichTextBuffer*) & GetBuffer());
+ int hit = ((wxRichTextCtrl*)this)->GetFocusObject()->HitTest(dc, context, pt2, *pos, & hitObj, & contextObj, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS);
if ((hit & wxRICHTEXT_HITTEST_BEFORE) && (hit & wxRICHTEXT_HITTEST_OUTSIDE))
return wxTE_HT_BEFORE;
wxPoint logicalPt = GetLogicalPoint(pt);
wxRichTextObject* contextObj = NULL;
- hit = GetBuffer().HitTest(dc, logicalPt, position, &hitObj, &contextObj, flags);
+ wxRichTextDrawingContext context(& GetBuffer());
+ hit = GetBuffer().HitTest(dc, context, logicalPt, position, &hitObj, &contextObj, flags);
wxRichTextParagraphLayoutBox* container = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox);
return container;
bool wxRichTextCtrl::CanCut() const
{
- return HasSelection() && IsEditable();
+ return CanDeleteSelection();
}
bool wxRichTextCtrl::CanPaste() const
{
- if ( !IsEditable() )
+ if ( !IsEditable() || !GetFocusObject() || !CanInsertContent(* GetFocusObject(), m_caretPosition+1))
return false;
return GetBuffer().CanPasteFromClipboard();
bool wxRichTextCtrl::CanDeleteSelection() const
{
- return HasSelection() && IsEditable();
+ return HasSelection() && IsEditable() && CanDeleteRange(* GetFocusObject(), GetSelectionRange());
}
if (pt != wxDefaultPosition)
{
wxPoint logicalPt = GetLogicalPoint(ScreenToClient(pt));
- int hit = GetBuffer().HitTest(dc, logicalPt, position, & hitObj, & contextObj);
+ wxRichTextDrawingContext context(& GetBuffer());
+ int hit = GetBuffer().HitTest(dc, context, logicalPt, position, & hitObj, & contextObj);
if (hit == wxRICHTEXT_HITTEST_ON || hit == wxRICHTEXT_HITTEST_BEFORE || hit == wxRICHTEXT_HITTEST_AFTER)
{
if (!container)
container = GetFocusObject();
- if (container->FindPosition(dc, position, pt, & height, m_caretAtLineStart))
+ wxRichTextDrawingContext context(& GetBuffer());
+ if (container->FindPosition(dc, context, position, pt, & height, m_caretAtLineStart))
{
// Caret height can't be zero
if (height == 0)
PrepareDC(dc);
+ wxRichTextDrawingContext context(& GetBuffer());
GetBuffer().Defragment();
GetBuffer().UpdateRanges(); // If items were deleted, ranges need recalculation
- GetBuffer().Layout(dc, availableSpace, availableSpace, flags);
+ GetBuffer().Layout(dc, context, availableSpace, availableSpace, flags);
GetBuffer().Invalidate(wxRICHTEXT_NONE);
if (!IsFrozen())
}
#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;
+}
+
#if wxRICHTEXT_USE_OWN_CARET