[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