editeng/source/items/paraitem.cxx                     |   25 +++++++++++++++++-
 include/editeng/editrids.hrc                          |    2 +
 include/editeng/hyphenzoneitem.hxx                    |    4 ++
 include/editeng/memberids.h                           |    1 
 include/unotools/linguprops.hxx                       |    2 +
 offapi/com/sun/star/style/ParagraphProperties.idl     |   12 ++++++++
 svx/sdi/svxitems.sdi                                  |    1 
 sw/inc/inspectorproperties.hrc                        |    1 
 sw/inc/unoprnms.hxx                                   |    1 
 sw/qa/extras/ooxmlexport/data/tdf165354.docx          |binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx            |   19 +++++++++----
 sw/qa/uitest/styleInspector/styleInspector.py         |   20 +++++++-------
 sw/qa/uitest/styleInspector/tdf137513.py              |    2 -
 sw/source/core/inc/txtfrm.hxx                         |    3 ++
 sw/source/core/text/guess.cxx                         |    6 +++-
 sw/source/core/text/inftxt.cxx                        |   17 ++++++++----
 sw/source/core/text/txtfrm.cxx                        |    1 
 sw/source/core/text/widorp.cxx                        |   25 ++++++++++++++++--
 sw/source/core/unocore/unomapproperties.hxx           |    2 +
 sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx |    1 
 sw/source/writerfilter/dmapper/PropertyIds.cxx        |    1 
 sw/source/writerfilter/dmapper/PropertyIds.hxx        |    1 
 sw/source/writerfilter/dmapper/SettingsTable.cxx      |   16 +++++++++--
 sw/source/writerfilter/dmapper/SettingsTable.hxx      |    1 
 24 files changed, 135 insertions(+), 29 deletions(-)

New commits:
commit 3e02ffb76c484a05cdc140d8a10bc3d993fe8320
Author:     László Németh <[email protected]>
AuthorDate: Mon Feb 17 19:20:04 2025 +0100
Commit:     László Németh <[email protected]>
CommitDate: Fri Feb 21 08:52:21 2025 +0100

    tdf#i165354 sw offapi DOCX: implement HyphenationKeepLine – part 1
    
    ODF 1.0 feature hyphenation-keep, i.e. disabling hyphenation across
    page etc. was implemented by shifting the full hyphenated line
    (fixing also the DOCX layout interoperability, when value of the
    useWord2013TrackBottomHyphenation MSO DOCX compatibility option is
    true). To shift only the last word, add UNO paragraph property
    
    com::sun::star::text::ParagraphHyphenationKeepLine
    
    and the associated layout in Writer core, i.e. disabling
    the hyphenation in the last line, instead of line shifting,
    if the value of ParagraphHyphenationKeepLine is true.
    
    Fix missing DOCX layout interoperability by mapping the unhandled
    useWord2013TrackBottomHyphenation = false case to the new layout.
    
    Note: shifting lines may be better for languages with long
    words, but only with 1) typesetting with line-level (greedy)
    line breaking instead of the desirable paragraph-level, 2) and
    with missing optimized hyphenation at boundaries of compound word
    constituents, and 3) forgotting the following: Shifting only words
    or word constituents are better for 1) equal line count on pages
    and spreads (very basic typographical requirement), 2) disabling
    hyphenation really (shifting doesn't guarantee this, because
    shifting is limited in a single line, but the previous line can be
    hyphenated, too) and 3) more compact typesetting.
    Both hyphenation-keep algorithms are important for interoperability,
    but the new HyphenationKeepLine can create state-of-the-art automatic
    typesetting with the planned improvements.
    
    Follow-up to commit 9574a62add8e4901405e12117e75c86c2d2c2f21
    "tdf#132599 cui offapi sw xmloff: implement hyphenate-keep".
    and commit c8ee0e8f581b8a6e41b1a6b8aa4d40b442c1d463
    "tdf160518 DOCX: import hyphenation-keep to fix layout".
    
    Change-Id: Iafa352ec91bbd5d1d227b8480337fa2b9acb5993
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181954
    Reviewed-by: László Németh <[email protected]>
    Tested-by: Jenkins

diff --git a/editeng/source/items/paraitem.cxx 
b/editeng/source/items/paraitem.cxx
index d06255ea3e89..91c30e5b55e1 100644
--- a/editeng/source/items/paraitem.cxx
+++ b/editeng/source/items/paraitem.cxx
@@ -594,6 +594,7 @@ SvxHyphenZoneItem::SvxHyphenZoneItem( const bool bHyph, 
const sal_uInt16 nId ) :
     nMinWordLength(0),
     nTextHyphenZone(0),
     nKeepType(css::text::ParagraphHyphenationKeepType::COLUMN),
+    bKeepLine(false),
     nCompoundMinLead(0)
 {
 }
@@ -634,6 +635,9 @@ bool    SvxHyphenZoneItem::QueryValue( uno::Any& rVal, 
sal_uInt8 nMemberId ) con
         case MID_HYPHEN_KEEP_TYPE:
             rVal <<= static_cast<sal_Int16>(nKeepType);
         break;
+        case MID_HYPHEN_KEEP_LINE:
+            rVal <<= bKeepLine;
+        break;
         case MID_HYPHEN_COMPOUND_MIN_LEAD:
             rVal <<= static_cast<sal_Int16>(nCompoundMinLead);
         break;
