diff options
-rw-r--r-- | editeng/source/editeng/editeng.cxx | 4 | ||||
-rw-r--r-- | editeng/source/editeng/editundo.cxx | 11 | ||||
-rw-r--r-- | editeng/source/editeng/editundo.hxx | 3 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 2 | ||||
-rw-r--r-- | editeng/source/editeng/impedit5.cxx | 3 | ||||
-rw-r--r-- | sd/qa/unit/tiledrendering/data/paste-undo.fodp | 34 | ||||
-rw-r--r-- | sd/qa/unit/tiledrendering/tiledrendering.cxx | 41 |
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(); |