]> git.saurik.com Git - wxWidgets.git/blobdiff - src/richtext/richtextctrl.cpp
Warning fix.
[wxWidgets.git] / src / richtext / richtextctrl.cpp
index e4ec1418d0a0ce0cd1945beeaafddbd36725e1b9..b3cef4837e9a0f8132a00710ea45c493ae0a1c7e 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        richtext/richeditctrl.cpp
+// Name:        src/richtext/richeditctrl.cpp
 // Purpose:     A rich edit control
 // Author:      Julian Smart
 // Modified by:
@@ -13,7 +13,7 @@
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-  #pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #if wxUSE_RICHTEXT
 #include "wx/richtext/richtextctrl.h"
 
 #ifndef WX_PRECOMP
-  #include "wx/wx.h"
+    #include "wx/wx.h"
+    #include "wx/settings.h"
 #endif
 
 #include "wx/textfile.h"
 #include "wx/ffile.h"
-#include "wx/settings.h"
 #include "wx/filename.h"
 #include "wx/dcbuffer.h"
 #include "wx/arrimpl.cpp"
 
+// DLL options compatibility check:
+#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)
@@ -102,17 +106,17 @@ wxRichTextCtrl::wxRichTextCtrl()
     Init();
 }
 
-wxRichTextCtrl::wxRichTextCtrl( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
+wxRichTextCtrl::wxRichTextCtrl( wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style)
 #if wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
     : wxScrollHelper(this)
 #endif
 {
     Init();
-    Create(parent, id, pos, size, style);
+    Create(parent, id, value, pos, size, style);
 }
 
 /// Creation
-bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, 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)
 {
 #if wxRICHTEXT_DERIVES_FROM_TEXTCTRLBASE
     if (!wxTextCtrlBase::Create(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE
@@ -151,6 +155,9 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos
     RecreateBuffer(size);
 
     SetCursor(wxCursor(wxCURSOR_IBEAM));
+    
+    if (!value.IsEmpty())
+        SetValue(value);
 
     return true;
 }
@@ -205,6 +212,8 @@ void wxRichTextCtrl::Clear()
     m_caretAtLineStart = false;
     m_selectionRange.SetRange(-2, -2);
 
+    SetScrollbars(0, 0, 0, 0, 0, 0);
+
     if (m_freezeCount == 0)
     {
         SetupScrollbars();
@@ -222,19 +231,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())
@@ -243,7 +252,7 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
             GetBuffer().SetDirty(false);
             SetupScrollbars();
         }
-        
+
         GetBuffer().Draw(dc, GetBuffer().GetRange(), GetSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */);
     }
 
@@ -429,13 +438,21 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
         event.GetKeyCode() == WXK_HOME ||
         event.GetKeyCode() == WXK_PAGEUP ||
         event.GetKeyCode() == WXK_PAGEDOWN ||
-        event.GetKeyCode() == WXK_PRIOR ||
-        event.GetKeyCode() == WXK_NEXT ||
         event.GetKeyCode() == WXK_END)
     {
         KeyboardNavigate(event.GetKeyCode(), flags);
+        return;
     }
-    else if (event.GetKeyCode() == WXK_RETURN)
+
+    // all the other keys modify the controls contents which shouldn't be
+    // possible if we're read-only
+    if ( !IsEditable() )
+    {
+        event.Skip();
+        return;
+    }
+
+    if (event.GetKeyCode() == WXK_RETURN)
     {
         BeginBatchUndo(_("Insert Text"));
 
@@ -454,6 +471,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
 
         EndBatchUndo();
         SetDefaultStyleToCursorStyle();
+
+        ScrollIntoView(m_caretPosition, WXK_RIGHT);
     }
     else if (event.GetKeyCode() == WXK_BACK)
     {
@@ -483,6 +502,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
             SetDefaultStyleToCursorStyle();
         }
 
+        ScrollIntoView(m_caretPosition, WXK_LEFT);
     }
     else if (event.GetKeyCode() == WXK_DELETE)
     {
@@ -524,11 +544,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
         EndBatchUndo();
 
         SetDefaultStyleToCursorStyle();
+        ScrollIntoView(m_caretPosition, WXK_RIGHT);
     }
-#if 0
-    else
-        event.Skip();
-#endif
 }
 
 /// Delete content if there is a selection, e.g. when pressing a key.
@@ -614,11 +631,11 @@ bool wxRichTextCtrl::KeyboardNavigate(int keyCode, int flags)
         else
             success = MoveDown(1, flags);
     }
-    else if (keyCode == WXK_PAGEUP || keyCode == WXK_PRIOR)
+    else if (keyCode == WXK_PAGEUP)
     {
         success = PageUp(1, flags);
     }
