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