diff options
29 files changed, 208 insertions, 84 deletions
diff --git a/cui/source/inc/paragrph.hxx b/cui/source/inc/paragrph.hxx index 73cc5faf32cd..0967c32a060e 100644 --- a/cui/source/inc/paragrph.hxx +++ b/cui/source/inc/paragrph.hxx @@ -225,6 +225,7 @@ private: // hyphenation std::unique_ptr<weld::CheckButton> m_xHyphenBox; std::unique_ptr<weld::CheckButton> m_xHyphenNoCapsBox; + std::unique_ptr<weld::CheckButton> m_xHyphenNoLastWordBox; std::unique_ptr<weld::Label> m_xBeforeText; std::unique_ptr<weld::SpinButton> m_xExtHyphenBeforeBox; std::unique_ptr<weld::Label> m_xAfterText; diff --git a/cui/source/tabpages/paragrph.cxx b/cui/source/tabpages/paragrph.cxx index 14a43480caa5..29bc2fc76b43 100644 --- a/cui/source/tabpages/paragrph.cxx +++ b/cui/source/tabpages/paragrph.cxx @@ -1352,6 +1352,7 @@ bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* rOutSet ) if ( m_xHyphenBox->get_state_changed_from_saved() || m_xHyphenNoCapsBox->get_state_changed_from_saved() || + m_xHyphenNoLastWordBox->get_state_changed_from_saved() || m_xExtHyphenBeforeBox->get_value_changed_from_saved() || m_xExtHyphenAfterBox->get_value_changed_from_saved() || m_xMaxHyphenEdit->get_value_changed_from_saved() ) @@ -1360,6 +1361,7 @@ bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* rOutSet ) static_cast<const SvxHyphenZoneItem&>(GetItemSet().Get( _nWhich )) ); aHyphen.SetHyphen( eHyphenState == TRISTATE_TRUE ); aHyphen.SetNoCapsHyphenation(m_xHyphenNoCapsBox->get_state() == TRISTATE_TRUE); + aHyphen.SetNoLastWordHyphenation(m_xHyphenNoLastWordBox->get_state() == TRISTATE_TRUE); if ( eHyphenState == TRISTATE_TRUE ) { @@ -1570,6 +1572,7 @@ void SvxExtParagraphTabPage::Reset( const SfxItemSet* rSet ) bIsHyphen = rHyphen.IsHyphen(); m_xHyphenBox->set_state(bIsHyphen ? TRISTATE_TRUE : TRISTATE_FALSE); m_xHyphenNoCapsBox->set_state(rHyphen.IsNoCapsHyphenation() ? TRISTATE_TRUE : TRISTATE_FALSE); + m_xHyphenNoLastWordBox->set_state(rHyphen.IsNoLastWordHyphenation() ? TRISTATE_TRUE : TRISTATE_FALSE); m_xExtHyphenBeforeBox->set_value(rHyphen.GetMinLead()); m_xExtHyphenAfterBox->set_value(rHyphen.GetMinTrail()); @@ -1579,9 +1582,11 @@ void SvxExtParagraphTabPage::Reset( const SfxItemSet* rSet ) { m_xHyphenBox->set_state(TRISTATE_INDET); m_xHyphenNoCapsBox->set_state(TRISTATE_INDET); + m_xHyphenNoLastWordBox->set_state(TRISTATE_INDET); } bool bEnable = bItemAvailable && bIsHyphen; m_xHyphenNoCapsBox->set_sensitive(bEnable); + m_xHyphenNoLastWordBox->set_sensitive(bEnable); m_xExtHyphenBeforeBox->set_sensitive(bEnable); m_xExtHyphenAfterBox->set_sensitive(bEnable); m_xBeforeText->set_sensitive(bEnable); @@ -1843,6 +1848,7 @@ void SvxExtParagraphTabPage::ChangesApplied() { m_xHyphenBox->save_state(); m_xHyphenNoCapsBox->save_state(); + m_xHyphenNoLastWordBox->save_state(); m_xExtHyphenBeforeBox->set_value(m_xExtHyphenBeforeBox->get_value()); m_xExtHyphenAfterBox->set_value(m_xExtHyphenAfterBox->get_value()); m_xMaxHyphenEdit->set_value(m_xMaxHyphenEdit->get_value()); @@ -1889,6 +1895,7 @@ SvxExtParagraphTabPage::SvxExtParagraphTabPage(weld::Container* pPage, weld::Dia // Hyphenation , m_xHyphenBox(m_xBuilder->weld_check_button("checkAuto")) , m_xHyphenNoCapsBox(m_xBuilder->weld_check_button("checkNoCaps")) + , m_xHyphenNoLastWordBox(m_xBuilder->weld_check_button("checkNoLastWord")) , m_xBeforeText(m_xBuilder->weld_label("labelLineBegin")) , m_xExtHyphenBeforeBox(m_xBuilder->weld_spin_button("spinLineEnd")) , m_xAfterText(m_xBuilder->weld_label("labelLineEnd")) @@ -1956,6 +1963,7 @@ SvxExtParagraphTabPage::SvxExtParagraphTabPage(weld::Container* pPage, weld::Dia bHtmlMode = true; m_xHyphenBox->set_sensitive(false); m_xHyphenNoCapsBox->set_sensitive(false); + m_xHyphenNoLastWordBox->set_sensitive(false); m_xBeforeText->set_sensitive(false); m_xExtHyphenBeforeBox->set_sensitive(false); m_xAfterText->set_sensitive(false); @@ -2088,6 +2096,7 @@ void SvxExtParagraphTabPage::HyphenClickHdl() { bool bEnable = m_xHyphenBox->get_state() == TRISTATE_TRUE; m_xHyphenNoCapsBox->set_sensitive(bEnable); + m_xHyphenNoLastWordBox->set_sensitive(bEnable); m_xBeforeText->set_sensitive(bEnable); m_xExtHyphenBeforeBox->set_sensitive(bEnable); m_xAfterText->set_sensitive(bEnable); diff --git a/cui/uiconfig/ui/textflowpage.ui b/cui/uiconfig/ui/textflowpage.ui index a0b307c674aa..9ff931ddc6b8 100644 --- a/cui/uiconfig/ui/textflowpage.ui +++ b/cui/uiconfig/ui/textflowpage.ui @@ -102,7 +102,7 @@ </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">4</property> + <property name="top_attach">5</property> </packing> </child> <child> @@ -122,7 +122,7 @@ </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">3</property> + <property name="top_attach">4</property> </packing> </child> <child> @@ -142,7 +142,7 @@ </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">2</property> + <property name="top_attach">3</property> </packing> </child> <child> @@ -156,7 +156,7 @@ </object> <packing> <property name="left_attach">1</property> - <property name="top_attach">2</property> + <property name="top_attach">3</property> </packing> </child> <child> @@ -170,7 +170,7 @@ </object> <packing> <property name="left_attach">1</property> - <property name="top_attach">3</property> + <property name="top_attach">4</property> </packing> </child> <child> @@ -184,7 +184,7 @@ </object> <packing> <property name="left_attach">1</property> - <property name="top_attach">4</property> + <property name="top_attach">5</property> </packing> </child> <child> @@ -202,6 +202,21 @@ <property name="width">2</property> </packing> </child> + <child> + <object class="GtkCheckButton" id="checkNoLastWord"> + <property name="label" translatable="yes" context="textflowpage|checkNoLastWord">Don't hyphenate the last word</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">2</property> + </packing> + </child> </object> </child> <child type="label"> diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx index b0df5683b03a..0b8e41f48976 100644 --- a/editeng/source/editeng/editdoc.cxx +++ b/editeng/source/editeng/editdoc.cxx @@ -164,6 +164,7 @@ const SfxItemInfo aItemInfos[EDITITEMCOUNT] = { { SID_ATTR_NUMBERING_RULE, true }, // EE_PARA_NUMBULL { 0, true }, // EE_PARA_HYPHENATE { 0, true }, // EE_PARA_HYPHENATE_NO_CAPS + { 0, true }, // EE_PARA_HYPHENATE_NO_LAST_WORD { 0, true }, // EE_PARA_BULLETSTATE { 0, true }, // EE_PARA_OUTLLRSPACE { SID_ATTR_PARA_OUTLLEVEL, true }, // EE_PARA_OUTLLEVEL diff --git a/editeng/source/editeng/eerdll.cxx b/editeng/source/editeng/eerdll.cxx index 0002d68caafb..b7120bd1befd 100644 --- a/editeng/source/editeng/eerdll.cxx +++ b/editeng/source/editeng/eerdll.cxx @@ -89,59 +89,60 @@ DefItems::DefItems() rDefItems[5] = new SvxNumBulletItem( aDefaultNumRule, EE_PARA_NUMBULLET ); rDefItems[6] = new SfxBoolItem( EE_PARA_HYPHENATE, false ); rDefItems[7] = new SfxBoolItem( EE_PARA_HYPHENATE_NO_CAPS, false ); - rDefItems[8] = new SfxBoolItem( EE_PARA_BULLETSTATE, true ); - rDefItems[9] = new SvxLRSpaceItem( EE_PARA_OUTLLRSPACE ); - rDefItems[10] = new SfxInt16Item( EE_PARA_OUTLLEVEL, -1 ); - rDefItems[11] = new SvxBulletItem( EE_PARA_BULLET ); - rDefItems[12] = new SvxLRSpaceItem( EE_PARA_LRSPACE ); - rDefItems[13] = new SvxULSpaceItem( EE_PARA_ULSPACE ); - rDefItems[14] = new SvxLineSpacingItem( 0, EE_PARA_SBL ); - rDefItems[15] = new SvxAdjustItem( SvxAdjust::Left, EE_PARA_JUST ); - rDefItems[16] = new SvxTabStopItem( 0, 0, SvxTabAdjust::Left, EE_PARA_TABS ); - rDefItems[17] = new SvxJustifyMethodItem( SvxCellJustifyMethod::Auto, EE_PARA_JUST_METHOD ); - rDefItems[18] = new SvxVerJustifyItem( SvxCellVerJustify::Standard, EE_PARA_VER_JUST ); + rDefItems[8] = new SfxBoolItem( EE_PARA_HYPHENATE_NO_LAST_WORD, false ); + rDefItems[9] = new SfxBoolItem( EE_PARA_BULLETSTATE, true ); + rDefItems[10] = new SvxLRSpaceItem( EE_PARA_OUTLLRSPACE ); + rDefItems[11] = new SfxInt16Item( EE_PARA_OUTLLEVEL, -1 ); + rDefItems[12] = new SvxBulletItem( EE_PARA_BULLET ); + rDefItems[13] = new SvxLRSpaceItem( EE_PARA_LRSPACE ); + rDefItems[14] = new SvxULSpaceItem( EE_PARA_ULSPACE ); + rDefItems[15] = new SvxLineSpacingItem( 0, EE_PARA_SBL ); + rDefItems[16] = new SvxAdjustItem( SvxAdjust::Left, EE_PARA_JUST ); + rDefItems[17] = new SvxTabStopItem( 0, 0, SvxTabAdjust::Left, EE_PARA_TABS ); + rDefItems[18] = new SvxJustifyMethodItem( SvxCellJustifyMethod::Auto, EE_PARA_JUST_METHOD ); + rDefItems[19] = new SvxVerJustifyItem( SvxCellVerJustify::Standard, EE_PARA_VER_JUST ); // Character attributes: - rDefItems[19] = new SvxColorItem( COL_AUTO, EE_CHAR_COLOR ); - rDefItems[20] = new SvxFontItem( EE_CHAR_FONTINFO ); - rDefItems[21] = new SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT ); - rDefItems[22] = new SvxCharScaleWidthItem( 100, EE_CHAR_FONTWIDTH ); - rDefItems[23] = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT ); - rDefItems[24] = new SvxUnderlineItem( LINESTYLE_NONE, EE_CHAR_UNDERLINE ); - rDefItems[25] = new SvxCrossedOutItem( STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ); - rDefItems[26] = new SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC ); - rDefItems[27] = new SvxContourItem( false, EE_CHAR_OUTLINE ); - rDefItems[28] = new SvxShadowedItem( false, EE_CHAR_SHADOW ); - rDefItems[29] = new SvxEscapementItem( 0, 100, EE_CHAR_ESCAPEMENT ); - rDefItems[30] = new SvxAutoKernItem( false, EE_CHAR_PAIRKERNING ); - rDefItems[31] = new SvxKerningItem( 0, EE_CHAR_KERNING ); - rDefItems[32] = new SvxWordLineModeItem( false, EE_CHAR_WLM ); - rDefItems[33] = new SvxLanguageItem( LANGUAGE_DONTKNOW, EE_CHAR_LANGUAGE ); - rDefItems[34] = new SvxLanguageItem( LANGUAGE_DONTKNOW, EE_CHAR_LANGUAGE_CJK ); - rDefItems[35] = new SvxLanguageItem( LANGUAGE_DONTKNOW, EE_CHAR_LANGUAGE_CTL ); - rDefItems[36] = new SvxFontItem( EE_CHAR_FONTINFO_CJK ); - rDefItems[37] = new SvxFontItem( EE_CHAR_FONTINFO_CTL ); - rDefItems[38] = new SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT_CJK ); - rDefItems[39] = new SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT_CTL ); - rDefItems[40] = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT_CJK ); - rDefItems[41] = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT_CTL ); - rDefItems[42] = new SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC_CJK ); - rDefItems[43] = new SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC_CTL ); - rDefItems[44] = new SvxEmphasisMarkItem( FontEmphasisMark::NONE, EE_CHAR_EMPHASISMARK ); - rDefItems[45] = new SvxCharReliefItem( FontRelief::NONE, EE_CHAR_RELIEF ); - rDefItems[46] = new SfxVoidItem( EE_CHAR_RUBI_DUMMY ); - rDefItems[47] = new SvXMLAttrContainerItem( EE_CHAR_XMLATTRIBS ); - rDefItems[48] = new SvxOverlineItem( LINESTYLE_NONE, EE_CHAR_OVERLINE ); - rDefItems[49] = new SvxCaseMapItem( SvxCaseMap::NotMapped, EE_CHAR_CASEMAP ); - rDefItems[50] = new SfxGrabBagItem( EE_CHAR_GRABBAG ); - rDefItems[51] = new SvxColorItem( COL_AUTO, EE_CHAR_BKGCOLOR ); + rDefItems[20] = new SvxColorItem( COL_AUTO, EE_CHAR_COLOR ); + rDefItems[21] = new SvxFontItem( EE_CHAR_FONTINFO ); + rDefItems[22] = new SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT ); + rDefItems[23] = new SvxCharScaleWidthItem( 100, EE_CHAR_FONTWIDTH ); + rDefItems[24] = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT ); + rDefItems[25] = new SvxUnderlineItem( LINESTYLE_NONE, EE_CHAR_UNDERLINE ); + rDefItems[26] = new SvxCrossedOutItem( STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ); + rDefItems[27] = new SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC ); + rDefItems[28] = new SvxContourItem( false, EE_CHAR_OUTLINE ); + rDefItems[29] = new SvxShadowedItem( false, EE_CHAR_SHADOW ); + rDefItems[30] = new SvxEscapementItem( 0, 100, EE_CHAR_ESCAPEMENT ); + rDefItems[31] = new SvxAutoKernItem( false, EE_CHAR_PAIRKERNING ); + rDefItems[32] = new SvxKerningItem( 0, EE_CHAR_KERNING ); + rDefItems[33] = new SvxWordLineModeItem( false, EE_CHAR_WLM ); + rDefItems[34] = new SvxLanguageItem( LANGUAGE_DONTKNOW, EE_CHAR_LANGUAGE ); + rDefItems[35] = new SvxLanguageItem( LANGUAGE_DONTKNOW, EE_CHAR_LANGUAGE_CJK ); + rDefItems[36] = new SvxLanguageItem( LANGUAGE_DONTKNOW, EE_CHAR_LANGUAGE_CTL ); + rDefItems[37] = new SvxFontItem( EE_CHAR_FONTINFO_CJK ); + rDefItems[38] = new SvxFontItem( EE_CHAR_FONTINFO_CTL ); + rDefItems[39] = new SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT_CJK ); + rDefItems[40] = new SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT_CTL ); + rDefItems[41] = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT_CJK ); + rDefItems[42] = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT_CTL ); + rDefItems[43] = new SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC_CJK ); + rDefItems[44] = new SvxPostureItem( ITALIC_NONE, EE_CHAR_ITALIC_CTL ); + rDefItems[45] = new SvxEmphasisMarkItem( FontEmphasisMark::NONE, EE_CHAR_EMPHASISMARK ); + rDefItems[46] = new SvxCharReliefItem( FontRelief::NONE, EE_CHAR_RELIEF ); + rDefItems[47] = new SfxVoidItem( EE_CHAR_RUBI_DUMMY ); + rDefItems[48] = new SvXMLAttrContainerItem( EE_CHAR_XMLATTRIBS ); + rDefItems[49] = new SvxOverlineItem( LINESTYLE_NONE, EE_CHAR_OVERLINE ); + rDefItems[50] = new SvxCaseMapItem( SvxCaseMap::NotMapped, EE_CHAR_CASEMAP ); + rDefItems[51] = new SfxGrabBagItem( EE_CHAR_GRABBAG ); + rDefItems[52] = new SvxColorItem( COL_AUTO, EE_CHAR_BKGCOLOR ); // Features - rDefItems[52] = new SfxVoidItem( EE_FEATURE_TAB ); - rDefItems[53] = new SfxVoidItem( EE_FEATURE_LINEBR ); - rDefItems[54] = new SvxColorItem( COL_RED, EE_FEATURE_NOTCONV ); - rDefItems[55] = new SvxFieldItem( SvxFieldData(), EE_FEATURE_FIELD ); + rDefItems[53] = new SfxVoidItem( EE_FEATURE_TAB ); + rDefItems[54] = new SfxVoidItem( EE_FEATURE_LINEBR ); + rDefItems[55] = new SvxColorItem( COL_RED, EE_FEATURE_NOTCONV ); + rDefItems[56] = new SvxFieldItem( SvxFieldData(), EE_FEATURE_FIELD ); - assert(EDITITEMCOUNT == 56 && "ITEMCOUNT changed, adjust DefItems!"); + assert(EDITITEMCOUNT == 57 && "ITEMCOUNT changed, adjust DefItems!"); // Init DefFonts: GetDefaultFonts( *static_cast<SvxFontItem*>(rDefItems[EE_CHAR_FONTINFO - EE_ITEMS_START]), diff --git a/editeng/source/items/paraitem.cxx b/editeng/source/items/paraitem.cxx index 6f5e5f9acd80..56d9628276b3 100644 --- a/editeng/source/items/paraitem.cxx +++ b/editeng/source/items/paraitem.cxx @@ -555,6 +555,7 @@ SvxHyphenZoneItem::SvxHyphenZoneItem( const bool bHyph, const sal_uInt16 nId ) : bHyphen(bHyph), bPageEnd(true), bNoCapsHyphenation(false), + bNoLastWordHyphenation(false), nMinLead(0), nMinTrail(0), nMaxHyphens(255) @@ -582,6 +583,9 @@ bool SvxHyphenZoneItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) con case MID_HYPHEN_NO_CAPS: rVal <<= bNoCapsHyphenation; break; + case MID_HYPHEN_NO_LAST_WORD: + rVal <<= bNoLastWordHyphenation; + break; } return true; } @@ -591,9 +595,12 @@ bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) nMemberId &= ~CONVERT_TWIPS; sal_Int16 nNewVal = 0; - if( nMemberId != MID_IS_HYPHEN && nMemberId != MID_HYPHEN_NO_CAPS ) + if( nMemberId != MID_IS_HYPHEN && nMemberId != MID_HYPHEN_NO_CAPS && + nMemberId != MID_HYPHEN_NO_LAST_WORD ) + { if(!(rVal >>= nNewVal)) return false; + } switch(nMemberId) { @@ -612,6 +619,9 @@ bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) case MID_HYPHEN_NO_CAPS: bNoCapsHyphenation = Any2Bool(rVal); break; + case MID_HYPHEN_NO_LAST_WORD: + bNoLastWordHyphenation = Any2Bool(rVal); + break; } return true; } @@ -624,6 +634,7 @@ bool SvxHyphenZoneItem::operator==( const SfxPoolItem& rAttr ) const const SvxHyphenZoneItem& rItem = static_cast<const SvxHyphenZoneItem&>(rAttr); return ( rItem.bHyphen == bHyphen && rItem.bNoCapsHyphenation == bNoCapsHyphenation + && rItem.bNoLastWordHyphenation == bNoLastWordHyphenation && rItem.bPageEnd == bPageEnd && rItem.nMinLead == nMinLead && rItem.nMinTrail == nMinTrail diff --git a/include/editeng/eeitem.hxx b/include/editeng/eeitem.hxx index 28e5d8a0dd80..f862244865c1 100644 --- a/include/editeng/eeitem.hxx +++ b/include/editeng/eeitem.hxx @@ -80,18 +80,19 @@ constexpr TypedWhichId<SvxScriptSpaceItem> EE_PARA_ASIANCJKSPACING (EE constexpr TypedWhichId<SvxNumBulletItem> EE_PARA_NUMBULLET (EE_PARA_START+5); constexpr TypedWhichId<SfxBoolItem> EE_PARA_HYPHENATE (EE_PARA_START+6); constexpr TypedWhichId<SfxBoolItem> EE_PARA_HYPHENATE_NO_CAPS (EE_PARA_START+7); -constexpr TypedWhichId<SfxBoolItem> EE_PARA_BULLETSTATE (EE_PARA_START+8); -constexpr TypedWhichId<SvxLRSpaceItem> EE_PARA_OUTLLRSPACE (EE_PARA_START+9); -constexpr TypedWhichId<SfxInt16Item> EE_PARA_OUTLLEVEL (EE_PARA_START+10); -constexpr TypedWhichId<SvxBulletItem> EE_PARA_BULLET (EE_PARA_START+11); -constexpr TypedWhichId<SvxLRSpaceItem> EE_PARA_LRSPACE (EE_PARA_START+12); -constexpr TypedWhichId<SvxULSpaceItem> EE_PARA_ULSPACE (EE_PARA_START+13); -constexpr TypedWhichId<SvxLineSpacingItem> EE_PARA_SBL (EE_PARA_START+14); -constexpr TypedWhichId<SvxAdjustItem> EE_PARA_JUST (EE_PARA_START+15); -constexpr TypedWhichId<SvxTabStopItem> EE_PARA_TABS (EE_PARA_START+16); -constexpr TypedWhichId<SvxJustifyMethodItem> EE_PARA_JUST_METHOD (EE_PARA_START+17); -constexpr TypedWhichId<SvxVerJustifyItem> EE_PARA_VER_JUST (EE_PARA_START+18); -constexpr sal_uInt16 EE_PARA_END (EE_PARA_START + 18); +constexpr TypedWhichId<SfxBoolItem> EE_PARA_HYPHENATE_NO_LAST_WORD (EE_PARA_START+8); +constexpr TypedWhichId<SfxBoolItem> EE_PARA_BULLETSTATE (EE_PARA_START+9); +constexpr TypedWhichId<SvxLRSpaceItem> EE_PARA_OUTLLRSPACE (EE_PARA_START+10); +constexpr TypedWhichId<SfxInt16Item> EE_PARA_OUTLLEVEL (EE_PARA_START+11); +constexpr TypedWhichId<SvxBulletItem> EE_PARA_BULLET (EE_PARA_START+12); +constexpr TypedWhichId<SvxLRSpaceItem> EE_PARA_LRSPACE (EE_PARA_START+13); +constexpr TypedWhichId<SvxULSpaceItem> EE_PARA_ULSPACE (EE_PARA_START+14); +constexpr TypedWhichId<SvxLineSpacingItem> EE_PARA_SBL (EE_PARA_START+15); +constexpr TypedWhichId<SvxAdjustItem> EE_PARA_JUST (EE_PARA_START+16); +constexpr TypedWhichId<SvxTabStopItem> EE_PARA_TABS (EE_PARA_START+17); +constexpr TypedWhichId<SvxJustifyMethodItem> EE_PARA_JUST_METHOD (EE_PARA_START+18); +constexpr TypedWhichId<SvxVerJustifyItem> EE_PARA_VER_JUST (EE_PARA_START+19); +constexpr sal_uInt16 EE_PARA_END (EE_PARA_START + 19); // Character attributes: constexpr sal_uInt16 EE_CHAR_START (EE_PARA_END + 1); diff --git a/include/editeng/hyphenzoneitem.hxx b/include/editeng/hyphenzoneitem.hxx index 9b3abd338839..26dd9a1b31f0 100644 --- a/include/editeng/hyphenzoneitem.hxx +++ b/include/editeng/hyphenzoneitem.hxx @@ -35,6 +35,7 @@ class EDITENG_DLLPUBLIC SvxHyphenZoneItem final : public SfxPoolItem bool bHyphen : 1; bool bPageEnd : 1; bool bNoCapsHyphenation : 1; + bool bNoLastWordHyphenation : 1; sal_uInt8 nMinLead; sal_uInt8 nMinTrail; sal_uInt8 nMaxHyphens; @@ -65,6 +66,8 @@ public: void SetNoCapsHyphenation( const bool bNew ) { bNoCapsHyphenation = bNew; } bool IsNoCapsHyphenation() const { return bNoCapsHyphenation; } + void SetNoLastWordHyphenation( const bool bNew ) { bNoLastWordHyphenation = bNew; } + bool IsNoLastWordHyphenation() const { return bNoLastWordHyphenation; } sal_uInt8 &GetMinLead() { return nMinLead; } sal_uInt8 GetMinLead() const { return nMinLead; } diff --git a/include/editeng/memberids.h b/include/editeng/memberids.h index 1b50ab467229..a40d24cd6211 100644 --- a/include/editeng/memberids.h +++ b/include/editeng/memberids.h @@ -47,6 +47,7 @@ #define MID_HYPHEN_MIN_TRAIL 2 #define MID_HYPHEN_MAX_HYPHENS 3 #define MID_HYPHEN_NO_CAPS 4 +#define MID_HYPHEN_NO_LAST_WORD 5 // SvxBoxInfoItem #define MID_HORIZONTAL 1 diff --git a/include/editeng/unotext.hxx b/include/editeng/unotext.hxx index 87dc02a37c09..3c8f95368473 100644 --- a/include/editeng/unotext.hxx +++ b/include/editeng/unotext.hxx @@ -140,6 +140,7 @@ struct SfxItemPropertyMapEntry; { UNO_NAME_EDIT_PARA_BMARGIN, EE_PARA_ULSPACE, ::cppu::UnoType<sal_Int32>::get(), 0, MID_LO_MARGIN, PropertyMoreFlags::METRIC_ITEM }, \ { UNO_NAME_EDIT_PARA_IS_HYPHEN, EE_PARA_HYPHENATE, ::cppu::UnoType<bool>::get(), 0, 0 }, \ {u"ParaHyphenationNoCaps", EE_PARA_HYPHENATE_NO_CAPS, ::cppu::UnoType<bool>::get(), 0, 0 }, \ + {u"ParaHyphenationNoLastWord", EE_PARA_HYPHENATE_NO_LAST_WORD, ::cppu::UnoType<bool>::get(), 0, 0 }, \ { UNO_NAME_EDIT_PARA_LASTLINEADJ, EE_PARA_JUST, ::cppu::UnoType<sal_Int16>::get(), 0, MID_LAST_LINE_ADJUST }, \ { UNO_NAME_EDIT_PARA_LMARGIN, EE_PARA_LRSPACE, ::cppu::UnoType<sal_Int32>::get(), 0, MID_TXT_LMARGIN, PropertyMoreFlags::METRIC_ITEM }, \ { UNO_NAME_EDIT_PARA_LINESPACING, EE_PARA_SBL, cppu::UnoType<css::style::LineSpacing>::get(), 0, CONVERT_TWIPS}, \ diff --git a/include/unotools/linguprops.hxx b/include/unotools/linguprops.hxx index 9cc88e82d7f4..adede0b91777 100644 --- a/include/unotools/linguprops.hxx +++ b/include/unotools/linguprops.hxx @@ -41,6 +41,7 @@ inline constexpr OUStringLiteral UPN_HYPH_MIN_LEADING = u"HyphMin inline constexpr OUStringLiteral UPN_HYPH_MIN_TRAILING = u"HyphMinTrailing"; 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"; // UNO property names for Lingu // (those not covered by the SpellChecker and Hyphenator @@ -107,6 +108,7 @@ inline constexpr OUStringLiteral UPN_IS_GRAMMAR_INTERACTIVE = u"IsInter #define UPH_IS_GRAMMAR_AUTO 34 #define UPH_IS_GRAMMAR_INTERACTIVE 35 #define UPH_HYPH_NO_CAPS 36 +#define UPH_HYPH_NO_LAST_WORD 37 #ifdef __GNUC__ #pragma GCC diagnostic pop diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 8371c96e5839..469a0c5ad2ea 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -1051,6 +1051,7 @@ namespace xmloff::token { XML_HYPHENATION_PUSH_CHAR_COUNT, XML_HYPHENATION_REMAIN_CHAR_COUNT, XML_HYPHENATION_NO_CAPS, + XML_HYPHENATION_NO_LAST_WORD, 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 886234d62b31..975c1c0a76ad 100644 --- a/offapi/com/sun/star/style/ParagraphProperties.idl +++ b/offapi/com/sun/star/style/ParagraphProperties.idl @@ -416,6 +416,13 @@ published service ParagraphProperties */ [optional, property] boolean ParaHyphenationNoCaps; + /** Specifies whether last word of paragraph will be hyphenated. + Setting to `true` will disable hyphenation of last word for this paragraph. + + @since LibreOffice 7.4 + */ + [optional, property] boolean ParaHyphenationNoLastWord; + }; diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng index 6f1a298cdd8e..2fe197e92e79 100644 --- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng +++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng @@ -2706,6 +2706,15 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. </rng:define> <!-- TODO no proposal --> + <rng:define name="style-text-properties-attlist" combine="interleave"> + <rng:optional> + <rng:attribute name="loext:hyphenation-no-last-word"> + <rng:ref name="boolean"/> + </rng:attribute> + </rng:optional> + </rng:define> + + <!-- TODO no proposal --> <rng:define name="chart-data-point-attlist" combine="interleave"> <rng:optional> <rng:attribute name="loext:custom-label-pos-x"> diff --git a/sw/inc/inspectorproperties.hrc b/sw/inc/inspectorproperties.hrc index 03c2cc8c60b4..89deab1418cc 100644 --- a/sw/inc/inspectorproperties.hrc +++ b/sw/inc/inspectorproperties.hrc @@ -206,6 +206,7 @@ #define RID_PARA_HYPHENATION_MAX_LEADING_CHARS NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Max Leading Chars") #define RID_PARA_HYPHENATION_MAX_TRAILING_CHARS NC_("RID_ATTRIBUTE_NAMES_MAP", "Para Hyphenation Max Trailing Chars") #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_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 fa9d86992809..abb9bb8ea4d9 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_NO_CAPS "ParaHyphenationNoCaps" +#define UNO_NAME_PARA_HYPHENATION_NO_LAST_WORD "ParaHyphenationNoLastWord" #define UNO_NAME_LEFT_MARGIN "LeftMargin" #define UNO_NAME_RIGHT_MARGIN "RightMargin" #define UNO_NAME_GUTTER_MARGIN "GutterMargin" diff --git a/sw/qa/extras/layout/data/tdf149248.odt b/sw/qa/extras/layout/data/tdf149248.odt Binary files differnew file mode 100644 index 000000000000..18685bd0a585 --- /dev/null +++ b/sw/qa/extras/layout/data/tdf149248.odt diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index cca5636d933c..93dbd19184a4 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -4161,6 +4161,21 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf121658) assertXPath(pXmlDoc, "//Special[@nType='PortionType::Hyphen']", 2); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf149248) +{ + uno::Reference<linguistic2::XHyphenator> xHyphenator = LinguMgr::GetHyphenator(); + if (!xHyphenator->hasLocale(lang::Locale("en", "US", OUString()))) + return; + + createSwDoc(DATA_DIRECTORY, "tdf149248.odt"); + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + + // Only 1 hyphenated word should appear in the document (last word of the second + // paragraph). Last word should not be hyphenated for the fourth paragraph + // (the same paragraph, but with forbidden hyphenation of the last word). + assertXPath(pXmlDoc, "//Special[@nType='PortionType::Hyphen']", 1); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testWriterImageNoCapture) { createSwDoc(DATA_DIRECTORY, "writer-image-no-capture.docx"); diff --git a/sw/qa/extras/odfexport/data/tdf149248.odt b/sw/qa/extras/odfexport/data/tdf149248.odt Binary files differnew file mode 100644 index 000000000000..18685bd0a585 --- /dev/null +++ b/sw/qa/extras/odfexport/data/tdf149248.odt diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx index bd11c7406a68..743ee2b475af 100644 --- a/sw/qa/extras/odfexport/odfexport.cxx +++ b/sw/qa/extras/odfexport/odfexport.cxx @@ -3038,6 +3038,13 @@ DECLARE_ODFEXPORT_TEST(tdf121658, "tdf121658.odt") CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xStyle1, "ParaHyphenationNoCaps")); } +DECLARE_ODFEXPORT_TEST(tdf149248, "tdf149248.odt") +{ + CPPUNIT_ASSERT_EQUAL(1, getPages()); + CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(getParagraph(2), "ParaHyphenationNoLastWord")); + CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(getParagraph(4), "ParaHyphenationNoLastWord")); +} + 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 14b4590582cf..49d02fc01c9b 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(137, len(xListBox.getChild('0').getChild('0').getChildren())) + self.assertEqual(138, 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(137, len(xListBox.getChild('0').getChild('0').getChildren())) + self.assertEqual(138, 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(137, len(xListBox.getChild('0').getChild('0').getChildren())) + self.assertEqual(138, 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(137, len(xParStyle.getChild('0').getChildren())) + self.assertEqual(138, 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(137, len(xParStyle.getChild('0').getChildren())) + self.assertEqual(138, 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(137, len(xListBox.getChild('0').getChild('0').getChildren())) + self.assertEqual(138, 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(137, len(xListBox.getChild('0').getChild('0').getChildren())) + self.assertEqual(138, 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(137, len(xListBox.getChild('0').getChild('0').getChildren())) + self.assertEqual(138, 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(137, len(xListBox.getChild('1').getChild('0').getChildren())) + self.assertEqual(138, 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(137, len(xListBox.getChild('0').getChild('0').getChildren())) + self.assertEqual(138, 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 63d208dc2d86..f04f6106cf7c 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(137, len(xListBox.getChild('0').getChild('0').getChildren())) + self.assertEqual(138, 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 8bf9819c4d66..907502ed0063 100644 --- a/sw/source/core/text/guess.cxx +++ b/sw/source/core/text/guess.cxx @@ -31,6 +31,7 @@ #include "porfld.hxx" #include <paratr.hxx> #include <doc.hxx> +#include <unotools/linguprops.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -195,8 +196,30 @@ 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; + const css::beans::PropertyValues & rHyphValues = rInf.GetHyphValues(); + assert( rHyphValues.getLength() > 3 && rHyphValues[3].Name == UPN_HYPH_NO_LAST_WORD ); + if ( rHyphValues[3].Value >>= bHyphenationNoLastWord ) + { + 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; + } + } + m_nCutPos = rInf.GetTextBreak( nLineWidth, nMaxLen, nMaxComp, nHyphPos, rInf.GetCachedVclData().get() ); + // don't hyphenate last word of the paragraph + if ( bHyphenationNoLastWord && sal_Int32(m_nCutPos) > nLastWord ) + 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 5f4cbb95b6fc..6f22e920d135 100644 --- a/sw/source/core/text/inftxt.cxx +++ b/sw/source/core/text/inftxt.cxx @@ -1360,13 +1360,14 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion &rPor, } static void lcl_InitHyphValues( PropertyValues &rVals, - sal_Int16 nMinLeading, sal_Int16 nMinTrailing, bool bNoCapsHyphenation ) + sal_Int16 nMinLeading, sal_Int16 nMinTrailing, + bool bNoCapsHyphenation, bool bNoLastWordHyphenation ) { sal_Int32 nLen = rVals.getLength(); if (0 == nLen) // yet to be initialized? { - rVals.realloc( 3 ); + rVals.realloc( 4 ); PropertyValue *pVal = rVals.getArray(); pVal[0].Name = UPN_HYPH_MIN_LEADING; @@ -1380,13 +1381,18 @@ static void lcl_InitHyphValues( PropertyValues &rVals, pVal[2].Name = UPN_HYPH_NO_CAPS; pVal[2].Handle = UPH_HYPH_NO_CAPS; pVal[2].Value <<= bNoCapsHyphenation; + + pVal[3].Name = UPN_HYPH_NO_LAST_WORD; + pVal[3].Handle = UPH_HYPH_NO_LAST_WORD; + pVal[3].Value <<= bNoLastWordHyphenation; } - else if (3 == nLen) // already initialized once? + else if (4 == nLen) // already initialized once? { PropertyValue *pVal = rVals.getArray(); pVal[0].Value <<= nMinLeading; pVal[1].Value <<= nMinTrailing; pVal[2].Value <<= bNoCapsHyphenation; + pVal[3].Value <<= bNoLastWordHyphenation; } else { OSL_FAIL( "unexpected size of sequence" ); @@ -1395,7 +1401,7 @@ static void lcl_InitHyphValues( PropertyValues &rVals, const PropertyValues & SwTextFormatInfo::GetHyphValues() const { - OSL_ENSURE( 3 == m_aHyphVals.getLength(), + OSL_ENSURE( 4 == m_aHyphVals.getLength(), "hyphenation values not yet initialized" ); return m_aHyphVals; } @@ -1414,7 +1420,9 @@ bool SwTextFormatInfo::InitHyph( const bool bAutoHyphen ) const sal_Int16 nMinimalLeading = std::max(rAttr.GetMinLead(), sal_uInt8(2)); const sal_Int16 nMinimalTrailing = rAttr.GetMinTrail(); const bool bNoCapsHyphenation = rAttr.IsNoCapsHyphenation(); - lcl_InitHyphValues( m_aHyphVals, nMinimalLeading, nMinimalTrailing, bNoCapsHyphenation); + const bool bNoLastWordHyphenation = rAttr.IsNoLastWordHyphenation(); + lcl_InitHyphValues( m_aHyphVals, nMinimalLeading, nMinimalTrailing, + bNoCapsHyphenation, bNoLastWordHyphenation ); } return bAuto; } diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx index e2e1ce136553..ec9ce71977af 100644 --- a/sw/source/core/unocore/unomapproperties.hxx +++ b/sw/source/core/unocore/unomapproperties.hxx @@ -113,6 +113,7 @@ { u"" UNO_NAME_PARRSID, RES_PARATR_RSID, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::MAYBEVOID, 0 }, \ { u"" UNO_NAME_PARA_IS_HYPHENATION, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_IS_HYPHEN }, \ { u"" UNO_NAME_PARA_HYPHENATION_NO_CAPS, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_CAPS }, \ + { u"" UNO_NAME_PARA_HYPHENATION_NO_LAST_WORD, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_LAST_WORD }, \ { u"" UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_LEAD }, \ { 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 }, \ @@ -435,6 +436,7 @@ { u"" UNO_NAME_BOTTOM_BORDER_DISTANCE, RES_BOX, cppu::UnoType<sal_Int32>::get(), 0, BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },\ { u"" UNO_NAME_PARA_IS_HYPHENATION, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_IS_HYPHEN },\ { u"" UNO_NAME_PARA_HYPHENATION_NO_CAPS, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_CAPS },\ + { u"" UNO_NAME_PARA_HYPHENATION_NO_LAST_WORD, RES_PARATR_HYPHENZONE, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_NO_LAST_WORD },\ { u"" UNO_NAME_PARA_HYPHENATION_MAX_LEADING_CHARS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_LEAD },\ { 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},\ diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx index 72a9238c7c66..59108e4ed1f8 100644 --- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx +++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx @@ -252,6 +252,7 @@ static OUString PropertyNametoRID(const OUString& rName) { "ParaHyphenationMaxLeadingChars", RID_PARA_HYPHENATION_MAX_LEADING_CHARS }, { "ParaHyphenationMaxTrailingChars", RID_PARA_HYPHENATION_MAX_TRAILING_CHARS }, { "ParaHyphenationNoCaps", RID_PARA_HYPHENATION_NO_CAPS }, + { "ParaHyphenationNoLastWord", RID_PARA_HYPHENATION_NO_LAST_WORD }, { "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 949178c67f09..34371453c815 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -1064,6 +1064,7 @@ namespace xmloff::token { TOKEN( "hyphenation-push-char-count", XML_HYPHENATION_PUSH_CHAR_COUNT ), TOKEN( "hyphenation-remain-char-count", XML_HYPHENATION_REMAIN_CHAR_COUNT ), TOKEN( "hyphenation-no-caps", XML_HYPHENATION_NO_CAPS ), + TOKEN( "hyphenation-no-last-word", XML_HYPHENATION_NO_LAST_WORD ), 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 ce09a85c917a..b116b16c836e 100644 --- a/xmloff/source/text/txtprmap.cxx +++ b/xmloff/source/text/txtprmap.cxx @@ -343,6 +343,7 @@ XMLPropertyMapEntry const aXMLParaPropMap[] = MT_E( "ParaHyphenationMaxTrailingChars",FO, HYPHENATION_PUSH_CHAR_COUNT, XML_TYPE_NUMBER16_NO_ZERO, 0 ), MP_E( "ParaHyphenationMaxHyphens", FO, HYPHENATION_LADDER_COUNT, XML_TYPE_NUMBER16_NONE, 0 ), 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 ), // 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 04b8b62de5d3..cc365e61d3a0 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -964,6 +964,7 @@ hyphenation-ladder-count hyphenation-push-char-count hyphenation-remain-char-count hyphenation-no-caps +hyphenation-no-last-word i icon icon-set |