[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - 4 commits - sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue May 5 08:02:49 UTC 2020


 sw/qa/extras/layout/data/writer-image-no-capture.docx       |binary
 sw/qa/extras/layout/layout.cxx                              |   15 ++
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx                  |   68 ++++++++++++
 sw/source/core/objectpositioning/anchoredobjectposition.cxx |    6 -
 sw/source/filter/ww8/docxattributeoutput.cxx                |    6 -
 sw/source/filter/ww8/docxexport.cxx                         |   55 +++++++++
 sw/source/filter/ww8/docxexport.hxx                         |    3 
 sw/source/filter/ww8/ww8atr.cxx                             |    7 +
 8 files changed, 154 insertions(+), 6 deletions(-)

New commits:
commit 0ce45bf39c53a953c9f84635699ee116f1cbb5a3
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Jan 30 17:56:53 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue May 5 09:53:31 2020 +0200

    DOCX export: write document variables
    
    This means that in case a user field is exported to DOCX and the user
    updates the field, the result will be still correct, not empty.
    
    (cherry picked from commit ae5f469d3893de73850ccc369dbf426a4acd8f15)
    
    Conflicts:
            sw/source/filter/ww8/docxexport.cxx
    
    Change-Id: I2b52292c70aa6f597f92af95e16c773839247efa

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 6a9ab0b35ead..f2867ccd5629 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -295,6 +295,7 @@ CPPUNIT_TEST_FIXTURE(SwModelTestBase, testUserField)
     utl::MediaDescriptor aMediaDescriptor;
     aMediaDescriptor["FilterName"] <<= OUString("Office Open XML Text");
     xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+    validate(maTempFile.GetFileName(), test::OOXML);
     mbExported = true;
     xmlDocPtr pXmlDoc = parseExport("word/document.xml");
     CPPUNIT_ASSERT(pXmlDoc);
@@ -303,6 +304,12 @@ CPPUNIT_TEST_FIXTURE(SwModelTestBase, testUserField)
     // exported as <w:t>User Field foo = bar</w:t>.
     assertXPathContent(pXmlDoc, "//w:p/w:r[2]/w:instrText", " DOCVARIABLE foo ");
     assertXPathContent(pXmlDoc, "//w:p/w:r[4]/w:t", "bar");
+
+    // Make sure that not only the variables, but also their values are written.
+    pXmlDoc = parseExport("word/settings.xml");
+    CPPUNIT_ASSERT(pXmlDoc);
+    assertXPath(pXmlDoc, "//w:docVars/w:docVar", "name", "foo");
+    assertXPath(pXmlDoc, "//w:docVars/w:docVar", "val", "bar");
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf124367, "tdf124367.docx")
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 7fed578100d1..b0f1ccf51627 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -34,6 +34,7 @@
 #include <com/sun/star/xml/sax/Writer.hpp>
 #include <com/sun/star/awt/XControlModel.hpp>
 #include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/text/XTextFieldsSupplier.hpp>
 
 #include <oox/token/namespaces.hxx>
 #include <oox/token/tokens.hxx>
@@ -895,6 +896,58 @@ void DocxExport::WriteProperties( )
     m_pFilter->exportDocumentProperties( xDocProps, bSecurityOptOpenReadOnly );
 }
 
