cui/source/inc/paragrph.hxx                                 |    1 
 cui/source/tabpages/paragrph.cxx                            |   28 ++++
 cui/uiconfig/ui/textflowpage.ui                             |   48 ++++++++
 editeng/source/items/paraitem.cxx                           |   43 ++++++-
 include/editeng/editrids.hrc                                |    5 
 include/editeng/hyphenzoneitem.hxx                          |    8 +
 include/editeng/memberids.h                                 |    1 
 include/unotools/linguprops.hxx                             |    2 
 include/xmloff/xmltoken.hxx                                 |    1 
 offapi/com/sun/star/style/ParagraphProperties.idl           |    7 +
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng |   12 ++
 svx/sdi/svxitems.sdi                                        |    1 
 sw/inc/inspectorproperties.hrc                              |    1 
 sw/inc/unoprnms.hxx                                         |    1 
 sw/qa/extras/layout/data/tdf149420.odt                      |binary
 sw/qa/extras/layout/layout.cxx                              |   15 ++
 sw/qa/extras/odfexport/data/tdf149420.odt                   |binary
 sw/qa/extras/odfexport/odfexport.cxx                        |    7 +
 sw/qa/uitest/styleInspector/styleInspector.py               |   20 +--
 sw/qa/uitest/styleInspector/tdf137513.py                    |    2 
 sw/source/core/text/guess.cxx                               |   72 +++++++++---
 sw/source/core/text/inftxt.cxx                              |   18 ++-
 sw/source/core/unocore/unomapproperties.hxx                 |    2 
 sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx       |    1 
 xmloff/source/core/xmltoken.cxx                             |    1 
 xmloff/source/text/txtprmap.cxx                             |    1 
 xmloff/source/token/tokens.txt                              |    1 
 27 files changed, 257 insertions(+), 42 deletions(-)

New commits:
commit 7a1d4b7d1db93ca1f541856a8d00d621d50e7bd6
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Wed Jun 1 16:38:28 2022 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Thu Jun 2 09:57:39 2022 +0200

    tdf#149420 sw offapi xmloff: add hyphenation zone
    
    Add hyphenation zone support, i.e. allow the specified
    amount of extra space in lines instead of forcing hyphenation.
    It's for limiting hyphenation, used especially with
    not justified paragraph alignment.
    
    Note: this is an OOXML interoperability feature,
    used also in DTP software and CSS.
    
    * Add checkbox to Text Flow in paragraph dialog
    * Store property in paragraph model 
(com::sun::star::style::ParagraphProperties::ParaHyphenationZone)
    * Add ODF import/export
    * Add ODF unit test
    * Add layout test
    
    Note: extend SvxHyphenZoneItem::GetPresentation() with
    missing No CAPS and No last word hyphenation options.
    
    Note: fix OSL_ENSURE condition in SwTextFormatInfo::GetHyphValues().
    
    Follow-up to commit 29359fc15c435cec17987fd6221ab6833d38746e
    "tdf#149324 sw offapi xmloff: add option to not hyphenate short words".
    
    Change-Id: Ib8eff6ea98a9aa5ca6cb9d17faa0bbb789687ce9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135247
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/cui/source/inc/paragrph.hxx b/cui/source/inc/paragrph.hxx
index f0c56775fc2c..3947c14d10c8 100644
--- a/cui/source/inc/paragrph.hxx
+++ b/cui/source/inc/paragrph.hxx
@@ -233,6 +233,7 @@ private:
     std::unique_ptr<weld::Label> m_xMaxHyphenLabel;
     std::unique_ptr<weld::SpinButton> m_xMaxHyphenEdit;
     std::unique_ptr<weld::SpinButton> m_xMinWordLength;
+    std::unique_ptr<SvxRelativeField> m_xHyphenZone;
 
     // pagebreak
     std::unique_ptr<weld::CheckButton> m_xPageBreakBox;
diff --git a/cui/source/tabpages/paragrph.cxx b/cui/source/tabpages/paragrph.cxx
index 2d651fedae6a..3fa77d9fb791 100644
--- a/cui/source/tabpages/paragrph.cxx
+++ b/cui/source/tabpages/paragrph.cxx
@@ -1356,7 +1356,8 @@ bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* 
rOutSet )
          m_xExtHyphenBeforeBox->get_value_changed_from_saved() ||
          m_xExtHyphenAfterBox->get_value_changed_from_saved() ||
          m_xMaxHyphenEdit->get_value_changed_from_saved() ||
-         m_xMinWordLength->get_value_changed_from_saved() )
+         m_xMinWordLength->get_value_changed_from_saved() ||
+         m_xHyphenZone->get_value_changed_from_saved() )
     {
         SvxHyphenZoneItem aHyphen(
             static_cast<const SvxHyphenZoneItem&>(GetItemSet().Get( _nWhich )) 
);
@@ -1372,6 +1373,11 @@ bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* 
rOutSet )
         }
         aHyphen.GetMaxHyphens() = 
static_cast<sal_uInt8>(m_xMaxHyphenEdit->get_value());
 
+        SfxItemPool* pPool = GetItemSet().GetPool();
+        DBG_ASSERT( pPool, "Where is the pool?" );
+        MapUnit eUnit = pPool->GetMetric( _nWhich );
+        aHyphen.GetTextHyphenZone() = 
static_cast<sal_uInt16>(m_xHyphenZone->GetCoreValue(eUnit));
+
         if ( !pOld ||
             *static_cast<const SvxHyphenZoneItem*>(pOld) != aHyphen ||
                 m_xHyphenBox->get_state_changed_from_saved())
