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