X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8db2e3ef1565e738ade7f63580951d1d040b9c29..76c67131022c84eb8c424adea124620da6b0d03e:/src/richtext/richtextctrl.cpp diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index 9395714d2d..e8eff5d801 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -356,6 +356,7 @@ void wxRichTextCtrl::Init() m_selectionAnchorObject = NULL; m_selectionState = wxRichTextCtrlSelectionState_Normal; m_editable = true; + m_verticalScrollbarEnabled = true; m_caretAtLineStart = false; m_dragging = false; #if wxUSE_DRAG_AND_DROP @@ -861,7 +862,6 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event) // Check for dragging across multiple containers long position2 = 0; wxRichTextObject* hitObj2 = NULL, *contextObj2 = NULL; - 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) { @@ -1113,12 +1113,26 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) // 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) @@ -1128,13 +1142,25 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) 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(); @@ -1150,14 +1176,18 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) 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); + // Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion. + //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(); } @@ -1177,10 +1207,18 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) 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()) @@ -1219,12 +1257,21 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) } 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) @@ -1234,13 +1281,25 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) 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(); @@ -1256,25 +1315,38 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) 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); + // Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion. + //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) { @@ -1283,13 +1355,25 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) 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(); @@ -1305,14 +1389,18 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) 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); + // Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion. + //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(); } @@ -1377,6 +1465,12 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) } } + if (!CanInsertContent(* GetFocusObject(), m_caretPosition+1)) + return; + + if (HasSelection() && !CanDeleteRange(* GetFocusObject(), GetSelectionRange())) + return; + BeginBatchUndo(_("Insert Text")); long newPos = m_caretPosition; @@ -2465,7 +2559,7 @@ void wxRichTextCtrl::SetupScrollbars(bool atTop) if (IsFrozen()) return; - if (GetBuffer().IsEmpty()) + if (GetBuffer().IsEmpty() || !m_verticalScrollbarEnabled) { SetScrollbars(0, 0, 0, 0, 0, 0); return; @@ -3018,12 +3112,12 @@ bool wxRichTextCtrl::CanCopy() const 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(); @@ -3031,7 +3125,7 @@ bool wxRichTextCtrl::CanPaste() const bool wxRichTextCtrl::CanDeleteSelection() const { - return HasSelection() && IsEditable(); + return HasSelection() && IsEditable() && CanDeleteRange(* GetFocusObject(), GetSelectionRange()); } @@ -4460,6 +4554,22 @@ bool wxRichTextDropSource::GiveFeedback(wxDragResult WXUNUSED(effect)) } #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(); +} + #if wxRICHTEXT_USE_OWN_CARET