@@ -1560,6 +1566,17 @@ bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* 
rOutSet )
 }
 void SvxExtParagraphTabPage::Reset( const SfxItemSet* rSet )
 {
+    SfxItemPool* pPool = rSet->GetPool();
+    DBG_ASSERT( pPool, "Where is the pool?" );
+
+    // adjust metric
+    FieldUnit eFUnit = GetModuleFieldUnit( *rSet );
+
+    bool bApplyCharUnit = GetApplyCharUnit( *rSet );
+
+    if( SvtCJKOptions::IsAsianTypographyEnabled() && bApplyCharUnit )
+        eFUnit = FieldUnit::CHAR;
+
     sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_HYPHENZONE );
     SfxItemState eItemState = rSet->GetItemState( _nWhich );
 
@@ -1580,6 +1597,8 @@ void SvxExtParagraphTabPage::Reset( const SfxItemSet* 
rSet )
         m_xExtHyphenAfterBox->set_value(rHyphen.GetMinTrail());
         m_xMaxHyphenEdit->set_value(rHyphen.GetMaxHyphens());
         m_xMinWordLength->set_value(rHyphen.GetMinWordLength());
+        m_xHyphenZone->SetFieldUnit(eFUnit);
+        m_xHyphenZone->SetMetricValue(rHyphen.GetTextHyphenZone(), 
MapUnit::MapTwip);
     }
     else
     {
@@ -1597,6 +1616,7 @@ void SvxExtParagraphTabPage::Reset( const SfxItemSet* 
rSet )
     m_xMaxHyphenLabel->set_sensitive(bEnable);
     m_xMaxHyphenEdit->set_sensitive(bEnable);
     m_xMinWordLength->set_sensitive(bEnable);
+    m_xHyphenZone->set_sensitive(bEnable);
 
     switch (rSet->GetItemState(SID_ATTR_PARA_PAGENUM))
     {
@@ -1857,6 +1877,11 @@ void SvxExtParagraphTabPage::ChangesApplied()
     m_xExtHyphenAfterBox->set_value(m_xExtHyphenAfterBox->get_value());
     m_xMaxHyphenEdit->set_value(m_xMaxHyphenEdit->get_value());
     m_xMinWordLength->set_value(m_xMinWordLength->get_value());
+    SfxItemPool* pPool = GetItemSet().GetPool();
+    DBG_ASSERT( pPool, "Where is the pool?" );
+    FieldUnit eUnit =
+           MapToFieldUnit( pPool->GetMetric( GetWhich( 
SID_ATTR_PARA_HYPHENZONE ) ) );
+    m_xHyphenZone->set_value(m_xHyphenZone->get_value(eUnit), eUnit);
     m_xPageBreakBox->save_state();
     m_xBreakPositionLB->save_value();
     m_xBreakTypeLB->save_value();
@@ -1908,6 +1933,7 @@ 
SvxExtParagraphTabPage::SvxExtParagraphTabPage(weld::Container* pPage, weld::Dia
     , m_xMaxHyphenLabel(m_xBuilder->weld_label("labelMaxNum"))
     , m_xMaxHyphenEdit(m_xBuilder->weld_spin_button("spinMaxNum"))
     , m_xMinWordLength(m_xBuilder->weld_spin_button("spinMinLen"))
+    , m_xHyphenZone(new 
SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinHyphenZone", 
FieldUnit::CM)))
     //Page break
     , m_xPageBreakBox(m_xBuilder->weld_check_button("checkInsert"))
     , m_xBreakTypeFT(m_xBuilder->weld_label("labelType"))
diff --git a/cui/uiconfig/ui/textflowpage.ui b/cui/uiconfig/ui/textflowpage.ui
index 89ac8a3a22dd..496f22f05619 100644
--- a/cui/uiconfig/ui/textflowpage.ui
+++ b/cui/uiconfig/ui/textflowpage.ui
@@ -48,6 +48,11 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
+  <object class="GtkAdjustment" id="adjustment8">
+    <property name="upper">55.88</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
   <!-- n-columns=1 n-rows=1 -->
   <object class="GtkGrid" id="TextFlowPage">
     <property name="visible">True</property>
@@ -258,6 +263,49 @@
                 <property name="width">2</property>
               </packing>
             </child>
+            <child>
+              <!-- n-columns=1 n-rows=1 -->
+              <object class="GtkGrid" id="gridHyphenZone">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="row_spacing">6</property>
+                <property name="column_spacing">12</property>
+                <property name="margin-start">12</property>
+                <property name="margin-top">6</property>
+                <child>
+                  <object class="GtkSpinButton" id="spinHyphenZone">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="activates_default">True</property>
+                    <property name="truncate_multiline">True</property>
+                    <property name="adjustment">adjustment8</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="labelHyphenZone">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes" 
context="textflowpage|labelHyphenZone">Hyphenation _zone:</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">spinHyphenZone</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">7</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
           </object>
         </child>
         <child type="label">
diff --git a/editeng/source/items/paraitem.cxx 
b/editeng/source/items/paraitem.cxx
index 202341caa949..9368dfdf3c2a 100644
--- a/editeng/source/items/paraitem.cxx
+++ b/editeng/source/items/paraitem.cxx
@@ -559,7 +559,8 @@ SvxHyphenZoneItem::SvxHyphenZoneItem( const bool bHyph, 
const sal_uInt16 nId ) :
     nMinLead(0),
     nMinTrail(0),
     nMaxHyphens(255),
-    nMinWordLength(0)
+    nMinWordLength(0),
+    nTextHyphenZone(0)
 {
 }
 
@@ -590,6 +591,9 @@ bool    SvxHyphenZoneItem::QueryValue( uno::Any& rVal, 
sal_uInt8 nMemberId ) con
         case MID_HYPHEN_MIN_WORD_LENGTH:
             rVal <<= static_cast<sal_Int16>(nMinWordLength);
         break;
+        case MID_HYPHEN_ZONE:
+            rVal <<= static_cast<sal_Int16>(nTextHyphenZone);
+        break;
     }
     return true;
 }
