LibreOffice Module sw (master)  1
txtnum.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sfx2/request.hxx>
21 #include <svl/eitem.hxx>
22 #include <svl/stritem.hxx>
23 #include <editeng/numitem.hxx>
24 #include <editeng/brushitem.hxx>
25 #include <osl/diagnose.h>
26 #include <numrule.hxx>
27 
28 #include <cmdid.h>
29 #include <wrtsh.hxx>
30 #include <view.hxx>
31 #include <viewopt.hxx>
32 #include <wdocsh.hxx>
33 #include <poolfmt.hxx>
34 #include <textsh.hxx>
35 #include <swabstdlg.hxx>
36 #include <SwStyleNameMapper.hxx>
37 #include <sfx2/tabdlg.hxx>
38 #include <svx/nbdtmg.hxx>
39 #include <svx/nbdtmgfact.hxx>
40 #include <sfx2/viewfrm.hxx>
41 #include <sfx2/bindings.hxx>
42 #include <memory>
43 
45 {
46  //Because the record before any shell exchange.
47  switch(rReq.GetSlot())
48  {
49  case FN_NUM_NUMBERING_ON:
50  {
52  const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
53  bool bMode = !GetShell().SelectionHasNumber(); // #i29560#
54  if ( pItem )
55  bMode = pItem->GetValue();
56  else
57  rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bMode ) );
58 
59  if ( bMode != (GetShell().SelectionHasNumber()) ) // #i29560#
60  {
61  rReq.Done();
62  if( bMode )
63  GetShell().NumOn();
64  else
65  GetShell().NumOrBulletOff(); // #i29560#
66  }
67  bool bNewResult = GetShell().SelectionHasNumber();
68  if (bNewResult!=bMode) {
69  SfxBindings& rBindings = GetView().GetViewFrame()->GetBindings();
70  SfxBoolItem aItem(FN_NUM_NUMBERING_ON,!bNewResult);
71  rBindings.SetState(aItem);
72  SfxBoolItem aNewItem(FN_NUM_NUMBERING_ON,bNewResult);
73  rBindings.SetState(aNewItem);
74  }
76  }
77  break;
78  case FN_NUM_BULLET_ON:
79  {
81  const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
82  bool bMode = !GetShell().SelectionHasBullet(); // #i29560#
83  if ( pItem )
84  bMode = pItem->GetValue();
85  else
86  rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bMode ) );
87 
88  if ( bMode != (GetShell().SelectionHasBullet()) ) // #i29560#
89  {
90  rReq.Done();
91  if( bMode )
92  GetShell().BulletOn();
93  else
94  GetShell().NumOrBulletOff(); // #i29560#
95  }
96  bool bNewResult = GetShell().SelectionHasBullet();
97  if (bNewResult!=bMode) {
98  SfxBindings& rBindings = GetView().GetViewFrame()->GetBindings();
99  SfxBoolItem aItem(FN_NUM_BULLET_ON,!bNewResult);
100  rBindings.SetState(aItem);
101  SfxBoolItem aNewItem(FN_NUM_BULLET_ON,bNewResult);
102  rBindings.SetState(aNewItem);
103  }
105  }
106  break;
107 
108  case FN_NUM_BULLET_OFF:
109  {
111  SfxRequest aReq(GetView().GetViewFrame(), FN_NUM_BULLET_ON);
112  aReq.AppendItem(SfxBoolItem(FN_PARAM_1, false));
113  aReq.Done();
115  GetShell().DelNumRules();
117  }
118  break;
119 
120  case FN_NUMBER_BULLETS:
121  case SID_OUTLINE_BULLET:
122  {
123  SfxItemSet aSet( GetPool(),
124  svl::Items<SID_HTML_MODE, SID_HTML_MODE,
125  SID_ATTR_NUMBERING_RULE, SID_PARAM_CUR_NUM_LEVEL>{} );
126  SwDocShell* pDocSh = GetView().GetDocShell();
127  const bool bHtml = dynamic_cast<SwWebDocShell*>( pDocSh ) != nullptr;
128  const SwNumRule* pNumRuleAtCurrentSelection = GetShell().GetNumRuleAtCurrentSelection();
129  if ( pNumRuleAtCurrentSelection != nullptr )
130  {
131  SvxNumRule aRule = pNumRuleAtCurrentSelection->MakeSvxNumRule();
132 
133  //convert type of linked bitmaps from SVX_NUM_BITMAP to (SVX_NUM_BITMAP|LINK_TOKEN)
134  for ( sal_uInt16 i = 0; i < aRule.GetLevelCount(); i++ )
135  {
136  SvxNumberFormat aFormat( aRule.GetLevel( i ) );
137  if ( SVX_NUM_BITMAP == aFormat.GetNumberingType() )
138  {
139  const SvxBrushItem* pBrush = aFormat.GetBrush();
140  if(pBrush && !pBrush->GetGraphicLink().isEmpty())
141  aFormat.SetNumberingType(SvxNumType(SVX_NUM_BITMAP|LINK_TOKEN));
142  aRule.SetLevel(i, aFormat, aRule.Get(i) != nullptr);
143  }
144  }
145  if(bHtml)
146  aRule.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP, false);
147 
148  aSet.Put(SvxNumBulletItem(aRule));
149  OSL_ENSURE( GetShell().GetNumLevel() < MAXLEVEL,
150  "<SwTextShell::ExecEnterNum()> - numbered node without valid list level. Serious defect." );
151  sal_uInt16 nLevel = GetShell().GetNumLevel();
152  if( nLevel < MAXLEVEL )
153  {
154  nLevel = 1 << nLevel;
155  aSet.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL, nLevel ) );
156  }
157  }
158  else
159  {
160  SwNumRule aRule( GetShell().GetUniqueNumRuleName(),
161  // #i89178#
163  SvxNumRule aSvxRule = aRule.MakeSvxNumRule();
164  const bool bRightToLeft = GetShell().IsInRightToLeftText();
165 
166  if ( bHtml || bRightToLeft )
167  {
168  for ( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
169  {
170  SvxNumberFormat aFormat( aSvxRule.GetLevel( n ) );
171  if ( n && bHtml )
172  {
173  // 1/2" for HTML
174  aFormat.SetAbsLSpace(n * 720);
175  }
176  // #i38904# Default alignment for
177  // numbering/bullet should be rtl in rtl paragraph:
178  if ( bRightToLeft )
179  {
180  aFormat.SetNumAdjust( SvxAdjust::Right );
181  }
182  aSvxRule.SetLevel( n, aFormat, false );
183  }
184  aSvxRule.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP, false);
185  }
186  aSet.Put( SvxNumBulletItem( aSvxRule ) );
187  }
188 
189  aSet.Put( SfxBoolItem( SID_PARAM_NUM_PRESET,false ));
190 
191  // Before the dialogue of the HTML mode will be dropped at the Docshell.
192  pDocSh->PutItem(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(pDocSh)));
193 
195  weld::Window *pParent = rReq.GetFrameWeld();
196  VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSvxNumBulletTabDialog(pParent, &aSet, GetShell()));
197  const SfxStringItem* pPageItem = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
198  if ( pPageItem )
199  pDlg->SetCurPageId( OUStringToOString( pPageItem->GetValue(), RTL_TEXTENCODING_UTF8 ) );
200 
201  auto pRequest = std::make_shared<SfxRequest>(rReq);
202  rReq.Ignore(); // the 'old' request is not relevant any more
203 
204  pDlg->StartExecuteAsync([aSet, pDlg, pNumRuleAtCurrentSelection, pRequest, this](sal_Int32 nResult){
205  if (RET_OK == nResult)
206  {
207  const SfxPoolItem* pItem;
208  if (SfxItemState::SET == pDlg->GetOutputItemSet()->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem))
209  {
210  pRequest->AppendItem(*pItem);
211  pRequest->Done();
212  SvxNumRule& rSetRule = const_cast<SvxNumRule&>(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule());
213  rSetRule.UnLinkGraphics();
214  SwNumRule aSetRule(pNumRuleAtCurrentSelection != nullptr
215  ? pNumRuleAtCurrentSelection->GetName()
218  aSetRule.SetSvxRule(rSetRule, GetShell().GetDoc());
219  aSetRule.SetAutoRule(true);
220  // No start of new list, if an existing list style is edited.
221  // Otherwise start a new list.
222  const bool bCreateList = (pNumRuleAtCurrentSelection == nullptr);
223  GetShell().SetCurNumRule(aSetRule, bCreateList);
224  }
225  // If the Dialog was leaved with OK but nothing was chosen then the
226  // numbering must be at least activated, if it is not already.
227  else if (pNumRuleAtCurrentSelection == nullptr
228  && SfxItemState::SET == aSet.GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem))
229  {
230  pRequest->AppendItem(*pItem);
231  pRequest->Done();
232  const SvxNumRule& rSetRule = static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule();
233  SwNumRule aSetRule(
234  GetShell().GetUniqueNumRuleName(),
236  aSetRule.SetSvxRule(rSetRule, GetShell().GetDoc());
237  aSetRule.SetAutoRule(true);
238  // start new list
239  GetShell().SetCurNumRule(aSetRule, true);
240  }
241  }
242  else if (RET_USER == nResult)
243  GetShell().DelNumRules();
244  pDlg->disposeOnce();
245  });
246  }
247  break;
248 
249  default:
250  OSL_FAIL("wrong dispatcher");
251  return;
252  }
253 }
254 
255 
257 {
258  const sal_uInt16 nSlot = rReq.GetSlot();
259  switch ( nSlot )
260  {
261  case FN_SVX_SET_NUMBER:
262  case FN_SVX_SET_BULLET:
263  case FN_SVX_SET_OUTLINE:
264  {
265  const SfxUInt16Item* pItem = rReq.GetArg<SfxUInt16Item>(nSlot);
266  if ( pItem != nullptr )
267  {
268  const sal_uInt16 nChosenItemIdx = pItem->GetValue();
270  if ( nSlot == FN_SVX_SET_NUMBER )
272  else if ( nSlot == FN_SVX_SET_OUTLINE )
274 
276 
277  if ( pNBOTypeMgr != nullptr )
278  {
279  const SwNumRule* pNumRuleAtCurrentSelection = GetShell().GetNumRuleAtCurrentSelection();
280  sal_uInt16 nActNumLvl = USHRT_MAX;
281  if ( pNumRuleAtCurrentSelection != nullptr )
282  {
283  const sal_uInt16 nLevel = GetShell().GetNumLevel();
284  if ( nLevel < MAXLEVEL )
285  {
286  nActNumLvl = 1 << nLevel;
287  }
288  }
289  SwNumRule aNewNumRule(
290  pNumRuleAtCurrentSelection != nullptr ? pNumRuleAtCurrentSelection->GetName() : GetShell().GetUniqueNumRuleName(),
292  SvxNumRule aNewSvxNumRule = pNumRuleAtCurrentSelection != nullptr
293  ? pNumRuleAtCurrentSelection->MakeSvxNumRule()
294  : aNewNumRule.MakeSvxNumRule();
295 
296  OUString aNumCharFormat, aBulletCharFormat;
299 
300  SfxAllItemSet aSet( GetPool() );
301  aSet.Put( SfxStringItem( SID_NUM_CHAR_FMT, aNumCharFormat ) );
302  aSet.Put( SfxStringItem( SID_BULLET_CHAR_FMT, aBulletCharFormat ) );
303  aSet.Put( SvxNumBulletItem( aNewSvxNumRule, SID_ATTR_NUMBERING_RULE ) );
304 
305  pNBOTypeMgr->SetItems( &aSet );
306  pNBOTypeMgr->ApplyNumRule( aNewSvxNumRule, nChosenItemIdx - 1, nActNumLvl );
307 
308  aNewNumRule.SetSvxRule( aNewSvxNumRule, GetShell().GetDoc() );
309  aNewNumRule.SetAutoRule( true );
310  const bool bCreateNewList = ( pNumRuleAtCurrentSelection == nullptr );
311  GetShell().SetCurNumRule( aNewNumRule, bCreateNewList );
312  }
313  }
314  }
315  break;
316 
317  default:
318  OSL_ENSURE(false, "wrong Dispatcher");
319  return;
320  }
321 }
322 
323 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void UnLinkGraphics()
SfxViewFrame * GetViewFrame() const
bool GetValue() const
SwView & GetView()
Definition: basesh.hxx:59
void BulletOn()
Definition: wrtsh1.cxx:1427
void SetState(const SfxItemSet &rSet)
void SetAutoRule(bool bFlag)
Definition: numrule.hxx:231
OUString GetUniqueNumRuleName() const
Definition: ednumber.cxx:816
static void FillUIName(const OUString &rName, OUString &rFillName, SwGetPoolIdFromName)
SwWrtShell & GetShell()
Definition: basesh.cxx:2760
sal_Int64 n
const SvxNumberFormat * Get(sal_uInt16 nLevel) const
sal_uInt16 GetValue() const
bool SelectionHasNumber() const
Definition: ednumber.cxx:152
const OUString & GetName() const
Definition: numrule.hxx:225
void Done(bool bRemove=false)
NBOTypeMgrBase * CreateInstance(const NBOType aType)
void EndAllAction()
Definition: edws.cxx:97
sal_uInt8 GetNumLevel() const
Definition: ednumber.cxx:702
SvxNumType
void SetCurNumRule(const SwNumRule &, const bool bCreateNewList, const OUString &sContinuedListId=OUString(), const bool bResetIndentAttrs=false)
Optional parameter (default value false).
Definition: ednumber.cxx:771
#define FN_NUMBER_BULLETS
Definition: cmdid.h:73
#define FN_NUM_BULLET_OFF
Definition: cmdid.h:89
virtual VclPtr< SfxAbstractTabDialog > CreateSvxNumBulletTabDialog(weld::Window *pParent, const SfxItemSet *pSwItemSet, SwWrtShell &)=0
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
Numbering symbols.
Definition: poolfmt.hxx:117
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
void DelNumRules()
Delete, split enumeration list.
Definition: ednumber.cxx:280
SfxItemPool & GetPool() const
SvxNumRule MakeSvxNumRule() const
Definition: number.cxx:911
void NumOn()
Definition: wrtsh1.cxx:1376
void SetFeatureFlag(SvxNumRuleFlags nFlag, bool bSet=true)
SVX_NUM_BITMAP
bool IsInRightToLeftText() const
Definition: crsrsh.cxx:3442
int i
void ExecEnterNum(SfxRequest &)
Definition: txtnum.cxx:44
SfxBindings & GetBindings()
sal_uInt16 GetHtmlMode(const SwDocShell *pShell)
Definition: viewopt.cxx:354
const T * GetArg(sal_uInt16 nSlotId) const
const SvxNumberFormat & GetLevel(sal_uInt16 nLevel) const
sal_uInt16 GetLevelCount() const
void NumOrBulletOff()
Definition: wrtsh1.cxx:1381
static SwAbstractDialogFactory * Create()
Definition: swabstdlg.cxx:36
SwDocShell * GetDocShell()
Definition: view.cxx:1122
const SwNumRule * GetNumRuleAtCurrentSelection() const
Returns the numbering rule found at the paragraphs of the current selection, if all paragraphs of the...
Definition: ednumber.cxx:733
bool SelectionHasBullet() const
Definition: ednumber.cxx:201
const OUString & GetGraphicLink() const
weld::Window * GetFrameWeld() const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_uInt16 GetSlot() const
#define RET_USER
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
Definition: number.cxx:1505
#define LINK_TOKEN
unsigned char sal_uInt8
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:249
RET_OK
void SetSvxRule(const SvxNumRule &, SwDoc *pDoc)
Definition: number.cxx:899
void ExecSetNumber(SfxRequest const &)
Definition: txtnum.cxx:256
void AppendItem(const SfxPoolItem &)
void SetAbsLSpace(sal_Int32 nSet)
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
void Ignore()
SwNumRule * GetNumRule(SwTextFormatColl &rTextFormatColl)
determines the list style, which directly set at the given paragraph style
Definition: fmtcol.cxx:76
virtual void ApplyNumRule(SvxNumRule &aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool isDefault=false, bool isResetSize=false)=0
void SetLevel(sal_uInt16 nLevel, const SvxNumberFormat &rFmt, bool bIsValid=true)
void SetItems(const SfxItemSet *pArg)