+void DocxExport::WriteDocVars(const sax_fastparser::FSHelperPtr& pFS)
+{
+    SwDocShell* pDocShell = m_pDoc->GetDocShell();
+    if (!pDocShell)
+    {
+        return;
+    }
+
+    uno::Reference<text::XTextFieldsSupplier> xModel(pDocShell->GetModel(), uno::UNO_QUERY);
+    uno::Reference<container::XNameAccess> xTextFieldMasters = xModel->getTextFieldMasters();
+    uno::Sequence<rtl::OUString> aMasterNames = xTextFieldMasters->getElementNames();
+    if (!aMasterNames.hasElements())
+    {
+        return;
+    }
+
+    // Only write docVars if there will be at least a single docVar.
+    bool bStarted = false;
+    const OUStringLiteral aPrefix("com.sun.star.text.fieldmaster.User.");
+    for (const auto& rMasterName : std::as_const(aMasterNames))
+    {
+        if (!rMasterName.startsWith(aPrefix))
+        {
+            // Not a user field.
+            continue;
+        }
+
+        uno::Reference<beans::XPropertySet> xField;
+        xTextFieldMasters->getByName(rMasterName) >>= xField;
+        if (!xField.is())
+        {
+            continue;
+        }
+
+        OUString aKey = rMasterName.copy(aPrefix.getLength());
+        OUString aValue;
+        xField->getPropertyValue("Content") >>= aValue;
+        if (!bStarted)
+        {
+            bStarted = true;
+            pFS->startElementNS(XML_w, XML_docVars);
+        }
+        pFS->singleElementNS(XML_w, XML_docVar, FSNS(XML_w, XML_name), aKey.toUtf8(),
+                             FSNS(XML_w, XML_val), aValue.toUtf8());
+    }
+
+    if (bStarted)
+    {
+        pFS->endElementNS(XML_w, XML_docVars);
+    }
+}
+
 void DocxExport::WriteSettings()
 {
     SwViewShell *pViewShell(m_pDoc->getIDocumentLayoutAccess().GetCurrentViewShell());
@@ -1162,6 +1215,8 @@ void DocxExport::WriteSettings()
         }
     }
 
+    WriteDocVars(pFS);
+
     if (! hasProtectionProperties)
     {
         // Protect form - highest priority
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index 00b908dc7efa..f659cd1244f4 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -245,6 +245,9 @@ private:
     /// Write word/settings.xml
     void WriteSettings();
 
+    /// Writes the <w:docVars> part of settings.xml
+    void WriteDocVars(const sax_fastparser::FSHelperPtr& pFS);
+
     /// Write word/theme/theme1.xml
     void WriteTheme();
 
commit d0251db8511dbdef790599e9b47174a3bc9201cf
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Jan 30 10:21:08 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue May 5 09:51:52 2020 +0200

    DOCX export: implement support for user fields
    
    Updating the field doesn't work yet, that'll need additional markup in
    settings.xml.
    
    (cherry picked from commit 676862bb8aa043f116615e5d0dac59254eaa8138)
    
    Conflicts:
            sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
    
    Change-Id: I562ae62cebcbd5ca474bd0f7a181773f8e515f5e

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 0b0fddb4a83c..6a9ab0b35ead 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -21,6 +21,7 @@
 #include <com/sun/star/awt/FontWeight.hpp>
 #include <com/sun/star/style/LineSpacing.hpp>
 #include <com/sun/star/style/LineSpacingMode.hpp>
+#include <com/sun/star/text/XDependentTextField.hpp>
 
 class Test : public SwModelTestBase
 {
@@ -273,6 +274,37 @@ CPPUNIT_TEST_FIXTURE(SwModelTestBase, testZeroLineSpacing)
     assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:spacing", "line", "0");
 }
 
+CPPUNIT_TEST_FIXTURE(SwModelTestBase, testUserField)
+{
+    // Create an in-memory empty document with a user field.
+    loadURL("private:factory/swriter", nullptr);
+    uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XDependentTextField> xField(
+        xFactory->createInstance("com.sun.star.text.TextField.User"), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xMaster(
+        xFactory->createInstance("com.sun.star.text.FieldMaster.User"), uno::UNO_QUERY);
+    xMaster->setPropertyValue("Name", uno::makeAny(OUString("foo")));
+    xField->attachTextFieldMaster(xMaster);
+    xField->getTextFieldMaster()->setPropertyValue("Content", uno::makeAny(OUString("bar")));
+    uno::Reference<text::XTextDocument> xDocument(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XText> xText = xDocument->getText();
+    xText->insertTextContent(xText->createTextCursor(), xField, /*bAbsorb=*/false);
+
+    // Export to docx.
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= OUString("Office Open XML Text");
+    xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+    mbExported = true;
+    xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+    CPPUNIT_ASSERT(pXmlDoc);
+
+    // Without the accompanying fix in place, this test would have failed, the user field was
+    // exported as <w:t>User Field foo = bar</w:t>.
+    assertXPathContent(pXmlDoc, "//w:p/w:r[2]/w:instrText", " DOCVARIABLE foo ");
+    assertXPathContent(pXmlDoc, "//w:p/w:r[4]/w:t", "bar");
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf124367, "tdf124367.docx")
 {
     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 4be2d36e177b..cc272ff062e5 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -3271,6 +3271,13 @@ void AttributeOutputBase::TextField( const SwFormatField& rField )
             GetExport().OutputField( pField, ww::eMACROBUTTON, sStr );
         }
         break;
+    case SwFieldIds::User:
+    {
+        ww::eField eField = ww::eDOCVARIABLE;
+        OUString aExpand = FieldString(eField) + pField->GetPar1() + " ";
+        GetExport().OutputField(pField, eField, aExpand);
+    }
+    break;
     default:
         bWriteExpand = true;
         break;
commit 1fb04f7c4b6838e436d085f5294ebf29b62610a1
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jan 24 17:01:29 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue May 5 09:50:31 2020 +0200

    DOCX export: fix line spacing when spacing is 0
    
    When the input was:
    
        <w:pPr>
          <w:spacing w:line="0" w:lineRule="atLeast"/>
        </w:pPr>
    
    Then we used to write:
    
        <w:pPr>
          <w:spacing w:lineRule="auto"/>
        </w:pPr>
    
    which is clarly wrong.
    
    The comment at the end of AttributeOutputBase::ParaLineSpacing()
    documents the intention reasonably clearly (and is in sync with what's
    in the DOC and DOCX spec), adapt
    DocxAttributeOutput::ParaLineSpacing_Impl() accordingly.
    
    (cherry picked from commit ff139ea42279cc9861abb13e22878c9d435acb21)
    
    Conflicts:
            sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
    
    Change-Id: I60cbc3392a6460ba2760b2c02ae0755726478ec1

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 445f245d0160..0b0fddb4a83c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -19,6 +19,8 @@
 #include <com/sun/star/text/RelOrientation.hpp>
 #include <com/sun/star/text/XDocumentIndex.hpp>
 #include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/style/LineSpacingMode.hpp>
 
 class Test : public SwModelTestBase
 {
@@ -244,6 +246,33 @@ DECLARE_OOXMLEXPORT_TEST(testTdf121658, "tdf121658.docx")
     assertXPath(pXmlSettings, "/w:settings/w:doNotHyphenateCaps");
 }
 
+CPPUNIT_TEST_FIXTURE(SwModelTestBase, testZeroLineSpacing)
+{
+    // Create the doc model.
+    loadURL("private:factory/swriter", nullptr);
+    uno::Reference<beans::XPropertySet> xParagraph(getParagraph(1), uno::UNO_QUERY);
+    style::LineSpacing aSpacing;
+    aSpacing.Mode = style::LineSpacingMode::MINIMUM;
+    aSpacing.Height = 0;
+    xParagraph->setPropertyValue("ParaLineSpacing", uno::makeAny(aSpacing));
+
+    // Export to docx.
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= OUString("Office Open XML Text");
+    xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+    mbExported = true;
+    xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+    CPPUNIT_ASSERT(pXmlDoc);
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: atLeast
+    // - Actual  : auto
+    // i.e. the minimal linespacing was lost on export.
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:spacing", "lineRule", "atLeast");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:spacing", "line", "0");
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf124367, "tdf124367.docx")
 {
     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index ec37717bc7bc..993a6b984ca5 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -7792,20 +7792,18 @@ void DocxAttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
                 FSNS( XML_w, XML_lineRule ), "exact",
                 FSNS( XML_w, XML_line ), OString::number( -nSpace ).getStr() );
     }
-    else if( nMulti )
+    else if( nSpace > 0 && nMulti )
     {
         AddToAttrList( m_pParagraphSpacingAttrList, 2,
                 FSNS( XML_w, XML_lineRule ), "auto",
                 FSNS( XML_w, XML_line ), OString::number( nSpace ).getStr() );
     }
-    else if ( nSpace > 0 )
+    else
     {
         AddToAttrList( m_pParagraphSpacingAttrList, 2,
                 FSNS( XML_w, XML_lineRule ), "atLeast",
                 FSNS( XML_w, XML_line ), OString::number( nSpace ).getStr() );
     }
-    else
-        AddToAttrList( m_pParagraphSpacingAttrList, FSNS( XML_w, XML_lineRule ), "auto" );
 }
 
 void DocxAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
