]> git.saurik.com Git - wxWidgets.git/blobdiff - src/richtext/richtextctrl.cpp
Always link with expat in monolithic build.
[wxWidgets.git] / src / richtext / richtextctrl.cpp
index abc5b0f6beb3b333474294e0f1ce747aa94f549e..0e1c0c1ed8709076314796facebba84a04700f23 100644 (file)
 #include "wx/fontenum.h"
 #include "wx/accel.h"
 
+#if defined (__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__)
+#define wxHAVE_PRIMARY_SELECTION 1
+#else
+#define wxHAVE_PRIMARY_SELECTION 0
+#endif
+
+#if wxUSE_CLIPBOARD && wxHAVE_PRIMARY_SELECTION
+#include "wx/clipbrd.h"
+#endif
+
 // DLL options compatibility check:
 #include "wx/app.h"
 WX_CHECK_BUILD_OPTIONS("wxRichTextCtrl")
@@ -293,12 +303,12 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va
     // Accelerators
     wxAcceleratorEntry entries[6];
 
-    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);
-    entries[4].Set(wxACCEL_CMD,   (int) 'Z',       wxID_UNDO);
-    entries[5].Set(wxACCEL_CMD,   (int) 'Y',       wxID_REDO);
+    entries[0].Set(wxACCEL_CTRL,   (int) 'C',       wxID_COPY);
+    entries[1].Set(wxACCEL_CTRL,   (int) 'X',       wxID_CUT);
+    entries[2].Set(wxACCEL_CTRL,   (int) 'V',       wxID_PASTE);
+    entries[3].Set(wxACCEL_CTRL,   (int) 'A',       wxID_SELECTALL);
+    entries[4].Set(wxACCEL_CTRL,   (int) 'Z',       wxID_UNDO);
+    entries[5].Set(wxACCEL_CTRL,   (int) 'Y',       wxID_REDO);
 
     wxAcceleratorTable accel(6, entries);
     SetAcceleratorTable(accel);
@@ -568,12 +578,7 @@ void wxRichTextCtrl::OnLeftClick(wxMouseEvent& event)
 
         // For now, don't handle shift-click when we're selecting multiple objects.
         if (event.ShiftDown() && GetFocusObject() == oldFocusObject && m_selectionState == wxRichTextCtrlSelectionState_Normal)
-        {
-            if (!m_selection.IsValid())
-                ExtendSelection(oldCaretPos, m_caretPosition, wxRICHTEXT_SHIFT_DOWN);
-            else
-                ExtendSelection(m_caretPosition, m_caretPosition, wxRICHTEXT_SHIFT_DOWN);
-        }
+            ExtendSelection(oldCaretPos, m_caretPosition, wxRICHTEXT_SHIFT_DOWN);
         else
             SelectNone();
     }
@@ -644,6 +649,19 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event)
             }
         }
     }
+
+#if wxUSE_CLIPBOARD && wxUSE_DATAOBJ && wxHAVE_PRIMARY_SELECTION
+    if (HasSelection() && GetFocusObject() && GetFocusObject()->GetBuffer())
+    {
+        // Put the selection in PRIMARY, if it exists
+        wxTheClipboard->UsePrimarySelection(true);
+
+        wxRichTextRange range = GetInternalSelectionRange();
+        GetFocusObject()->GetBuffer()->CopyToClipboard(range);
+
+        wxTheClipboard->UsePrimarySelection(false);
+    }
+#endif
 }
 
 /// Left-click
@@ -844,6 +862,13 @@ void wxRichTextCtrl::OnMiddleClick(wxMouseEvent& event)
 
     if (!GetEventHandler()->ProcessEvent(cmdEvent))
         event.Skip();
+
+#if wxUSE_CLIPBOARD && wxUSE_DATAOBJ && wxHAVE_PRIMARY_SELECTION
+    // Paste any PRIMARY selection, if it exists
+    wxTheClipboard->UsePrimarySelection(true);
+    Paste();
+    wxTheClipboard->UsePrimarySelection(false);
+#endif
 }
 
 /// Key press
@@ -2930,13 +2955,19 @@ void wxRichTextCtrl::SetSelection(long from, long to)
 // Editing
 // ----------------------------------------------------------------------------
 
-void wxRichTextCtrl::Replace(long WXUNUSED(from), long WXUNUSED(to),
+void wxRichTextCtrl::Replace(long from, long to,
                              const wxString& value)
 {
     BeginBatchUndo(_("Replace"));
 
+    SetSelection(from, to);
+
+    wxRichTextAttr attr = GetDefaultStyle();
+
     DeleteSelectedContent();
 
+    SetDefaultStyle(attr);
+
     DoWriteText(value, SetValue_SelectionOnly);
 
     EndBatchUndo();
@@ -3376,13 +3407,26 @@ void wxRichTextCtrl::PositionCaret(wxRichTextParagraphLayoutBox* container)
             if (GetCaret()->GetSize() != newSz)
                 GetCaret()->SetSize(newSz);
 
-            int halfSize = newSz.y/2;
-            // If the caret is beyond the margin, hide it by moving it out of the way
-            if (((pt.y + halfSize) < GetBuffer().GetTopMargin()) || ((pt.y + halfSize) > (GetClientSize().y - GetBuffer().GetBottomMargin())))
+            // Adjust size so the caret size and position doesn't appear in the margins
+            if (((pt.y + newSz.y) <= GetBuffer().GetTopMargin()) || (pt.y >= (GetClientSize().y - GetBuffer().GetBottomMargin())))
             {
                 pt.x = -200;
                 pt.y = -200;
             }
+            else if (pt.y < GetBuffer().GetTopMargin() && (pt.y + newSz.y) > GetBuffer().GetTopMargin())
+            {
+                newSz.y -= (GetBuffer().GetTopMargin() - pt.y);
+                if (newSz.y > 0)
+                {
+                    pt.y = GetBuffer().GetTopMargin();
+                    GetCaret()->SetSize(newSz);
+                }
+            }
+            else if (pt.y < (GetClientSize().y - GetBuffer().GetBottomMargin()) && (pt.y + newSz.y) > (GetClientSize().y - GetBuffer().GetBottomMargin()))
+            {
+                newSz.y = GetClientSize().y - GetBuffer().GetBottomMargin() - pt.y;
+                GetCaret()->SetSize(newSz);
+            }
 
             GetCaret()->Move(pt);
             GetCaret()->Show();
@@ -3496,7 +3540,7 @@ bool wxRichTextCtrl::LayoutContent(bool onlyVisibleRect)
     return true;
 }
 
-/// Is all of the selection bold?
+/// Is all of the selection, or the current caret position, bold?
 bool wxRichTextCtrl::IsSelectionBold()
 {
     if (HasSelection())
@@ -3526,7 +3570,7 @@ bool wxRichTextCtrl::IsSelectionBold()
     return false;
 }
 
-/// Is all of the selection italics?
+/// Is all of the selection, or the current caret position, italics?
 bool wxRichTextCtrl::IsSelectionItalics()
 {
     if (HasSelection())
@@ -3556,7 +3600,7 @@ bool wxRichTextCtrl::IsSelectionItalics()
     return false;
 }
 
-/// Is all of the selection underlined?
+/// Is all of the selection, or the current caret position, underlined?
 bool wxRichTextCtrl::IsSelectionUnderlined()
 {
     if (HasSelection())
@@ -3586,6 +3630,33 @@ bool wxRichTextCtrl::IsSelectionUnderlined()
     return false;
 }
 
+/// Does all of the selection, or the current caret position, have this wxTextAttrEffects flag(s)?
+bool wxRichTextCtrl::DoesSelectionHaveTextEffectFlag(int flag)
+{
+    wxRichTextAttr attr;
+    attr.SetFlags(wxTEXT_ATTR_EFFECTS);
+    attr.SetTextEffectFlags(flag);
+    attr.SetTextEffects(flag);
+
+    if (HasSelection())
+    {
+        return HasCharacterAttributes(GetSelectionRange(), attr);
+    }
+    else
+    {
+        // If no selection, then we need to combine current style with default style
+        // to see what the effect would be if we started typing.
+        long pos = GetAdjustedCaretPosition(GetCaretPosition());
+        if (GetStyle(pos, attr))
+        {
+            if (IsDefaultStyleShowing())
+                wxRichTextApplyStyle(attr, GetDefaultStyleEx());
+            return (attr.GetTextEffectFlags() & flag) != 0;
+        }
+    }
+    return false;
+}
+
 /// Apply bold to the selection
 bool wxRichTextCtrl::ApplyBoldToSelection()
 {
@@ -3640,6 +3711,28 @@ bool wxRichTextCtrl::ApplyUnderlineToSelection()
     return true;
 }
 
+/// Apply the wxTextAttrEffects flag(s) to the selection, or the current caret position if there's no selection
+bool wxRichTextCtrl::ApplyTextEffectToSelection(int flags)
+{
+    wxRichTextAttr attr;
+    attr.SetFlags(wxTEXT_ATTR_EFFECTS);
+    attr.SetTextEffectFlags(flags);
+    if (!DoesSelectionHaveTextEffectFlag(flags))
+        attr.SetTextEffects(flags);
+     else
+        attr.SetTextEffects(attr.GetTextEffectFlags() & ~flags);
+
+    if (HasSelection())
+        return SetStyleEx(GetSelectionRange(), attr, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY);
+    else
+    {
+        wxRichTextAttr current = GetDefaultStyleEx();
+        current.Apply(attr);
+        SetAndShowDefaultStyle(current);
+    }
+    return true;
+}
+
 /// Is all of the selection aligned according to the specified flag?
 bool wxRichTextCtrl::IsSelectionAligned(wxTextAttrAlignment alignment)
 {