@@ -647,7 +651,8 @@ bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, 
sal_uInt8 nMemberId )
     sal_Int32 nNewVal = 0; // sal_Int32 needs for MID_HYPHEN_KEEP_TYPE
 
     if( nMemberId != MID_IS_HYPHEN && nMemberId != MID_HYPHEN_NO_CAPS &&
-                nMemberId != MID_HYPHEN_NO_LAST_WORD && nMemberId != 
MID_HYPHEN_KEEP )
+                nMemberId != MID_HYPHEN_NO_LAST_WORD && nMemberId != 
MID_HYPHEN_KEEP &&
+                nMemberId != MID_HYPHEN_KEEP_LINE )
     {
         if(!(rVal >>= nNewVal))
             return false;
@@ -685,6 +690,9 @@ bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, 
sal_uInt8 nMemberId )
         case MID_HYPHEN_KEEP_TYPE:
             nKeepType = static_cast<sal_uInt8>(nNewVal);
         break;
+        case  MID_HYPHEN_KEEP_LINE:
+            bKeepLine = Any2Bool(rVal);
+        break;
         case MID_HYPHEN_COMPOUND_MIN_LEAD:
             nCompoundMinLead = static_cast<sal_uInt8>(nNewVal);
         break;
@@ -708,6 +716,7 @@ bool SvxHyphenZoneItem::operator==( const SfxPoolItem& 
rAttr ) const
             && rItem.nMaxHyphens == nMaxHyphens
             && rItem.nMinWordLength == nMinWordLength
             && rItem.nTextHyphenZone == nTextHyphenZone
+            && rItem.bKeepLine == bKeepLine
             && rItem.nKeepType == nKeepType );
 }
 
@@ -748,10 +757,18 @@ bool SvxHyphenZoneItem::GetPresentation
                 rText += cpDelimTmp + 
EditResId(RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE);
 
             if ( bKeep )
+            {
                 rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_TRUE) +
                                  cpDelimTmp + OUString::number( nKeepType );
+                if ( bKeepLine )
+                    rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_LINE_TRUE);
+                else
+                    rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_LINE_FALSE);
+            }
             else
                 rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_FALSE);
+
+
             return true;
         }
         case SfxItemPresentation::Complete:
@@ -788,6 +805,7 @@ bool SvxHyphenZoneItem::GetPresentation
             if ( bKeep )
             {
                 rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_TRUE) + cpDelimTmp;
+
                 switch ( nKeepType )
                 {
                     case 0:
@@ -806,6 +824,11 @@ bool SvxHyphenZoneItem::GetPresentation
                         rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_ALWAYS);
                         break;
                 }
+
+                if ( bKeepLine )
+                    rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_LINE_TRUE);
+                else
+                    rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_LINE_FALSE);
             }
             else
                 rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_FALSE);
diff --git a/include/editeng/editrids.hrc b/include/editeng/editrids.hrc
index 270b02707758..4cdc87bcf856 100644
--- a/include/editeng/editrids.hrc
+++ b/include/editeng/editrids.hrc
@@ -201,6 +201,8 @@
 #define RID_SVXITEMS_HYPHEN_FALSE               
NC_("RID_SVXITEMS_HYPHEN_FALSE", "No hyphenation")
 #define RID_SVXITEMS_HYPHEN_KEEP_TRUE           
NC_("RID_SVXITEMS_HYPHEN_KEEP_TRUE", "No hyphenation across")
 #define RID_SVXITEMS_HYPHEN_KEEP_FALSE          
NC_("RID_SVXITEMS_HYPHEN_KEEP_FALSE", "Hyphenation across page")
+#define RID_SVXITEMS_HYPHEN_KEEP_LINE_TRUE      
NC_("RID_SVXITEMS_HYPHEN_KEEP_LINE_TRUE", "by shifting the last hyphenated 
word")
+#define RID_SVXITEMS_HYPHEN_KEEP_LINE_FALSE     
NC_("RID_SVXITEMS_HYPHEN_KEEP_LINE_FALSE", "by shifting the last hyphenated 
line")
 #define RID_SVXITEMS_SIZE_WIDTH                 NC_("RID_SVXITEMS_SIZE_WIDTH", 
"Width: ")
 #define RID_SVXITEMS_SIZE_HEIGHT                
NC_("RID_SVXITEMS_SIZE_HEIGHT", "Height: ")
 #define RID_SVXITEMS_LRSPACE_LEFT               
NC_("RID_SVXITEMS_LRSPACE_LEFT", "Indent left ")
diff --git a/include/editeng/hyphenzoneitem.hxx 
b/include/editeng/hyphenzoneitem.hxx
index 5e68ca9281ae..05d3c9145ab8 100644
--- a/include/editeng/hyphenzoneitem.hxx
+++ b/include/editeng/hyphenzoneitem.hxx
@@ -42,6 +42,7 @@ class EDITENG_DLLPUBLIC SvxHyphenZoneItem final : public 
SfxPoolItem
     sal_uInt8 nMinWordLength;   // hyphenate only words with at least 
nMinWordLength characters
     sal_uInt16 nTextHyphenZone; // don't force hyphenation at line end, allow 
this extra white space
     sal_uInt8 nKeepType;        // avoid hyphenation across page etc., see 
ParagraphHyphenationKeep
+    bool      bKeepLine : 1;    // if bKeep, shift the hyphenated word (true), 
or the full line
     sal_uInt8 nCompoundMinLead; // min. characters between compound word 
boundary and hyphenation
 
 public:
@@ -94,6 +95,9 @@ public:
 
     sal_uInt8 &GetKeepType() { return nKeepType; }
     sal_uInt8 GetKeepType() const { return nKeepType; }
+
+    void SetKeepLine( const bool bNew ) { bKeepLine = bNew; }
+    bool IsKeepLine() const { return bKeepLine; }
 };
 
 #endif
