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 "taskpane/PanelId.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, 152 ::sd::toolpanel::PID_LAYOUT); 153 SfxViewFrame* pFrame = mrViewShell.GetViewFrame(); 154 if (pFrame!=NULL && pFrame->GetDispatcher()!=NULL) 155 { 156 pFrame->GetDispatcher()->Execute ( 157 SID_SHOW_TOOL_PANEL, 158 SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, 159 &aMakeToolPaneVisible, 160 &aPanelId, 161 NULL); 162 } 163 else 164 { 165 DBG_ASSERT(pFrame!=NULL && pFrame->GetDispatcher()!=NULL, 166 "ViewShell::Implementation::ProcessModifyPageSlot(): can not get dispatcher"); 167 } 168 169 // We have activated a non-modal control in the task pane. 170 // Because it does not return anything we can not do anything 171 // more right now and have to exit here. 172 break; 173 } 174 else if (pArgs->Count() == 4) 175 { 176 SFX_REQUEST_ARG (rRequest, pNewName, SfxStringItem, ID_VAL_PAGENAME, sal_False); 177 SFX_REQUEST_ARG (rRequest, pNewAutoLayout, SfxUInt32Item, ID_VAL_WHATLAYOUT, sal_False); 178 SFX_REQUEST_ARG (rRequest, pBVisible, SfxBoolItem, ID_VAL_ISPAGEBACK, sal_False); 179 SFX_REQUEST_ARG (rRequest, pBObjsVisible, SfxBoolItem, ID_VAL_ISPAGEOBJ, sal_False); 180 AutoLayout aLayout ((AutoLayout)pNewAutoLayout->GetValue ()); 181 if (aLayout >= AUTOLAYOUT__START 182 && aLayout < AUTOLAYOUT__END) 183 { 184 aNewName = pNewName->GetValue (); 185 aNewAutoLayout = (AutoLayout) pNewAutoLayout->GetValue (); 186 bBVisible = pBVisible->GetValue (); 187 bBObjsVisible = pBObjsVisible->GetValue (); 188 } 189 else 190 { 191 StarBASIC::FatalError (SbERR_BAD_PROP_VALUE); 192 rRequest.Ignore (); 193 break; 194 } 195 if (ePageKind == PK_HANDOUT) 196 { 197 bHandoutMode = sal_True; 198 pHandoutMPage = pDocument->GetMasterSdPage(0, PK_HANDOUT); 199 } 200 } 201 else 202 { 203 StarBASIC::FatalError (SbERR_WRONG_ARGS); 204 rRequest.Ignore (); 205 break; 206 } 207 208 SdPage* pUndoPage = 209 bHandoutMode ? pHandoutMPage : pCurrentPage; 210 211 ::svl::IUndoManager* pUndoManager = mrViewShell.GetDocSh()->GetUndoManager(); 212 DBG_ASSERT(pUndoManager, "No UNDO MANAGER ?!?"); 213 214 if( pUndoManager ) 215 { 216 String aComment( SdResId(STR_UNDO_MODIFY_PAGE) ); 217 pUndoManager->EnterListAction(aComment, aComment); 218 ModifyPageUndoAction* pAction = new ModifyPageUndoAction( 219 pDocument, pUndoPage, aNewName, aNewAutoLayout, bBVisible, bBObjsVisible); 220 pUndoManager->AddUndoAction(pAction); 221 222 // Clear the selection because the selectec object may be removed as 223 // a result of the ssignment of the layout. 224 mrViewShell.GetDrawView()->UnmarkAll(); 225 226 if (!bHandoutMode) 227 { 228 if (pCurrentPage->GetName() != aNewName) 229 { 230 pCurrentPage->SetName(aNewName); 231 232 if (ePageKind == PK_STANDARD) 233 { 234 sal_uInt16 nPage = (pCurrentPage->GetPageNum()-1) / 2; 235 SdPage* pNotesPage = pDocument->GetSdPage(nPage, PK_NOTES); 236 if (pNotesPage != NULL) 237 pNotesPage->SetName(aNewName); 238 } 239 } 240 241 pCurrentPage->SetAutoLayout(aNewAutoLayout, sal_True); 242 243 aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False); 244 aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False); 245 aVisibleLayers.Set(aBckgrnd, bBVisible); 246 aVisibleLayers.Set(aBckgrndObj, bBObjsVisible); 247 pCurrentPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers); 248 } 249 else 250 { 251 pHandoutMPage->SetAutoLayout(aNewAutoLayout, sal_True); 252 } 253 254 mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_SWITCHPAGE, 255 SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); 256 257 sal_Bool bSetModified = sal_True; 258 259 if (pArgs && pArgs->Count() == 1) 260 { 261 bSetModified = (sal_Bool) ((SfxBoolItem&) pArgs->Get(SID_MODIFYPAGE)).GetValue(); 262 } 263 264 pUndoManager->AddUndoAction( new UndoAutoLayoutPosAndSize( *pUndoPage ) ); 265 pUndoManager->LeaveListAction(); 266 267 pDocument->SetChanged(bSetModified); 268 } 269 } 270 while (false); 271 272 mrViewShell.Cancel(); 273 rRequest.Done (); 274 } 275 276 void ViewShell::Implementation::AssignLayout ( SfxRequest& rRequest, PageKind ePageKind ) 277 { 278 const SfxUInt32Item* pWhatPage = static_cast< const SfxUInt32Item* > ( rRequest.GetArg( ID_VAL_WHATPAGE, sal_False, TYPE(SfxUInt32Item) ) ); 279 const SfxUInt32Item* pWhatLayout = static_cast< const SfxUInt32Item* > ( rRequest.GetArg( ID_VAL_WHATLAYOUT, sal_False, TYPE(SfxUInt32Item) ) ); 280 281 SdDrawDocument* pDocument = mrViewShell.GetDoc(); 282 if( !pDocument ) 283 return; 284 285 SdPage* pPage = 0; 286 if( pWhatPage ) 287 { 288 pPage = pDocument->GetSdPage(static_cast<sal_uInt16>(pWhatPage->GetValue()), ePageKind); 289 } 290 291 if( pPage == 0 ) 292 pPage = mrViewShell.getCurrentPage(); 293 294 if( pPage ) 295 { 296 AutoLayout eLayout = pPage->GetAutoLayout(); 297 298 if( pWhatLayout ) 299 eLayout = static_cast< AutoLayout >( pWhatLayout->GetValue() ); 300 301 // Transform the given request into the four argument form that is 302 // understood by ProcessModifyPageSlot(). 303 SdrLayerAdmin& rLayerAdmin (mrViewShell.GetViewShellBase().GetDocument()->GetLayerAdmin()); 304 sal_uInt8 aBackground (rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False)); 305 sal_uInt8 aBackgroundObject (rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False)); 306 307 SetOfByte aVisibleLayers; 308 309 if( pPage->GetPageKind() == PK_HANDOUT ) 310 aVisibleLayers.SetAll(); 311 else 312 aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); 313 314 SfxRequest aRequest (mrViewShell.GetViewShellBase().GetViewFrame(), SID_MODIFYPAGE); 315 aRequest.AppendItem(SfxStringItem (ID_VAL_PAGENAME, pPage->GetName())); 316 aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, eLayout)); 317 aRequest.AppendItem(SfxBoolItem(ID_VAL_ISPAGEBACK, aVisibleLayers.IsSet(aBackground))); 318 aRequest.AppendItem(SfxBoolItem(ID_VAL_ISPAGEOBJ, aVisibleLayers.IsSet(aBackgroundObject))); 319 320 // Forward the call with the new arguments. 321 ProcessModifyPageSlot( aRequest, pPage, pPage->GetPageKind()); 322 } 323 } 324 325 326 327 328 sal_uInt16 ViewShell::Implementation::GetViewId (void) 329 { 330 switch (mrViewShell.GetShellType()) 331 { 332 case ViewShell::ST_IMPRESS: 333 case ViewShell::ST_NOTES: 334 case ViewShell::ST_HANDOUT: 335 return IMPRESS_FACTORY_ID; 336 337 case ViewShell::ST_DRAW: 338 return DRAW_FACTORY_ID; 339 340 case ViewShell::ST_OUTLINE: 341 return OUTLINE_FACTORY_ID; 342 343 case ViewShell::ST_SLIDE_SORTER: 344 return SLIDE_SORTER_FACTORY_ID; 345 346 case ViewShell::ST_PRESENTATION: 347 return PRESENTATION_FACTORY_ID; 348 349 // Since we have to return a view id for every possible shell type 350 // and there is not (yet) a proper ViewShellBase sub class for the 351 // remaining types we chose the Impress factory as a fall back. 352 case ViewShell::ST_TASK_PANE: 353 case ViewShell::ST_NONE: 354 default: 355 return IMPRESS_FACTORY_ID; 356 } 357 } 358 359 360 361 362 SvxIMapDlg* ViewShell::Implementation::GetImageMapDialog (void) 363 { 364 SvxIMapDlg* pDialog = NULL; 365 SfxChildWindow* pChildWindow = SfxViewFrame::Current()->GetChildWindow( 366 SvxIMapDlgChildWindow::GetChildWindowId()); 367 if (pChildWindow != NULL) 368 pDialog = dynamic_cast<SvxIMapDlg*>(pChildWindow->GetWindow()); 369 return pDialog; 370 } 371 372 373 374 //===== ToolBarManagerLock ==================================================== 375 376 class ViewShell::Implementation::ToolBarManagerLock::Deleter { public: 377 void operator() (ToolBarManagerLock* pObject) { delete pObject; } 378 }; 379 380 ::boost::shared_ptr<ViewShell::Implementation::ToolBarManagerLock> 381 ViewShell::Implementation::ToolBarManagerLock::Create ( 382 const ::boost::shared_ptr<ToolBarManager>& rpManager) 383 { 384 ::boost::shared_ptr<ToolBarManagerLock> pLock ( 385 new ViewShell::Implementation::ToolBarManagerLock(rpManager), 386 ViewShell::Implementation::ToolBarManagerLock::Deleter()); 387 pLock->mpSelf = pLock; 388 return pLock; 389 } 390 391 392 393 394 ViewShell::Implementation::ToolBarManagerLock::ToolBarManagerLock ( 395 const ::boost::shared_ptr<ToolBarManager>& rpManager) 396 : mpLock(new ToolBarManager::UpdateLock(rpManager)), 397 maTimer() 398 { 399 // Start a timer that will unlock the ToolBarManager update lock when 400 // that is not done explicitly by calling Release(). 401 maTimer.SetTimeoutHdl(LINK(this,ToolBarManagerLock,TimeoutCallback)); 402 maTimer.SetTimeout(100); 403 maTimer.Start(); 404 } 405 406 407 408 409 IMPL_LINK(ViewShell::Implementation::ToolBarManagerLock,TimeoutCallback,Timer*,EMPTYARG) 410 { 411 // If possible then release the lock now. Otherwise start the timer 412 // and try again later. 413 if (Application::IsUICaptured()) 414 { 415 maTimer.Start(); 416 } 417 else 418 { 419 mpSelf.reset(); 420 } 421 return 0; 422 } 423 424 425 426 427 void ViewShell::Implementation::ToolBarManagerLock::Release (bool bForce) 428 { 429 // If possible then release the lock now. Otherwise try again when the 430 // timer expires. 431 if (bForce || ! Application::IsUICaptured()) 432 { 433 mpSelf.reset(); 434 } 435 } 436 437 438 439 440 ViewShell::Implementation::ToolBarManagerLock::~ToolBarManagerLock (void) 441 { 442 mpLock.reset(); 443 } 444 445 } // end of namespace sd 446