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 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 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 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 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 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 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: 359 void operator() (ToolBarManagerLock* pObject) { delete pObject; } 360 }; 361 362 ::boost::shared_ptr<ViewShell::Implementation::ToolBarManagerLock> 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 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 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 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 422 ViewShell::Implementation::ToolBarManagerLock::~ToolBarManagerLock (void) 423 { 424 mpLock.reset(); 425 } 426 427 } // end of namespace sd 428