]> git.saurik.com Git - wxWidgets.git/blobdiff - src/richtext/richtextctrl.cpp
no changes, just de TABified
[wxWidgets.git] / src / richtext / richtextctrl.cpp
index ae7de5772277316d46b13917d6f07560f1c65c08..749eba3829617a3dc30f5153b7dd7ce5ba2801c6 100644 (file)
 #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
@@ -559,15 +590,12 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
     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();
@@ -584,6 +612,15 @@ 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)
@@ -593,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();
@@ -611,6 +645,15 @@ 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
@@ -726,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
@@ -744,6 +795,8 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
 
                         PromoteList(promoteBy, range, NULL);
 
+                        GetEventHandler()->ProcessEvent(cmdEvent);
+
                         return;
                     }
                 }
@@ -754,12 +807,15 @@ 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();
             }
         }
@@ -772,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)
@@ -1986,7 +2039,7 @@ void wxRichTextCtrl::DoWriteText(const wxString& value, int flags)
 {
     wxString valueUnix = wxTextFile::Translate(value, wxTextFileType_Unix);
 
-    GetBuffer().InsertTextWithUndo(m_caretPosition+1, valueUnix, this);
+    GetBuffer().InsertTextWithUndo(m_caretPosition+1, valueUnix, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE);
 
     if ( flags & SetValue_SendEvent )
         SendTextUpdatedEvent();
@@ -2047,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
@@ -2195,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();
@@ -2220,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())
@@ -2510,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)
@@ -2690,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);
 
@@ -2719,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);
@@ -2749,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);
@@ -2821,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);
@@ -2852,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;
 
@@ -2922,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;
@@ -2945,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.
@@ -3018,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)