]> git.saurik.com Git - wxWidgets.git/blobdiff - src/richtext/richtextctrl.cpp
deal with the situation when a (dynamic) event handler disconnects itself during...
[wxWidgets.git] / src / richtext / richtextctrl.cpp
index 297a3dea4f1252fad8038099e9ca971b74470966..04712e599178cee6241d5ef1a86b97bfbd7100ba 100644 (file)
   #pragma hdrstop
 #endif
 
+#if wxUSE_RICHTEXT
+
+#include "wx/richtext/richtextctrl.h"
+
 #ifndef WX_PRECOMP
   #include "wx/wx.h"
 #endif
 
-#include "wx/image.h"
-
-#if wxUSE_RICHTEXT
-
 #include "wx/textfile.h"
 #include "wx/ffile.h"
 #include "wx/settings.h"
 #include "wx/filename.h"
 #include "wx/dcbuffer.h"
-
-#include "wx/richtext/richtextctrl.h"
 #include "wx/arrimpl.cpp"
 
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_RICHTEXT_ITEM_SELECTED)
@@ -187,14 +185,14 @@ void wxRichTextCtrl::Freeze()
 }
 
 /// Call Thaw to refresh
-void wxRichTextCtrl::Thaw(bool refresh)
+void wxRichTextCtrl::Thaw()
 {
     m_freezeCount --;
 
-    if (m_freezeCount == 0 && refresh)
+    if (m_freezeCount == 0)
     {
         SetupScrollbars();
-        Refresh();
+        Refresh(false);
     }
 }
 
@@ -210,7 +208,7 @@ void wxRichTextCtrl::Clear()
     if (m_freezeCount == 0)
     {
         SetupScrollbars();
-        Refresh();
+        Refresh(false);
     }
     SendUpdateEvent();
 }
@@ -224,19 +222,19 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
     {
         wxBufferedPaintDC dc(this, m_bufferBitmap);
         //wxLogDebug(wxT("OnPaint"));
-        
+
         PrepareDC(dc);
-        
+
         if (m_freezeCount > 0)
             return;
-        
+
         dc.SetFont(GetFont());
-        
+
         // Paint the background
         PaintBackground(dc);
-        
+
         wxRegion dirtyRegion = GetUpdateRegion();
-        
+
         wxRect drawingArea(GetLogicalPoint(wxPoint(0, 0)), GetClientSize());
         wxRect availableSpace(GetClientSize());
         if (GetBuffer().GetDirty())
@@ -245,7 +243,7 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
             GetBuffer().SetDirty(false);
             SetupScrollbars();
         }
-        
+
         GetBuffer().Draw(dc, GetBuffer().GetRange(), GetSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */);
     }
 
@@ -268,7 +266,7 @@ void wxRichTextCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event))
     PositionCaret();
 
     if (!IsFrozen())
-        Refresh();
+        Refresh(false);
 }
 
 void wxRichTextCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event))
@@ -276,7 +274,7 @@ void wxRichTextCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event))
     SetCaret(NULL);
 
     if (!IsFrozen())
-        Refresh();
+        Refresh(false);
 }
 
 /// Left-click
@@ -389,7 +387,7 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event)
             SetDefaultStyleToCursorStyle();
 
             if (extendSel)
-                Refresh();
+                Refresh(false);
         }
     }
 }
@@ -435,7 +433,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
         event.GetKeyCode() == WXK_NEXT ||
         event.GetKeyCode() == WXK_END)
     {
-        Navigate(event.GetKeyCode(), flags);
+        KeyboardNavigate(event.GetKeyCode(), flags);
     }
     else if (event.GetKeyCode() == WXK_RETURN)
     {
@@ -456,6 +454,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
 
         EndBatchUndo();
         SetDefaultStyleToCursorStyle();
+
+        ScrollIntoView(m_caretPosition, WXK_RIGHT);
     }
     else if (event.GetKeyCode() == WXK_BACK)
     {
@@ -485,6 +485,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
             SetDefaultStyleToCursorStyle();
         }
 
+        ScrollIntoView(m_caretPosition, WXK_LEFT);
     }
     else if (event.GetKeyCode() == WXK_DELETE)
     {
@@ -526,6 +527,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
         EndBatchUndo();
 
         SetDefaultStyleToCursorStyle();
+        ScrollIntoView(m_caretPosition, WXK_RIGHT);
     }
 #if 0
     else
@@ -584,10 +586,9 @@ Adding Shift does the above but starts/extends selection.
 
  */
 
-bool wxRichTextCtrl::Navigate(int keyCode, int flags)
+bool wxRichTextCtrl::KeyboardNavigate(int keyCode, int flags)
 {
     bool success = false;
-    Freeze();
 
     if (keyCode == WXK_RIGHT)
     {
@@ -646,8 +647,6 @@ bool wxRichTextCtrl::Navigate(int keyCode, int flags)
         SetDefaultStyleToCursorStyle();
     }
 
-    Thaw(false);
-
     return success;
 }
 
