[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - 9 commits - include/xmloff lotuswordpro/source sc/source sc/uiconfig sw/inc sw/qa sw/source writerfilter/source xmloff/source

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Mon Jun 15 16:08:29 UTC 2020


 include/xmloff/xmlnumfi.hxx                      |    2 
 lotuswordpro/source/filter/lwpframelayout.cxx    |    2 
 sc/source/ui/inc/hdrcont.hxx                     |    1 
 sc/source/ui/view/hdrcont.cxx                    |   15 ++
 sc/uiconfig/scalc/ui/mergecellsdialog.ui         |    1 
 sw/inc/undobj.hxx                                |    3 
 sw/qa/extras/odfimport/data/tdf133459.odt        |binary
 sw/qa/extras/odfimport/odfimport.cxx             |   30 ++++
 sw/qa/extras/ooxmlexport/data/tdf83309.docx      |binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx       |   14 ++
 sw/qa/extras/uiwriter/uiwriter2.cxx              |  148 +++++++++++++++++++++++
 sw/source/core/doc/docedt.cxx                    |   36 ++---
 sw/source/core/edit/edlingu.cxx                  |    3 
 sw/source/core/text/txttab.cxx                   |   10 +
 sw/source/core/undo/undobj.cxx                   |   57 ++++----
 sw/source/core/undo/unins.cxx                    |   41 ++----
 sw/source/filter/ww8/docxattributeoutput.cxx     |    2 
 sw/source/filter/ww8/wrtw8num.cxx                |    2 
 writerfilter/source/dmapper/NumberingManager.cxx |    4 
 writerfilter/source/dmapper/NumberingManager.hxx |    3 
 xmloff/source/core/xmlimp.cxx                    |    8 -
 xmloff/source/style/xmlnumfi.cxx                 |   16 ++
 22 files changed, 312 insertions(+), 86 deletions(-)

New commits:
commit ff49c4ba3933bc634f6d374b507613a9ca4a849a
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sun Jun 14 17:24:51 2020 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 15 17:07:55 2020 +0100

    Resolves: tdf#133985 make ok the default
    
    Change-Id: I5fa0db660c03fb85a6a661b70fa9c14014c92579
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96279
    Tested-by: Jenkins
    Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>

diff --git a/sc/uiconfig/scalc/ui/mergecellsdialog.ui b/sc/uiconfig/scalc/ui/mergecellsdialog.ui
index d646474ca7f2..917138a76033 100644
--- a/sc/uiconfig/scalc/ui/mergecellsdialog.ui
+++ b/sc/uiconfig/scalc/ui/mergecellsdialog.ui
@@ -44,7 +44,6 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
-                <property name="has_default">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_stock">True</property>
               </object>
commit 14066fe42f6f4bfc722c45a96d9967cbd169a277
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Jun 12 14:17:20 2020 +0200
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 15 17:07:54 2020 +0100

    tdf#131912 sw: fix spell check correct deleting flys
    
    * SwEditShell::ApplyChangedSentence() should not call
      DeleteAndJoin() + InsertString() but ReplaceRange()
    
    * ReplaceRange() and SwUndoReplace need to set a new flag
      DelContentType::Replace to tell SwUndoSaveContent::DelContentIndex()
      not to delete flys but instead record the previous anchor positions
    
    * SwUndoReplace::UndoImpl() should also not call DeleteAndJoin()
      + InsertString(); instead call ReplaceRange() for the start node
      and then DeleteAndJoin() for any regex "\n" that were inserted
    
    (regression from 28b77c89dfcafae82cf2a6d85731b643ff9290e5)
    
    Change-Id: I485d79510ae233213cb4b208533871934c5e5ec6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96201
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit e1629c210ad78310e3d48c0756723134a27b89df)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96204
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx
index 89013a7dd2f5..d449de1f8c9f 100644
--- a/sw/inc/undobj.hxx
+++ b/sw/inc/undobj.hxx
@@ -135,12 +135,13 @@ enum class DelContentType : sal_uInt16
     Fly          = 0x02,
     Bkm          = 0x08,
     AllMask      = 0x0b,
+    Replace      = 0x10,
     WriterfilterHack = 0x20,
     ExcludeFlyAtStartEnd = 0x40,
     CheckNoCntnt = 0x80,
 };
 namespace o3tl {
-    template<> struct typed_flags<DelContentType> : is_typed_flags<DelContentType, 0xeb> {};
+    template<> struct typed_flags<DelContentType> : is_typed_flags<DelContentType, 0xfb> {};
 }
 
 /// will DelContentIndex destroy a frame anchored at character at rAnchorPos?
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 6c8ef7966efb..7890dbf22b4b 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -371,6 +371,154 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf132236)
     assertXPath(pXmlDoc, "/root/page[1]/body/txt", 1);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf131912)
