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 selected object may be removed as
205 			// a result of the assignment 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