commit 7d54de978e5719f734c670241af252ba850502f6
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Jan 23 18:05:26 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue May 5 09:48:29 2020 +0200

    sw DoNotCaptureDrawObjsOnPage: don't capture wrap-through Writer images, either
    
    This compat flag was originally added in commit
    7961b14c4f9f00696b241e5ad9bf9ba18041fe22 (INTEGRATION: CWS
    swdrawobjpos203 (1.12.54); FILE MERGED, 2006-03-22) for compatibility
    with OOo 1.x.
    
    Later commit af313fc149f80adb0f1680ca20e19745ccb7fede (tdf#105143 DOCX
    import: enable DoNotCaptureDrawObjsOnPage layout compat option,
    2017-01-06) also turned it on for DOCX documents.
    
    One overlooked difference was that the compat flag disables "capturing"
    of draw objects only, but not wrap-through Writer images. The DOCX case
    wants the same for wrap-through Writer images as well, since Word does
    no capturing in either case.
    
    Fix the problem by disabling capturing for wrap-through Writer images as
    well; if this turns out to be too problematic, we can have a dedicated
    compat flag just for OOo 1.x documents, but that comes at some cost as
    well.  (Need to write the new compat flag to each & every new ODT.)
    
    TextBoxes are handled separately (see testTDF91260 in
    CppunitTest_sw_ooxmlexport8), so leave their handling unchanged.
    
    Change-Id: I74f434ed7518d7784c7cba085deb6ff8baf1770a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87289
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 195eae4852012eed6da72c0a9f55094a09aa2867)

diff --git a/sw/qa/extras/layout/data/writer-image-no-capture.docx b/sw/qa/extras/layout/data/writer-image-no-capture.docx
new file mode 100644
index 000000000000..ebb1f669f4a7
Binary files /dev/null and b/sw/qa/extras/layout/data/writer-image-no-capture.docx differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index e33eaf66e108..3f90898142ac 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -3810,6 +3810,21 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testBtlrTableRowSpan)
     assertXPathContent(pXmlDoc, "//textarray[1]/text", "USA");
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testWriterImageNoCapture)
+{
+    createDoc("writer-image-no-capture.docx");
+    xmlDocPtr pXmlDoc = parseLayoutDump();
+    CPPUNIT_ASSERT(pXmlDoc);
+    sal_Int32 nPageLeft = getXPath(pXmlDoc, "//page/infos/bounds", "left").toInt32();
+    sal_Int32 nImageLeft = getXPath(pXmlDoc, "//fly/infos/bounds", "left").toInt32();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected less than: 284
+    // - Actual  : 284
+    // i.e. the image position was modified to be inside the page frame ("captured"), even if Word
+    // does not do that.
+    CPPUNIT_ASSERT_LESS(nPageLeft, nImageLeft);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
index ad3f7cd8ee46..7480e991d090 100644
--- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx
+++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
@@ -118,10 +118,12 @@ void SwAnchoredObjectPosition::GetInfoAboutObj()
     // determine, if anchored object has not to be captured on the page.
     // the following conditions must be hold to *not* capture it:
     // - corresponding document compatibility flag is set
-    // - it's a drawing object
+    // - it's a drawing object or it's a non-textbox wrap-though fly frame
     // - it doesn't follow the text flow
     {
-        mbDoNotCaptureAnchoredObj = !mbIsObjFly && !mbFollowTextFlow &&
+        bool bTextBox = SwTextBoxHelper::isTextBox(mpFrameFormat, RES_FLYFRMFMT);
+        bool bWrapThrough = mpFrameFormat->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH;
+        mbDoNotCaptureAnchoredObj = (!mbIsObjFly || (!bTextBox && bWrapThrough)) && !mbFollowTextFlow &&
                                     mpFrameFormat->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE);
     }
 }


More information about the Libreoffice-commits mailing list