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 "TabControl.hxx" 32 33 #include <sfx2/viewfrm.hxx> 34 #include <svx/svdlayer.hxx> 35 #include <svx/svdpagv.hxx> 36 #include <sfx2/dispatch.hxx> 37 38 39 #include "sdattr.hxx" 40 #include "app.hxx" 41 #include "app.hrc" 42 #include "glob.hrc" 43 #include "res_bmp.hrc" 44 #include "DrawViewShell.hxx" 45 #include "GraphicViewShell.hxx" 46 #include "helpids.h" 47 #include "View.hxx" 48 #include "sdpage.hxx" 49 #include "drawdoc.hxx" 50 #include "Window.hxx" 51 #include "unmodpg.hxx" 52 #include "DrawDocShell.hxx" 53 #include "sdresid.hxx" 54 55 56 namespace sd { 57 58 #define SWITCH_TIMEOUT 20 59 60 // ----------------------------------------- 61 // - SdTabControl::SdPageObjsTransferable - 62 // ----------------------------------------- 63 64 TabControl::TabControlTransferable::~TabControlTransferable() 65 { 66 } 67 68 // ----------------------------------------------------------------------------- 69 70 void TabControl::TabControlTransferable::AddSupportedFormats() 71 { 72 AddFormat( SOT_FORMATSTR_ID_STARDRAW_TABBAR ); 73 } 74 75 // ----------------------------------------------------------------------------- 76 77 sal_Bool TabControl::TabControlTransferable::GetData( const ::com::sun::star::datatransfer::DataFlavor& ) 78 { 79 return sal_False; 80 } 81 82 // ----------------------------------------------------------------------------- 83 84 void TabControl::TabControlTransferable::DragFinished( sal_Int8 nDropAction ) 85 { 86 mrParent.DragFinished( nDropAction ); 87 } 88 89 /************************************************************************* 90 |* 91 |* Standard-Konstruktor 92 |* 93 \************************************************************************/ 94 95 TabControl::TabControl(DrawViewShell* pViewSh, Window* pParent) : 96 TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL | WB_SIZEABLE | WB_DRAG) ), 97 DragSourceHelper( this ), 98 DropTargetHelper( this ), 99 pDrViewSh(pViewSh), 100 bInternalMove(sal_False) 101 { 102 EnableEditMode(); 103 SetSizePixel(Size(0, 0)); 104 SetMaxPageWidth( 150 ); 105 SetHelpId( HID_SD_TABBAR_PAGES ); 106 } 107 108 /************************************************************************* 109 |* 110 |* Destruktor 111 |* 112 \************************************************************************/ 113 114 TabControl::~TabControl() 115 { 116 } 117 118 /************************************************************************* 119 |* 120 \************************************************************************/ 121 122 void TabControl::Select() 123 { 124 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); 125 pDispatcher->Execute(SID_SWITCHPAGE, SFX_CALLMODE_ASYNCHRON | 126 SFX_CALLMODE_RECORD); 127 } 128 129 /************************************************************************* 130 |* 131 \************************************************************************/ 132 133 void TabControl::MouseButtonDown(const MouseEvent& rMEvt) 134 { 135 if (rMEvt.IsLeft() 136 && !rMEvt.IsMod1() 137 && !rMEvt.IsMod2() 138 && !rMEvt.IsShift()) 139 { 140 Point aPos = PixelToLogic( rMEvt.GetPosPixel() ); 141 sal_uInt16 aPageId = GetPageId(aPos); 142 143 if (aPageId == 0) 144 { 145 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); 146 147 pDispatcher->Execute(SID_INSERTPAGE_QUICK, 148 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD); 149 } 150 } 151 152 // A single left click with pressed control key on a tab page first 153 // switches to that page before the usual handling (copying with drag 154 // and drop) takes place. 155 else if (rMEvt.IsLeft() && rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift()) 156 { 157 pDrViewSh->SwitchPage (GetPageId (rMEvt.GetPosPixel()) - 1); 158 } 159 160 // When only the right button is pressed then first process a 161 // synthesized left button click to make the page the current one 162 // whose tab has been clicked. When then the actual right button 163 // click is processed the resulting context menu relates to the 164 // now current page. 165 if (rMEvt.IsRight() && ! rMEvt.IsLeft()) 166 { 167 MouseEvent aSyntheticEvent ( 168 rMEvt.GetPosPixel(), 169 rMEvt.GetClicks(), 170 rMEvt.GetMode(), 171 MOUSE_LEFT, 172 rMEvt.GetModifier()); 173 TabBar::MouseButtonDown(aSyntheticEvent); 174 } 175 176 TabBar::MouseButtonDown(rMEvt); 177 } 178 179 /************************************************************************* 180 |* 181 \************************************************************************/ 182 183 void TabControl::DoubleClick() 184 { 185 if (GetCurPageId() != 0) 186 { 187 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); 188 pDispatcher->Execute( SID_MODIFYPAGE, 189 SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); 190 } 191 } 192 193 /************************************************************************* 194 |* 195 |* StartDrag-Request 196 |* 197 \************************************************************************/ 198 199 void TabControl::StartDrag( sal_Int8, const Point& ) 200 { 201 bInternalMove = sal_True; 202 203 // object is delete by reference mechanismn 204 ( new TabControl::TabControlTransferable( *this ) )->StartDrag( this, DND_ACTION_COPYMOVE ); 205 } 206 207 /************************************************************************* 208 |* 209 |* DragFinished 210 |* 211 \************************************************************************/ 212 213 void TabControl::DragFinished( sal_Int8 ) 214 { 215 bInternalMove = sal_False; 216 } 217 218 /************************************************************************* 219 |* 220 |* AcceptDrop-Event 221 |* 222 \************************************************************************/ 223 224 sal_Int8 TabControl::AcceptDrop( const AcceptDropEvent& rEvt ) 225 { 226 sal_Int8 nRet = DND_ACTION_NONE; 227 228 if( rEvt.mbLeaving ) 229 EndSwitchPage(); 230 231 if( !pDrViewSh->GetDocSh()->IsReadOnly() ) 232 { 233 SdDrawDocument* pDoc = pDrViewSh->GetDoc(); 234 Point aPos( rEvt.maPosPixel ); 235 236 if( bInternalMove ) 237 { 238 if( rEvt.mbLeaving || ( pDrViewSh->GetEditMode() == EM_MASTERPAGE ) ) 239 HideDropPos(); 240 else 241 { 242 ShowDropPos( aPos ); 243 nRet = rEvt.mnAction; 244 } 245 } 246 else 247 { 248 HideDropPos(); 249 250 sal_Int32 nPageId = GetPageId( aPos ) - 1; 251 252 if( ( nPageId >= 0 ) && pDoc->GetPage( (sal_uInt16)nPageId ) ) 253 { 254 nRet = pDrViewSh->AcceptDrop( rEvt, *this, NULL, (sal_uInt16)nPageId, SDRLAYER_NOTFOUND ); 255 SwitchPage( aPos ); 256 } 257 } 258 } 259 260 return nRet; 261 } 262 263 /************************************************************************* 264 |* 265 |* ExecuteDrop-Event 266 |* 267 \************************************************************************/ 268 269 sal_Int8 TabControl::ExecuteDrop( const ExecuteDropEvent& rEvt ) 270 { 271 SdDrawDocument* pDoc = pDrViewSh->GetDoc(); 272 Point aPos( rEvt.maPosPixel ); 273 sal_Int8 nRet = DND_ACTION_NONE; 274 275 if( bInternalMove ) 276 { 277 sal_uInt16 nPageId = ShowDropPos( aPos ) - 1; 278 279 switch (rEvt.mnAction) 280 { 281 case DND_ACTION_MOVE: 282 if( pDrViewSh->IsSwitchPageAllowed() && pDoc->MovePages( nPageId ) ) 283 { 284 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); 285 pDispatcher->Execute(SID_SWITCHPAGE, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); 286 } 287 break; 288 289 case DND_ACTION_COPY: 290 { 291 // Copying the selected page to the place that rEvt points 292 // takes place in three steps: 293 // 1. Create a copy of the selected page. This copy will 294 // lie directly behind the selected page. 295 // 2. Move the copy to the desired place. 296 // 3. Select the copy. 297 if (pDrViewSh->IsSwitchPageAllowed()) 298 { 299 // 1. Create a copy. 300 sal_uInt16 nPageNumOfCopy = pDoc->DuplicatePage (GetCurPageId() - 1); 301 // 2. Move page. For this first switch to the copy: 302 // MovePages operates on the currently selected page(s). 303 pDrViewSh->SwitchPage (nPageNumOfCopy); 304 // Adapt target page id when necessary, i.e. page copy 305 // has been inserted in front of the target page. 306 sal_uInt16 nPageNum = nPageId; 307 if ((nPageNumOfCopy <= nPageNum) && (nPageNum != (sal_uInt16)-1)) 308 nPageNum += 1; 309 if (pDoc->MovePages(nPageNum)) 310 { 311 // 3. Switch to the copy that has been moved to its 312 // final destination. Use an asynchron slot call to 313 // be executed after the still pending ones. 314 if (nPageNumOfCopy >= nPageNum || (nPageNum == (sal_uInt16)-1)) 315 nPageNum += 1; 316 SetCurPageId (GetPageId(nPageNum)); 317 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); 318 pDispatcher->Execute(SID_SWITCHPAGE, 319 SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); 320 } 321 } 322 323 break; 324 } 325 } 326 327 nRet = rEvt.mnAction; 328 } 329 else 330 { 331 sal_Int32 nPageId = GetPageId( aPos ) - 1; 332 333 if( ( nPageId >= 0 ) && pDoc->GetPage( (sal_uInt16)nPageId ) ) 334 { 335 nRet = pDrViewSh->ExecuteDrop( rEvt, *this, NULL, (sal_uInt16)nPageId, SDRLAYER_NOTFOUND ); 336 } 337 } 338 339 HideDropPos(); 340 EndSwitchPage(); 341 342 return nRet; 343 } 344 345 /************************************************************************* 346 |* 347 \************************************************************************/ 348 349 void TabControl::Command(const CommandEvent& rCEvt) 350 { 351 sal_uInt16 nCmd = rCEvt.GetCommand(); 352 353 if ( nCmd == COMMAND_CONTEXTMENU ) 354 { 355 sal_Bool bGraphicShell = pDrViewSh->ISA(GraphicViewShell); 356 sal_uInt16 nResId = bGraphicShell ? RID_GRAPHIC_PAGETAB_POPUP : 357 RID_DRAW_PAGETAB_POPUP; 358 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); 359 pDispatcher->ExecutePopup( SdResId( nResId ) ); 360 } 361 } 362 363 /************************************************************************* 364 |* 365 \************************************************************************/ 366 367 long TabControl::StartRenaming() 368 { 369 sal_Bool bOK = sal_False; 370 371 if (pDrViewSh->GetPageKind() == PK_STANDARD) 372 { 373 bOK = sal_True; 374 375 ::sd::View* pView = pDrViewSh->GetView(); 376 377 if ( pView->IsTextEdit() ) 378 pView->SdrEndTextEdit(); 379 } 380 381 return( bOK ); 382 } 383 384 /************************************************************************* 385 |* 386 \************************************************************************/ 387 388 long TabControl::AllowRenaming() 389 { 390 sal_Bool bOK = sal_True; 391 392 String aNewName( GetEditText() ); 393 String aCompareName( GetPageText( GetEditPageId() ) ); 394 395 if( aCompareName != aNewName ) 396 { 397 // Seite umbenennen 398 if( pDrViewSh->GetDocSh()->CheckPageName( this, aNewName ) ) 399 { 400 SetEditText( aNewName ); 401 EndRenaming(); 402 } 403 else 404 { 405 bOK = sal_False; 406 } 407 } 408 return( bOK ); 409 } 410 411 /************************************************************************* 412 |* 413 \************************************************************************/ 414 415 void TabControl::EndRenaming() 416 { 417 if( !IsEditModeCanceled() ) 418 pDrViewSh->RenameSlide( GetEditPageId(), GetEditText() ); 419 } 420 421 422 /************************************************************************* 423 |* 424 \************************************************************************/ 425 426 void TabControl::ActivatePage() 427 { 428 if ( /*IsInSwitching && */ pDrViewSh->IsSwitchPageAllowed() ) 429 { 430 SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); 431 pDispatcher->Execute(SID_SWITCHPAGE, 432 SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD); 433 } 434 } 435 436 437 /************************************************************************* 438 |* 439 \************************************************************************/ 440 441 long TabControl::DeactivatePage() 442 { 443 return pDrViewSh->IsSwitchPageAllowed(); 444 } 445 446 447 448 449 void TabControl::SendActivatePageEvent (void) 450 { 451 CallEventListeners (VCLEVENT_TABBAR_PAGEACTIVATED, 452 reinterpret_cast<void*>(GetCurPageId())); 453 } 454 455 456 457 458 void TabControl::SendDeactivatePageEvent (void) 459 { 460 CallEventListeners (VCLEVENT_TABBAR_PAGEDEACTIVATED, 461 reinterpret_cast<void*>(GetCurPageId())); 462 } 463 464 } // end of namespace sd 465