summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editeng/source/editeng/editeng.cxx4
-rw-r--r--editeng/source/editeng/editundo.cxx11
-rw-r--r--editeng/source/editeng/editundo.hxx3
-rw-r--r--editeng/source/editeng/impedit.hxx2
-rw-r--r--editeng/source/editeng/impedit5.cxx3
-rw-r--r--sd/qa/unit/tiledrendering/data/paste-undo.fodp34
-rw-r--r--sd/qa/unit/tiledrendering/tiledrendering.cxx41
7 files changed, 93 insertions, 5 deletions
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();