@@ -704,7 +703,7 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode)
     startX = 0;
     startY = startY * ppuY;
 
-    int sx, sy;
+    int sx = 0, sy = 0;
     GetVirtualSize(& sx, & sy);
     sx = 0;
     if (ppuY != 0)
@@ -797,7 +796,7 @@ bool wxRichTextCtrl::IsPositionVisible(long pos) const
     startX = 0;
     startY = startY * ppuY;
 
-    int sx, sy;
+    int sx = 0, sy = 0;
     GetVirtualSize(& sx, & sy);
     sx = 0;
     if (ppuY != 0)
@@ -939,7 +938,7 @@ bool wxRichTextCtrl::MoveRight(int noPositions, int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
     else
@@ -968,7 +967,7 @@ bool wxRichTextCtrl::MoveLeft(int noPositions, int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
     else
@@ -1059,11 +1058,11 @@ bool wxRichTextCtrl::MoveDown(int noLines, int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
-    else
-        return false;
+
+    return false;
 }
 
 /// Move to the end of the paragraph
@@ -1082,7 +1081,7 @@ bool wxRichTextCtrl::MoveToParagraphEnd(int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
 
@@ -1105,7 +1104,7 @@ bool wxRichTextCtrl::MoveToParagraphStart(int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
 
@@ -1130,7 +1129,7 @@ bool wxRichTextCtrl::MoveToLineEnd(int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
 
@@ -1157,7 +1156,7 @@ bool wxRichTextCtrl::MoveToLineStart(int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
 
@@ -1178,7 +1177,7 @@ bool wxRichTextCtrl::MoveHome(int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
     else
@@ -1201,7 +1200,7 @@ bool wxRichTextCtrl::MoveEnd(int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
     else
@@ -1242,7 +1241,7 @@ bool wxRichTextCtrl::PageDown(int noPages, int flags)
                 SetDefaultStyleToCursorStyle();
 
                 if (extendSel)
-                    Refresh();
+                    Refresh(false);
                 return true;
             }
         }
@@ -1341,7 +1340,7 @@ bool wxRichTextCtrl::WordLeft(int WXUNUSED(n), int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
 
@@ -1365,7 +1364,7 @@ bool wxRichTextCtrl::WordRight(int WXUNUSED(n), int flags)
         SetDefaultStyleToCursorStyle();
 
         if (extendSel)
-            Refresh();
+            Refresh(false);
         return true;
     }
 
@@ -1381,7 +1380,7 @@ void wxRichTextCtrl::OnSize(wxSizeEvent& event)
         m_fullLayoutRequired = true;
         m_fullLayoutTime = wxGetLocalTimeMillis();
         m_fullLayoutSavedPosition = GetFirstVisiblePosition();
-        Layout(true /* onlyVisibleRect */);
+        LayoutContent(true /* onlyVisibleRect */);
     }
     else
         GetBuffer().Invalidate(wxRICHTEXT_ALL);
@@ -1403,7 +1402,7 @@ void wxRichTextCtrl::OnIdle(wxIdleEvent& event)
         m_fullLayoutTime = 0;
         GetBuffer().Invalidate(wxRICHTEXT_ALL);
         ShowPosition(m_fullLayoutSavedPosition);
-        Refresh();
+        Refresh(false);
     }
     event.Skip();
 }
@@ -1497,10 +1496,10 @@ bool wxRichTextCtrl::LoadFile(const wxString& filename, int type)
 
     DiscardEdits();
     SetInsertionPoint(0);
-    Layout();
+    LayoutContent();
     PositionCaret();
     SetupScrollbars(true);
-    Refresh();
+    Refresh(false);
     SendUpdateEvent();
 
     if (success)
@@ -1582,17 +1581,20 @@ wxString wxRichTextCtrl::GetStringSelection() const
 }
 
 // do the window-specific processing after processing the update event
+#if !wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
 void wxRichTextCtrl::DoUpdateWindowUI(wxUpdateUIEvent& event)
 {
-    if ( event.GetSetEnabled() )
-        Enable(event.GetEnabled());
+    // call inherited
+    wxWindowBase::DoUpdateWindowUI(event);
 
+    // update text
     if ( event.GetSetText() )
     {
         if ( event.GetText() != GetValue() )
             SetValue(event.GetText());
     }
 }
+#endif // !wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
 
 // ----------------------------------------------------------------------------
 // hit testing
@@ -1623,14 +1625,20 @@ wxRichTextCtrl::HitTest(const wxPoint& pt,
     ((wxRichTextCtrl*)this)->PrepareDC(dc);
 
     int hit = ((wxRichTextCtrl*)this)->GetBuffer().HitTest(dc, pt, *pos);
-    if (hit == wxRICHTEXT_HITTEST_BEFORE)
-        return wxTE_HT_BEFORE;
-    else if (hit == wxRICHTEXT_HITTEST_AFTER)
-        return wxTE_HT_BEYOND;
-    else if (hit == wxRICHTEXT_HITTEST_ON)
-        return wxTE_HT_ON_TEXT;
-    else
-        return wxTE_HT_UNKNOWN;
+
+    switch ( hit )
+    {
+        case wxRICHTEXT_HITTEST_BEFORE:
+            return wxTE_HT_BEFORE;
+
+        case wxRICHTEXT_HITTEST_AFTER:
+            return wxTE_HT_BEYOND;
+
+        case wxRICHTEXT_HITTEST_ON:
+            return wxTE_HT_ON_TEXT;
+    }
+
+    return wxTE_HT_UNKNOWN;
 }
 
 // ----------------------------------------------------------------------------
@@ -1700,8 +1708,8 @@ bool wxRichTextCtrl::WriteImage(const wxImage& image, int bitmapType)
     wxImage image2 = image;
     if (imageBlock.MakeImageBlock(image2, bitmapType))
         return WriteImage(imageBlock);
-    else
-        return false;
+
+    return false;
 }
 
 bool wxRichTextCtrl::WriteImage(const wxString& filename, int bitmapType)
@@ -1711,8 +1719,8 @@ bool wxRichTextCtrl::WriteImage(const wxString& filename, int bitmapType)
     wxImage image;
     if (imageBlock.MakeImageBlock(filename, bitmapType, image, false))
         return WriteImage(imageBlock);
-    else
-        return false;
+
+    return false;
 }
 
 bool wxRichTextCtrl::WriteImage(const wxRichTextImageBlock& imageBlock)
