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

Miklos Vajna vmiklos at collabora.co.uk
Fri Feb 16 22:44:53 UTC 2018


 editeng/source/editeng/editeng.cxx            |    7 ++
 editeng/source/outliner/outliner.cxx          |    5 +
 include/editeng/editeng.hxx                   |    2 
 include/editeng/outliner.hxx                  |    2 
 sd/qa/unit/tiledrendering/data/tdf115783.fodp |   52 +++++++++++++++++++
 sd/qa/unit/tiledrendering/tiledrendering.cxx  |   71 ++++++++++++++++++++++++++
 sd/source/ui/view/sdview.cxx                  |   13 ++++
 7 files changed, 151 insertions(+), 1 deletion(-)

New commits:
commit f0c25c751cf8e166a84b289746bce6202a40391d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 16 18:08:46 2018 +0100

    tdf#115783 sd: fix lost char attributes during in-table copy&paste
    
    The SvxFontHeightItem (12pt) is originally a character-level property on
    the table cell (covering the whole cell text) but when the user sets the
    font height of the cell,
    sdr::properties::CellProperties::ItemSetChanged() will turn that into a
    paragraph-level property. This is fine, except that this way the
    property has unclear semantics when the user pastes single-paragraph
    content into an existing paragraph. (Keep the old paragraph properties?
    Use the new ones?)
    
    The current behavior is that sd::View::OnEndPasteOrDrop() calls into
    ContentAttribs::SetStyleSheet() at the end of the paste, which removes
    paragraph-level formatting (giving visibility to the from-style 18pt
    font height this way for the existing content), so both the old and the
    new paragraph formatting is lost.
    
    Improve the situation by copying these paragraph-level character
    properties back to character-level before paste at the paste position
    (so doc model is back to the state after load), that way font height and
    similar properties are not removed by the on-end-paste handler.
    
    Change-Id: I43d321dedcda6c0df9b009b9d99c3544f783473c
    Reviewed-on: https://gerrit.libreoffice.org/49868
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index d434114b9119..dcadbdc03db9 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -1738,6 +1738,13 @@ const SfxPoolItem& EditEngine::GetParaAttrib( sal_Int32 nPara, sal_uInt16 nWhich
     return pImpEditEngine->GetParaAttrib( nPara, nWhich );
 }
 
+void EditEngine::SetCharAttribs(sal_Int32 nPara, const SfxItemSet& rSet)
+{
+    EditSelection aSel(pImpEditEngine->ConvertSelection(nPara, 0, nPara, GetTextLen(nPara)));
+    pImpEditEngine->SetAttribs(aSel, rSet);
+    pImpEditEngine->FormatAndUpdate();
+}
+
 void EditEngine::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const
 {
     pImpEditEngine->GetCharAttribs( nPara, rLst );
diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx
index 5c310ceab03a..869ecb72a2e2 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -746,6 +746,11 @@ void Outliner::SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet )
     pEditEngine->SetParaAttribs( nPara, rSet );
 }
 
+void Outliner::SetCharAttribs(sal_Int32 nPara, const SfxItemSet& rSet)
+{
+    pEditEngine->SetCharAttribs(nPara, rSet);
+}
+
 bool Outliner::Expand( Paragraph const * pPara )
 {
     if ( pParaList->HasHiddenChildren( pPara ) )
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index c47c281f22bb..fc3a6713707a 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -313,6 +313,8 @@ public:
     virtual void        SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet );
     const SfxItemSet&   GetParaAttribs( sal_Int32 nPara ) const;
 
+    /// Set attributes from rSet an all characters of nPara.
+    void SetCharAttribs(sal_Int32 nPara, const SfxItemSet& rSet);
     void            GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const;
 
     SfxItemSet      GetAttribs( sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, GetAttribsFlags nFlags = GetAttribsFlags::ALL ) const;
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index aad54a179ae4..1b65a7bf215f 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -892,6 +892,8 @@ public:
     // Only for EditEngine mode
     void            QuickInsertText( const OUString& rText, const ESelection& rSel );
     void            QuickDelete( const ESelection& rSel );
+    /// Set attributes from rSet an all characters of nPara.
+    void SetCharAttribs(sal_Int32 nPara, const SfxItemSet& rSet);
     void            RemoveCharAttribs( sal_Int32 nPara, sal_uInt16 nWhich = 0 );
     void            QuickFormatDoc();
 
diff --git a/sd/qa/unit/tiledrendering/data/tdf115783.fodp b/sd/qa/unit/tiledrendering/data/tdf115783.fodp
new file mode 100644
index 000000000000..d9ada63ad15e
--- /dev/null
+++ b/sd/qa/unit/tiledrendering/data/tdf115783.fodp
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table: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:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:scr
 ipt="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:smil="urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xml
 ns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.presentation">
+  <office:font-face-decls>
+    <style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/>
+  </office:font-face-decls>
+  <office:automatic-styles>
+    <style:style style:name="co1" style:family="table-column">
+      <style:table-column-properties style:column-width="4.3cm" style:use-optimal-column-width="false"/>
+    </style:style>
+    <style:style style:name="co2" style:family="table-column">
+      <style:table-column-properties style:column-width="6.241cm" style:use-optimal-column-width="false"/>
+    </style:style>
+    <style:style style:name="co3" style:family="table-column">
+      <style:table-column-properties style:column-width="4.909cm" style:use-optimal-column-width="false"/>
+    </style:style>
+    <style:style style:name="ro1" style:family="table-row">
+      <style:table-row-properties style:row-height="1.364cm"/>
+    </style:style>
+    <style:style style:name="ce1" style:family="table-cell">
+      <loext:graphic-properties draw:fill="none" style:repeat="repeat"/>
+      <style:paragraph-properties fo:border="0.03pt solid #000000"/>
+      <style:text-properties style:font-name="Arial" fo:font-size="12pt"/>
+    </style:style>
+    <style:style style:name="T1" style:family="text">
+      <style:text-properties style:font-name="Arial" fo:font-size="12pt"/>
+    </style:style>
+  </office:automatic-styles>
+  <office:body>
+    <office:presentation>
+      <draw:page draw:name="page1">
+        <draw:frame draw:style-name="standard" draw:layer="layout" svg:width="15.449cm" svg:height="1.363cm" svg:x="2.179cm" svg:y="3.302cm">
+          <table:table table:template-name="default">
+            <table:table-column table:style-name="co1"/>
+            <table:table-column table:style-name="co2"/>
+            <table:table-column table:style-name="co3"/>
+            <table:table-row table:style-name="ro1" table:default-cell-style-name="ce1">
+              <table:table-cell>
+                <text:p><text:span text:style-name="T1">before</text:span></text:p>
+              </table:table-cell>
+              <table:table-cell>
+                <text:p><text:span text:style-name="T1">hello</text:span></text:p>
+              </table:table-cell>
+              <table:table-cell>
+                <text:p><text:span text:style-name="T1">after</text:span></text:p>
+              </table:table-cell>
+            </table:table-row>
+          </table:table>
+        </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 dbb77a32b3e8..162c2f8c2e4f 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -109,6 +109,7 @@ public:
     void testLanguageStatus();
     void testDefaultView();
     void testIMESupport();
+    void testTdf115783();
 
     CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -150,6 +151,7 @@ public:
     CPPUNIT_TEST(testLanguageStatus);
     CPPUNIT_TEST(testDefaultView);
     CPPUNIT_TEST(testIMESupport);
