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

Miklos Vajna vmiklos at collabora.co.uk
Wed Apr 20 17:17:41 UTC 2016


 include/svx/svdotable.hxx      |    4 ++
 sd/qa/unit/misc-tests.cxx      |   75 +++++++++++++++++++++++++++++++++++++++++
 svx/source/table/cell.cxx      |    5 ++
 svx/source/table/svdotable.cxx |   12 ++++++
 4 files changed, 96 insertions(+)

New commits:
commit 100eb15b4d8529d7a11d98a28742f31f0f792fa1
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Apr 20 17:44:29 2016 +0200

    tdf#99396 SdrTableObj::EndTextEdit: restore cell format undo items
    
    As seen by the user: after finishing the text edit of an Impress table
    cell, the text changes are still on the undo stack, but the table ones
    (like background color or vertical alignment) get lost.
    
    This happens as SdrUndoManager::SetEndTextEditHdl() removes all undo
    items from the stack which are created after the start of the text edit,
    and creates a single item, but that doesn't include the table changes,
    just the text ones.
    
    Fix the problem by creating a copy of the CellUndo objects when it text
    edit mode, and pushing them to the undo stack in
    SdrTableObj::EndTextEdit(), which already writes the undo stack and runs
    after the undo manager cleared the text edit items from the undo stack.
    
    Change-Id: I7d2768c86b5b262e98be1d09d7fa08d581430bb5
    Reviewed-on: https://gerrit.libreoffice.org/24264
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/include/svx/svdotable.hxx b/include/svx/svdotable.hxx
index de68ed7..ed1264d 100644
--- a/include/svx/svdotable.hxx
+++ b/include/svx/svdotable.hxx
@@ -30,6 +30,7 @@
 
 class SvStream;
 class SfxStyleSheet;
