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