+    CPPUNIT_TEST(testTdf115783);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -1984,6 +1986,75 @@ void SdTiledRenderingTest::testIMESupport()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+void SdTiledRenderingTest::testTdf115783()
+{
+    // Load the document.
+    comphelper::LibreOfficeKit::setActive();
+    SdXImpressDocument* pXImpressDocument = createDoc("tdf115783.fodp");
+    sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
+    SdPage* pActualPage = pViewShell->GetActualPage();
+    SdrObject* pObject = pActualPage->GetObj(0);
+    auto pTableObject = dynamic_cast<sdr::table::SdrTableObj*>(pObject);
+    CPPUNIT_ASSERT(pTableObject);
+    SdrView* pView = pViewShell->GetView();
+    pView->MarkObj(pTableObject, pView->GetSdrPageView());
+
+    // Create a cell selection and set font height.
+    // Go to the end of the B1 cell.
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_LEFT);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_LEFT);
+    // Create a B1->C1 cell selection.
+    const int nShiftRight = KEY_SHIFT + KEY_RIGHT;
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, nShiftRight);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, nShiftRight);
+    uno::Sequence<beans::PropertyValue> aArgs = comphelper::InitPropertySequence({
+        { "FontHeight.Height", uno::makeAny(static_cast<float>(12)) },
+    });
+    comphelper::dispatchCommand(".uno:FontHeight", aArgs);
+    Scheduler::ProcessEventsToIdle();
+
+    // Create a text selection on the B1 cell.
+    pTableObject->setActiveCell(sdr::table::CellPos(1, 0));
+    pView->SdrBeginTextEdit(pTableObject);
+    EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
+    // Start para, start char, end para, end char.
+    rEditView.SetSelection(ESelection(0, 0, 0, 5));
+    CPPUNIT_ASSERT_EQUAL(OUString("hello"), rEditView.GetSelected());
+
+    // Copy selection, paste at the start of the cell.
+    aArgs = {};
+    comphelper::dispatchCommand(".uno:Copy", aArgs);
+    Scheduler::ProcessEventsToIdle();
+    rEditView.SetSelection(ESelection(0, 0, 0, 0));
+    aArgs = {};
+    comphelper::dispatchCommand(".uno:Paste", aArgs);
+    Scheduler::ProcessEventsToIdle();
+    pView->SdrEndTextEdit();
+
+    // And now verify that the cell has the correct font size.
+    uno::Reference<table::XCellRange> xTable(pTableObject->getTable(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xTable.is());
+    uno::Reference<text::XTextRange> xCell(xTable->getCellByPosition(1, 0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xCell.is());
+    uno::Reference<container::XEnumerationAccess> xText(xCell->getText(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xText.is());
+    uno::Reference<container::XEnumerationAccess> xParagraph(
+        xText->createEnumeration()->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xParagraph.is());
+    uno::Reference<text::XTextRange> xPortion(xParagraph->createEnumeration()->nextElement(),
+                                              uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xPortion.is());
+    // This failed, it was only "hello" as the paragraph had 2 portions: a
+    // "hello" with 12pt size and a "hello" with 18pt.
+    CPPUNIT_ASSERT_EQUAL(OUString("hellohello"), xPortion->getString());
+    uno::Reference<beans::XPropertySet> xPropertySet(xPortion, uno::UNO_QUERY);
+    int nHeight = xPropertySet->getPropertyValue("CharHeight").get<float>();
+    // Make sure that the single font size for the cell is the expected one.
+    CPPUNIT_ASSERT_EQUAL(12, nHeight);
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx
index be1417f82940..7927bbda1bef 100644
--- a/sd/source/ui/view/sdview.cxx
+++ b/sd/source/ui/view/sdview.cxx
@@ -93,6 +93,8 @@
 #include <comphelper/lok.hxx>
 #include <sfx2/lokhelper.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <svl/itemiter.hxx>
+#include <editeng/editeng.hxx>
 #include <DrawController.hxx>
 
 #include <memory>
@@ -1185,8 +1187,17 @@ void View::CheckPossibilities()
     maSmartTags.CheckPossibilities();
 }
 
-void View::OnBeginPasteOrDrop( PasteOrDropInfos* /*pInfo*/ )
+void View::OnBeginPasteOrDrop( PasteOrDropInfos* pInfo )
 {
+    SdrOutliner* pOutliner = GetTextEditOutliner();
+    if (!pOutliner)
+        return;
+
+    // Turn character attributes of the paragraph of the insert position into
+    // character-level attributes, so they are not lost when OnEndPasteOrDrop()
+    // sets the paragraph stylesheet.
+    SfxItemSet aSet(pOutliner->GetParaAttribs(pInfo->nStartPara));
+    pOutliner->SetCharAttribs(pInfo->nStartPara, aSet);
 }
 
 /** this is called after a paste or drop operation, make sure that the newly inserted paragraphs


More information about the Libreoffice-commits mailing list