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().NumOrBulletOff();
115 GetShell().DelNumRules();
116 GetShell().EndAllAction();
120 case FN_NUMBER_BULLETS
:
121 case SID_OUTLINE_BULLET
:
123 SfxItemSetFixed
<SID_HTML_MODE
, SID_HTML_MODE
,
124 SID_ATTR_NUMBERING_RULE
, SID_PARAM_CUR_NUM_LEVEL
> aSet( GetPool() );
125 SwDocShell
* pDocSh
= GetView().GetDocShell();
126 const bool bHtml
= dynamic_cast<SwWebDocShell
*>( pDocSh
) != nullptr;
127 const SwNumRule
* pNumRuleAtCurrentSelection
= GetShell().GetNumRuleAtCurrentSelection();
128 if ( pNumRuleAtCurrentSelection
!= nullptr )
130 SvxNumRule aRule
= pNumRuleAtCurrentSelection
->MakeSvxNumRule();
132 //convert type of linked bitmaps from SVX_NUM_BITMAP to (SVX_NUM_BITMAP|LINK_TOKEN)
133 for ( sal_uInt16 i
= 0; i
< aRule
.GetLevelCount(); i
++ )
135 SvxNumberFormat
aFormat( aRule
.GetLevel( i
) );
136 if ( SVX_NUM_BITMAP
== aFormat
.GetNumberingType() )
138 const SvxBrushItem
* pBrush
= aFormat
.GetBrush();
139 if(pBrush
&& !pBrush
->GetGraphicLink().isEmpty())
140 aFormat
.SetNumberingType(SvxNumType(SVX_NUM_BITMAP
|LINK_TOKEN
));
141 aRule
.SetLevel(i
, aFormat
, aRule
.Get(i
) != nullptr);
145 aRule
.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP
, false);
147 aSet
.Put(SvxNumBulletItem(aRule
));
148 OSL_ENSURE( GetShell().GetNumLevel() < MAXLEVEL
,
149 "<SwTextShell::ExecEnterNum()> - numbered node without valid list level. Serious defect." );
150 sal_uInt16 nLevel
= GetShell().GetNumLevel();
151 if( nLevel
< MAXLEVEL
)
153 nLevel
= 1 << nLevel
;
154 aSet
.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL
, nLevel
) );
159 SwNumRule
aRule( GetShell().GetUniqueNumRuleName(),
161 numfunc::GetDefaultPositionAndSpaceMode() );
162 SvxNumRule aSvxRule
= aRule
.MakeSvxNumRule();
163 const bool bRightToLeft
= GetShell().IsInRightToLeftText();
165 if ( bHtml
|| bRightToLeft
)
167 for ( sal_uInt8 n
= 0; n
< MAXLEVEL
; ++n
)
169 SvxNumberFormat
aFormat( aSvxRule
.GetLevel( n
) );
173 aFormat
.SetAbsLSpace(n
* 720);
175 // #i38904# Default alignment for
176 // numbering/bullet should be rtl in rtl paragraph:
179 aFormat
.SetNumAdjust( SvxAdjust::Right
);
181 aSvxRule
.SetLevel( n
, aFormat
, false );
183 aSvxRule
.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP
, false);
185 aSet
.Put( SvxNumBulletItem( std::move(aSvxRule
) ) );
188 aSet
.Put( SfxBoolItem( SID_PARAM_NUM_PRESET
,false ));
190 // Before the dialogue of the HTML mode will be dropped at the Docshell.
191 pDocSh
->PutItem(SfxUInt16Item(SID_HTML_MODE
, ::GetHtmlMode(pDocSh
)));
193 SwAbstractDialogFactory
* pFact
= SwAbstractDialogFactory::Create();
194 weld::Window
*pParent
= rReq
.GetFrameWeld();
195 VclPtr
<SfxAbstractTabDialog
> pDlg(pFact
->CreateSvxNumBulletTabDialog(pParent
, &aSet
, GetShell()));
196 const SfxStringItem
* pPageItem
= rReq
.GetArg
<SfxStringItem
>(FN_PARAM_1
);
198 pDlg
->SetCurPageId( pPageItem
->GetValue() );
200 auto pRequest
= std::make_shared
<SfxRequest
>(rReq
);
201 rReq
.Ignore(); // the 'old' request is not relevant any more
203 pDlg
->StartExecuteAsync([aSet
, pDlg
, pNumRuleAtCurrentSelection
, pRequest
, this](sal_Int32 nResult
){
204 if (RET_OK
== nResult
)
206 const SvxNumBulletItem
* pBulletItem
= pDlg
->GetOutputItemSet()->GetItemIfSet(SID_ATTR_NUMBERING_RULE
, false);
209 pRequest
->AppendItem(*pBulletItem
);
211 SvxNumRule
& rSetRule
= const_cast<SvxNumRule
&>(pBulletItem
->GetNumRule());
212 rSetRule
.UnLinkGraphics();
213 SwNumRule
aSetRule(pNumRuleAtCurrentSelection
!= nullptr
214 ? pNumRuleAtCurrentSelection
->GetName()
215 : GetShell().GetUniqueNumRuleName(),
216 numfunc::GetDefaultPositionAndSpaceMode());
217 aSetRule
.SetSvxRule(rSetRule
, GetShell().GetDoc());
218 aSetRule
.SetAutoRule(true);
219 // No start of new list, if an existing list style is edited.
220 // Otherwise start a new list.
221 const bool bCreateList
= (pNumRuleAtCurrentSelection
== nullptr);
222 GetShell().SetCurNumRule(aSetRule
, bCreateList
);
224 // If the Dialog was leaved with OK but nothing was chosen then the
225 // numbering must be at least activated, if it is not already.
226 else if (pNumRuleAtCurrentSelection
== nullptr
227 && (pBulletItem
= aSet
.GetItemIfSet(SID_ATTR_NUMBERING_RULE
, false)))
229 pRequest
->AppendItem(*pBulletItem
);
231 const SvxNumRule
& rSetRule
= pBulletItem
->GetNumRule();
233 GetShell().GetUniqueNumRuleName(),
234 numfunc::GetDefaultPositionAndSpaceMode());
235 aSetRule
.SetSvxRule(rSetRule
, GetShell().GetDoc());
236 aSetRule
.SetAutoRule(true);
238 GetShell().SetCurNumRule(aSetRule
, true);
241 else if (RET_USER
== nResult
)
242 GetShell().DelNumRules();
249 OSL_FAIL("wrong dispatcher");
255 void SwTextShell::ExecSetNumber(SfxRequest
const &rReq
)
257 const sal_uInt16 nSlot
= rReq
.GetSlot();
260 case FN_SVX_SET_NUMBER
:
261 case FN_SVX_SET_BULLET
:
262 case FN_SVX_SET_OUTLINE
:
264 const SfxUInt16Item
* pItem
= rReq
.GetArg
<SfxUInt16Item
>(nSlot
);
265 if ( pItem
!= nullptr )
267 const sal_uInt16 nChosenItemIdx
= pItem
->GetValue();
268 svx::sidebar::NBOType nNBOType
= svx::sidebar::NBOType::Bullets
;
269 if ( nSlot
== FN_SVX_SET_NUMBER
)
270 nNBOType
= svx::sidebar::NBOType::Numbering
;
271 else if ( nSlot
== FN_SVX_SET_OUTLINE
)
272 nNBOType
= svx::sidebar::NBOType::Outline
;
274 svx::sidebar::NBOTypeMgrBase
* pNBOTypeMgr
= svx::sidebar::NBOutlineTypeMgrFact::CreateInstance( nNBOType
);
276 if ( pNBOTypeMgr
!= nullptr )
278 const SwNumRule
* pNumRuleAtCurrentSelection
= GetShell().GetNumRuleAtCurrentSelection();
279 sal_uInt16 nActNumLvl
= USHRT_MAX
;
280 if ( pNumRuleAtCurrentSelection
!= nullptr )
282 const sal_uInt16 nLevel
= GetShell().GetNumLevel();
283 if ( nLevel
< MAXLEVEL
)
285 nActNumLvl
= 1 << nLevel
;
288 SwNumRule
aNewNumRule(
289 pNumRuleAtCurrentSelection
!= nullptr ? pNumRuleAtCurrentSelection
->GetName() : GetShell().GetUniqueNumRuleName(),
290 numfunc::GetDefaultPositionAndSpaceMode() );
291 SvxNumRule aNewSvxNumRule
= pNumRuleAtCurrentSelection
!= nullptr
292 ? pNumRuleAtCurrentSelection
->MakeSvxNumRule()
293 : aNewNumRule
.MakeSvxNumRule();
295 OUString aNumCharFormat
, aBulletCharFormat
;
296 SwStyleNameMapper::FillUIName( RES_POOLCHR_NUM_LEVEL
, aNumCharFormat
);
297 SwStyleNameMapper::FillUIName( RES_POOLCHR_BULLET_LEVEL
, aBulletCharFormat
);
299 SfxAllItemSet
aSet( GetPool() );
300 aSet
.Put( SfxStringItem( SID_NUM_CHAR_FMT
, aNumCharFormat
) );
301 aSet
.Put( SfxStringItem( SID_BULLET_CHAR_FMT
, aBulletCharFormat
) );
302 aSet
.Put( SvxNumBulletItem( aNewSvxNumRule
, SID_ATTR_NUMBERING_RULE
) );
304 pNBOTypeMgr
->SetItems( &aSet
);
305 pNBOTypeMgr
->ApplyNumRule( aNewSvxNumRule
, nChosenItemIdx
- 1, nActNumLvl
);
307 aNewNumRule
.SetSvxRule( aNewSvxNumRule
, GetShell().GetDoc() );
308 aNewNumRule
.SetAutoRule( true );
309 const bool bCreateNewList
= ( pNumRuleAtCurrentSelection
== nullptr );
310 GetShell().SetCurNumRule( aNewNumRule
, bCreateNewList
);
317 OSL_ENSURE(false, "wrong Dispatcher");
322 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */