sw/qa/extras/uiwriter/data/pageBreakWithPageStyle.fodt |   17 ++++
 sw/qa/extras/uiwriter/uiwriter8.cxx                    |   32 +++++++++
 sw/source/core/doc/docfmt.cxx                          |   60 +++++++++--------
 3 files changed, 82 insertions(+), 27 deletions(-)

New commits:
commit 05bc773b0e88b408a997ffa5851cc9207d3303e5
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue May 30 16:10:03 2023 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Tue May 30 18:05:08 2023 +0200

    tdf#73483: make sure to not reset style names
    
    The problem was, that resetting direct formatting also used to reset
    RES_FRMATR_STYLE_NAME and RES_FRMATR_CONDITIONAL_STYLE_NAME. These
    are important at autostyles export: in XMLTextParagraphExport::Add,
    SwXAutoStyle is queried for ParaStyleName/ParaConditionalStyleName
    properties, and empty values of these were used to add the autostyle
    to pool. Looking for the autostyle while exporting the paragraph,
    SwXParagraph reports the correct "Standard" as the style name, but
    no matching children were found for the "Standard" parent style, and
    so the paragraph got "Standard" style name, instead of the autostyle.
    
    Change-Id: Iadf24ebd2b85e494267b73336a54b24f85ea0a0c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152393
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/qa/extras/uiwriter/data/pageBreakWithPageStyle.fodt 
b/sw/qa/extras/uiwriter/data/pageBreakWithPageStyle.fodt
new file mode 100644
index 000000000000..6cd520c7f674
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/pageBreakWithPageStyle.fodt
@@ -0,0 +1,17 @@
+<?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" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Standard" style:master-page-name="Right_20_Page"/>
+ </office:automatic-styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+  <style:master-page style:name="Right_20_Page" style:display-name="Right 
Page" style:page-layout-name="pm2" style:next-style-name="Left_20_Page"/>
+  <style:master-page style:name="Left_20_Page" style:display-name="Left Page" 
style:page-layout-name="pm3" style:next-style-name="Right_20_Page"/>
+ </office:master-styles>
+ <office:body>
+  <office:text>
+   <text:p text:style-name="P1"/>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx 
b/sw/qa/extras/uiwriter/uiwriter8.cxx
index 81a6d9e25fc2..610bdf9c8bf7 100644
--- a/sw/qa/extras/uiwriter/uiwriter8.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -2593,6 +2593,38 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, 
testCursorPositionAfterUndo)
     
CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf73483)
+{
+    // Given a document with a first paragraph having a manually set page 
break with page style
+    createSwDoc("pageBreakWithPageStyle.fodt");
+    SwDoc* pDoc = getSwDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+    CPPUNIT_ASSERT_EQUAL(OUString("Right Page"), pWrtShell->GetCurPageStyle());
+
+    dispatchCommand(mxComponent, ".uno:ResetAttributes", {}); // Ctrl+M "Clear 
Direct Formatting"
+    // Make sure that clearing direct formatting doesn't clear the page style
+    CPPUNIT_ASSERT_EQUAL(OUString("Right Page"), pWrtShell->GetCurPageStyle());
+
+    // Make sure that the page break with page style survives ODF 
save-and-reload
+    reload("writer8", "pageBreakWithPageStyle.odt");
+
+    xmlDocUniquePtr pXml = parseExport("content.xml");
+    CPPUNIT_ASSERT(pXml);
+    OUString para_style_name
+        = getXPath(pXml, 
"/office:document-content/office:body/office:text/text:p", "style-name");
+    // Without the fix in place, this would fail
+    CPPUNIT_ASSERT(!para_style_name.equalsIgnoreAsciiCase("Standard"));
+
+    OString para_style_path
+        = 
"/office:document-content/office:automatic-styles/style:style[@style:name='"
+          + para_style_name.toUtf8() + "']";
+    assertXPath(pXml, para_style_path, "family", "paragraph");
+    // Without the fix in place, the autostyle had no parent
+    assertXPath(pXml, para_style_path, "parent-style-name", "Standard");
+    assertXPath(pXml, para_style_path, "master-page-name", "Right_20_Page");
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index bc5994a58d37..8ed9c4c9d249 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -116,7 +116,8 @@ static bool lcl_RstAttr( SwNode* pNd, void* pArgs )
         SfxItemSetFixed<
                 RES_PARATR_NUMRULE, RES_PARATR_NUMRULE,
                 RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1,
-                RES_PAGEDESC, RES_BREAK>  aSavedAttrsSet(rDoc.GetAttrPool());
+                RES_PAGEDESC, RES_BREAK,
+                RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME> 
aSavedAttrsSet(rDoc.GetAttrPool());
         const SfxItemSet* pAttrSetOfNode = pNode->GetpSwAttrSet();
 
         std::vector<sal_uInt16> aClearWhichIds;
@@ -137,32 +138,35 @@ static bool lcl_RstAttr( SwNode* pNd, void* pArgs )
             }
         }
 
