[Libreoffice-commits] core.git: editeng/source sd/qa

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Aug 10 05:44:21 UTC 2021


 editeng/source/editeng/editeng.cxx             |    4 +-
 editeng/source/editeng/editundo.cxx            |   11 +++++-
 editeng/source/editeng/editundo.hxx            |    3 +
 editeng/source/editeng/impedit.hxx             |    2 -
 editeng/source/editeng/impedit5.cxx            |    3 +
 sd/qa/unit/tiledrendering/data/paste-undo.fodp |   34 ++++++++++++++++++++
 sd/qa/unit/tiledrendering/tiledrendering.cxx   |   41 +++++++++++++++++++++++++
 7 files changed, 93 insertions(+), 5 deletions(-)

New commits:
commit fc4c0747e97bb997cc37263b3e86b07dab21fe25
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Aug 9 19:20:53 2021 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Aug 10 07:43:46 2021 +0200

    tdf#142845 editeng: don't update selection when formatting before sd paste
    
    Regression from commit f0c25c751cf8e166a84b289746bce6202a40391d
    (tdf#115783 sd: fix lost char attributes during in-table copy&paste,
    2018-02-16), the problem was that the formatting before paste also
    created an undo action, and executing it alters the selection, which was
    not intended.
    
    So in case the textbox contains "world" and we paste "hello", then the
    undo will set the cursor at the end of "world", while the expected
    result is to just undo the paste and the formatting of "world".
    
    Fix the problem by not altering the selection in the undo of
    Outliner::SetCharAttribs(), which is only called by sd/ in the
    before-paste case, not anywhere else.
    
    Change-Id: Ie4a08f57d22cd1862c02987a5f86089fda8a5d9d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120220
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index abc9f64a9b04..c9aec527b222 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -1768,7 +1768,9 @@ const SfxPoolItem& EditEngine::GetParaAttrib( sal_Int32 nPara, sal_uInt16 nWhich
 void EditEngine::SetCharAttribs(sal_Int32 nPara, const SfxItemSet& rSet)
 {
     EditSelection aSel(pImpEditEngine->ConvertSelection(nPara, 0, nPara, GetTextLen(nPara)));
-    pImpEditEngine->SetAttribs(aSel, rSet);
+    // This is called by sd::View::OnBeginPasteOrDrop(), updating the cursor position on undo is not
+    // wanted.
+    pImpEditEngine->SetAttribs(aSel, rSet, /*nSpecial=*/SetAttribsMode::NONE, /*bSetSelection=*/false);
     pImpEditEngine->FormatAndUpdate();
 }
 
diff --git a/editeng/source/editeng/editundo.cxx b/editeng/source/editeng/editundo.cxx
index 714dd1b682ed..892183f754af 100644
--- a/editeng/source/editeng/editundo.cxx
+++ b/editeng/source/editeng/editundo.cxx
@@ -501,6 +501,7 @@ EditUndoSetAttribs::EditUndoSetAttribs(EditEngine* pEE, const ESelection& rESel,
     aESel(rESel),
     aNewAttribs(rNewItems),
     nSpecial(SetAttribsMode::NONE),
+    m_bSetSelection(true),
     // When EditUndoSetAttribs actually is a RemoveAttribs this could be
     // recognize by the empty itemset, but then it would have to be caught in
     // its own place, which possible a setAttribs does with an empty itemset.
@@ -560,7 +561,10 @@ void EditUndoSetAttribs::Undo()
     }
     if ( bFields )
         pEE->UpdateFieldsOnly();
-    ImpSetSelection();
+    if (m_bSetSelection)
+    {
+        ImpSetSelection();
+    }
 }
 
 void EditUndoSetAttribs::Redo()
@@ -574,7 +578,10 @@ void EditUndoSetAttribs::Redo()
     else
         pEE->RemoveCharAttribs( aSel, bRemoveParaAttribs, nRemoveWhich );
 
-    ImpSetSelection();
+    if (m_bSetSelection)
+    {
+        ImpSetSelection();
+    }
 }
 
 void EditUndoSetAttribs::AppendContentInfo(ContentAttribsInfo* pNew)
diff --git a/editeng/source/editeng/editundo.hxx b/editeng/source/editeng/editundo.hxx
index 43d2a0d3b911..f87180ba7dd7 100644
--- a/editeng/source/editeng/editundo.hxx
+++ b/editeng/source/editeng/editundo.hxx
@@ -218,6 +218,8 @@ private:
     InfoArrayType       aPrevAttribs;
 
     SetAttribsMode      nSpecial;
+    /// Once the attributes are set / unset, set the selection to the end of the formatted range?
+    bool m_bSetSelection;
     bool                bSetIsRemove;
     bool                bRemoveParaAttribs;
     sal_uInt16          nRemoveWhich;
@@ -232,6 +234,7 @@ public:
     SfxItemSet&         GetNewAttribs()     { return aNewAttribs; }
 
     void                SetSpecial( SetAttribsMode n )  { nSpecial = n; }
+    void                SetUpdateSelection( bool bSetSelection )  { m_bSetSelection = bSetSelection; }
     void                SetRemoveAttribs( bool b )      { bSetIsRemove = b; }
     void                SetRemoveParaAttribs( bool b )  { bRemoveParaAttribs = b; }
     void                SetRemoveWhich( sal_uInt16 n )  { nRemoveWhich = n; }
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 78b2f85f9cc7..e138fa532f32 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -910,7 +910,7 @@ public:
 
     SfxItemSet      GetAttribs( sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, GetAttribsFlags nFlags = GetAttribsFlags::ALL ) const;
     SfxItemSet      GetAttribs( EditSelection aSel, EditEngineAttribs nOnlyHardAttrib = EditEngineAttribs::All  );
-    void            SetAttribs( EditSelection aSel, const SfxItemSet& rSet, SetAttribsMode nSpecial = SetAttribsMode::NONE );
+    void            SetAttribs( EditSelection aSel, const SfxItemSet& rSet, SetAttribsMode nSpecial = SetAttribsMode::NONE, bool bSetSelection = true );
     void            RemoveCharAttribs( EditSelection aSel, EERemoveParaAttribsMode eMode, sal_uInt16 nWhich );
     void            RemoveCharAttribs( sal_Int32 nPara, sal_uInt16 nWhich = 0, bool bRemoveFeatures = false );
     void            SetFlatMode( bool bFlat );
diff --git a/editeng/source/editeng/impedit5.cxx b/editeng/source/editeng/impedit5.cxx
index 02133496bb6b..d1846f1df880 100644
--- a/editeng/source/editeng/impedit5.cxx
+++ b/editeng/source/editeng/impedit5.cxx
@@ -483,7 +483,7 @@ SfxItemSet ImpEditEngine::GetAttribs( sal_Int32 nPara, sal_Int32 nStart, sal_Int
 }
 
 
-void ImpEditEngine::SetAttribs( EditSelection aSel, const SfxItemSet& rSet, SetAttribsMode nSpecial )
+void ImpEditEngine::SetAttribs( EditSelection aSel, const SfxItemSet& rSet, SetAttribsMode nSpecial, bool bSetSelection )
 {
     aSel.Adjust( aEditDoc );
 
@@ -499,6 +499,7 @@ void ImpEditEngine::SetAttribs( EditSelection aSel, const SfxItemSet& rSet, SetA
     {
         std::unique_ptr<EditUndoSetAttribs> pUndo = CreateAttribUndo( aSel, rSet );
         pUndo->SetSpecial( nSpecial );
+        pUndo->SetUpdateSelection(bSetSelection);
         InsertUndo( std::move(pUndo) );
     }
 
diff --git a/sd/qa/unit/tiledrendering/data/paste-undo.fodp b/sd/qa/unit/tiledrendering/data/paste-undo.fodp
new file mode 100644
index 000000000000..2615d1e11445
--- /dev/null
+++ b/sd/qa/unit/tiledrendering/data/paste-undo.fodp
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.presentation">
+  <office:styles>
+    <style:presentation-page-layout style:name="AL1T0">
+      <presentation:placeholder presentation:object="title" svg:x="2.058cm" svg:y="1.743cm" svg:width="23.912cm" svg:height="3.507cm"/>
+      <presentation:placeholder presentation:object="subtitle" svg:x="2.058cm" svg:y="5.838cm" svg:width="23.912cm" svg:height="13.23cm"/>
+    </style:presentation-page-layout>
+  </office:styles>
+  <office:automatic-styles>
+    <style:page-layout style:name="PM0">
+      <style:page-layout-properties fo:margin-top="0cm" fo:margin-bottom="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:page-width="21cm" fo:page-height="29.7cm" style:print-orientation="portrait"/>
+    </style:page-layout>
+    <style:page-layout style:name="PM1">
+      <style:page-layout-properties fo:margin-top="0cm" fo:margin-bottom="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:page-width="28cm" fo:page-height="15.75cm" style:print-orientation="landscape"/>
+    </style:page-layout>
+    <style:style style:name="dp3" style:family="drawing-page">
+    </style:style>
+    <style:style style:name="gr3" style:family="graphic" style:parent-style-name="standard">
+      <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:auto-grow-height="true" draw:auto-grow-width="false" fo:max-height="0cm" fo:min-height="0.712cm"/>
+      <style:paragraph-properties style:writing-mode="lr-tb"/>
+    </style:style>
+  </office:automatic-styles>
+  <office:body>
+    <office:presentation>
+      <draw:page draw:name="page1" draw:style-name="dp3" draw:master-page-name="Default" presentation:presentation-page-layout-name="AL1T0">
+        <draw:frame draw:style-name="gr3" draw:text-style-name="P7" draw:layer="layout" svg:width="7.5cm" svg:height="0.962cm" svg:x="3.5cm" svg:y="3.5cm">
+          <draw:text-box>
+            <text:p>world</text:p>
+          </draw:text-box>
+        </draw:frame>
+      </draw:page>
+    </office:presentation>
+  </office:body>
+</office:document>
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 02856dd0043e..1bdd4c30386a 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -8,6 +8,9 @@
  */
 
 #include "../sdmodeltestbase.hxx"
+
+#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
+
 #include <app.hrc>
 #include <test/bootstrapfixture.hxx>
 #include <test/helper/transferable.hxx>
@@ -53,6 +56,7 @@
 #include <vcl/cursor.hxx>
 #include <vcl/scheduler.hxx>
 #include <vcl/vclevent.hxx>
+#include <vcl/unohelp2.hxx>
 
 #include <chrono>
 #include <cstdlib>
@@ -133,6 +137,7 @@ public:
     void testSlideDuplicateUndo();
     void testMoveShapeHandle();
     void testDeleteTable();
+    void testPasteUndo();
 
     CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
     CPPUNIT_TEST(testCreateDestroy);
@@ -190,6 +195,7 @@ public:
     CPPUNIT_TEST(testSlideDuplicateUndo);
     CPPUNIT_TEST(testMoveShapeHandle);
     CPPUNIT_TEST(testDeleteTable);
+    CPPUNIT_TEST(testPasteUndo);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -2679,6 +2685,41 @@ void SdTiledRenderingTest::testMoveShapeHandle()
     }
 
 }
+
+void SdTiledRenderingTest::testPasteUndo()
+{
+    // Given a document with a textbox, containing "world":
+    SdXImpressDocument* pXImpressDocument = createDoc("paste-undo.fodp");
+    sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
+    SdPage* pActualPage = pViewShell->GetActualPage();
+    SdrObject* pObject = pActualPage->GetObj(0);
+    SdrView* pView = pViewShell->GetView();
+    pView->MarkObj(pObject, pView->GetSdrPageView());
+    pView->SdrBeginTextEdit(pObject);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_HOME);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_HOME);
+    EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
+    ESelection aWordSelection(0, 0, 0, 1); // "w" of "world"
+    rEditView.SetSelection(aWordSelection);
+    comphelper::dispatchCommand(".uno:Cut", {});
+    Scheduler::ProcessEventsToIdle();
+
+    // When undoing a paste:
+    comphelper::dispatchCommand(".uno:Paste", {});
+    Scheduler::ProcessEventsToIdle();
+    comphelper::dispatchCommand(".uno:Undo", {});
+    Scheduler::ProcessEventsToIdle();
+
+    // Then make sure the cursor position is still at the beginning:
+    ESelection aSelection = rEditView.GetSelection();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 0
+    // - Actual  : 4
+    // i.e. the cursor position after undo was at the end of the line, not at the start, as
+    // expected.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aSelection.nStartPos);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();


More information about the Libreoffice-commits mailing list