@@ -629,6 +633,9 @@ bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, 
sal_uInt8 nMemberId )
         case MID_HYPHEN_MIN_WORD_LENGTH:
             nMinWordLength = static_cast<sal_uInt8>(nNewVal);
         break;
+        case MID_HYPHEN_ZONE:
+            nTextHyphenZone = nNewVal;
+        break;
     }
     return true;
 }
@@ -646,7 +653,8 @@ bool SvxHyphenZoneItem::operator==( const SfxPoolItem& 
rAttr ) const
             && rItem.nMinLead == nMinLead
             && rItem.nMinTrail == nMinTrail
             && rItem.nMaxHyphens == nMaxHyphens
-            && rItem.nMinWordLength == nMinWordLength );
+            && rItem.nMinWordLength == nMinWordLength
+            && rItem.nTextHyphenZone == nTextHyphenZone );
 }
 
 SvxHyphenZoneItem* SvxHyphenZoneItem::Clone( SfxItemPool * ) const
@@ -657,9 +665,9 @@ SvxHyphenZoneItem* SvxHyphenZoneItem::Clone( SfxItemPool * 
) const
 bool SvxHyphenZoneItem::GetPresentation
 (
     SfxItemPresentation ePres,
-    MapUnit             /*eCoreUnit*/,
-    MapUnit             /*ePresUnit*/,
-    OUString&           rText, const IntlWrapper&
+    MapUnit             eCoreUnit,
+    MapUnit             ePresUnit,
+    OUString&           rText, const IntlWrapper& rIntl
 )   const
 {
     OUString cpDelimTmp(cpDelim);
@@ -680,7 +688,16 @@ bool SvxHyphenZoneItem::GetPresentation
                     OUString::number( nMinLead ) + cpDelimTmp +
                     OUString::number( nMinTrail ) + cpDelimTmp +
                     OUString::number( nMaxHyphens ) + cpDelimTmp +
-                    OUString::number( nMinWordLength );
+                    OUString::number( nMinWordLength ) + cpDelimTmp +
+                    GetMetricText( nTextHyphenZone, eCoreUnit, ePresUnit, 
&rIntl ) +
+                        " " + EditResId(GetMetricId(ePresUnit));
+
+            if ( bNoCapsHyphenation )
+                rText += cpDelimTmp + 
EditResId(RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE);
+
+            if ( bNoLastWordHyphenation )
+                rText += cpDelimTmp + 
EditResId(RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE);
+
             return true;
         }
         case SfxItemPresentation::Complete:
@@ -703,6 +720,20 @@ bool SvxHyphenZoneItem::GetPresentation
                     EditResId(RID_SVXITEMS_HYPHEN_MAX).replaceAll("%1", 
OUString::number(nMaxHyphens)) +
                     cpDelimTmp +
                     EditResId(RID_SVXITEMS_HYPHEN_MINWORDLEN).replaceAll("%1", 
OUString::number(nMinWordLength));
+
+            if ( nTextHyphenZone > 0 )
+            {
+                rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_ZONE) +
+                        GetMetricText( nTextHyphenZone, eCoreUnit, ePresUnit, 
&rIntl ) +
+                        " " + EditResId(GetMetricId(ePresUnit));
+            }
+
+            if ( bNoCapsHyphenation )
+                rText += cpDelimTmp + 
EditResId(RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE);
+
+            if ( bNoLastWordHyphenation )
+                rText += cpDelimTmp + 
EditResId(RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE);
+
             return true;
         }
         default: ;//prevent warning
diff --git a/include/editeng/editrids.hrc b/include/editeng/editrids.hrc
index 57342e7c1deb..31ac07a1d22b 100644
--- a/include/editeng/editrids.hrc
+++ b/include/editeng/editrids.hrc
@@ -230,7 +230,10 @@
 #define RID_SVXITEMS_HYPHEN_MINLEAD             
NC_("RID_SVXITEMS_HYPHEN_MINLEAD", "%1 characters at end of line")
 #define RID_SVXITEMS_HYPHEN_MINTRAIL            
NC_("RID_SVXITEMS_HYPHEN_MINTRAIL", "%1 characters at beginning of line")
 #define RID_SVXITEMS_HYPHEN_MAX                 NC_("RID_SVXITEMS_HYPHEN_MAX", 
