1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26
27
28 #include "fuolbull.hxx"
29 #include <vcl/msgbox.hxx>
30 #include <svl/intitem.hxx>
31 #include <editeng/outliner.hxx>
32 #include <editeng/eeitem.hxx>
33 #include <sfx2/request.hxx>
34 #include <svl/intitem.hxx>
35 #include <editeng/numitem.hxx>
36 #include "sdresid.hxx"
37 #include "glob.hrc"
38
39 #include <editeng/editdata.hxx>
40 #include <svx/svxids.hrc>
41 #include "OutlineView.hxx"
42 #include "OutlineViewShell.hxx"
43 #include "DrawViewShell.hxx"
44 #ifndef SD_WINDOW_SHELL_HXX
45 #include "Window.hxx"
46 #endif
47 #include "drawdoc.hxx"
48 #include "sdabstdlg.hxx"
49 #include <svx/nbdtmg.hxx>
50 #include <svx/nbdtmgfact.hxx>
51 #include <svx/svdoutl.hxx>
52 using namespace svx::sidebar;
53 namespace sd {
54
55 TYPEINIT1( FuOutlineBullet, FuPoor );
56
57 /*************************************************************************
58 |*
59 |* Konstruktor
60 |*
61 \************************************************************************/
62
FuOutlineBullet(ViewShell * pViewShell,::sd::Window * pWindow,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq)63 FuOutlineBullet::FuOutlineBullet(ViewShell* pViewShell, ::sd::Window* pWindow,
64 ::sd::View* pView, SdDrawDocument* pDoc,
65 SfxRequest& rReq)
66 : FuPoor(pViewShell, pWindow, pView, pDoc, rReq)
67 {
68 }
69
Create(ViewShell * pViewSh,::sd::Window * pWin,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq)70 FunctionReference FuOutlineBullet::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
71 {
72 FunctionReference xFunc( new FuOutlineBullet( pViewSh, pWin, pView, pDoc, rReq ) );
73 xFunc->DoExecute(rReq);
74 return xFunc;
75 }
76
DoExecute(SfxRequest & rReq)77 void FuOutlineBullet::DoExecute( SfxRequest& rReq )
78 {
79 const sal_uInt16 nSId = rReq.GetSlot();
80 if ( nSId == FN_SVX_SET_BULLET || nSId == FN_SVX_SET_NUMBER )
81 {
82 SetCurrentBulletsNumbering(rReq);
83 return;
84 }
85
86 const SfxItemSet* pArgs = rReq.GetArgs();
87
88 if( !pArgs )
89 {
90 // ItemSet fuer Dialog fuellen
91 SfxItemSet aEditAttr( mpDoc->GetPool() );
92 mpView->GetAttributes( aEditAttr );
93
94 SfxItemSet aNewAttr( mpViewShell->GetPool(),
95 EE_ITEMS_START, EE_ITEMS_END );
96 aNewAttr.Put( aEditAttr, sal_False );
97
98 // Dialog hochfahren und ausfuehren
99 SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
100 SfxAbstractTabDialog* pDlg = pFact ? pFact->CreateSdOutlineBulletTabDlg( NULL, &aNewAttr, mpView ) : 0;
101 if( pDlg )
102 {
103 sal_uInt16 nResult = pDlg->Execute();
104
105 switch( nResult )
106 {
107 case RET_OK:
108 {
109 SfxItemSet aSet( *pDlg->GetOutputItemSet() );
110
111 OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
112
113 std::auto_ptr< OutlineViewModelChangeGuard > aGuard;
114
115 if (mpView->ISA(OutlineView))
116 {
117 pOLV = static_cast<OutlineView*>(mpView)
118 ->GetViewByWindow(mpViewShell->GetActiveWindow());
119
120 aGuard.reset( new OutlineViewModelChangeGuard( static_cast<OutlineView&>(*mpView) ) );
121 }
122
123 if( pOLV )
124 pOLV->EnableBullets();
125
126 rReq.Done( aSet );
127 pArgs = rReq.GetArgs();
128 }
129 break;
130
131 default:
132 {
133 delete pDlg;
134 return;
135 }
136 }
137
138 delete pDlg;
139 }
140 }
141
142 // nicht direkt an pOlView, damit SdDrawView::SetAttributes
143 // Aenderungen auf der Masterpage abfangen und in eine
144 // Vorlage umleiten kann
145 mpView->SetAttributes(*pArgs);
146
147 /* #i35937#
148 // evtl. Betroffene Felder invalidieren
149 mpViewShell->Invalidate( FN_NUM_BULLET_ON );
150 */
151 }
152
SetCurrentBulletsNumbering(SfxRequest & rReq)153 void FuOutlineBullet::SetCurrentBulletsNumbering(SfxRequest& rReq)
154 {
155 if (!mpDoc || !mpView)
156 return;
157
158 const sal_uInt16 nSId = rReq.GetSlot();
159 if ( nSId != FN_SVX_SET_BULLET && nSId != FN_SVX_SET_NUMBER )
160 {
161 // unexpected SfxRequest
162 return;
163 }
164
165 SFX_REQUEST_ARG( rReq, pItem, SfxUInt16Item, nSId, sal_False );
166 if ( !pItem )
167 {
168 rReq.Done();
169 return;
170 }
171
172 SfxItemSet aNewAttr( mpViewShell->GetPool(), EE_ITEMS_START, EE_ITEMS_END );
173 {
174 SfxItemSet aEditAttr( mpDoc->GetPool() );
175 mpView->GetAttributes( aEditAttr );
176 aNewAttr.Put( aEditAttr, sal_False );
177 }
178
179 const DrawViewShell* pDrawViewShell = dynamic_cast< DrawViewShell* >(mpViewShell);
180 //Init bullet level in "Customize" tab page in bullet dialog in master page view
181 const bool bInMasterView = pDrawViewShell && pDrawViewShell->GetEditMode() == EM_MASTERPAGE;
182 if ( bInMasterView )
183 {
184 SdrObject* pObj = mpView->GetTextEditObject();
185 if( pObj && pObj->GetObjIdentifier() == OBJ_OUTLINETEXT )
186 {
187 const sal_uInt16 nLevel = mpView->GetSelectionLevel();
188 if( nLevel != 0xFFFF )
189 {
190 //save the itemset value
191 SfxItemSet aStoreSet( aNewAttr );
192 aNewAttr.ClearItem();
193 //extend range
194 aNewAttr.MergeRange( SID_PARAM_NUM_PRESET, SID_PARAM_CUR_NUM_LEVEL );
195 aNewAttr.Put( aStoreSet );
196 //put current level user selected
197 aNewAttr.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL, nLevel ) );
198 }
199 }
200 }
201
202 sal_uInt16 nIdx = pItem->GetValue();
203 bool bToggle = false;
204 bool bSwitchOff = false;
205 if( nIdx == (sal_uInt16)0xFFFF )
206 {
207 // If the nIdx is (sal_uInt16)0xFFFF, means set bullet status to on/off
208 nIdx = 1;
209 bToggle = true;
210 }
211 else if (nIdx == DEFAULT_NONE)
212 {
213 bSwitchOff = true;
214 }
215 nIdx--;
216
217 sal_uInt32 nNumItemId = SID_ATTR_NUMBERING_RULE;
218 const SfxPoolItem* pTmpItem = GetNumBulletItem( aNewAttr, nNumItemId );
219 SvxNumRule* pNumRule = NULL;
220 if ( pTmpItem )
221 {
222 pNumRule = new SvxNumRule(*((SvxNumBulletItem*)pTmpItem)->GetNumRule());
223
224 // get numbering rule corresponding to <nIdx> and apply the needed number formats to <pNumRule>
225 NBOTypeMgrBase* pNumRuleMgr =
226 NBOutlineTypeMgrFact::CreateInstance(
227 nSId == FN_SVX_SET_BULLET ? eNBOType::MIXBULLETS : eNBOType::NUMBERING );
228 if ( pNumRuleMgr )
229 {
230 sal_uInt16 nActNumLvl = (sal_uInt16)0xFFFF;
231 const SfxPoolItem* pNumLevelItem = NULL;
232 if(SFX_ITEM_SET == aNewAttr.GetItemState(SID_PARAM_CUR_NUM_LEVEL, sal_False, &pNumLevelItem))
233 nActNumLvl = ((const SfxUInt16Item*)pNumLevelItem)->GetValue();
234
235 pNumRuleMgr->SetItems(&aNewAttr);
236 SvxNumRule aTmpRule( *pNumRule );
237 if ( nSId == FN_SVX_SET_BULLET && bToggle && nIdx==0 )
238 {
239 // for toggling bullets get default numbering rule
240 pNumRuleMgr->ApplyNumRule( aTmpRule, nIdx, nActNumLvl, true );
241 }
242 else
243 {
244 pNumRuleMgr->ApplyNumRule( aTmpRule, nIdx, nActNumLvl );
245 }
246
247 sal_uInt16 nMask = 1;
248 for(sal_uInt16 i = 0; i < pNumRule->GetLevelCount(); i++)
249 {
250 if(nActNumLvl & nMask)
251 {
252 SvxNumberFormat aFmt(aTmpRule.GetLevel(i));
253 pNumRule->SetLevel(i, aFmt);
254 }
255 nMask <<= 1;
256 }
257 }
258 }
259
260 OutlinerView* pOLV = mpView->GetTextEditOutlinerView();
261 std::auto_ptr< OutlineViewModelChangeGuard > aGuard;
262 {
263 if (mpView->ISA(OutlineView))
264 {
265 pOLV = static_cast<OutlineView*>(mpView)
266 ->GetViewByWindow(mpViewShell->GetActiveWindow());
267
268 aGuard.reset( new OutlineViewModelChangeGuard( static_cast<OutlineView&>(*mpView) ) );
269 }
270 }
271
272 SdrOutliner* pOwner = bInMasterView ? mpView->GetTextEditOutliner() : 0;
273 const bool bOutlinerUndoEnabled = pOwner && !pOwner->IsInUndo() && pOwner->IsUndoEnabled();
274 SdrModel* pSdrModel = bInMasterView ? mpView->GetModel() : 0;
275 const bool bModelUndoEnabled = pSdrModel && pSdrModel->IsUndoEnabled();
276
277 if ( bOutlinerUndoEnabled )
278 {
279 pOwner->UndoActionStart( OLUNDO_ATTR );
280 }
281 else if ( bModelUndoEnabled )
282 {
283 pSdrModel->BegUndo();
284 }
285
286 if ( pOLV )
287 {
288 if ( bSwitchOff )
289 {
290 pOLV->SwitchOffBulletsNumbering( true );
291 }
292 else
293 {
294 pOLV->ToggleBulletsNumbering( bToggle, nSId == FN_SVX_SET_BULLET, bInMasterView ? 0 : pNumRule );
295 }
296 }
297 else
298 {
299 mpView->ChangeMarkedObjectsBulletsNumbering( bToggle, nSId == FN_SVX_SET_BULLET, bInMasterView ? 0 : pNumRule, bSwitchOff );
300 }
301 if ( bInMasterView )
302 {
303 SfxItemSet aSetAttr( mpViewShell->GetPool(), EE_ITEMS_START, EE_ITEMS_END );
304 aSetAttr.Put(SvxNumBulletItem( *pNumRule ), nNumItemId);
305 mpView->SetAttributes(aSetAttr);
306 }
307
308 if( bOutlinerUndoEnabled )
309 {
310 pOwner->UndoActionEnd( OLUNDO_ATTR );
311 }
312 else if ( bModelUndoEnabled )
313 {
314 pSdrModel->EndUndo();
315 }
316
317 delete pNumRule;
318 rReq.Done();
319 }
320
GetNumBulletItem(SfxItemSet & aNewAttr,sal_uInt32 & nNumItemId)321 const SfxPoolItem* FuOutlineBullet::GetNumBulletItem(SfxItemSet& aNewAttr, sal_uInt32& nNumItemId)
322 {
323 //SvxNumBulletItem* pRetItem = NULL;
324 const SfxPoolItem* pTmpItem = NULL;
325
326 if(aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem) == SFX_ITEM_SET)
327 {
328 return pTmpItem;
329 }
330 else
331 {
332 nNumItemId = aNewAttr.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
333 SfxItemState eState = aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem);
334 if (eState == SFX_ITEM_SET)
335 return pTmpItem;
336 else
337 {
338 sal_Bool bOutliner = sal_False;
339 sal_Bool bTitle = sal_False;
340
341 if( mpView )
342 {
343 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
344 const sal_uInt32 nCount = rMarkList.GetMarkCount();
345
346 for(sal_uInt32 nNum = 0; nNum < nCount; nNum++)
347 {
348 SdrObject* pObj = rMarkList.GetMark(nNum)->GetMarkedSdrObj();
349 if( pObj->GetObjInventor() == SdrInventor )
350 {
351 switch(pObj->GetObjIdentifier())
352 {
353 case OBJ_TITLETEXT:
354 bTitle = sal_True;
355 break;
356 case OBJ_OUTLINETEXT:
357 bOutliner = sal_True;
358 break;
359 }
360 }
361 }
362 }
363
364 const SvxNumBulletItem *pItem = NULL;
365 if(bOutliner)
366 {
367 SfxStyleSheetBasePool* pSSPool = mpView->GetDocSh()->GetStyleSheetPool();
368 String aStyleName((SdResId((sal_uInt16)STR_LAYOUT_OUTLINE)));
369 aStyleName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " 1" ) );
370 SfxStyleSheetBase* pFirstStyleSheet = pSSPool->Find( aStyleName, SD_STYLE_FAMILY_PSEUDO);
371 if( pFirstStyleSheet )
372 pFirstStyleSheet->GetItemSet().GetItemState(EE_PARA_NUMBULLET, sal_False, (const SfxPoolItem**)&pItem);
373 }
374
375 if( pItem == NULL )
376 pItem = (SvxNumBulletItem*) aNewAttr.GetPool()->GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET);
377
378 //DBG_ASSERT( pItem, "Kein EE_PARA_NUMBULLET im Pool! [CL]" );
379
380 aNewAttr.Put(*pItem, EE_PARA_NUMBULLET);
381
382 if(bTitle && aNewAttr.GetItemState(EE_PARA_NUMBULLET,sal_True) == SFX_ITEM_ON )
383 {
384 SvxNumBulletItem* pItem = (SvxNumBulletItem*)aNewAttr.GetItem(EE_PARA_NUMBULLET,sal_True);
385 SvxNumRule* pRule = pItem->GetNumRule();
386 if(pRule)
387 {
388 SvxNumRule aNewRule( *pRule );
389 aNewRule.SetFeatureFlag( NUM_NO_NUMBERS, sal_True );
390
391 SvxNumBulletItem aNewItem( aNewRule, EE_PARA_NUMBULLET );
392 aNewAttr.Put(aNewItem);
393 }
394 }
395
396 SfxItemState eState = aNewAttr.GetItemState(nNumItemId, sal_False, &pTmpItem);
397 if (eState == SFX_ITEM_SET)
398 return pTmpItem;
399
400 }
401 //DBG_ASSERT(eState == SFX_ITEM_SET, "kein Item gefunden!")
402 }
403 return pTmpItem;
404 }
405
406 } // end of namespace sd
407