sw/inc/IDocumentSettingAccess.hxx                  |    2 
 sw/qa/core/text/data/firstLineIndent-withFlag.fodt |   31 ++++++++
 sw/qa/core/text/text.cxx                           |   25 +++++++
 sw/source/core/doc/DocumentSettingManager.cxx      |    9 ++
 sw/source/core/inc/DocumentSettingManager.hxx      |    1 
 sw/source/core/text/itrcrsr.cxx                    |   73 +++++++++++----------
 sw/source/filter/xml/xmlimp.cxx                    |    6 +
 sw/source/uibase/uno/SwXDocumentSettings.cxx       |   18 +++++
 8 files changed, 130 insertions(+), 35 deletions(-)

New commits:
commit 86cffd61c1f01a18f4016bb09c8d63a581f5cded
Author:     Kevin Suo <suokunl...@126.com>
AuthorDate: Mon Nov 22 00:01:34 2021 +0800
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Jan 3 08:35:21 2022 +0100

    tdf#129448: Auto first-line indent should not be effected by line space
    
    Previously, if you set the first line indent to auto, then if you change
    the line height, the first line indent will also change. I do not see a
    reason to change the first line indent value in case of change in line
    spacing, even for English language.
    
    Some languages (e.g. Chinese) may have set the auto first line indent
    to be 2 characters of the current font, but if the first line indent
    changes when line height changes, then this 2-character rule is not 
possible.
    
    For compatibility with old documents, a compatability flag
    'AutoFirstLineIndentDisregardLineSpace' is added in this patch, thus this
    patch only has effect to new ODF documents. DOC/DOCX documents will also
    benefit from this patch, no matter old or new, because, as Miklos Vajna
    has pointed out, Word does not have the auto first line height feature.
    
    Change-Id: I1e2ddc33cce4ff9b3b2b4122445894f724d5bcd1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125627
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/inc/IDocumentSettingAccess.hxx 
b/sw/inc/IDocumentSettingAccess.hxx
index 11bef9d2729d..7de8674c4d0f 100644
--- a/sw/inc/IDocumentSettingAccess.hxx
+++ b/sw/inc/IDocumentSettingAccess.hxx
@@ -90,6 +90,8 @@ enum class DocumentSettingId
     // tdf#112443 disable off-page content positioning
     DISABLE_OFF_PAGE_POSITIONING,
     EMPTY_DB_FIELD_HIDES_PARA,
+    // tdf#129448: Auto first-line indent should not be effected by line space
+    AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE,
     // COMPATIBILITY FLAGS END
     BROWSE_MODE,
     HTML_MODE,
diff --git a/sw/qa/core/text/data/firstLineIndent-withFlag.fodt 
b/sw/qa/core/text/data/firstLineIndent-withFlag.fodt
new file mode 100644
index 000000000000..069b960b9d6f
--- /dev/null
+++ b/sw/qa/core/text/data/firstLineIndent-withFlag.fodt
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:settings>
+  <config:config-item-set config:name="ooo:configuration-settings">
+   <config:config-item config:name="AutoFirstLineIndentDisregardLineSpace" 
config:type="boolean">true</config:config-item>
+  </config:config-item-set>
+ </office:settings>
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Serif" 
svg:font-family="&apos;Liberation Serif&apos;" 
style:font-family-generic="roman" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="paragraph">
+   <style:text-properties style:font-name="Liberation Serif" 
fo:font-size="12pt" fo:language="en" fo:country="US" 
style:letter-kerning="true" fo:hyphenate="false"/>
+  </style:default-style>
+  <style:style style:name="Standard" style:family="paragraph" 
style:class="text"/>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" 
fo:margin-bottom="5.5mm" fo:line-height="100%" fo:text-indent="0cm" 
style:auto-text-indent="true"/>
+  </style:style>
+  <style:style style:name="P2" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" 
fo:line-height="200%" fo:text-indent="0cm" style:auto-text-indent="true"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:p text:style-name="P1">LibreOffice is a free and powerful office 
suite, and a successor to OpenOffice.org (commonly known as OpenOffice). Its 
clean interface and feature-rich tools help you unleash your creativity and 
enhance your productivity. LibreOffice is one of the friendliest and 
fastest-growing projects in the free and open source software world.</text:p>
+   <text:p text:style-name="P2">LibreOffice is a free and powerful office 
suite, and a successor to OpenOffice.org (commonly known as OpenOffice). Its 
clean interface and feature-rich tools help you unleash your creativity and 
enhance your productivity. LibreOffice is one of the friendliest and 
fastest-growing projects in the free and open source software world.</text:p>
+  </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index 6832ad2cb436..a7c6bc7838a6 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -176,6 +176,31 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testLineWidth)
     CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(65536), nNewLeft - nOldLeft);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testChineseAutoFirstLineIndent)