"%1 hyphens")
-#define RID_SVXITEMS_HYPHEN_MINWORDLEN          
NC_("RID_SVXITEMS_HYPHEN_MINWORDLEN", "Words with at least %1 characters")
+#define RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE        
NC_("RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE", "Not hyphenated CAPS")
+#define RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE      
NC_("RID_SVXITEMS_HYPHEN_NO_CAPS_FALSE", "Not hyphenated last word")
+#define RID_SVXITEMS_HYPHEN_MINWORDLEN          
NC_("RID_SVXITEMS_HYPHEN_MINWORDLEN", "%1 characters in words")
+#define RID_SVXITEMS_HYPHEN_ZONE                
NC_("RID_SVXITEMS_HYPHEN_ZONE", "Hyphenation zone ")
 #define RID_SVXITEMS_PAGEMODEL_COMPLETE         
NC_("RID_SVXITEMS_PAGEMODEL_COMPLETE", "Page Style: ")
 #define RID_SVXITEMS_KERNING_COMPLETE           
NC_("RID_SVXITEMS_KERNING_COMPLETE", "Kerning ")
 #define RID_SVXITEMS_KERNING_EXPANDED           
NC_("RID_SVXITEMS_KERNING_EXPANDED", "locked ")
diff --git a/include/editeng/hyphenzoneitem.hxx 
b/include/editeng/hyphenzoneitem.hxx
index b1ec7cba3a45..7104d2d7db58 100644
--- a/include/editeng/hyphenzoneitem.hxx
+++ b/include/editeng/hyphenzoneitem.hxx
@@ -38,8 +38,9 @@ class EDITENG_DLLPUBLIC SvxHyphenZoneItem final : public 
SfxPoolItem
     bool      bNoLastWordHyphenation : 1;
     sal_uInt8 nMinLead;
     sal_uInt8 nMinTrail;
-    sal_uInt8 nMaxHyphens;
-    sal_uInt8 nMinWordLength;
+    sal_uInt8 nMaxHyphens;      // max. consecutive lines with hyphenation
+    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
 
 public:
     static SfxPoolItem* CreateDefault();
@@ -81,6 +82,9 @@ public:
 
     sal_uInt8 &GetMinWordLength() { return nMinWordLength; }
     sal_uInt8 GetMinWordLength() const { return nMinWordLength; }
+
+    sal_uInt16 &GetTextHyphenZone() { return nTextHyphenZone; }
+    sal_uInt16 GetTextHyphenZone() const { return nTextHyphenZone; }
 };
 
 #endif
diff --git a/include/editeng/memberids.h b/include/editeng/memberids.h
index 4ec470f31db7..9b89ebafaefb 100644
--- a/include/editeng/memberids.h
+++ b/include/editeng/memberids.h
@@ -49,6 +49,7 @@
 #define MID_HYPHEN_NO_CAPS      4
 #define MID_HYPHEN_NO_LAST_WORD 5
 #define MID_HYPHEN_MIN_WORD_LENGTH 6
+#define MID_HYPHEN_ZONE         7
 
 // SvxBoxInfoItem
 #define MID_HORIZONTAL          1
diff --git a/include/unotools/linguprops.hxx b/include/unotools/linguprops.hxx
index adede0b91777..971c0280444c 100644
--- a/include/unotools/linguprops.hxx
+++ b/include/unotools/linguprops.hxx
@@ -42,6 +42,7 @@ inline constexpr OUStringLiteral UPN_HYPH_MIN_TRAILING        
       = u"HyphMin
 inline constexpr OUStringLiteral UPN_HYPH_MIN_WORD_LENGTH            = 
u"HyphMinWordLength";
 inline constexpr OUStringLiteral UPN_HYPH_NO_CAPS                    = 
u"HyphNoCaps";
 inline constexpr OUStringLiteral UPN_HYPH_NO_LAST_WORD               = 
u"HyphNoLastWord";
+inline constexpr OUStringLiteral UPN_HYPH_ZONE                       = 
u"HyphZone";
 
 // UNO property names for Lingu
 // (those not covered by the SpellChecker and Hyphenator
@@ -109,6 +110,7 @@ inline constexpr OUStringLiteral UPN_IS_GRAMMAR_INTERACTIVE 
         = u"IsInter
 #define UPH_IS_GRAMMAR_INTERACTIVE          35
 #define UPH_HYPH_NO_CAPS                    36
 #define UPH_HYPH_NO_LAST_WORD               37
+#define UPH_HYPH_ZONE                       38
 
 #ifdef __GNUC__
 #pragma GCC diagnostic pop
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 4592c01c75fb..69a495687da6 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1053,6 +1053,7 @@ namespace xmloff::token {
         XML_HYPHENATION_NO_CAPS,
         XML_HYPHENATION_NO_LAST_WORD,
         XML_HYPHENATION_WORD_CHAR_COUNT,
+        XML_HYPHENATION_ZONE,
         XML_I,
         XML_ICON,
         XML_ICON_SET,
diff --git a/offapi/com/sun/star/style/ParagraphProperties.idl 
b/offapi/com/sun/star/style/ParagraphProperties.idl
index e9522d77d1cd..32a63282d54e 100644
--- a/offapi/com/sun/star/style/ParagraphProperties.idl
+++ b/offapi/com/sun/star/style/ParagraphProperties.idl
@@ -428,6 +428,13 @@ published service ParagraphProperties
             @since LibreOffice 7.4
          */
         [optional, property] short ParaHyphenationMinWordLength;
+
+        /** specifies the hyphenation zone, i.e. allowed extra white space
+            in the line before applying hyphenation.
+
+            @since LibreOffice 7.4
+         */
+        [optional, property] long ParaHyphenationZone;
 };
 
 
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index d5857c132e37..293e40d9601c 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -2726,6 +2726,18 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
     </rng:optional>
   </rng:define>
 
+  <!-- TODO no proposal -->
+  <rng:define name="style-text-properties-attlist" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:hyphenation-zone">
+        <rng:choice>
+          <rng:value>no-limit</rng:value>
+          <rng:ref name="positiveInteger"/>
+        </rng:choice>
+      </rng:attribute>
+    </rng:optional>
+  </rng:define>
+
   <!-- TODO no proposal -->
   <rng:define name="chart-data-point-attlist" combine="interleave">
     <rng:optional>
diff --git a/svx/sdi/svxitems.sdi b/svx/sdi/svxitems.sdi
index 00e4b74237a2..df389994a868 100644
--- a/svx/sdi/svxitems.sdi
+++ b/svx/sdi/svxitems.sdi
@@ -260,6 +260,7 @@ struct SvxHyphenZone
     INT16       MinTrail      MID_HYPHEN_MIN_TRAIL;
     INT16       MaxHyphens    MID_HYPHEN_MAX_HYPHENS;
     INT16       MinWordLength MID_HYPHEN_MIN_WORD_LENGTH;
+    INT16       HyphenZone    MID_HYPHEN_ZONE;
 };
 item SvxHyphenZone SvxHyphenZoneItem;
 
diff --git a/sw/inc/inspectorproperties.hrc b/sw/inc/inspectorproperties.hrc
index f1327ec348c1..c2fd2a106f63 100644
--- a/sw/inc/inspectorproperties.hrc
+++ b/sw/inc/inspectorproperties.hrc
@@ -208,6 +208,7 @@
 #define RID_PARA_HYPHENATION_NO_CAPS                        
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation No Caps")
 #define RID_PARA_HYPHENATION_NO_LAST_WORD                   
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation No Last Word")
 #define RID_PARA_HYPHENATION_MIN_WORD_LENGTH                
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Min Word Length")
+#define RID_PARA_HYPHENATION_ZONE                           
NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Zone")
 #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 14da263acd96..c3a7d97b32e8 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -65,6 +65,7 @@
 #define UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS 
"ParaHyphenationMaxTrailingChars"
 #define UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS "ParaHyphenationMaxHyphens"
 #define UNO_NAME_PARA_HYPHENATION_MIN_WORD_LENGTH 
"ParaHyphenationMinWordLength"
+#define UNO_NAME_PARA_HYPHENATION_ZONE "ParaHyphenationZone"
 #define UNO_NAME_PARA_HYPHENATION_NO_CAPS "ParaHyphenationNoCaps"
 #define UNO_NAME_PARA_HYPHENATION_NO_LAST_WORD "ParaHyphenationNoLastWord"
 #define UNO_NAME_LEFT_MARGIN "LeftMargin"
diff --git a/sw/qa/extras/layout/data/tdf149420.odt 
b/sw/qa/extras/layout/data/tdf149420.odt
new file mode 100644
index 000000000000..249d7267eb27
Binary files /dev/null and b/sw/qa/extras/layout/data/tdf149420.odt differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index e42f5c22b83a..2a6b2ca099c9 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -4379,6 +4379,21 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf121658)
     assertXPath(pXmlDoc, "//Special[@nType='PortionType::Hyphen']", 2);
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf149420)
+{
+    uno::Reference<linguistic2::XHyphenator> xHyphenator = 
LinguMgr::GetHyphenator();
+    if (!xHyphenator->hasLocale(lang::Locale("en", "US", OUString())))
+        return;
+
+    createSwDoc(DATA_DIRECTORY, "tdf149420.odt");
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+    // Only 3 hyphenated words should appear in the document (last paragraph
+    // has got a 1 cm hyphenation zone, removing two hyphenations, which 
visible
+    // in the second paragraph).
+    assertXPath(pXmlDoc, "//Special[@nType='PortionType::Hyphen']", 8);
+}
+
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf149324)
 {
     uno::Reference<linguistic2::XHyphenator> xHyphenator = 
LinguMgr::GetHyphenator();
diff --git a/sw/qa/extras/odfexport/data/tdf149420.odt 
b/sw/qa/extras/odfexport/data/tdf149420.odt
new file mode 100644
index 000000000000..249d7267eb27
Binary files /dev/null and b/sw/qa/extras/odfexport/data/tdf149420.odt differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx 
b/sw/qa/extras/odfexport/odfexport.cxx
index 6f85db1d99a8..e58b772b8cdf 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -3052,6 +3052,13 @@ DECLARE_ODFEXPORT_TEST(tdf149324, "tdf149324.odt")
     CPPUNIT_ASSERT_EQUAL(sal_uInt16(7), 
getProperty<sal_uInt16>(getParagraph(4), "ParaHyphenationMinWordLength"));
 }
 