@@ -1729,9 +1737,8 @@ bool wxRichTextCtrl::WriteImage(const wxBitmap& bitmap, int bitmapType)
         wxImage image = bitmap.ConvertToImage();
         if (image.Ok() && imageBlock.MakeImageBlock(image, bitmapType))
             return WriteImage(imageBlock);
-        else
-            return false;
     }
+
     return false;
 }
 
@@ -1763,8 +1770,8 @@ void wxRichTextCtrl::Cut()
         GetBuffer().CopyToClipboard(range);
 
         DeleteSelectedContent();
-        Layout();
-        Refresh();
+        LayoutContent();
+        Refresh(false);
     }
 }
 
@@ -1887,7 +1894,7 @@ void wxRichTextCtrl::DoSetSelection(long from, long to, bool WXUNUSED(scrollCare
 {
     m_selectionAnchor = from;
     m_selectionRange.SetRange(from, to);
-    Refresh();
+    Refresh(false);
     PositionCaret();
 }
 
@@ -1915,9 +1922,9 @@ void wxRichTextCtrl::Remove(long from, long to)
         from,                           // New caret position
         this);
 
-    Layout();
+    LayoutContent();
     if (!IsFrozen())
-        Refresh();
+        Refresh(false);
 }
 
 bool wxRichTextCtrl::IsModified() const
@@ -2259,8 +2266,8 @@ bool wxRichTextCtrl::GetCaretPositionForIndex(long position, wxRect& rect)
         rect = wxRect(pt, wxSize(wxRICHTEXT_DEFAULT_CARET_WIDTH, height));
         return true;
     }
-    else
-        return false;
+
+    return false;
 }
 
 /// Gets the line for the visible caret position. If the caret is
@@ -2289,7 +2296,7 @@ wxRichTextLine* wxRichTextCtrl::GetVisibleLineForCaretPosition(long caretPositio
 bool wxRichTextCtrl::MoveCaret(long pos, bool showAtLineStart)
 {
     if (GetBuffer().GetDirty())
-        Layout();
+        LayoutContent();
 
     if (pos <= GetBuffer().GetRange().GetEnd())
     {
@@ -2305,7 +2312,7 @@ bool wxRichTextCtrl::MoveCaret(long pos, bool showAtLineStart)
 
 /// Layout the buffer: which we must do before certain operations, such as
 /// setting the caret position.
-bool wxRichTextCtrl::Layout(bool onlyVisibleRect)
+bool wxRichTextCtrl::LayoutContent(bool onlyVisibleRect)
 {
     if (GetBuffer().GetDirty() || onlyVisibleRect)
     {
@@ -2321,17 +2328,17 @@ bool wxRichTextCtrl::Layout(bool onlyVisibleRect)
             flags |= wxRICHTEXT_LAYOUT_SPECIFIED_RECT;
             availableSpace.SetPosition(GetLogicalPoint(wxPoint(0, 0)));
         }
-        
+
         wxClientDC dc(this);
         dc.SetFont(GetFont());
-        
+
         PrepareDC(dc);
-        
+
         GetBuffer().Defragment();
         GetBuffer().UpdateRanges();     // If items were deleted, ranges need recalculation
         GetBuffer().Layout(dc, availableSpace, flags);
         GetBuffer().SetDirty(false);
-        
+
         if (!IsFrozen())
             SetupScrollbars();
     }
@@ -2510,8 +2517,8 @@ bool wxRichTextCtrl::SetDefaultStyleToCursorStyle()
         SetDefaultStyle(attr);
         return true;
     }
-    else
-        return false;
+
+    return false;
 }
 
 /// Returns the first visible position in the current view