-        const SfxPoolItem* pItem;
-
-        sal_uInt16 const aSavIds[3] = { RES_PAGEDESC, RES_BREAK, 
RES_PARATR_NUMRULE };
-        for (sal_uInt16 aSavId : aSavIds)
+        if (auto pItem = pAttrSetOfNode->GetItemIfSet(RES_PARATR_NUMRULE, 
false);
+            pItem && !pItem->GetValue().isEmpty())
         {
-            if (SfxItemState::SET == pAttrSetOfNode->GetItemState(aSavId, 
false, &pItem))
-            {
-                bool bSave = false;
-                switch( aSavId )
-                {
-                    case RES_PAGEDESC:
-                        bSave = nullptr != 
pItem->StaticWhichCast(RES_PAGEDESC).GetPageDesc();
-                    break;
-                    case RES_BREAK:
-                        bSave = SvxBreak::NONE != 
pItem->StaticWhichCast(RES_BREAK).GetBreak();
-                    break;
-                    case RES_PARATR_NUMRULE:
-                        bSave = 
!pItem->StaticWhichCast(RES_PARATR_NUMRULE).GetValue().isEmpty();
-                    break;
-                }
-                if( bSave )
-                {
-                    aSavedAttrsSet.Put(*pItem);
-                    aClearWhichIds.push_back(aSavId);
-                }
-            }
+            aSavedAttrsSet.Put(*pItem);
+            aClearWhichIds.push_back(RES_PARATR_NUMRULE);
+        }
+        if (auto pItem = pAttrSetOfNode->GetItemIfSet(RES_PAGEDESC, false);
+            pItem && pItem->GetPageDesc())
+        {
+            aSavedAttrsSet.Put(*pItem);
+            aClearWhichIds.push_back(RES_PAGEDESC);
+        }
+        if (auto pItem = pAttrSetOfNode->GetItemIfSet(RES_BREAK, false);
+            pItem && pItem->GetBreak() != SvxBreak::NONE)
+        {
+            aSavedAttrsSet.Put(*pItem);
+            aClearWhichIds.push_back(RES_BREAK);
+        }
+        if (auto pItem = pAttrSetOfNode->GetItemIfSet(RES_FRMATR_STYLE_NAME, 
false);
+            pItem && !pItem->GetValue().isEmpty())
+        {
+            aSavedAttrsSet.Put(*pItem);
+            aClearWhichIds.push_back(RES_FRMATR_STYLE_NAME);
+        }
+        if (auto pItem = 
pAttrSetOfNode->GetItemIfSet(RES_FRMATR_CONDITIONAL_STYLE_NAME, false);
+            pItem && !pItem->GetValue().isEmpty())
+        {
+            aSavedAttrsSet.Put(*pItem);
+            aClearWhichIds.push_back(RES_FRMATR_CONDITIONAL_STYLE_NAME);
         }
 
         // do not clear items directly from item set and only clear to be kept
@@ -186,10 +190,12 @@ static bool lcl_RstAttr( SwNode* pNd, void* pArgs )
                 OSL_ENSURE( !bKeepAttributes,
                         "<lcl_RstAttr(..)> - certain attributes are kept, but 
not needed." );
                 SfxItemIter aIter( *pPara->pDelSet );
-                for (pItem = aIter.GetCurItem(); pItem; pItem = 
aIter.NextItem())
+                for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; 
pItem = aIter.NextItem())
                 {
                     if ( ( pItem->Which() != RES_PAGEDESC &&
                            pItem->Which() != RES_BREAK &&
+                           pItem->Which() != RES_FRMATR_STYLE_NAME &&
+                           pItem->Which() != RES_FRMATR_CONDITIONAL_STYLE_NAME 
&&
                            pItem->Which() != RES_PARATR_NUMRULE ) ||
                          ( aSavedAttrsSet.GetItemState( pItem->Which(), false 
) != SfxItemState::SET ) )
                     {

Reply via email to