+{
+    // The test document contains two simple multi-line paragraph. For both 
paragraphs, the first line indent
+    // is set to 'auto'. Line spacing is 100% for the 1st paragraph and 200% 
for the 2nd paragraph.
+    // Also, there is a "AutoFirstLineIndentDisregardLineSpace" capability 
flag set in the document.
+    createSwDoc(DATA_DIRECTORY, "firstLineIndent-withFlag.fodt");
+
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+    // Get the line width of the first line for the 1st paragrapsh.
+    sal_Int32 nFirstLineWidth
+        = getXPath(pXmlDoc, 
"//body/txt[1]/SwParaPortion[1]/SwLineLayout[1]/SwLinePortion[1]",
+                   "width")
+              .toInt32();
+    // Get the line width of the first line for the 2nd paragrapsh.
+    sal_Int32 nSecondLineWidth
+        = getXPath(pXmlDoc, 
"//body/txt[2]/SwParaPortion[1]/SwLineLayout[1]/SwLinePortion[1]",
+                   "width")
+              .toInt32();
+
+    // Tdf#129448: the changing of line-height should not affect the auto 
first line indent.
+    // As a result, the first line width of the two paragraphs should be the 
same.
+    CPPUNIT_ASSERT_EQUAL(nSecondLineWidth, nFirstLineWidth);
+}
+
 CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testRuby)
 {
     // Given a document with multiple ruby portions:
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx 
b/sw/source/core/doc/DocumentSettingManager.cxx
index d47360022eee..3e03097fb41f 100644
--- a/sw/source/core/doc/DocumentSettingManager.cxx
+++ b/sw/source/core/doc/DocumentSettingManager.cxx
@@ -104,7 +104,8 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc 
&rDoc)
     mbFrameAutowidthWithMorePara(false),
     mbGutterAtTop(false),
     mbFootnoteInColumnToPageEnd(false),
-    mnImagePreferredDPI(0)
+    mnImagePreferredDPI(0),
+    mbAutoFirstLineIndentDisregardLineSpace(true)
 
     // COMPATIBILITY FLAGS END
 {
@@ -241,6 +242,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ 
DocumentSettingId id) const
         case DocumentSettingId::GUTTER_AT_TOP:
             return mbGutterAtTop;
         case DocumentSettingId::FOOTNOTE_IN_COLUMN_TO_PAGEEND: return 
mbFootnoteInColumnToPageEnd;
+        case DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE:
+            return mbAutoFirstLineIndentDisregardLineSpace;
         default:
             OSL_FAIL("Invalid setting id");
     }
@@ -415,6 +418,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ 
DocumentSettingId id, /*[in]*/ boo
             mbSubtractFlys = value;
             break;
 
+        case DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE:
+            mbAutoFirstLineIndentDisregardLineSpace = value;
+            break;
+
         // COMPATIBILITY FLAGS END
 
         case DocumentSettingId::BROWSE_MODE: //can be used temporary 
(load/save) when no SwViewShell is available
diff --git a/sw/source/core/inc/DocumentSettingManager.hxx 
b/sw/source/core/inc/DocumentSettingManager.hxx
index 8109e3f5a916..c687eb5939a5 100644
--- a/sw/source/core/inc/DocumentSettingManager.hxx
+++ b/sw/source/core/inc/DocumentSettingManager.hxx
@@ -173,6 +173,7 @@ class DocumentSettingManager final :
     bool mbGutterAtTop;
     bool mbFootnoteInColumnToPageEnd;
     sal_Int32 mnImagePreferredDPI;
