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 #include "ViewShellImplementation.hxx"
28 
29 #include "sdpage.hxx"
30 #include "drawdoc.hxx"
31 #include "sdresid.hxx"
32 #include "glob.hrc"
33 #include "app.hrc"
34 #include "strings.hrc"
35 #include "strings.hrc"
36 #include "helpids.h"
37 #include "sdattr.hxx"
38 #include "sdabstdlg.hxx"
39 #include "unmodpg.hxx"
40 #include "Window.hxx"
41 #include "optsitem.hxx"
42 #include "DrawDocShell.hxx"
43 #include "DrawController.hxx"
44 #include "FactoryIds.hxx"
45 #include "slideshow.hxx"
46 #include "ViewShellBase.hxx"
47 #include "FrameView.hxx"
48 #include "DrawViewShell.hxx"
49 #include "ViewShellHint.hxx"
50 #include "SidebarPanelId.hxx"
51 #include "framework/FrameworkHelper.hxx"
52 
53 #include <sfx2/bindings.hxx>
54 #include <sfx2/dispatch.hxx>
55 #include <sfx2/request.hxx>
56 #include <sfx2/sidebar/Sidebar.hxx>
57 #include <svl/aeitem.hxx>
58 #include <svx/imapdlg.hxx>
59 #include <vcl/msgbox.hxx>
60 #include <basic/sbstar.hxx>
61 #include "undo/undoobjects.hxx"
62 
63 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
64 
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::drawing::framework;
67 using ::sd::framework::FrameworkHelper;
68 
69 namespace sd {
70 
Implementation(ViewShell & rViewShell)71 ViewShell::Implementation::Implementation (ViewShell& rViewShell)
72     : mbIsShowingUIControls(false),
73       mbIsMainViewShell(false),
74       mbIsInitialized(false),
75       mbArrangeActive(false),
76       mpSubShellFactory(),
77       mpUpdateLockForMouse(),
78       mrViewShell(rViewShell)
79 {
80 }
81 
82 
83 
84 
~Implementation(void)85 ViewShell::Implementation::~Implementation (void)
86 {
87     if ( ! mpUpdateLockForMouse.expired())
88     {
89         ::boost::shared_ptr<ToolBarManagerLock> pLock(mpUpdateLockForMouse);
90         if (pLock.get() != NULL)
91         {
92             // Force the ToolBarManagerLock to be released even when the
93             // IsUICaptured() returns <TRUE/>.
94             pLock->Release(true);
95         }
96     }
97 }
98 
99 
100 
101 
ProcessModifyPageSlot(SfxRequest & rRequest,SdPage * pCurrentPage,PageKind ePageKind)102 void ViewShell::Implementation::ProcessModifyPageSlot (
103     SfxRequest& rRequest,
104     SdPage* pCurrentPage,
105     PageKind ePageKind)
106 {
107     SdDrawDocument* pDocument = mrViewShell.GetDoc();
108     SdrLayerAdmin& rLayerAdmin = pDocument->GetLayerAdmin();
109     sal_uInt8 aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False);
110     sal_uInt8 aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False);
111     SetOfByte aVisibleLayers;
112     sal_Bool bHandoutMode = sal_False;
113     SdPage* pHandoutMPage = NULL;
114     String aNewName;
115 
116     // #95981#
117     String aOldName;
118 
119     AutoLayout aNewAutoLayout;
120 
121     sal_Bool bBVisible;
122     sal_Bool bBObjsVisible;
123     const SfxItemSet* pArgs = rRequest.GetArgs();
124 
125     if (pCurrentPage != NULL && pCurrentPage->TRG_HasMasterPage())
126         aVisibleLayers = pCurrentPage->TRG_GetMasterPageVisibleLayers();
127     else
128         aVisibleLayers.SetAll();
129 
130     do
131     {
132         if (pCurrentPage == NULL)
133             break;
134 
135         if (!pArgs || pArgs->Count() == 1 || pArgs->Count() == 2 )
136         {
137             if (pArgs && pArgs->Count() == 2)
138             {
139                 // We have been called with a request that contains two
140                 // arguments.  One was used as preselected layout in a
141                 // dialog.  We could select that layout in the
142                 // layout panel instead.
143                 /*
144                     SFX_REQUEST_ARG (rRequest, pNewAutoLayout, SfxUInt32Item, ID_VAL_WHATLAYOUT, sal_False);
145                     eNewAutoLayout = (AutoLayout) pNewAutoLayout->GetValue
146                     ();
147                 */
148             }
149 
150             // Make the layout menu visible in the tool pane.
151             sfx2::sidebar::Sidebar::ShowPanel(
152                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImpressLayoutsPanel")),
153                 mrViewShell.GetViewFrame()->GetFrame().GetFrameInterface());
154             break;
155         }
156         else if (pArgs->Count() == 4)
157         {
158             SFX_REQUEST_ARG (rRequest, pNewName, SfxStringItem, ID_VAL_PAGENAME, sal_False);
159             SFX_REQUEST_ARG (rRequest, pNewAutoLayout, SfxUInt32Item, ID_VAL_WHATLAYOUT, sal_False);
160             SFX_REQUEST_ARG (rRequest, pBVisible, SfxBoolItem, ID_VAL_ISPAGEBACK, sal_False);
161             SFX_REQUEST_ARG (rRequest, pBObjsVisible, SfxBoolItem, ID_VAL_ISPAGEOBJ, sal_False);
162             AutoLayout aLayout ((AutoLayout)pNewAutoLayout->GetValue ());
163             if (aLayout >= AUTOLAYOUT__START
164                 && aLayout < AUTOLAYOUT__END)
165             {
166                 aNewName		= pNewName->GetValue ();
167                 aNewAutoLayout = (AutoLayout) pNewAutoLayout->GetValue ();
168                 bBVisible		= pBVisible->GetValue ();
169                 bBObjsVisible	= pBObjsVisible->GetValue ();
170             }
171             else
172             {
173                 StarBASIC::FatalError (SbERR_BAD_PROP_VALUE);
174                 rRequest.Ignore ();
175                 break;
176             }
177             if (ePageKind == PK_HANDOUT)
178             {
179                 bHandoutMode = sal_True;
180                 pHandoutMPage = pDocument->GetMasterSdPage(0, PK_HANDOUT);
181             }
182         }
183         else
184         {
185             StarBASIC::FatalError (SbERR_WRONG_ARGS);
186             rRequest.Ignore ();
187             break;
188         }
189 
190         SdPage* pUndoPage =
191             bHandoutMode ? pHandoutMPage : pCurrentPage;
192 
193         ::svl::IUndoManager* pUndoManager = mrViewShell.GetDocSh()->GetUndoManager();
194         DBG_ASSERT(pUndoManager, "No UNDO MANAGER ?!?");
195 
196 		if( pUndoManager )
197 		{
198 			String aComment( SdResId(STR_UNDO_MODIFY_PAGE) );
199 			pUndoManager->EnterListAction(aComment, aComment);
200 			ModifyPageUndoAction* pAction = new ModifyPageUndoAction(
201 				pDocument, pUndoPage, aNewName, aNewAutoLayout, bBVisible, bBObjsVisible);
202 			pUndoManager->AddUndoAction(pAction);
203 
204 			// Clear the selection because the selectec object may be removed as
205 			// a result of the ssignment of the layout.
206 			mrViewShell.GetDrawView()->UnmarkAll();
207 
208 			if (!bHandoutMode)
209 			{
210 				if (pCurrentPage->GetName() != aNewName)
211 				{
212 					pCurrentPage->SetName(aNewName);
213 
214 					if (ePageKind == PK_STANDARD)
215 					{
216 						sal_uInt16 nPage = (pCurrentPage->GetPageNum()-1) / 2;
217 						SdPage* pNotesPage = pDocument->GetSdPage(nPage, PK_NOTES);
218 						if (pNotesPage != NULL)
219 							pNotesPage->SetName(aNewName);
220 					}
221 				}
222 
223 				pCurrentPage->SetAutoLayout(aNewAutoLayout, sal_True);
224 
225 				aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False);
226 				aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False);
227 				aVisibleLayers.Set(aBckgrnd, bBVisible);
228 				aVisibleLayers.Set(aBckgrndObj, bBObjsVisible);
229 				pCurrentPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
230 			}
231 			else
232 			{
233 				pHandoutMPage->SetAutoLayout(aNewAutoLayout, sal_True);
234 			}
235 
236 			mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_SWITCHPAGE,
237 				SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);
238 
239 			sal_Bool bSetModified = sal_True;
240 
241 			if (pArgs && pArgs->Count() == 1)
242 			{
243 				bSetModified = (sal_Bool) ((SfxBoolItem&) pArgs->Get(SID_MODIFYPAGE)).GetValue();
244 			}
245 
246 			pUndoManager->AddUndoAction( new UndoAutoLayoutPosAndSize( *pUndoPage ) );
247 			pUndoManager->LeaveListAction();
248 
249 			pDocument->SetChanged(bSetModified);
250         }
251     }
252     while (false);
253 
254     mrViewShell.Cancel();
255     rRequest.Done ();
256 }
257 
AssignLayout(SfxRequest & rRequest,PageKind ePageKind)258 void ViewShell::Implementation::AssignLayout ( SfxRequest& rRequest, PageKind ePageKind )
259 {
260     const SfxUInt32Item* pWhatPage = static_cast< const SfxUInt32Item*  > ( rRequest.GetArg( ID_VAL_WHATPAGE, sal_False, TYPE(SfxUInt32Item) ) );
261     const SfxUInt32Item* pWhatLayout = static_cast< const SfxUInt32Item*  > ( rRequest.GetArg( ID_VAL_WHATLAYOUT, sal_False, TYPE(SfxUInt32Item) ) );
262 
263     SdDrawDocument* pDocument = mrViewShell.GetDoc();
264 	if( !pDocument )
265 		return;
266 
267     SdPage* pPage = 0;
268     if( pWhatPage )
269     {
270 		pPage = pDocument->GetSdPage(static_cast<sal_uInt16>(pWhatPage->GetValue()), ePageKind);
271     }
272 
273     if( pPage == 0 )
274         pPage = mrViewShell.getCurrentPage();
275 
276     if( pPage )
277     {
278         AutoLayout eLayout = pPage->GetAutoLayout();
279 
280         if( pWhatLayout )
281             eLayout = static_cast< AutoLayout >( pWhatLayout->GetValue() );
282 
283         // Transform the given request into the four argument form that is
284         // understood by ProcessModifyPageSlot().
285         SdrLayerAdmin& rLayerAdmin (mrViewShell.GetViewShellBase().GetDocument()->GetLayerAdmin());
286         sal_uInt8 aBackground (rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False));
287         sal_uInt8 aBackgroundObject (rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False));
288 
289         SetOfByte aVisibleLayers;
290 
291 		if( pPage->GetPageKind() == PK_HANDOUT )
292 			aVisibleLayers.SetAll();
293 		else
294 			aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers();
295 
296 		SfxRequest aRequest (mrViewShell.GetViewShellBase().GetViewFrame(), SID_MODIFYPAGE);
297         aRequest.AppendItem(SfxStringItem (ID_VAL_PAGENAME, pPage->GetName()));
298         aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, eLayout));
299         aRequest.AppendItem(SfxBoolItem(ID_VAL_ISPAGEBACK, aVisibleLayers.IsSet(aBackground)));
300         aRequest.AppendItem(SfxBoolItem(ID_VAL_ISPAGEOBJ, aVisibleLayers.IsSet(aBackgroundObject)));
301 
302         // Forward the call with the new arguments.
303         ProcessModifyPageSlot( aRequest, pPage, pPage->GetPageKind());
304     }
305 }
306 
307 
308 
309 
GetViewId(void)310 sal_uInt16 ViewShell::Implementation::GetViewId (void)
311 {
312     switch (mrViewShell.GetShellType())
313     {
314         case ViewShell::ST_IMPRESS:
315         case ViewShell::ST_NOTES:
316         case ViewShell::ST_HANDOUT:
317             return IMPRESS_FACTORY_ID;
318 
319         case ViewShell::ST_DRAW:
320             return DRAW_FACTORY_ID;
321 
322         case ViewShell::ST_OUTLINE:
323             return OUTLINE_FACTORY_ID;
324 
325         case ViewShell::ST_SLIDE_SORTER:
326             return SLIDE_SORTER_FACTORY_ID;
327 
328         case ViewShell::ST_PRESENTATION:
329             return PRESENTATION_FACTORY_ID;
330 
331         // Since we have to return a view id for every possible shell type
332         // and there is not (yet) a proper ViewShellBase sub class for the
333         // remaining types we chose the Impress factory as a fall back.
334         case ViewShell::ST_SIDEBAR:
335         case ViewShell::ST_NONE:
336         default:
337             return IMPRESS_FACTORY_ID;
338     }
339 }
340 
341 
342 
343 
GetImageMapDialog(void)344 SvxIMapDlg* ViewShell::Implementation::GetImageMapDialog (void)
345 {
346     SvxIMapDlg* pDialog = NULL;
347     SfxChildWindow* pChildWindow = SfxViewFrame::Current()->GetChildWindow(
348         SvxIMapDlgChildWindow::GetChildWindowId());
349     if (pChildWindow != NULL)
350         pDialog = dynamic_cast<SvxIMapDlg*>(pChildWindow->GetWindow());
351     return pDialog;
352 }
353 
354 
355 
356 //===== ToolBarManagerLock ====================================================
357 
358 class ViewShell::Implementation::ToolBarManagerLock::Deleter { public:
operator ()(ToolBarManagerLock * pObject)359     void operator() (ToolBarManagerLock* pObject) { delete pObject; }
360 };
361 
362 ::boost::shared_ptr<ViewShell::Implementation::ToolBarManagerLock>
Create(const::boost::shared_ptr<ToolBarManager> & rpManager)363     ViewShell::Implementation::ToolBarManagerLock::Create (
364         const ::boost::shared_ptr<ToolBarManager>& rpManager)
365 {
366     ::boost::shared_ptr<ToolBarManagerLock> pLock (
367         new ViewShell::Implementation::ToolBarManagerLock(rpManager),
368         ViewShell::Implementation::ToolBarManagerLock::Deleter());
369     pLock->mpSelf = pLock;
370     return pLock;
371 }
372 
373 
374 
375 
ToolBarManagerLock(const::boost::shared_ptr<ToolBarManager> & rpManager)376 ViewShell::Implementation::ToolBarManagerLock::ToolBarManagerLock (
377     const ::boost::shared_ptr<ToolBarManager>& rpManager)
378     : mpLock(new ToolBarManager::UpdateLock(rpManager)),
379       maTimer()
380 {
381     // Start a timer that will unlock the ToolBarManager update lock when
382     // that is not done explicitly by calling Release().
383     maTimer.SetTimeoutHdl(LINK(this,ToolBarManagerLock,TimeoutCallback));
384     maTimer.SetTimeout(100);
385     maTimer.Start();
386 }
387 
388 
389 
390 
IMPL_LINK(ViewShell::Implementation::ToolBarManagerLock,TimeoutCallback,Timer *,EMPTYARG)391 IMPL_LINK(ViewShell::Implementation::ToolBarManagerLock,TimeoutCallback,Timer*,EMPTYARG)
392 {
393     // If possible then release the lock now.  Otherwise start the timer
394     // and try again later.
395     if (Application::IsUICaptured())
396     {
397         maTimer.Start();
398     }
399     else
400     {
401         mpSelf.reset();
402     }
403     return 0;
404 }
405 
406 
407 
408 
Release(bool bForce)409 void ViewShell::Implementation::ToolBarManagerLock::Release (bool bForce)
410 {
411     // If possible then release the lock now.  Otherwise try again when the
412     // timer expires.
413     if (bForce || ! Application::IsUICaptured())
414     {
415         mpSelf.reset();
416     }
417 }
418 
419 
420 
421 
~ToolBarManagerLock(void)422 ViewShell::Implementation::ToolBarManagerLock::~ToolBarManagerLock (void)
423 {
424     mpLock.reset();
425 }
426 
427 } // end of namespace sd
428