X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/af33c0ec5f817ca4285cd9ef6f3285cf31e320dd..c40fd721e4fb645c97368d0492ddb1a7a8922c53:/src/richtext/richtextctrl.cpp diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index 885a055858..ff48ec1d7d 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -32,6 +32,7 @@ #include "wx/dcbuffer.h" #include "wx/arrimpl.cpp" #include "wx/fontenum.h" +#include "wx/accel.h" // DLL options compatibility check: #include "wx/app.h" @@ -56,6 +57,69 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_BUFFER_RESET) +#if wxRICHTEXT_USE_OWN_CARET + +/*! + * wxRichTextCaret + * + * This implements a non-flashing cursor in case there + * are platform-specific problems with the generic caret. + * wxRICHTEXT_USE_OWN_CARET is set in richtextbuffer.h. + */ + +class wxRichTextCaret: public wxCaret +{ +public: + // ctors + // ----- + // default - use Create() + wxRichTextCaret() { Init(); } + // creates a block caret associated with the given window + wxRichTextCaret(wxRichTextCtrl *window, int width, int height) + : wxCaret(window, width, height) { Init(); m_richTextCtrl = window; } + wxRichTextCaret(wxRichTextCtrl *window, const wxSize& size) + : wxCaret(window, size) { Init(); m_richTextCtrl = window; } + + virtual ~wxRichTextCaret(); + + // implementation + // -------------- + + // called by wxWindow (not using the event tables) + virtual void OnSetFocus(); + virtual void OnKillFocus(); + + // draw the caret on the given DC + void DoDraw(wxDC *dc); + + // get the visible count + int GetVisibleCount() const { return m_countVisible; } + + // delay repositioning + bool GetNeedsUpdate() const { return m_needsUpdate; } + void SetNeedsUpdate(bool needsUpdate = true ) { m_needsUpdate = needsUpdate; } + +protected: + virtual void DoShow(); + virtual void DoHide(); + virtual void DoMove(); + virtual void DoSize(); + + // refresh the caret + void Refresh(); + +private: + void Init(); + + int m_xOld, + m_yOld; + bool m_hasFocus; // true => our window has focus + bool m_needsUpdate; // must be repositioned + + wxRichTextCtrl* m_richTextCtrl; +}; +#endif + IMPLEMENT_CLASS( wxRichTextCtrl, wxControl ) IMPLEMENT_CLASS( wxRichTextEvent, wxNotifyEvent ) @@ -152,8 +216,6 @@ 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); @@ -168,8 +230,11 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va GetBuffer().Reset(); GetBuffer().SetRichTextCtrl(this); +#if wxRICHTEXT_USE_OWN_CARET + SetCaret(new wxRichTextCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16)); +#else SetCaret(new wxCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16)); - GetCaret()->Show(); +#endif // Tell the sizers to use the given or best size SetInitialSize(size); @@ -189,6 +254,17 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va GetBuffer().AddEventHandler(this); + // Accelerators + wxAcceleratorEntry entries[4]; + + entries[0].Set(wxACCEL_CMD, (int) 'C', wxID_COPY); + entries[1].Set(wxACCEL_CMD, (int) 'X', wxID_CUT); + entries[2].Set(wxACCEL_CMD, (int) 'V', wxID_PASTE); + entries[3].Set(wxACCEL_CMD, (int) 'A', wxID_SELECTALL); + + wxAcceleratorTable accel(4, entries); + SetAcceleratorTable(accel); + return true; } @@ -250,8 +326,10 @@ void wxRichTextCtrl::Clear() /// Painting void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) { - if (GetCaret() && GetCaret()->IsVisible()) +#if !wxRICHTEXT_USE_OWN_CARET + if (GetCaret() && !IsFrozen()) GetCaret()->Hide(); +#endif { #if wxRICHTEXT_BUFFERED_PAINTING @@ -284,12 +362,19 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) } GetBuffer().Draw(dc, GetBuffer().GetRange(), GetInternalSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */); +#if wxRICHTEXT_USE_OWN_CARET + if (GetCaret()->IsVisible()) + { + ((wxRichTextCaret*) GetCaret())->DoDraw(& dc); + } +#endif } - if (GetCaret() && !GetCaret()->IsVisible()) +#if !wxRICHTEXT_USE_OWN_CARET + if (GetCaret()) GetCaret()->Show(); - PositionCaret(); +#endif } // Empty implementation, to prevent flicker @@ -301,22 +386,33 @@ void wxRichTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event)) { if (GetCaret()) { - if (!GetCaret()->IsVisible()) - GetCaret()->Show(); +#if !wxRICHTEXT_USE_OWN_CARET PositionCaret(); +#endif + GetCaret()->Show(); } - // if (!IsFrozen()) - // Refresh(false); +#if defined(__WXGTK__) && !wxRICHTEXT_USE_OWN_CARET + // Work around dropouts when control is focused + if (!IsFrozen()) + { + Refresh(false); + } +#endif } void wxRichTextCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event)) { - if (GetCaret() && GetCaret()->IsVisible()) + if (GetCaret()) GetCaret()->Hide(); - // if (!IsFrozen()) - // Refresh(false); +#if defined(__WXGTK__) && !wxRICHTEXT_USE_OWN_CARET + // Work around dropouts when control is focused + if (!IsFrozen()) + { + Refresh(false); + } +#endif } void wxRichTextCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event)) @@ -364,14 +460,10 @@ void wxRichTextCtrl::OnLeftClick(wxMouseEvent& event) if (event.ShiftDown()) { - bool extendSel = false; if (m_selectionRange.GetStart() == -2) - extendSel = ExtendSelection(oldCaretPos, m_caretPosition, wxRICHTEXT_SHIFT_DOWN); + ExtendSelection(oldCaretPos, m_caretPosition, wxRICHTEXT_SHIFT_DOWN); else - extendSel = ExtendSelection(m_caretPosition, m_caretPosition, wxRICHTEXT_SHIFT_DOWN); - - if (extendSel) - Refresh(false); + ExtendSelection(m_caretPosition, m_caretPosition, wxRICHTEXT_SHIFT_DOWN); } else SelectNone(); @@ -398,7 +490,7 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event) wxPoint logicalPt = event.GetLogicalPosition(dc); int hit = GetBuffer().HitTest(dc, logicalPt, position); - if (hit != wxRICHTEXT_HITTEST_NONE) + if ((hit != wxRICHTEXT_HITTEST_NONE) && !(hit & wxRICHTEXT_HITTEST_OUTSIDE)) { wxRichTextEvent cmdEvent( wxEVT_COMMAND_RICHTEXT_LEFT_CLICK, @@ -500,13 +592,10 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event) if (m_caretPosition != position) { - bool extendSel = ExtendSelection(m_caretPosition, position, wxRICHTEXT_SHIFT_DOWN); + ExtendSelection(m_caretPosition, position, wxRICHTEXT_SHIFT_DOWN); MoveCaret(position, caretAtLineStart); SetDefaultStyleToCursorStyle(); - - if (extendSel) - Refresh(false); } } } @@ -608,6 +697,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) wxString text; text = wxRichTextLineBreakChar; GetBuffer().InsertTextWithUndo(newPos+1, text, this); + m_caretAtLineStart = true; + PositionCaret(); } else GetBuffer().InsertNewlineWithUndo(newPos+1, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE|wxRICHTEXT_INSERT_INTERACTIVE); @@ -642,7 +733,19 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) // 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), this); + bool processed = false; + if (event.CmdDown()) + { + long pos = wxRichTextCtrl::FindNextWordPosition(-1); + if (pos != -1 && (pos < m_caretPosition)) + { + GetBuffer().DeleteRangeWithUndo(wxRichTextRange(pos+1, m_caretPosition), this); + processed = true; + } + } + + if (!processed) + GetBuffer().DeleteRangeWithUndo(wxRichTextRange(m_caretPosition, m_caretPosition), this); } else DeleteSelectedContent(); @@ -994,6 +1097,8 @@ bool wxRichTextCtrl::ExtendSelection(long oldPos, long newPos, int flags) { if (flags & wxRICHTEXT_SHIFT_DOWN) { + wxRichTextRange oldSelection = m_selectionRange; + // If not currently selecting, start selecting if (m_selectionRange.GetStart() == -2) { @@ -1014,6 +1119,8 @@ bool wxRichTextCtrl::ExtendSelection(long oldPos, long newPos, int flags) m_selectionRange.SetRange(newPos+1, m_selectionAnchor); } + RefreshForSelectionChange(oldSelection, m_selectionRange); + if (m_selectionRange.GetStart() > m_selectionRange.GetEnd()) { wxLogDebug(wxT("Strange selection range")); @@ -1128,7 +1235,11 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode) } } } - PositionCaret(); + +#if !wxRICHTEXT_USE_OWN_CARET + if (scrolled) +#endif + PositionCaret(); return scrolled; } @@ -1283,8 +1394,6 @@ bool wxRichTextCtrl::MoveRight(int noPositions, int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } else @@ -1312,8 +1421,6 @@ bool wxRichTextCtrl::MoveLeft(int noPositions, int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } else @@ -1403,8 +1510,6 @@ bool wxRichTextCtrl::MoveDown(int noLines, int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } @@ -1426,8 +1531,6 @@ bool wxRichTextCtrl::MoveToParagraphEnd(int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } @@ -1449,8 +1552,6 @@ bool wxRichTextCtrl::MoveToParagraphStart(int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } @@ -1474,8 +1575,6 @@ bool wxRichTextCtrl::MoveToLineEnd(int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } @@ -1501,8 +1600,6 @@ bool wxRichTextCtrl::MoveToLineStart(int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } @@ -1522,8 +1619,6 @@ bool wxRichTextCtrl::MoveHome(int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } else @@ -1545,8 +1640,6 @@ bool wxRichTextCtrl::MoveEnd(int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } else @@ -1586,8 +1679,6 @@ bool wxRichTextCtrl::PageDown(int noPages, int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } } @@ -1705,8 +1796,6 @@ bool wxRichTextCtrl::WordLeft(int WXUNUSED(n), int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } @@ -1729,8 +1818,6 @@ bool wxRichTextCtrl::WordRight(int WXUNUSED(n), int flags) PositionCaret(); SetDefaultStyleToCursorStyle(); - if (extendSel) - Refresh(false); return true; } @@ -1762,6 +1849,15 @@ void wxRichTextCtrl::OnSize(wxSizeEvent& event) /// Idle-time processing void wxRichTextCtrl::OnIdle(wxIdleEvent& event) { +#if wxRICHTEXT_USE_OWN_CARET + if (((wxRichTextCaret*) GetCaret())->GetNeedsUpdate()) + { + ((wxRichTextCaret*) GetCaret())->SetNeedsUpdate(false); + PositionCaret(); + GetCaret()->Show(); + } +#endif + const int layoutInterval = wxRICHTEXT_DEFAULT_LAYOUT_INTERVAL; if (m_fullLayoutRequired && (wxGetLocalTimeMillis() > (m_fullLayoutTime + layoutInterval))) @@ -1787,7 +1883,14 @@ void wxRichTextCtrl::OnIdle(wxIdleEvent& event) /// Scrolling void wxRichTextCtrl::OnScroll(wxScrollWinEvent& event) { - // Not used +#if wxRICHTEXT_USE_OWN_CARET + if (!((wxRichTextCaret*) GetCaret())->GetNeedsUpdate()) + { + GetCaret()->Hide(); + ((wxRichTextCaret*) GetCaret())->SetNeedsUpdate(); + } +#endif + event.Skip(); } @@ -1817,14 +1920,31 @@ void wxRichTextCtrl::SetupScrollbars(bool atTop) if (!atTop) GetViewStart(& startX, & startY); - int maxPositionX = 0; // wxMax(sz.x - clientSize.x, 0); + int maxPositionX = 0; int maxPositionY = (int) ((((float)(wxMax((unitsY*pixelsPerUnit) - clientSize.y, 0)))/((float)pixelsPerUnit)) + 0.5); + int newStartX = wxMin(maxPositionX, startX); + int newStartY = wxMin(maxPositionY, startY); + + int oldPPUX, oldPPUY; + int oldStartX, oldStartY; + int oldVirtualSizeX = 0, oldVirtualSizeY = 0; + GetScrollPixelsPerUnit(& oldPPUX, & oldPPUY); + GetViewStart(& oldStartX, & oldStartY); + GetVirtualSize(& oldVirtualSizeX, & oldVirtualSizeY); + if (oldPPUY > 0) + oldVirtualSizeY /= oldPPUY; + + if (oldPPUX == 0 && oldPPUY == pixelsPerUnit && oldVirtualSizeY == unitsY && oldStartX == newStartX && oldStartY == newStartY) + return; + + // Don't set scrollbars if there were none before, and there will be none now. + if (oldPPUY != 0 && (oldVirtualSizeY < clientSize.y) && (unitsY*pixelsPerUnit < clientSize.y)) + return; + // Move to previous scroll position if // possible - SetScrollbars(0, pixelsPerUnit, - 0, unitsY, - wxMin(maxPositionX, startX), wxMin(maxPositionY, startY)); + SetScrollbars(0, pixelsPerUnit, 0, unitsY, newStartX, newStartY); } /// Paint the background @@ -1870,7 +1990,7 @@ bool wxRichTextCtrl::RecreateBuffer(const wxSize& size) bool wxRichTextCtrl::DoLoadFile(const wxString& filename, int fileType) { - bool success = GetBuffer().LoadFile(filename, fileType); + bool success = GetBuffer().LoadFile(filename, (wxRichTextFileType)fileType); if (success) m_filename = filename; @@ -1894,7 +2014,7 @@ bool wxRichTextCtrl::DoLoadFile(const wxString& filename, int fileType) bool wxRichTextCtrl::DoSaveFile(const wxString& filename, int fileType) { - if (GetBuffer().SaveFile(filename, fileType)) + if (GetBuffer().SaveFile(filename, (wxRichTextFileType)fileType)) { m_filename = filename; @@ -1915,13 +2035,17 @@ bool wxRichTextCtrl::DoSaveFile(const wxString& filename, int fileType) /// Add a new paragraph of text to the end of the buffer wxRichTextRange wxRichTextCtrl::AddParagraph(const wxString& text) { - return GetBuffer().AddParagraph(text); + wxRichTextRange range = GetBuffer().AddParagraph(text); + LayoutContent(); + return range; } /// Add an image wxRichTextRange wxRichTextCtrl::AddImage(const wxImage& image) { - return GetBuffer().AddImage(image); + wxRichTextRange range = GetBuffer().AddImage(image); + LayoutContent(); + return range; } // ---------------------------------------------------------------------------- @@ -1938,7 +2062,13 @@ void wxRichTextCtrl::SelectAll() void wxRichTextCtrl::SelectNone() { if (!(GetSelectionRange() == wxRichTextRange(-2, -2))) - SetSelection(-2, -2); + { + wxRichTextRange oldSelection = m_selectionRange; + + m_selectionRange = wxRichTextRange(-2, -2); + + RefreshForSelectionChange(oldSelection, m_selectionRange); + } m_selectionAnchor = -2; } @@ -1957,6 +2087,9 @@ bool wxRichTextCtrl::SelectWord(long position) if (!para) return false; + if (position == para->GetRange().GetEnd()) + position --; + long positionStart = position; long positionEnd = position; @@ -1984,6 +2117,9 @@ bool wxRichTextCtrl::SelectWord(long position) if (positionEnd >= para->GetRange().GetEnd()) positionEnd = para->GetRange().GetEnd(); + if (positionEnd < positionStart) + return false; + SetSelection(positionStart, positionEnd+1); if (positionStart >= 0) @@ -2064,13 +2200,27 @@ wxString wxRichTextCtrl::GetRange(long from, long to) const void wxRichTextCtrl::DoSetValue(const wxString& value, int flags) { - Clear(); + // Don't call Clear here, since it always sends a text updated event + m_buffer.ResetAndClearCommands(); + m_buffer.SetDirty(true); + m_caretPosition = -1; + m_caretPositionForDefaultStyle = -2; + m_caretAtLineStart = false; + m_selectionRange.SetRange(-2, -2); + + Scroll(0,0); + + if (!IsFrozen()) + { + LayoutContent(); + Refresh(false); + } if (!value.IsEmpty()) { // Remove empty paragraph GetBuffer().Clear(); - DoWriteText(value); + DoWriteText(value, flags); // for compatibility, don't move the cursor when doing SetValue() SetInsertionPoint(0); @@ -2107,7 +2257,7 @@ void wxRichTextCtrl::AppendText(const wxString& text) } /// Write an image at the current insertion point -bool wxRichTextCtrl::WriteImage(const wxImage& image, int bitmapType) +bool wxRichTextCtrl::WriteImage(const wxImage& image, wxBitmapType bitmapType) { wxRichTextImageBlock imageBlock; @@ -2118,7 +2268,7 @@ bool wxRichTextCtrl::WriteImage(const wxImage& image, int bitmapType) return false; } -bool wxRichTextCtrl::WriteImage(const wxString& filename, int bitmapType) +bool wxRichTextCtrl::WriteImage(const wxString& filename, wxBitmapType bitmapType) { wxRichTextImageBlock imageBlock; @@ -2134,7 +2284,7 @@ bool wxRichTextCtrl::WriteImage(const wxRichTextImageBlock& imageBlock) return GetBuffer().InsertImageWithUndo(m_caretPosition+1, imageBlock, this); } -bool wxRichTextCtrl::WriteImage(const wxBitmap& bitmap, int bitmapType) +bool wxRichTextCtrl::WriteImage(const wxBitmap& bitmap, wxBitmapType bitmapType) { if (bitmap.Ok()) { @@ -2305,18 +2455,25 @@ void wxRichTextCtrl::SetSelection(long from, long to) } DoSetSelection(from, to); - SetDefaultStyleToCursorStyle(); } void wxRichTextCtrl::DoSetSelection(long from, long to, bool WXUNUSED(scrollCaret)) { - m_selectionAnchor = from; - m_selectionRange.SetRange(from, to-1); - if (from > -2) - m_caretPosition = from-1; + if (from == to) + { + SelectNone(); + } + else + { + wxRichTextRange oldSelection = m_selectionRange; + m_selectionAnchor = from; + m_selectionRange.SetRange(from, to-1); + if (from > -2) + m_caretPosition = from-1; - Refresh(false); - PositionCaret(); + RefreshForSelectionChange(oldSelection, m_selectionRange); + PositionCaret(); + } } // ---------------------------------------------------------------------------- @@ -2339,7 +2496,7 @@ void wxRichTextCtrl::Remove(long from, long to) { SelectNone(); - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(from, to), this); + GetBuffer().DeleteRangeWithUndo(wxRichTextRange(from, to-1), this); LayoutContent(); if (!IsFrozen()) @@ -2652,8 +2809,11 @@ void wxRichTextCtrl::PositionCaret() wxPoint pt = GetPhysicalPoint(newPt); if (GetCaret()->GetPosition() != pt || GetCaret()->GetSize() != newSz) { + GetCaret()->Hide(); + if (GetCaret()->GetSize() != newSz) + GetCaret()->SetSize(newSz); GetCaret()->Move(pt); - GetCaret()->SetSize(newSz); + GetCaret()->Show(); } } } @@ -2858,7 +3018,11 @@ bool wxRichTextCtrl::ApplyBoldToSelection() if (HasSelection()) return SetStyleEx(GetSelectionRange(), attr, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY); else - SetAndShowDefaultStyle(attr); + { + wxRichTextAttr current = GetDefaultStyleEx(); + current.Apply(attr); + SetAndShowDefaultStyle(current); + } return true; } @@ -2872,7 +3036,11 @@ bool wxRichTextCtrl::ApplyItalicToSelection() if (HasSelection()) return SetStyleEx(GetSelectionRange(), attr, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY); else - SetAndShowDefaultStyle(attr); + { + wxRichTextAttr current = GetDefaultStyleEx(); + current.Apply(attr); + SetAndShowDefaultStyle(current); + } return true; } @@ -2886,7 +3054,11 @@ bool wxRichTextCtrl::ApplyUnderlineToSelection() if (HasSelection()) return SetStyleEx(GetSelectionRange(), attr, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY); else - SetAndShowDefaultStyle(attr); + { + wxRichTextAttr current = GetDefaultStyleEx(); + current.Apply(attr); + SetAndShowDefaultStyle(current); + } return true; } @@ -2964,7 +3136,9 @@ bool wxRichTextCtrl::ApplyStyle(wxRichTextStyleDefinition* def) return SetStyleEx(GetSelectionRange(), attr, flags); else { - SetAndShowDefaultStyle(attr); + wxRichTextAttr current = GetDefaultStyleEx(); + current.Apply(attr); + SetAndShowDefaultStyle(current); return true; } } @@ -3133,5 +3307,175 @@ void wxRichTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event) Refresh(); } +// Refresh the area affected by a selection change +bool wxRichTextCtrl::RefreshForSelectionChange(const wxRichTextRange& oldSelection, const wxRichTextRange& newSelection) +{ + // Calculate the refresh rectangle - just the affected lines + long firstPos, lastPos; + if (oldSelection.GetStart() == -2 && newSelection.GetStart() != -2) + { + firstPos = newSelection.GetStart(); + lastPos = newSelection.GetEnd(); + } + else if (oldSelection.GetStart() != -2 && newSelection.GetStart() == -2) + { + firstPos = oldSelection.GetStart(); + lastPos = oldSelection.GetEnd(); + } + else if (oldSelection.GetStart() == -2 && newSelection.GetStart() == -2) + { + return false; + } + else + { + firstPos = wxMin(oldSelection.GetStart(), newSelection.GetStart()); + lastPos = wxMax(oldSelection.GetEnd(), newSelection.GetEnd()); + } + + wxRichTextLine* firstLine = GetBuffer().GetLineAtPosition(firstPos); + wxRichTextLine* lastLine = GetBuffer().GetLineAtPosition(lastPos); + + if (firstLine && lastLine) + { + wxSize clientSize = GetClientSize(); + wxPoint pt1 = GetPhysicalPoint(firstLine->GetAbsolutePosition()); + wxPoint pt2 = GetPhysicalPoint(lastLine->GetAbsolutePosition()) + wxPoint(0, lastLine->GetSize().y); + + pt1.x = 0; + pt1.y = wxMax(0, pt1.y); + pt2.x = 0; + pt2.y = wxMin(clientSize.y, pt2.y); + + wxRect rect(pt1, wxSize(clientSize.x, pt2.y - pt1.y)); + RefreshRect(rect, false); + } + else + Refresh(false); + + return true; +} + +#if wxRICHTEXT_USE_OWN_CARET + +// ---------------------------------------------------------------------------- +// initialization and destruction +// ---------------------------------------------------------------------------- + +void wxRichTextCaret::Init() +{ + m_hasFocus = true; + + m_xOld = + m_yOld = -1; + m_richTextCtrl = NULL; + m_needsUpdate = false; +} + +wxRichTextCaret::~wxRichTextCaret() +{ +} + +// ---------------------------------------------------------------------------- +// showing/hiding/moving the caret (base class interface) +// ---------------------------------------------------------------------------- + +void wxRichTextCaret::DoShow() +{ + Refresh(); +} + +void wxRichTextCaret::DoHide() +{ + Refresh(); +} + +void wxRichTextCaret::DoMove() +{ + if (IsVisible()) + { + Refresh(); + + if (m_xOld != -1 && m_yOld != -1) + { + if (m_richTextCtrl) + { + wxRect rect(GetPosition(), GetSize()); + m_richTextCtrl->RefreshRect(rect, false); + } + } + } + + m_xOld = m_x; + m_yOld = m_y; +} + +void wxRichTextCaret::DoSize() +{ + int countVisible = m_countVisible; + if (countVisible > 0) + { + m_countVisible = 0; + DoHide(); + } + + if (countVisible > 0) + { + m_countVisible = countVisible; + DoShow(); + } +} + +// ---------------------------------------------------------------------------- +// handling the focus +// ---------------------------------------------------------------------------- + +void wxRichTextCaret::OnSetFocus() +{ + m_hasFocus = true; + + if ( IsVisible() ) + Refresh(); +} + +void wxRichTextCaret::OnKillFocus() +{ + m_hasFocus = false; +} + +// ---------------------------------------------------------------------------- +// drawing the caret +// ---------------------------------------------------------------------------- + +void wxRichTextCaret::Refresh() +{ + if (m_richTextCtrl) + { + wxRect rect(GetPosition(), GetSize()); + m_richTextCtrl->RefreshRect(rect, false); + } +} + +void wxRichTextCaret::DoDraw(wxDC *dc) +{ + dc->SetPen( *wxBLACK_PEN ); + + dc->SetBrush(*(m_hasFocus ? wxBLACK_BRUSH : wxTRANSPARENT_BRUSH)); + dc->SetPen(*wxBLACK_PEN); + + // VZ: unfortunately, the rectangle comes out a pixel smaller when this is + // done under wxGTK - no idea why + //dc->SetLogicalFunction(wxINVERT); + + wxPoint pt(m_x, m_y); + + if (m_richTextCtrl) + { + pt = m_richTextCtrl->GetLogicalPoint(pt); + } + dc->DrawRectangle(pt.x, pt.y, m_width, m_height); +} +#endif + // wxRICHTEXT_USE_OWN_CARET + #endif // wxUSE_RICHTEXT