xref: /aoo41x/main/sd/source/ui/view/viewshe3.cxx (revision 5b190011)
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 "ViewShell.hxx"
29 #include "GraphicViewShell.hxx"
30 #include "GraphicViewShellBase.hxx"
31 
32 #include <sfx2/viewfrm.hxx>
33 #include <svtools/svtools.hrc>
34 #include <com/sun/star/lang/Locale.hpp>
35 #include <svtools/svtdata.hxx>
36 #include <utility>
37 #include <vector>
38 
39 #include "app.hrc"
40 #include "strings.hrc"
41 #include "res_bmp.hrc"
42 #include "glob.hrc"
43 #include "sdabstdlg.hxx"
44 
45 #include "fupoor.hxx"
46 #include <sfx2/dispatch.hxx>
47 #include <svx/prtqry.hxx>
48 #include <svx/svdopage.hxx>
49 #include <sfx2/progress.hxx>
50 #include <svx/svdobj.hxx>
51 #include <vcl/msgbox.hxx>
52 #include <sfx2/bindings.hxx>
53 #include <svx/svdpagv.hxx>
54 #include <svx/svdetc.hxx>
55 #include <editeng/outliner.hxx>
56 #include <editeng/editstat.hxx>
57 #include <tools/multisel.hxx>
58 #include <svl/intitem.hxx>
59 #include <svl/style.hxx>
60 #include <unotools/localedatawrapper.hxx>
61 #include <comphelper/processfactory.hxx>
62 #include <rtl/ustrbuf.hxx>
63 #include "stlsheet.hxx"
64 #ifndef SD_WINDOW_UPDATER_HXX
65 #include "WindowUpdater.hxx"
66 #endif
67 #include "DrawViewShell.hxx"
68 #include "OutlineViewShell.hxx"
69 #include "drawview.hxx"
70 
71 #include "sdattr.hxx"
72 #include "drawdoc.hxx"
73 #include "sdpage.hxx"
74 #include "unoaprms.hxx"                 // Undo-Action
75 #include "sdundogr.hxx"                 // Undo Gruppe
76 #include "Window.hxx"
77 #include "DrawDocShell.hxx"
78 #include "FrameView.hxx"
79 #include "framework/FrameworkHelper.hxx"
80 #include "optsitem.hxx"
81 #include "sdresid.hxx"
82 
83 // #96090#
84 #ifndef _SVXIDS_HXX
85 #include <svx/svxids.hrc>
86 #endif
87 #include <sfx2/request.hxx>
88 #include <svl/aeitem.hxx>
89 #include <basic/sbstar.hxx>
90 
91 using namespace ::com::sun::star;
92 using namespace ::rtl;
93 
94 namespace sd {
95 
96 /*************************************************************************
97 |*
98 |* Status (Enabled/Disabled) von Menue-SfxSlots setzen
99 |*
100 \************************************************************************/
101 
102 void  ViewShell::GetMenuState( SfxItemSet &rSet )
103 {
104 	if( SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_STYLE_FAMILY ) )
105 	{
106 		sal_uInt16 nFamily = (sal_uInt16)GetDocSh()->GetStyleFamily();
107 
108 		SdrView* pDrView = GetDrawView();
109 
110 		if( pDrView->AreObjectsMarked() )
111 		{
112 			SfxStyleSheet* pStyleSheet = pDrView->GetStyleSheet();
113 			if( pStyleSheet )
114 			{
115 				if (pStyleSheet->GetFamily() == SD_STYLE_FAMILY_MASTERPAGE)
116 					pStyleSheet = ((SdStyleSheet*)pStyleSheet)->GetPseudoStyleSheet();
117 
118 				if( pStyleSheet )
119 				{
120 					SfxStyleFamily eFamily = pStyleSheet->GetFamily();
121 					if(eFamily == SD_STYLE_FAMILY_GRAPHICS)
122 						nFamily = 2;
123 					else if(eFamily == SD_STYLE_FAMILY_CELL )
124 						nFamily = 3;
125 					else // SD_STYLE_FAMILY_PSEUDO
126 						nFamily = 5;
127 
128 					GetDocSh()->SetStyleFamily(nFamily);
129 				}
130 			}
131 		}
132 		rSet.Put(SfxUInt16Item(SID_STYLE_FAMILY, nFamily ));
133 	}
134 
135 	// #96090#
136     if(SFX_ITEM_AVAILABLE == rSet.GetItemState(SID_GETUNDOSTRINGS))
137 	{
138 		ImpGetUndoStrings(rSet);
139 	}
140 
141 	// #96090#
142     if(SFX_ITEM_AVAILABLE == rSet.GetItemState(SID_GETREDOSTRINGS))
143 	{
144 		ImpGetRedoStrings(rSet);
145 	}
146 
147 	// #96090#
148     if(SFX_ITEM_AVAILABLE == rSet.GetItemState(SID_UNDO))
149 	{
150 		::svl::IUndoManager* pUndoManager = ImpGetUndoManager();
151 		sal_Bool bActivate(sal_False);
152 
153 		if(pUndoManager)
154 		{
155 			if(pUndoManager->GetUndoActionCount() != 0)
156 			{
157 				bActivate = sal_True;
158 			}
159 		}
160 
161 		if(bActivate)
162 		{
163 			// #87229# Set the necessary string like in
164 			// sfx2/source/view/viewfrm.cxx ver 1.23 ln 1072 ff.
165 			String aTmp( SvtResId( STR_UNDO ) );
166 			aTmp += pUndoManager->GetUndoActionComment(0);
167 			rSet.Put(SfxStringItem(SID_UNDO, aTmp));
168 		}
169 		else
170 		{
171 			rSet.DisableItem(SID_UNDO);
172 		}
173 	}
174 
175 	// #96090#
176     if(SFX_ITEM_AVAILABLE == rSet.GetItemState(SID_REDO))
177 	{
178 		::svl::IUndoManager* pUndoManager = ImpGetUndoManager();
179 		sal_Bool bActivate(sal_False);
180 
181 		if(pUndoManager)
182 		{
183 			if(pUndoManager->GetRedoActionCount() != 0)
184 			{
185 				bActivate = sal_True;
186 			}
187 		}
188 
189 		if(bActivate)
190 		{
191 			// #87229# Set the necessary string like in
192 			// sfx2/source/view/viewfrm.cxx ver 1.23 ln 1081 ff.
193 			String aTmp(SvtResId(STR_REDO));
194 			aTmp += pUndoManager->GetRedoActionComment(0);
195 			rSet.Put(SfxStringItem(SID_REDO, aTmp));
196 		}
197 		else
198 		{
199 			rSet.DisableItem(SID_REDO);
200 		}
201 	}
202 }
203 
204 
205 
206 
207 /** This method consists basically of three parts:
208     1. Process the arguments of the SFX request.
209     2. Use the model to create a new page or duplicate an existing one.
210     3. Update the tab control and switch to the new page.
211 */
212 SdPage* ViewShell::CreateOrDuplicatePage (
213     SfxRequest& rRequest,
214     PageKind ePageKind,
215     SdPage* pPage,
216     const sal_Int32 nInsertPosition)
217 {
218 	sal_uInt16 nSId = rRequest.GetSlot();
219     SdDrawDocument* pDocument = GetDoc();
220     SdrLayerAdmin& rLayerAdmin = pDocument->GetLayerAdmin();
221     sal_uInt8 aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False);
222     sal_uInt8 aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False);
223     SetOfByte aVisibleLayers;
224     // Determine the page from which to copy some values, such as layers,
225     // size, master page, to the new page.  This is usually the given page.
226     // When the given page is NULL then use the first page of the document.
227     SdPage* pTemplatePage = pPage;
228     if (pTemplatePage == NULL)
229         if (pDocument->GetSdPage(0, ePageKind) > 0)
230             pTemplatePage = pDocument->GetSdPage(0, ePageKind);
231     if (pTemplatePage != NULL && pTemplatePage->TRG_HasMasterPage())
232         aVisibleLayers = pTemplatePage->TRG_GetMasterPageVisibleLayers();
233     else
234         aVisibleLayers.SetAll();
235 
236     String aStandardPageName;
237     String aNotesPageName;
238     AutoLayout eStandardLayout (AUTOLAYOUT_NONE);
239     AutoLayout eNotesLayout (AUTOLAYOUT_NOTES);
240     sal_Bool bIsPageBack = aVisibleLayers.IsSet(aBckgrnd);
241     sal_Bool bIsPageObj = aVisibleLayers.IsSet(aBckgrndObj);
242 
243     // 1. Process the arguments.
244     const SfxItemSet* pArgs = rRequest.GetArgs();
245     if (! pArgs)
246     {
247 /*
248         // Make the layout menu visible in the tool pane.
249         const ViewShellBase& rBase (GetViewShellBase());
250 		if (rBase.GetMainViewShell()!=NULL
251             && rBase.GetMainViewShell()->GetShellType()!=ViewShell::ST_OUTLINE
252             && rBase.GetMainViewShell()->GetShellType()!=ViewShell::ST_DRAW)
253         {
254             framework::FrameworkHelper::Instance(GetViewShellBase())->RequestTaskPanel(
255                 framework::FrameworkHelper::msLayoutTaskPanelURL,
256                 false);
257         }
258 */
259 
260         // AutoLayouts muessen fertig sein
261         pDocument->StopWorkStartupDelay();
262 
263         // Use the layouts of the previous page and notes page as template.
264         if (pTemplatePage != NULL)
265         {
266             eStandardLayout = pTemplatePage->GetAutoLayout();
267 			if( eStandardLayout == AUTOLAYOUT_TITLE )
268 				eStandardLayout = AUTOLAYOUT_ENUM;
269 
270             SdPage* pNotesTemplatePage = static_cast<SdPage*>(pDocument->GetPage(pTemplatePage->GetPageNum()+1));
271             if (pNotesTemplatePage != NULL)
272                 eNotesLayout = pNotesTemplatePage->GetAutoLayout();
273         }
274     }
275     else if (pArgs->Count() == 1)
276     {
277         pDocument->StopWorkStartupDelay();
278         SFX_REQUEST_ARG (rRequest, pLayout, SfxUInt32Item, ID_VAL_WHATLAYOUT, sal_False);
279 		if( pLayout )
280 		{
281             if (ePageKind == PK_NOTES)
282             {
283                 eNotesLayout   = (AutoLayout) pLayout->GetValue ();
284             }
285             else
286             {
287                 eStandardLayout   = (AutoLayout) pLayout->GetValue ();
288             }
289 		}
290 	}
291     else if (pArgs->Count() == 4)
292     {
293         // AutoLayouts muessen fertig sein
294         pDocument->StopWorkStartupDelay();
295 
296         SFX_REQUEST_ARG (rRequest, pPageName, SfxStringItem, ID_VAL_PAGENAME, sal_False);
297         SFX_REQUEST_ARG (rRequest, pLayout, SfxUInt32Item, ID_VAL_WHATLAYOUT, sal_False);
298         SFX_REQUEST_ARG (rRequest, pIsPageBack, SfxBoolItem, ID_VAL_ISPAGEBACK, sal_False);
299         SFX_REQUEST_ARG (rRequest, pIsPageObj, SfxBoolItem, ID_VAL_ISPAGEOBJ, sal_False);
300 
301         if (CHECK_RANGE (AUTOLAYOUT__START, (AutoLayout) pLayout->GetValue (), AUTOLAYOUT__END))
302         {
303             if (ePageKind == PK_NOTES)
304             {
305                 aNotesPageName = pPageName->GetValue ();
306                 eNotesLayout   = (AutoLayout) pLayout->GetValue ();
307             }
308             else
309             {
310                 aStandardPageName = pPageName->GetValue ();
311                 eStandardLayout   = (AutoLayout) pLayout->GetValue ();
312             }
313 
314             bIsPageBack = pIsPageBack->GetValue ();
315             bIsPageObj	= pIsPageObj->GetValue ();
316         }
317         else
318         {
319             Cancel();
320 
321             if(HasCurrentFunction( SID_BEZIER_EDIT ) )
322                 GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON);
323 
324             StarBASIC::FatalError (SbERR_BAD_PROP_VALUE);
325             rRequest.Ignore ();
326             return NULL;
327         }
328     }
329     else
330     {
331         Cancel();
332 
333         if(HasCurrentFunction(SID_BEZIER_EDIT) )
334             GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON);
335 
336         StarBASIC::FatalError (SbERR_WRONG_ARGS);
337         rRequest.Ignore ();
338         return NULL;
339     }
340 
341     // 2. Create a new page or duplicate an existing one.
342     View* pDrView = GetView();
343 	const bool bUndo = pDrView && pDrView->IsUndoEnabled();
344 	if( bUndo )
345 		pDrView->BegUndo( String( SdResId(STR_INSERTPAGE) ) );
346 
347     sal_uInt16 nNewPageIndex = 0xffff;
348     switch (nSId)
349     {
350         case SID_INSERTPAGE:
351         case SID_INSERTPAGE_QUICK:
352         case SID_INSERT_MASTER_PAGE:
353             // There are three cases.  a) pPage is not NULL: we use it as a
354             // template and create a new slide behind it. b) pPage is NULL
355             // but the document is not empty: we use the first slide/notes
356             // page as template, create a new slide after it and move it
357             // then to the head of the document. c) pPage is NULL and the
358             // document is empty: We use CreateFirstPages to create the
359             // first page of the document.
360             if (pPage == NULL)
361                 if (pTemplatePage == NULL)
362                 {
363                     pDocument->CreateFirstPages();
364                     nNewPageIndex = 0;
365                 }
366                 else
367                 {
368                     // Create a new page with the first page as template and
369                     // insert it after the first page.
370                     nNewPageIndex = pDocument->CreatePage (
371                         pTemplatePage,
372                         ePageKind,
373                         aStandardPageName,
374                         aNotesPageName,
375                         eStandardLayout,
376                         eNotesLayout,
377                         bIsPageBack,
378                         bIsPageObj,
379                         nInsertPosition);
380                     // Select exactly the new page.
381                     sal_uInt16 nPageCount (pDocument->GetSdPageCount(ePageKind));
382                     for (sal_uInt16 i=0; i<nPageCount; i++)
383                     {
384                         pDocument->GetSdPage(i, PK_STANDARD)->SetSelected(
385                             i == nNewPageIndex);
386                         pDocument->GetSdPage(i, PK_NOTES)->SetSelected(
387                             i == nNewPageIndex);
388                     }
389                     // Move the selected page to the head of the document
390                     pDocument->MovePages ((sal_uInt16)-1);
391                     nNewPageIndex = 0;
392                 }
393             else
394                 nNewPageIndex = pDocument->CreatePage (
395                     pPage,
396                     ePageKind,
397                     aStandardPageName,
398                     aNotesPageName,
399                     eStandardLayout,
400                     eNotesLayout,
401                     bIsPageBack,
402                     bIsPageObj,
403                     nInsertPosition);
404             break;
405 
406 		case SID_DUPLICATE_PAGE:
407             // Duplication makes no sense when pPage is NULL.
408             if (pPage != NULL)
409                 nNewPageIndex = pDocument->DuplicatePage (
410                     pPage,
411                     ePageKind,
412                     aStandardPageName,
413                     aNotesPageName,
414                     eStandardLayout,
415                     eNotesLayout,
416                     bIsPageBack,
417                     bIsPageObj,
418                     nInsertPosition);
419             break;
420 
421         default:
422             DBG_WARNING("wrong slot id given to CreateOrDuplicatePage");
423             // Try to handle another slot id gracefully.
424     }
425 	SdPage* pNewPage = 0;
426 	if(nNewPageIndex != 0xffff)
427 		pNewPage = pDocument->GetSdPage(nNewPageIndex, PK_STANDARD);
428 
429 	if( bUndo )
430 	{
431 		if( pNewPage )
432 		{
433 			pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pNewPage));
434 			pDrView->AddUndo(pDocument->GetSdrUndoFactory().CreateUndoNewPage(*pDocument->GetSdPage (nNewPageIndex, PK_NOTES)));
435 		}
436 
437 		pDrView->EndUndo();
438 	}
439 
440     return pNewPage;
441 }
442 
443 
444 } // end of namespace sd
445