X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/85d8909ba3b07daa5f2af4f1377d2d26661e1a9a..bde733b0c646954653799d75d839960af3bd0d39:/src/richtext/richtextctrl.cpp diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index bf308ffb7a..3dcaa1f4ec 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -37,18 +37,24 @@ #include "wx/app.h" WX_CHECK_BUILD_OPTIONS("wxRichTextCtrl") -DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_ITEM_SELECTED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_ITEM_DESELECTED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_LEFT_CLICK) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_MIDDLE_CLICK) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_RIGHT_CLICK) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_LEFT_DCLICK) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_RETURN) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_CHARACTER) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_DELETE) + DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACING) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGING) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLESHEET_CHANGED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_CONTENT_INSERTED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED) + IMPLEMENT_CLASS( wxRichTextCtrl, wxControl ) IMPLEMENT_CLASS( wxRichTextEvent, wxNotifyEvent ) @@ -109,18 +115,22 @@ wxRichTextCtrl::wxRichTextCtrl(wxWindow* parent, const wxString& value, const wxPoint& pos, const wxSize& size, - long style) + long style, + const wxValidator& validator, + const wxString& name) : wxScrollHelper(this) { Init(); - Create(parent, id, value, pos, size, style); + Create(parent, id, value, pos, size, style, validator, name); } /// Creation -bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style) +bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, + const wxValidator& validator, const wxString& name) { if (!wxTextCtrlBase::Create(parent, id, pos, size, - style|wxFULL_REPAINT_ON_RESIZE)) + style|wxFULL_REPAINT_ON_RESIZE, + validator, name)) return false; if (!GetFont().Ok()) @@ -130,10 +140,14 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va GetBuffer().Reset(); GetBuffer().SetRichTextCtrl(this); + + SetCaret(new wxCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16)); + GetCaret()->Show(); if (style & wxTE_READONLY) SetEditable(false); + // The base attributes must all have default values wxTextAttrEx attributes; attributes.SetFont(GetFont()); attributes.SetTextColour(*wxBLACK); @@ -142,6 +156,8 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va attributes.SetLineSpacing(10); attributes.SetParagraphSpacingAfter(10); attributes.SetParagraphSpacingBefore(0); + attributes.SetTextEffects(0); + attributes.SetTextEffectFlags(wxTEXT_ATTR_EFFECT_STRIKETHROUGH|wxTEXT_ATTR_EFFECT_CAPITALS); SetBasicStyle(attributes); @@ -154,7 +170,7 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va SetBackgroundStyle(wxBG_STYLE_CUSTOM); // Tell the sizers to use the given or best size - SetBestFittingSize(size); + SetInitialSize(size); #if wxRICHTEXT_BUFFERED_PAINTING // Create a buffer @@ -241,7 +257,7 @@ void wxRichTextCtrl::Clear() /// Painting void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) { - if (GetCaret()) + if (GetCaret() && GetCaret()->IsVisible()) GetCaret()->Hide(); { @@ -260,7 +276,11 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) // Paint the background PaintBackground(dc); - wxRect drawingArea(GetLogicalPoint(wxPoint(0, 0)), GetClientSize()); + // wxRect drawingArea(GetLogicalPoint(wxPoint(0, 0)), GetClientSize()); + + wxRect drawingArea(GetUpdateRegion().GetBox()); + drawingArea.SetPosition(GetLogicalPoint(drawingArea.GetPosition())); + wxRect availableSpace(GetClientSize()); if (GetBuffer().GetDirty()) { @@ -272,7 +292,7 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) GetBuffer().Draw(dc, GetBuffer().GetRange(), GetInternalSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */); } - if (GetCaret()) + if (GetCaret() && !GetCaret()->IsVisible()) GetCaret()->Show(); PositionCaret(); @@ -285,21 +305,24 @@ void wxRichTextCtrl::OnEraseBackground(wxEraseEvent& WXUNUSED(event)) void wxRichTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event)) { - wxCaret* caret = new wxCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16); - SetCaret(caret); - caret->Show(); - PositionCaret(); + if (GetCaret()) + { + if (!GetCaret()->IsVisible()) + GetCaret()->Show(); + PositionCaret(); + } - if (!IsFrozen()) - Refresh(false); + // if (!IsFrozen()) + // Refresh(false); } void wxRichTextCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event)) { - SetCaret(NULL); + if (GetCaret() && GetCaret()->IsVisible()) + GetCaret()->Hide(); - if (!IsFrozen()) - Refresh(false); + // if (!IsFrozen()) + // Refresh(false); } /// Left-click @@ -416,13 +439,11 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event) { if (attr.HasFlag(wxTEXT_ATTR_URL)) { - if (GetCursor() != m_urlCursor) - SetCursor(m_urlCursor); + SetCursor(m_urlCursor); } else if (!attr.HasFlag(wxTEXT_ATTR_URL)) { - if (GetCursor() != m_textCursor) - SetCursor(m_textCursor); + SetCursor(m_textCursor); } } } @@ -535,7 +556,15 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) DeleteSelectedContent(& newPos); - GetBuffer().InsertNewlineWithUndo(newPos+1, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); + if (event.ShiftDown()) + { + wxString text; + text = wxRichTextLineBreakChar; + GetBuffer().InsertTextWithUndo(newPos+1, text, this); + } + else + GetBuffer().InsertNewlineWithUndo(newPos+1, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); + EndBatchUndo(); SetDefaultStyleToCursorStyle(); @@ -546,6 +575,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) GetId()); cmdEvent.SetEventObject(this); cmdEvent.SetFlags(flags); + cmdEvent.SetPosition(newPos+1); + if (!GetEventHandler()->ProcessEvent(cmdEvent)) { // Generate conventional event @@ -554,19 +585,17 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) GetEventHandler()->ProcessEvent(textEvent); } + Update(); } else if (event.GetKeyCode() == WXK_BACK) { BeginBatchUndo(_("Delete Text")); - + // 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 (m_caretPosition > -1 && !HasSelection()) { - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(m_caretPosition, m_caretPosition), - m_caretPosition, // Current caret position - m_caretPosition-1, // New caret position - this); + GetBuffer().DeleteRangeWithUndo(wxRichTextRange(m_caretPosition, m_caretPosition), this); } else DeleteSelectedContent(); @@ -583,6 +612,16 @@ 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); + GetEventHandler()->ProcessEvent(cmdEvent); + + Update(); } else if (event.GetKeyCode() == WXK_DELETE) { @@ -591,10 +630,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) // Submit range in character positions, which are greater than caret positions, if (m_caretPosition < GetBuffer().GetRange().GetEnd()+1 && !HasSelection()) { - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(m_caretPosition+1, m_caretPosition+1), - m_caretPosition, // Current caret position - m_caretPosition+1, // New caret position - this); + GetBuffer().DeleteRangeWithUndo(wxRichTextRange(m_caretPosition+1, m_caretPosition+1), this); } else DeleteSelectedContent(); @@ -609,6 +645,16 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) PositionCaret(); SetDefaultStyleToCursorStyle(); } + + wxRichTextEvent cmdEvent( + wxEVT_COMMAND_RICHTEXT_DELETE, + GetId()); + cmdEvent.SetEventObject(this); + cmdEvent.SetFlags(flags); + cmdEvent.SetPosition(m_caretPosition+1); + GetEventHandler()->ProcessEvent(cmdEvent); + + Update(); } else { @@ -723,6 +769,14 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) return; } + wxRichTextEvent cmdEvent( + wxEVT_COMMAND_RICHTEXT_CHARACTER, + GetId()); + cmdEvent.SetEventObject(this); + cmdEvent.SetFlags(flags); + cmdEvent.SetCharacter((wxChar) keycode); + cmdEvent.SetPosition(m_caretPosition+1); + if (keycode == wxT('\t')) { // See if we need to promote or demote the selection or paragraph at the cursor @@ -741,6 +795,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) PromoteList(promoteBy, range, NULL); + GetEventHandler()->ProcessEvent(cmdEvent); + return; } } @@ -751,12 +807,16 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) DeleteSelectedContent(& newPos); wxString str = (wxChar) event.GetKeyCode(); - GetBuffer().InsertTextWithUndo(newPos+1, str, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); + GetBuffer().InsertTextWithUndo(newPos+1, str, this, 0); EndBatchUndo(); SetDefaultStyleToCursorStyle(); ScrollIntoView(m_caretPosition, WXK_RIGHT); + + GetEventHandler()->ProcessEvent(cmdEvent); + + Update(); } } } @@ -768,10 +828,7 @@ bool wxRichTextCtrl::DeleteSelectedContent(long* newPos) if (HasSelection()) { long pos = m_selectionRange.GetStart(); - GetBuffer().DeleteRangeWithUndo(m_selectionRange, - m_caretPosition, // Current caret position - pos, // New caret position - this); + GetBuffer().DeleteRangeWithUndo(m_selectionRange, this); m_selectionRange.SetRange(-2, -2); if (newPos) @@ -2043,6 +2100,13 @@ bool wxRichTextCtrl::Newline() return GetBuffer().InsertNewlineWithUndo(m_caretPosition+1, this); } +/// Insert a line break at the current insertion point. +bool wxRichTextCtrl::LineBreak() +{ + wxString text; + text = wxRichTextLineBreakChar; + return GetBuffer().InsertTextWithUndo(m_caretPosition+1, text, this); +} // ---------------------------------------------------------------------------- // Clipboard operations @@ -2191,6 +2255,8 @@ void wxRichTextCtrl::DoSetSelection(long from, long to, bool WXUNUSED(scrollCare { m_selectionAnchor = from; m_selectionRange.SetRange(from, to-1); + if (from > -2) + m_caretPosition = from-1; Refresh(false); PositionCaret(); @@ -2216,10 +2282,7 @@ void wxRichTextCtrl::Remove(long from, long to) { SelectNone(); - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(from, to), - m_caretPosition, // Current caret position - from, // New caret position - this); + GetBuffer().DeleteRangeWithUndo(wxRichTextRange(from, to), this); LayoutContent(); if (!IsFrozen()) @@ -2506,6 +2569,24 @@ bool wxRichTextCtrl::GetStyle(long position, wxRichTextAttr& style) return GetBuffer().GetStyle(position, style); } +// get the common set of styles for the range +bool wxRichTextCtrl::GetStyleForRange(const wxRichTextRange& range, wxRichTextAttr& style) +{ + wxTextAttrEx styleEx; + if (GetBuffer().GetStyleForRange(range.ToInternal(), styleEx)) + { + style = styleEx; + return true; + } + else + return false; +} + +bool wxRichTextCtrl::GetStyleForRange(const wxRichTextRange& range, wxTextAttrEx& style) +{ + return GetBuffer().GetStyleForRange(range.ToInternal(), style); +} + /// Get the content (uncombined) attributes for this position. bool wxRichTextCtrl::GetUncombinedStyle(long position, wxTextAttr& style) @@ -2686,7 +2767,7 @@ bool wxRichTextCtrl::IsSelectionBold() if (HasSelection()) { wxRichTextAttr attr; - wxRichTextRange range = GetInternalSelectionRange(); + wxRichTextRange range = GetSelectionRange(); attr.SetFlags(wxTEXT_ATTR_FONT_WEIGHT); attr.SetFontWeight(wxBOLD); @@ -2715,7 +2796,7 @@ bool wxRichTextCtrl::IsSelectionItalics() { if (HasSelection()) { - wxRichTextRange range = GetInternalSelectionRange(); + wxRichTextRange range = GetSelectionRange(); wxRichTextAttr attr; attr.SetFlags(wxTEXT_ATTR_FONT_ITALIC); attr.SetFontStyle(wxITALIC); @@ -2745,7 +2826,7 @@ bool wxRichTextCtrl::IsSelectionUnderlined() { if (HasSelection()) { - wxRichTextRange range = GetInternalSelectionRange(); + wxRichTextRange range = GetSelectionRange(); wxRichTextAttr attr; attr.SetFlags(wxTEXT_ATTR_FONT_UNDERLINE); attr.SetFontUnderlined(true); @@ -2817,9 +2898,9 @@ bool wxRichTextCtrl::IsSelectionAligned(wxTextAttrAlignment alignment) { wxRichTextRange range; if (HasSelection()) - range = GetInternalSelectionRange(); + range = GetSelectionRange(); else - range = wxRichTextRange(GetCaretPosition()+1, GetCaretPosition()+1); + range = wxRichTextRange(GetCaretPosition()+1, GetCaretPosition()+2); wxRichTextAttr attr; attr.SetAlignment(alignment); @@ -2848,7 +2929,7 @@ bool wxRichTextCtrl::ApplyStyle(wxRichTextStyleDefinition* def) { // Flags are defined within each definition, so only certain // attributes are applied. - wxRichTextAttr attr(def->GetStyle()); + wxRichTextAttr attr(GetStyleSheet() ? def->GetStyleMergedWithBase(GetStyleSheet()) : def->GetStyle()); int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE; @@ -2918,11 +2999,7 @@ bool wxRichTextCtrl::SetDefaultStyleToCursorStyle() // If at the start of a paragraph, use the next position. long pos = GetAdjustedCaretPosition(GetCaretPosition()); -#if wxRICHTEXT_USE_DYNAMIC_STYLES if (GetUncombinedStyle(pos, attr)) -#else - if (GetStyle(pos, attr)) -#endif { SetDefaultStyle(attr); return true; @@ -2941,6 +3018,18 @@ long wxRichTextCtrl::GetFirstVisiblePosition() const return 0; } +/// Get the first visible point in the window +wxPoint wxRichTextCtrl::GetFirstVisiblePoint() const +{ + int ppuX, ppuY; + int startXUnits, startYUnits; + + GetScrollPixelsPerUnit(& ppuX, & ppuY); + GetViewStart(& startXUnits, & startYUnits); + + return wxPoint(startXUnits * ppuX, startYUnits * ppuY); +} + /// The adjusted caret position is the character position adjusted to take /// into account whether we're at the start of a paragraph, in which case /// style information should be taken from the next position, not current one. @@ -3014,6 +3103,12 @@ bool wxRichTextCtrl::PromoteList(int promoteBy, const wxRichTextRange& range, co return GetBuffer().PromoteList(promoteBy, range.ToInternal(), defName, flags, specifiedLevel); } +/// Deletes the content in the given range +bool wxRichTextCtrl::Delete(const wxRichTextRange& range) +{ + return GetBuffer().DeleteRangeWithUndo(range.ToInternal(), this); +} + const wxArrayString& wxRichTextCtrl::GetAvailableFontNames() { if (sm_availableFontNames.GetCount() == 0)