Add a comment to clarify what kind of inputs the class handles
[LibreOffice.git] / sw / source / uibase / shells / txtattr.cxx
blob6846e101de8ac4dc624d308e03353b5403fadbbe
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hintids.hxx>
22 #include <svl/whiter.hxx>
23 #include <svl/stritem.hxx>
24 #include <svl/ctloptions.hxx>
25 #include <swmodule.hxx>
26 #include <sfx2/bindings.hxx>
27 #include <sfx2/request.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <editeng/fhgtitem.hxx>
30 #include <editeng/adjustitem.hxx>
31 #include <editeng/lspcitem.hxx>
32 #include <editeng/lrspitem.hxx>
33 #include <editeng/udlnitem.hxx>
34 #include <editeng/escapementitem.hxx>
35 #include <editeng/pmdlitem.hxx>
36 #include <sfx2/htmlmode.hxx>
37 #include <editeng/scripttypeitem.hxx>
38 #include <editeng/frmdiritem.hxx>
39 #include <editeng/cmapitem.hxx>
40 #include <editeng/nhypitem.hxx>
41 #include <osl/diagnose.h>
42 #include <paratr.hxx>
44 #include <fmtinfmt.hxx>
45 #include <wrtsh.hxx>
46 #include <view.hxx>
47 #include <viewopt.hxx>
48 #include <uitool.hxx>
49 #include <textsh.hxx>
50 #include <swundo.hxx>
51 #include <fmtcol.hxx>
53 #include <cmdid.h>
54 #include <globals.h>
55 #include <SwStyleNameMapper.hxx>
56 #include <swabstdlg.hxx>
57 #include <memory>
59 const sal_uInt32 nFontInc = 40; // 2pt
60 const sal_uInt32 nFontMaxSz = 19998; // 999.9pt
62 void SwTextShell::ExecCharAttr(SfxRequest &rReq)
64 SwWrtShell &rSh = GetShell();
65 const SfxItemSet *pArgs = rReq.GetArgs();
66 int eState = STATE_TOGGLE;
67 sal_uInt16 nWhich = rReq.GetSlot();
69 if(pArgs )
71 const SfxPoolItem* pItem;
72 pArgs->GetItemState(nWhich, false, &pItem);
73 eState = static_cast<const SfxBoolItem &>( pArgs->
74 Get( nWhich )).GetValue() ? STATE_ON : STATE_OFF;
77 SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1> aSet( GetPool() );
78 if (STATE_TOGGLE == eState)
79 rSh.GetCurAttr( aSet );
81 switch ( nWhich )
83 case FN_SET_SUB_SCRIPT:
84 case FN_SET_SUPER_SCRIPT:
86 SvxEscapement eEscape = SvxEscapement::Subscript;
87 switch (eState)
89 case STATE_TOGGLE:
91 short nTmpEsc = aSet.Get( RES_CHRATR_ESCAPEMENT ).GetEsc();
92 eEscape = nWhich == FN_SET_SUPER_SCRIPT ?
93 SvxEscapement::Superscript:
94 SvxEscapement::Subscript;
95 if( (nWhich == FN_SET_SUB_SCRIPT && nTmpEsc < 0) ||
96 (nWhich == FN_SET_SUPER_SCRIPT && nTmpEsc > 0) )
97 eEscape = SvxEscapement::Off;
99 SfxBindings& rBind = GetView().GetViewFrame().GetBindings();
100 if( nWhich == FN_SET_SUB_SCRIPT )
101 rBind.SetState( SfxBoolItem( FN_SET_SUPER_SCRIPT,
102 false ) );
103 else
104 rBind.SetState( SfxBoolItem( FN_SET_SUB_SCRIPT,
105 false ) );
108 break;
109 case STATE_ON:
110 eEscape = nWhich == FN_SET_SUPER_SCRIPT ?
111 SvxEscapement::Superscript:
112 SvxEscapement::Subscript;
113 break;
114 case STATE_OFF:
115 eEscape = SvxEscapement::Off;
116 break;
118 SvxEscapementItem aEscape( eEscape, RES_CHRATR_ESCAPEMENT );
119 rSh.SetAttrItem( aEscape );
120 rReq.AppendItem( aEscape );
121 rReq.Done();
123 break;
125 case FN_SET_SMALL_CAPS:
127 SvxCaseMap eCaseMap = SvxCaseMap::SmallCaps;
128 switch (eState)
130 case STATE_TOGGLE:
132 SvxCaseMap eTmpCaseMap = aSet.Get(RES_CHRATR_CASEMAP).GetCaseMap();
133 if (eTmpCaseMap == SvxCaseMap::SmallCaps)
134 eCaseMap = SvxCaseMap::NotMapped;
136 break;
137 case STATE_ON:
138 // Nothing to do, already set.
139 break;
140 case STATE_OFF:
141 eCaseMap = SvxCaseMap::NotMapped;
142 break;
144 SvxCaseMapItem aCaseMap(eCaseMap, RES_CHRATR_CASEMAP);
145 rSh.SetAttrItem(aCaseMap);
146 rReq.AppendItem(aCaseMap);
147 rReq.Done();
149 break;
151 case FN_UPDATE_STYLE_BY_EXAMPLE:
152 rSh.QuickUpdateStyle();
153 rReq.Done();
154 break;
156 case SID_ULINE_VAL_NONE:
158 SvxUnderlineItem aUnderline(LINESTYLE_NONE, RES_CHRATR_UNDERLINE );
159 rSh.SetAttrItem( aUnderline );
160 rReq.AppendItem( aUnderline );
161 rReq.Done();
162 break;
165 case SID_ULINE_VAL_SINGLE:
166 case SID_ULINE_VAL_DOUBLE:
167 case SID_ULINE_VAL_DOTTED:
169 FontLineStyle eOld = aSet.Get(RES_CHRATR_UNDERLINE).GetLineStyle();
170 FontLineStyle eNew = eOld;
172 switch (nWhich)
174 case SID_ULINE_VAL_SINGLE:
175 eNew = ( eOld == LINESTYLE_SINGLE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
176 break;
177 case SID_ULINE_VAL_DOUBLE:
178 eNew = ( eOld == LINESTYLE_DOUBLE ) ? LINESTYLE_NONE : LINESTYLE_DOUBLE;
179 break;
180 case SID_ULINE_VAL_DOTTED:
181 eNew = ( eOld == LINESTYLE_DOTTED ) ? LINESTYLE_NONE : LINESTYLE_DOTTED;
182 break;
185 SvxUnderlineItem aUnderline(eNew, RES_CHRATR_UNDERLINE );
186 rSh.SetAttrItem( aUnderline );
187 rReq.AppendItem( aUnderline );
188 rReq.Done();
190 break;
191 case FN_REMOVE_DIRECT_CHAR_FORMATS:
192 if( !rSh.HasReadonlySel() && rSh.IsEndPara())
193 rSh.DontExpandFormat();
194 break;
195 case FN_NO_BREAK:
197 bool bNoHyphen = aSet.Get(RES_CHRATR_NOHYPHEN).GetValue();
198 SvxNoHyphenItem aNoHyphen( !bNoHyphen, RES_CHRATR_NOHYPHEN );
199 rSh.SetAttrItem( aNoHyphen );
201 break;
202 default:
203 OSL_FAIL("wrong dispatcher");
204 return;
208 void SwTextShell::ExecCharAttrArgs(SfxRequest &rReq)
210 sal_uInt16 nSlot = rReq.GetSlot();
211 const SfxItemSet* pArgs = rReq.GetArgs();
212 bool bArgs = pArgs != nullptr && pArgs->Count() > 0;
213 SwWrtShell& rWrtSh = GetShell();
214 SwTextFormatColl* pColl = nullptr;
216 // Is only set if the whole paragraph is selected and AutoUpdateFormat is set.
217 if (rWrtSh.HasSelection() && rWrtSh.IsSelFullPara())
219 pColl = rWrtSh.GetCurTextFormatColl();
220 if ( pColl && !pColl->IsAutoUpdateOnDirectFormat() )
221 pColl = nullptr;
223 SfxItemPool& rPool = GetPool();
224 sal_uInt16 nWhich = rPool.GetWhichIDFromSlotID( nSlot );
225 switch (nSlot)
227 case FN_TXTATR_INET:
228 // Special treatment of the PoolId of the SwFormatInetFormat
229 if(bArgs)
231 const SfxPoolItem& rItem = pArgs->Get( nWhich );
233 SwFormatINetFormat aINetFormat( static_cast<const SwFormatINetFormat&>(rItem) );
234 if ( USHRT_MAX == aINetFormat.GetVisitedFormatId() )
236 OSL_ENSURE( false, "<SwTextShell::ExecCharAttrArgs(..)> - unexpected visited character format ID at hyperlink attribute" );
237 aINetFormat.SetVisitedFormatAndId(
238 aINetFormat.GetVisitedFormat(),
239 SwStyleNameMapper::GetPoolIdFromUIName( aINetFormat.GetVisitedFormat(), SwGetPoolIdFromName::ChrFmt ) );
241 if ( USHRT_MAX == aINetFormat.GetINetFormatId() )
243 OSL_ENSURE( false, "<SwTextShell::ExecCharAttrArgs(..)> - unexpected unvisited character format ID at hyperlink attribute" );
244 aINetFormat.SetINetFormatAndId(
245 aINetFormat.GetINetFormat(),
246 SwStyleNameMapper::GetPoolIdFromUIName( aINetFormat.GetINetFormat(), SwGetPoolIdFromName::ChrFmt ) );
249 if ( pColl )
250 pColl->SetFormatAttr( aINetFormat );
251 else
252 rWrtSh.SetAttrItem( aINetFormat );
253 rReq.Done();
255 break;
257 case FN_GROW_FONT_SIZE:
258 case FN_SHRINK_FONT_SIZE:
260 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT, rPool );
261 rWrtSh.GetCurAttr( aSetItem.GetItemSet() );
262 SfxItemSet aAttrSet( rPool, aSetItem.GetItemSet().GetRanges() );
264 SvtScriptType nScriptTypes = rWrtSh.GetScriptType();
265 const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>(
266 aSetItem.GetItemOfScript( nScriptTypes ) ) );
267 std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> vItems;
268 // simple case where selected text has one size and
269 // (tdf#124919) selection is not multiple table cells
270 if (pSize && !rWrtSh.IsTableMode())
272 // must create new one, otherwise document is without pam
273 SwPaM* pPaM = rWrtSh.GetCursor();
274 vItems.emplace_back( pSize, std::make_unique<SwPaM>( *(pPaM->GetMark()), *(pPaM->GetPoint())) );
276 else
277 vItems = rWrtSh.GetItemWithPaM( RES_CHRATR_FONTSIZE );
279 rWrtSh.StartUndo( SwUndoId::INSATTR );
280 for( std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >& iPair : vItems )
282 std::unique_ptr<SwPaM> pPaM = std::move(iPair.second);
283 const SfxPoolItem* pItem = iPair.first;
284 aSetItem.GetItemSet().ClearItem();
285 rWrtSh.GetPaMAttr( pPaM.get(), aSetItem.GetItemSet() );
286 aAttrSet.SetRanges( aSetItem.GetItemSet().GetRanges() );
288 pSize = static_cast<const SvxFontHeightItem*>( pItem );
289 if (pSize)
291 SvxFontHeightItem aSize(*pSize);
293 sal_uInt32 nSize = aSize.GetHeight();
295 if ( nSlot == FN_GROW_FONT_SIZE && ( nSize += nFontInc ) > nFontMaxSz )
296 nSize = nFontMaxSz;
297 else if ( nSlot == FN_SHRINK_FONT_SIZE && ( nSize -= nFontInc ) < nFontInc )
298 nSize = nFontInc;
300 aSize.SetHeight( nSize );
301 aSetItem.PutItemForScriptType( nScriptTypes, aSize );
302 aAttrSet.Put( aSetItem.GetItemSet() );
303 if( pColl )
304 pColl->SetFormatAttr( aAttrSet );
305 else
306 rWrtSh.SetAttrSet( aAttrSet, SetAttrMode::DEFAULT, pPaM.get() );
309 rWrtSh.EndUndo( SwUndoId::INSATTR );
310 rReq.Done();
312 break;
314 default:
315 OSL_FAIL("wrong dispatcher");
316 return;
320 void SwTextShell::ExecParaAttr(SfxRequest &rReq)
322 SvxAdjust eAdjst;
323 sal_uInt16 ePropL;
324 const SfxItemSet* pArgs = rReq.GetArgs();
326 // Get both attributes immediately isn't more expensive!!
327 SfxItemSetFixed
328 <RES_PARATR_LINESPACING, RES_PARATR_ADJUST,
329 RES_PARATR_HYPHENZONE, RES_PARATR_HYPHENZONE,
330 RES_FRAMEDIR, RES_FRAMEDIR> aSet( GetPool() );
332 sal_uInt16 nSlot = rReq.GetSlot();
333 switch (nSlot)
335 case SID_ATTR_PARA_ADJUST:
337 if( pArgs && SfxItemState::SET == pArgs->GetItemState(RES_PARATR_ADJUST) )
339 const SvxAdjustItem& rAdj = pArgs->Get(RES_PARATR_ADJUST);
340 SvxAdjustItem aAdj( rAdj.GetAdjust(), RES_PARATR_ADJUST );
341 if ( rAdj.GetAdjust() == SvxAdjust::Block )
343 aAdj.SetLastBlock( rAdj.GetLastBlock() );
344 aAdj.SetOneWord( rAdj.GetOneWord() );
347 aSet.Put(aAdj);
350 break;
351 case SID_ATTR_PARA_ADJUST_LEFT: eAdjst = SvxAdjust::Left; goto SET_ADJUST;
352 case SID_ATTR_PARA_ADJUST_RIGHT: eAdjst = SvxAdjust::Right; goto SET_ADJUST;
353 case SID_ATTR_PARA_ADJUST_CENTER: eAdjst = SvxAdjust::Center; goto SET_ADJUST;
354 case SID_ATTR_PARA_ADJUST_BLOCK: eAdjst = SvxAdjust::Block; goto SET_ADJUST;
355 SET_ADJUST:
357 aSet.Put(SvxAdjustItem(eAdjst,RES_PARATR_ADJUST));
358 rReq.AppendItem( SfxBoolItem( GetPool().GetWhichIDFromSlotID(nSlot), true ) );
360 break;
362 case SID_ATTR_PARA_LINESPACE:
363 if(pArgs && SfxItemState::SET == pArgs->GetItemState( GetPool().GetWhichIDFromSlotID(nSlot) ))
365 SvxLineSpacingItem aLineSpace = static_cast<const SvxLineSpacingItem&>( pArgs->Get(
366 GetPool().GetWhichIDFromSlotID(nSlot)));
367 aSet.Put( aLineSpace );
369 break;
370 case SID_ATTR_PARA_LINESPACE_10: ePropL = 100; goto SET_LINESPACE;
371 case SID_ATTR_PARA_LINESPACE_15: ePropL = 150; goto SET_LINESPACE;
372 case SID_ATTR_PARA_LINESPACE_115: ePropL = 115; goto SET_LINESPACE;
373 case SID_ATTR_PARA_LINESPACE_20: ePropL = 200; goto SET_LINESPACE;
375 SET_LINESPACE:
378 SvxLineSpacingItem aLineSpacing(ePropL, RES_PARATR_LINESPACING );
379 aLineSpacing.SetLineSpaceRule( SvxLineSpaceRule::Auto );
380 if( 100 == ePropL )
381 aLineSpacing.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
382 else
383 aLineSpacing.SetPropLineSpace(ePropL);
384 aSet.Put( aLineSpacing );
386 break;
388 case SID_ATTR_PARA_LEFT_TO_RIGHT :
389 case SID_ATTR_PARA_RIGHT_TO_LEFT :
391 SfxItemSetFixed<RES_PARATR_ADJUST, RES_PARATR_ADJUST> aAdjustSet( GetPool() );
392 GetShell().GetCurAttr(aAdjustSet);
393 bool bChgAdjust = false;
394 SfxItemState eAdjustState = aAdjustSet.GetItemState(RES_PARATR_ADJUST, false);
395 if(eAdjustState >= SfxItemState::DEFAULT)
397 SvxAdjust eAdjust =
398 aAdjustSet.Get(RES_PARATR_ADJUST).GetAdjust();
399 bChgAdjust = (SvxAdjust::Left == eAdjust && SID_ATTR_PARA_RIGHT_TO_LEFT == nSlot) ||
400 (SvxAdjust::Right == eAdjust && SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot);
402 else
403 bChgAdjust = true;
405 SvxFrameDirection eFrameDirection =
406 (SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot) ?
407 SvxFrameDirection::Horizontal_LR_TB : SvxFrameDirection::Horizontal_RL_TB;
408 aSet.Put( SvxFrameDirectionItem( eFrameDirection, RES_FRAMEDIR ) );
410 if (bChgAdjust)
412 SvxAdjust eAdjust = (SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot) ?
413 SvxAdjust::Left : SvxAdjust::Right;
414 SvxAdjustItem aAdjust( eAdjust, RES_PARATR_ADJUST );
415 aSet.Put( aAdjust );
416 aAdjust.SetWhich(SID_ATTR_PARA_ADJUST);
417 GetView().GetViewFrame().GetBindings().SetState( aAdjust );
418 // Toggle numbering alignment
419 const SwNumRule* pCurRule = GetShell().GetNumRuleAtCurrCursorPos();
420 if( pCurRule )
422 SvxNumRule aRule = pCurRule->MakeSvxNumRule();
424 for(sal_uInt16 i = 0; i < aRule.GetLevelCount(); i++)
426 SvxNumberFormat aFormat(aRule.GetLevel(i));
427 if(SvxAdjust::Left == aFormat.GetNumAdjust())
428 aFormat.SetNumAdjust( SvxAdjust::Right );
430 else if(SvxAdjust::Right == aFormat.GetNumAdjust())
431 aFormat.SetNumAdjust( SvxAdjust::Left );
433 aRule.SetLevel(i, aFormat, aRule.Get(i) != nullptr);
435 SwNumRule aSetRule( pCurRule->GetName(),
436 pCurRule->Get( 0 ).GetPositionAndSpaceMode() );
437 aSetRule.SetSvxRule( aRule, GetShell().GetDoc());
438 aSetRule.SetAutoRule( true );
439 // no start or continuation of a list - list style is only changed
440 GetShell().SetCurNumRule( aSetRule, false );
444 break;
445 case SID_ATTR_PARA_HYPHENZONE:
447 SfxItemSetFixed<RES_PARATR_HYPHENZONE, RES_PARATR_HYPHENZONE> aHyphSet( GetPool() );
448 GetShell().GetCurAttr(aHyphSet);
449 SfxItemState eState = aHyphSet.GetItemState(RES_PARATR_HYPHENZONE, false);
450 if ( eState >= SfxItemState::DEFAULT )
452 SvxHyphenZoneItem aHyphen( pArgs->Get( RES_PARATR_HYPHENZONE ) );
453 aSet.Put( aHyphen );
456 break;
458 default:
459 OSL_FAIL("wrong dispatcher");
460 return;
462 SwWrtShell& rWrtSh = GetShell();
463 SwTextFormatColl* pColl = rWrtSh.GetCurTextFormatColl();
464 if(pColl && pColl->IsAutoUpdateOnDirectFormat())
466 rWrtSh.AutoUpdatePara(pColl, aSet);
468 else
469 rWrtSh.SetAttrSet( aSet, SetAttrMode::DEFAULT, nullptr, true);
470 rReq.Done();
473 void SwTextShell::ExecParaAttrArgs(SfxRequest &rReq)
475 SwWrtShell &rSh = GetShell();
476 const SfxItemSet *pArgs = rReq.GetArgs();
477 const SfxPoolItem *pItem = nullptr;
479 sal_uInt16 nSlot = rReq.GetSlot();
480 if(pArgs)
481 pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem);
482 switch ( nSlot )
484 case FN_DROP_CHAR_STYLE_NAME:
485 if( pItem )
487 OUString sCharStyleName = static_cast<const SfxStringItem*>(pItem)->GetValue();
488 SfxItemSetFixed<RES_PARATR_DROP, RES_PARATR_DROP> aSet(GetPool());
489 rSh.GetCurAttr(aSet);
490 SwFormatDrop aDropItem(aSet.Get(RES_PARATR_DROP));
491 SwCharFormat* pFormat = nullptr;
492 if(!sCharStyleName.isEmpty())
493 pFormat = rSh.FindCharFormatByName( sCharStyleName );
494 aDropItem.SetCharFormat( pFormat );
495 aSet.Put(aDropItem);
496 rSh.SetAttrSet(aSet);
498 break;
499 case FN_FORMAT_DROPCAPS:
501 if(pItem)
503 rSh.SetAttrItem(*pItem);
504 rReq.Done();
506 else
508 SfxItemSetFixed<RES_PARATR_DROP, RES_PARATR_DROP,
509 HINT_END, HINT_END> aSet(GetPool());
510 rSh.GetCurAttr(aSet);
511 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
512 ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwDropCapsDialog(GetView().GetFrameWeld(), aSet));
513 if (pDlg->Execute() == RET_OK)
515 rSh.StartAction();
516 rSh.StartUndo( SwUndoId::START );
517 if ( const SfxStringItem* pHintItem = aSet.GetItemIfSet(HINT_END,false) )
519 if ( !pHintItem->GetValue().isEmpty() )
520 rSh.ReplaceDropText(pHintItem->GetValue());
522 rSh.SetAttrSet(*pDlg->GetOutputItemSet());
523 rSh.EndUndo( SwUndoId::END );
524 rSh.EndAction();
525 rReq.Done(*pDlg->GetOutputItemSet());
529 break;
530 case SID_ATTR_PARA_PAGEBREAK:
531 if(pItem)
533 rSh.SetAttrItem( *pItem );
534 rReq.Done();
536 break;
537 case SID_ATTR_PARA_MODEL:
539 if(pItem)
541 SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC,
542 SID_ATTR_PARA_MODEL, SID_ATTR_PARA_MODEL> aCoreSet( GetPool() );
543 aCoreSet.Put(*pItem);
544 SfxToSwPageDescAttr( rSh, aCoreSet);
545 rSh.SetAttrSet(aCoreSet);
546 rReq.Done();
549 break;
551 default:
552 OSL_FAIL("wrong dispatcher");
553 return;
557 void SwTextShell::GetAttrState(SfxItemSet &rSet)
559 SwWrtShell &rSh = GetShell();
560 SfxItemPool& rPool = GetPool();
561 SfxItemSet aCoreSet(rPool, aTextFormatCollSetRange);
562 // Request *all* text attributes from the core.
563 // fdo#78737: this is called from SvxRuler, which requires the list indents!
564 rSh.GetCurAttr(aCoreSet, /* bMergeIndentValuesOfNumRule = */ true);
566 SfxWhichIter aIter(rSet);
567 sal_uInt16 nSlot = aIter.FirstWhich();
568 bool bFlag = false;
569 SfxBoolItem aFlagItem;
570 const SfxPoolItem* pItem = nullptr;
571 SvxAdjust eAdjust = SvxAdjust::Left;
572 bool bAdjustGood = false;
573 SfxItemState eState = aCoreSet.GetItemState(RES_PARATR_ADJUST, false, &pItem);
575 if( SfxItemState::DEFAULT == eState )
576 pItem = &rPool.GetUserOrPoolDefaultItem(RES_PARATR_ADJUST);
577 if( SfxItemState::DEFAULT <= eState )
579 eAdjust = static_cast<const SvxAdjustItem* >( pItem)->GetAdjust();
580 bAdjustGood = true;
583 short nEsc = 0;
584 eState = aCoreSet.GetItemState(RES_CHRATR_ESCAPEMENT, false, &pItem);
585 if( SfxItemState::DEFAULT == eState )
586 pItem = &rPool.GetUserOrPoolDefaultItem(RES_CHRATR_ESCAPEMENT);
587 if( eState >= SfxItemState::DEFAULT )
588 nEsc = static_cast<const SvxEscapementItem* >(pItem)->GetEsc();
590 sal_uInt16 nLineSpace = 0;
591 eState = aCoreSet.GetItemState(RES_PARATR_LINESPACING, false, &pItem);
592 if( SfxItemState::DEFAULT == eState )
593 pItem = &rPool.GetUserOrPoolDefaultItem(RES_PARATR_LINESPACING);
594 if( SfxItemState::DEFAULT <= eState &&
595 static_cast<const SvxLineSpacingItem* >(pItem)->GetLineSpaceRule() == SvxLineSpaceRule::Auto )
597 if(SvxInterLineSpaceRule::Off ==
598 static_cast<const SvxLineSpacingItem* >(pItem)->GetInterLineSpaceRule())
599 nLineSpace = 100;
600 else
601 nLineSpace = static_cast<const SvxLineSpacingItem* >(pItem)->GetPropLineSpace();
604 SvxCaseMap eCaseMap = SvxCaseMap::NotMapped;
605 eState = aCoreSet.GetItemState(RES_CHRATR_CASEMAP, false, &pItem);
606 if (eState == SfxItemState::DEFAULT)
607 pItem = &rPool.GetUserOrPoolDefaultItem(RES_CHRATR_CASEMAP);
608 if (eState >= SfxItemState::DEFAULT)
609 eCaseMap = static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap();
611 while (nSlot)
613 switch(nSlot)
615 case FN_SET_SUPER_SCRIPT:
616 bFlag = 0 < nEsc;
617 break;
618 case FN_SET_SUB_SCRIPT:
619 bFlag = 0 > nEsc;
620 break;
621 case FN_SET_SMALL_CAPS:
622 bFlag = eCaseMap == SvxCaseMap::SmallCaps;
623 break;
624 case SID_ATTR_PARA_ADJUST_LEFT:
625 if (!bAdjustGood)
627 rSet.InvalidateItem( nSlot );
628 nSlot = 0;
630 else
631 bFlag = SvxAdjust::Left == eAdjust;
632 break;
633 case SID_ATTR_PARA_ADJUST_RIGHT:
634 if (!bAdjustGood)
636 rSet.InvalidateItem( nSlot );
637 nSlot = 0;
639 else
640 bFlag = SvxAdjust::Right == eAdjust;
641 break;
642 case SID_ATTR_PARA_ADJUST_CENTER:
643 if (!bAdjustGood)
645 rSet.InvalidateItem( nSlot );
646 nSlot = 0;
648 else
649 bFlag = SvxAdjust::Center == eAdjust;
650 break;
651 case SID_ATTR_PARA_ADJUST_BLOCK:
653 if (!bAdjustGood)
655 rSet.InvalidateItem( nSlot );
656 nSlot = 0;
658 else
660 bFlag = SvxAdjust::Block == eAdjust;
661 sal_uInt16 nHtmlMode = GetHtmlMode(rSh.GetView().GetDocShell());
662 if((nHtmlMode & HTMLMODE_ON) && !(nHtmlMode & HTMLMODE_FULL_STYLES ))
664 rSet.DisableItem( nSlot );
665 nSlot = 0;
669 break;
670 case SID_ATTR_PARA_LINESPACE_10:
671 bFlag = nLineSpace == 100;
672 break;
673 case SID_ATTR_PARA_LINESPACE_115:
674 bFlag = nLineSpace == 115;
675 break;
676 case SID_ATTR_PARA_LINESPACE_15:
677 bFlag = nLineSpace == 150;
678 break;
679 case SID_ATTR_PARA_LINESPACE_20:
680 bFlag = nLineSpace == 200;
681 break;
682 case FN_GROW_FONT_SIZE:
683 case FN_SHRINK_FONT_SIZE:
685 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT,
686 *rSet.GetPool() );
687 aSetItem.GetItemSet().Put( aCoreSet, false );
688 const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>(
689 aSetItem.GetItemOfScript( rSh.GetScriptType() ) ) );
691 if( pSize ) // selection is of one size
693 sal_uInt32 nSize = pSize->GetHeight();
694 if( nSize == nFontMaxSz )
695 rSet.DisableItem( FN_GROW_FONT_SIZE );
696 else if( nSize == nFontInc )
697 rSet.DisableItem( FN_SHRINK_FONT_SIZE );
699 else
701 std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >>
702 vFontHeight = rSh.GetItemWithPaM( RES_CHRATR_FONTSIZE );
703 for ( const std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM>>& aIt : vFontHeight )
705 if (!aIt.first)
707 rSet.DisableItem(FN_GROW_FONT_SIZE);
708 rSet.DisableItem(FN_SHRINK_FONT_SIZE);
709 break;
711 pSize = static_cast<const SvxFontHeightItem*>( aIt.first );
712 sal_uInt32 nSize = pSize->GetHeight();
713 if( nSize == nFontMaxSz )
714 rSet.DisableItem( FN_GROW_FONT_SIZE );
715 else if( nSize == nFontInc )
716 rSet.DisableItem( FN_SHRINK_FONT_SIZE );
719 nSlot = 0;
721 break;
722 case SID_ULINE_VAL_NONE:
723 case SID_ULINE_VAL_SINGLE:
724 case SID_ULINE_VAL_DOUBLE:
725 case SID_ULINE_VAL_DOTTED:
727 eState = aCoreSet.GetItemState(RES_CHRATR_UNDERLINE);
728 if( eState >= SfxItemState::DEFAULT )
730 FontLineStyle eLineStyle = aCoreSet.Get(RES_CHRATR_UNDERLINE).GetLineStyle();
732 switch (nSlot)
734 case SID_ULINE_VAL_NONE:
735 rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_NONE));
736 break;
737 case SID_ULINE_VAL_SINGLE:
738 rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_SINGLE));
739 break;
740 case SID_ULINE_VAL_DOUBLE:
741 rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_DOUBLE));
742 break;
743 case SID_ULINE_VAL_DOTTED:
744 rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_DOTTED));
745 break;
748 else
749 rSet.InvalidateItem(nSlot);
750 nSlot = 0;
752 break;
753 case SID_ATTR_PARA_ADJUST:
754 if (!bAdjustGood)
755 rSet.InvalidateItem( nSlot );
756 else
757 rSet.Put(SvxAdjustItem(eAdjust, SID_ATTR_PARA_ADJUST ));
758 nSlot = 0;
759 break;
760 case SID_ATTR_PARA_LRSPACE:
761 case SID_ATTR_PARA_LEFTSPACE:
762 case SID_ATTR_PARA_RIGHTSPACE:
763 case SID_ATTR_PARA_FIRSTLINESPACE:
765 eState = aCoreSet.GetItemState(RES_MARGIN_FIRSTLINE);
766 eState = std::min(aCoreSet.GetItemState(RES_MARGIN_TEXTLEFT), eState);
767 eState = std::min(aCoreSet.GetItemState(RES_MARGIN_RIGHT), eState);
768 if( eState >= SfxItemState::DEFAULT )
770 SvxLRSpaceItem aLR(RES_LR_SPACE);
771 SvxFirstLineIndentItem const& rFirstLine(aCoreSet.Get(RES_MARGIN_FIRSTLINE));
772 SvxTextLeftMarginItem const& rLeftMargin(aCoreSet.Get(RES_MARGIN_TEXTLEFT));
773 SvxRightMarginItem const& rRightMargin(aCoreSet.Get(RES_MARGIN_RIGHT));
775 aLR.SetTextFirstLineOffset(rFirstLine.GetTextFirstLineOffset(),
776 rFirstLine.GetPropTextFirstLineOffset());
777 aLR.SetAutoFirst(rFirstLine.IsAutoFirst());
778 aLR.SetTextLeft(rLeftMargin.GetTextLeft(), rLeftMargin.GetPropLeft());
779 aLR.SetRight(rRightMargin.GetRight(), rRightMargin.GetPropRight());
780 aLR.SetWhich(nSlot);
781 rSet.Put(aLR);
783 else
784 rSet.InvalidateItem(nSlot);
785 nSlot = 0;
787 break;
789 case SID_ATTR_PARA_LEFT_TO_RIGHT :
790 case SID_ATTR_PARA_RIGHT_TO_LEFT :
792 if ( !SvtCTLOptions::IsCTLFontEnabled() )
794 rSet.DisableItem( nSlot );
795 nSlot = 0;
797 else
799 // is the item set?
800 sal_uInt16 nHtmlMode = GetHtmlMode(rSh.GetView().GetDocShell());
801 if((!(nHtmlMode & HTMLMODE_ON) || (0 != (nHtmlMode & HTMLMODE_SOME_STYLES))) &&
802 aCoreSet.GetItemState( RES_FRAMEDIR, false ) >= SfxItemState::DEFAULT)
804 SvxFrameDirection eFrameDir =
805 aCoreSet.Get(RES_FRAMEDIR).GetValue();
806 if (SvxFrameDirection::Environment == eFrameDir)
808 eFrameDir = rSh.IsInRightToLeftText() ?
809 SvxFrameDirection::Horizontal_RL_TB : SvxFrameDirection::Horizontal_LR_TB;
811 bFlag = (SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot &&
812 SvxFrameDirection::Horizontal_LR_TB == eFrameDir) ||
813 (SID_ATTR_PARA_RIGHT_TO_LEFT == nSlot &&
814 SvxFrameDirection::Horizontal_RL_TB == eFrameDir);
816 else
818 rSet.InvalidateItem(nSlot);
819 nSlot = 0;
823 break;
825 case SID_ATTR_CHAR_LANGUAGE:
826 case SID_ATTR_CHAR_KERNING:
827 case RES_PARATR_DROP:
829 rSet.Put(aCoreSet.Get( GetPool().GetWhichIDFromSlotID(nSlot)));
830 nSlot = 0;
832 break;
833 case SID_ATTR_PARA_MODEL:
835 SfxItemSetFixed
836 <RES_PAGEDESC,RES_PAGEDESC,
837 SID_ATTR_PARA_MODEL,SID_ATTR_PARA_MODEL> aTemp(GetPool());
838 aTemp.Put(aCoreSet);
839 ::SwToSfxPageDescAttr(aTemp);
840 rSet.Put(aTemp.Get(SID_ATTR_PARA_MODEL));
841 nSlot = 0;
843 break;
844 case RES_TXTATR_INETFMT:
846 SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
847 rSh.GetCurAttr(aSet);
848 const SfxPoolItem& rItem = aSet.Get(RES_TXTATR_INETFMT);
849 rSet.Put(rItem);
850 nSlot = 0;
852 break;
853 case FN_NO_BREAK:
855 SfxItemSetFixed<RES_CHRATR_NOHYPHEN, RES_CHRATR_NOHYPHEN> aSet(GetPool());
856 rSh.GetCurAttr(aSet);
857 const SfxPoolItem& rItem = aSet.Get(RES_CHRATR_NOHYPHEN);
859 SwWrtShell& rWrtSh = GetShell();
860 // add "No Break" menu item to the context menu, if the word
861 // has "no break" setting, or it is hyphenated
862 if ( static_cast<const SvxNoHyphenItem&>(rItem).GetValue() || ( rWrtSh.GetCursor()
863 && rWrtSh.GetCursor()->IsInHyphenatedWord(*rWrtSh.GetLayout()) ) )
865 rSet.Put(rItem);
867 else
868 rSet.DisableItem(nSlot);
869 nSlot = 0;
871 break;
872 default:
873 // Do nothing
874 nSlot = 0;
875 break;
878 if( nSlot )
880 aFlagItem.SetWhich( nSlot );
881 aFlagItem.SetValue( bFlag );
882 rSet.Put( aFlagItem );
884 nSlot = aIter.NextWhich();
887 rSet.Put(aCoreSet,false);
890 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */