Added further API for intercepting deletion and content insertion
Added simple implementation of locked objects to sample git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70465 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -3231,6 +3231,12 @@ public:
|
||||
|
||||
virtual wxRichTextObject* Clone() const { return new wxRichTextParagraphLayoutBox(*this); }
|
||||
|
||||
/**
|
||||
Prepares the content just before insertion (or after buffer reset).
|
||||
Currently is only called if undo mode is on.
|
||||
*/
|
||||
virtual void PrepareContent(wxRichTextParagraphLayoutBox& container);
|
||||
|
||||
/**
|
||||
Insert fragment into this box at the given position. If partialParagraph is true,
|
||||
it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
|
||||
|
@@ -1658,6 +1658,24 @@ public:
|
||||
*/
|
||||
virtual wxString GetPropertiesMenuLabel(wxRichTextObject* obj) { return obj->GetPropertiesMenuLabel(); }
|
||||
|
||||
/**
|
||||
Prepares the content just before insertion (or after buffer reset). Called by the same function in wxRichTextBuffer.
|
||||
Currently is only called if undo mode is on.
|
||||
*/
|
||||
virtual void PrepareContent(wxRichTextParagraphLayoutBox& WXUNUSED(container)) {}
|
||||
|
||||
/**
|
||||
Can we delete this range?
|
||||
Sends an event to the control.
|
||||
*/
|
||||
virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox& container, const wxRichTextRange& range) const;
|
||||
|
||||
/**
|
||||
Can we insert content at this position?
|
||||
Sends an event to the control.
|
||||
*/
|
||||
virtual bool CanInsertContent(wxRichTextParagraphLayoutBox& container, long pos) const;
|
||||
|
||||
// Command handlers
|
||||
|
||||
/**
|
||||
|
@@ -3111,6 +3111,12 @@ public:
|
||||
|
||||
virtual wxRichTextObject* Clone() const { return new wxRichTextParagraphLayoutBox(*this); }
|
||||
|
||||
/**
|
||||
Prepares the content just before insertion (or after buffer reset).
|
||||
Currently is only called if undo mode is on.
|
||||
*/
|
||||
virtual void PrepareContent(wxRichTextParagraphLayoutBox& container);
|
||||
|
||||
/**
|
||||
Insert fragment into this box at the given position. If partialParagraph is true,
|
||||
it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
|
||||
|
@@ -1617,6 +1617,24 @@ public:
|
||||
*/
|
||||
virtual wxString GetPropertiesMenuLabel(wxRichTextObject* obj);
|
||||
|
||||
/**
|
||||
Prepares the content just before insertion (or after buffer reset). Called by the same function in wxRichTextBuffer.
|
||||
Currently is only called if undo mode is on.
|
||||
*/
|
||||
virtual void PrepareContent(wxRichTextParagraphLayoutBox& WXUNUSED(container)) {}
|
||||
|
||||
/**
|
||||
Can we delete this range?
|
||||
Sends an event to the control.
|
||||
*/
|
||||
virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox& container, const wxRichTextRange& range) const;
|
||||
|
||||
/**
|
||||
Can we insert content at this position?
|
||||
Sends an event to the control.
|
||||
*/
|
||||
virtual bool CanInsertContent(wxRichTextParagraphLayoutBox& container, long pos) const;
|
||||
|
||||
// Command handlers
|
||||
|
||||
/**
|
||||
|
@@ -89,6 +89,49 @@
|
||||
// private classes
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Define a new application type, each program should derive a class from wxApp
|
||||
class MyRichTextCtrl: public wxRichTextCtrl
|
||||
{
|
||||
public:
|
||||
MyRichTextCtrl( wxWindow* parent, wxWindowID id = -1, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = wxRE_MULTILINE, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxTextCtrlNameStr):
|
||||
wxRichTextCtrl(parent, id, value, pos, size, style, validator, name)
|
||||
{
|
||||
m_lockId = 0;
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
void SetLockId(long id) { m_lockId = id; }
|
||||
long GetLockId() const { return m_lockId; }
|
||||
|
||||
void BeginLock() { m_lockId ++; m_locked = true; }
|
||||
void EndLock() { m_locked = false; }
|
||||
bool IsLocked() const { return m_locked; }
|
||||
|
||||
static void SetEnhancedDrawingHandler();
|
||||
|
||||
/**
|
||||
Prepares the content just before insertion (or after buffer reset). Called by the same function in wxRichTextBuffer.
|
||||
Currently is only called if undo mode is on.
|
||||
*/
|
||||
virtual void PrepareContent(wxRichTextParagraphLayoutBox& container);
|
||||
|
||||
/**
|
||||
Can we delete this range?
|
||||
Sends an event to the control.
|
||||
*/
|
||||
virtual bool CanDeleteRange(wxRichTextParagraphLayoutBox& container, const wxRichTextRange& range) const;
|
||||
|
||||
/**
|
||||
Can we insert content at this position?
|
||||
Sends an event to the control.
|
||||
*/
|
||||
virtual bool CanInsertContent(wxRichTextParagraphLayoutBox& container, long pos) const;
|
||||
|
||||
long m_lockId;
|
||||
bool m_locked;
|
||||
};
|
||||
|
||||
// Define a new application type, each program should derive a class from wxApp
|
||||
class MyApp : public wxApp
|
||||
{
|
||||
@@ -205,7 +248,7 @@ private:
|
||||
// any class wishing to process wxWidgets events must use this macro
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
wxRichTextCtrl* m_richTextCtrl;
|
||||
MyRichTextCtrl* m_richTextCtrl;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -387,6 +430,8 @@ bool MyApp::OnInit()
|
||||
|
||||
CreateStyles();
|
||||
|
||||
MyRichTextCtrl::SetEnhancedDrawingHandler();
|
||||
|
||||
// Add extra handlers (plain text is automatically added)
|
||||
wxRichTextBuffer::AddHandler(new wxRichTextXMLHandler);
|
||||
wxRichTextBuffer::AddHandler(new wxRichTextHTMLHandler);
|
||||
@@ -736,7 +781,7 @@ MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos,
|
||||
wxFont boldFont = wxFont(12, wxROMAN, wxNORMAL, wxBOLD);
|
||||
wxFont italicFont = wxFont(12, wxROMAN, wxITALIC, wxNORMAL);
|
||||
|
||||
m_richTextCtrl = new wxRichTextCtrl(splitter, ID_RICHTEXT_CTRL, wxEmptyString, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxWANTS_CHARS);
|
||||
m_richTextCtrl = new MyRichTextCtrl(splitter, ID_RICHTEXT_CTRL, wxEmptyString, wxDefaultPosition, wxSize(200, 200), wxVSCROLL|wxHSCROLL|wxWANTS_CHARS);
|
||||
wxFont font(12, wxROMAN, wxNORMAL, wxNORMAL);
|
||||
|
||||
m_richTextCtrl->SetFont(font);
|
||||
@@ -773,10 +818,27 @@ MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos,
|
||||
// Write text
|
||||
void MyFrame::WriteInitialText()
|
||||
{
|
||||
wxRichTextCtrl& r = *m_richTextCtrl;
|
||||
MyRichTextCtrl& r = *m_richTextCtrl;
|
||||
|
||||
r.SetDefaultStyle(wxRichTextAttr());
|
||||
|
||||
// Add some locked content first - needs Undo to be enabled
|
||||
{
|
||||
r.BeginLock();
|
||||
r.WriteText(wxString(wxT("This is a locked object.")));
|
||||
r.EndLock();
|
||||
|
||||
r.WriteText(wxString(wxT(" This is unlocked text. ")));
|
||||
|
||||
r.BeginLock();
|
||||
r.WriteText(wxString(wxT("More locked content.")));
|
||||
r.EndLock();
|
||||
r.Newline();
|
||||
|
||||
// Flush the Undo buffer
|
||||
r.GetCommandProcessor()->ClearCommands();
|
||||
}
|
||||
|
||||
r.BeginSuppressUndo();
|
||||
|
||||
r.Freeze();
|
||||
@@ -1807,3 +1869,107 @@ void MyFrame::OnPageSetup(wxCommandEvent& WXUNUSED(event))
|
||||
|
||||
// wxGetApp().GetPrinting()->PageSetup();
|
||||
}
|
||||
|
||||
void MyRichTextCtrl::PrepareContent(wxRichTextParagraphLayoutBox& container)
|
||||
{
|
||||
if (IsLocked())
|
||||
{
|
||||
// Lock all content that's about to be added to the control
|
||||
wxRichTextObjectList::compatibility_iterator node = container.GetChildren().GetFirst();
|
||||
while (node)
|
||||
{
|
||||
wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph);
|
||||
if (para)
|
||||
{
|
||||
wxRichTextObjectList::compatibility_iterator childNode = para->GetChildren().GetFirst();
|
||||
while (childNode)
|
||||
{
|
||||
wxRichTextObject* obj = childNode->GetData();
|
||||
obj->GetProperties().SetProperty(wxT("Lock"), m_lockId);
|
||||
|
||||
childNode = childNode->GetNext();
|
||||
}
|
||||
}
|
||||
node = node->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MyRichTextCtrl::CanDeleteRange(wxRichTextParagraphLayoutBox& container, const wxRichTextRange& range) const
|
||||
{
|
||||
long i;
|
||||
for (i = range.GetStart(); i < range.GetEnd(); i++)
|
||||
{
|
||||
wxRichTextObject* obj = container.GetLeafObjectAtPosition(i);
|
||||
if (obj && obj->GetProperties().HasProperty(wxT("Lock")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MyRichTextCtrl::CanInsertContent(wxRichTextParagraphLayoutBox& container, long pos) const
|
||||
{
|
||||
wxRichTextObject* child1 = container.GetLeafObjectAtPosition(pos);
|
||||
wxRichTextObject* child2 = container.GetLeafObjectAtPosition(pos-1);
|
||||
|
||||
long lock1 = -1, lock2 = -1;
|
||||
|
||||
if (child1 && child1->GetProperties().HasProperty(wxT("Lock")))
|
||||
lock1 = child1->GetProperties().GetPropertyLong(wxT("Lock"));
|
||||
if (child2 && child2->GetProperties().HasProperty(wxT("Lock")))
|
||||
lock2 = child2->GetProperties().GetPropertyLong(wxT("Lock"));
|
||||
|
||||
if (lock1 != -1 && lock1 == lock2)
|
||||
return false;
|
||||
|
||||
// Don't allow insertion before a locked object if it's at the beginning of the buffer.
|
||||
if (pos == 0 && lock1 != -1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class wxRichTextEnhancedDrawingHandler: public wxRichTextDrawingHandler
|
||||
{
|
||||
public:
|
||||
wxRichTextEnhancedDrawingHandler()
|
||||
{
|
||||
SetName(wxT("enhanceddrawing"));
|
||||
m_lockBackgroundColour = wxColour(220, 220, 220);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns @true if this object has virtual attributes that we can provide.
|
||||
*/
|
||||
virtual bool HasVirtualAttributes(wxRichTextObject* obj) const;
|
||||
|
||||
/**
|
||||
Provides virtual attributes that we can provide.
|
||||
*/
|
||||
virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const;
|
||||
|
||||
wxColour m_lockBackgroundColour;
|
||||
};
|
||||
|
||||
bool wxRichTextEnhancedDrawingHandler::HasVirtualAttributes(wxRichTextObject* obj) const
|
||||
{
|
||||
return obj->GetProperties().HasProperty(wxT("Lock"));
|
||||
}
|
||||
|
||||
bool wxRichTextEnhancedDrawingHandler::GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const
|
||||
{
|
||||
if (obj->GetProperties().HasProperty(wxT("Lock")))
|
||||
{
|
||||
attr.SetBackgroundColour(m_lockBackgroundColour);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MyRichTextCtrl::SetEnhancedDrawingHandler()
|
||||
{
|
||||
wxRichTextBuffer::AddDrawingHandler(new wxRichTextEnhancedDrawingHandler);
|
||||
}
|
||||
|
@@ -3524,6 +3524,14 @@ bool wxRichTextParagraphLayoutBox::HasParagraphAttributes(const wxRichTextRange&
|
||||
return foundCount == matchingCount && foundCount != 0;
|
||||
}
|
||||
|
||||
void wxRichTextParagraphLayoutBox::PrepareContent(wxRichTextParagraphLayoutBox& container)
|
||||
{
|
||||
wxRichTextBuffer* buffer = GetBuffer();
|
||||
if (buffer && buffer->GetRichTextCtrl())
|
||||
buffer->GetRichTextCtrl()->PrepareContent(container);
|
||||
}
|
||||
|
||||
|
||||
/// Set character or paragraph properties
|
||||
bool wxRichTextParagraphLayoutBox::SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags)
|
||||
{
|
||||
@@ -3697,6 +3705,8 @@ void wxRichTextParagraphLayoutBox::Reset()
|
||||
|
||||
AddParagraph(wxEmptyString);
|
||||
|
||||
PrepareContent(*this);
|
||||
|
||||
InvalidateHierarchy(wxRICHTEXT_ALL);
|
||||
}
|
||||
|
||||
@@ -7201,6 +7211,9 @@ bool wxRichTextBuffer::EndBatchUndo()
|
||||
/// Submit immediately, or delay according to whether collapsing is on
|
||||
bool wxRichTextBuffer::SubmitAction(wxRichTextAction* action)
|
||||
{
|
||||
if (action && !action->GetNewParagraphs().IsEmpty())
|
||||
PrepareContent(action->GetNewParagraphs());
|
||||
|
||||
if (BatchingUndo() && m_batchedCommand && !SuppressingUndo())
|
||||
{
|
||||
wxRichTextCommand* cmd = new wxRichTextCommand(action->GetName());
|
||||
|
@@ -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,6 +1176,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
|
||||
|
||||
ScrollIntoView(m_caretPosition, WXK_LEFT);
|
||||
|
||||
if (deletions > 0)
|
||||
{
|
||||
wxRichTextEvent cmdEvent(
|
||||
wxEVT_COMMAND_RICHTEXT_DELETE,
|
||||
GetId());
|
||||
@@ -1158,6 +1186,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
|
||||
cmdEvent.SetPosition(m_caretPosition+1);
|
||||
cmdEvent.SetContainer(GetFocusObject());
|
||||
GetEventHandler()->ProcessEvent(cmdEvent);
|
||||
}
|
||||
|
||||
Update();
|
||||
}
|
||||
@@ -1177,10 +1206,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 +1256,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 +1280,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,6 +1314,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
|
||||
|
||||
ScrollIntoView(m_caretPosition, WXK_LEFT);
|
||||
|
||||
if (deletions > 0)
|
||||
{
|
||||
wxRichTextEvent cmdEvent(
|
||||
wxEVT_COMMAND_RICHTEXT_DELETE,
|
||||
GetId());
|
||||
@@ -1264,17 +1324,27 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
|
||||
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 +1353,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,6 +1387,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
|
||||
|
||||
ScrollIntoView(m_caretPosition, WXK_LEFT);
|
||||
|
||||
if (deletions > 0)
|
||||
{
|
||||
wxRichTextEvent cmdEvent(
|
||||
wxEVT_COMMAND_RICHTEXT_DELETE,
|
||||
GetId());
|
||||
@@ -1313,6 +1397,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
|
||||
cmdEvent.SetPosition(m_caretPosition+1);
|
||||
cmdEvent.SetContainer(GetFocusObject());
|
||||
GetEventHandler()->ProcessEvent(cmdEvent);
|
||||
}
|
||||
|
||||
Update();
|
||||
}
|
||||
@@ -1377,6 +1462,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;
|
||||
@@ -3018,12 +3109,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 +3122,7 @@ bool wxRichTextCtrl::CanPaste() const
|
||||
|
||||
bool wxRichTextCtrl::CanDeleteSelection() const
|
||||
{
|
||||
return HasSelection() && IsEditable();
|
||||
return HasSelection() && IsEditable() && CanDeleteRange(* GetFocusObject(), GetSelectionRange());
|
||||
}
|
||||
|
||||
|
||||
@@ -4460,6 +4551,16 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
#if wxRICHTEXT_USE_OWN_CARET
|
||||
|
||||
|
Reference in New Issue
Block a user