+DECLARE_ODFEXPORT_TEST(tdf149420, "tdf149420.odt")
+{
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), 
getProperty<sal_uInt16>(getParagraph(2), "ParaHyphenationZone"));
+    CPPUNIT_ASSERT_EQUAL(sal_uInt16(567), 
getProperty<sal_uInt16>(getParagraph(4), "ParaHyphenationZone"));
+}
+
 DECLARE_ODFEXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.odt")
 {
     CPPUNIT_ASSERT_EQUAL(1, getPages());
diff --git a/sw/qa/uitest/styleInspector/styleInspector.py 
b/sw/qa/uitest/styleInspector/styleInspector.py
index 29300f60ff17..f5ce2cd6bc75 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\t", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(139, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(140, 
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\t", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(139, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(140, 
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\t", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(139, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(140, 
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\t", 
get_state_as_dict(xParStyle.getChild('0'))['Text'])
-            self.assertEqual(139, len(xParStyle.getChild('0').getChildren()))
+            self.assertEqual(140, len(xParStyle.getChild('0').getChildren()))
             self.assertEqual("Heading\t", 
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\t", 
get_state_as_dict(xParStyle.getChild('0'))['Text'])
-            self.assertEqual(139, len(xParStyle.getChild('0').getChildren()))
+            self.assertEqual(140, len(xParStyle.getChild('0').getChildren()))
             self.assertEqual("Text Body\t", 
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\t", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(139, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(140, 
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\t", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(139, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(140, 
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\t", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(139, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(140, 
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\t", 
get_state_as_dict(xListBox.getChild('1').getChild('0'))['Text'])
-            self.assertEqual(139, 
len(xListBox.getChild('1').getChild('0').getChildren()))
+            self.assertEqual(140, 
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\t", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
-            self.assertEqual(139, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(140, 
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 8dfc5929c0c1..a0c9ddaafed0 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\t", 
get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
             self.assertEqual("Table Contents\t", 
get_state_as_dict(xListBox.getChild('0').getChild('1'))['Text'])
-            self.assertEqual(139, 
len(xListBox.getChild('0').getChild('0').getChildren()))
+            self.assertEqual(140, 
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/text/guess.cxx b/sw/source/core/text/guess.cxx
index d2711d4087d2..3055c69957cc 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -196,29 +196,69 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, 
SwTextFormatInfo &rInf,
     // considering an additional "-" for hyphenation
     if( bHyph )
     {
-        // search start of the last word, if needed
-        sal_Int32 nLastWord = rInf.GetText().getLength() - 1;
-        bool bHyphenationNoLastWord = false;
+        // nHyphZone is the first character not fitting in the hyphenation 
zone,
+        // or 0, if the whole line in the hyphenation zone,
+        // or -1, if no hyphenation zone defined (i.e. it is 0)
+        sal_Int32 nHyphZone = -1;
         const css::beans::PropertyValues & rHyphValues = rInf.GetHyphValues();
-        assert( rHyphValues.getLength() > 3 && rHyphValues[3].Name == 
UPN_HYPH_NO_LAST_WORD );
-        if ( rHyphValues[3].Value >>= bHyphenationNoLastWord )
+        assert( rHyphValues.getLength() > 5 && rHyphValues[5].Name == 
UPN_HYPH_ZONE );
+        // hyphenation zone (distance from the line end in twips)
+        sal_uInt16 nTextHyphenZone;
+        if ( rHyphValues[5].Value >>= nTextHyphenZone )
+            nHyphZone = nTextHyphenZone >= nLineWidth
+                ? 0
+                : sal_Int32(rInf.GetTextBreak( nLineWidth - nTextHyphenZone,
+                                        nMaxLen, nMaxComp, 
rInf.GetCachedVclData().get() ));
+
+        m_nCutPos = rInf.GetTextBreak( nLineWidth, nMaxLen, nMaxComp, 
nHyphPos, rInf.GetCachedVclData().get() );
+
+        // don't try to hyphenate in the hyphenation zone
+        if ( nHyphZone != -1 && TextFrameIndex(COMPLETE_STRING) != m_nCutPos )
         {
-            bool bCutBlank = false;
-            for (; sal_Int32(rInf.GetIdx()) <= nLastWord; --nLastWord )
+            sal_Int32 nZonePos = sal_Int32(m_nCutPos);
+            // disable hyphenation, if there is a space within the hyphenation 
zone
+            // Note: for better interoperability, not fitting space character 
at
+            // rInf.GetIdx()[nHyphZone] always disables the hyphenation, don't 
need to calculate
+            // with its fitting part. Moreover, do not check double or more 
spaces there, they
+            // are accepted outside of the hyphenation zone, too.
+            for (; sal_Int32(rInf.GetIdx()) <= nZonePos && nHyphZone <= 
nZonePos; --nZonePos )
             {
-                sal_Unicode cChar = rInf.GetText()[nLastWord];
-                if ( cChar != CH_BLANK && cChar != CH_FULL_BLANK && cChar != 
CH_SIX_PER_EM )
-                    bCutBlank = true;
-                else if ( bCutBlank )
-                    break;
+                sal_Unicode cChar = rInf.GetText()[nZonePos];
+                if ( cChar == CH_BLANK || cChar == CH_FULL_BLANK || cChar == 
CH_SIX_PER_EM )
+                {
+                    bHyph = false;
+                }
             }
         }
 
-        m_nCutPos = rInf.GetTextBreak( nLineWidth, nMaxLen, nMaxComp, 
nHyphPos, rInf.GetCachedVclData().get() );
+        // search start of the last word, if needed
+        if ( bHyph )
+        {
+            // nLastWord is the space character before the last word
+            sal_Int32 nLastWord = rInf.GetText().getLength() - 1;
+            bool bHyphenationNoLastWord = false;
+            assert( rHyphValues.getLength() > 3 && rHyphValues[3].Name == 
UPN_HYPH_NO_LAST_WORD );
+            if ( rHyphValues[3].Value >>= bHyphenationNoLastWord )
+            {
+                // skip spaces after the last word
+                bool bCutBlank = false;
+                for (; sal_Int32(rInf.GetIdx()) <= nLastWord; --nLastWord )
+                {
+                    sal_Unicode cChar = rInf.GetText()[nLastWord];
+                    if ( cChar != CH_BLANK && cChar != CH_FULL_BLANK && cChar 
!= CH_SIX_PER_EM )
+                        bCutBlank = true;
+                    else if ( bCutBlank )
+                        break;
+                }
+            }
 
-        // don't hyphenate last word of the paragraph
-        if ( bHyphenationNoLastWord && sal_Int32(m_nCutPos) > nLastWord )
-            m_nCutPos = TextFrameIndex(nLastWord);
+            // don't hyphenate the last word of the paragraph
+            if ( bHyphenationNoLastWord && sal_Int32(m_nCutPos) > nLastWord &&
+                            TextFrameIndex(COMPLETE_STRING) != m_nCutPos )
+            {
+                m_nCutPos = TextFrameIndex(nLastWord);
+            }
+        }
 
         if ( !nHyphPos && rInf.GetIdx() )
             nHyphPos = rInf.GetIdx() - TextFrameIndex(1);
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 5a794370b6da..c3a5068b3cf9 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1361,13 +1361,14 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion 
&rPor,
 
 static void lcl_InitHyphValues( PropertyValues &rVals,
             sal_Int16 nMinLeading, sal_Int16 nMinTrailing,
-            bool bNoCapsHyphenation, bool bNoLastWordHyphenation, sal_Int16 
nMinWordLength )
+            bool bNoCapsHyphenation, bool bNoLastWordHyphenation,
+            sal_Int16 nMinWordLength, sal_Int16 nTextHyphZone )
 {
     sal_Int32 nLen = rVals.getLength();
 
     if (0 == nLen)  // yet to be initialized?
     {
-        rVals.realloc( 5 );
+        rVals.realloc( 6 );
         PropertyValue *pVal = rVals.getArray();
 
         pVal[0].Name    = UPN_HYPH_MIN_LEADING;
@@ -1389,8 +1390,12 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
         pVal[4].Name    = UPN_HYPH_MIN_WORD_LENGTH;
         pVal[4].Handle  = UPH_HYPH_MIN_WORD_LENGTH;
         pVal[4].Value   <<= nMinWordLength;
+
+        pVal[5].Name    = UPN_HYPH_ZONE;
+        pVal[5].Handle  = UPH_HYPH_ZONE;
+        pVal[5].Value   <<= nTextHyphZone;
     }
-    else if (5 == nLen) // already initialized once?
+    else if (6 == nLen) // already initialized once?
     {
         PropertyValue *pVal = rVals.getArray();
         pVal[0].Value <<= nMinLeading;
@@ -1398,6 +1403,7 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
         pVal[2].Value <<= bNoCapsHyphenation;
         pVal[3].Value <<= bNoLastWordHyphenation;
         pVal[4].Value <<= nMinWordLength;
+        pVal[5].Value <<= nTextHyphZone;
     }
     else {
         OSL_FAIL( "unexpected size of sequence" );
@@ -1406,7 +1412,7 @@ static void lcl_InitHyphValues( PropertyValues &rVals,
 
 const PropertyValues & SwTextFormatInfo::GetHyphValues() const
 {
-    OSL_ENSURE( 4 == m_aHyphVals.getLength(),
+    OSL_ENSURE( 6 == m_aHyphVals.getLength(),
             "hyphenation values not yet initialized" );
     return m_aHyphVals;
 }
@@ -1427,8 +1433,10 @@ bool SwTextFormatInfo::InitHyph( const bool bAutoHyphen )
         const sal_Int16 nMinimalWordLength = rAttr.GetMinWordLength();
         const bool bNoCapsHyphenation = rAttr.IsNoCapsHyphenation();
         const bool bNoLastWordHyphenation = rAttr.IsNoLastWordHyphenation();
+        const sal_Int16 nTextHyphZone = rAttr.GetTextHyphenZone();
         lcl_InitHyphValues( m_aHyphVals, nMinimalLeading, nMinimalTrailing,
-                 bNoCapsHyphenation, bNoLastWordHyphenation, 
nMinimalWordLength );
+                 bNoCapsHyphenation, bNoLastWordHyphenation,
+                 nMinimalWordLength, nTextHyphZone );
     }
     return bAuto;
 }
diff --git a/sw/source/core/unocore/unomapproperties.hxx 
b/sw/source/core/unocore/unomapproperties.hxx
index 1f679b2e38fd..da2d4d907adf 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -118,6 +118,7 @@
         { u"" UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS, 
RES_PARATR_HYPHENZONE,         cppu::UnoType<sal_Int16>::get(),         
PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL                   }, \
         { u"" UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS,        
RES_PARATR_HYPHENZONE,         cppu::UnoType<sal_Int16>::get(),         
PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS                 }, \
         { u"" UNO_NAME_PARA_HYPHENATION_MIN_WORD_LENGTH,    
RES_PARATR_HYPHENZONE,         cppu::UnoType<sal_Int16>::get(),         
PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_WORD_LENGTH             }, \
+        { u"" UNO_NAME_PARA_HYPHENATION_ZONE,               
RES_PARATR_HYPHENZONE,         cppu::UnoType<sal_Int16>::get(),         
PropertyAttribute::MAYBEVOID, MID_HYPHEN_ZONE}, \
         { u"" UNO_NAME_CHAR_AUTO_KERNING,                   
RES_CHRATR_AUTOKERN,           cppu::UnoType<bool>::get(),       
PropertyAttribute::MAYBEVOID, 0                                      }, \
         { u"" UNO_NAME_CHAR_BACK_COLOR,                     
RES_CHRATR_BACKGROUND,         cppu::UnoType<sal_Int32>::get(),         
PropertyAttribute::MAYBEVOID, MID_BACK_COLOR                         }, \
         { u"" UNO_NAME_CHAR_HIGHLIGHT,                      
RES_CHRATR_HIGHLIGHT,          cppu::UnoType<sal_Int32>::get(), 
PropertyAttribute::MAYBEVOID, MID_BACK_COLOR                         }, \
@@ -442,6 +443,7 @@
                     { u"" UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS, 
RES_PARATR_HYPHENZONE,        cppu::UnoType<sal_Int16>::get(),   
PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL  },\
                     { u"" UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS, 
RES_PARATR_HYPHENZONE,       cppu::UnoType<sal_Int16>::get(),   
PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS},\
                     { u"" UNO_NAME_PARA_HYPHENATION_MIN_WORD_LENGTH, 
RES_PARATR_HYPHENZONE,       cppu::UnoType<sal_Int16>::get(),   
PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_WORD_LENGTH},\
+                    { u"" UNO_NAME_PARA_HYPHENATION_ZONE, 
RES_PARATR_HYPHENZONE,                      cppu::UnoType<sal_Int16>::get(),   
PropertyAttribute::MAYBEVOID, MID_HYPHEN_ZONE},\
                     { u"" 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},\
                     { u"" 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 530f72cdc923..913703366451 100644
--- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
+++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
@@ -258,6 +258,7 @@ static OUString PropertyNametoRID(const OUString& rName)
         { "ParaHyphenationNoCaps", RID_PARA_HYPHENATION_NO_CAPS },
         { "ParaHyphenationNoLastWord", RID_PARA_HYPHENATION_NO_LAST_WORD },
         { "ParaHyphenationMinWordLength", RID_PARA_HYPHENATION_MIN_WORD_LENGTH 
},
+        { "ParaHyphenationZone", RID_PARA_HYPHENATION_ZONE },
         { "ParaInteropGrabBag", RID_PARA_INTEROP_GRAB_BAG },
         { "ParaIsAutoFirstLineIndent", RID_PARA_IS_AUTO_FIRST_LINE_INDENT },
         { "ParaIsCharacterDistance", RID_PARA_IS_CHARACTER_DISTANCE },
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 356b98051ec0..efdd8a912cf8 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -1066,6 +1066,7 @@ namespace xmloff::token {
         TOKEN( "hyphenation-no-caps",             XML_HYPHENATION_NO_CAPS ),
         TOKEN( "hyphenation-no-last-word",        XML_HYPHENATION_NO_LAST_WORD 
),
         TOKEN( "hyphenation-word-char-count",     
XML_HYPHENATION_WORD_CHAR_COUNT ),
+        TOKEN( "hyphenation-zone",                XML_HYPHENATION_ZONE ),
         TOKEN( "i",                               XML_I ),
         TOKEN( "icon",                            XML_ICON ),
         TOKEN( "icon-set",                        XML_ICON_SET ),
diff --git a/xmloff/source/text/txtprmap.cxx b/xmloff/source/text/txtprmap.cxx
index a2e110e5bdb0..66bda55a8e3f 100644
--- a/xmloff/source/text/txtprmap.cxx
+++ b/xmloff/source/text/txtprmap.cxx
@@ -345,6 +345,7 @@ XMLPropertyMapEntry const aXMLParaPropMap[] =
     MAP_EXT( "ParaHyphenationNoCaps",  XML_NAMESPACE_LO_EXT, 
XML_HYPHENATION_NO_CAPS, XML_TYPE_BOOL|XML_TYPE_PROP_TEXT, 0 ),
     MAP_EXT( "ParaHyphenationNoLastWord",  XML_NAMESPACE_LO_EXT, 
XML_HYPHENATION_NO_LAST_WORD, XML_TYPE_BOOL|XML_TYPE_PROP_TEXT, 0 ),
     MAP_EXT( "ParaHyphenationMinWordLength",  XML_NAMESPACE_LO_EXT, 
XML_HYPHENATION_WORD_CHAR_COUNT, XML_TYPE_NUMBER16_NONE|XML_TYPE_PROP_TEXT, 0 ),
+    MAP_EXT( "ParaHyphenationZone",  XML_NAMESPACE_LO_EXT, 
XML_HYPHENATION_ZONE, XML_TYPE_NUMBER16_NONE|XML_TYPE_PROP_TEXT, 0 ),
     // RES_PARATR_DROP
     MP_E( "DropCapWholeWord",   STYLE,  LENGTH,     
MID_FLAG_SPECIAL_ITEM|XML_TYPE_BOOL, CTF_DROPCAPWHOLEWORD ),
     MP_E( "DropCapCharStyleName",   STYLE,  STYLE_NAME, 
MID_FLAG_SPECIAL_ITEM|XML_TYPE_STRING, CTF_DROPCAPCHARSTYLE ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index ee0adc36055d..aaf1442d1dc6 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -966,6 +966,7 @@ hyphenation-remain-char-count
 hyphenation-no-caps
 hyphenation-no-last-word
 hyphenation-word-char-count
+hyphenation-zone
 i
 icon
 icon-set

Reply via email to