-    else if (keyCode == WXK_PAGEDOWN || keyCode == WXK_NEXT)
+    else if (keyCode == WXK_PAGEDOWN)
     {
         success = PageDown(1, flags);
     }
@@ -694,16 +711,16 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode)
     int ppuX, ppuY;
     GetScrollPixelsPerUnit(& ppuX, & ppuY);
 
-    int startX, startY;
-    GetViewStart(& startX, & startY);
-    startX = 0;
-    startY = startY * ppuY;
+    int startXUnits, startYUnits;
+    GetViewStart(& startXUnits, & startYUnits);
+    int startY = startYUnits * ppuY;
 
-    int sx, sy;
+    int sx = 0, sy = 0;
     GetVirtualSize(& sx, & sy);
-    sx = 0;
+    int sxUnits = 0;
+    int syUnits = 0;
     if (ppuY != 0)
-        sy = sy/ppuY;
+        syUnits = sy/ppuY;
 
     wxRect rect = line->GetRect();
 
@@ -712,18 +729,22 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode)
     wxSize clientSize = GetClientSize();
 
     // Going down
-    if (keyCode == WXK_DOWN || keyCode == WXK_RIGHT || keyCode == WXK_END || keyCode == WXK_NEXT || keyCode == WXK_PAGEDOWN)
+    if (keyCode == WXK_DOWN || keyCode == WXK_RIGHT || keyCode == WXK_END || keyCode == WXK_PAGEDOWN)
     {
         if ((rect.y + rect.height) > (clientSize.y + startY))
         {
             // Make it scroll so this item is at the bottom
             // of the window
             int y = rect.y - (clientSize.y - rect.height);
-            y = (int) (0.5 + y/ppuY);
+            int yUnits = (int) (0.5 + ((float) y)/(float) ppuY);
+
+            // If we're still off the screen, scroll another line down
+            if ((rect.y + rect.height) > (clientSize.y + (yUnits*ppuY)))
+                yUnits ++;
 
-            if (startY != y)
+            if (startYUnits != yUnits)
             {
-                SetScrollbars(ppuX, ppuY, sx, sy, 0, y);
+                SetScrollbars(ppuX, ppuY, sxUnits, syUnits, 0, yUnits);
                 scrolled = true;
             }
         }
@@ -732,28 +753,28 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode)
             // Make it scroll so this item is at the top
             // of the window
             int y = rect.y ;
-            y = (int) (0.5 + y/ppuY);
+            int yUnits = (int) (0.5 + ((float) y)/(float) ppuY);
 
-            if (startY != y)
+            if (startYUnits != yUnits)
             {
-                SetScrollbars(ppuX, ppuY, sx, sy, 0, y);
+                SetScrollbars(ppuX, ppuY, sxUnits, syUnits, 0, yUnits);
                 scrolled = true;
             }
         }
     }
     // Going up
-    else if (keyCode == WXK_UP || keyCode == WXK_LEFT || keyCode == WXK_HOME || keyCode == WXK_PRIOR || keyCode == WXK_PAGEUP)
+    else if (keyCode == WXK_UP || keyCode == WXK_LEFT || keyCode == WXK_HOME || keyCode == WXK_PAGEUP )
     {
         if (rect.y < startY)
         {
             // Make it scroll so this item is at the top
             // of the window
             int y = rect.y ;
-            y = (int) (0.5 + y/ppuY);
+            int yUnits = (int) (0.5 + ((float) y)/(float) ppuY);
 
-            if (startY != y)
+            if (startYUnits != yUnits)
             {
-                SetScrollbars(ppuX, ppuY, sx, sy, 0, y);
+                SetScrollbars(ppuX, ppuY, sxUnits, syUnits, 0, yUnits);
                 scrolled = true;
             }
         }
@@ -762,11 +783,15 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode)
             // Make it scroll so this item is at the bottom
             // of the window
             int y = rect.y - (clientSize.y - rect.height);
-            y = (int) (0.5 + y/ppuY);
+            int yUnits = (int) (0.5 + ((float) y)/(float) ppuY);
 
-            if (startY != y)
+            // If we're still off the screen, scroll another line down
+            if ((rect.y + rect.height) > (clientSize.y + (yUnits*ppuY)))
+                yUnits ++;
+
+            if (startYUnits != yUnits)
             {
-                SetScrollbars(ppuX, ppuY, sx, sy, 0, y);
+                SetScrollbars(ppuX, ppuY, sxUnits, syUnits, 0, yUnits);
                 scrolled = true;
             }
         }
@@ -792,7 +817,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)
@@ -1057,8 +1082,8 @@ bool wxRichTextCtrl::MoveDown(int noLines, int flags)
             Refresh(false);
         return true;
     }
-    else
-        return false;
+
+    return false;
 }
 
 /// Move to the end of the paragraph