diff --git a/include/editeng/memberids.h b/include/editeng/memberids.h
index 82a1fe65e9bf..f07d051c4825 100644
--- a/include/editeng/memberids.h
+++ b/include/editeng/memberids.h
@@ -54,6 +54,7 @@
 #define MID_HYPHEN_KEEP         8
 #define MID_HYPHEN_KEEP_TYPE    9
 #define MID_HYPHEN_COMPOUND_MIN_LEAD 10
+#define MID_HYPHEN_KEEP_LINE    11
 
 // SvxBoxInfoItem
 #define MID_HORIZONTAL          1
diff --git a/include/unotools/linguprops.hxx b/include/unotools/linguprops.hxx
index 92767f657620..0451a0d94a27 100644
--- a/include/unotools/linguprops.hxx
+++ b/include/unotools/linguprops.hxx
@@ -44,6 +44,7 @@ inline constexpr OUString UPN_HYPH_NO_LAST_WORD               
= u"HyphNoLastWord
 inline constexpr OUString UPN_HYPH_ZONE                       = 
u"HyphZone"_ustr;
 inline constexpr OUString UPN_HYPH_KEEP                       = 
u"HyphKeep"_ustr;
 inline constexpr OUString UPN_HYPH_KEEP_TYPE                  = 
u"HyphKeepType"_ustr;
+inline constexpr OUString UPN_HYPH_KEEP_LINE                  = 
u"HyphKeepLine"_ustr;
 
 // UNO property names for Lingu
 // (those not covered by the SpellChecker and Hyphenator
@@ -113,6 +114,7 @@ inline constexpr OUString UPN_IS_GRAMMAR_INTERACTIVE        
  = u"IsInteractiveG
 #define UPH_HYPH_KEEP                       34
 #define UPH_HYPH_KEEP_TYPE                  35
 #define UPH_HYPH_COMPOUND_MIN_LEADING       36
+#define UPH_HYPH_KEEP_LINE                  37
 
 #ifdef __GNUC__
 #pragma GCC diagnostic pop
diff --git a/offapi/com/sun/star/style/ParagraphProperties.idl 
b/offapi/com/sun/star/style/ParagraphProperties.idl
index 9cb2ff598562..5b1097feae04 100644
--- a/offapi/com/sun/star/style/ParagraphProperties.idl
+++ b/offapi/com/sun/star/style/ParagraphProperties.idl
@@ -454,6 +454,18 @@ published service ParagraphProperties
             @since LibreOffice 24.8
          */
         [optional, property] short ParaHyphenationCompoundMinLeadingChars;
+
+        /** This value is `TRUE` if ParaHyphenationKeep = TRUE solved by
+            shifting the hyphenated word, and FALSE, if it is solved by 
shifting
+            (only a single) full hyphenated line.
+
+            @see ParaHyphenationKeep
+
+            @see ParaHyphenationKeepType
+
+            @since LibreOffice 25.8
+         */
+        [optional, property] boolean ParaHyphenationKeepLine;
 };
 
 
diff --git a/svx/sdi/svxitems.sdi b/svx/sdi/svxitems.sdi
index 0f3da887b64c..0415b6955dd9 100644
--- a/svx/sdi/svxitems.sdi
+++ b/svx/sdi/svxitems.sdi
@@ -277,6 +277,7 @@ struct SvxHyphenZone
     INT16       HyphenZone    MID_HYPHEN_ZONE;
     BOOL        HyphenKeep    MID_HYPHEN_KEEP;
     INT16       HyphenKeepType MID_HYPHEN_KEEP_TYPE;
+    BOOL        HyphenKeepLine MID_HYPHEN_KEEP_LINE;
     INT16       MinLead       MID_HYPHEN_COMPOUND_MIN_LEAD;
 };
 item SvxHyphenZone SvxHyphenZoneItem;
diff --git a/sw/inc/inspectorproperties.hrc b/sw/inc/inspectorproperties.hrc
index 88f535847970..3404018a8c19 100644
--- a/sw/inc/inspectorproperties.hrc
+++ b/sw/inc/inspectorproperties.hrc
@@ -212,6 +212,7 @@
 #define RID_PARA_HYPHENATION_ZONE                           
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Zone")
 #define RID_PARA_HYPHENATION_KEEP                           
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Keep")
 #define RID_PARA_HYPHENATION_KEEP_TYPE                      
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Keep Type")
+#define RID_PARA_HYPHENATION_KEEP_LINE                      
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Keep Line")
 #define RID_PARA_INTEROP_GRAB_BAG                           
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Interop Grab Bag")
 #define RID_PARA_IS_AUTO_FIRST_LINE_INDENT                  
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para is Auto First Line Indent")
 #define RID_PARA_IS_CHARACTER_DISTANCE                      
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para is Character Distance")
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index b262018c41f6..8408c0f13fd7 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -83,6 +83,7 @@ inline constexpr OUString 
UNO_NAME_PARA_HYPHENATION_NO_LAST_WORD
     = u"ParaHyphenationNoLastWord"_ustr;
 inline constexpr OUString UNO_NAME_PARA_HYPHENATION_KEEP = 
