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_svtools.hxx" 30 31 /* 32 Todo: 33 - Anker loeschen in SelectionEngine bei manuellem Selektieren 34 - SelectAll( sal_False ), nur die deselektierten Entries repainten 35 */ 36 37 #include <string.h> 38 #include <svtools/svlbox.hxx> 39 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 40 #include <vcl/svapp.hxx> 41 #include <vcl/accel.hxx> 42 #include <vcl/i18nhelp.hxx> 43 #include <sot/formats.hxx> 44 #include <unotools/accessiblestatesethelper.hxx> 45 #include <rtl/instance.hxx> 46 47 #define _SVSTDARR_ULONGSSORT 48 #include <svl/svstdarr.hxx> 49 50 #ifndef _SVEDI_HXX 51 #include <svtools/svmedit.hxx> 52 #endif 53 #include <svtools/svlbitm.hxx> 54 55 using namespace ::com::sun::star::accessibility; 56 57 // Drag&Drop 58 static SvLBox* pDDSource = NULL; 59 static SvLBox* pDDTarget = NULL; 60 61 DBG_NAME(SvInplaceEdit) 62 DBG_NAME(SvInplaceEdit2) 63 64 #define SVLBOX_ACC_RETURN 1 65 #define SVLBOX_ACC_ESCAPE 2 66 67 SvInplaceEdit::SvInplaceEdit 68 ( 69 Window* pParent, 70 const Point& rPos, 71 const Size& rSize, 72 const String& rData, 73 const Link& rNotifyEditEnd, 74 const Selection& rSelection 75 ) : 76 77 Edit( pParent, WB_LEFT ), 78 79 aCallBackHdl ( rNotifyEditEnd ), 80 bCanceled ( sal_False ), 81 bAlreadyInCallBack ( sal_False ) 82 83 { 84 DBG_CTOR(SvInplaceEdit,0); 85 86 Font aFont( pParent->GetFont() ); 87 aFont.SetTransparent( sal_False ); 88 Color aColor( pParent->GetBackground().GetColor() ); 89 aFont.SetFillColor(aColor ); 90 SetFont( aFont ); 91 SetBackground( pParent->GetBackground() ); 92 SetPosPixel( rPos ); 93 SetSizePixel( rSize ); 94 SetText( rData ); 95 SetSelection( rSelection ); 96 SaveValue(); 97 98 aAccReturn.InsertItem( SVLBOX_ACC_RETURN, KeyCode(KEY_RETURN) ); 99 aAccEscape.InsertItem( SVLBOX_ACC_ESCAPE, KeyCode(KEY_ESCAPE) ); 100 101 aAccReturn.SetActivateHdl( LINK( this, SvInplaceEdit, ReturnHdl_Impl) ); 102 aAccEscape.SetActivateHdl( LINK( this, SvInplaceEdit, EscapeHdl_Impl) ); 103 GetpApp()->InsertAccel( &aAccReturn ); 104 GetpApp()->InsertAccel( &aAccEscape ); 105 106 Show(); 107 GrabFocus(); 108 } 109 110 SvInplaceEdit::~SvInplaceEdit() 111 { 112 DBG_DTOR(SvInplaceEdit,0); 113 if( !bAlreadyInCallBack ) 114 { 115 GetpApp()->RemoveAccel( &aAccReturn ); 116 GetpApp()->RemoveAccel( &aAccEscape ); 117 } 118 } 119 120 IMPL_LINK_INLINE_START( SvInplaceEdit, ReturnHdl_Impl, Accelerator *, EMPTYARG ) 121 { 122 DBG_CHKTHIS(SvInplaceEdit,0); 123 bCanceled = sal_False; 124 CallCallBackHdl_Impl(); 125 return 1; 126 } 127 IMPL_LINK_INLINE_END( SvInplaceEdit, ReturnHdl_Impl, Accelerator *, EMPTYARG ) 128 129 IMPL_LINK_INLINE_START( SvInplaceEdit, EscapeHdl_Impl, Accelerator *, EMPTYARG ) 130 { 131 DBG_CHKTHIS(SvInplaceEdit,0); 132 bCanceled = sal_True; 133 CallCallBackHdl_Impl(); 134 return 1; 135 } 136 IMPL_LINK_INLINE_END( SvInplaceEdit, EscapeHdl_Impl, Accelerator *, EMPTYARG ) 137 138 void SvInplaceEdit::KeyInput( const KeyEvent& rKEvt ) 139 { 140 DBG_CHKTHIS(SvInplaceEdit,0); 141 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); 142 switch ( nCode ) 143 { 144 case KEY_ESCAPE: 145 bCanceled = sal_True; 146 CallCallBackHdl_Impl(); 147 break; 148 149 case KEY_RETURN: 150 bCanceled = sal_False; 151 CallCallBackHdl_Impl(); 152 break; 153 154 default: 155 Edit::KeyInput( rKEvt ); 156 } 157 } 158 159 void SvInplaceEdit::StopEditing( sal_Bool bCancel ) 160 { 161 DBG_CHKTHIS(SvInplaceEdit,0); 162 if ( !bAlreadyInCallBack ) 163 { 164 bCanceled = bCancel; 165 CallCallBackHdl_Impl(); 166 } 167 } 168 169 void SvInplaceEdit::LoseFocus() 170 { 171 DBG_CHKTHIS(SvInplaceEdit,0); 172 if ( !bAlreadyInCallBack ) 173 { 174 bCanceled = sal_False; 175 aTimer.SetTimeout(10); 176 aTimer.SetTimeoutHdl(LINK(this,SvInplaceEdit,Timeout_Impl)); 177 aTimer.Start(); 178 } 179 } 180 181 IMPL_LINK_INLINE_START( SvInplaceEdit, Timeout_Impl, Timer *, EMPTYARG ) 182 { 183 DBG_CHKTHIS(SvInplaceEdit,0); 184 CallCallBackHdl_Impl(); 185 return 0; 186 } 187 IMPL_LINK_INLINE_END( SvInplaceEdit, Timeout_Impl, Timer *, EMPTYARG ) 188 189 void SvInplaceEdit::CallCallBackHdl_Impl() 190 { 191 DBG_CHKTHIS(SvInplaceEdit,0); 192 aTimer.Stop(); 193 if ( !bAlreadyInCallBack ) 194 { 195 bAlreadyInCallBack = sal_True; 196 GetpApp()->RemoveAccel( &aAccReturn ); 197 GetpApp()->RemoveAccel( &aAccEscape ); 198 Hide(); 199 aCallBackHdl.Call( this ); 200 // bAlreadyInCallBack = sal_False; 201 } 202 } 203 204 205 // *************************************************************** 206 207 class MyEdit_Impl : public Edit 208 { 209 SvInplaceEdit2* pOwner; 210 public: 211 MyEdit_Impl( Window* pParent, SvInplaceEdit2* pOwner ); 212 virtual void KeyInput( const KeyEvent& rKEvt ); 213 virtual void LoseFocus(); 214 }; 215 216 class MyMultiEdit_Impl : public MultiLineEdit 217 { 218 SvInplaceEdit2* pOwner; 219 public: 220 MyMultiEdit_Impl( Window* pParent, SvInplaceEdit2* pOwner ); 221 virtual void KeyInput( const KeyEvent& rKEvt ); 222 virtual void LoseFocus(); 223 }; 224 225 MyEdit_Impl::MyEdit_Impl( Window* pParent, SvInplaceEdit2* _pOwner ) : 226 227 Edit( pParent, WB_LEFT ), 228 229 pOwner( _pOwner ) 230 231 { 232 } 233 234 void MyEdit_Impl::KeyInput( const KeyEvent& rKEvt ) 235 { 236 if( !pOwner->KeyInput( rKEvt )) 237 Edit::KeyInput( rKEvt ); 238 } 239 240 void MyEdit_Impl::LoseFocus() 241 { 242 pOwner->LoseFocus(); 243 } 244 245 MyMultiEdit_Impl::MyMultiEdit_Impl( Window* pParent, SvInplaceEdit2* _pOwner ) 246 : MultiLineEdit( pParent, 247 WB_CENTER 248 ), pOwner(_pOwner) 249 { 250 } 251 252 void MyMultiEdit_Impl::KeyInput( const KeyEvent& rKEvt ) 253 { 254 if( !pOwner->KeyInput( rKEvt )) 255 MultiLineEdit::KeyInput( rKEvt ); 256 } 257 258 void MyMultiEdit_Impl::LoseFocus() 259 { 260 pOwner->LoseFocus(); 261 } 262 263 264 SvInplaceEdit2::SvInplaceEdit2 265 ( 266 Window* pParent, const Point& rPos, 267 const Size& rSize, 268 const String& rData, 269 const Link& rNotifyEditEnd, 270 const Selection& rSelection, 271 sal_Bool bMulti 272 ) : 273 274 aCallBackHdl ( rNotifyEditEnd ), 275 bCanceled ( sal_False ), 276 bAlreadyInCallBack ( sal_False ), 277 bMultiLine ( bMulti ) 278 279 { 280 DBG_CTOR(SvInplaceEdit2,0); 281 282 if( bMulti ) 283 pEdit = new MyMultiEdit_Impl( pParent, this ); 284 else 285 pEdit = new MyEdit_Impl( pParent, this ); 286 287 Font aFont( pParent->GetFont() ); 288 aFont.SetTransparent( sal_False ); 289 Color aColor( pParent->GetBackground().GetColor() ); 290 aFont.SetFillColor(aColor ); 291 pEdit->SetFont( aFont ); 292 pEdit->SetBackground( pParent->GetBackground() ); 293 pEdit->SetPosPixel( rPos ); 294 pEdit->SetSizePixel( rSize ); 295 pEdit->SetText( rData ); 296 pEdit->SetSelection( rSelection ); 297 pEdit->SaveValue(); 298 299 aAccReturn.InsertItem( SVLBOX_ACC_RETURN, KeyCode(KEY_RETURN) ); 300 aAccEscape.InsertItem( SVLBOX_ACC_ESCAPE, KeyCode(KEY_ESCAPE) ); 301 302 aAccReturn.SetActivateHdl( LINK( this, SvInplaceEdit2, ReturnHdl_Impl) ); 303 aAccEscape.SetActivateHdl( LINK( this, SvInplaceEdit2, EscapeHdl_Impl) ); 304 GetpApp()->InsertAccel( &aAccReturn ); 305 GetpApp()->InsertAccel( &aAccEscape ); 306 307 pEdit->Show(); 308 pEdit->GrabFocus(); 309 } 310 311 SvInplaceEdit2::~SvInplaceEdit2() 312 { 313 DBG_DTOR(SvInplaceEdit2,0); 314 if( !bAlreadyInCallBack ) 315 { 316 GetpApp()->RemoveAccel( &aAccReturn ); 317 GetpApp()->RemoveAccel( &aAccEscape ); 318 } 319 delete pEdit; 320 } 321 322 String SvInplaceEdit2::GetSavedValue() const 323 { 324 return pEdit->GetSavedValue(); 325 } 326 327 void SvInplaceEdit2::Hide() 328 { 329 pEdit->Hide(); 330 } 331 332 333 IMPL_LINK_INLINE_START( SvInplaceEdit2, ReturnHdl_Impl, Accelerator *, EMPTYARG ) 334 { 335 DBG_CHKTHIS(SvInplaceEdit2,0); 336 bCanceled = sal_False; 337 CallCallBackHdl_Impl(); 338 return 1; 339 } 340 IMPL_LINK_INLINE_END( SvInplaceEdit2, ReturnHdl_Impl, Accelerator *, EMPTYARG ) 341 342 IMPL_LINK_INLINE_START( SvInplaceEdit2, EscapeHdl_Impl, Accelerator *, EMPTYARG ) 343 { 344 DBG_CHKTHIS(SvInplaceEdit2,0); 345 bCanceled = sal_True; 346 CallCallBackHdl_Impl(); 347 return 1; 348 } 349 IMPL_LINK_INLINE_END( SvInplaceEdit2, EscapeHdl_Impl, Accelerator *, EMPTYARG ) 350 351 352 sal_Bool SvInplaceEdit2::KeyInput( const KeyEvent& rKEvt ) 353 { 354 DBG_CHKTHIS(SvInplaceEdit2,0); 355 KeyCode aCode = rKEvt.GetKeyCode(); 356 sal_uInt16 nCode = aCode.GetCode(); 357 358 switch ( nCode ) 359 { 360 case KEY_ESCAPE: 361 bCanceled = sal_True; 362 CallCallBackHdl_Impl(); 363 return sal_True; 364 365 case KEY_RETURN: 366 bCanceled = sal_False; 367 CallCallBackHdl_Impl(); 368 return sal_True; 369 } 370 return sal_False; 371 } 372 373 void SvInplaceEdit2::StopEditing( sal_Bool bCancel ) 374 { 375 DBG_CHKTHIS(SvInplaceEdit2,0); 376 if ( !bAlreadyInCallBack ) 377 { 378 bCanceled = bCancel; 379 CallCallBackHdl_Impl(); 380 } 381 } 382 383 void SvInplaceEdit2::LoseFocus() 384 { 385 DBG_CHKTHIS(SvInplaceEdit2,0); 386 if ( !bAlreadyInCallBack 387 && ((!Application::GetFocusWindow()) || !pEdit->IsChild( Application::GetFocusWindow()) ) 388 ) 389 { 390 bCanceled = sal_False; 391 aTimer.SetTimeout(10); 392 aTimer.SetTimeoutHdl(LINK(this,SvInplaceEdit2,Timeout_Impl)); 393 aTimer.Start(); 394 } 395 } 396 397 IMPL_LINK_INLINE_START( SvInplaceEdit2, Timeout_Impl, Timer *, EMPTYARG ) 398 { 399 DBG_CHKTHIS(SvInplaceEdit2,0); 400 CallCallBackHdl_Impl(); 401 return 0; 402 } 403 IMPL_LINK_INLINE_END( SvInplaceEdit2, Timeout_Impl, Timer *, EMPTYARG ) 404 405 void SvInplaceEdit2::CallCallBackHdl_Impl() 406 { 407 DBG_CHKTHIS(SvInplaceEdit2,0); 408 aTimer.Stop(); 409 if ( !bAlreadyInCallBack ) 410 { 411 bAlreadyInCallBack = sal_True; 412 GetpApp()->RemoveAccel( &aAccReturn ); 413 GetpApp()->RemoveAccel( &aAccEscape ); 414 pEdit->Hide(); 415 aCallBackHdl.Call( this ); 416 } 417 } 418 419 String SvInplaceEdit2::GetText() const 420 { 421 return pEdit->GetText(); 422 } 423 424 // *************************************************************** 425 // class SvLBoxTab 426 // *************************************************************** 427 428 DBG_NAME(SvLBoxTab); 429 430 SvLBoxTab::SvLBoxTab() 431 { 432 DBG_CTOR(SvLBoxTab,0); 433 nPos = 0; 434 pUserData = 0; 435 nFlags = 0; 436 } 437 438 SvLBoxTab::SvLBoxTab( long nPosition, sal_uInt16 nTabFlags ) 439 { 440 DBG_CTOR(SvLBoxTab,0); 441 nPos = nPosition; 442 pUserData = 0; 443 nFlags = nTabFlags; 444 } 445 446 SvLBoxTab::SvLBoxTab( const SvLBoxTab& rTab ) 447 { 448 DBG_CTOR(SvLBoxTab,0); 449 nPos = rTab.nPos; 450 pUserData = rTab.pUserData; 451 nFlags = rTab.nFlags; 452 } 453 454 SvLBoxTab::~SvLBoxTab() 455 { 456 DBG_DTOR(SvLBoxTab,0); 457 } 458 459 460 long SvLBoxTab::CalcOffset( long nItemWidth, long nTabWidth ) 461 { 462 DBG_CHKTHIS(SvLBoxTab,0); 463 long nOffset = 0; 464 if ( nFlags & SV_LBOXTAB_ADJUST_RIGHT ) 465 { 466 nOffset = nTabWidth - nItemWidth; 467 if( nOffset < 0 ) 468 nOffset = 0; 469 } 470 else if ( nFlags & SV_LBOXTAB_ADJUST_CENTER ) 471 { 472 if( nFlags & SV_LBOXTAB_FORCE ) 473 { 474 //richtige Implementierung der Zentrierung 475 nOffset = ( nTabWidth - nItemWidth ) / 2; 476 if( nOffset < 0 ) 477 nOffset = 0; 478 } 479 else 480 { 481 // historisch gewachsene falsche Berechnung des Tabs, auf die sich 482 // Abo-Tabbox, Extras/Optionen/Anpassen etc. verlassen 483 nItemWidth++; 484 nOffset = -( nItemWidth / 2 ); 485 } 486 } 487 return nOffset; 488 } 489 490 /* 491 long SvLBoxTab::CalcOffset( const String& rStr, const OutputDevice& rOutDev ) 492 { 493 DBG_CHKTHIS(SvLBoxTab,0); 494 long nWidth; 495 if ( nFlags & SV_LBOXTAB_ADJUST_NUMERIC ) 496 { 497 sal_uInt16 nPos = rStr.Search( '.' ); 498 if ( nPos == STRING_NOTFOUND ) 499 nPos = rStr.Search( ',' ); 500 if ( nPos == STRING_NOTFOUND ) 501 nPos = STRING_LEN; 502 503 nWidth = rOutDev.GetTextSize( rStr, 0, nPos ).Width(); 504 nWidth *= -1; 505 } 506 else 507 { 508 nWidth = rOutDev.GetTextSize( rStr ).Width(); 509 nWidth = CalcOffset( nWidth ); 510 } 511 return nWidth; 512 } 513 */ 514 515 // *************************************************************** 516 // class SvLBoxItem 517 // *************************************************************** 518 519 DBG_NAME(SvLBoxItem); 520 521 SvLBoxItem::SvLBoxItem( SvLBoxEntry*, sal_uInt16 ) 522 { 523 DBG_CTOR(SvLBoxItem,0); 524 } 525 526 SvLBoxItem::SvLBoxItem() 527 { 528 DBG_CTOR(SvLBoxItem,0); 529 } 530 531 SvLBoxItem::~SvLBoxItem() 532 { 533 DBG_DTOR(SvLBoxItem,0); 534 } 535 536 const Size& SvLBoxItem::GetSize( SvLBox* pView,SvLBoxEntry* pEntry ) 537 { 538 DBG_CHKTHIS(SvLBoxItem,0); 539 SvViewDataItem* pViewData = pView->GetViewDataItem( pEntry, this ); 540 return pViewData->aSize; 541 } 542 543 const Size& SvLBoxItem::GetSize( SvLBoxEntry* pEntry, SvViewDataEntry* pViewData) 544 { 545 DBG_CHKTHIS(SvLBoxItem,0); 546 sal_uInt16 nItemPos = pEntry->GetPos( this ); 547 SvViewDataItem* pItemData = pViewData->pItemData+nItemPos; 548 return pItemData->aSize; 549 } 550 551 DBG_NAME(SvViewDataItem); 552 553 SvViewDataItem::SvViewDataItem() 554 { 555 DBG_CTOR(SvViewDataItem,0); 556 } 557 558 SvViewDataItem::~SvViewDataItem() 559 { 560 DBG_DTOR(SvViewDataItem,0); 561 } 562 563 564 565 // *************************************************************** 566 // class SvLBoxEntry 567 // *************************************************************** 568 569 DBG_NAME(SvLBoxEntry); 570 571 SvLBoxEntry::SvLBoxEntry() : aItems() 572 { 573 DBG_CTOR(SvLBoxEntry,0); 574 nEntryFlags = 0; 575 pUserData = 0; 576 } 577 578 SvLBoxEntry::~SvLBoxEntry() 579 { 580 DBG_DTOR(SvLBoxEntry,0); 581 DeleteItems_Impl(); 582 } 583 584 void SvLBoxEntry::DeleteItems_Impl() 585 { 586 DBG_CHKTHIS(SvLBoxEntry,0); 587 sal_uInt16 nCount = aItems.Count(); 588 while( nCount ) 589 { 590 nCount--; 591 SvLBoxItem* pItem = (SvLBoxItem*)aItems.GetObject( nCount ); 592 delete pItem; 593 } 594 aItems.Remove(0, aItems.Count() ); 595 } 596 597 598 void SvLBoxEntry::AddItem( SvLBoxItem* pItem ) 599 { 600 DBG_CHKTHIS(SvLBoxEntry,0); 601 aItems.Insert( pItem, aItems.Count() ); 602 } 603 604 void SvLBoxEntry::Clone( SvListEntry* pSource ) 605 { 606 DBG_CHKTHIS(SvLBoxEntry,0); 607 SvListEntry::Clone( pSource ); 608 SvLBoxItem* pNewItem; 609 DeleteItems_Impl(); 610 sal_uInt16 nCount = ((SvLBoxEntry*)pSource)->ItemCount(); 611 sal_uInt16 nCurPos = 0; 612 while( nCurPos < nCount ) 613 { 614 SvLBoxItem* pItem = ((SvLBoxEntry*)pSource)->GetItem( nCurPos ); 615 pNewItem = pItem->Create(); 616 pNewItem->Clone( pItem ); 617 AddItem( pNewItem ); 618 nCurPos++; 619 } 620 pUserData = ((SvLBoxEntry*)pSource)->GetUserData(); 621 nEntryFlags = ((SvLBoxEntry*)pSource)->nEntryFlags; 622 } 623 624 void SvLBoxEntry::EnableChildsOnDemand( sal_Bool bEnable ) 625 { 626 DBG_CHKTHIS(SvLBoxEntry,0); 627 if ( bEnable ) 628 nEntryFlags |= SV_ENTRYFLAG_CHILDS_ON_DEMAND; 629 else 630 nEntryFlags &= (~SV_ENTRYFLAG_CHILDS_ON_DEMAND); 631 } 632 633 void SvLBoxEntry::ReplaceItem( SvLBoxItem* pNewItem, sal_uInt16 nPos ) 634 { 635 DBG_CHKTHIS(SvLBoxEntry,0); 636 DBG_ASSERT(pNewItem,"ReplaceItem:No Item"); 637 SvLBoxItem* pOld = GetItem( nPos ); 638 if ( pOld ) 639 { 640 aItems.Remove( nPos ); 641 aItems.Insert( pNewItem, nPos ); 642 delete pOld; 643 } 644 } 645 646 SvLBoxItem* SvLBoxEntry::GetFirstItem( sal_uInt16 nId ) 647 { 648 sal_uInt16 nCount = aItems.Count(); 649 sal_uInt16 nCur = 0; 650 SvLBoxItem* pItem; 651 while( nCur < nCount ) 652 { 653 pItem = GetItem( nCur ); 654 if( pItem->IsA() == nId ) 655 return pItem; 656 nCur++; 657 } 658 return 0; 659 } 660 661 // *************************************************************** 662 // class SvLBoxViewData 663 // *************************************************************** 664 665 DBG_NAME(SvViewDataEntry); 666 667 SvViewDataEntry::SvViewDataEntry() 668 : SvViewData() 669 { 670 DBG_CTOR(SvViewDataEntry,0); 671 pItemData = 0; 672 } 673 674 SvViewDataEntry::~SvViewDataEntry() 675 { 676 DBG_DTOR(SvViewDataEntry,0); 677 delete [] pItemData; 678 } 679 680 // *************************************************************** 681 // struct SvLBox_Impl 682 // *************************************************************** 683 SvLBox_Impl::SvLBox_Impl( SvLBox& _rBox ) 684 :m_bIsEmptyTextAllowed( true ) 685 ,m_bEntryMnemonicsEnabled( false ) 686 ,m_bDoingQuickSelection( false ) 687 ,m_pLink( NULL ) 688 ,m_aMnemonicEngine( _rBox ) 689 ,m_aQuickSelectionEngine( _rBox ) 690 { 691 } 692 693 // *************************************************************** 694 // class SvLBox 695 // *************************************************************** 696 697 DBG_NAME(SvLBox); 698 699 SvLBox::SvLBox( Window* pParent, WinBits nWinStyle ) : 700 Control( pParent, nWinStyle | WB_CLIPCHILDREN ), 701 DropTargetHelper( this ), DragSourceHelper( this ), eSelMode( NO_SELECTION ) 702 { 703 DBG_CTOR(SvLBox,0); 704 nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK; 705 nImpFlags = 0; 706 pTargetEntry = 0; 707 nDragDropMode = 0; 708 pLBoxImpl = new SvLBox_Impl( *this ); 709 SvLBoxTreeList* pTempModel = new SvLBoxTreeList; 710 pTempModel->SetRefCount( 0 ); 711 SetModel( pTempModel ); 712 pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl )); 713 pModel->InsertView( this ); 714 pHdlEntry = 0; 715 pEdCtrl = 0; 716 SetSelectionMode( SINGLE_SELECTION ); // pruefen ob TreeListBox gecallt wird 717 SetDragDropMode( SV_DRAGDROP_NONE ); 718 SetType(WINDOW_TREELISTBOX); 719 } 720 721 SvLBox::SvLBox( Window* pParent, const ResId& rResId ) : 722 Control( pParent, rResId ), 723 DropTargetHelper( this ), DragSourceHelper( this ), eSelMode( NO_SELECTION ) 724 { 725 DBG_CTOR(SvLBox,0); 726 pTargetEntry = 0; 727 nImpFlags = 0; 728 pLBoxImpl = new SvLBox_Impl( *this ); 729 nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK; 730 nDragDropMode = 0; 731 SvLBoxTreeList* pTempModel = new SvLBoxTreeList; 732 pTempModel->SetRefCount( 0 ); 733 SetModel( pTempModel ); 734 pModel->InsertView( this ); 735 pHdlEntry = 0; 736 pEdCtrl = 0; 737 pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl )); 738 SetType(WINDOW_TREELISTBOX); 739 } 740 741 __EXPORT SvLBox::~SvLBox() 742 { 743 DBG_DTOR(SvLBox,0); 744 delete pEdCtrl; 745 pEdCtrl = 0; 746 pModel->RemoveView( this ); 747 if ( pModel->GetRefCount() == 0 ) 748 { 749 pModel->Clear(); 750 delete pModel; 751 pModel = NULL; 752 } 753 754 SvLBox::RemoveBoxFromDDList_Impl( *this ); 755 756 if( this == pDDSource ) 757 pDDSource = 0; 758 if( this == pDDTarget ) 759 pDDTarget = 0; 760 delete pLBoxImpl; 761 } 762 763 void SvLBox::SetModel( SvLBoxTreeList* pNewModel ) 764 { 765 DBG_CHKTHIS(SvLBox,0); 766 // erledigt das ganz CleanUp 767 SvListView::SetModel( pNewModel ); 768 pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl )); 769 SvLBoxEntry* pEntry = First(); 770 while( pEntry ) 771 { 772 ModelHasInserted( pEntry ); 773 pEntry = Next( pEntry ); 774 } 775 } 776 777 void SvLBox::DisconnectFromModel() 778 { 779 DBG_CHKTHIS(SvLBox,0); 780 SvLBoxTreeList* pNewModel = new SvLBoxTreeList; 781 pNewModel->SetRefCount( 0 ); // else this will never be deleted 782 SvListView::SetModel( pNewModel ); 783 } 784 785 void SvLBox::Clear() 786 { 787 DBG_CHKTHIS(SvLBox,0); 788 pModel->Clear(); // Model ruft SvLBox::ModelHasCleared() auf 789 } 790 791 void SvLBox::EnableEntryMnemonics( bool _bEnable ) 792 { 793 if ( _bEnable == IsEntryMnemonicsEnabled() ) 794 return; 795 796 pLBoxImpl->m_bEntryMnemonicsEnabled = _bEnable; 797 Invalidate(); 798 } 799 800 bool SvLBox::IsEntryMnemonicsEnabled() const 801 { 802 return pLBoxImpl->m_bEntryMnemonicsEnabled; 803 } 804 805 sal_uInt16 SvLBox::IsA() 806 { 807 DBG_CHKTHIS(SvLBox,0); 808 return SVLISTBOX_ID_LBOX; 809 } 810 811 IMPL_LINK_INLINE_START( SvLBox, CloneHdl_Impl, SvListEntry*, pEntry ) 812 { 813 DBG_CHKTHIS(SvLBox,0); 814 return (long)(CloneEntry((SvLBoxEntry*)pEntry)); 815 } 816 IMPL_LINK_INLINE_END( SvLBox, CloneHdl_Impl, SvListEntry*, pEntry ) 817 818 sal_uLong SvLBox::Insert( SvLBoxEntry* pEntry, SvLBoxEntry* pParent, sal_uLong nPos ) 819 { 820 DBG_CHKTHIS(SvLBox,0); 821 sal_uLong nInsPos = pModel->Insert( pEntry, pParent, nPos ); 822 return nInsPos; 823 } 824 825 sal_uLong SvLBox::Insert( SvLBoxEntry* pEntry,sal_uLong nRootPos ) 826 { 827 DBG_CHKTHIS(SvLBox,0); 828 sal_uLong nInsPos = pModel->Insert( pEntry, nRootPos ); 829 return nInsPos; 830 } 831 832 long SvLBox::ExpandingHdl() 833 { 834 DBG_CHKTHIS(SvLBox,0); 835 return aExpandingHdl.IsSet() ? aExpandingHdl.Call( this ) : 1; 836 } 837 838 void SvLBox::ExpandedHdl() 839 { 840 DBG_CHKTHIS(SvLBox,0); 841 aExpandedHdl.Call( this ); 842 } 843 844 void SvLBox::SelectHdl() 845 { 846 DBG_CHKTHIS(SvLBox,0); 847 aSelectHdl.Call( this ); 848 } 849 850 void SvLBox::DeselectHdl() 851 { 852 DBG_CHKTHIS(SvLBox,0); 853 aDeselectHdl.Call( this ); 854 } 855 856 sal_Bool SvLBox::DoubleClickHdl() 857 { 858 DBG_CHKTHIS(SvLBox,0); 859 aDoubleClickHdl.Call( this ); 860 return sal_True; 861 } 862 863 864 sal_Bool SvLBox::CheckDragAndDropMode( SvLBox* pSource, sal_Int8 nAction ) 865 { 866 DBG_CHKTHIS(SvLBox,0); 867 if ( pSource == this ) 868 { 869 if ( !(nDragDropMode & (SV_DRAGDROP_CTRL_MOVE | SV_DRAGDROP_CTRL_COPY) ) ) 870 return sal_False; // D&D innerhalb der Liste gesperrt 871 if( DND_ACTION_MOVE == nAction ) 872 { 873 if ( !(nDragDropMode & SV_DRAGDROP_CTRL_MOVE) ) 874 return sal_False; // kein lokales Move 875 } 876 else 877 { 878 if ( !(nDragDropMode & SV_DRAGDROP_CTRL_COPY)) 879 return sal_False; // kein lokales Copy 880 } 881 } 882 else 883 { 884 if ( !(nDragDropMode & SV_DRAGDROP_APP_DROP ) ) 885 return sal_False; // kein Drop 886 if ( DND_ACTION_MOVE == nAction ) 887 { 888 if ( !(nDragDropMode & SV_DRAGDROP_APP_MOVE) ) 889 return sal_False; // kein globales Move 890 } 891 else 892 { 893 if ( !(nDragDropMode & SV_DRAGDROP_APP_COPY)) 894 return sal_False; // kein globales Copy 895 } 896 } 897 return sal_True; 898 } 899 900 901 902 903 void SvLBox::NotifyRemoving( SvLBoxEntry* ) 904 { 905 DBG_CHKTHIS(SvLBox,0); 906 } 907 908 /* 909 NotifyMoving/Copying 910 ==================== 911 912 Standard-Verhalten: 913 914 1. Target hat keine Childs 915 - Entry wird Sibling des Targets. Entry steht hinter dem 916 Target (->Fenster: Unter dem Target) 917 2. Target ist ein aufgeklappter Parent 918 - Entry wird an den Anfang der Target-Childlist gehaengt 919 3. Target ist ein zugeklappter Parent 920 - Entry wird an das Ende der Target-Childlist gehaengt 921 */ 922 #ifdef DBG_UTIL 923 sal_Bool SvLBox::NotifyMoving( 924 SvLBoxEntry* pTarget, // D&D-Drop-Position in this->GetModel() 925 SvLBoxEntry* pEntry, // Zu verschiebender Entry aus 926 // GetSourceListBox()->GetModel() 927 SvLBoxEntry*& rpNewParent, // Neuer Target-Parent 928 sal_uLong& rNewChildPos) // Position in Childlist des Target-Parents 929 #else 930 sal_Bool SvLBox::NotifyMoving( 931 SvLBoxEntry* pTarget, // D&D-Drop-Position in this->GetModel() 932 SvLBoxEntry*, // Zu verschiebender Entry aus 933 // GetSourceListBox()->GetModel() 934 SvLBoxEntry*& rpNewParent, // Neuer Target-Parent 935 sal_uLong& rNewChildPos) // Position in Childlist des Target-Parents 936 #endif 937 { 938 DBG_CHKTHIS(SvLBox,0); 939 DBG_ASSERT(pEntry,"NotifyMoving:SoureEntry?"); 940 if( !pTarget ) 941 { 942 rpNewParent = 0; 943 rNewChildPos = 0; 944 return sal_True; 945 } 946 if ( !pTarget->HasChilds() && !pTarget->HasChildsOnDemand() ) 947 { 948 // Fall 1 949 rpNewParent = GetParent( pTarget ); 950 rNewChildPos = pModel->GetRelPos( pTarget ) + 1; 951 rNewChildPos += nCurEntrySelPos; 952 nCurEntrySelPos++; 953 } 954 else 955 { 956 // Faelle 2 & 3 957 rpNewParent = pTarget; 958 if( IsExpanded(pTarget)) 959 rNewChildPos = 0; 960 else 961 rNewChildPos = LIST_APPEND; 962 } 963 return sal_True; 964 } 965 966 sal_Bool SvLBox::NotifyCopying( 967 SvLBoxEntry* pTarget, // D&D-Drop-Position in this->GetModel() 968 SvLBoxEntry* pEntry, // Zu kopierender Entry aus 969 // GetSourceListBox()->GetModel() 970 SvLBoxEntry*& rpNewParent, // Neuer Target-Parent 971 sal_uLong& rNewChildPos) // Position in Childlist des Target-Parents 972 { 973 DBG_CHKTHIS(SvLBox,0); 974 return NotifyMoving(pTarget,pEntry,rpNewParent,rNewChildPos); 975 /* 976 DBG_ASSERT(pEntry,"NotifyCopying:SourceEntry?"); 977 if( !pTarget ) 978 { 979 rpNewParent = 0; 980 rNewChildPos = 0; 981 return sal_True; 982 } 983 if ( !pTarget->HasChilds() && !pTarget->HasChildsOnDemand() ) 984 { 985 // Fall 1 986 rpNewParent = GetParent( pTarget ); 987 rNewChildPos = GetRelPos( pTarget ) + 1; 988 } 989 else 990 { 991 // Faelle 2 & 3 992 rpNewParent = pTarget; 993 if( IsExpanded(pTarget)) 994 rNewChildPos = 0; 995 else 996 rNewChildPos = LIST_APPEND; 997 } 998 return sal_True; 999 */ 1000 } 1001 1002 SvLBoxEntry* SvLBox::CloneEntry( SvLBoxEntry* pSource ) 1003 { 1004 DBG_CHKTHIS(SvLBox,0); 1005 SvLBoxEntry* pEntry = (SvLBoxEntry*)CreateEntry(); // new SvLBoxEntry; 1006 pEntry->Clone( (SvListEntry*)pSource ); 1007 return pEntry; 1008 } 1009 1010 1011 // Rueckgabe: Alle Entries wurden kopiert 1012 sal_Bool SvLBox::CopySelection( SvLBox* pSource, SvLBoxEntry* pTarget ) 1013 { 1014 DBG_CHKTHIS(SvLBox,0); 1015 nCurEntrySelPos = 0; // Selektionszaehler fuer NotifyMoving/Copying 1016 sal_Bool bSuccess = sal_True; 1017 SvTreeEntryList aList; 1018 sal_Bool bClone = (sal_Bool)( (sal_uLong)(pSource->GetModel()) != (sal_uLong)GetModel() ); 1019 Link aCloneLink( pModel->GetCloneLink() ); 1020 pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl )); 1021 1022 // Selektion zwischenspeichern, um bei D&D-Austausch 1023 // innerhalb der gleichen Listbox das Iterieren ueber 1024 // die Selektion zu vereinfachen 1025 SvLBoxEntry* pSourceEntry = pSource->FirstSelected(); 1026 while ( pSourceEntry ) 1027 { 1028 // Childs werden automatisch mitkopiert 1029 pSource->SelectChilds( pSourceEntry, sal_False ); 1030 aList.Insert( pSourceEntry, LIST_APPEND ); 1031 pSourceEntry = pSource->NextSelected( pSourceEntry ); 1032 } 1033 1034 pSourceEntry = (SvLBoxEntry*)aList.First(); 1035 while ( pSourceEntry ) 1036 { 1037 SvLBoxEntry* pNewParent = 0; 1038 sal_uLong nInsertionPos = LIST_APPEND; 1039 sal_Bool bOk=NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos); 1040 if ( bOk ) 1041 { 1042 if ( bClone ) 1043 { 1044 sal_uLong nCloneCount = 0; 1045 pSourceEntry = (SvLBoxEntry*) 1046 pModel->Clone( (SvListEntry*)pSourceEntry, nCloneCount ); 1047 pModel->InsertTree( (SvListEntry*)pSourceEntry, 1048 (SvListEntry*)pNewParent, nInsertionPos ); 1049 } 1050 else 1051 { 1052 sal_uLong nListPos = pModel->Copy( (SvListEntry*)pSourceEntry, 1053 (SvListEntry*)pNewParent, nInsertionPos ); 1054 pSourceEntry = GetEntry( pNewParent, nListPos ); 1055 } 1056 } 1057 else 1058 bSuccess = sal_False; 1059 1060 if( bOk == (sal_Bool)2 ) // !!!HACK verschobenen Entry sichtbar machen? 1061 MakeVisible( pSourceEntry ); 1062 1063 pSourceEntry = (SvLBoxEntry*)aList.Next(); 1064 } 1065 pModel->SetCloneLink( aCloneLink ); 1066 return bSuccess; 1067 } 1068 1069 // Rueckgabe: Alle Entries wurden verschoben 1070 sal_Bool SvLBox::MoveSelection( SvLBox* pSource, SvLBoxEntry* pTarget ) 1071 { 1072 return MoveSelectionCopyFallbackPossible( pSource, pTarget, sal_False ); 1073 } 1074 1075 sal_Bool SvLBox::MoveSelectionCopyFallbackPossible( SvLBox* pSource, SvLBoxEntry* pTarget, sal_Bool bAllowCopyFallback ) 1076 { 1077 DBG_CHKTHIS(SvLBox,0); 1078 nCurEntrySelPos = 0; // Selektionszaehler fuer NotifyMoving/Copying 1079 sal_Bool bSuccess = sal_True; 1080 SvTreeEntryList aList; 1081 sal_Bool bClone = (sal_Bool)( (sal_uLong)(pSource->GetModel()) != (sal_uLong)GetModel() ); 1082 Link aCloneLink( pModel->GetCloneLink() ); 1083 if ( bClone ) 1084 pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl )); 1085 1086 SvLBoxEntry* pSourceEntry = pSource->FirstSelected(); 1087 while ( pSourceEntry ) 1088 { 1089 // Childs werden automatisch mitbewegt 1090 pSource->SelectChilds( pSourceEntry, sal_False ); 1091 aList.Insert( pSourceEntry, LIST_APPEND ); 1092 pSourceEntry = pSource->NextSelected( pSourceEntry ); 1093 } 1094 1095 pSourceEntry = (SvLBoxEntry*)aList.First(); 1096 while ( pSourceEntry ) 1097 { 1098 SvLBoxEntry* pNewParent = 0; 1099 sal_uLong nInsertionPos = LIST_APPEND; 1100 sal_Bool bOk = NotifyMoving(pTarget,pSourceEntry,pNewParent,nInsertionPos); 1101 sal_Bool bCopyOk = bOk; 1102 if ( !bOk && bAllowCopyFallback ) 1103 { 1104 nInsertionPos = LIST_APPEND; 1105 bCopyOk = NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos); 1106 } 1107 1108 if ( bOk || bCopyOk ) 1109 { 1110 if ( bClone ) 1111 { 1112 sal_uLong nCloneCount = 0; 1113 pSourceEntry = (SvLBoxEntry*) 1114 pModel->Clone( (SvListEntry*)pSourceEntry, nCloneCount ); 1115 pModel->InsertTree( (SvListEntry*)pSourceEntry, 1116 (SvListEntry*)pNewParent, nInsertionPos ); 1117 } 1118 else 1119 { 1120 if ( bOk ) 1121 pModel->Move( (SvListEntry*)pSourceEntry, 1122 (SvListEntry*)pNewParent, nInsertionPos ); 1123 else 1124 pModel->Copy( (SvListEntry*)pSourceEntry, 1125 (SvListEntry*)pNewParent, nInsertionPos ); 1126 } 1127 } 1128 else 1129 bSuccess = sal_False; 1130 1131 if( bOk == (sal_Bool)2 ) // !!!HACK verschobenen Entry sichtbar machen? 1132 MakeVisible( pSourceEntry ); 1133 1134 pSourceEntry = (SvLBoxEntry*)aList.Next(); 1135 } 1136 pModel->SetCloneLink( aCloneLink ); 1137 return bSuccess; 1138 } 1139 1140 void SvLBox::RemoveSelection() 1141 { 1142 DBG_CHKTHIS(SvLBox,0); 1143 SvTreeEntryList aList; 1144 // Selektion zwischenspeichern, da die Impl bei 1145 // dem ersten Remove alles deselektiert! 1146 SvLBoxEntry* pEntry = FirstSelected(); 1147 while ( pEntry ) 1148 { 1149 aList.Insert( pEntry ); 1150 if ( pEntry->HasChilds() ) 1151 // Remove loescht Childs automatisch 1152 SelectChilds( pEntry, sal_False ); 1153 pEntry = NextSelected( pEntry ); 1154 } 1155 pEntry = (SvLBoxEntry*)aList.First(); 1156 while ( pEntry ) 1157 { 1158 pModel->Remove( pEntry ); 1159 pEntry = (SvLBoxEntry*)aList.Next(); 1160 } 1161 } 1162 1163 SvLBox* SvLBox::GetSourceView() const 1164 { 1165 return pDDSource; 1166 } 1167 1168 SvLBox* SvLBox::GetTargetView() const 1169 { 1170 return pDDTarget; 1171 } 1172 1173 void SvLBox::RequestingChilds( SvLBoxEntry* ) 1174 { 1175 DBG_CHKTHIS(SvLBox,0); 1176 DBG_ERROR("Child-Request-Hdl not implemented!"); 1177 } 1178 1179 void SvLBox::RecalcViewData() 1180 { 1181 DBG_CHKTHIS(SvLBox,0); 1182 SvLBoxEntry* pEntry = First(); 1183 while( pEntry ) 1184 { 1185 sal_uInt16 nCount = pEntry->ItemCount(); 1186 sal_uInt16 nCurPos = 0; 1187 while ( nCurPos < nCount ) 1188 { 1189 SvLBoxItem* pItem = pEntry->GetItem( nCurPos ); 1190 pItem->InitViewData( this, pEntry ); 1191 nCurPos++; 1192 } 1193 ViewDataInitialized( pEntry ); 1194 pEntry = Next( pEntry ); 1195 } 1196 } 1197 1198 void SvLBox::ViewDataInitialized( SvLBoxEntry* ) 1199 { 1200 DBG_CHKTHIS(SvLBox,0); 1201 } 1202 1203 void SvLBox::StateChanged( StateChangedType eType ) 1204 { 1205 if( eType == STATE_CHANGE_ENABLE ) 1206 Invalidate( INVALIDATE_CHILDREN ); 1207 Control::StateChanged( eType ); 1208 } 1209 1210 void SvLBox::ImplShowTargetEmphasis( SvLBoxEntry* pEntry, sal_Bool bShow) 1211 { 1212 DBG_CHKTHIS(SvLBox,0); 1213 if ( bShow && (nImpFlags & SVLBOX_TARGEMPH_VIS) ) 1214 return; 1215 if ( !bShow && !(nImpFlags & SVLBOX_TARGEMPH_VIS) ) 1216 return; 1217 ShowTargetEmphasis( pEntry, bShow ); 1218 if( bShow ) 1219 nImpFlags |= SVLBOX_TARGEMPH_VIS; 1220 else 1221 nImpFlags &= ~SVLBOX_TARGEMPH_VIS; 1222 } 1223 1224 void SvLBox::ShowTargetEmphasis( SvLBoxEntry*, sal_Bool /* bShow */ ) 1225 { 1226 DBG_CHKTHIS(SvLBox,0); 1227 } 1228 1229 1230 sal_Bool SvLBox::Expand( SvLBoxEntry* ) 1231 { 1232 DBG_CHKTHIS(SvLBox,0); 1233 return sal_True; 1234 } 1235 1236 sal_Bool SvLBox::Collapse( SvLBoxEntry* ) 1237 { 1238 DBG_CHKTHIS(SvLBox,0); 1239 return sal_True; 1240 } 1241 1242 sal_Bool SvLBox::Select( SvLBoxEntry*, sal_Bool ) 1243 { 1244 DBG_CHKTHIS(SvLBox,0); 1245 return sal_False; 1246 } 1247 1248 sal_uLong SvLBox::SelectChilds( SvLBoxEntry* , sal_Bool ) 1249 { 1250 DBG_CHKTHIS(SvLBox,0); 1251 return 0; 1252 } 1253 1254 void SvLBox::OnCurrentEntryChanged() 1255 { 1256 if ( !pLBoxImpl->m_bDoingQuickSelection ) 1257 pLBoxImpl->m_aQuickSelectionEngine.Reset(); 1258 } 1259 1260 void SvLBox::SelectAll( sal_Bool /* bSelect */ , sal_Bool /* bPaint */ ) 1261 { 1262 DBG_CHKTHIS(SvLBox,0); 1263 } 1264 1265 SvLBoxEntry* SvLBox::GetEntryFromPath( const ::std::deque< sal_Int32 >& _rPath ) const 1266 { 1267 DBG_CHKTHIS(SvLBox,0); 1268 1269 SvLBoxEntry* pEntry = NULL; 1270 SvLBoxEntry* pParent = NULL; 1271 for( ::std::deque< sal_Int32 >::const_iterator pItem = _rPath.begin(); pItem != _rPath.end(); ++pItem ) 1272 { 1273 pEntry = GetEntry( pParent, *pItem ); 1274 if ( !pEntry ) 1275 break; 1276 pParent = pEntry; 1277 } 1278 1279 return pEntry; 1280 } 1281 1282 void SvLBox::FillEntryPath( SvLBoxEntry* pEntry, ::std::deque< sal_Int32 >& _rPath ) const 1283 { 1284 DBG_CHKTHIS(SvLBox,0); 1285 1286 if ( pEntry ) 1287 { 1288 SvLBoxEntry* pParentEntry = GetParent( pEntry ); 1289 while ( sal_True ) 1290 { 1291 sal_uLong i, nCount = GetLevelChildCount( pParentEntry ); 1292 for ( i = 0; i < nCount; ++i ) 1293 { 1294 SvLBoxEntry* pTemp = GetEntry( pParentEntry, i ); 1295 DBG_ASSERT( pEntry, "invalid entry" ); 1296 if ( pEntry == pTemp ) 1297 { 1298 _rPath.push_front( (sal_Int32)i ); 1299 break; 1300 } 1301 } 1302 1303 if ( pParentEntry ) 1304 { 1305 pEntry = pParentEntry; 1306 pParentEntry = GetParent( pParentEntry ); 1307 } 1308 else 1309 break; 1310 } 1311 } 1312 } 1313 1314 String SvLBox::GetEntryText( SvLBoxEntry* ) const 1315 { 1316 DBG_CHKTHIS(SvLBox,0); 1317 1318 return String(); 1319 } 1320 1321 sal_uLong SvLBox::GetLevelChildCount( SvLBoxEntry* _pParent ) const 1322 { 1323 DBG_CHKTHIS(SvLBox,0); 1324 1325 sal_uLong nCount = 0; 1326 SvLBoxEntry* pEntry = FirstChild( _pParent ); 1327 while ( pEntry ) 1328 { 1329 ++nCount; 1330 pEntry = NextSibling( pEntry ); 1331 } 1332 1333 return nCount; 1334 } 1335 1336 void SvLBox::SetSelectionMode( SelectionMode eSelectMode ) 1337 { 1338 DBG_CHKTHIS(SvLBox,0); 1339 eSelMode = eSelectMode; 1340 } 1341 1342 void SvLBox::SetDragDropMode( DragDropMode nDDMode ) 1343 { 1344 DBG_CHKTHIS(SvLBox,0); 1345 nDragDropMode = nDDMode; 1346 } 1347 1348 SvViewData* SvLBox::CreateViewData( SvListEntry* ) 1349 { 1350 DBG_CHKTHIS(SvLBox,0); 1351 SvViewDataEntry* pEntryData = new SvViewDataEntry; 1352 return (SvViewData*)pEntryData; 1353 } 1354 1355 void SvLBox::InitViewData( SvViewData* pData, SvListEntry* pEntry ) 1356 { 1357 DBG_CHKTHIS(SvLBox,0); 1358 SvLBoxEntry* pInhEntry = (SvLBoxEntry*)pEntry; 1359 SvViewDataEntry* pEntryData = (SvViewDataEntry*)pData; 1360 1361 pEntryData->pItemData = new SvViewDataItem[ pInhEntry->ItemCount() ]; 1362 SvViewDataItem* pItemData = pEntryData->pItemData; 1363 pEntryData->nItmCnt = pInhEntry->ItemCount(); // Anzahl Items fuer delete 1364 sal_uInt16 nCount = pInhEntry->ItemCount(); 1365 sal_uInt16 nCurPos = 0; 1366 while( nCurPos < nCount ) 1367 { 1368 SvLBoxItem* pItem = pInhEntry->GetItem( nCurPos ); 1369 pItem->InitViewData( this, pInhEntry, pItemData ); 1370 pItemData++; 1371 nCurPos++; 1372 } 1373 } 1374 1375 1376 1377 void SvLBox::EnableSelectionAsDropTarget( sal_Bool bEnable, sal_Bool bWithChilds ) 1378 { 1379 DBG_CHKTHIS(SvLBox,0); 1380 sal_uInt16 nRefDepth; 1381 SvLBoxEntry* pTemp; 1382 1383 SvLBoxEntry* pSelEntry = FirstSelected(); 1384 while( pSelEntry ) 1385 { 1386 if ( !bEnable ) 1387 { 1388 pSelEntry->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP; 1389 if ( bWithChilds ) 1390 { 1391 nRefDepth = pModel->GetDepth( pSelEntry ); 1392 pTemp = Next( pSelEntry ); 1393 while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth ) 1394 { 1395 pTemp->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP; 1396 pTemp = Next( pTemp ); 1397 } 1398 } 1399 } 1400 else 1401 { 1402 pSelEntry->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP); 1403 if ( bWithChilds ) 1404 { 1405 nRefDepth = pModel->GetDepth( pSelEntry ); 1406 pTemp = Next( pSelEntry ); 1407 while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth ) 1408 { 1409 pTemp->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP); 1410 pTemp = Next( pTemp ); 1411 } 1412 } 1413 } 1414 pSelEntry = NextSelected( pSelEntry ); 1415 } 1416 } 1417 1418 SvLBoxEntry* SvLBox::GetDropTarget( const Point& ) 1419 { 1420 DBG_CHKTHIS(SvLBox,0); 1421 return 0; 1422 } 1423 1424 // ****************************************************************** 1425 // InplaceEditing 1426 // ****************************************************************** 1427 1428 void SvLBox::EditText( const String& rStr, const Rectangle& rRect, 1429 const Selection& rSel ) 1430 { 1431 EditText( rStr, rRect, rSel, sal_False ); 1432 } 1433 1434 void SvLBox::EditText( const String& rStr, const Rectangle& rRect, 1435 const Selection& rSel, sal_Bool bMulti ) 1436 { 1437 DBG_CHKTHIS(SvLBox,0); 1438 if( pEdCtrl ) 1439 delete pEdCtrl; 1440 nImpFlags |= SVLBOX_IN_EDT; 1441 nImpFlags &= ~SVLBOX_EDTEND_CALLED; 1442 HideFocus(); 1443 pEdCtrl = new SvInplaceEdit2( 1444 this, rRect.TopLeft(), rRect.GetSize(), rStr, 1445 LINK( this, SvLBox, TextEditEndedHdl_Impl ), 1446 rSel, bMulti ); 1447 } 1448 1449 IMPL_LINK( SvLBox, TextEditEndedHdl_Impl, SvInplaceEdit2 *, EMPTYARG ) 1450 { 1451 DBG_CHKTHIS(SvLBox,0); 1452 if ( nImpFlags & SVLBOX_EDTEND_CALLED ) // Nesting verhindern 1453 return 0; 1454 nImpFlags |= SVLBOX_EDTEND_CALLED; 1455 String aStr; 1456 if ( !pEdCtrl->EditingCanceled() ) 1457 aStr = pEdCtrl->GetText(); 1458 else 1459 aStr = pEdCtrl->GetSavedValue(); 1460 if ( IsEmptyTextAllowed() || aStr.Len() > 0 ) 1461 EditedText( aStr ); 1462 // Hide darf erst gerufen werden, nachdem der neue Text in den 1463 // Entry gesetzt wurde, damit im GetFocus der ListBox nicht 1464 // der Selecthandler mit dem alten EntryText gerufen wird. 1465 pEdCtrl->Hide(); 1466 // delete pEdCtrl; 1467 // pEdCtrl = 0; 1468 nImpFlags &= (~SVLBOX_IN_EDT); 1469 GrabFocus(); 1470 return 0; 1471 } 1472 1473 void SvLBox::CancelTextEditing() 1474 { 1475 DBG_CHKTHIS(SvLBox,0); 1476 if ( pEdCtrl ) 1477 pEdCtrl->StopEditing( sal_True ); 1478 nImpFlags &= (~SVLBOX_IN_EDT); 1479 } 1480 1481 void SvLBox::EndEditing( sal_Bool bCancel ) 1482 { 1483 DBG_CHKTHIS(SvLBox,0); 1484 if( pEdCtrl ) 1485 pEdCtrl->StopEditing( bCancel ); 1486 nImpFlags &= (~SVLBOX_IN_EDT); 1487 } 1488 1489 1490 bool SvLBox::IsEmptyTextAllowed() const 1491 { 1492 DBG_CHKTHIS(SvLBox,0); 1493 return pLBoxImpl->m_bIsEmptyTextAllowed; 1494 } 1495 1496 void SvLBox::ForbidEmptyText() 1497 { 1498 DBG_CHKTHIS(SvLBox,0); 1499 pLBoxImpl->m_bIsEmptyTextAllowed = false; 1500 } 1501 1502 void SvLBox::EditedText( const String& ) 1503 { 1504 DBG_CHKTHIS(SvLBox,0); 1505 } 1506 1507 void SvLBox::EditingRequest( SvLBoxEntry*, SvLBoxItem*,const Point& ) 1508 { 1509 DBG_CHKTHIS(SvLBox,0); 1510 } 1511 1512 1513 SvLBoxEntry* SvLBox::CreateEntry() const 1514 { 1515 DBG_CHKTHIS(SvLBox,0); 1516 return new SvLBoxEntry; 1517 } 1518 1519 void SvLBox::MakeVisible( SvLBoxEntry* ) 1520 { 1521 DBG_CHKTHIS(SvLBox,0); 1522 } 1523 1524 void SvLBox::Command( const CommandEvent& i_rCommandEvent ) 1525 { 1526 DBG_CHKTHIS(SvLBox,0); 1527 1528 if ( COMMAND_STARTDRAG == i_rCommandEvent.GetCommand() ) 1529 { 1530 Point aEventPos( i_rCommandEvent.GetMousePosPixel() ); 1531 MouseEvent aMouseEvt( aEventPos, 1, MOUSE_SELECT, MOUSE_LEFT ); 1532 MouseButtonUp( aMouseEvt ); 1533 } 1534 Control::Command( i_rCommandEvent ); 1535 } 1536 1537 void SvLBox::KeyInput( const KeyEvent& rKEvt ) 1538 { 1539 bool bHandled = HandleKeyInput( rKEvt ); 1540 if ( !bHandled ) 1541 Control::KeyInput( rKEvt ); 1542 } 1543 1544 const void* SvLBox::FirstSearchEntry( String& _rEntryText ) const 1545 { 1546 SvLBoxEntry* pEntry = GetCurEntry(); 1547 if ( pEntry ) 1548 pEntry = const_cast< SvLBoxEntry* >( static_cast< const SvLBoxEntry* >( NextSearchEntry( pEntry, _rEntryText ) ) ); 1549 else 1550 { 1551 pEntry = FirstSelected(); 1552 if ( !pEntry ) 1553 pEntry = First(); 1554 } 1555 1556 if ( pEntry ) 1557 _rEntryText = GetEntryText( pEntry ); 1558 1559 return pEntry; 1560 } 1561 1562 const void* SvLBox::NextSearchEntry( const void* _pCurrentSearchEntry, String& _rEntryText ) const 1563 { 1564 SvLBoxEntry* pEntry = const_cast< SvLBoxEntry* >( static_cast< const SvLBoxEntry* >( _pCurrentSearchEntry ) ); 1565 1566 if ( ( ( GetChildCount( pEntry ) > 0 ) 1567 || ( pEntry->HasChildsOnDemand() ) 1568 ) 1569 && !IsExpanded( pEntry ) 1570 ) 1571 { 1572 pEntry = NextSibling( pEntry ); 1573 } 1574 else 1575 { 1576 pEntry = Next( pEntry ); 1577 } 1578 1579 if ( !pEntry ) 1580 pEntry = First(); 1581 1582 if ( pEntry ) 1583 _rEntryText = GetEntryText( pEntry ); 1584 1585 return pEntry; 1586 } 1587 1588 void SvLBox::SelectSearchEntry( const void* _pEntry ) 1589 { 1590 SvLBoxEntry* pEntry = const_cast< SvLBoxEntry* >( static_cast< const SvLBoxEntry* >( _pEntry ) ); 1591 DBG_ASSERT( pEntry, "SvLBox::SelectSearchEntry: invalid entry!" ); 1592 if ( !pEntry ) 1593 return; 1594 1595 SelectAll( sal_False ); 1596 SetCurEntry( pEntry ); 1597 Select( pEntry ); 1598 } 1599 1600 void SvLBox::ExecuteSearchEntry( const void* /*_pEntry*/ ) const 1601 { 1602 // nothing to do here, we have no "execution" 1603 } 1604 1605 ::vcl::StringEntryIdentifier SvLBox::CurrentEntry( String& _out_entryText ) const 1606 { 1607 // always accept the current entry if there is one 1608 SvLBoxEntry* pCurrentEntry( GetCurEntry() ); 1609 if ( pCurrentEntry ) 1610 { 1611 _out_entryText = GetEntryText( pCurrentEntry ); 1612 return pCurrentEntry; 1613 } 1614 return FirstSearchEntry( _out_entryText ); 1615 } 1616 1617 ::vcl::StringEntryIdentifier SvLBox::NextEntry( ::vcl::StringEntryIdentifier _currentEntry, String& _out_entryText ) const 1618 { 1619 return NextSearchEntry( _currentEntry, _out_entryText ); 1620 } 1621 1622 void SvLBox::SelectEntry( ::vcl::StringEntryIdentifier _entry ) 1623 { 1624 SelectSearchEntry( _entry ); 1625 } 1626 1627 bool SvLBox::HandleKeyInput( const KeyEvent& _rKEvt ) 1628 { 1629 if ( IsEntryMnemonicsEnabled() 1630 && pLBoxImpl->m_aMnemonicEngine.HandleKeyEvent( _rKEvt ) 1631 ) 1632 return true; 1633 1634 if ( ( GetStyle() & WB_QUICK_SEARCH ) != 0 ) 1635 { 1636 pLBoxImpl->m_bDoingQuickSelection = true; 1637 const bool bHandled = pLBoxImpl->m_aQuickSelectionEngine.HandleKeyEvent( _rKEvt ); 1638 pLBoxImpl->m_bDoingQuickSelection = false; 1639 if ( bHandled ) 1640 return true; 1641 } 1642 1643 return false; 1644 } 1645 1646 SvLBoxEntry* SvLBox::GetEntry( const Point&, sal_Bool ) const 1647 { 1648 DBG_CHKTHIS(SvLBox,0); 1649 return 0; 1650 } 1651 1652 void SvLBox::ModelHasEntryInvalidated( SvListEntry* pEntry ) 1653 { 1654 DBG_CHKTHIS(SvLBox,0); 1655 sal_uInt16 nCount = ((SvLBoxEntry*)pEntry)->ItemCount(); 1656 for( sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++ ) 1657 { 1658 SvLBoxItem* pItem = ((SvLBoxEntry*)pEntry)->GetItem( nIdx ); 1659 pItem->InitViewData( this, (SvLBoxEntry*)pEntry, 0 ); 1660 } 1661 } 1662 1663 void SvLBox::SetInUseEmphasis( SvLBoxEntry* pEntry, sal_Bool bInUse ) 1664 { 1665 DBG_CHKTHIS(SvLBox,0); 1666 DBG_ASSERT(pEntry,"SetInUseEmphasis:No Entry"); 1667 if( bInUse ) 1668 { 1669 if( !pEntry->HasInUseEmphasis() ) 1670 { 1671 pEntry->nEntryFlags |= SV_ENTRYFLAG_IN_USE; 1672 pModel->InvalidateEntry( pEntry ); 1673 } 1674 } 1675 else 1676 { 1677 if( pEntry->HasInUseEmphasis() ) 1678 { 1679 pEntry->nEntryFlags &= (~SV_ENTRYFLAG_IN_USE); 1680 pModel->InvalidateEntry( pEntry ); 1681 } 1682 } 1683 } 1684 1685 void SvLBox::SetCursorEmphasis( SvLBoxEntry* pEntry, sal_Bool bCursored ) 1686 { 1687 DBG_CHKTHIS(SvLBox,0); 1688 DBG_ASSERT(pEntry,"SetInUseEmphasis:No Entry"); 1689 SvViewDataEntry* pViewData = GetViewDataEntry( pEntry ); 1690 if( pViewData && (bCursored != pViewData->IsCursored()) ) 1691 { 1692 pViewData->SetCursored( bCursored ); 1693 // paintet in allen Views 1694 // pModel->InvalidateEntry( pEntry ); 1695 // invalidiert nur in dieser View 1696 ModelHasEntryInvalidated( pEntry ); 1697 } 1698 } 1699 1700 sal_Bool SvLBox::HasCursorEmphasis( SvLBoxEntry* pEntry ) const 1701 { 1702 DBG_CHKTHIS(SvLBox,0); 1703 DBG_ASSERT(pEntry,"SetInUseEmphasis:No Entry"); 1704 SvViewDataEntry* pViewData = GetViewDataEntry( pEntry ); 1705 DBG_ASSERT(pViewData,"Entry not in View"); 1706 return pViewData->IsCursored(); 1707 } 1708 1709 void SvLBox::WriteDragServerInfo( const Point&, SvLBoxDDInfo* ) 1710 { 1711 DBG_CHKTHIS(SvLBox,0); 1712 } 1713 1714 void SvLBox::ReadDragServerInfo(const Point&, SvLBoxDDInfo* ) 1715 { 1716 DBG_CHKTHIS(SvLBox,0); 1717 } 1718 1719 sal_Bool SvLBox::EditingCanceled() const 1720 { 1721 if( pEdCtrl && pEdCtrl->EditingCanceled() ) 1722 return sal_True; 1723 return sal_False; 1724 } 1725 1726 1727 //JP 28.3.2001: new Drag & Drop API 1728 sal_Int8 SvLBox::AcceptDrop( const AcceptDropEvent& rEvt ) 1729 { 1730 DBG_CHKTHIS(SvLBox,0); 1731 sal_Int8 nRet = DND_ACTION_NONE; 1732 1733 if( rEvt.mbLeaving || !CheckDragAndDropMode( pDDSource, rEvt.mnAction ) ) 1734 { 1735 ImplShowTargetEmphasis( pTargetEntry, sal_False ); 1736 } 1737 else if( !nDragDropMode ) 1738 { 1739 DBG_ERRORFILE( "SvLBox::QueryDrop(): no target" ); 1740 } 1741 else 1742 { 1743 SvLBoxEntry* pEntry = GetDropTarget( rEvt.maPosPixel ); 1744 if( !IsDropFormatSupported( SOT_FORMATSTR_ID_TREELISTBOX ) ) 1745 { 1746 DBG_ERRORFILE( "SvLBox::QueryDrop(): no format" ); 1747 } 1748 else 1749 { 1750 DBG_ASSERT( pDDSource, "SvLBox::QueryDrop(): SourceBox == 0 (__EXPORT?)" ); 1751 if( !( pEntry && pDDSource->GetModel() == this->GetModel() 1752 && DND_ACTION_MOVE == rEvt.mnAction 1753 && ( pEntry->nEntryFlags & SV_ENTRYFLAG_DISABLE_DROP ) )) 1754 { 1755 if( NotifyAcceptDrop( pEntry )) 1756 nRet = rEvt.mnAction; 1757 } 1758 } 1759 1760 // **** Emphasis zeichnen **** 1761 if( DND_ACTION_NONE == nRet ) 1762 ImplShowTargetEmphasis( pTargetEntry, sal_False ); 1763 else if( pEntry != pTargetEntry || !(nImpFlags & SVLBOX_TARGEMPH_VIS) ) 1764 { 1765 ImplShowTargetEmphasis( pTargetEntry, sal_False ); 1766 pTargetEntry = pEntry; 1767 ImplShowTargetEmphasis( pTargetEntry, sal_True ); 1768 } 1769 } 1770 return nRet; 1771 } 1772 1773 sal_Int8 SvLBox::ExecuteDrop( const ExecuteDropEvent& rEvt, SvLBox* pSourceView ) 1774 { 1775 DBG_CHKTHIS(SvLBox,0); 1776 sal_Int8 nRet = DND_ACTION_NONE; 1777 1778 DBG_ASSERT( pSourceView, "SvLBox::ExecuteDrop(): no source view" ); 1779 pSourceView->EnableSelectionAsDropTarget( sal_True, sal_True ); 1780 1781 ImplShowTargetEmphasis( pTargetEntry, sal_False ); 1782 pDDTarget = this; 1783 1784 SvLBoxDDInfo aDDInfo; 1785 1786 TransferableDataHelper aData( rEvt.maDropEvent.Transferable ); 1787 if( aData.HasFormat( SOT_FORMATSTR_ID_TREELISTBOX )) 1788 { 1789 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq; 1790 if( aData.GetSequence( SOT_FORMATSTR_ID_TREELISTBOX, aSeq ) && 1791 sizeof(SvLBoxDDInfo) == aSeq.getLength() ) 1792 { 1793 memcpy( &aDDInfo, aSeq.getConstArray(), sizeof(SvLBoxDDInfo) ); 1794 nRet = rEvt.mnAction; 1795 } 1796 } 1797 1798 if( DND_ACTION_NONE != nRet ) 1799 { 1800 nRet = DND_ACTION_NONE; 1801 1802 ReadDragServerInfo( rEvt.maPosPixel, &aDDInfo ); 1803 1804 SvLBoxEntry* pTarget = pTargetEntry; // !!! kann 0 sein !!! 1805 1806 if( DND_ACTION_COPY == rEvt.mnAction ) 1807 { 1808 if ( CopySelection( aDDInfo.pSource, pTarget ) ) 1809 nRet = rEvt.mnAction; 1810 } 1811 else if( DND_ACTION_MOVE == rEvt.mnAction ) 1812 { 1813 if ( MoveSelection( aDDInfo.pSource, pTarget ) ) 1814 nRet = rEvt.mnAction; 1815 } 1816 else if( DND_ACTION_COPYMOVE == rEvt.mnAction ) 1817 { 1818 if ( MoveSelectionCopyFallbackPossible( aDDInfo.pSource, pTarget, sal_True ) ) 1819 nRet = rEvt.mnAction; 1820 } 1821 } 1822 return nRet; 1823 } 1824 1825 sal_Int8 SvLBox::ExecuteDrop( const ExecuteDropEvent& rEvt ) 1826 { 1827 DBG_CHKTHIS(SvLBox,0); 1828 return ExecuteDrop( rEvt, GetSourceView() ); 1829 } 1830 1831 void SvLBox::StartDrag( sal_Int8, const Point& rPosPixel ) 1832 { 1833 DBG_CHKTHIS(SvLBox,0); 1834 1835 Point aEventPos( rPosPixel ); 1836 MouseEvent aMouseEvt( aEventPos, 1, MOUSE_SELECT, MOUSE_LEFT ); 1837 MouseButtonUp( aMouseEvt ); 1838 1839 nOldDragMode = GetDragDropMode(); 1840 if ( !nOldDragMode ) 1841 return; 1842 1843 ReleaseMouse(); 1844 1845 SvLBoxEntry* pEntry = GetEntry( rPosPixel ); // GetDropTarget( rPos ); 1846 if( !pEntry ) 1847 { 1848 DragFinished( DND_ACTION_NONE ); 1849 return; 1850 } 1851 1852 TransferDataContainer* pContainer = new TransferDataContainer; 1853 ::com::sun::star::uno::Reference< 1854 ::com::sun::star::datatransfer::XTransferable > xRef( pContainer ); 1855 1856 nDragDropMode = NotifyStartDrag( *pContainer, pEntry ); 1857 if( !nDragDropMode || 0 == GetSelectionCount() ) 1858 { 1859 nDragDropMode = nOldDragMode; 1860 DragFinished( DND_ACTION_NONE ); 1861 return; 1862 } 1863 1864 SvLBoxDDInfo aDDInfo; 1865 memset(&aDDInfo,0,sizeof(SvLBoxDDInfo)); 1866 aDDInfo.pApp = GetpApp(); 1867 aDDInfo.pSource = this; 1868 aDDInfo.pDDStartEntry = pEntry; 1869 // abgeleitete Views zum Zuge kommen lassen 1870 WriteDragServerInfo( rPosPixel, &aDDInfo ); 1871 1872 pContainer->CopyAnyData( SOT_FORMATSTR_ID_TREELISTBOX, 1873 (sal_Char*)&aDDInfo, sizeof(SvLBoxDDInfo) ); 1874 pDDSource = this; 1875 pDDTarget = 0; 1876 1877 sal_Bool bOldUpdateMode = Control::IsUpdateMode(); 1878 Control::SetUpdateMode( sal_True ); 1879 Update(); 1880 Control::SetUpdateMode( bOldUpdateMode ); 1881 1882 // Selektion & deren Childs im Model als DropTargets sperren 1883 // Wichtig: Wenn im DropHandler die Selektion der 1884 // SourceListBox veraendert wird, muessen vorher die Eintraege 1885 // als DropTargets wieder freigeschaltet werden: 1886 // (GetSourceListBox()->EnableSelectionAsDropTarget( sal_True, sal_True );) 1887 EnableSelectionAsDropTarget( sal_False, sal_True /* with Childs */ ); 1888 1889 pContainer->StartDrag( this, nDragOptions, GetDragFinishedHdl() ); 1890 } 1891 1892 void SvLBox::DragFinished( sal_Int8 1893 #ifndef UNX 1894 nAction 1895 #endif 1896 ) 1897 { 1898 EnableSelectionAsDropTarget( sal_True, sal_True ); 1899 1900 #ifndef UNX 1901 if( (nAction == DND_ACTION_MOVE) && ( (pDDTarget && 1902 ((sal_uLong)(pDDTarget->GetModel())!=(sal_uLong)(this->GetModel()))) || 1903 !pDDTarget )) 1904 { 1905 RemoveSelection(); 1906 } 1907 #endif 1908 1909 ImplShowTargetEmphasis( pTargetEntry, sal_False ); 1910 pDDSource = 0; 1911 pDDTarget = 0; 1912 pTargetEntry = 0; 1913 nDragDropMode = nOldDragMode; 1914 } 1915 1916 DragDropMode SvLBox::NotifyStartDrag( TransferDataContainer&, SvLBoxEntry* ) 1917 { 1918 DBG_CHKTHIS(SvLBox,0); 1919 return (DragDropMode)0xffff; 1920 } 1921 1922 sal_Bool SvLBox::NotifyAcceptDrop( SvLBoxEntry* ) 1923 { 1924 DBG_CHKTHIS(SvLBox,0); 1925 return sal_True; 1926 } 1927 1928 // handler and methods for Drag - finished handler. 1929 // The with get GetDragFinishedHdl() get link can set on the 1930 // TransferDataContainer. This link is a callback for the DragFinished 1931 // call. AddBox method is called from the GetDragFinishedHdl() and the 1932 // remove is called in link callback and in the destructor. So it can't 1933 // called to a deleted object. 1934 1935 namespace 1936 { 1937 struct SortLBoxes : public rtl::Static<SvULongsSort, SortLBoxes> {}; 1938 } 1939 1940 void SvLBox::AddBoxToDDList_Impl( const SvLBox& rB ) 1941 { 1942 sal_uLong nVal = (sal_uLong)&rB; 1943 SortLBoxes::get().Insert( nVal ); 1944 } 1945 1946 void SvLBox::RemoveBoxFromDDList_Impl( const SvLBox& rB ) 1947 { 1948 sal_uLong nVal = (sal_uLong)&rB; 1949 SortLBoxes::get().Remove( nVal ); 1950 } 1951 1952 IMPL_STATIC_LINK( SvLBox, DragFinishHdl_Impl, sal_Int8*, pAction ) 1953 { 1954 sal_uLong nVal = (sal_uLong)pThis; 1955 sal_uInt16 nFnd; 1956 SvULongsSort &rSortLBoxes = SortLBoxes::get(); 1957 if( rSortLBoxes.Seek_Entry( nVal, &nFnd ) ) 1958 { 1959 pThis->DragFinished( *pAction ); 1960 rSortLBoxes.Remove( nFnd, 1 ); 1961 } 1962 return 0; 1963 } 1964 1965 Link SvLBox::GetDragFinishedHdl() const 1966 { 1967 AddBoxToDDList_Impl( *this ); 1968 return STATIC_LINK( this, SvLBox, DragFinishHdl_Impl ); 1969 } 1970 1971 void SvLBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& ) const 1972 { 1973 } 1974 1975 ::com::sun::star::uno::Reference< XAccessible > SvLBox::CreateAccessible() 1976 { 1977 return ::com::sun::star::uno::Reference< XAccessible >(); 1978 } 1979 1980 Rectangle SvLBox::GetBoundingRect( SvLBoxEntry* ) 1981 { 1982 return Rectangle(); 1983 } 1984 1985