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