+class SdrUndoAction;
 
 namespace sdr { namespace contact {
     class ViewContactOfTableObj;
@@ -249,6 +250,9 @@ public:
 
     css::text::WritingMode GetWritingMode() const;
 
+    /// Add an undo action that should be on the undo stack after ending text edit.
+    void AddUndo(SdrUndoAction* pUndo);
+
     virtual void onEditOutlinerStatusEvent( EditStatus* pEditStatus ) override;
 
     // Transformation interface for StarOfficeAPI. This implements support for
diff --git a/sd/qa/unit/misc-tests.cxx b/sd/qa/unit/misc-tests.cxx
index 105c071..857fbdd 100644
--- a/sd/qa/unit/misc-tests.cxx
+++ b/sd/qa/unit/misc-tests.cxx
@@ -27,6 +27,10 @@
 #include <svx/sdr/table/tablecontroller.hxx>
 #include <sfx2/request.hxx>
 #include <svx/svxids.hrc>
+#include <editeng/eeitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
 #include <ImpressViewShellBase.hxx>
 #include <SlideSorterViewShell.hxx>
 #include <SlideSorter.hxx>
@@ -45,11 +49,13 @@ public:
     void testTdf96206();
     void testTdf96708();
     void testTdf99396();
+    void testTdf99396TextEdit();
 
     CPPUNIT_TEST_SUITE(SdMiscTest);
     CPPUNIT_TEST(testTdf96206);
     CPPUNIT_TEST(testTdf96708);
     CPPUNIT_TEST(testTdf99396);
+    CPPUNIT_TEST(testTdf99396TextEdit);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -164,6 +170,75 @@ void SdMiscTest::testTdf99396()
     xDocSh->DoClose();
 }
 
+void SdMiscTest::testTdf99396TextEdit()
+{
+    // Load the document and select the table.
+    sd::DrawDocShellRef xDocSh = Load(m_directories.getURLFromSrc("/sd/qa/unit/data/tdf99396.odp"), ODP);
+    sd::ViewShell* pViewShell = xDocSh->GetViewShell();
+    SdPage* pPage = pViewShell->GetActualPage();
+    SdrObject* pObject = pPage->GetObj(0);
+    auto pTableObject = dynamic_cast<sdr::table::SdrTableObj*>(pObject);
+    SdrView* pView = pViewShell->GetView();
+    pView->MarkObj(pObject, pView->GetSdrPageView());
+
+    // Make sure that the undo stack is empty.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+
+    // Set horizontal and vertical adjustment during text edit.
+    pView->SdrBeginTextEdit(pObject);
+    CPPUNIT_ASSERT(pView->GetTextEditObject());
+    {
+        SfxRequest aRequest(pViewShell->GetViewFrame(), SID_ATTR_PARA_ADJUST_RIGHT);
+        SfxItemSet aEditAttr(xDocSh->GetDoc()->GetPool());
+        pView->GetAttributes(aEditAttr);
+        SfxItemSet aNewAttr(*(aEditAttr.GetPool()), aEditAttr.GetRanges());
+        aNewAttr.Put(SvxAdjustItem(SVX_ADJUST_RIGHT, EE_PARA_JUST));
+        aRequest.Done(aNewAttr);
+        const SfxItemSet* pArgs = aRequest.GetArgs();
+        pView->SetAttributes(*pArgs);
+    }
+    {
+        auto pTableController = dynamic_cast<sdr::table::SvxTableController*>(pView->getSelectionController().get());
+        SfxRequest aRequest(pViewShell->GetViewFrame(), SID_TABLE_VERT_BOTTOM);
+        pTableController->Execute(aRequest);
+    }
+    pView->SdrEndTextEdit();
+
+    // Check that the result is what we expect.
+    {
+        uno::Reference<table::XTable> xTable = pTableObject->getTable();
+        uno::Reference<beans::XPropertySet> xCell(xTable->getCellByPosition(0, 0), uno::UNO_QUERY);
+        drawing::TextVerticalAdjust eAdjust = xCell->getPropertyValue("TextVerticalAdjust").get<drawing::TextVerticalAdjust>();
+        CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_BOTTOM, eAdjust);
+    }
+    {
+        const EditTextObject& rEdit = pTableObject->getText(0)->GetOutlinerParaObject()->GetTextObject();
+        const SfxItemSet& rParaAttribs = rEdit.GetParaAttribs(0);
+        auto pAdjust = static_cast<const SvxAdjustItem*>(rParaAttribs.GetItem(EE_PARA_JUST));
+        CPPUNIT_ASSERT_EQUAL(SVX_ADJUST_RIGHT, pAdjust->GetAdjust());
+    }
+
+    // Now undo.
+    xDocSh->GetUndoManager()->Undo();
+
+    // Check again that the result is what we expect.
+    {
+        uno::Reference<table::XTable> xTable = pTableObject->getTable();
+        uno::Reference<beans::XPropertySet> xCell(xTable->getCellByPosition(0, 0), uno::UNO_QUERY);
+        drawing::TextVerticalAdjust eAdjust = xCell->getPropertyValue("TextVerticalAdjust").get<drawing::TextVerticalAdjust>();
+        // This failed: Undo() did not change it from drawing::TextVerticalAdjust_BOTTOM.
+        CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_TOP, eAdjust);
+    }
+    {
+        const EditTextObject& rEdit = pTableObject->getText(0)->GetOutlinerParaObject()->GetTextObject();
+        const SfxItemSet& rParaAttribs = rEdit.GetParaAttribs(0);
+        auto pAdjust = static_cast<const SvxAdjustItem*>(rParaAttribs.GetItem(EE_PARA_JUST));
+        CPPUNIT_ASSERT_EQUAL(SVX_ADJUST_CENTER, pAdjust->GetAdjust());
+    }
+
+    xDocSh->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdMiscTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx
index 7af8546..b4ff60a 100644
--- a/svx/source/table/cell.cxx
+++ b/svx/source/table/cell.cxx
@@ -781,6 +781,11 @@ void Cell::AddUndo()
     {
         CellRef xCell( this );
         GetModel()->AddUndo( new CellUndo( &rObj, xCell ) );
+
+        // Undo action for the after-text-edit-ended stack.
+        SdrTableObj* pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(&rObj);
+        if (pTableObj && pTableObj->IsTextEditActive())
+            pTableObj->AddUndo(new CellUndo(pTableObj, xCell));
     }
 }
 
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx
index 2bb0e28..4121fda 100644
--- a/svx/source/table/svdotable.cxx
+++ b/svx/source/table/svdotable.cxx
@@ -203,6 +203,7 @@ public:
     CellPos maEditPos;
     TableStyleSettings maTableStyle;
     Reference< XIndexAccess > mxTableStyle;
+    std::vector<std::unique_ptr<SdrUndoAction>> maUndos;
 
     void SetModel(SdrModel* pOldModel, SdrModel* pNewModel);
 
@@ -1781,7 +1782,14 @@ void SdrTableObj::EndTextEdit(SdrOutliner& rOutl)
     if(rOutl.IsModified())
     {
         if( GetModel() && GetModel()->IsUndoEnabled() )
+        {
+            // These actions should be on the undo stack after text edit.
+            for (std::unique_ptr<SdrUndoAction>& pAction : mpImpl->maUndos)
+                GetModel()->AddUndo(pAction.release());
+            mpImpl->maUndos.clear();
+
             GetModel()->AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*this) );
+        }
 
         OutlinerParaObject* pNewText = nullptr;
         Paragraph* p1stPara = rOutl.GetParagraph( 0 );
@@ -1992,6 +2000,10 @@ WritingMode SdrTableObj::GetWritingMode() const
     return eWritingMode;
 }
 
+void SdrTableObj::AddUndo(SdrUndoAction* pUndo)
+{
+    mpImpl->maUndos.push_back(std::unique_ptr<SdrUndoAction>(pUndo));
+}
 
 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
 // with the base geometry and returns TRUE. Otherwise it returns FALSE.


More information about the Libreoffice-commits mailing list