u"ParaHyphenationKeep"_ustr;
 inline constexpr OUString UNO_NAME_PARA_HYPHENATION_KEEP_TYPE = 
u"ParaHyphenationKeepType"_ustr;
+inline constexpr OUString UNO_NAME_PARA_HYPHENATION_KEEP_LINE = 
u"ParaHyphenationKeepLine"_ustr;
 inline constexpr OUString UNO_NAME_LEFT_MARGIN = u"LeftMargin"_ustr;
 inline constexpr OUString UNO_NAME_RIGHT_MARGIN = u"RightMargin"_ustr;
 inline constexpr OUString UNO_NAME_GUTTER_MARGIN = u"GutterMargin"_ustr;
diff --git a/sw/qa/extras/ooxmlexport/data/tdf165354.docx 
b/sw/qa/extras/ooxmlexport/data/tdf165354.docx
new file mode 100644
index 000000000000..3a90488e7f3b
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf165354.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index cc6cce590287..9f036b03c4d7 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -1496,13 +1496,20 @@ CPPUNIT_TEST_FIXTURE(Test, 
testTdf160518_page_in_text_body_style)
     assertXPath(pXmlDoc, 
"/w:settings/w:compat/w:compatSetting[@w:name='allowHyphenationAtTrackBottom']",
 0);
 }
 