@@ -1424,19 +1449,20 @@ void wxRichTextCtrl::SetupScrollbars(bool atTop)
 
     // TODO: reimplement scrolling so we scroll by line, not by fixed number
     // of pixels. See e.g. wxVScrolledWindow for ideas.
-    int pixelsPerUnit = 5; // 10;
+    int pixelsPerUnit = 5;
     wxSize clientSize = GetClientSize();
 
     int maxHeight = GetBuffer().GetCachedSize().y;
 
-    int unitsY = maxHeight/pixelsPerUnit;
+    // Round up so we have at least maxHeight pixels
+    int unitsY = (int) (((float)maxHeight/(float)pixelsPerUnit) + 0.5);
 
     int startX = 0, startY = 0;
     if (!atTop)
         GetViewStart(& startX, & startY);
 
     int maxPositionX = 0; // wxMax(sz.x - clientSize.x, 0);
-    int maxPositionY = (wxMax(maxHeight - clientSize.y, 0))/pixelsPerUnit;
+    int maxPositionY = (int) ((((float)(wxMax((unitsY*pixelsPerUnit) - clientSize.y, 0)))/((float)pixelsPerUnit)) + 0.5);
 
     // Move to previous scroll position if
     // possible
@@ -1577,17 +1603,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
@@ -1616,16 +1645,26 @@ wxRichTextCtrl::HitTest(const wxPoint& pt,
 {
     wxClientDC dc((wxRichTextCtrl*) this);
     ((wxRichTextCtrl*)this)->PrepareDC(dc);
+    
+    // Buffer uses logical position (relative to start of buffer)
+    // so convert
+    wxPoint pt2 = GetLogicalPoint(pt);
 
-    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;
+    int hit = ((wxRichTextCtrl*)this)->GetBuffer().HitTest(dc, pt2, *pos);
+
+    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;
 }
 
 // ----------------------------------------------------------------------------
@@ -1695,8 +1734,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)
@@ -1706,8 +1745,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)
@@ -1724,9 +1763,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;
 }
 
@@ -2001,10 +2039,10 @@ bool wxRichTextCtrl::CanRedo() const
 }
 
 // ----------------------------------------------------------------------------
-// implemenation details
+// implementation details
 // ----------------------------------------------------------------------------
 
-void wxRichTextCtrl::Command(wxCommandEvent & event)
+void wxRichTextCtrl::Command(wxCommandEvent& event)
 {
     SetValue(event.GetString());
     GetEventHandler()->ProcessEvent(event);
@@ -2157,6 +2195,11 @@ bool wxRichTextCtrl::SetStyle(long start, long end, const wxTextAttrEx& style)
     return GetBuffer().SetStyle(wxRichTextRange(start, end), style);
 }
 
+bool wxRichTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
+{
+    return GetBuffer().SetStyle(wxRichTextRange(start, end), wxTextAttrEx(style));
+}
+
 bool wxRichTextCtrl::SetStyle(const wxRichTextRange& range, const wxRichTextAttr& style)
 {
     return GetBuffer().SetStyle(range, style);
@@ -2167,11 +2210,33 @@ bool wxRichTextCtrl::SetDefaultStyle(const wxTextAttrEx& style)
     return GetBuffer().SetDefaultStyle(style);
 }
 
+bool wxRichTextCtrl::SetDefaultStyle(const wxTextAttr& style)
+{
+    return GetBuffer().SetDefaultStyle(wxTextAttrEx(style));
+}
+
 const wxTextAttrEx& wxRichTextCtrl::GetDefaultStyleEx() const
 {
     return GetBuffer().GetDefaultStyle();
 }
 
+const wxTextAttr& wxRichTextCtrl::GetDefaultStyle() const
+{
+    return GetBuffer().GetDefaultStyle();    
+}
+
+bool wxRichTextCtrl::GetStyle(long position, wxTextAttr& style) const
+{
+    wxTextAttrEx attr;
+    if (GetBuffer().GetStyle(position, attr))
+    {
+        style = attr;
+        return true;
+    }
+    else
+        return false;
+}
+
 bool wxRichTextCtrl::GetStyle(long position, wxTextAttrEx& style) const
 {
     return GetBuffer().GetStyle(position, style);
@@ -2254,8 +2319,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
@@ -2316,17 +2381,17 @@ bool wxRichTextCtrl::LayoutContent(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();
     }
@@ -2505,8 +2570,8 @@ bool wxRichTextCtrl::SetDefaultStyleToCursorStyle()
         SetDefaultStyle(attr);
         return true;
     }
-    else
-        return false;
+
+    return false;
 }
 
 /// Returns the first visible position in the current view
@@ -2521,4 +2586,3 @@ long wxRichTextCtrl::GetFirstVisiblePosition() const
 
 #endif
     // wxUSE_RICHTEXT
-