+{
+    SwDoc* const pDoc = createDoc();
+    SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+    sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
+
+    sw::UnoCursorPointer pCursor(
+        pDoc->CreateUnoCursor(SwPosition(SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1))));
+
+    pDoc->getIDocumentContentOperations().InsertString(*pCursor, "foo");
+
+    {
+        SfxItemSet flySet(pDoc->GetAttrPool(),
+                          svl::Items<RES_FRM_SIZE, RES_FRM_SIZE, RES_ANCHOR, RES_ANCHOR>{});
+        SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
+        pWrtShell->StartOfSection(false);
+        pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 2, /*bBasicCall=*/false);
+        anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
+        flySet.Put(anchor);
+        SwFormatFrameSize size(ATT_MIN_SIZE, 1000, 1000);
+        flySet.Put(size); // set a size, else we get 1 char per line...
+        SwFrameFormat const* pFly = pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true);
+        CPPUNIT_ASSERT(pFly != nullptr);
+    }
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+
+    pCursor->SetMark();
+    pCursor->GetMark()->nContent.Assign(pCursor->GetContentNode(), 0);
+    pCursor->GetPoint()->nContent.Assign(pCursor->GetContentNode(), 3);
+
+    // replace with more text
+    pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, "blahblah", false);
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    CPPUNIT_ASSERT_EQUAL(OUString("blahblah"), pCursor->GetNode().GetTextNode()->GetText());
+
+    rUndoManager.Undo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    CPPUNIT_ASSERT_EQUAL(OUString("foo"), pCursor->GetNode().GetTextNode()->GetText());
+
+    rUndoManager.Redo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    CPPUNIT_ASSERT_EQUAL(OUString("blahblah"), pCursor->GetNode().GetTextNode()->GetText());
+
+    rUndoManager.Undo();
+
+    pCursor->GetMark()->nContent.Assign(pCursor->GetContentNode(), 0);
+    pCursor->GetPoint()->nContent.Assign(pCursor->GetContentNode(), 3);
+
+    // replace with less text
+    pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, "x", false);
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    CPPUNIT_ASSERT_EQUAL(OUString("x"), pCursor->GetNode().GetTextNode()->GetText());
+
+    rUndoManager.Undo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    CPPUNIT_ASSERT_EQUAL(OUString("foo"), pCursor->GetNode().GetTextNode()->GetText());
+
+    rUndoManager.Redo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    CPPUNIT_ASSERT_EQUAL(OUString("x"), pCursor->GetNode().GetTextNode()->GetText());
+
+    rUndoManager.Undo();
+
+    pCursor->GetMark()->nContent.Assign(pCursor->GetContentNode(), 0);
+    pCursor->GetPoint()->nContent.Assign(pCursor->GetContentNode(), 3);
+
+    // regex replace with paragraph breaks
+    pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, "xyz\\n\\nquux\\n", true);
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    pWrtShell->StartOfSection(false);
+    CPPUNIT_ASSERT_EQUAL(OUString("xyz"),
+                         pWrtShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pWrtShell->EndOfSection(true);
+    CPPUNIT_ASSERT_EQUAL(OUString("xyz\n\nquux\n"), pWrtShell->GetCursor()->GetText());
+
+    rUndoManager.Undo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    CPPUNIT_ASSERT_EQUAL(OUString("foo"), pCursor->GetNode().GetTextNode()->GetText());
+    pWrtShell->StartOfSection(false);
+    pWrtShell->EndOfSection(true);
+    CPPUNIT_ASSERT_EQUAL(OUString("foo"), pWrtShell->GetCursor()->GetText());
+
+    rUndoManager.Redo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    pWrtShell->StartOfSection(false);
+    CPPUNIT_ASSERT_EQUAL(OUString("xyz"),
+                         pWrtShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pWrtShell->EndOfSection(true);
+    CPPUNIT_ASSERT_EQUAL(OUString("xyz\n\nquux\n"), pWrtShell->GetCursor()->GetText());
+
+    // regex replace with paragraph join
+    pWrtShell->StartOfSection(false);
+    pWrtShell->Down(true);
+    pDoc->getIDocumentContentOperations().ReplaceRange(*pWrtShell->GetCursor(), "bar", true);
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    pWrtShell->StartOfSection(false);
+    CPPUNIT_ASSERT_EQUAL(OUString("bar"),
+                         pWrtShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pWrtShell->EndOfSection(true);
+    CPPUNIT_ASSERT_EQUAL(OUString("bar\nquux\n"), pWrtShell->GetCursor()->GetText());
+
+    rUndoManager.Undo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    pWrtShell->StartOfSection(false);
+    CPPUNIT_ASSERT_EQUAL(OUString("xyz"),
+                         pWrtShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pWrtShell->EndOfSection(true);
+    CPPUNIT_ASSERT_EQUAL(OUString("xyz\n\nquux\n"), pWrtShell->GetCursor()->GetText());
+
+    rUndoManager.Redo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    pWrtShell->StartOfSection(false);
+    CPPUNIT_ASSERT_EQUAL(OUString("bar"),
+                         pWrtShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pWrtShell->EndOfSection(true);
+    CPPUNIT_ASSERT_EQUAL(OUString("bar\nquux\n"), pWrtShell->GetCursor()->GetText());
+
+    rUndoManager.Undo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    pWrtShell->StartOfSection(false);
+    CPPUNIT_ASSERT_EQUAL(OUString("xyz"),
+                         pWrtShell->GetCursor()->GetNode().GetTextNode()->GetText());
+    pWrtShell->EndOfSection(true);
+    CPPUNIT_ASSERT_EQUAL(OUString("xyz\n\nquux\n"), pWrtShell->GetCursor()->GetText());
+
+    rUndoManager.Undo();
+
+    CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_FRM));
+    CPPUNIT_ASSERT_EQUAL(OUString("foo"), pCursor->GetNode().GetTextNode()->GetText());
+    pWrtShell->StartOfSection(false);
+    pWrtShell->EndOfSection(true);
+    CPPUNIT_ASSERT_EQUAL(OUString("foo"), pWrtShell->GetCursor()->GetText());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf54819)
 {
     load(DATA_DIRECTORY, "tdf54819.fodt");
diff --git a/sw/source/core/edit/edlingu.cxx b/sw/source/core/edit/edlingu.cxx
index 5ce423517922..2a858c015270 100644
--- a/sw/source/core/edit/edlingu.cxx
+++ b/sw/source/core/edit/edlingu.cxx
@@ -1137,11 +1137,10 @@ void SwEditShell::ApplyChangedSentence(const svx::SpellPortions& rNewPortions, b
             if(aCurrentNewPortion->sText != aCurrentOldPortion->sText)
             {
                 // change text ...
-                mxDoc->getIDocumentContentOperations().DeleteAndJoin(*pCursor);
                 // ... and apply language if necessary
                 if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage)
                     SetAttrItem( SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId) );
-                mxDoc->getIDocumentContentOperations().InsertString(*pCursor, aCurrentNewPortion->sText);
+                mxDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, aCurrentNewPortion->sText, false);
             }
             else if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage)
             {
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index de81e9e338d5..3e4ddb2c01ef 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -967,7 +967,8 @@ void SwUndoSaveContent::DelContentIndex( const SwPosition& rMark,
                             if (!m_pHistory)
                                 m_pHistory.reset( new SwHistory );
 
-                            if (IsSelectFrameAnchoredAtPara(*pAPos, *pStt, *pEnd, nDelContentType))
+                            if (!(DelContentType::Replace & nDelContentType)
+                                && IsSelectFrameAnchoredAtPara(*pAPos, *pStt, *pEnd, nDelContentType))
                             {
                                 m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
                                 // reset n so that no Format is skipped
@@ -998,7 +999,8 @@ void SwUndoSaveContent::DelContentIndex( const SwPosition& rMark,
                     {
                         if( !m_pHistory )
                             m_pHistory.reset( new SwHistory );
-                        if (IsDestroyFrameAnchoredAtChar(
+                        if (!(DelContentType::Replace & nDelContentType)
+                            && IsDestroyFrameAnchoredAtChar(
                                 *pAPos, *pStt, *pEnd, nDelContentType))
                         {
                             m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
diff --git a/sw/source/core/undo/unins.cxx b/sw/source/core/undo/unins.cxx
index 4ebe984116ae..85b20fae911b 100644
--- a/sw/source/core/undo/unins.cxx
+++ b/sw/source/core/undo/unins.cxx
@@ -603,7 +603,7 @@ SwUndoReplace::Impl::Impl(
     OSL_ENSURE( pNd, "Dude, where's my TextNode?" );
 
     m_pHistory.reset( new SwHistory );
-    DelContentIndex( *rPam.GetMark(), *rPam.GetPoint() );
+    DelContentIndex(*rPam.GetMark(), *rPam.GetPoint(), DelContentType::AllMask | DelContentType::Replace);
 
     m_nSetPos = m_pHistory->Count();
 
@@ -664,42 +664,39 @@ void SwUndoReplace::Impl::UndoImpl(::sw::UndoRedoContext & rContext)
         pDoc->SetAutoCorrExceptWord( nullptr );
     }
 
-    SwIndex aIdx( pNd, m_nSttCnt );
     // don't look at m_sIns for deletion, maybe it was not completely inserted
     {
         rPam.GetPoint()->nNode = *pNd;
         rPam.GetPoint()->nContent.Assign( pNd, m_nSttCnt );
         rPam.SetMark();
-        rPam.GetPoint()->nNode = m_nEndNd - m_nOffset;
-        rPam.GetPoint()->nContent.Assign( rPam.GetContentNode(), m_nEndCnt );
-        // move it out of the way so it is not registered at deleted node
-        aIdx.Assign(nullptr, 0);
-
-        pDoc->getIDocumentContentOperations().DeleteAndJoin( rPam );
+        rPam.GetPoint()->nNode = m_nSttNd - m_nOffset;
+        rPam.GetPoint()->nContent.Assign(rPam.GetContentNode(), m_nSttNd == m_nEndNd ? m_nEndCnt : pNd->Len());
+
+        // replace only in start node, without regex
+        bool const ret = pDoc->getIDocumentContentOperations().ReplaceRange(rPam, m_sOld, false);
+        assert(ret); (void)ret;
+        if (m_nSttNd != m_nEndNd)
+        {   // in case of regex inserting paragraph breaks, join nodes...
+            assert(rPam.GetMark()->nContent == rPam.GetMark()->nNode.GetNode().GetTextNode()->Len());
+            rPam.GetPoint()->nNode = m_nEndNd - m_nOffset;
+            rPam.GetPoint()->nContent.Assign(rPam.GetContentNode(true), m_nEndCnt);
+            pDoc->getIDocumentContentOperations().DeleteAndJoin(rPam);
+        }
         rPam.DeleteMark();
-        pNd = rPam.GetNode().GetTextNode();
+        pNd = pDoc->GetNodes()[ m_nSttNd - m_nOffset ]->GetTextNode();
         OSL_ENSURE( pNd, "Dude, where's my TextNode?" );
-        aIdx.Assign( pNd, m_nSttCnt );
     }
 
     if( m_bSplitNext )
     {
-        SwPosition aPos( *pNd, aIdx );
+        SwPosition aPos(*pNd, pNd->Len());
         pDoc->getIDocumentContentOperations().SplitNode( aPos, false );
         pNd->RestoreMetadata(m_pMetadataUndoEnd);
         pNd = pDoc->GetNodes()[ m_nSttNd - m_nOffset ]->GetTextNode();
-        aIdx.Assign( pNd, m_nSttCnt );
         // METADATA: restore
         pNd->RestoreMetadata(m_pMetadataUndoStart);
     }
 
-    if (!m_sOld.isEmpty())
-    {
-        OUString const ins( pNd->InsertText( m_sOld, aIdx ) );
-        assert(ins.getLength() == m_sOld.getLength()); // must succeed
-        (void) ins;
-    }
-
     if( m_pHistory )
     {
         if( pNd->GetpSwpHints() )
@@ -726,7 +723,7 @@ void SwUndoReplace::Impl::UndoImpl(::sw::UndoRedoContext & rContext)
     }
 
     rPam.GetPoint()->nNode = m_nSttNd;
-    rPam.GetPoint()->nContent = aIdx;
+    rPam.GetPoint()->nContent = m_nSttCnt;
 }
 
 void SwUndoReplace::Impl::RedoImpl(::sw::UndoRedoContext & rContext)
@@ -752,7 +749,7 @@ void SwUndoReplace::Impl::RedoImpl(::sw::UndoRedoContext & rContext)
         auto xSave = std::make_unique<SwHistory>();
         std::swap(m_pHistory, xSave);
 
-        DelContentIndex( *rPam.GetMark(), *rPam.GetPoint() );
+        DelContentIndex(*rPam.GetMark(), *rPam.GetPoint(), DelContentType::AllMask | DelContentType::Replace);
         m_nSetPos = m_pHistory->Count();
 
         std::swap(xSave, m_pHistory);
@@ -761,7 +758,7 @@ void SwUndoReplace::Impl::RedoImpl(::sw::UndoRedoContext & rContext)
     else
     {
         m_pHistory.reset( new SwHistory );
-        DelContentIndex( *rPam.GetMark(), *rPam.GetPoint() );
+        DelContentIndex(*rPam.GetMark(), *rPam.GetPoint(), DelContentType::AllMask | DelContentType::Replace);
         m_nSetPos = m_pHistory->Count();
         if( !m_nSetPos )
         {
commit f8a2525542d987b7a5dd8f8fd9337a9212e1255a
Author:     Maxim Monastirsky <momonasmon at gmail.com>
AuthorDate: Fri Jun 12 16:38:13 2020 +0300
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 15 17:07:54 2020 +0100

    tdf#133459 Fix import of fields with user defined number formats
    
    commit 59ace23c367f83491a37e844d16f7d716eff6346 ("tdf#101710 Fix
    invalid style:data-style-name attribute") had a side effect of
    exporting user defined number formats under <office:styles> instead
    of under <office:automatic-styles> (which is valid, and what Calc
    does since forever). As it turned out, this didn't work well for
    fields:
    
    - For fields inside headers or footers, their number format wasn't
    imported at all. The reason here is that fields use the
    XMLTextImportHelper::GetDataStyleKey method to resolve data styles,
    and that method checks only automatic styles. Actually it resolves
    also styles from <office:styles>, because SvXMLImport::SetAutoStyles
    has a special code that merges styles from <office:styles> into
    automatic styles during content.xml reading. The problem is that
    headers and footers have their contents stored inside styles.xml,
    and no merging happens at this stage (unless it's a flat odf file).
    One way to solve this could be to explicitly check for styles from
    <office:styles> in XMLTextImportHelper::GetDataStyleKey (e.g. see
    previous gerrit patchsets, or XMLTableStyleContext::GetNumberFormat)
    I chose to simply modify the condition in SvXMLImport::SetAutoStyles,
    so that merging happens anyway.
    
    - Fields whose format resolution depends on the merging of
    SvXMLImport::SetAutoStyles, did import the number format itself,
    but not its language setting. This can be in one of three ways:
    (a) Fields in the document and the header, when both use the same
    format. In this case the format is stored once in styles.xml, so
    at least the consumer from content.xml depends on merging.
    (b) Field in the document with a user defined format - a regression
    of the above commit. Now stored in styles.xml under <office:styles>
    instead of in content.xml under <office:automatic-styles>.
    (c) Field in a header with a user defined format - depends
    on merging as a result of the above fix.
    
    The reason here is that the merging isn't done with the original
    SvXMLNumFormatContext objects, but with a newly created fake ones,
    which only have the format id correct (with the assumption that
    those formats already imported, and calling code could just find
    them by the id). The problem is that the fields code uses
    XMLTextImportHelper::GetDataStyleKey to get the language setting
    from style objects, and set the IsFixedLanguage property according
    to it, while we know that those fake objects don't have the
    language correctly set. Try to fix that problem by setting the
    correct language on those fake objects.
    
    Conflicts:
            sw/qa/extras/odfimport/odfimport.cxx
    
    Change-Id: Ibb362df019921e040708d3bda83bf155535ec7af
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95612
    Tested-by: Jenkins
    Reviewed-by: Maxim Monastirsky <momonasmon at gmail.com>
    (cherry picked from commit cd0dc1bc592d7952c36659da33d99ab964fe2e93)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96267
    Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>

diff --git a/include/xmloff/xmlnumfi.hxx b/include/xmloff/xmlnumfi.hxx
index 4a1eaca5b256..f772a54b4d28 100644
--- a/include/xmloff/xmlnumfi.hxx
+++ b/include/xmloff/xmlnumfi.hxx
@@ -91,6 +91,7 @@ public:
     SvXMLNumImpData* getData() { return pData.get(); }
 
     const SvXMLTokenMap&    GetStylesElemTokenMap();
+    LanguageType            GetLanguageForKey(sal_Int32 nKey);
 
 //  sal_uInt32  GetKeyForName( const OUString& rName );
 };
@@ -164,6 +165,7 @@ public:
                                     const OUString& rLName,
                                     const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
                                     const sal_Int32 nKey,
+                                    LanguageType nLang,
                                     SvXMLStylesContext& rStyles );
     virtual     ~SvXMLNumFormatContext() override;
 
diff --git a/sw/qa/extras/odfimport/data/tdf133459.odt b/sw/qa/extras/odfimport/data/tdf133459.odt
new file mode 100644
index 000000000000..9468d7918a6c
Binary files /dev/null and b/sw/qa/extras/odfimport/data/tdf133459.odt differ
diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx
index eb65f0d63540..27e1809eaeff 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -23,6 +23,9 @@
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/PageNumberType.hpp>
 #include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/lang/Locale.hpp>
 
 #include <IDocumentSettingAccess.hxx>
 #include <wrtsh.hxx>
@@ -970,5 +973,32 @@ DECLARE_ODFIMPORT_TEST(testTdf123968, "tdf123968.odt")
                          rStart.GetText());
 }
 
+DECLARE_ODFIMPORT_TEST(testTdf133459, "tdf133459.odt")
+{
+    // Test that the number format was correctly imported, and used by both fields.
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xFields(xTextFieldsSupplier->getTextFields()->createEnumeration());
+
+    // First Field
+    uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY);
+    const OUString sPresentation(xField->getPresentation(false));
+    const sal_Int32 nFormat(getProperty<sal_Int32>(xField, "NumberFormat"));
+    CPPUNIT_ASSERT_EQUAL(sal_True, getProperty<sal_Bool>(xField, "IsFixedLanguage"));
+
+    // Second field
+    xField.set(xFields->nextElement(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sPresentation, xField->getPresentation(false));
+    CPPUNIT_ASSERT_EQUAL(nFormat, getProperty<sal_Int32>(xField, "NumberFormat"));
+    CPPUNIT_ASSERT_EQUAL(sal_True, getProperty<sal_Bool>(xField, "IsFixedLanguage"));
+
+    // Test the number format itself
+    uno::Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xFormat(xNumberFormatsSupplier->getNumberFormats()->getByKey(nFormat));
+    lang::Locale aLocale(getProperty<lang::Locale>(xFormat, "Locale"));
+    CPPUNIT_ASSERT_EQUAL(OUString("ru"), aLocale.Language);
+    CPPUNIT_ASSERT_EQUAL(OUString("RU"), aLocale.Country);
+    CPPUNIT_ASSERT_EQUAL(OUString("QQ YYYY"), getProperty<OUString>(xFormat, "FormatString"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index 6ebbd00ea7bb..2c809d1112cb 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -1622,7 +1622,7 @@ void SvXMLImport::SetStyles( SvXMLStylesContext *pStyles )
 
 void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles )
 {
-    if (pAutoStyles && mxNumberStyles.is() && (mnImportFlags & SvXMLImportFlags::CONTENT) )
+    if (pAutoStyles && mxNumberStyles.is())
     {
         uno::Reference<xml::sax::XAttributeList> xAttrList;
         const uno::Sequence<OUString> aStyleNames = mxNumberStyles->getElementNames();
@@ -1633,7 +1633,8 @@ void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles )
             if (aAny >>= nKey)
             {
                 SvXMLStyleContext* pContext = new SvXMLNumFormatContext(
-                    *this, XML_NAMESPACE_NUMBER, name, xAttrList, nKey, *pAutoStyles);
+                    *this, XML_NAMESPACE_NUMBER, name, xAttrList, nKey,
+                    GetDataStylesImport()->GetLanguageForKey(nKey), *pAutoStyles);
                 pAutoStyles->AddStyle(*pContext);
             }
         }
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index c01992740f5e..6711d4471606 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -1480,7 +1480,7 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
 SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
                                     sal_uInt16 nPrfx, const OUString& rLName,
                                     const uno::Reference<xml::sax::XAttributeList>& xAttrList,
-                                    const sal_Int32 nTempKey,
+                                    const sal_Int32 nTempKey, LanguageType nLang,
                                     SvXMLStylesContext& rStyles ) :
     SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_DATA_STYLE ),
     pData( nullptr ),
@@ -1488,7 +1488,7 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
     aMyConditions(),
     nType( 0 ),
     nKey(nTempKey),
-    nFormatLang( LANGUAGE_SYSTEM ),
+    nFormatLang( nLang ),
     bAutoOrder( false ),
     bFromSystem( false ),
     bTruncate( true ),
@@ -2308,4 +2308,16 @@ const SvXMLTokenMap& SvXMLNumFmtHelper::GetStylesElemTokenMap()
     return pData->GetStylesElemTokenMap();
 }
 
+LanguageType SvXMLNumFmtHelper::GetLanguageForKey(sal_Int32 nKey)
+{
+    if (pData->GetNumberFormatter())
+    {
+        const SvNumberformat* pEntry = pData->GetNumberFormatter()->GetEntry(nKey);
+        if (pEntry)
+            return pEntry->GetLanguage();
+    }
+
+    return LANGUAGE_SYSTEM;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 46ba9313dbbcb796a37bb6c21e3ec1f42a1abda1
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sat Jun 13 14:31:19 2020 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 15 17:07:54 2020 +0100

    tdf#133953 use a popover to show interactive row/column resize into
    
    because a simple tooltip won't fire under gtk for that interaction
    
    Change-Id: I487b5c05805e3d0233da9a3b3c5ff1912d98baf6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96275
    Tested-by: Jenkins
    Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>

diff --git a/sc/source/ui/inc/hdrcont.hxx b/sc/source/ui/inc/hdrcont.hxx
index f3d7ee0b6638..3bb95e34562e 100644
--- a/sc/source/ui/inc/hdrcont.hxx
+++ b/sc/source/ui/inc/hdrcont.hxx
@@ -56,6 +56,7 @@ private:
     SCCOLROW        nDragNo;
     long            nDragStart;
     long            nDragPos;
+    void*           nTipVisible;
     bool            bDragMoved;
 
     bool            bIgnoreMove;
diff --git a/sc/source/ui/view/hdrcont.cxx b/sc/source/ui/view/hdrcont.cxx
index 601f982efd75..a8aeb47f9f88 100644
--- a/sc/source/ui/view/hdrcont.cxx
+++ b/sc/source/ui/view/hdrcont.cxx
@@ -57,6 +57,7 @@ ScHeaderControl::ScHeaderControl( vcl::Window* pParent, SelectionEngine* pSelect
             nDragNo     ( 0 ),
             nDragStart  ( 0 ),
             nDragPos    ( 0 ),
+            nTipVisible ( nullptr ),
             bDragMoved  ( false ),
             bIgnoreMove ( false ),
             bInRefMode  ( false ),
@@ -712,6 +713,11 @@ void ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt )
     {
         DrawInvert( nDragPos );
         ReleaseMouse();
+        if (nTipVisible)
+        {
+            Help::HidePopover(this, nTipVisible);
+            nTipVisible = nullptr;
+        }
         bDragging = false;
 
         long nScrPos    = GetScrPos( nDragNo );
@@ -879,6 +885,11 @@ void ScHeaderControl::StopMarking()
     if ( bDragging )
     {
         DrawInvert( nDragPos );
+        if (nTipVisible)
+        {
+            Help::HidePopover(this, nTipVisible);
+            nTipVisible = nullptr;
+        }
         bDragging = false;
     }
 
@@ -926,7 +937,9 @@ void ScHeaderControl::ShowDragHelp()
         aRect.SetRight( aRect.Left() );
         aRect.SetBottom( aRect.Top() );
 
-        Help::ShowQuickHelp(this, aRect, aHelpStr, nAlign);
+        if (nTipVisible)
+            Help::HidePopover(this, nTipVisible);
+        nTipVisible = Help::ShowPopover(this, aRect, aHelpStr, nAlign);
     }
 }
 
commit 6681c51754fea39424138b6f46b0bc281ca86909
Author:     David Tardon <dtardon at redhat.com>
AuthorDate: Fri Jun 12 16:41:07 2020 +0200
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 15 17:07:54 2020 +0100

    use dynamic_cast
    
    Change-Id: Iac420c2dd37be392ae817e0433de68c983546667
    (cherry picked from commit 06248bbaf21723f505d99c65906e5c6781c54c83)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96270
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/lotuswordpro/source/filter/lwpframelayout.cxx b/lotuswordpro/source/filter/lwpframelayout.cxx
index 3e6d9580f4e6..1d7fcc09e7df 100644
--- a/lotuswordpro/source/filter/lwpframelayout.cxx
+++ b/lotuswordpro/source/filter/lwpframelayout.cxx
@@ -1172,7 +1172,7 @@ void LwpDropcapLayout::XFConvert(XFContentContainer* pCont)
 
 void LwpDropcapLayout::RegisterStyle(LwpFoundry* pFoundry)
 {
-    LwpStory* pStory = static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
+    LwpStory* pStory = dynamic_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
     if (pStory)
     {
         pStory->SetDropcapFlag(true);
commit 15403f053fe985d3083f56f259ccb7f1f5643d97
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Dec 6 13:33:24 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 15 17:07:54 2020 +0100

    sw: reindent that
    
    Change-Id: Iea5784d98d2780166c88912f898f3da95d45e2ab
    Reviewed-on: https://gerrit.libreoffice.org/84623
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit 933dc9f99d6f8d608f67514d1236b5b2904f2b0a)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96203
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index a695cca98713..1b93a7a56a78 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -229,26 +229,26 @@ void DelFlyInRange( const SwNodeIndex& rMkNdIdx,
                     ? DelContentType::AllMask|DelContentType::WriterfilterHack
                     : DelContentType::AllMask|DelContentType::WriterfilterHack|DelContentType::CheckNoCntnt))))
         {
-                // If the Fly is deleted, all Flys in its content have to be deleted too.
-                const SwFormatContent &rContent = pFormat->GetContent();
-                // But only fly formats own their content, not draw formats.
-                if (rContent.GetContentIdx() && pFormat->Which() == RES_FLYFRMFMT)
-                {
-                    DelFlyInRange( *rContent.GetContentIdx(),
-                                    SwNodeIndex( *rContent.GetContentIdx()->
-                                            GetNode().EndOfSectionNode() ));
-                    // Position could have been moved!
-                    if( i > rTable.size() )
-                        i = rTable.size();
-                    else if( pFormat != rTable[i] )
-                        i = std::distance(rTable.begin(), rTable.find( pFormat ));
-                }
+            // If the Fly is deleted, all Flys in its content have to be deleted too.
+            const SwFormatContent &rContent = pFormat->GetContent();
+            // But only fly formats own their content, not draw formats.
+            if (rContent.GetContentIdx() && pFormat->Which() == RES_FLYFRMFMT)
+            {
+                DelFlyInRange( *rContent.GetContentIdx(),
+                                SwNodeIndex( *rContent.GetContentIdx()->
+                                        GetNode().EndOfSectionNode() ));
+                // Position could have been moved!
+                if (i > rTable.size())
+                    i = rTable.size();
+                else if (pFormat != rTable[i])
+                    i = std::distance(rTable.begin(), rTable.find( pFormat ));
+            }
 
-                pDoc->getIDocumentLayoutAccess().DelLayoutFormat( pFormat );
+            pDoc->getIDocumentLayoutAccess().DelLayoutFormat( pFormat );
 
-                // DelLayoutFormat can also trigger the deletion of objects.
-                if( i > rTable.size() )
-                    i = rTable.size();
+            // DelLayoutFormat can also trigger the deletion of objects.
+            if (i > rTable.size())
+                i = rTable.size();
         }
     }
 }
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index ae19a4d4c95a..de81e9e338d5 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -964,32 +964,31 @@ void SwUndoSaveContent::DelContentIndex( const SwPosition& rMark,
                         if (pAPos &&
                             pStt->nNode <= pAPos->nNode && pAPos->nNode <= pEnd->nNode)
                         {
-                                if( !m_pHistory )
-                                    m_pHistory.reset( new SwHistory );
+                            if (!m_pHistory)
+                                m_pHistory.reset( new SwHistory );
 
-                                if (IsSelectFrameAnchoredAtPara(*pAPos, *pStt, *pEnd, nDelContentType))
-                                {
-                                    m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
-                                    // reset n so that no Format is skipped
-                                    n = n >= rSpzArr.size()
-                                        ? rSpzArr.size() : n+1;
-                                }
-                                // Moving the anchor?
-                                else if (!((DelContentType::CheckNoCntnt|DelContentType::ExcludeFlyAtStartEnd)
-                                        & nDelContentType) &&
-                                    // at least for calls from SwUndoDelete,
-                                    // this should work - other Undos don't
-                                    // remember the order of the cursor
-                                    (rPoint.nNode.GetIndex() == pAPos->nNode.GetIndex())
-                                    // Do not try to move the anchor to a table!
-                                    && rMark.nNode.GetNode().IsTextNode())
-                                {
-                                    m_pHistory->AddChangeFlyAnchor(*pFormat);
-                                    SwFormatAnchor aAnch( *pAnchor );
-                                    SwPosition aPos( rMark.nNode );
-                                    aAnch.SetAnchor( &aPos );
-                                    pFormat->SetFormatAttr( aAnch );
-                                }
+                            if (IsSelectFrameAnchoredAtPara(*pAPos, *pStt, *pEnd, nDelContentType))
+                            {
+                                m_pHistory->AddDeleteFly(*pFormat, nChainInsPos);
+                                // reset n so that no Format is skipped
+                                n = n >= rSpzArr.size() ? rSpzArr.size() : n+1;
+                            }
+                            // Moving the anchor?
+                            else if (!((DelContentType::CheckNoCntnt|DelContentType::ExcludeFlyAtStartEnd)
+                                    & nDelContentType) &&
+                                // at least for calls from SwUndoDelete,
+                                // this should work - other Undos don't
+                                // remember the order of the cursor
+                                (rPoint.nNode.GetIndex() == pAPos->nNode.GetIndex())
+                                // Do not try to move the anchor to a table!
+                                && rMark.nNode.GetNode().IsTextNode())
+                            {
+                                m_pHistory->AddChangeFlyAnchor(*pFormat);
+                                SwFormatAnchor aAnch( *pAnchor );
+                                SwPosition aPos( rMark.nNode );
+                                aAnch.SetAnchor( &aPos );
+                                pFormat->SetFormatAttr( aAnch );
+                            }
                         }
                     }
                     break;
commit c2333e06d4677716cceea6ed30a27e81d4e0d05c
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Jun 11 14:12:28 2020 +0200
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 15 17:07:54 2020 +0100

    tdf#132321 sw: adapt fly at-para deletion to at-char wrt. sections
    
    971205dc2110c1c23ff1db1fc4041e2babf6fa9f changed at-char selection to
    check that not only the start is at the start of the section or the
    end is at the end of the section, but that both are true.
    
    Let's do this for at-para flys too for consistency, changing what was
    introduced with 91b2325808a75174f284c48c8b8afc118fad74e4.
    
    Change-Id: I1ec93b076d729288ce0809d1cfc24379aa9591ab
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96125
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit be2f539012d818eaa2d40a9cf199b53d32e1dee4)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96149
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index eb42e7dfbc0c..ae19a4d4c95a 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -1627,14 +1627,14 @@ bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos,
                 && ((rStart.nNode != rEnd.nNode && rStart.nContent == 0
                         // but not if the selection is backspace/delete!
                         && IsNotBackspaceHeuristic(rStart, rEnd))
-                    || IsAtStartOfSection(rStart))))
+                    || (IsAtStartOfSection(rAnchorPos) && IsAtEndOfSection2(rEnd)))))
         && ((rAnchorPos.nNode < rEnd.nNode)
             || (rAnchorPos.nNode == rEnd.nNode
                 && !(nDelContentType & DelContentType::ExcludeFlyAtStartEnd)
                 // special case: fully deleted node
                 && ((rEnd.nNode != rStart.nNode && rEnd.nContent == rEnd.nNode.GetNode().GetTextNode()->Len()
                         && IsNotBackspaceHeuristic(rStart, rEnd))
-                    || IsAtEndOfSection(rEnd))));
+                    || (IsAtEndOfSection(rAnchorPos) && IsAtStartOfSection2(rStart)))));
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit f13dec4fd169fac95f8caf8252f93440cefca5be
Author:     Vasily Melenchuk <vasily.melenchuk at cib.de>
AuthorDate: Fri May 29 14:25:04 2020 +0300
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 15 17:07:53 2020 +0100

    tdf#83309: docx import: allow for lists tabstop at zero position
    
    Zero position is valid value for tabstop, but previously it was
    treated as "no tab stop defined". Right now writer distinguishes
    tab stop at zero postion and no tab stop.
    
    Change-Id: Ie32da3d36a263644ba85a882029a8b29ae0501c8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95132
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit d2e428d1abb9f2907c0b87d55830e8742f8209b9)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95561
    (cherry picked from commit a380a06c1872091e8fa8c810e95a8e1d5dfe1820)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96178