+    bool mbAutoFirstLineIndentDisregardLineSpace;
 
 public:
 
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index cd915f14ea50..841aff1f395a 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -250,49 +250,54 @@ void SwTextMargin::CtorInitTextMargin( SwTextFrame 
*pNewFrame, SwTextSizeInfo *p
             if (aLang != LANGUAGE_KOREAN && aLang != LANGUAGE_JAPANESE)
                 nFirstLineOfs<<=1;
 
-            const SvxLineSpacingItem *pSpace = m_aLineInf.GetLineSpacing();
-            if( pSpace )
+            // tdf#129448: Auto first-line indent should not be effected by 
line space.
+            // Below is for compatibility with old documents.
+            if 
(!pNode->getIDocumentSettingAccess()->get(DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE))
             {
-                switch( pSpace->GetLineSpaceRule() )
+                const SvxLineSpacingItem *pSpace = m_aLineInf.GetLineSpacing();
+                if( pSpace )
                 {
-                    case SvxLineSpaceRule::Auto:
-                    break;
-                    case SvxLineSpaceRule::Min:
+                    switch( pSpace->GetLineSpaceRule() )
                     {
-                        if( nFirstLineOfs < pSpace->GetLineHeight() )
-                            nFirstLineOfs = pSpace->GetLineHeight();
+                        case SvxLineSpaceRule::Auto:
                         break;
-                    }
-                    case SvxLineSpaceRule::Fix:
-                        nFirstLineOfs = pSpace->GetLineHeight();
-                    break;
-                    default: OSL_FAIL( ": unknown LineSpaceRule" );
-                }
-                switch( pSpace->GetInterLineSpaceRule() )
-                {
-                    case SvxInterLineSpaceRule::Off:
-                    break;
-                    case SvxInterLineSpaceRule::Prop:
-                    {
-                        tools::Long nTmp = pSpace->GetPropLineSpace();
-                        // 50% is the minimum, at 0% we switch to
-                        // the default value 100%...
-                        if( nTmp < 50 )
-                            nTmp = nTmp ? 50 : 100;
-
-                        nTmp *= nFirstLineOfs;
-                        nTmp /= 100;
-                        if( !nTmp )
-                            ++nTmp;
-                        nFirstLineOfs = nTmp;
+                        case SvxLineSpaceRule::Min:
+                        {
+                            if( nFirstLineOfs < pSpace->GetLineHeight() )
+                                nFirstLineOfs = pSpace->GetLineHeight();
+                            break;
+                        }
+                        case SvxLineSpaceRule::Fix:
+                            nFirstLineOfs = pSpace->GetLineHeight();
                         break;
+                        default: OSL_FAIL( ": unknown LineSpaceRule" );
                     }
-                    case SvxInterLineSpaceRule::Fix:
+                    switch( pSpace->GetInterLineSpaceRule() )
                     {
-                        nFirstLineOfs += pSpace->GetInterLineSpace();
+                        case SvxInterLineSpaceRule::Off:
                         break;
+                        case SvxInterLineSpaceRule::Prop:
+                        {
+                            tools::Long nTmp = pSpace->GetPropLineSpace();
+                            // 50% is the minimum, at 0% we switch to
+                            // the default value 100%...
+                            if( nTmp < 50 )
+                                nTmp = nTmp ? 50 : 100;
+
+                            nTmp *= nFirstLineOfs;
+                            nTmp /= 100;
+                            if( !nTmp )
+                                ++nTmp;
+                            nFirstLineOfs = nTmp;
+                            break;
+                        }
+                        case SvxInterLineSpaceRule::Fix:
+                        {
+                            nFirstLineOfs += pSpace->GetInterLineSpace();
+                            break;
+                        }
+                        default: OSL_FAIL( ": unknown InterLineSpaceRule" );
                     }
-                    default: OSL_FAIL( ": unknown InterLineSpaceRule" );
                 }
             }
         }
diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx
index 36932bb9622f..6afabdd855e3 100644
--- a/sw/source/filter/xml/xmlimp.cxx
+++ b/sw/source/filter/xml/xmlimp.cxx
@@ -1302,6 +1302,7 @@ void SwXMLImport::SetConfigurationSettings(const Sequence 
< PropertyValue > & aC
     bool bSubtractFlysAnchoredAtFlys = false;
     bool bEmptyDbFieldHidesPara = false;
     bool bCollapseEmptyCellPara = false;
+    bool bAutoFirstLineIndentDisregardLineSpace = false;
 
     const PropertyValue* currentDatabaseDataSource = nullptr;
     const PropertyValue* currentDatabaseCommand = nullptr;
@@ -1393,6 +1394,8 @@ void SwXMLImport::SetConfigurationSettings(const Sequence 
< PropertyValue > & aC
                     bEmptyDbFieldHidesPara = true;
                 else if (rValue.Name == "CollapseEmptyCellPara")
                     bCollapseEmptyCellPara = true;
+                else if (rValue.Name == 
"AutoFirstLineIndentDisregardLineSpace")
+                    bAutoFirstLineIndentDisregardLineSpace = true;
             }
             catch( Exception& )
             {
@@ -1552,6 +1555,9 @@ void SwXMLImport::SetConfigurationSettings(const Sequence 
< PropertyValue > & aC
     if (!bCollapseEmptyCellPara)
         xProps->setPropertyValue("CollapseEmptyCellPara", makeAny(false));
 
+    if (!bAutoFirstLineIndentDisregardLineSpace)
+        xProps->setPropertyValue("AutoFirstLineIndentDisregardLineSpace", 
makeAny(false));
+
     SwDoc *pDoc = getDoc();
     SfxPrinter *pPrinter = pDoc->getIDocumentDeviceAccess().getPrinter( false 
);
     if( pPrinter )
diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx 
b/sw/source/uibase/uno/SwXDocumentSettings.cxx
index bc6051bd576c..4cfda7bbf3e4 100644
--- a/sw/source/uibase/uno/SwXDocumentSettings.cxx
+++ b/sw/source/uibase/uno/SwXDocumentSettings.cxx
@@ -151,6 +151,7 @@ enum SwDocumentSettingsPropertyHandles
     HANDLE_GUTTER_AT_TOP,
     HANDLE_FOOTNOTE_IN_COLUMN_TO_PAGEEND,
     HANDLE_IMAGE_PREFERRED_DPI,
+    HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE,
 };
 
 }
@@ -248,6 +249,7 @@ static rtl::Reference<MasterPropertySetInfo> 
lcl_createSettingsInfo()
         { OUString("GutterAtTop"), HANDLE_GUTTER_AT_TOP, 
cppu::UnoType<bool>::get(), 0 },
         { OUString("FootnoteInColumnToPageEnd"), 
HANDLE_FOOTNOTE_IN_COLUMN_TO_PAGEEND, cppu::UnoType<bool>::get(), 0 },
         { OUString("ImagePreferredDPI"), HANDLE_IMAGE_PREFERRED_DPI, 
cppu::UnoType<sal_Int32>::get(), 0 },
+        { OUString("AutoFirstLineIndentDisregardLineSpace"), 
HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE, cppu::UnoType<bool>::get(), 
0 },
 
 /*
  * As OS said, we don't have a view when we need to set this, so I have to
@@ -1039,6 +1041,16 @@ void SwXDocumentSettings::_setSingleValue( const 
comphelper::PropertyInfo & rInf
             }
         }
         break;
+        case HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE:
+        {
+            bool bTmp;
+            if (rValue >>= bTmp)
+            {
+                mpDoc->getIDocumentSettingAccess().set(
+                    
DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE, bTmp);
+            }
+        }
+        break;
         default:
             throw UnknownPropertyException(OUString::number(rInfo.mnHandle));
     }
@@ -1556,6 +1568,12 @@ void SwXDocumentSettings::_getSingleValue( const 
comphelper::PropertyInfo & rInf
             rValue <<= 
mpDoc->getIDocumentSettingAccess().getImagePreferredDPI();
         }
         break;
+        case HANDLE_AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE:
+        {
+            rValue <<= mpDoc->getIDocumentSettingAccess().get(
+                
DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE);
+        }
+        break;
         default:
             throw UnknownPropertyException(OUString::number(rInfo.mnHandle));
     }

Reply via email to