-CPPUNIT_TEST_FIXTURE(Test, testTdf160518_auto_in_text_body_style)
+CPPUNIT_TEST_FIXTURE(Test, testTdf165354)
 {
-    // text body  style contains hyphenation settings
-    loadAndReload("tdf160518_auto_in_text_body_style.fodt");
-    xmlDocUniquePtr pXmlDoc = parseExport(u"word/settings.xml"_ustr);
-    assertXPath(pXmlDoc, 
"/w:settings/w:compat/w:compatSetting[@w:name='useWord2013TrackBottomHyphenation']",
 "val", u"1");
-    assertXPath(pXmlDoc, 
"/w:settings/w:compat/w:compatSetting[@w:name='allowHyphenationAtTrackBottom']",
 "val", u"1");
+    uno::Reference<linguistic2::XHyphenator> xHyphenator = 
LinguMgr::GetHyphenator();
+    if (!xHyphenator->hasLocale(lang::Locale(u"en"_ustr, u"US"_ustr, 
OUString())))
+        return;
+
+    loadAndReload("tdf165354.docx");
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    // This was "except that it has an at" (hyphenation at the end of the page)
+    assertXPath(pXmlDoc, 
"//page[1]/body/txt[2]/SwParaPortion/SwLineLayout[9]", "portion", u"except that 
it has an ");
+    // This started with "mosphere" (hyphenation at the end of the previous 
page)
+    assertXPath(pXmlDoc, 
"//page[2]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion", u"atmosphere. 
The Earth ");
+    // The same word is still hyphenated in the same paragraph, but not at the 
bottom of the page
+    assertXPath(pXmlDoc, 
"//page[2]/body/txt[1]/SwParaPortion/SwLineLayout[9]", "portion", u"except that 
it has an at");
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testHyphenationAuto)
diff --git a/sw/qa/uitest/styleInspector/styleInspector.py 
b/sw/qa/uitest/styleInspector/styleInspector.py
index e4fe8e0259c7..2dc13d93cc48 100644
--- a/sw/qa/uitest/styleInspector/styleInspector.py
+++ b/sw/qa/uitest/styleInspector/styleInspector.py
@@ -26,7 +26,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text without formatting and default style
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(143, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(144, 
len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -36,7 +36,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text with direct formatting
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(143, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(144, 
len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
 
@@ -54,7 +54,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text with paragraph direct formatting
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(143, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(144, 
len(xListBox.getChild('0').getChild('0').getChildren()))
 
             xParDirFormatting = xListBox.getChild('1')
             self.assertEqual(7, len(xParDirFormatting.getChildren()))
@@ -75,7 +75,7 @@ class styleNavigator(UITestCase):
             xParStyle = xListBox.getChild('0')
             self.assertEqual(3, len(xParStyle.getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xParStyle.getChild('0'))['Text'])
-            self.assertEqual(143, len(xParStyle.getChild('0').getChildren()))
+            self.assertEqual(144, len(xParStyle.getChild('0').getChildren()))
             self.assertEqual("Heading  ", 
get_state_as_dict(xParStyle.getChild('1'))['Text'])
             self.assertEqual(28, len(xParStyle.getChild('1').getChildren()))
 
@@ -109,7 +109,7 @@ class styleNavigator(UITestCase):
             xParStyle = xListBox.getChild('0')
             self.assertEqual(3, len(xParStyle.getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xParStyle.getChild('0'))['Text'])
-            self.assertEqual(143, len(xParStyle.getChild('0').getChildren()))
+            self.assertEqual(144, len(xParStyle.getChild('0').getChildren()))
             self.assertEqual("Body Text        ", 
get_state_as_dict(xParStyle.getChild('1'))['Text'])
             self.assertEqual(6, len(xParStyle.getChild('1').getChildren()))
 
@@ -144,7 +144,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text without metadata
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(143, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(144, 
len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -154,7 +154,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text with paragraph metadata showed under 
direct paragraph formatting
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(143, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(144, 
len(xListBox.getChild('0').getChild('0').getChildren()))
 
             xParDirFormatting = xListBox.getChild('1')
             self.assertEqual(1, len(xParDirFormatting.getChildren()))
@@ -207,7 +207,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text without metadata
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(143, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(144, 
len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -217,7 +217,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text with paragraph metadata showed under 
direct paragraph formatting
             self.assertEqual(1, len(xListBox.getChild('1').getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xListBox.getChild('1').getChild('0'))['Text'])
-            self.assertEqual(143, 
len(xListBox.getChild('1').getChild('0').getChildren()))
+            self.assertEqual(144, 
len(xListBox.getChild('1').getChild('0').getChildren()))
 
             # Outer bookmark
             xBookmarkFormatting = xListBox.getChild('0')
@@ -264,7 +264,7 @@ class styleNavigator(UITestCase):
             # The cursor is on text without metadata
             self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(143, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(144, 
len(xListBox.getChild('0').getChild('0').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
             self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
 
diff --git a/sw/qa/uitest/styleInspector/tdf137513.py 
b/sw/qa/uitest/styleInspector/tdf137513.py
index 936cb9400740..70f74c76a5e9 100644
--- a/sw/qa/uitest/styleInspector/tdf137513.py
+++ b/sw/qa/uitest/styleInspector/tdf137513.py
@@ -35,7 +35,7 @@ class tdf137513(UITestCase):
             self.assertEqual(2, len(xListBox.getChild('0').getChildren()))
             self.assertEqual("Default Paragraph Style  ", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
             self.assertEqual("Table Contents   ", 
get_state_as_dict(xListBox.getChild('0').getChild('1'))['Text'])
-            self.assertEqual(143, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(144, 
len(xListBox.getChild('0').getChild('0').getChildren()))
 
             xTableContent = xListBox.getChild('0').getChild('1')
             self.assertEqual(5, len(xTableContent.getChildren()))
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index f0166fd2d7aa..f2eb15cf187c 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -208,6 +208,7 @@ class SW_DLLPUBLIC SwTextFrame final : public SwContentFrame
     std::unique_ptr<sw::MergedPara> m_pMergedPara;
 
     TextFrameIndex mnOffset; // Is the offset in the Content (character count)
+    TextFrameIndex mnNoHyphOffset; // Is the offset of the last line to 
disable its hyphenation
 
     sal_uInt16 mnCacheIndex; // Index into the cache, USHRT_MAX if there's 
definitely no fitting object in the cache
 
@@ -454,6 +455,8 @@ public:
     TextFrameIndex GetOffset() const { return mnOffset; }
            void        SetOffset_(TextFrameIndex nNewOfst);
     inline void        SetOffset (TextFrameIndex nNewOfst);
+    TextFrameIndex GetNoHyphOffset() const { return mnNoHyphOffset; }
+    void SetNoHyphOffset(TextFrameIndex const nNewOfst) { mnNoHyphOffset = 
nNewOfst; }
     void ManipOfst(TextFrameIndex const nNewOfst) { mnOffset = nNewOfst; }
            SwTextFrame   *GetFrameAtPos ( const SwPosition &rPos);
     inline const SwTextFrame *GetFrameAtPos ( const SwPosition &rPos) const;
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
index 680411147a35..6e4996b6f980 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -286,7 +286,11 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
         }
     }
 
-    bool bHyph = rInf.IsHyphenate() && !rInf.IsHyphForbud();
+    bool bHyph = rInf.IsHyphenate() && !rInf.IsHyphForbud() &&
+        // disable hyphenation in the last line, when hyphenation-keep-line is 
enabled
+        ( rInf.GetTextFrame()->GetNoHyphOffset() == 
TextFrameIndex(COMPLETE_STRING) ||
+          // when there is a portion in the last line, rInf.GetIdx() > 
GetNoHyphOffset()
+          rInf.GetTextFrame()->GetNoHyphOffset() > rInf.GetIdx() );
     TextFrameIndex nHyphPos(0);
 
     // nCutPos is the first character not fitting to the current line
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 37fdee6a346f..bde01b5bf5b1 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1563,13 +1563,13 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
             sal_Int16 nMinLeading, sal_Int16 nMinTrailing,
             bool bNoCapsHyphenation, bool bNoLastWordHyphenation,
             sal_Int16 nMinWordLength, sal_Int16 nTextHyphZone, bool bKeep, 
sal_Int16 nKeepType,
-            sal_Int16 nCompoundMinLeading )
+            bool bKeepLine, sal_Int16 nCompoundMinLeading )
 {
     sal_Int32 nLen = rVals.getLength();
 
     if (0 == nLen)  // yet to be initialized?
     {
-        rVals.realloc( 9 );
+        rVals.realloc( 10 );
         PropertyValue *pVal = rVals.getArray();
 
         pVal[0].Name    = UPN_HYPH_MIN_LEADING;
@@ -1607,8 +1607,12 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
         pVal[8].Name    = UPN_HYPH_KEEP;
         pVal[8].Handle  = UPH_HYPH_KEEP;
         pVal[8].Value   <<= bKeep;
+
+        pVal[9].Name    = UPN_HYPH_KEEP_LINE;
+        pVal[9].Handle  = UPH_HYPH_KEEP_LINE;
+        pVal[9].Value   <<= bKeepLine;
     }
-    else if (9 == nLen) // already initialized once?
+    else if (10 == nLen) // already initialized once?
     {
         PropertyValue *pVal = rVals.getArray();
         pVal[0].Value <<= nMinLeading;
@@ -1620,6 +1624,7 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
         pVal[6].Value <<= nKeepType;
         pVal[7].Value <<= nCompoundMinLeading;
         pVal[8].Value <<= bKeep;
+        pVal[9].Value <<= bKeepLine;
     }
     else {
         OSL_FAIL( "unexpected size of sequence" );
@@ -1628,7 +1633,7 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
 
 const PropertyValues & SwTextFormatInfo::GetHyphValues() const
 {
-    OSL_ENSURE( 9 == m_aHyphVals.getLength(),
+    OSL_ENSURE( 10 == m_aHyphVals.getLength(),
             "hyphenation values not yet initialized" );
     return m_aHyphVals;
 }
@@ -1652,10 +1657,12 @@ bool SwTextFormatInfo::InitHyph( const bool bAutoHyphen 
)
         const sal_Int16 nTextHyphZone = rAttr.GetTextHyphenZone();
         const bool bKeep = rAttr.IsKeep();
         const sal_Int16 nKeepType = rAttr.GetKeepType();
+        const bool bKeepLine = rAttr.IsKeepLine();
         const sal_Int16 nCompoundMinimalLeading  = 
std::max(rAttr.GetCompoundMinLead(), sal_uInt8(2));
         lcl_InitHyphValues( m_aHyphVals, nMinimalLeading, nMinimalTrailing,
                  bNoCapsHyphenation, bNoLastWordHyphenation,
-                 nMinimalWordLength, nTextHyphZone, bKeep, nKeepType, 
nCompoundMinimalLeading );
+                 nMinimalWordLength, nTextHyphZone, bKeep, nKeepType,
+                 bKeepLine, nCompoundMinimalLeading );
     }
     return bAuto;
 }
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 8603c256c28f..9ed922e99656 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -773,6 +773,7 @@ SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* 
pSib,
     , mnHeightOfLastLine( 0 )
     , mnAdditionalFirstLineOffset( 0 )
     , mnOffset( 0 )
+    , mnNoHyphOffset( COMPLETE_STRING )
     , mnCacheIndex( USHRT_MAX )
     , mbLocked( false )
     , mbWidow( false )
diff --git a/sw/source/core/text/widorp.cxx b/sw/source/core/text/widorp.cxx
index 9d541644d652..d858b30d47a4 100644
--- a/sw/source/core/text/widorp.cxx
+++ b/sw/source/core/text/widorp.cxx
@@ -469,6 +469,7 @@ bool WidowsAndOrphans::FindWidows( SwTextFrame *pFrame, 
SwTextMargin &rLine )
 
     // hyphenation-keep: truncate a hyphenated line at the end of
     // the column, page or spread (but not more)
+    // hyphenation-keep-line: disable hyphenation in the last line instead of 
truncating it
     int nExtraWidLines = 0;
     if( rLine.GetLineNr() >= m_nWidLines && pMaster->HasPara() &&
         ( rLine.GetLineNr() == m_nWidLines || !rLine.GetCurr()->IsEndHyph() ) )
@@ -478,6 +479,7 @@ bool WidowsAndOrphans::FindWidows( SwTextFrame *pFrame, 
SwTextMargin &rLine )
         const SvxHyphenZoneItem &rAttr = rSet.GetHyphenZone();
 
         bool bKeep = rAttr.IsHyphen() && rAttr.IsKeep() && rAttr.GetKeepType();
+        bool bKeepLine = bKeep && rAttr.IsKeepLine();
 
         // if PAGE or SPREAD, allow hyphenation in the not last column or in 
the
         // not last linked frame on the same page
@@ -499,7 +501,10 @@ bool WidowsAndOrphans::FindWidows( SwTextFrame *pFrame, 
SwTextMargin &rLine )
 
         if ( bKeep && pMasterPara && pMasterPara->GetNext() )
         {
+            // calculate the beginning of last hyphenated line
+            TextFrameIndex nIdx(pMasterPara->GetLen());
             SwLineLayout * pNext = pMasterPara->GetNext();
+            nIdx += pNext->GetLen();
             SwLineLayout * pCurr = pNext;
             SwLineLayout * pPrev = pNext;
             while ( pNext->GetNext() )
@@ -507,21 +512,37 @@ bool WidowsAndOrphans::FindWidows( SwTextFrame *pFrame, 
SwTextMargin &rLine )
                 pPrev = pCurr;
                 pCurr = pNext;
                 pNext = pNext->GetNext();
+                nIdx += pNext->GetLen();
             }
+            nIdx -= pNext->GetLen();
             // hyphenated line, but not the last remaining one
-            if ( pNext->IsEndHyph() && !pNext->IsLastHyph() )
+            // in the case of shifting full line (bKeepLine = false)
+            if ( pNext->IsEndHyph() && ( bKeepLine || !pNext->IsLastHyph() ) )
             {
                 nExtraWidLines = rLine.GetLineNr() - m_nWidLines + 1;
+                // shift only a word: disable hyphenation in the line, if 
needed
+                if ( bKeepLine && nExtraWidLines )
+                {
+                    pMaster->SetNoHyphOffset(nIdx);
+                    nExtraWidLines = 0; // no need to shift the full line
+                }
+                // shift full line:
                 // set remaining line to "last remaining hyphenated line"
                 // to avoid truncating multiple hyphenated lines instead
                 // of a single one
-                if ( pCurr->IsEndHyph() )
+                else if ( !bKeepLine && pCurr->IsEndHyph() )
                     pCurr->SetLastHyph( true );
                 // also unset the line before the remaining one
                 // TODO: check also the line after the truncated line?
                 if ( pPrev->IsLastHyph() )
                     pPrev->SetLastHyph( false );
             }
+            else if ( !pNext->IsEndHyph() && pMaster->GetNoHyphOffset() != 
nIdx )
+            {
+                // not hyphenated and not a last line with forbidden 
hyphenation:
+                // enable hyphenation for all the lines in the TextFrame again
+                pMaster->SetNoHyphOffset(TextFrameIndex(COMPLETE_STRING));
+            }
         }
     }
 
diff --git a/sw/source/core/unocore/unomapproperties.hxx 
b/sw/source/core/unocore/unomapproperties.hxx
index 7e3f4c86216a..e441125576b7 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -123,6 +123,7 @@
         { UNO_NAME_PARA_HYPHENATION_ZONE,               RES_PARATR_HYPHENZONE, 
        cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, 
MID_HYPHEN_ZONE}, \
         { UNO_NAME_PARA_HYPHENATION_KEEP,               RES_PARATR_HYPHENZONE, 
        cppu::UnoType<bool>::get(),       PropertyAttribute::MAYBEVOID, 
MID_HYPHEN_KEEP                        }, \
         { UNO_NAME_PARA_HYPHENATION_KEEP_TYPE,          RES_PARATR_HYPHENZONE, 
        cppu::UnoType<sal_Int16>::get(),         PropertyAttribute::MAYBEVOID, 
MID_HYPHEN_KEEP_TYPE                   }, \
+        { UNO_NAME_PARA_HYPHENATION_KEEP_LINE,          RES_PARATR_HYPHENZONE, 
        cppu::UnoType<bool>::get(),              PropertyAttribute::MAYBEVOID, 
MID_HYPHEN_KEEP_LINE            }, \
         { UNO_NAME_CHAR_AUTO_KERNING,                   RES_CHRATR_AUTOKERN,   
        cppu::UnoType<bool>::get(),       PropertyAttribute::MAYBEVOID, 0       
                               }, \
         { UNO_NAME_CHAR_BACK_COLOR,                     RES_CHRATR_BACKGROUND, 
        cppu::UnoType<sal_Int32>::get(),         PropertyAttribute::MAYBEVOID, 
MID_BACK_COLOR                         }, \
         { UNO_NAME_CHAR_BACKGROUND_COMPLEX_COLOR,       RES_CHRATR_BACKGROUND, 
        cppu::UnoType<css::util::XComplexColor>::get(), PROPERTY_NONE, 
MID_BACKGROUND_COMPLEX_COLOR },\
@@ -493,6 +494,7 @@
                     { UNO_NAME_PARA_HYPHENATION_ZONE, RES_PARATR_HYPHENZONE,   
                   cppu::UnoType<sal_Int16>::get(),   
PropertyAttribute::MAYBEVOID, MID_HYPHEN_ZONE},\
                     { UNO_NAME_PARA_HYPHENATION_KEEP, RES_PARATR_HYPHENZONE,   
                   cppu::UnoType<bool>::get(),   PropertyAttribute::MAYBEVOID, 
MID_HYPHEN_KEEP},\
                     { UNO_NAME_PARA_HYPHENATION_KEEP_TYPE, 
RES_PARATR_HYPHENZONE,                 cppu::UnoType<sal_Int16>::get(),   
PropertyAttribute::MAYBEVOID, MID_HYPHEN_KEEP_TYPE},\
+                    { UNO_NAME_PARA_HYPHENATION_KEEP_LINE, 
RES_PARATR_HYPHENZONE,                 cppu::UnoType<bool>::get(),   
PropertyAttribute::MAYBEVOID, MID_HYPHEN_KEEP_LINE},\
                     { UNO_NAME_NUMBERING_STYLE_NAME, RES_PARATR_NUMRULE,  
cppu::UnoType<OUString>::get(),         PropertyAttribute::MAYBEVOID,   0},\
                     { UNO_NAME_NUMBERING_LEVEL, RES_PARATR_LIST_LEVEL,    
cppu::UnoType<sal_Int16>::get(),        PropertyAttribute::MAYBEVOID,   0},\
                     { UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES, 
RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), 
PropertyAttribute::MAYBEVOID, 0 },\
diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx 
b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
index 8ee351f719a5..289520cbcb50 100644
--- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
+++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
@@ -275,6 +275,7 @@ static OUString PropertyNametoRID(const OUString& rName)
         { "ParaHyphenationZone", RID_PARA_HYPHENATION_ZONE },
         { "ParaHyphenationKeep", RID_PARA_HYPHENATION_KEEP },
         { "ParaHyphenationKeepType", RID_PARA_HYPHENATION_KEEP_TYPE },
+        { "ParaHyphenationKeepLine", RID_PARA_HYPHENATION_KEEP_LINE },
         { "ParaInteropGrabBag", RID_PARA_INTEROP_GRAB_BAG },
         { "ParaIsAutoFirstLineIndent", RID_PARA_IS_AUTO_FIRST_LINE_INDENT },
         { "ParaIsCharacterDistance", RID_PARA_IS_CHARACTER_DISTANCE },
diff --git a/sw/source/writerfilter/dmapper/PropertyIds.cxx 
b/sw/source/writerfilter/dmapper/PropertyIds.cxx
index d2676d56e77a..9854cf7b0584 100644
--- a/sw/source/writerfilter/dmapper/PropertyIds.cxx
+++ b/sw/source/writerfilter/dmapper/PropertyIds.cxx
@@ -102,6 +102,7 @@ const OUString & getPropertyName( PropertyIds eId )
         { PROP_PARA_HYPHENATION_ZONE, u"ParaHyphenationZone"_ustr},
         { PROP_PARA_HYPHENATION_KEEP, u"ParaHyphenationKeep"_ustr},
         { PROP_PARA_HYPHENATION_KEEP_TYPE, u"ParaHyphenationKeepType"_ustr},
+        { PROP_PARA_HYPHENATION_KEEP_LINE, u"ParaHyphenationKeepLine"_ustr},
         { PROP_PARA_LINE_NUMBER_COUNT, u"ParaLineNumberCount"_ustr},
         { PROP_PARA_IS_HANGING_PUNCTUATION, u"ParaIsHangingPunctuation"_ustr},
         { PROP_PARA_LINE_SPACING, u"ParaLineSpacing"_ustr},
diff --git a/sw/source/writerfilter/dmapper/PropertyIds.hxx 
b/sw/source/writerfilter/dmapper/PropertyIds.hxx
index 277d4139862b..6bf8f749a962 100644
--- a/sw/source/writerfilter/dmapper/PropertyIds.hxx
+++ b/sw/source/writerfilter/dmapper/PropertyIds.hxx
@@ -250,6 +250,7 @@ enum PropertyIds
         ,PROP_PARA_HYPHENATION_ZONE
         ,PROP_PARA_HYPHENATION_KEEP
         ,PROP_PARA_HYPHENATION_KEEP_TYPE
+        ,PROP_PARA_HYPHENATION_KEEP_LINE
         ,PROP_PARA_KEEP_TOGETHER
         ,PROP_PARA_LAST_LINE_ADJUST
         ,PROP_PARA_LEFT_MARGIN
diff --git a/sw/source/writerfilter/dmapper/SettingsTable.cxx 
b/sw/source/writerfilter/dmapper/SettingsTable.cxx
index 7ec07453d4f6..ef301915cd93 100644
--- a/sw/source/writerfilter/dmapper/SettingsTable.cxx
+++ b/sw/source/writerfilter/dmapper/SettingsTable.cxx
@@ -572,11 +572,20 @@ sal_Int16 SettingsTable::GetConsecutiveHyphenLimit() const
 }
 
 bool SettingsTable::GetHyphenationKeep() const
+{
+    // if allowHyphenationAtTrackBottom is false, also if it is not defined
+    // (which means the same) hyphenation is not allowed in the last line, so
+    // set ParaHyphenationKeep to TRUE, and set ParaHyphenationKeepType to 
COLUMN
+    return m_pImpl->m_nAllowHyphenationAtTrackBottom != 1;
+}
+
+bool SettingsTable::GetHyphenationKeepLine() const
 {
     // if allowHyphenationAtTrackBottom is not true and 
useWord2013TrackBottomHyphenation is
-    // not present or it is true, set ParaHyphenationKeep to COLUMN
-    return m_pImpl->m_nAllowHyphenationAtTrackBottom != 1 &&
-                m_pImpl->m_nUseWord2013TrackBottomHyphenation != 0;
+    // not present or it is false, shift only the hyphenated word to the next 
column or page,
+    // not the full line, so set ParaHyphenationKeepLine to TRUE
+    return GetHyphenationKeep() &&
+                m_pImpl->m_nUseWord2013TrackBottomHyphenation != 1;
 }
 
 const OUString & SettingsTable::GetDecimalSymbol() const
@@ -746,6 +755,7 @@ void 
SettingsTable::ApplyProperties(rtl::Reference<SwXTextDocument> const& xDoc)
     {
         xDefault->setPropertyValue(u"ParaHyphenationKeep"_ustr, 
uno::Any(true));
         xDefault->setPropertyValue(u"ParaHyphenationKeepType"_ustr, 
uno::Any(text::ParagraphHyphenationKeepType::COLUMN));
+        xDefault->setPropertyValue(u"ParaHyphenationKeepLine"_ustr, 
uno::Any(GetHyphenationKeepLine()));
     }
 }
 
diff --git a/sw/source/writerfilter/dmapper/SettingsTable.hxx 
b/sw/source/writerfilter/dmapper/SettingsTable.hxx
index c90f5f389abf..d385465e0d1b 100644
--- a/sw/source/writerfilter/dmapper/SettingsTable.hxx
+++ b/sw/source/writerfilter/dmapper/SettingsTable.hxx
@@ -81,6 +81,7 @@ public:
     sal_Int16 GetHyphenationZone() const;
     sal_Int16 GetConsecutiveHyphenLimit() const;
     bool GetHyphenationKeep() const;
+    bool GetHyphenationKeepLine() const;
 
     const OUString& GetDecimalSymbol() const;
     const OUString& GetListSeparator() const;

Reply via email to