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 <hintids.hxx>
21 #include <sfx2/request.hxx>
22 #include <svl/eitem.hxx>
23 #include <svl/stritem.hxx>
24 #include <editeng/numitem.hxx>
25 #include <editeng/brushitem.hxx>
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 <uiitems.hxx>
36 #include <swabstdlg.hxx>
37 #include <SwStyleNameMapper.hxx>
38 #include <globals.hrc>
39 #include <sfx2/tabdlg.hxx>
40 #include <svx/nbdtmg.hxx>
41 #include <svx/nbdtmgfact.hxx>
42 #include <svx/svxids.hrc>
43 #include <sfx2/viewfrm.hxx>
44 #include <sfx2/bindings.hxx>
45 #include <memory>
46
ExecEnterNum(SfxRequest & rReq)47 void SwTextShell::ExecEnterNum(SfxRequest &rReq)
48 {
49 //Because the record before any shell exchange.
50 switch(rReq.GetSlot())
51 {
52 case FN_NUM_NUMBERING_ON:
53 {
54 GetShell().StartAllAction();
55 const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
56 bool bMode = !GetShell().SelectionHasNumber(); // #i29560#
57 if ( pItem )
58 bMode = pItem->GetValue();
59 else
60 rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bMode ) );
61
62 if ( bMode != (GetShell().SelectionHasNumber()) ) // #i29560#
63 {
64 rReq.Done();
65 if( bMode )
66 GetShell().NumOn();
67 else
68 GetShell().NumOrBulletOff(); // #i29560#
69 }
70 bool bNewResult = GetShell().SelectionHasNumber();
71 if (bNewResult!=bMode) {
72 SfxBindings& rBindings = GetView().GetViewFrame()->GetBindings();
73 SfxBoolItem aItem(FN_NUM_NUMBERING_ON,!bNewResult);
74 rBindings.SetState(aItem);
75 SfxBoolItem aNewItem(FN_NUM_NUMBERING_ON,bNewResult);
76 rBindings.SetState(aNewItem);
77 }
78 GetShell().EndAllAction();
79 }
80 break;
81 case FN_NUM_BULLET_ON:
82 {
83 GetShell().StartAllAction();
84 const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FN_PARAM_1);
85 bool bMode = !GetShell().SelectionHasBullet(); // #i29560#
86 if ( pItem )
87 bMode = pItem->GetValue();
88 else
89 rReq.AppendItem( SfxBoolItem( FN_PARAM_1, bMode ) );
90
91 if ( bMode != (GetShell().SelectionHasBullet()) ) // #i29560#
92 {
93 rReq.Done();
94 if( bMode )
95 GetShell().BulletOn();
96 else
97 GetShell().NumOrBulletOff(); // #i29560#
98 }
99 bool bNewResult = GetShell().SelectionHasBullet();
100 if (bNewResult!=bMode) {
101 SfxBindings& rBindings = GetView().GetViewFrame()->GetBindings();
102 SfxBoolItem aItem(FN_NUM_BULLET_ON,!bNewResult);
103 rBindings.SetState(aItem);
104 SfxBoolItem aNewItem(FN_NUM_BULLET_ON,bNewResult);
105 rBindings.SetState(aNewItem);
106 }
107 GetShell().EndAllAction();
108 }
109 break;
110
111 case FN_NUMBER_BULLETS:
112 case SID_OUTLINE_BULLET:
113 {
114 SfxItemSet aSet( GetPool(),
115 svl::Items<SID_HTML_MODE, SID_HTML_MODE,
116 SID_ATTR_NUMBERING_RULE, SID_PARAM_CUR_NUM_LEVEL>{} );
117 SwDocShell* pDocSh = GetView().GetDocShell();
118 const bool bHtml = dynamic_cast<SwWebDocShell*>( pDocSh ) != nullptr;
119 const SwNumRule* pNumRuleAtCurrentSelection = GetShell().GetNumRuleAtCurrentSelection();
120 if ( pNumRuleAtCurrentSelection != nullptr )
121 {
122 SvxNumRule aRule = pNumRuleAtCurrentSelection->MakeSvxNumRule();
123
124 //convert type of linked bitmaps from SVX_NUM_BITMAP to (SVX_NUM_BITMAP|LINK_TOKEN)
125 for ( sal_uInt16 i = 0; i < aRule.GetLevelCount(); i++ )
126 {
127 SvxNumberFormat aFormat( aRule.GetLevel( i ) );
128 if ( SVX_NUM_BITMAP == aFormat.GetNumberingType() )
129 {
130 const SvxBrushItem* pBrush = aFormat.GetBrush();
131 if(pBrush && !pBrush->GetGraphicLink().isEmpty())
132 aFormat.SetNumberingType(SvxNumType(SVX_NUM_BITMAP|LINK_TOKEN));
133 aRule.SetLevel(i, aFormat, aRule.Get(i) != nullptr);
134 }
135 }
136 if(bHtml)
137 aRule.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP, false);
138
139 aSet.Put(SvxNumBulletItem(aRule));
140 OSL_ENSURE( GetShell().GetNumLevel() < MAXLEVEL,
141 "<SwTextShell::ExecEnterNum()> - numbered node without valid list level. Serious defect." );
142 sal_uInt16 nLevel = GetShell().GetNumLevel();
143 if( nLevel < MAXLEVEL )
144 {
145 nLevel = 1 << nLevel;
146 aSet.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL, nLevel ) );
147 }
148 }
149 else
150 {
151 SwNumRule aRule( GetShell().GetUniqueNumRuleName(),
152 // #i89178#
153 numfunc::GetDefaultPositionAndSpaceMode() );
154 SvxNumRule aSvxRule = aRule.MakeSvxNumRule();
155 const bool bRightToLeft = GetShell().IsInRightToLeftText();
156
157 if ( bHtml || bRightToLeft )
158 {
159 for ( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
160 {
161 SvxNumberFormat aFormat( aSvxRule.GetLevel( n ) );
162 if ( n && bHtml )
163 {
164 // 1/2" for HTML
165 aFormat.SetAbsLSpace(n * 720);
166 }
167 // #i38904# Default alignment for
168 // numbering/bullet should be rtl in rtl paragraph:
169 if ( bRightToLeft )
170 {
171 aFormat.SetNumAdjust( SvxAdjust::Right );
172 }
173 aSvxRule.SetLevel( n, aFormat, false );
174 }
175 aSvxRule.SetFeatureFlag(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP, false);
176 }
177 aSet.Put( SvxNumBulletItem( aSvxRule ) );
178 }
179
180 aSet.Put( SfxBoolItem( SID_PARAM_NUM_PRESET,false ));
181
182 // Before the dialogue of the HTML mode will be dropped at the Docshell.
183 pDocSh->PutItem(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(pDocSh)));
184
185 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
186 weld::Window *pParent = rReq.GetFrameWeld();
187 VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateSvxNumBulletTabDialog(pParent, &aSet, GetShell()));
188 const SfxStringItem* pPageItem = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
189 if ( pPageItem )
190 pDlg->SetCurPageId( OUStringToOString( pPageItem->GetValue(), RTL_TEXTENCODING_UTF8 ) );
191
192 std::shared_ptr<SfxRequest> pRequest(new SfxRequest(rReq));
193 rReq.Ignore(); // the 'old' request is not relevant any more
194
195 pDlg->StartExecuteAsync([aSet, pDlg, pNumRuleAtCurrentSelection, pRequest, this](sal_Int32 nResult){
196 if (RET_OK == nResult)
197 {
198 const SfxPoolItem* pItem;
199 if (SfxItemState::SET == pDlg->GetOutputItemSet()->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem))
200 {
201 pRequest->AppendItem(*pItem);
202 pRequest->Done();
203 SvxNumRule* pSetRule = static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule();
204 pSetRule->UnLinkGraphics();
205 SwNumRule aSetRule(pNumRuleAtCurrentSelection != nullptr
206 ? pNumRuleAtCurrentSelection->GetName()
207 : GetShell().GetUniqueNumRuleName(),
208 numfunc::GetDefaultPositionAndSpaceMode());
209 aSetRule.SetSvxRule(*pSetRule, GetShell().GetDoc());
210 aSetRule.SetAutoRule(true);
211 // No start of new list, if an existing list style is edited.
212 // Otherwise start a new list.
213 const bool bCreateList = (pNumRuleAtCurrentSelection == nullptr);
214 GetShell().SetCurNumRule(aSetRule, bCreateList);
215 }
216 // If the Dialog was leaved with OK but nothing was chosen then the
217 // numbering must be at least activated, if it is not already.
218 else if (pNumRuleAtCurrentSelection == nullptr
219 && SfxItemState::SET == aSet.GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem))
220 {
221 pRequest->AppendItem(*pItem);
222 pRequest->Done();
223 SvxNumRule* pSetRule = static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule();
224 SwNumRule aSetRule(
225 GetShell().GetUniqueNumRuleName(),
226 numfunc::GetDefaultPositionAndSpaceMode());
227 aSetRule.SetSvxRule(*pSetRule, GetShell().GetDoc());
228 aSetRule.SetAutoRule(true);
229 // start new list
230 GetShell().SetCurNumRule(aSetRule, true);
231 }
232 }
233 else if (RET_USER == nResult)
234 GetShell().DelNumRules();
235 pDlg->disposeOnce();
236 });
237 }
238 break;
239
240 default:
241 OSL_FAIL("wrong dispatcher");
242 return;
243 }
244 }
245
246
ExecSetNumber(SfxRequest const & rReq)247 void SwTextShell::ExecSetNumber(SfxRequest const &rReq)
248 {
249 const sal_uInt16 nSlot = rReq.GetSlot();
250 switch ( nSlot )
251 {
252 case FN_SVX_SET_NUMBER:
253 case FN_SVX_SET_BULLET:
254 case FN_SVX_SET_OUTLINE:
255 {
256 const SfxUInt16Item* pItem = rReq.GetArg<SfxUInt16Item>(nSlot);
257 if ( pItem != nullptr )
258 {
259 const sal_uInt16 nChoosenItemIdx = pItem->GetValue();
260 svx::sidebar::NBOType nNBOType = svx::sidebar::NBOType::Bullets;
261 if ( nSlot == FN_SVX_SET_NUMBER )
262 nNBOType = svx::sidebar::NBOType::Numbering;
263 else if ( nSlot == FN_SVX_SET_OUTLINE )
264 nNBOType = svx::sidebar::NBOType::Outline;
265
266 svx::sidebar::NBOTypeMgrBase* pNBOTypeMgr = svx::sidebar::NBOutlineTypeMgrFact::CreateInstance( nNBOType );
267
268 if ( pNBOTypeMgr != nullptr )
269 {
270 const SwNumRule* pNumRuleAtCurrentSelection = GetShell().GetNumRuleAtCurrentSelection();
271 sal_uInt16 nActNumLvl = USHRT_MAX;
272 if ( pNumRuleAtCurrentSelection != nullptr )
273 {
274 const sal_uInt16 nLevel = GetShell().GetNumLevel();
275 if ( nLevel < MAXLEVEL )
276 {
277 nActNumLvl = 1 << nLevel;
278 }
279 }
280 SwNumRule aNewNumRule(
281 pNumRuleAtCurrentSelection != nullptr ? pNumRuleAtCurrentSelection->GetName() : GetShell().GetUniqueNumRuleName(),
282 numfunc::GetDefaultPositionAndSpaceMode() );
283 SvxNumRule aNewSvxNumRule = pNumRuleAtCurrentSelection != nullptr
284 ? pNumRuleAtCurrentSelection->MakeSvxNumRule()
285 : aNewNumRule.MakeSvxNumRule();
286
287 OUString aNumCharFormat, aBulletCharFormat;
288 SwStyleNameMapper::FillUIName( RES_POOLCHR_NUM_LEVEL, aNumCharFormat );
289 SwStyleNameMapper::FillUIName( RES_POOLCHR_BUL_LEVEL, aBulletCharFormat );
290
291 SfxAllItemSet aSet( GetPool() );
292 aSet.Put( SfxStringItem( SID_NUM_CHAR_FMT, aNumCharFormat ) );
293 aSet.Put( SfxStringItem( SID_BULLET_CHAR_FMT, aBulletCharFormat ) );
294 aSet.Put( SvxNumBulletItem( aNewSvxNumRule, SID_ATTR_NUMBERING_RULE ) );
295
296 pNBOTypeMgr->SetItems( &aSet );
297 pNBOTypeMgr->ApplyNumRule( aNewSvxNumRule, nChoosenItemIdx - 1, nActNumLvl );
298
299 aNewNumRule.SetSvxRule( aNewSvxNumRule, GetShell().GetDoc() );
300 aNewNumRule.SetAutoRule( true );
301 const bool bCreateNewList = ( pNumRuleAtCurrentSelection == nullptr );
302 GetShell().SetCurNumRule( aNewNumRule, bCreateNewList );
303 }
304 }
305 }
306 break;
307
308 default:
309 OSL_ENSURE(false, "wrong Dispatcher");
310 return;
311 }
312 }
313
314 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
315