]> git.saurik.com Git - wxWidgets.git/blobdiff - src/richtext/richtextctrl.cpp
Made all bitmaps 16x16
[wxWidgets.git] / src / richtext / richtextctrl.cpp
index ad63479c42458c26ec9bc2de047ce5309fae0f52..636c49443972f05c48317d86accc05b5cd23aee8 100644 (file)
@@ -44,6 +44,10 @@ 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_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)
 
 IMPLEMENT_CLASS( wxRichTextCtrl, wxControl )
 
@@ -124,7 +128,11 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va
         SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
     }
 
+    GetBuffer().Reset();
     GetBuffer().SetRichTextCtrl(this);
+    
+    SetCaret(new wxCaret(this, wxRICHTEXT_DEFAULT_CARET_WIDTH, 16));
+    GetCaret()->Show();
 
     if (style & wxTE_READONLY)
         SetEditable(false);
@@ -137,7 +145,7 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va
     attributes.SetLineSpacing(10);
     attributes.SetParagraphSpacingAfter(10);
     attributes.SetParagraphSpacingBefore(0);
-    attributes.SetFlags(wxTEXT_ATTR_ALL);
+
     SetBasicStyle(attributes);
 
     // The default attributes will be merged with base attributes, so
@@ -149,23 +157,30 @@ 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
     RecreateBuffer(size);
 #endif
 
-    SetCursor(wxCursor(wxCURSOR_IBEAM));
+    m_textCursor = wxCursor(wxCURSOR_IBEAM);
+    m_urlCursor = wxCursor(wxCURSOR_HAND);
+
+    SetCursor(m_textCursor);
 
     if (!value.IsEmpty())
         SetValue(value);
 
+    GetBuffer().AddEventHandler(this);
+
     return true;
 }
 
 wxRichTextCtrl::~wxRichTextCtrl()
 {
+    GetBuffer().RemoveEventHandler(this);
+    
     delete m_contextMenu;
 }
 
@@ -209,7 +224,7 @@ void wxRichTextCtrl::Thaw()
 /// Clear all text
 void wxRichTextCtrl::Clear()
 {
-    m_buffer.Reset();
+    m_buffer.ResetAndClearCommands();
     m_buffer.SetDirty(true);
     m_caretPosition = -1;
     m_caretPositionForDefaultStyle = -2;
@@ -229,7 +244,7 @@ void wxRichTextCtrl::Clear()
 /// Painting
 void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
 {
-    if (GetCaret())
+    if (GetCaret() && GetCaret()->IsVisible())
         GetCaret()->Hide();
 
     {
@@ -248,7 +263,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())
         {
@@ -260,7 +279,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();
@@ -273,21 +292,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
@@ -333,25 +355,59 @@ void wxRichTextCtrl::OnLeftClick(wxMouseEvent& event)
 }
 
 /// Left-up
-void wxRichTextCtrl::OnLeftUp(wxMouseEvent& WXUNUSED(event))
+void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event)
 {
     if (m_dragging)
     {
         m_dragging = false;
         if (GetCapture() == this)
             ReleaseMouse();
+
+        // See if we clicked on a URL
+        wxClientDC dc(this);
+        PrepareDC(dc);
+        dc.SetFont(GetFont());
+
+        long position = 0;
+        wxPoint logicalPt = event.GetLogicalPosition(dc);
+        int hit = GetBuffer().HitTest(dc, logicalPt, position);
+    
+        if (hit != wxRICHTEXT_HITTEST_NONE)
+        {
+            wxTextAttrEx attr;
+            if (GetStyle(position, attr))
+            {
+                if (attr.HasFlag(wxTEXT_ATTR_URL))
+                {
+                    wxString urlTarget = attr.GetURL();
+                    if (!urlTarget.IsEmpty())
+                    {
+                        wxMouseEvent mouseEvent(event);
+                        
+                        long startPos = 0, endPos = 0;
+                        wxRichTextObject* obj = GetBuffer().GetLeafObjectAtPosition(position);
+                        if (obj)
+                        {
+                            startPos = obj->GetRange().GetStart();
+                            endPos = obj->GetRange().GetEnd();
+                        }                        
+                        
+                        wxTextUrlEvent urlEvent(GetId(), mouseEvent, startPos, endPos);
+                        InitCommandEvent(urlEvent);
+
+                        urlEvent.SetString(urlTarget);
+                        
+                        GetEventHandler()->ProcessEvent(urlEvent);
+                    }
+                }
+            }
+        }
     }
 }
 
 /// Left-click
 void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event)
 {
-    if (!event.Dragging())
-    {
-        event.Skip();
-        return;
-    }
-
     wxClientDC dc(this);
     PrepareDC(dc);
     dc.SetFont(GetFont());
@@ -359,6 +415,32 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event)
     long position = 0;
     wxPoint logicalPt = event.GetLogicalPosition(dc);
     int hit = GetBuffer().HitTest(dc, logicalPt, position);
+    
+    // See if we need to change the cursor
+    
+    {
+        if (hit != wxRICHTEXT_HITTEST_NONE)
+        {
+            wxTextAttrEx attr;
+            if (GetStyle(position, attr))
+            {
+                if (attr.HasFlag(wxTEXT_ATTR_URL))
+                {
+                    SetCursor(m_urlCursor);
+                }
+                else if (!attr.HasFlag(wxTEXT_ATTR_URL))
+                {
+                    SetCursor(m_textCursor);
+                }
+            }
+        }
+    }
+
+    if (!event.Dragging())
+    {
+        event.Skip();
+        return;
+    }
 
     if (m_dragging && hit != wxRICHTEXT_HITTEST_NONE)
     {
@@ -462,18 +544,25 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
         DeleteSelectedContent(& newPos);
 
         GetBuffer().InsertNewlineWithUndo(newPos+1, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE);
+        EndBatchUndo();
+        SetDefaultStyleToCursorStyle();
+
+        ScrollIntoView(m_caretPosition, WXK_RIGHT);
 
         wxRichTextEvent cmdEvent(
             wxEVT_COMMAND_RICHTEXT_RETURN,
             GetId());
         cmdEvent.SetEventObject(this);
         cmdEvent.SetFlags(flags);
-        GetEventHandler()->ProcessEvent(cmdEvent);
-
-        EndBatchUndo();
-        SetDefaultStyleToCursorStyle();
-
-        ScrollIntoView(m_caretPosition, WXK_RIGHT);
+        if (!GetEventHandler()->ProcessEvent(cmdEvent))
+        {
+            // Generate conventional event
+            wxCommandEvent textEvent(wxEVT_COMMAND_TEXT_ENTER, GetId());
+            InitCommandEvent(textEvent);
+            
+            GetEventHandler()->ProcessEvent(textEvent);
+        }
+        Update();
     }
     else if (event.GetKeyCode() == WXK_BACK)
     {
@@ -493,7 +582,6 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
 
         EndBatchUndo();
 
-        // Shouldn't this be in Do()?
         if (GetLastPosition() == -1)
         {
             GetBuffer().Reset();
@@ -504,6 +592,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
         }
 
         ScrollIntoView(m_caretPosition, WXK_LEFT);
+        Update();
     }
     else if (event.GetKeyCode() == WXK_DELETE)
     {
@@ -522,7 +611,6 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
 
         EndBatchUndo();
 
-        // Shouldn't this be in Do()?
         if (GetLastPosition() == -1)
         {
             GetBuffer().Reset();
@@ -531,6 +619,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
             PositionCaret();
             SetDefaultStyleToCursorStyle();
         }
+        Update();
     }
     else
     {
@@ -644,7 +733,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
                     event.Skip();
                     return;
                 }
-                
+
                 if (keycode == wxT('\t'))
                 {
                     // See if we need to promote or demote the selection or paragraph at the cursor
@@ -658,10 +747,11 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
                             range = GetSelectionRange();
                         else
                             range = para->GetRange().FromInternal();
-                        
+
                         int promoteBy = event.ShiftDown() ? 1 : -1;
 
                         PromoteList(promoteBy, range, NULL);
+
                         return;
                     }
                 }
@@ -678,6 +768,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
 
                 SetDefaultStyleToCursorStyle();
                 ScrollIntoView(m_caretPosition, WXK_RIGHT);
+                Update();
             }
         }
     }
@@ -2776,20 +2867,20 @@ bool wxRichTextCtrl::ApplyStyle(wxRichTextStyleDefinition* def)
     if (def->IsKindOf(CLASSINFO(wxRichTextListStyleDefinition)))
     {
         flags |= wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY;
-        
+
         wxRichTextRange range;
-        
+
         if (HasSelection())
             range = GetSelectionRange();
         else
         {
-            long pos = GetAdjustedCaretPosition(GetCaretPosition());            
+            long pos = GetAdjustedCaretPosition(GetCaretPosition());
             range = wxRichTextRange(pos, pos+1);
         }
-        
-        return SetListStyle(range, (wxRichTextListStyleDefinition*) def, flags);        
-    }    
-    
+
+        return SetListStyle(range, (wxRichTextListStyleDefinition*) def, flags);
+    }
+
     // Make sure the attr has the style name
     if (def->IsKindOf(CLASSINFO(wxRichTextParagraphStyleDefinition)))
     {
@@ -2862,6 +2953,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.
@@ -2916,12 +3019,12 @@ bool wxRichTextCtrl::ClearListStyle(const wxRichTextRange& range, int flags)
 /// Number/renumber any list elements in the given range
 bool wxRichTextCtrl::NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel)
 {
-    return GetBuffer().NumberList(range.ToInternal(), def, flags, startFrom, specifiedLevel);    
+    return GetBuffer().NumberList(range.ToInternal(), def, flags, startFrom, specifiedLevel);
 }
 
 bool wxRichTextCtrl::NumberList(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel)
 {
-    return GetBuffer().NumberList(range.ToInternal(), defName, flags, startFrom, specifiedLevel);    
+    return GetBuffer().NumberList(range.ToInternal(), defName, flags, startFrom, specifiedLevel);
 }
 
 /// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1
@@ -2952,4 +3055,3 @@ void wxRichTextCtrl::ClearAvailableFontNames()
 
 #endif
     // wxUSE_RICHTEXT
-