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