diff --git a/sw/qa/extras/ooxmlexport/data/tdf83309.docx b/sw/qa/extras/ooxmlexport/data/tdf83309.docx
new file mode 100644
index 000000000000..8dfddb6ed201
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf83309.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 17ce04efd87b..6974577bd9bf 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -363,6 +363,20 @@ DECLARE_OOXMLIMPORT_TEST(testTdf125038c, "tdf125038c.docx")
     CPPUNIT_ASSERT_EQUAL(OUString("email: test at test.test"), aActual);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf83309, "tdf83309.docx")
+{
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    OUString sNodeType;
+
+    // First paragraph does not have tab before
+    sNodeType = parseDump("/root/page/body/txt[1]/Text[1]", "nType");
+    CPPUNIT_ASSERT_EQUAL(OUString("PortionType::Text"), sNodeType);
+
+    // Second paragraph starts with tab
+    sNodeType = parseDump("/root/page/body/txt[2]/Text[1]", "nType");
+    CPPUNIT_ASSERT_EQUAL(OUString("PortionType::TabLeft"), sNodeType);
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf121661, "tdf121661.docx")
 {
     xmlDocPtr pXmlSettings = parseExport("word/settings.xml");
diff --git a/sw/source/core/text/txttab.cxx b/sw/source/core/text/txttab.cxx
index c2fded221827..37b00c532bae 100644
--- a/sw/source/core/text/txttab.cxx
+++ b/sw/source/core/text/txttab.cxx
@@ -122,7 +122,7 @@ SwTabPortion *SwTextFormatter::NewTabPortion( SwTextFormatInfo &rInf, bool bAuto
 
         // #i24363# tab stops relative to indent
         // nSearchPos: The current position relative to the tabs origin
-        const SwTwips nSearchPos = bRTL ?
+        SwTwips nSearchPos = bRTL ?
                                    nTabLeft - nCurrentAbsPos :
                                    nCurrentAbsPos - nTabLeft;
 
@@ -130,6 +130,14 @@ SwTabPortion *SwTextFormatter::NewTabPortion( SwTextFormatInfo &rInf, bool bAuto
         // any hard set tab stops:
         // Note: If there are no user defined tab stops, there is always a
         // default tab stop.
+
+        // If search is started from zero position (beginning of line), than
+        // lets do it from -1: this will allow to include into account potential
+        // tab stop at zero position. Yes, it will be zero width tab useless
+        // mostly, but this have sense in case of lists.
+        if (nSearchPos == 0)
+            nSearchPos = -1;
+
         const SvxTabStop* pTabStop = m_aLineInf.GetTabStop( nSearchPos, nMyRight );
         if ( pTabStop )
         {
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 91085b203251..ba5b7a2dadaa 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6897,7 +6897,7 @@ void DocxAttributeOutput::NumberingLevel( sal_uInt8 nLevel,
 
     // indentation
     m_pSerializer->startElementNS(XML_w, XML_pPr);
-    if( nListTabPos != 0 )
+    if( nListTabPos >= 0 )
     {
         m_pSerializer->startElementNS(XML_w, XML_tabs);
         m_pSerializer->singleElementNS( XML_w, XML_tab,
diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx
index ec6df09838b5..b52bc5857fb9 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -592,7 +592,7 @@ void MSWordExportBase::NumberingLevel(
 
     sal_Int16 nIndentAt = 0;
     sal_Int16 nFirstLineIndex = 0;
-    sal_Int16 nListTabPos = 0;
+    sal_Int16 nListTabPos = -1;
 
     // #i86652#
     if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx
index 30846dc3c290..7cdc061c0a4b 100644
--- a/writerfilter/source/dmapper/NumberingManager.cxx
+++ b/writerfilter/source/dmapper/NumberingManager.cxx
@@ -229,8 +229,8 @@ uno::Sequence<beans::PropertyValue> ListLevel::GetLevelProperties(bool bDefaults
         aNumberingProperties.push_back(lcl_makePropVal(PROP_GRAPHIC_SIZE, m_aGraphicSize));
     }
 
-    if (bDefaults || m_nTabstop != 0)
-        aNumberingProperties.push_back(lcl_makePropVal(PROP_LISTTAB_STOP_POSITION, m_nTabstop));
+    if (m_nTabstop.has_value())
+        aNumberingProperties.push_back(lcl_makePropVal(PROP_LISTTAB_STOP_POSITION, *m_nTabstop));
 
     //TODO: handling of nFLegal?
     //TODO: nFNoRestart lower levels do not restart when higher levels are incremented, like:
diff --git a/writerfilter/source/dmapper/NumberingManager.hxx b/writerfilter/source/dmapper/NumberingManager.hxx
index 3d70257029f4..ff81ef20eec4 100644
--- a/writerfilter/source/dmapper/NumberingManager.hxx
+++ b/writerfilter/source/dmapper/NumberingManager.hxx
@@ -51,7 +51,7 @@ class ListLevel : public PropertyMap
     OUString                               m_sBulletChar;
     css::awt::Size                         m_aGraphicSize;
     css::uno::Reference<css::awt::XBitmap> m_xGraphicBitmap;
-    sal_Int32                                     m_nTabstop;
+    std::optional<sal_Int32>               m_nTabstop;
     tools::SvRef< StyleSheetEntry >          m_pParaStyle;
     bool                                          m_outline;
     bool m_bHasValues = false;
@@ -65,7 +65,6 @@ public:
         ,m_nStartOverride(-1)
         ,m_nNFC(-1)
         ,m_nXChFollow(SvxNumberFormat::LISTTAB)
-        ,m_nTabstop( 0 )
         ,m_outline(false)
         {}
 
commit 0e52418af46e5f056fe43688c731d6aeafb9b69c
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Jun 12 17:42:51 2020 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Jun 15 17:07:53 2020 +0100

    Add more debug to try to catch a slew of unhelpful messages.
    
    Change-Id: I905d54ade7fdce992b0ff6e81d51915b43acd2ed

diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index e3c15d63fa82..6ebbd00ea7bb 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -782,7 +782,8 @@ rName
         sal_uInt16 nPrefix =
             mpNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
         SAL_WARN_IF( xContext->GetPrefix() != nPrefix,  "xmloff.core", "SvXMLImport::endElement: popped context has wrong prefix" );
-        SAL_WARN_IF( xContext->GetLocalName() != aLocalName, "xmloff.core", "SvXMLImport::endElement: popped context has wrong lname" );
+        SAL_WARN_IF( xContext->GetLocalName() != aLocalName, "xmloff.core", "SvXMLImport::endElement: popped context has wrong lname '"
+                     << aLocalName << "' expected. '" << xContext->GetLocalName() << "' with impl " << getImplementationName() );
 #endif
 
         // Call a EndElement at the current context.


More information about the Libreoffice-commits mailing list