xref: /trunk/main/sd/source/ui/func/fuolbull.cxx (revision af89ca6e)
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