1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <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>
31 #include <viewopt.hxx>
33 #include <poolfmt.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>
44 void SwTextShell::ExecEnterNum(SfxRequest
&rReq
)
46 //Because the record before any shell exchange.
47 switch(rReq
.GetSlot())
49 case FN_NUM_NUMBERING_ON
:
51 GetShell().StartAllAction();
52 const SfxBoolItem
* pItem
= rReq
.GetArg
<SfxBoolItem
>(FN_PARAM_1
);
53 bool bMode
= !GetShell().SelectionHasNumber(); // #i29560#
55 bMode
= pItem
->GetValue();
57 rReq
.AppendItem( SfxBoolItem( FN_PARAM_1
, bMode
) );
59 if ( bMode
!= (GetShell().SelectionHasNumber()) ) // #i29560#
65 GetShell().NumOrBulletOff(); // #i29560#
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
);
75 GetShell().EndAllAction();
78 case FN_NUM_BULLET_ON
:
80 GetShell().StartAllAction();
81 const SfxBoolItem
* pItem
= rReq
.GetArg
<SfxBoolItem
>(FN_PARAM_1
);
82 bool bMode
= !GetShell().SelectionHasBullet(); // #i29560#
84 bMode
= pItem
->GetValue();
86 rReq
.AppendItem( SfxBoolItem( FN_PARAM_1
, bMode
) );
88 if ( bMode
!= (GetShell().SelectionHasBullet()) ) // #i29560#
92 GetShell().BulletOn();
94 GetShell().NumOrBulletOff(); // #i29560#
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
);
104 GetShell().EndAllAction();
108 case FN_NUM_BULLET_OFF
:
110 GetShell().StartAllAction();
111 SfxRequest
aReq(GetView().GetViewFrame(), FN_NUM_BULLET_ON
);
112 aReq
.AppendItem(SfxBoolItem(FN_PARAM_1
, false));
114 GetShell().DelNumRules();
115 GetShell().EndAllAction();
119 case FN_NUMBER_BULLETS
:
120 case SID_OUTLINE_BULLET
:
122 SfxItemSetFixed
<SID_HTML_MODE
, SID_HTML_MODE
,
123 SID_ATTR_NUMBERING_RULE
, SID_PARAM_CUR_NUM_LEVEL
> aSet( GetPool() );
124 SwDocShell
* pDocSh
= GetView().GetDocShell();
125 const bool bHtml
= dynamic_cast<SwWebDocShell
*>( pDocSh
) != nullptr;
126 const SwNumRule
* pNumRuleAtCurrentSelection
= GetShell().GetNumRuleAtCurrentSelection();
127 if ( pNumRuleAtCurrentSelection
!= nullptr )
129 SvxNumRule aRule
= pNumRuleAtCurrentSelection
->MakeSvxNumRule();
131 //convert type of linked bitmaps from SVX_NUM_BITMAP to (SVX_NUM_BITMAP|LINK_TOKEN)
132 for ( sal_uInt16 i
= 0; i
< aRule
.GetLevelCount(); i
++ )
134 SvxNumberFormat
aFormat( aRule
.GetLevel( i
) );
135 if ( SVX_NUM_BITMAP
== aFormat
.GetNumberingType() )
137 const SvxBrushItem
* pBrush
= aFormat
.GetBrush();
138 if(pBrush
&& !pBrush
->GetGraphicLink().isEmpty())
139 aFormat
.SetNumberingType(SvxNumType(SVX_NUM_BITMAP
|LINK_TOKEN
));
140 aRule
.SetLevel(i
, aFormat
, aRule
.Get(i
) != nullptr);
144 aRule
.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP
, false);
146 aSet
.Put(SvxNumBulletItem(aRule
));
147 OSL_ENSURE( GetShell().GetNumLevel() < MAXLEVEL
,
148 "<SwTextShell::ExecEnterNum()> - numbered node without valid list level. Serious defect." );
149 sal_uInt16 nLevel
= GetShell().GetNumLevel();
150 if( nLevel
< MAXLEVEL
)
152 nLevel
= 1 << nLevel
;
153 aSet
.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL
, nLevel
) );
158 SwNumRule
aRule( GetShell().GetUniqueNumRuleName(),
160 numfunc::GetDefaultPositionAndSpaceMode() );
161 SvxNumRule aSvxRule
= aRule
.MakeSvxNumRule();
162 const bool bRightToLeft
= GetShell().IsInRightToLeftText();
164 if ( bHtml
|| bRightToLeft
)
166 for ( sal_uInt8 n
= 0; n
< MAXLEVEL
; ++n
)
168 SvxNumberFormat
aFormat( aSvxRule
.GetLevel( n
) );
172 aFormat
.SetAbsLSpace(n
* 720);
174 // #i38904# Default alignment for
175 // numbering/bullet should be rtl in rtl paragraph:
178 aFormat
.SetNumAdjust( SvxAdjust::Right
);
180 aSvxRule
.SetLevel( n
, aFormat
, false );
182 aSvxRule
.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP
, false);
184 aSet
.Put( SvxNumBulletItem( std::move(aSvxRule
) ) );
187 aSet
.Put( SfxBoolItem( SID_PARAM_NUM_PRESET
,false ));
189 // Before the dialogue of the HTML mode will be dropped at the Docshell.
190 pDocSh
->PutItem(SfxUInt16Item(SID_HTML_MODE
, ::GetHtmlMode(pDocSh
)));
192 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
193 weld::Window
*pParent
= rReq
.GetFrameWeld();
194 VclPtr
<AbstractNumBulletDialog
> pDlg(pFact
->CreateSvxNumBulletTabDialog(pParent
, aSet
, GetShell()));
195 const SfxStringItem
* pPageItem
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
197 pDlg
->SetCurPageId( pPageItem
->GetValue() );
199 auto xRequest
= std::make_shared
<SfxRequest
>(rReq
);
200 rReq
.Ignore(); // the 'old' request is not relevant any more
202 pDlg
->StartExecuteAsync([pDlg
, pNumRuleAtCurrentSelection
, xRequest
=std::move(xRequest
), this](sal_Int32 nResult
){
203 if (RET_OK
== nResult
)
205 const SvxNumBulletItem
* pBulletItem
= pDlg
->GetOutputItemSet()->GetItemIfSet(SID_ATTR_NUMBERING_RULE
, false);
208 xRequest
->AppendItem(*pBulletItem
);
210 SvxNumRule
& rSetRule
= const_cast<SvxNumRule
&>(pBulletItem
->GetNumRule());
211 rSetRule
.UnLinkGraphics();
212 SwNumRule
aSetRule(pNumRuleAtCurrentSelection
!= nullptr
213 ? pNumRuleAtCurrentSelection
->GetName()
214 : GetShell().GetUniqueNumRuleName(),
215 numfunc::GetDefaultPositionAndSpaceMode());
216 aSetRule
.SetSvxRule(rSetRule
, GetShell().GetDoc());
217 aSetRule
.SetAutoRule(true);
218 // No start of new list, if an existing list style is edited.
219 // Otherwise start a new list.
220 const bool bCreateList
= (pNumRuleAtCurrentSelection
== nullptr);
221 GetShell().SetCurNumRule(aSetRule
, bCreateList
);
223 // If the Dialog was leaved with OK but nothing was chosen then the
224 // numbering must be at least activated, if it is not already.
225 else if (pNumRuleAtCurrentSelection
== nullptr
226 && (pBulletItem
= pDlg
->GetInputItemSet()->GetItemIfSet(SID_ATTR_NUMBERING_RULE
, false)))
228 xRequest
->AppendItem(*pBulletItem
);
230 const SvxNumRule
& rSetRule
= pBulletItem
->GetNumRule();
232 GetShell().GetUniqueNumRuleName(),
233 numfunc::GetDefaultPositionAndSpaceMode());
234 aSetRule
.SetSvxRule(rSetRule
, GetShell().GetDoc());
235 aSetRule
.SetAutoRule(true);
237 GetShell().SetCurNumRule(aSetRule
, true);
240 else if (RET_USER
== nResult
)
241 GetShell().DelNumRules();
248 OSL_FAIL("wrong dispatcher");
254 void SwTextShell::ExecSetNumber(SfxRequest
const &rReq
)
256 const sal_uInt16 nSlot
= rReq
.GetSlot();
259 case FN_SVX_SET_NUMBER
:
260 case FN_SVX_SET_BULLET
:
261 case FN_SVX_SET_OUTLINE
:
263 const SfxUInt16Item
* pIndexItem
= nullptr;
264 const SfxStringItem
* pCharItem
= nullptr;
265 const SfxStringItem
* pFontItem
= nullptr;
267 // tdf#162264 check if rReq.GetArgs() is a nullptr
268 if ( rReq
.GetArgs() )
270 pIndexItem
= rReq
.GetArgs()->GetItem( SID_ATTR_BULLET_INDEX
);
271 if (!pIndexItem
) // tdf#161653
272 pIndexItem
= rReq
.GetArg
<SfxUInt16Item
>(nSlot
);
273 pCharItem
= rReq
.GetArgs()->GetItem( SID_ATTR_BULLET_CHAR
);
274 pFontItem
= rReq
.GetArgs()->GetItem( SID_ATTR_BULLET_FONT
);
277 if ( pIndexItem
!= nullptr || ( pCharItem
!= nullptr && pFontItem
!= nullptr ) )
279 svx::sidebar::NBOType nNBOType
= svx::sidebar::NBOType::Bullets
;
280 if ( nSlot
== FN_SVX_SET_NUMBER
)
281 nNBOType
= svx::sidebar::NBOType::Numbering
;
282 else if ( nSlot
== FN_SVX_SET_OUTLINE
)
283 nNBOType
= svx::sidebar::NBOType::Outline
;
285 svx::sidebar::NBOTypeMgrBase
* pNBOTypeMgr
= svx::sidebar::NBOutlineTypeMgrFact::CreateInstance( nNBOType
);
287 if ( pNBOTypeMgr
!= nullptr )
289 const SwNumRule
* pNumRuleAtCurrentSelection
= GetShell().GetNumRuleAtCurrentSelection();
290 sal_uInt16 nActNumLvl
= USHRT_MAX
;
291 if ( pNumRuleAtCurrentSelection
!= nullptr )
293 const sal_uInt16 nLevel
= GetShell().GetNumLevel();
294 if ( nLevel
< MAXLEVEL
)
296 nActNumLvl
= 1 << nLevel
;
299 SwNumRule
aNewNumRule(
300 pNumRuleAtCurrentSelection
!= nullptr ? pNumRuleAtCurrentSelection
->GetName() : GetShell().GetUniqueNumRuleName(),
301 numfunc::GetDefaultPositionAndSpaceMode() );
302 SvxNumRule aNewSvxNumRule
= pNumRuleAtCurrentSelection
!= nullptr
303 ? pNumRuleAtCurrentSelection
->MakeSvxNumRule()
304 : aNewNumRule
.MakeSvxNumRule();
306 OUString aNumCharFormat
, aBulletCharFormat
;
307 SwStyleNameMapper::FillUIName( RES_POOLCHR_NUM_LEVEL
, aNumCharFormat
);
308 SwStyleNameMapper::FillUIName( RES_POOLCHR_BULLET_LEVEL
, aBulletCharFormat
);
310 SfxAllItemSet
aSet( GetPool() );
311 aSet
.Put( SfxStringItem( SID_NUM_CHAR_FMT
, aNumCharFormat
) );
312 aSet
.Put( SfxStringItem( SID_BULLET_CHAR_FMT
, aBulletCharFormat
) );
313 aSet
.Put( SvxNumBulletItem( aNewSvxNumRule
, SID_ATTR_NUMBERING_RULE
) );
315 pNBOTypeMgr
->SetItems( &aSet
);
317 pNBOTypeMgr
->ApplyNumRule( aNewSvxNumRule
, pIndexItem
->GetValue() - 1, nActNumLvl
);
320 svx::sidebar::BulletsTypeMgr
* pBulletsTypeMgr
321 = dynamic_cast<svx::sidebar::BulletsTypeMgr
*>(pNBOTypeMgr
);
322 pBulletsTypeMgr
->ApplyCustomRule(aNewSvxNumRule
, pCharItem
->GetValue(),
323 pFontItem
->GetValue(), nActNumLvl
);
326 aNewNumRule
.SetSvxRule( aNewSvxNumRule
, GetShell().GetDoc() );
327 aNewNumRule
.SetAutoRule( true );
328 const bool bCreateNewList
= ( pNumRuleAtCurrentSelection
== nullptr );
329 GetShell().SetCurNumRule( aNewNumRule
, bCreateNewList
);
332 else if (nSlot
== FN_SVX_SET_OUTLINE
)
334 // no outline provided: launch dialog to request a specific outline
335 SfxBindings
& rBindings
= GetView().GetViewFrame().GetBindings();
336 const SfxStringItem
aPage(FN_PARAM_1
, u
"outlinenum"_ustr
);
337 const SfxPoolItem
* aItems
[] = { &aPage
, nullptr };
338 rBindings
.Execute(SID_OUTLINE_BULLET
, aItems
);
344 OSL_ENSURE(false, "wrong Dispatcher");
349 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */