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 #define _SVTREEBX_CXX 32 #include <vcl/svapp.hxx> 33 #ifndef GCC 34 #endif 35 36 class TabBar; 37 38 // #102891# ----------------------- 39 40 #include <svtools/svlbox.hxx> 41 #include <svtools/svlbitm.hxx> 42 #include <svtools/svtreebx.hxx> 43 #include <tools/diagnose_ex.h> 44 #include <svimpbox.hxx> 45 #include <unotools/accessiblestatesethelper.hxx> 46 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 47 #include <com/sun/star/awt/XWindowPeer.hpp> 48 49 50 using namespace ::com::sun::star::accessibility; 51 52 /* 53 Bugs/ToDo 54 55 - Berechnung Rectangle beim Inplace-Editing (Bug bei manchen Fonts) 56 - SetSpaceBetweenEntries: Offset wird in SetEntryHeight nicht 57 beruecksichtigt 58 */ 59 60 #define TREEFLAG_FIXEDHEIGHT 0x0010 61 62 63 DBG_NAME(SvTreeListBox) 64 65 #define SV_LBOX_DEFAULT_INDENT_PIXEL 20 66 67 SvTreeListBox::SvTreeListBox( Window* pParent, WinBits nWinStyle ) 68 : SvLBox( pParent, nWinStyle ) 69 { 70 DBG_CTOR(SvTreeListBox,0); 71 InitTreeView(); 72 73 SetSublistOpenWithLeftRight(); 74 } 75 76 SvTreeListBox::SvTreeListBox( Window* pParent , const ResId& rResId ) 77 : SvLBox( pParent,rResId ) 78 { 79 DBG_CTOR(SvTreeListBox,0); 80 81 InitTreeView(); 82 Resize(); 83 84 SetSublistOpenWithLeftRight(); 85 } 86 87 void SvTreeListBox::InitTreeView() 88 { 89 DBG_CHKTHIS(SvTreeListBox,0); 90 pCheckButtonData = NULL; 91 pEdEntry = NULL; 92 pEdItem = NULL; 93 nEntryHeight = 0; 94 pEdCtrl = NULL; 95 nFirstSelTab = 0; 96 nLastSelTab = 0; 97 nFocusWidth = -1; 98 99 Link* pLink = new Link( LINK(this,SvTreeListBox, DefaultCompare) ); 100 pLBoxImpl->m_pLink = pLink; 101 102 nTreeFlags = TREEFLAG_RECALCTABS; 103 nIndent = SV_LBOX_DEFAULT_INDENT_PIXEL; 104 nEntryHeightOffs = SV_ENTRYHEIGHTOFFS_PIXEL; 105 pImp = new SvImpLBox( this, GetModel(), GetStyle() ); 106 107 aContextBmpMode = SVLISTENTRYFLAG_EXPANDED; 108 nContextBmpWidthMax = 0; 109 SetFont( GetFont() ); 110 SetSpaceBetweenEntries( 0 ); 111 SetLineColor(); 112 InitSettings( sal_True, sal_True, sal_True ); 113 ImplInitStyle(); 114 SetTabs(); 115 } 116 117 118 SvTreeListBox::~SvTreeListBox() 119 { 120 DBG_DTOR(SvTreeListBox,0); 121 pImp->CallEventListeners( VCLEVENT_OBJECT_DYING ); 122 delete pImp; 123 delete pLBoxImpl->m_pLink; 124 ClearTabList(); 125 } 126 127 void SvTreeListBox::SetExtendedWinBits( ExtendedWinBits _nBits ) 128 { 129 pImp->SetExtendedWindowBits( _nBits ); 130 } 131 132 ExtendedWinBits SvTreeListBox::GetExtendedWinBits() const 133 { 134 return pImp->GetExtendedWindowBits(); 135 } 136 137 void SvTreeListBox::SetModel( SvLBoxTreeList* pNewModel ) 138 { 139 DBG_CHKTHIS(SvTreeListBox,0); 140 pImp->SetModel( pNewModel ); 141 SvLBox::SetModel( pNewModel ); 142 } 143 144 void SvTreeListBox::DisconnectFromModel() 145 { 146 DBG_CHKTHIS(SvTreeListBox,0); 147 SvLBox::DisconnectFromModel(); 148 pImp->SetModel( GetModel() ); 149 } 150 151 152 sal_uInt16 SvTreeListBox::IsA() 153 { 154 DBG_CHKTHIS(SvTreeListBox,0); 155 return SV_LISTBOX_ID_TREEBOX; 156 } 157 158 void SvTreeListBox::SetSublistOpenWithReturn( sal_Bool b ) 159 { 160 pImp->bSubLstOpRet = b; 161 } 162 163 sal_Bool SvTreeListBox::IsSublistOpenWithReturn() const 164 { 165 return pImp->bSubLstOpRet; 166 } 167 168 void SvTreeListBox::SetSublistOpenWithLeftRight( sal_Bool b ) 169 { 170 pImp->bSubLstOpLR = b; 171 } 172 173 sal_Bool SvTreeListBox::IsSublistOpenWithLeftRight() const 174 { 175 return pImp->bSubLstOpLR; 176 } 177 178 void SvTreeListBox::Resize() 179 { 180 DBG_CHKTHIS(SvTreeListBox,0); 181 if( IsEditingActive() ) 182 EndEditing( sal_True ); 183 SvLBox::Resize(); 184 pImp->Resize(); 185 nFocusWidth = -1; 186 pImp->ShowCursor( sal_False ); 187 pImp->ShowCursor( sal_True ); 188 } 189 190 /* Faelle: 191 192 A) Entries haben Bitmaps 193 0. Keine Buttons 194 1. Node-Buttons (optional auch an Root-Items) 195 2. Node-Buttons (optional auch an Root-Items) + CheckButton 196 3. CheckButton 197 B) Entries haben keine Bitmaps (->ueber WindowBits wg. D&D !!!!!!) 198 0. Keine Buttons 199 1. Node-Buttons (optional auch an Root-Items) 200 2. Node-Buttons (optional auch an Root-Items) + CheckButton 201 3. CheckButton 202 */ 203 204 #define NO_BUTTONS 0 205 #define NODE_BUTTONS 1 206 #define NODE_AND_CHECK_BUTTONS 2 207 #define CHECK_BUTTONS 3 208 209 #define TABFLAGS_TEXT (SV_LBOXTAB_DYNAMIC | \ 210 SV_LBOXTAB_ADJUST_LEFT | \ 211 SV_LBOXTAB_EDITABLE | \ 212 SV_LBOXTAB_SHOW_SELECTION) 213 214 #define TABFLAGS_CONTEXTBMP (SV_LBOXTAB_DYNAMIC | SV_LBOXTAB_ADJUST_CENTER) 215 216 #define TABFLAGS_CHECKBTN (SV_LBOXTAB_DYNAMIC | \ 217 SV_LBOXTAB_ADJUST_CENTER | \ 218 SV_LBOXTAB_PUSHABLE) 219 220 #define TAB_STARTPOS 2 221 222 // bei Aenderungen GetTextOffset beruecksichtigen 223 void SvTreeListBox::SetTabs() 224 { 225 DBG_CHKTHIS(SvTreeListBox,0); 226 if( IsEditingActive() ) 227 EndEditing( sal_True ); 228 nTreeFlags &= (~TREEFLAG_RECALCTABS); 229 nFocusWidth = -1; 230 const WinBits nStyle( GetStyle() ); 231 sal_Bool bHasButtons = (nStyle & WB_HASBUTTONS)!=0; 232 sal_Bool bHasButtonsAtRoot = (nStyle & (WB_HASLINESATROOT | 233 WB_HASBUTTONSATROOT))!=0; 234 long nStartPos = TAB_STARTPOS; 235 long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width(); 236 237 long nCheckWidth = 0; 238 if( nTreeFlags & TREEFLAG_CHKBTN ) 239 nCheckWidth = pCheckButtonData->aBmps[0].GetSizePixel().Width(); 240 long nCheckWidthDIV2 = nCheckWidth / 2; 241 242 long nContextWidth = nContextBmpWidthMax; 243 long nContextWidthDIV2 = nContextWidth / 2; 244 245 ClearTabList(); 246 247 int nCase = NO_BUTTONS; 248 if( !(nTreeFlags & TREEFLAG_CHKBTN) ) 249 { 250 if( bHasButtons ) 251 nCase = NODE_BUTTONS; 252 } 253 else 254 { 255 if( bHasButtons ) 256 nCase = NODE_AND_CHECK_BUTTONS; 257 else 258 nCase = CHECK_BUTTONS; 259 } 260 261 switch( nCase ) 262 { 263 case NO_BUTTONS : 264 nStartPos += nContextWidthDIV2; // wg. Zentrierung 265 AddTab( nStartPos, TABFLAGS_CONTEXTBMP ); 266 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 267 // Abstand setzen nur wenn Bitmaps da 268 if( nContextBmpWidthMax ) 269 nStartPos += 5; // Abstand Context-Bmp - Text 270 AddTab( nStartPos, TABFLAGS_TEXT ); 271 break; 272 273 case NODE_BUTTONS : 274 if( bHasButtonsAtRoot ) 275 nStartPos += ( nIndent + (nNodeWidthPixel/2) ); 276 else 277 nStartPos += nContextWidthDIV2; 278 AddTab( nStartPos, TABFLAGS_CONTEXTBMP ); 279 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 280 // Abstand setzen nur wenn Bitmaps da 281 if( nContextBmpWidthMax ) 282 nStartPos += 5; // Abstand Context-Bmp - Text 283 AddTab( nStartPos, TABFLAGS_TEXT ); 284 break; 285 286 case NODE_AND_CHECK_BUTTONS : 287 if( bHasButtonsAtRoot ) 288 nStartPos += ( nIndent + nNodeWidthPixel ); 289 else 290 nStartPos += nCheckWidthDIV2; 291 AddTab( nStartPos, TABFLAGS_CHECKBTN ); 292 nStartPos += nCheckWidthDIV2; // rechter Rand des CheckButtons 293 nStartPos += 3; // Abstand CheckButton Context-Bmp 294 nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp 295 AddTab( nStartPos, TABFLAGS_CONTEXTBMP ); 296 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 297 // Abstand setzen nur wenn Bitmaps da 298 if( nContextBmpWidthMax ) 299 nStartPos += 5; // Abstand Context-Bmp - Text 300 AddTab( nStartPos, TABFLAGS_TEXT ); 301 break; 302 303 case CHECK_BUTTONS : 304 nStartPos += nCheckWidthDIV2; 305 AddTab( nStartPos, TABFLAGS_CHECKBTN ); 306 nStartPos += nCheckWidthDIV2; // rechter Rand CheckButton 307 nStartPos += 3; // Abstand CheckButton Context-Bmp 308 nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp 309 AddTab( nStartPos, TABFLAGS_CONTEXTBMP ); 310 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 311 // Abstand setzen nur wenn Bitmaps da 312 if( nContextBmpWidthMax ) 313 nStartPos += 5; // Abstand Context-Bmp - Text 314 AddTab( nStartPos, TABFLAGS_TEXT ); 315 break; 316 } 317 pImp->NotifyTabsChanged(); 318 } 319 320 void SvTreeListBox::InitEntry( SvLBoxEntry* pEntry, 321 const XubString& aStr, const Image& aCollEntryBmp, const Image& aExpEntryBmp, 322 SvLBoxButtonKind eButtonKind) 323 { 324 DBG_CHKTHIS(SvTreeListBox,0); 325 SvLBoxButton* pButton; 326 SvLBoxString* pString; 327 SvLBoxContextBmp* pContextBmp; 328 329 if( nTreeFlags & TREEFLAG_CHKBTN ) 330 { 331 pButton= new SvLBoxButton( pEntry,eButtonKind,0,pCheckButtonData ); 332 pEntry->AddItem( pButton ); 333 } 334 335 pContextBmp= new SvLBoxContextBmp( pEntry,0, aCollEntryBmp,aExpEntryBmp, 336 aContextBmpMode ); 337 pEntry->AddItem( pContextBmp ); 338 339 pString = new SvLBoxString( pEntry, 0, aStr ); 340 pEntry->AddItem( pString ); 341 } 342 343 String SvTreeListBox::GetEntryText(SvLBoxEntry* pEntry) const 344 { 345 DBG_CHKTHIS(SvTreeListBox,0); 346 DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): no entry" ); 347 SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); 348 DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): item not found" ); 349 return pItem->GetText(); 350 } 351 352 String SvTreeListBox::SearchEntryText( SvLBoxEntry* pEntry ) const 353 { 354 DBG_CHKTHIS(SvTreeListBox,0); 355 DBG_ASSERT( pEntry, "SvTreeListBox::SearchEntryText(): no entry" ); 356 String sRet; 357 sal_uInt16 nCount = pEntry->ItemCount(); 358 sal_uInt16 nCur = 0; 359 SvLBoxItem* pItem; 360 while( nCur < nCount ) 361 { 362 pItem = pEntry->GetItem( nCur ); 363 if ( pItem->IsA() == SV_ITEM_ID_LBOXSTRING && 364 static_cast<SvLBoxString*>( pItem )->GetText().Len() > 0 ) 365 { 366 sRet = static_cast<SvLBoxString*>( pItem )->GetText(); 367 break; 368 } 369 nCur++; 370 } 371 return sRet; 372 } 373 374 const Image& SvTreeListBox::GetExpandedEntryBmp(SvLBoxEntry* pEntry, BmpColorMode _eMode) const 375 { 376 DBG_CHKTHIS(SvTreeListBox,0); 377 DBG_ASSERT(pEntry,"Entry?"); 378 SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)); 379 DBG_ASSERT(pItem,"GetContextBmp:Item not found"); 380 return pItem->GetBitmap2( _eMode ); 381 } 382 383 const Image& SvTreeListBox::GetCollapsedEntryBmp( SvLBoxEntry* pEntry, BmpColorMode _eMode ) const 384 { 385 DBG_CHKTHIS(SvTreeListBox,0); 386 DBG_ASSERT(pEntry,"Entry?"); 387 SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)); 388 DBG_ASSERT(pItem,"GetContextBmp:Item not found"); 389 return pItem->GetBitmap1( _eMode ); 390 } 391 392 IMPL_LINK_INLINE_START( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData ) 393 { 394 DBG_CHKTHIS(SvTreeListBox,0); 395 pHdlEntry = pData->GetActEntry(); 396 CheckButtonHdl(); 397 return 0; 398 } 399 IMPL_LINK_INLINE_END( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData ) 400 401 SvLBoxEntry* SvTreeListBox::InsertEntry( const XubString& aText,SvLBoxEntry* pParent, 402 sal_Bool bChildsOnDemand, sal_uLong nPos, void* pUser, 403 SvLBoxButtonKind eButtonKind ) 404 { 405 DBG_CHKTHIS(SvTreeListBox,0); 406 nTreeFlags |= TREEFLAG_MANINS; 407 408 const Image& rDefExpBmp = pImp->GetDefaultEntryExpBmp( ); 409 const Image& rDefColBmp = pImp->GetDefaultEntryColBmp( ); 410 411 aCurInsertedExpBmp = rDefExpBmp; 412 aCurInsertedColBmp = rDefColBmp; 413 414 SvLBoxEntry* pEntry = CreateEntry(); 415 pEntry->SetUserData( pUser ); 416 InitEntry( pEntry, aText, rDefColBmp, rDefExpBmp, eButtonKind ); 417 pEntry->EnableChildsOnDemand( bChildsOnDemand ); 418 419 // Add the HC versions of the default images 420 SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) ); 421 if( pBmpItem ) 422 { 423 pBmpItem->SetBitmap1( pImp->GetDefaultEntryColBmp( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST ); 424 pBmpItem->SetBitmap2( pImp->GetDefaultEntryExpBmp( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST ); 425 } 426 427 if( !pParent ) 428 SvLBox::Insert( pEntry, nPos ); 429 else 430 SvLBox::Insert( pEntry, pParent, nPos ); 431 432 aPrevInsertedExpBmp = rDefExpBmp; 433 aPrevInsertedColBmp = rDefColBmp; 434 435 nTreeFlags &= (~TREEFLAG_MANINS); 436 437 return pEntry; 438 } 439 440 SvLBoxEntry* SvTreeListBox::InsertEntry( const XubString& aText, 441 const Image& aExpEntryBmp, const Image& aCollEntryBmp, 442 SvLBoxEntry* pParent, sal_Bool bChildsOnDemand, sal_uLong nPos, void* pUser, 443 SvLBoxButtonKind eButtonKind ) 444 { 445 DBG_CHKTHIS(SvTreeListBox,0); 446 nTreeFlags |= TREEFLAG_MANINS; 447 448 aCurInsertedExpBmp = aExpEntryBmp; 449 aCurInsertedColBmp = aCollEntryBmp; 450 451 SvLBoxEntry* pEntry = CreateEntry(); 452 pEntry->SetUserData( pUser ); 453 InitEntry( pEntry, aText, aCollEntryBmp, aExpEntryBmp, eButtonKind ); 454 455 pEntry->EnableChildsOnDemand( bChildsOnDemand ); 456 457 if( !pParent ) 458 SvLBox::Insert( pEntry, nPos ); 459 else 460 SvLBox::Insert( pEntry, pParent, nPos ); 461 462 aPrevInsertedExpBmp = aExpEntryBmp; 463 aPrevInsertedColBmp = aCollEntryBmp; 464 465 nTreeFlags &= (~TREEFLAG_MANINS); 466 467 return pEntry; 468 } 469 470 void SvTreeListBox::SetEntryText( SvLBoxEntry* pEntry, const XubString& aStr) 471 { 472 DBG_CHKTHIS(SvTreeListBox,0); 473 SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); 474 DBG_ASSERT(pItem,"SetText:Item not found"); 475 pItem->SetText( pEntry, aStr ); 476 pItem->InitViewData( this, pEntry, 0 ); 477 GetModel()->InvalidateEntry( pEntry ); 478 } 479 480 void SvTreeListBox::SetExpandedEntryBmp( SvLBoxEntry* pEntry, const Image& aBmp, BmpColorMode _eMode ) 481 { 482 DBG_CHKTHIS(SvTreeListBox,0); 483 SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)); 484 485 DBG_ASSERT(pItem,"SetExpBmp:Item not found"); 486 pItem->SetBitmap2( aBmp, _eMode ); 487 488 GetModel()->InvalidateEntry( pEntry ); 489 SetEntryHeight( pEntry ); 490 Size aSize = aBmp.GetSizePixel(); 491 // #97680# --------------- 492 short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() ); 493 if( nWidth > nContextBmpWidthMax ) 494 { 495 nContextBmpWidthMax = nWidth; 496 SetTabs(); 497 } 498 } 499 500 void SvTreeListBox::SetCollapsedEntryBmp(SvLBoxEntry* pEntry,const Image& aBmp, BmpColorMode _eMode ) 501 { 502 DBG_CHKTHIS(SvTreeListBox,0); 503 SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)); 504 505 DBG_ASSERT(pItem,"SetExpBmp:Item not found"); 506 pItem->SetBitmap1( aBmp, _eMode ); 507 508 GetModel()->InvalidateEntry( pEntry ); 509 SetEntryHeight( pEntry ); 510 Size aSize = aBmp.GetSizePixel(); 511 // #97680# ----------- 512 short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() ); 513 if( nWidth > nContextBmpWidthMax ) 514 { 515 nContextBmpWidthMax = nWidth; 516 SetTabs(); 517 } 518 } 519 520 void SvTreeListBox::ImpEntryInserted( SvLBoxEntry* pEntry ) 521 { 522 DBG_CHKTHIS(SvTreeListBox,0); 523 524 SvLBoxEntry* pParent = (SvLBoxEntry*)pModel->GetParent( pEntry ); 525 if( pParent ) 526 { 527 sal_uInt16 nFlags = pParent->GetFlags(); 528 nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP; 529 pParent->SetFlags( nFlags ); 530 } 531 532 if(!((nTreeFlags & TREEFLAG_MANINS) && 533 (aPrevInsertedExpBmp == aCurInsertedExpBmp) && 534 (aPrevInsertedColBmp == aCurInsertedColBmp) )) 535 { 536 Size aSize = GetCollapsedEntryBmp( pEntry ).GetSizePixel(); 537 if( aSize.Width() > nContextBmpWidthMax ) 538 { 539 nContextBmpWidthMax = (short)aSize.Width(); 540 nTreeFlags |= TREEFLAG_RECALCTABS; 541 } 542 aSize = GetExpandedEntryBmp( pEntry ).GetSizePixel(); 543 if( aSize.Width() > nContextBmpWidthMax ) 544 { 545 nContextBmpWidthMax = (short)aSize.Width(); 546 nTreeFlags |= TREEFLAG_RECALCTABS; 547 } 548 } 549 SetEntryHeight( (SvLBoxEntry*)pEntry ); 550 } 551 552 553 554 void SvTreeListBox::SetCheckButtonState( SvLBoxEntry* pEntry, SvButtonState eState) 555 { 556 DBG_CHKTHIS(SvTreeListBox,0); 557 if( nTreeFlags & TREEFLAG_CHKBTN ) 558 { 559 SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON)); 560 if(!(pItem && pItem->CheckModification())) 561 return ; 562 switch( eState ) 563 { 564 case SV_BUTTON_CHECKED: 565 pItem->SetStateChecked(); 566 break; 567 568 case SV_BUTTON_UNCHECKED: 569 pItem->SetStateUnchecked(); 570 break; 571 572 case SV_BUTTON_TRISTATE: 573 pItem->SetStateTristate(); 574 break; 575 } 576 InvalidateEntry( pEntry ); 577 } 578 } 579 580 SvButtonState SvTreeListBox::GetCheckButtonState( SvLBoxEntry* pEntry ) const 581 { 582 DBG_CHKTHIS(SvTreeListBox,0); 583 SvButtonState eState = SV_BUTTON_UNCHECKED; 584 if( nTreeFlags & TREEFLAG_CHKBTN ) 585 { 586 SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON)); 587 if(!pItem) 588 return SV_BUTTON_TRISTATE; 589 sal_uInt16 nButtonFlags = pItem->GetButtonFlags(); 590 eState = pCheckButtonData->ConvertToButtonState( nButtonFlags ); 591 } 592 return eState; 593 } 594 595 void SvTreeListBox::CheckButtonHdl() 596 { 597 DBG_CHKTHIS(SvTreeListBox,0); 598 aCheckButtonHdl.Call( this ); 599 if ( pCheckButtonData ) 600 pImp->CallEventListeners( VCLEVENT_CHECKBOX_TOGGLE, (void*)pCheckButtonData->GetActEntry() ); 601 } 602 603 // ********************************************************************* 604 // ********************************************************************* 605 606 // 607 // TODO: Momentan werden die Daten so geklont, dass sie dem 608 // Standard-TreeView-Format entsprechen. Hier sollte eigentlich 609 // das Model als Referenz dienen. Dies fuehrt dazu, dass 610 // SvLBoxEntry::Clone _nicht_ gerufen wird, sondern nur dessen 611 // Basisklasse SvListEntry 612 // 613 614 SvLBoxEntry* SvTreeListBox::CloneEntry( SvLBoxEntry* pSource ) 615 { 616 DBG_CHKTHIS(SvTreeListBox,0); 617 XubString aStr; 618 Image aCollEntryBmp; 619 Image aExpEntryBmp; 620 SvLBoxButtonKind eButtonKind = SvLBoxButtonKind_enabledCheckbox; 621 622 SvLBoxString* pStringItem = (SvLBoxString*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); 623 if( pStringItem ) 624 aStr = pStringItem->GetText(); 625 SvLBoxContextBmp* pBmpItem = (SvLBoxContextBmp*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)); 626 if( pBmpItem ) 627 { 628 aCollEntryBmp = pBmpItem->GetBitmap1( BMP_COLOR_NORMAL ); 629 aExpEntryBmp = pBmpItem->GetBitmap2( BMP_COLOR_NORMAL ); 630 } 631 SvLBoxButton* pButtonItem = (SvLBoxButton*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXBUTTON)); 632 if( pButtonItem ) 633 eButtonKind = pButtonItem->GetKind(); 634 SvLBoxEntry* pClone = CreateEntry(); 635 InitEntry( pClone, aStr, aCollEntryBmp, aExpEntryBmp, eButtonKind ); 636 pClone->SvListEntry::Clone( pSource ); 637 pClone->EnableChildsOnDemand( pSource->HasChildsOnDemand() ); 638 pClone->SetUserData( pSource->GetUserData() ); 639 640 if ( pBmpItem ) 641 { 642 SvLBoxContextBmp* pCloneBitmap = static_cast< SvLBoxContextBmp* >( pClone->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) ); 643 if ( pCloneBitmap ) 644 { 645 pCloneBitmap->SetBitmap1( pBmpItem->GetBitmap1( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST ); 646 pCloneBitmap->SetBitmap2( pBmpItem->GetBitmap2( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST ); 647 } 648 } 649 650 return pClone; 651 } 652 653 // ********************************************************************* 654 // ********************************************************************* 655 656 657 void SvTreeListBox::ShowExpandBitmapOnCursor( sal_Bool bYes ) 658 { 659 DBG_CHKTHIS(SvTreeListBox,0); 660 if( bYes ) 661 aContextBmpMode = SVLISTENTRYFLAG_FOCUSED; 662 else 663 aContextBmpMode = SVLISTENTRYFLAG_EXPANDED; 664 } 665 666 void SvTreeListBox::SetIndent( short nNewIndent ) 667 { 668 DBG_CHKTHIS(SvTreeListBox,0); 669 nIndent = nNewIndent; 670 SetTabs(); 671 if( IsUpdateMode() ) 672 Invalidate(); 673 } 674 675 const Image& SvTreeListBox::GetDefaultExpandedEntryBmp( BmpColorMode _eMode ) const 676 { 677 return pImp->GetDefaultEntryExpBmp( _eMode ); 678 } 679 680 const Image& SvTreeListBox::GetDefaultCollapsedEntryBmp( BmpColorMode _eMode ) const 681 { 682 return pImp->GetDefaultEntryColBmp( _eMode ); 683 } 684 685 void SvTreeListBox::SetDefaultExpandedEntryBmp( const Image& aBmp, BmpColorMode _eMode ) 686 { 687 DBG_CHKTHIS(SvTreeListBox,0); 688 Size aSize = aBmp.GetSizePixel(); 689 if( aSize.Width() > nContextBmpWidthMax ) 690 nContextBmpWidthMax = (short)aSize.Width(); 691 SetTabs(); 692 693 pImp->SetDefaultEntryExpBmp( aBmp, _eMode ); 694 } 695 696 void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image& aBmp, BmpColorMode _eMode ) 697 { 698 DBG_CHKTHIS(SvTreeListBox,0); 699 Size aSize = aBmp.GetSizePixel(); 700 if( aSize.Width() > nContextBmpWidthMax ) 701 nContextBmpWidthMax = (short)aSize.Width(); 702 SetTabs(); 703 704 pImp->SetDefaultEntryColBmp( aBmp, _eMode ); 705 } 706 707 void SvTreeListBox::EnableCheckButton( SvLBoxButtonData* pData ) 708 { 709 DBG_CHKTHIS(SvTreeListBox,0); 710 DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0"); 711 if( !pData ) 712 nTreeFlags &= (~TREEFLAG_CHKBTN); 713 else 714 { 715 SetCheckButtonData( pData ); 716 nTreeFlags |= TREEFLAG_CHKBTN; 717 pData->SetLink( LINK(this, SvTreeListBox, CheckButtonClick)); 718 } 719 720 SetTabs(); 721 if( IsUpdateMode() ) 722 Invalidate(); 723 } 724 725 void SvTreeListBox::SetCheckButtonData( SvLBoxButtonData* pData ) 726 { 727 DBG_CHKTHIS(SvTreeListBox,0); 728 if ( pData ) 729 pCheckButtonData = pData; 730 } 731 732 const Image& SvTreeListBox::GetDefaultExpandedNodeImage( BmpColorMode _eMode ) 733 { 734 return SvImpLBox::GetDefaultExpandedNodeImage( _eMode ); 735 } 736 737 const Image& SvTreeListBox::GetDefaultCollapsedNodeImage( BmpColorMode _eMode ) 738 { 739 return SvImpLBox::GetDefaultCollapsedNodeImage( _eMode ); 740 } 741 742 void SvTreeListBox::SetNodeBitmaps( const Image& rCollapsedNodeBmp, const Image& rExpandedNodeBmp, BmpColorMode _eMode ) 743 { 744 DBG_CHKTHIS(SvTreeListBox,0); 745 SetExpandedNodeBmp( rExpandedNodeBmp, _eMode ); 746 SetCollapsedNodeBmp( rCollapsedNodeBmp, _eMode ); 747 SetTabs(); 748 } 749 750 void SvTreeListBox::SetDontKnowNodeBitmap( const Image& rDontKnowBmp, BmpColorMode _eMode ) 751 { 752 pImp->SetDontKnowNodeBmp( rDontKnowBmp, _eMode ); 753 } 754 755 sal_Bool SvTreeListBox::EditingEntry( SvLBoxEntry*, Selection& ) 756 { 757 DBG_CHKTHIS(SvTreeListBox,0); 758 return sal_True; 759 } 760 761 sal_Bool SvTreeListBox::EditedEntry( SvLBoxEntry* /*pEntry*/,const XubString& /*rNewText*/) 762 { 763 DBG_CHKTHIS(SvTreeListBox,0); 764 return sal_True; 765 } 766 767 void SvTreeListBox::EnableInplaceEditing( sal_Bool bOn ) 768 { 769 DBG_CHKTHIS(SvTreeListBox,0); 770 SvLBox::EnableInplaceEditing( bOn ); 771 } 772 773 void SvTreeListBox::KeyInput( const KeyEvent& rKEvt ) 774 { 775 DBG_CHKTHIS(SvTreeListBox,0); 776 // unter OS/2 bekommen wir auch beim Editieren Key-Up/Down 777 if( IsEditingActive() ) 778 return; 779 780 nImpFlags |= SVLBOX_IS_TRAVELSELECT; 781 782 #ifdef OVDEBUG 783 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); 784 switch ( nCode ) 785 { 786 case KEY_F1: 787 { 788 SvLBoxEntry* pEntry = First(); 789 pEntry = NextVisible( pEntry ); 790 SetEntryText( pEntry, "SetEntryText" ); 791 Sound::Beep(); 792 } 793 break; 794 } 795 #endif 796 797 if( !pImp->KeyInput( rKEvt ) ) 798 SvLBox::KeyInput( rKEvt ); 799 800 nImpFlags &= ~SVLBOX_IS_TRAVELSELECT; 801 } 802 803 void SvTreeListBox::RequestingChilds( SvLBoxEntry* pParent ) 804 { 805 DBG_CHKTHIS(SvTreeListBox,0); 806 if( !pParent->HasChilds() ) 807 InsertEntry( String::CreateFromAscii("<dummy>"), pParent, sal_False, LIST_APPEND ); 808 } 809 810 void SvTreeListBox::GetFocus() 811 { 812 DBG_CHKTHIS(SvTreeListBox,0); 813 pImp->GetFocus(); 814 SvLBox::GetFocus(); 815 816 SvLBoxEntry* pEntry = FirstSelected(); 817 if ( pEntry ) 818 pImp->CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry ); 819 820 } 821 822 void SvTreeListBox::LoseFocus() 823 { 824 DBG_CHKTHIS(SvTreeListBox,0); 825 pImp->LoseFocus(); 826 SvLBox::LoseFocus(); 827 } 828 829 void SvTreeListBox::ModelHasCleared() 830 { 831 DBG_CHKTHIS(SvTreeListBox,0); 832 pImp->pCursor = 0; //sonst Absturz beim Inplace-Editieren im GetFocus 833 delete pEdCtrl; 834 pEdCtrl = NULL; 835 pImp->Clear(); 836 nFocusWidth = -1; 837 838 nContextBmpWidthMax = 0; 839 SetDefaultExpandedEntryBmp( GetDefaultExpandedEntryBmp() ); 840 SetDefaultCollapsedEntryBmp( GetDefaultCollapsedEntryBmp() ); 841 842 if( !(nTreeFlags & TREEFLAG_FIXEDHEIGHT )) 843 nEntryHeight = 0; 844 AdjustEntryHeight( GetFont() ); 845 AdjustEntryHeight( GetDefaultExpandedEntryBmp() ); 846 AdjustEntryHeight( GetDefaultCollapsedEntryBmp() ); 847 848 SvLBox::ModelHasCleared(); 849 // if( IsUpdateMode() ) 850 // Invalidate(); 851 } 852 853 void SvTreeListBox::ShowTargetEmphasis( SvLBoxEntry* pEntry, sal_Bool /* bShow */ ) 854 { 855 DBG_CHKTHIS(SvTreeListBox,0); 856 pImp->PaintDDCursor( pEntry ); 857 } 858 859 void SvTreeListBox::ScrollOutputArea( short nDeltaEntries ) 860 { 861 DBG_CHKTHIS(SvTreeListBox,0); 862 if( !nDeltaEntries || !pImp->aVerSBar.IsVisible() ) 863 return; 864 865 long nThumb = pImp->aVerSBar.GetThumbPos(); 866 long nMax = pImp->aVerSBar.GetRange().Max(); 867 868 NotifyBeginScroll(); 869 if( nDeltaEntries < 0 ) 870 { 871 // das Fenster nach oben verschieben 872 nDeltaEntries *= -1; 873 long nVis = pImp->aVerSBar.GetVisibleSize(); 874 long nTemp = nThumb + nVis; 875 if( nDeltaEntries > (nMax - nTemp) ) 876 nDeltaEntries = (short)(nMax - nTemp); 877 pImp->PageDown( (sal_uInt16)nDeltaEntries ); 878 } 879 else 880 { 881 if( nDeltaEntries > nThumb ) 882 nDeltaEntries = (short)nThumb; 883 pImp->PageUp( (sal_uInt16)nDeltaEntries ); 884 } 885 pImp->SyncVerThumb(); 886 NotifyEndScroll(); 887 } 888 889 void SvTreeListBox::SetSelectionMode( SelectionMode eSelectMode ) 890 { 891 DBG_CHKTHIS(SvTreeListBox,0); 892 SvLBox::SetSelectionMode( eSelectMode ); 893 pImp->SetSelectionMode( eSelectMode ); 894 } 895 896 void SvTreeListBox::SetDragDropMode( DragDropMode nDDMode ) 897 { 898 DBG_CHKTHIS(SvTreeListBox,0); 899 SvLBox::SetDragDropMode( nDDMode ); 900 pImp->SetDragDropMode( nDDMode ); 901 } 902 903 short SvTreeListBox::GetHeightOffset(const Image& rBmp, Size& aSizeLogic ) 904 { 905 DBG_CHKTHIS(SvTreeListBox,0); 906 short nOffset = 0; 907 aSizeLogic = rBmp.GetSizePixel(); 908 if( GetEntryHeight() > aSizeLogic.Height() ) 909 nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2; 910 return nOffset; 911 } 912 913 short SvTreeListBox::GetHeightOffset(const Font& /* rFont */, Size& aSizeLogic ) 914 { 915 DBG_CHKTHIS(SvTreeListBox,0); 916 short nOffset = 0; 917 aSizeLogic = Size(GetTextWidth('X'), GetTextHeight()); 918 if( GetEntryHeight() > aSizeLogic.Height() ) 919 nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2; 920 return nOffset; 921 } 922 923 void SvTreeListBox::SetEntryHeight( SvLBoxEntry* pEntry ) 924 { 925 DBG_CHKTHIS(SvTreeListBox,0); 926 short nHeight, nHeightMax=0; 927 sal_uInt16 nCount = pEntry->ItemCount(); 928 sal_uInt16 nCur = 0; 929 SvViewDataEntry* pViewData = GetViewDataEntry( pEntry ); 930 while( nCur < nCount ) 931 { 932 SvLBoxItem* pItem = pEntry->GetItem( nCur ); 933 nHeight = (short)(pItem->GetSize( pViewData, nCur ).Height()); 934 if( nHeight > nHeightMax ) 935 nHeightMax = nHeight; 936 nCur++; 937 } 938 939 if( nHeightMax > nEntryHeight ) 940 { 941 nEntryHeight = nHeightMax; 942 SvLBox::SetFont( GetFont() ); 943 pImp->SetEntryHeight( nHeightMax ); 944 } 945 } 946 947 void SvTreeListBox::SetEntryHeight( short nHeight, sal_Bool bAlways ) 948 { 949 DBG_CHKTHIS(SvTreeListBox,0); 950 951 if( bAlways || nHeight > nEntryHeight ) 952 { 953 nEntryHeight = nHeight; 954 if( nEntryHeight ) 955 nTreeFlags |= TREEFLAG_FIXEDHEIGHT; 956 else 957 nTreeFlags &= ~TREEFLAG_FIXEDHEIGHT; 958 SvLBox::SetFont( GetFont() ); 959 pImp->SetEntryHeight( nHeight ); 960 } 961 } 962 963 964 void SvTreeListBox::AdjustEntryHeight( const Image& rBmp ) 965 { 966 DBG_CHKTHIS(SvTreeListBox,0); 967 Size aSize; 968 GetHeightOffset( rBmp, aSize ); 969 if( aSize.Height() > nEntryHeight ) 970 { 971 nEntryHeight = (short)aSize.Height() + nEntryHeightOffs; 972 pImp->SetEntryHeight( nEntryHeight ); 973 } 974 } 975 976 void SvTreeListBox::AdjustEntryHeight( const Font& rFont ) 977 { 978 DBG_CHKTHIS(SvTreeListBox,0); 979 Size aSize; 980 GetHeightOffset( rFont, aSize ); 981 if( aSize.Height() > nEntryHeight ) 982 { 983 nEntryHeight = (short)aSize.Height() + nEntryHeightOffs; 984 pImp->SetEntryHeight( nEntryHeight ); 985 } 986 } 987 988 sal_Bool SvTreeListBox::Expand( SvLBoxEntry* pParent ) 989 { 990 DBG_CHKTHIS(SvTreeListBox,0); 991 pHdlEntry = pParent; 992 sal_Bool bExpanded = sal_False; 993 sal_uInt16 nFlags; 994 995 if( pParent->HasChildsOnDemand() ) 996 RequestingChilds( pParent ); 997 if( pParent->HasChilds() ) 998 { 999 nImpFlags |= SVLBOX_IS_EXPANDING; 1000 if( ExpandingHdl() ) 1001 { 1002 bExpanded = sal_True; 1003 SvListView::Expand( pParent ); 1004 pImp->EntryExpanded( pParent ); 1005 pHdlEntry = pParent; 1006 ExpandedHdl(); 1007 } 1008 nFlags = pParent->GetFlags(); 1009 nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP; 1010 nFlags |= SV_ENTRYFLAG_HAD_CHILDREN; 1011 pParent->SetFlags( nFlags ); 1012 } 1013 else 1014 { 1015 nFlags = pParent->GetFlags(); 1016 nFlags |= SV_ENTRYFLAG_NO_NODEBMP; 1017 pParent->SetFlags( nFlags ); 1018 GetModel()->InvalidateEntry( pParent ); // neu zeichnen 1019 } 1020 1021 // --> OD 2009-04-01 #i92103# 1022 if ( bExpanded ) 1023 { 1024 pImp->CallEventListeners( VCLEVENT_ITEM_EXPANDED, pParent ); 1025 } 1026 // <-- 1027 1028 return bExpanded; 1029 } 1030 1031 sal_Bool SvTreeListBox::Collapse( SvLBoxEntry* pParent ) 1032 { 1033 DBG_CHKTHIS(SvTreeListBox,0); 1034 nImpFlags &= ~SVLBOX_IS_EXPANDING; 1035 pHdlEntry = pParent; 1036 sal_Bool bCollapsed = sal_False; 1037 1038 if( ExpandingHdl() ) 1039 { 1040 bCollapsed = sal_True; 1041 pImp->CollapsingEntry( pParent ); 1042 SvListView::Collapse( pParent ); 1043 pImp->EntryCollapsed( pParent ); 1044 pHdlEntry = pParent; 1045 ExpandedHdl(); 1046 } 1047 1048 // --> OD 2009-04-01 #i92103# 1049 if ( bCollapsed ) 1050 { 1051 pImp->CallEventListeners( VCLEVENT_ITEM_COLLAPSED, pParent ); 1052 } 1053 // <-- 1054 1055 return bCollapsed; 1056 } 1057 1058 sal_Bool SvTreeListBox::Select( SvLBoxEntry* pEntry, sal_Bool bSelect ) 1059 { 1060 DBG_CHKTHIS(SvTreeListBox,0); 1061 DBG_ASSERT(pEntry,"Select: Null-Ptr"); 1062 sal_Bool bRetVal = SvListView::Select( pEntry, bSelect ); 1063 DBG_ASSERT(IsSelected(pEntry)==bSelect,"Select failed"); 1064 if( bRetVal ) 1065 { 1066 pImp->EntrySelected( pEntry, bSelect ); 1067 pHdlEntry = pEntry; 1068 if( bSelect ) 1069 { 1070 SelectHdl(); 1071 pImp->CallEventListeners( VCLEVENT_LISTBOX_SELECT, pEntry ); 1072 } 1073 else 1074 DeselectHdl(); 1075 } 1076 return bRetVal; 1077 } 1078 1079 sal_uLong SvTreeListBox::SelectChilds( SvLBoxEntry* pParent, sal_Bool bSelect ) 1080 { 1081 DBG_CHKTHIS(SvTreeListBox,0); 1082 pImp->DestroyAnchor(); 1083 sal_uLong nRet = 0; 1084 if( !pParent->HasChilds() ) 1085 return 0; 1086 sal_uInt16 nRefDepth = pModel->GetDepth( pParent ); 1087 SvLBoxEntry* pChild = FirstChild( pParent ); 1088 do { 1089 nRet++; 1090 Select( pChild, bSelect ); 1091 pChild = Next( pChild ); 1092 } while( pChild && pModel->GetDepth( pChild ) > nRefDepth ); 1093 return nRet; 1094 } 1095 1096 void SvTreeListBox::SelectAll( sal_Bool bSelect, sal_Bool ) 1097 { 1098 DBG_CHKTHIS(SvTreeListBox,0); 1099 pImp->SelAllDestrAnch( 1100 bSelect, 1101 sal_True, // Anker loeschen, 1102 sal_True ); // auch bei SINGLE_SELECTION den Cursor deselektieren 1103 } 1104 1105 void SvTreeListBox::ModelHasInsertedTree( SvListEntry* pEntry ) 1106 { 1107 DBG_CHKTHIS(SvTreeListBox,0); 1108 sal_uInt16 nRefDepth = pModel->GetDepth( (SvLBoxEntry*)pEntry ); 1109 SvLBoxEntry* pTmp = (SvLBoxEntry*)pEntry; 1110 do 1111 { 1112 ImpEntryInserted( pTmp ); 1113 pTmp = Next( pTmp ); 1114 } while( pTmp && nRefDepth < pModel->GetDepth( pTmp ) ); 1115 pImp->TreeInserted( (SvLBoxEntry*)pEntry ); 1116 } 1117 1118 void SvTreeListBox::ModelHasInserted( SvListEntry* pEntry ) 1119 { 1120 DBG_CHKTHIS(SvTreeListBox,0); 1121 ImpEntryInserted( (SvLBoxEntry*)pEntry ); 1122 pImp->EntryInserted( (SvLBoxEntry*)pEntry ); 1123 } 1124 1125 void SvTreeListBox::ModelIsMoving(SvListEntry* pSource, 1126 SvListEntry* /* pTargetParent */, 1127 sal_uLong /* nChildPos */ ) 1128 { 1129 DBG_CHKTHIS(SvTreeListBox,0); 1130 pImp->MovingEntry( (SvLBoxEntry*)pSource ); 1131 } 1132 1133 void SvTreeListBox::ModelHasMoved( SvListEntry* pSource ) 1134 { 1135 DBG_CHKTHIS(SvTreeListBox,0); 1136 pImp->EntryMoved( (SvLBoxEntry*)pSource ); 1137 } 1138 1139 void SvTreeListBox::ModelIsRemoving( SvListEntry* pEntry ) 1140 { 1141 DBG_CHKTHIS(SvTreeListBox,0); 1142 if(pEdEntry == pEntry) 1143 pEdEntry = NULL; 1144 1145 pImp->RemovingEntry( (SvLBoxEntry*)pEntry ); 1146 NotifyRemoving( (SvLBoxEntry*)pEntry ); 1147 } 1148 1149 void SvTreeListBox::ModelHasRemoved( SvListEntry* pEntry ) 1150 { 1151 DBG_CHKTHIS(SvTreeListBox,0); 1152 if ( pEntry == pHdlEntry) 1153 pHdlEntry = NULL; 1154 pImp->EntryRemoved(); 1155 } 1156 1157 void SvTreeListBox::SetCollapsedNodeBmp( const Image& rBmp, BmpColorMode _eMode ) 1158 { 1159 DBG_CHKTHIS(SvTreeListBox,0); 1160 AdjustEntryHeight( rBmp ); 1161 pImp->SetCollapsedNodeBmp( rBmp, _eMode ); 1162 } 1163 1164 void SvTreeListBox::SetExpandedNodeBmp( const Image& rBmp, BmpColorMode _eMode ) 1165 { 1166 DBG_CHKTHIS(SvTreeListBox,0); 1167 AdjustEntryHeight( rBmp ); 1168 pImp->SetExpandedNodeBmp( rBmp, _eMode ); 1169 } 1170 1171 1172 void SvTreeListBox::SetFont( const Font& rFont ) 1173 { 1174 DBG_CHKTHIS(SvTreeListBox,0); 1175 Font aTempFont( rFont ); 1176 aTempFont.SetTransparent( sal_True ); 1177 Control::SetFont( aTempFont ); 1178 AdjustEntryHeight( aTempFont ); 1179 // immer Invalidieren, sonst fallen wir 1180 // bei SetEntryHeight auf die Nase 1181 RecalcViewData(); 1182 } 1183 1184 1185 void SvTreeListBox::Paint( const Rectangle& rRect ) 1186 { 1187 DBG_CHKTHIS(SvTreeListBox,0); 1188 SvLBox::Paint( rRect ); 1189 if( nTreeFlags & TREEFLAG_RECALCTABS ) 1190 SetTabs(); 1191 pImp->Paint( rRect ); 1192 } 1193 1194 void SvTreeListBox::MouseButtonDown( const MouseEvent& rMEvt ) 1195 { 1196 DBG_CHKTHIS(SvTreeListBox,0); 1197 pImp->MouseButtonDown( rMEvt ); 1198 } 1199 1200 void SvTreeListBox::MouseButtonUp( const MouseEvent& rMEvt ) 1201 { 1202 DBG_CHKTHIS(SvTreeListBox,0); 1203 pImp->MouseButtonUp( rMEvt ); 1204 } 1205 1206 void SvTreeListBox::MouseMove( const MouseEvent& rMEvt ) 1207 { 1208 DBG_CHKTHIS(SvTreeListBox,0); 1209 pImp->MouseMove( rMEvt ); 1210 } 1211 1212 1213 void SvTreeListBox::SetUpdateMode( sal_Bool bUpdate ) 1214 { 1215 DBG_CHKTHIS(SvTreeListBox,0); 1216 pImp->SetUpdateMode( bUpdate ); 1217 } 1218 1219 void SvTreeListBox::SetUpdateModeFast( sal_Bool bUpdate ) 1220 { 1221 DBG_CHKTHIS(SvTreeListBox,0); 1222 pImp->SetUpdateModeFast( bUpdate ); 1223 } 1224 1225 void SvTreeListBox::SetSpaceBetweenEntries( short nOffsLogic ) 1226 { 1227 DBG_CHKTHIS(SvTreeListBox,0); 1228 if( nOffsLogic != nEntryHeightOffs ) 1229 { 1230 nEntryHeight = nEntryHeight - nEntryHeightOffs; 1231 nEntryHeightOffs = (short)nOffsLogic; 1232 nEntryHeight = nEntryHeight + nOffsLogic; 1233 AdjustEntryHeight( GetFont() ); 1234 RecalcViewData(); 1235 pImp->SetEntryHeight( nEntryHeight ); 1236 } 1237 } 1238 1239 void SvTreeListBox::SetCursor( SvLBoxEntry* pEntry, sal_Bool bForceNoSelect ) 1240 { 1241 DBG_CHKTHIS(SvTreeListBox,0); 1242 pImp->SetCursor(pEntry, bForceNoSelect); 1243 } 1244 1245 void SvTreeListBox::SetCurEntry( SvLBoxEntry* pEntry ) 1246 { 1247 DBG_CHKTHIS(SvTreeListBox,0); 1248 pImp->SetCurEntry( pEntry ); 1249 } 1250 1251 Image SvTreeListBox::GetCollapsedNodeBmp( BmpColorMode _eMode ) const 1252 { 1253 return pImp->GetCollapsedNodeBmp( _eMode ); 1254 } 1255 1256 Image SvTreeListBox::GetExpandedNodeBmp( BmpColorMode _eMode ) const 1257 { 1258 return pImp->GetExpandedNodeBmp( _eMode ); 1259 } 1260 1261 Point SvTreeListBox::GetEntryPosition( SvLBoxEntry* pEntry ) const 1262 { 1263 return pImp->GetEntryPosition( pEntry ); 1264 } 1265 1266 void SvTreeListBox::ShowEntry( SvLBoxEntry* pEntry ) 1267 { 1268 MakeVisible( pEntry ); 1269 } 1270 1271 void SvTreeListBox::MakeVisible( SvLBoxEntry* pEntry ) 1272 { 1273 pImp->MakeVisible(pEntry); 1274 } 1275 1276 void SvTreeListBox::MakeVisible( SvLBoxEntry* pEntry, sal_Bool bMoveToTop ) 1277 { 1278 pImp->MakeVisible( pEntry, bMoveToTop ); 1279 } 1280 1281 void SvTreeListBox::ModelHasEntryInvalidated( SvListEntry* pEntry ) 1282 { 1283 DBG_CHKTHIS(SvTreeListBox,0); 1284 // die einzelnen Items des Entries reinitialisieren 1285 SvLBox::ModelHasEntryInvalidated( pEntry ); 1286 // repainten 1287 pImp->InvalidateEntry( (SvLBoxEntry*)pEntry ); 1288 } 1289 1290 void SvTreeListBox::EditItemText( SvLBoxEntry* pEntry, SvLBoxString* pItem, 1291 const Selection& rSelection ) 1292 { 1293 DBG_CHKTHIS(SvTreeListBox,0); 1294 DBG_ASSERT(pEntry&&pItem,"EditItemText: Bad params"); 1295 if( IsSelected( pEntry )) 1296 { 1297 pImp->ShowCursor( sal_False ); 1298 SvListView::Select( pEntry, sal_False ); 1299 PaintEntry( pEntry ); 1300 SvListView::Select( pEntry, sal_True ); 1301 pImp->ShowCursor( sal_True ); 1302 } 1303 pEdEntry = pEntry; 1304 pEdItem = pItem; 1305 SvLBoxTab* pTab = GetTab( pEntry, pItem ); 1306 DBG_ASSERT(pTab,"EditItemText:Tab not found"); 1307 1308 Size aItemSize( pItem->GetSize(this, pEntry) ); 1309 Point aPos = GetEntryPosition( pEntry ); 1310 aPos.Y() += ( nEntryHeight - aItemSize.Height() ) / 2; 1311 aPos.X() = GetTabPos( pEntry, pTab ); 1312 long nOutputWidth = pImp->GetOutputSize().Width(); 1313 Size aSize( nOutputWidth - aPos.X(), aItemSize.Height() ); 1314 sal_uInt16 nPos = aTabs.GetPos( pTab ); 1315 if( nPos+1 < aTabs.Count() ) 1316 { 1317 SvLBoxTab* pRightTab = (SvLBoxTab*)aTabs.GetObject( nPos + 1 ); 1318 long nRight = GetTabPos( pEntry, pRightTab ); 1319 if( nRight <= nOutputWidth ) 1320 aSize.Width() = nRight - aPos.X(); 1321 } 1322 Point aOrigin( GetMapMode().GetOrigin() ); 1323 aPos += aOrigin; // in Win-Koord umrechnen 1324 aSize.Width() -= aOrigin.X(); 1325 Rectangle aRect( aPos, aSize ); 1326 #ifdef OS2 1327 // Platz lassen fuer WB_BORDER 1328 aRect.Left() -= 2; 1329 aRect.Top() -= 3; 1330 aRect.Bottom() += 3; 1331 #endif 1332 EditText( pItem->GetText(), aRect, rSelection ); 1333 } 1334 1335 void SvTreeListBox::CancelEditing() 1336 { 1337 DBG_CHKTHIS(SvTreeListBox,0); 1338 SvLBox::CancelTextEditing(); 1339 } 1340 1341 void SvTreeListBox::EditEntry( SvLBoxEntry* pEntry ) 1342 { 1343 pImp->aEditClickPos = Point( -1, -1 ); 1344 ImplEditEntry( pEntry ); 1345 } 1346 1347 void SvTreeListBox::ImplEditEntry( SvLBoxEntry* pEntry ) 1348 { 1349 DBG_CHKTHIS(SvTreeListBox,0); 1350 if( IsEditingActive() ) 1351 EndEditing(); 1352 if( !pEntry ) 1353 pEntry = GetCurEntry(); 1354 if( pEntry ) 1355 { 1356 long nClickX = pImp->aEditClickPos.X(); 1357 bool bIsMouseTriggered = nClickX >= 0; 1358 1359 SvLBoxString* pItem = NULL; 1360 sal_uInt16 nCount = pEntry->ItemCount(); 1361 for( sal_uInt16 i = 0 ; i < nCount ; i++ ) 1362 { 1363 SvLBoxItem* pTmpItem = pEntry->GetItem( i ); 1364 if( pTmpItem->IsA() != SV_ITEM_ID_LBOXSTRING ) 1365 continue; 1366 1367 SvLBoxTab* pTab = GetTab( pEntry, pTmpItem ); 1368 long nTabPos = pTab->GetPos(); 1369 long nNextTabPos = -1; 1370 if( i < nCount - 1 ) 1371 { 1372 SvLBoxItem* pNextItem = pEntry->GetItem( i + 1 ); 1373 SvLBoxTab* pNextTab = GetTab( pEntry, pNextItem ); 1374 nNextTabPos = pNextTab->GetPos(); 1375 } 1376 1377 if( pTab && pTab->IsEditable() ) 1378 { 1379 if( !bIsMouseTriggered || (nClickX > nTabPos && (nNextTabPos == -1 || nClickX < nNextTabPos ) ) ) 1380 { 1381 pItem = static_cast<SvLBoxString*>( pTmpItem ); 1382 break; 1383 } 1384 } 1385 } 1386 1387 Selection aSel( SELECTION_MIN, SELECTION_MAX ); 1388 if( pItem && EditingEntry( pEntry, aSel ) ) 1389 { 1390 SelectAll( sal_False ); 1391 MakeVisible( pEntry ); 1392 EditItemText( pEntry, pItem, aSel ); 1393 } 1394 } 1395 } 1396 1397 sal_Bool SvTreeListBox::AreChildrenTransient() const 1398 { 1399 return pImp->AreChildrenTransient(); 1400 } 1401 1402 void SvTreeListBox::SetChildrenNotTransient() 1403 { 1404 pImp->SetChildrenNotTransient(); 1405 } 1406 1407 void SvTreeListBox::EditedText( const XubString& rStr ) 1408 1409 { 1410 DBG_CHKTHIS(SvTreeListBox,0); 1411 if(pEdEntry) // we have to check if this entry is null that means that it is removed while editing 1412 { 1413 Point aPos = GetEntryPosition( pEdEntry ); 1414 if( EditedEntry( pEdEntry, rStr ) ) 1415 { 1416 ((SvLBoxString*)pEdItem)->SetText( pEdEntry, rStr ); 1417 pModel->InvalidateEntry( pEdEntry ); 1418 } 1419 //if( GetSelectionMode() == SINGLE_SELECTION ) 1420 //{ 1421 if( GetSelectionCount() == 0 ) 1422 Select( pEdEntry ); 1423 if( GetSelectionMode() == MULTIPLE_SELECTION && !GetCurEntry() ) 1424 SetCurEntry( pEdEntry ); 1425 //} 1426 } 1427 } 1428 1429 void SvTreeListBox::EditingRequest( SvLBoxEntry* pEntry, SvLBoxItem* pItem, 1430 const Point& ) 1431 { 1432 DBG_CHKTHIS(SvTreeListBox,0); 1433 if( IsEditingActive() ) 1434 EndEditing(); 1435 if( pItem->IsA() == SV_ITEM_ID_LBOXSTRING ) 1436 { 1437 Selection aSel( SELECTION_MIN, SELECTION_MAX ); 1438 if( EditingEntry( pEntry, aSel ) ) 1439 { 1440 SelectAll( sal_False ); 1441 EditItemText( pEntry, (SvLBoxString*)pItem, aSel ); 1442 } 1443 } 1444 } 1445 1446 1447 1448 SvLBoxEntry* SvTreeListBox::GetDropTarget( const Point& rPos ) 1449 { 1450 DBG_CHKTHIS(SvTreeListBox,0); 1451 // Scrollen 1452 if( rPos.Y() < 12 ) 1453 { 1454 SvLBox::ImplShowTargetEmphasis( SvLBox::pTargetEntry, sal_False ); 1455 ScrollOutputArea( +1 ); 1456 } 1457 else 1458 { 1459 Size aSize( pImp->GetOutputSize() ); 1460 if( rPos.Y() > aSize.Height() - 12 ) 1461 { 1462 SvLBox::ImplShowTargetEmphasis( SvLBox::pTargetEntry, sal_False ); 1463 ScrollOutputArea( -1 ); 1464 } 1465 } 1466 1467 SvLBoxEntry* pTarget = pImp->GetEntry( rPos ); 1468 // bei Droppen in leere Flaeche -> den letzten Eintrag nehmen 1469 if( !pTarget ) 1470 return (SvLBoxEntry*)LastVisible(); 1471 else if( (GetDragDropMode() & SV_DRAGDROP_ENABLE_TOP) && 1472 pTarget == First() && rPos.Y() < 6 ) 1473 return 0; 1474 1475 return pTarget; 1476 } 1477 1478 1479 SvLBoxEntry* SvTreeListBox::GetEntry( const Point& rPos, sal_Bool bHit ) const 1480 { 1481 DBG_CHKTHIS(SvTreeListBox,0); 1482 SvLBoxEntry* pEntry = pImp->GetEntry( rPos ); 1483 if( pEntry && bHit ) 1484 { 1485 long nLine = pImp->GetEntryLine( pEntry ); 1486 if( !(pImp->EntryReallyHit( pEntry, rPos, nLine)) ) 1487 return 0; 1488 } 1489 return pEntry; 1490 } 1491 1492 SvLBoxEntry* SvTreeListBox::GetCurEntry() const 1493 { 1494 DBG_CHKTHIS(SvTreeListBox,0); 1495 return pImp->GetCurEntry(); 1496 } 1497 1498 void SvTreeListBox::ImplInitStyle() 1499 { 1500 DBG_CHKTHIS(SvTreeListBox,0); 1501 1502 const WinBits nWindowStyle = GetStyle(); 1503 1504 nTreeFlags |= TREEFLAG_RECALCTABS; 1505 if( nWindowStyle & WB_SORT ) 1506 { 1507 GetModel()->SetSortMode( SortAscending ); 1508 GetModel()->SetCompareHdl( LINK(this,SvTreeListBox,DefaultCompare)); 1509 } 1510 else 1511 { 1512 GetModel()->SetSortMode( SortNone ); 1513 GetModel()->SetCompareHdl( Link() ); 1514 } 1515 #ifdef OS2 1516 nWindowStyle |= WB_VSCROLL; 1517 #endif 1518 pImp->SetStyle( nWindowStyle ); 1519 pImp->Resize(); 1520 Invalidate(); 1521 } 1522 1523 void SvTreeListBox::PaintEntry( SvLBoxEntry* pEntry ) 1524 { 1525 DBG_CHKTHIS(SvTreeListBox,0); 1526 DBG_ASSERT(pEntry,"PaintEntry:No Entry"); 1527 if( pEntry ) 1528 pImp->PaintEntry( pEntry ); 1529 } 1530 1531 void SvTreeListBox::InvalidateEntry( SvLBoxEntry* pEntry ) 1532 { 1533 DBG_CHKTHIS(SvTreeListBox,0); 1534 DBG_ASSERT(pEntry,"InvalidateEntry:No Entry"); 1535 if( pEntry ) 1536 { 1537 GetModel()->InvalidateEntry( pEntry ); 1538 // pImp->InvalidateEntry( pEntry ); 1539 } 1540 } 1541 1542 1543 long SvTreeListBox::PaintEntry(SvLBoxEntry* pEntry,long nLine,sal_uInt16 nTabFlags) 1544 { 1545 return PaintEntry1(pEntry,nLine,nTabFlags); 1546 } 1547 1548 #define SV_TAB_BORDER 8 1549 1550 long SvTreeListBox::PaintEntry1(SvLBoxEntry* pEntry,long nLine,sal_uInt16 nTabFlags, 1551 sal_Bool bHasClipRegion ) 1552 { 1553 DBG_CHKTHIS(SvTreeListBox,0); 1554 1555 Rectangle aRect; // multi purpose 1556 1557 sal_Bool bHorSBar = pImp->HasHorScrollBar(); 1558 PreparePaint( pEntry ); 1559 1560 // #97680# ------------------ 1561 pImp->UpdateContextBmpWidthMax( pEntry ); 1562 1563 if( nTreeFlags & TREEFLAG_RECALCTABS ) 1564 SetTabs(); 1565 1566 short nTempEntryHeight = GetEntryHeight(); 1567 long nWidth = pImp->GetOutputSize().Width(); 1568 1569 // wurde innerhalb des PreparePaints die horizontale ScrollBar 1570 // angeschaltet? Wenn ja, muss die ClipRegion neu gesetzt werden 1571 if( !bHorSBar && pImp->HasHorScrollBar() ) 1572 SetClipRegion( Region(pImp->GetClipRegionRect()) ); 1573 1574 Point aEntryPos( GetMapMode().GetOrigin() ); 1575 aEntryPos.X() *= -1; // Umrechnung Dokumentkoord. 1576 long nMaxRight = nWidth + aEntryPos.X() - 1; 1577 1578 Color aBackupTextColor( GetTextColor() ); 1579 Font aBackupFont( GetFont() ); 1580 Color aBackupColor = GetFillColor(); 1581 1582 bool bCurFontIsSel = false; 1583 sal_Bool bInUse = pEntry->HasInUseEmphasis(); 1584 // wenn eine ClipRegion von aussen gesetzt wird, dann 1585 // diese nicht zuruecksetzen 1586 const WinBits nWindowStyle = GetStyle(); 1587 const sal_Bool bResetClipRegion = !bHasClipRegion; 1588 const sal_Bool bHideSelection = ((nWindowStyle & WB_HIDESELECTION) && !HasFocus())!=0; 1589 const StyleSettings& rSettings = GetSettings().GetStyleSettings(); 1590 1591 Font aHighlightFont( GetFont() ); 1592 const Color aHighlightTextColor( rSettings.GetHighlightTextColor() ); 1593 aHighlightFont.SetColor( aHighlightTextColor ); 1594 1595 Size aRectSize( 0, nTempEntryHeight ); 1596 1597 if( !bHasClipRegion && nWindowStyle & WB_HSCROLL ) 1598 { 1599 SetClipRegion( Region(pImp->GetClipRegionRect()) ); 1600 bHasClipRegion = sal_True; 1601 } 1602 1603 SvViewDataEntry* pViewDataEntry = GetViewDataEntry( pEntry ); 1604 1605 sal_uInt16 nTabCount = aTabs.Count(); 1606 sal_uInt16 nItemCount = pEntry->ItemCount(); 1607 sal_uInt16 nCurTab = 0; 1608 sal_uInt16 nCurItem = 0; 1609 1610 while( nCurTab < nTabCount && nCurItem < nItemCount ) 1611 { 1612 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nCurTab ); 1613 sal_uInt16 nNextTab = nCurTab + 1; 1614 SvLBoxTab* pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0; 1615 SvLBoxItem* pItem = nCurItem < nItemCount ? pEntry->GetItem(nCurItem) : 0; 1616 1617 sal_uInt16 nFlags = pTab->nFlags; 1618 Size aSize( pItem->GetSize( pViewDataEntry, nCurItem )); 1619 long nTabPos = GetTabPos( pEntry, pTab ); 1620 1621 long nNextTabPos; 1622 if( pNextTab ) 1623 nNextTabPos = GetTabPos( pEntry, pNextTab ); 1624 else 1625 { 1626 nNextTabPos = nMaxRight; 1627 if( nTabPos > nMaxRight ) 1628 nNextTabPos += 50; 1629 } 1630 1631 long nX; 1632 if( pTab->nFlags & SV_LBOXTAB_ADJUST_RIGHT ) 1633 //verhindern, das rechter Rand von der Tabtrennung abgeschnitten wird 1634 nX = nTabPos + pTab->CalcOffset(aSize.Width(), (nNextTabPos-SV_TAB_BORDER-1) -nTabPos); 1635 else 1636 nX = nTabPos + pTab->CalcOffset(aSize.Width(), nNextTabPos-nTabPos); 1637 1638 if( nFlags & nTabFlags ) 1639 { 1640 if( !bHasClipRegion && nX + aSize.Width() >= nMaxRight ) 1641 { 1642 SetClipRegion( Region(pImp->GetClipRegionRect()) ); 1643 bHasClipRegion = sal_True; 1644 } 1645 aEntryPos.X() = nX; 1646 aEntryPos.Y() = nLine; 1647 1648 // Hintergrund-Muster & Farbe bestimmen 1649 1650 Wallpaper aWallpaper = GetBackground(); 1651 1652 int bSelTab = nFlags & SV_LBOXTAB_SHOW_SELECTION; 1653 sal_uInt16 nItemType = pItem->IsA(); 1654 1655 if ( pViewDataEntry->IsSelected() && bSelTab && !pViewDataEntry->IsCursored() ) 1656 { 1657 Color aNewWallColor = rSettings.GetHighlightColor(); 1658 if ( !bInUse || nItemType != SV_ITEM_ID_LBOXCONTEXTBMP ) 1659 { 1660 // if the face color is bright then the deactive color is also bright 1661 // -> so you can't see any deactive selection 1662 if ( bHideSelection && !rSettings.GetFaceColor().IsBright() && 1663 aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright() ) 1664 aNewWallColor = rSettings.GetDeactiveColor(); 1665 // set font color to highlight 1666 if ( !bCurFontIsSel ) 1667 { 1668 SetTextColor( aHighlightTextColor ); 1669 SetFont( aHighlightFont ); 1670 bCurFontIsSel = true; 1671 } 1672 } 1673 aWallpaper.SetColor( aNewWallColor ); 1674 } 1675 else // keine Selektion 1676 { 1677 if( bInUse && nItemType == SV_ITEM_ID_LBOXCONTEXTBMP ) 1678 aWallpaper.SetColor( rSettings.GetFieldColor() ); 1679 else if( bCurFontIsSel ) 1680 { 1681 bCurFontIsSel = false; 1682 SetTextColor( aBackupTextColor ); 1683 SetFont( aBackupFont ); 1684 } 1685 } 1686 1687 // Hintergrund zeichnen 1688 if( !(nTreeFlags & TREEFLAG_USESEL)) 1689 { 1690 // nur den Bereich zeichnen, den das Item einnimmt 1691 aRectSize.Width() = aSize.Width(); 1692 aRect.SetPos( aEntryPos ); 1693 aRect.SetSize( aRectSize ); 1694 } 1695 else 1696 { 1697 // vom aktuellen bis zum naechsten Tab zeichnen 1698 if( nCurTab != 0 ) 1699 aRect.Left() = nTabPos; 1700 else 1701 // beim nullten Tab immer ab Spalte 0 zeichnen 1702 // (sonst Probleme bei Tabs mit Zentrierung) 1703 aRect.Left() = 0; 1704 aRect.Top() = nLine; 1705 aRect.Bottom() = nLine + nTempEntryHeight - 1; 1706 if( pNextTab ) 1707 { 1708 long nRight; 1709 nRight = GetTabPos(pEntry,pNextTab)-1; 1710 if( nRight > nMaxRight ) 1711 nRight = nMaxRight; 1712 aRect.Right() = nRight; 1713 } 1714 else 1715 aRect.Right() = nMaxRight; 1716 } 1717 // bei anwenderdefinierter Selektion, die bei einer Tabposition 1718 // groesser 0 beginnt den Hintergrund des 0.ten Items nicht 1719 // fuellen, da sonst z.B. TablistBoxen mit Linien nicht 1720 // realisiert werden koennen. 1721 if( !(nCurTab==0 && (nTreeFlags & TREEFLAG_USESEL) && nFirstSelTab) ) 1722 { 1723 SetFillColor( aWallpaper.GetColor() ); 1724 // Bei kleinen hor. Resizes tritt dieser Fall auf 1725 if( aRect.Left() < aRect.Right() ) 1726 DrawRect( aRect ); 1727 } 1728 // Item zeichnen 1729 // vertikal zentrieren 1730 aEntryPos.Y() += ( nTempEntryHeight - aSize.Height() ) / 2; 1731 pItem->Paint( aEntryPos, *this, pViewDataEntry->GetFlags(), pEntry ); 1732 1733 // Trennungslinie zwischen Tabs 1734 if( pNextTab && pItem->IsA() == SV_ITEM_ID_LBOXSTRING && 1735 // nicht am rechten Fensterrand! 1736 aRect.Right() < nMaxRight ) 1737 { 1738 aRect.Left() = aRect.Right() - SV_TAB_BORDER; 1739 DrawRect( aRect ); 1740 } 1741 1742 SetFillColor( aBackupColor ); 1743 } 1744 nCurItem++; 1745 nCurTab++; 1746 } 1747 if( pViewDataEntry->IsCursored() && !HasFocus() ) 1748 { 1749 // Cursor-Emphasis 1750 SetFillColor(); 1751 Color aOldLineColor = GetLineColor(); 1752 SetLineColor( Color( COL_BLACK ) ); 1753 aRect = GetFocusRect( pEntry, nLine ); 1754 aRect.Top()++; 1755 aRect.Bottom()--; 1756 DrawRect( aRect ); 1757 SetLineColor( aOldLineColor ); 1758 SetFillColor( aBackupColor ); 1759 } 1760 1761 if( bCurFontIsSel ) 1762 { 1763 SetTextColor( aBackupTextColor ); 1764 SetFont( aBackupFont ); 1765 } 1766 1767 sal_uInt16 nFirstDynTabPos; 1768 SvLBoxTab* pFirstDynamicTab = GetFirstDynamicTab( nFirstDynTabPos ); 1769 long nDynTabPos = GetTabPos( pEntry, pFirstDynamicTab ); 1770 nDynTabPos += pImp->nNodeBmpTabDistance; 1771 nDynTabPos += pImp->nNodeBmpWidth / 2; 1772 nDynTabPos += 4; // 4 Pixel Reserve, damit die Node-Bitmap 1773 // nicht zu nah am naechsten Tab steht 1774 1775 if( (!(pEntry->GetFlags() & SV_ENTRYFLAG_NO_NODEBMP)) && 1776 (nWindowStyle & WB_HASBUTTONS) && pFirstDynamicTab && 1777 ( pEntry->HasChilds() || pEntry->HasChildsOnDemand() ) ) 1778 { 1779 // ersten festen Tab suchen, und pruefen ob die Node-Bitmap 1780 // in ihn hineinragt 1781 sal_uInt16 nNextTab = nFirstDynTabPos; 1782 SvLBoxTab* pNextTab; 1783 do 1784 { 1785 nNextTab++; 1786 pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0; 1787 } while( pNextTab && pNextTab->IsDynamic() ); 1788 1789 if( !pNextTab || (GetTabPos( pEntry, pNextTab ) > nDynTabPos) ) 1790 { 1791 if((nWindowStyle & WB_HASBUTTONSATROOT) || pModel->GetDepth(pEntry) > 0) 1792 { 1793 Point aPos( GetTabPos(pEntry,pFirstDynamicTab), nLine ); 1794 aPos.X() += pImp->nNodeBmpTabDistance; 1795 1796 const Image* pImg = 0; 1797 BmpColorMode eBitmapMode = BMP_COLOR_NORMAL; 1798 if ( GetSettings().GetStyleSettings().GetHighContrastMode() ) 1799 eBitmapMode = BMP_COLOR_HIGHCONTRAST; 1800 1801 if( IsExpanded(pEntry) ) 1802 pImg = &pImp->GetExpandedNodeBmp( eBitmapMode ); 1803 else 1804 { 1805 if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() && 1806 (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) && 1807 pImp->GetDontKnowNodeBmp().GetSizePixel().Width() ) 1808 pImg = &pImp->GetDontKnowNodeBmp( eBitmapMode ); 1809 else 1810 pImg = &pImp->GetCollapsedNodeBmp( eBitmapMode ); 1811 } 1812 aPos.Y() += (nTempEntryHeight - pImg->GetSizePixel().Height()) / 2; 1813 1814 sal_uInt16 nStyle = 0; 1815 if ( !IsEnabled() ) 1816 nStyle |= IMAGE_DRAW_DISABLE; 1817 1818 //native 1819 sal_Bool bNativeOK = sal_False; 1820 if ( IsNativeControlSupported( CTRL_LISTNODE, PART_ENTIRE_CONTROL) ) 1821 { 1822 ImplControlValue aControlValue; 1823 Rectangle aCtrlRegion( aPos, pImg->GetSizePixel() ); 1824 ControlState nState = 0; 1825 1826 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED; 1827 1828 if ( IsExpanded(pEntry) ) 1829 aControlValue.setTristateVal( BUTTONVALUE_ON );//expanded node 1830 else 1831 { 1832 if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() && 1833 (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) && 1834 pImp->GetDontKnowNodeBmp().GetSizePixel().Width() ) 1835 aControlValue.setTristateVal( BUTTONVALUE_DONTKNOW );//dont know 1836 else 1837 aControlValue.setTristateVal( BUTTONVALUE_OFF );//collapsed node 1838 } 1839 1840 bNativeOK = DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL, 1841 aCtrlRegion, nState, aControlValue, rtl::OUString() ); 1842 } 1843 1844 if( !bNativeOK) { 1845 //non native 1846 DrawImage( aPos, *pImg ,nStyle); 1847 } 1848 } 1849 } 1850 } 1851 1852 1853 if( bHasClipRegion && bResetClipRegion ) 1854 SetClipRegion(); 1855 return 0; // nRowLen; 1856 } 1857 1858 void SvTreeListBox::PreparePaint( SvLBoxEntry* ) 1859 { 1860 } 1861 1862 Rectangle SvTreeListBox::GetFocusRect( SvLBoxEntry* pEntry, long nLine ) 1863 { 1864 DBG_CHKTHIS(SvTreeListBox,0); 1865 Size aSize; 1866 Rectangle aRect; 1867 aRect.Top() = nLine; 1868 aSize.Height() = GetEntryHeight(); 1869 1870 long nRealWidth = pImp->GetOutputSize().Width(); 1871 nRealWidth -= GetMapMode().GetOrigin().X(); 1872 1873 sal_uInt16 nCurTab; 1874 SvLBoxTab* pTab = GetFirstTab( SV_LBOXTAB_SHOW_SELECTION, nCurTab ); 1875 long nTabPos = 0; 1876 if( pTab ) 1877 nTabPos = GetTabPos( pEntry, pTab ); 1878 long nNextTabPos; 1879 if( pTab && nCurTab < aTabs.Count() - 1 ) 1880 { 1881 SvLBoxTab* pNextTab = (SvLBoxTab*)aTabs.GetObject( nCurTab + 1 ); 1882 nNextTabPos = GetTabPos( pEntry, pNextTab ); 1883 } 1884 else 1885 { 1886 nNextTabPos = nRealWidth; 1887 if( nTabPos > nRealWidth ) 1888 nNextTabPos += 50; 1889 } 1890 1891 sal_Bool bUserSelection = (sal_Bool)( nTreeFlags & TREEFLAG_USESEL ) != 0; 1892 if( !bUserSelection ) 1893 { 1894 if( pTab && nCurTab < pEntry->ItemCount() ) 1895 { 1896 SvLBoxItem* pItem = pEntry->GetItem( nCurTab ); 1897 aSize.Width() = pItem->GetSize( this, pEntry ).Width(); 1898 if( !aSize.Width() ) 1899 aSize.Width() = 15; 1900 long nX = nTabPos; //GetTabPos( pEntry, pTab ); 1901 // Ausrichtung 1902 nX += pTab->CalcOffset( aSize.Width(), nNextTabPos - nTabPos ); 1903 aRect.Left() = nX; 1904 // damit erster & letzter Buchstabe nicht angeknabbert werden 1905 aRect.SetSize( aSize ); 1906 if( aRect.Left() > 0 ) 1907 aRect.Left()--; 1908 aRect.Right()++; 1909 } 1910 } 1911 else 1912 { 1913 // wenn erster SelTab != 0, dann muessen wir auch rechnen 1914 if( nFocusWidth == -1 || nFirstSelTab ) 1915 { 1916 sal_uInt16 nLastTab; 1917 SvLBoxTab* pLastTab = GetLastTab(SV_LBOXTAB_SHOW_SELECTION,nLastTab); 1918 nLastTab++; 1919 if( nLastTab < aTabs.Count() ) // gibts noch einen ? 1920 pLastTab = (SvLBoxTab*)aTabs.GetObject( nLastTab ); 1921 else 1922 pLastTab = 0; // ueber gesamte Breite selektieren 1923 aSize.Width() = pLastTab ? pLastTab->GetPos() : 0x0fffffff; 1924 nFocusWidth = (short)aSize.Width(); 1925 if( pTab ) 1926 nFocusWidth = nFocusWidth - (short)nTabPos; //pTab->GetPos(); 1927 } 1928 else 1929 { 1930 aSize.Width() = nFocusWidth; 1931 if( pTab ) 1932 { 1933 if( nCurTab ) 1934 aSize.Width() += nTabPos; 1935 else 1936 aSize.Width() += pTab->GetPos(); // Tab0 immer ab ganz links 1937 } 1938 } 1939 // wenn Sel. beim nullten Tab anfaengt, dann ab Spalte 0 sel. zeichnen 1940 if( nCurTab != 0 ) 1941 { 1942 aRect.Left() = nTabPos; 1943 aSize.Width() -= nTabPos; 1944 } 1945 aRect.SetSize( aSize ); 1946 } 1947 // rechten Rand anpassen wg. Clipping 1948 if( aRect.Right() >= nRealWidth ) 1949 { 1950 aRect.Right() = nRealWidth-1; 1951 nFocusWidth = (short)aRect.GetWidth(); 1952 } 1953 return aRect; 1954 } 1955 1956 1957 long SvTreeListBox::GetTabPos( SvLBoxEntry* pEntry, SvLBoxTab* pTab) 1958 { 1959 DBG_CHKTHIS(SvTreeListBox,0); 1960 DBG_ASSERT(pTab,"No Tab"); 1961 long nPos = pTab->GetPos(); 1962 if( pTab->IsDynamic() ) 1963 { 1964 sal_uInt16 nDepth = pModel->GetDepth( pEntry ); 1965 nDepth = nDepth * (sal_uInt16)nIndent; 1966 nPos += (long)nDepth; 1967 } 1968 return nPos; 1969 } 1970 1971 SvLBoxItem* SvTreeListBox::GetItem_Impl( SvLBoxEntry* pEntry, long nX, 1972 SvLBoxTab** ppTab, sal_uInt16 nEmptyWidth ) 1973 { 1974 DBG_CHKTHIS(SvTreeListBox,0); 1975 SvLBoxItem* pItemClicked = 0; 1976 sal_uInt16 nTabCount = aTabs.Count(); 1977 sal_uInt16 nItemCount = pEntry->ItemCount(); 1978 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0); 1979 SvLBoxItem* pItem = pEntry->GetItem(0); 1980 sal_uInt16 nNextItem = 1; 1981 nX -= GetMapMode().GetOrigin().X(); 1982 long nRealWidth = pImp->GetOutputSize().Width(); 1983 nRealWidth -= GetMapMode().GetOrigin().X(); 1984 1985 while( 1 ) 1986 { 1987 SvLBoxTab* pNextTab=nNextItem<nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextItem) : 0; 1988 long nStart = GetTabPos( pEntry, pTab ); 1989 1990 long nNextTabPos; 1991 if( pNextTab ) 1992 nNextTabPos = GetTabPos( pEntry, pNextTab ); 1993 else 1994 { 1995 nNextTabPos = nRealWidth; 1996 if( nStart > nRealWidth ) 1997 nNextTabPos += 50; 1998 } 1999 2000 Size aItemSize( pItem->GetSize(this, pEntry)); 2001 nStart += pTab->CalcOffset( aItemSize.Width(), nNextTabPos - nStart ); 2002 long nLen = aItemSize.Width(); 2003 if( pNextTab ) 2004 { 2005 long nTabWidth = GetTabPos( pEntry, pNextTab ) - nStart; 2006 if( nTabWidth < nLen ) 2007 nLen = nTabWidth; 2008 } 2009 2010 if( !nLen ) 2011 nLen = nEmptyWidth; 2012 2013 if( nX >= nStart && nX < (nStart+nLen ) ) 2014 { 2015 pItemClicked = pItem; 2016 if( ppTab ) 2017 { 2018 *ppTab = pTab; 2019 break; 2020 } 2021 } 2022 if( nNextItem >= nItemCount || nNextItem >= nTabCount) 2023 break; 2024 pTab = (SvLBoxTab*)aTabs.GetObject( nNextItem ); 2025 pItem = pEntry->GetItem( nNextItem ); 2026 nNextItem++; 2027 } 2028 return pItemClicked; 2029 } 2030 2031 SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX,SvLBoxTab** ppTab) 2032 { 2033 return GetItem_Impl( pEntry, nX, ppTab, 0 ); 2034 } 2035 2036 SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX ) 2037 { 2038 DBG_CHKTHIS(SvTreeListBox,0); 2039 SvLBoxTab* pDummyTab; 2040 return GetItem_Impl( pEntry, nX, &pDummyTab, 0 ); 2041 } 2042 2043 SvLBoxItem* SvTreeListBox::GetFirstDynamicItem( SvLBoxEntry* pEntry ) 2044 { 2045 DBG_CHKTHIS(SvTreeListBox,0); 2046 2047 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0); 2048 SvLBoxItem* pItem = pEntry->GetItem(0); 2049 sal_uInt16 nTabCount = aTabs.Count(); 2050 2051 sal_uInt16 nNext = 1; 2052 while ( !pTab->IsDynamic() && nNext < nTabCount ) 2053 { 2054 pItem = pEntry->GetItem( nNext ); 2055 pTab = (SvLBoxTab*)aTabs.GetObject( nNext ); 2056 nNext++; 2057 } 2058 return pItem; 2059 } 2060 2061 void SvTreeListBox::AddTab(long nTabPos,sal_uInt16 nFlags,void* pUserData ) 2062 { 2063 DBG_CHKTHIS(SvTreeListBox,0); 2064 nFocusWidth = -1; 2065 SvLBoxTab* pTab = new SvLBoxTab( nTabPos, nFlags ); 2066 pTab->SetUserData( pUserData ); 2067 aTabs.Insert( pTab, aTabs.Count() ); 2068 if( nTreeFlags & TREEFLAG_USESEL ) 2069 { 2070 sal_uInt16 nPos = aTabs.Count() - 1; 2071 if( nPos >= nFirstSelTab && nPos <= nLastSelTab ) 2072 pTab->nFlags |= SV_LBOXTAB_SHOW_SELECTION; 2073 else 2074 // String-Items werden normalerweise immer selektiert 2075 // deshalb explizit ausschalten 2076 pTab->nFlags &= ~SV_LBOXTAB_SHOW_SELECTION; 2077 } 2078 } 2079 2080 2081 2082 SvLBoxTab* SvTreeListBox::GetFirstDynamicTab( sal_uInt16& rPos ) const 2083 { 2084 DBG_CHKTHIS(SvTreeListBox,0); 2085 sal_uInt16 nCurTab = 0; 2086 sal_uInt16 nTabCount = aTabs.Count(); 2087 while( nCurTab < nTabCount ) 2088 { 2089 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(nCurTab); 2090 if( pTab->nFlags & SV_LBOXTAB_DYNAMIC ) 2091 { 2092 rPos = nCurTab; 2093 return pTab; 2094 } 2095 nCurTab++; 2096 } 2097 return 0; 2098 } 2099 2100 SvLBoxTab* SvTreeListBox::GetFirstDynamicTab() const 2101 { 2102 sal_uInt16 nDummy; 2103 return GetFirstDynamicTab( nDummy ); 2104 } 2105 2106 SvLBoxTab* SvTreeListBox::GetTab( SvLBoxEntry* pEntry, SvLBoxItem* pItem) const 2107 { 2108 DBG_CHKTHIS(SvTreeListBox,0); 2109 sal_uInt16 nPos = pEntry->GetPos( pItem ); 2110 return (SvLBoxTab*)aTabs.GetObject( nPos ); 2111 } 2112 2113 void SvTreeListBox::ClearTabList() 2114 { 2115 DBG_CHKTHIS(SvTreeListBox,0); 2116 sal_uInt16 nTabCount = aTabs.Count(); 2117 while( nTabCount ) 2118 { 2119 nTabCount--; 2120 SvLBoxTab* pDelTab = (SvLBoxTab*)aTabs.GetObject( nTabCount ); 2121 delete pDelTab; 2122 } 2123 aTabs.Remove(0,aTabs.Count()); 2124 } 2125 2126 2127 Size SvTreeListBox::GetOutputSizePixel() const 2128 { 2129 DBG_CHKTHIS(SvTreeListBox,0); 2130 Size aSize = pImp->GetOutputSize(); 2131 return aSize; 2132 } 2133 2134 void SvTreeListBox::NotifyBeginScroll() 2135 { 2136 DBG_CHKTHIS(SvTreeListBox,0); 2137 } 2138 2139 void SvTreeListBox::NotifyEndScroll() 2140 { 2141 DBG_CHKTHIS(SvTreeListBox,0); 2142 } 2143 2144 void SvTreeListBox::NotifyScrolling( long ) 2145 { 2146 DBG_CHKTHIS(SvTreeListBox,0); 2147 } 2148 2149 void SvTreeListBox::NotifyScrolled() 2150 { 2151 DBG_CHKTHIS(SvTreeListBox,0); 2152 aScrolledHdl.Call( this ); 2153 } 2154 2155 void SvTreeListBox::NotifyInvalidating() 2156 { 2157 DBG_CHKTHIS(SvTreeListBox,0); 2158 } 2159 2160 void SvTreeListBox::Invalidate( sal_uInt16 nInvalidateFlags ) 2161 { 2162 DBG_CHKTHIS(SvTreeListBox,0); 2163 if( nFocusWidth == -1 ) 2164 // damit Control nicht nach dem Paint ein falsches FocusRect anzeigt 2165 pImp->RecalcFocusRect(); 2166 NotifyInvalidating(); 2167 SvLBox::Invalidate( nInvalidateFlags ); 2168 pImp->Invalidate(); 2169 } 2170 2171 void SvTreeListBox::Invalidate( const Rectangle& rRect, sal_uInt16 nInvalidateFlags ) 2172 { 2173 DBG_CHKTHIS(SvTreeListBox,0); 2174 if( nFocusWidth == -1 ) 2175 // damit Control nicht nach dem Paint ein falsches FocusRect anzeigt 2176 pImp->RecalcFocusRect(); 2177 NotifyInvalidating(); 2178 SvLBox::Invalidate( rRect, nInvalidateFlags ); 2179 } 2180 2181 2182 void SvTreeListBox::SetHighlightRange( sal_uInt16 nStart, sal_uInt16 nEnd) 2183 { 2184 DBG_CHKTHIS(SvTreeListBox,0); 2185 2186 sal_uInt16 nTemp; 2187 nTreeFlags |= TREEFLAG_USESEL; 2188 if( nStart > nEnd ) 2189 { 2190 nTemp = nStart; 2191 nStart = nEnd; 2192 nEnd = nTemp; 2193 } 2194 // alle Tabs markieren, die im Bereich liegen 2195 nTreeFlags |= TREEFLAG_RECALCTABS; 2196 nFirstSelTab = nStart; 2197 nLastSelTab = nEnd; 2198 pImp->RecalcFocusRect(); 2199 } 2200 2201 void SvTreeListBox::RemoveHighlightRange() 2202 { 2203 DBG_CHKTHIS(SvTreeListBox,0); 2204 nTreeFlags &= (~TREEFLAG_USESEL); 2205 if( IsUpdateMode() ) 2206 Invalidate(); 2207 } 2208 2209 sal_uLong SvTreeListBox::GetAscInsertionPos(SvLBoxEntry*,SvLBoxEntry*) 2210 { 2211 return LIST_APPEND; 2212 } 2213 2214 sal_uLong SvTreeListBox::GetDescInsertionPos(SvLBoxEntry*,SvLBoxEntry*) 2215 { 2216 DBG_CHKTHIS(SvTreeListBox,0); 2217 return LIST_APPEND; 2218 } 2219 2220 Region SvTreeListBox::GetDragRegion() const 2221 { 2222 DBG_CHKTHIS(SvTreeListBox,0); 2223 Rectangle aRect; 2224 SvLBoxEntry* pEntry = GetCurEntry(); 2225 if( pEntry ) 2226 { 2227 Point aPos = GetEntryPosition( pEntry ); 2228 aRect = ((SvTreeListBox*)this)->GetFocusRect( pEntry, aPos.Y() ); 2229 } 2230 Region aRegion( aRect ); 2231 return aRegion; 2232 } 2233 2234 2235 void SvTreeListBox::Command( const CommandEvent& rCEvt ) 2236 { 2237 DBG_CHKTHIS(SvTreeListBox,0); 2238 // FIXME gnumake2 resync to DEV300_m84 2239 pImp->Command( rCEvt ); 2240 } 2241 2242 2243 void SvTreeListBox::RemoveParentKeepChilds( SvLBoxEntry* pParent ) 2244 { 2245 DBG_CHKTHIS(SvTreeListBox,0); 2246 DBG_ASSERT(pParent,"RemoveParentKeepChilds:No Parent"); 2247 SvLBoxEntry* pNewParent = GetParent( pParent ); 2248 if( pParent->HasChilds()) 2249 { 2250 SvLBoxEntry* pChild = FirstChild( pParent ); 2251 while( pChild ) 2252 { 2253 pModel->Move( pChild, pNewParent, LIST_APPEND ); 2254 pChild = FirstChild( pParent ); 2255 } 2256 } 2257 pModel->Remove( pParent ); 2258 } 2259 2260 SvLBoxTab* SvTreeListBox::GetFirstTab( sal_uInt16 nFlagMask, sal_uInt16& rPos ) 2261 { 2262 sal_uInt16 nTabCount = aTabs.Count(); 2263 for( sal_uInt16 nPos = 0; nPos < nTabCount; nPos++ ) 2264 { 2265 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nPos ); 2266 if( (pTab->nFlags & nFlagMask) ) 2267 { 2268 rPos = nPos; 2269 return pTab; 2270 } 2271 } 2272 rPos = 0xffff; 2273 return 0; 2274 } 2275 2276 SvLBoxTab* SvTreeListBox::GetLastTab( sal_uInt16 nFlagMask, sal_uInt16& rTabPos ) 2277 { 2278 short nTabCount = (short)aTabs.Count(); 2279 if( nTabCount ) 2280 { 2281 for( short nPos = nTabCount-1; nPos >= 0; nPos-- ) 2282 { 2283 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( (sal_uInt16)nPos ); 2284 if( (pTab->nFlags & nFlagMask) ) 2285 { 2286 rTabPos = (sal_uInt16)nPos; 2287 return pTab; 2288 } 2289 } 2290 } 2291 rTabPos = 0xffff; 2292 return 0; 2293 } 2294 2295 void SvTreeListBox::SetAddMode( sal_Bool bAdd ) 2296 { 2297 pImp->SetAddMode( bAdd ); 2298 } 2299 2300 sal_Bool SvTreeListBox::IsAddMode() const 2301 { 2302 return pImp->IsAddMode(); 2303 } 2304 2305 void SvTreeListBox::RequestHelp( const HelpEvent& rHEvt ) 2306 { 2307 if( !pImp->RequestHelp( rHEvt ) ) 2308 SvLBox::RequestHelp( rHEvt ); 2309 } 2310 2311 void SvTreeListBox::CursorMoved( SvLBoxEntry* ) 2312 { 2313 } 2314 2315 IMPL_LINK( SvTreeListBox, DefaultCompare, SvSortData*, pData ) 2316 { 2317 SvLBoxEntry* pLeft = (SvLBoxEntry*)(pData->pLeft ); 2318 SvLBoxEntry* pRight = (SvLBoxEntry*)(pData->pRight ); 2319 String aLeft( ((SvLBoxString*)(pLeft->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText()); 2320 String aRight( ((SvLBoxString*)(pRight->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText()); 2321 // #102891# ---------------- 2322 pImp->UpdateIntlWrapper(); 2323 return pImp->pIntlWrapper->getCaseCollator()->compareString( aLeft, aRight ); 2324 } 2325 2326 void SvTreeListBox::ModelNotification( sal_uInt16 nActionId, SvListEntry* pEntry1, 2327 SvListEntry* pEntry2, sal_uLong nPos ) 2328 { 2329 if( nActionId == LISTACTION_CLEARING ) 2330 CancelTextEditing(); 2331 2332 SvLBox::ModelNotification( nActionId, pEntry1, pEntry2, nPos ); 2333 switch( nActionId ) 2334 { 2335 case LISTACTION_INSERTED: 2336 { 2337 SvLBoxEntry* pEntry( dynamic_cast< SvLBoxEntry* >( pEntry1 ) ); 2338 ENSURE_OR_BREAK( pEntry, "SvTreeListBox::ModelNotification: invalid entry!" ); 2339 SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) ); 2340 if ( !pBmpItem ) 2341 break; 2342 const Image& rBitmap1( pBmpItem->GetBitmap1() ); 2343 const Image& rBitmap2( pBmpItem->GetBitmap2() ); 2344 short nMaxWidth = short( Max( rBitmap1.GetSizePixel().Width(), rBitmap2.GetSizePixel().Width() ) ); 2345 nMaxWidth = pImp->UpdateContextBmpWidthVector( pEntry, nMaxWidth ); 2346 if( nMaxWidth > nContextBmpWidthMax ) 2347 { 2348 nContextBmpWidthMax = nMaxWidth; 2349 SetTabs(); 2350 } 2351 } 2352 break; 2353 2354 case LISTACTION_RESORTING: 2355 SetUpdateMode( sal_False ); 2356 break; 2357 2358 case LISTACTION_RESORTED: 2359 // nach Sortierung den ersten Eintrag anzeigen, dabei die 2360 // Selektion erhalten. 2361 MakeVisible( (SvLBoxEntry*)pModel->First(), sal_True ); 2362 SetUpdateMode( sal_True ); 2363 break; 2364 2365 case LISTACTION_CLEARED: 2366 if( IsUpdateMode() ) 2367 Update(); 2368 break; 2369 } 2370 } 2371 2372 // bei Aenderungen SetTabs beruecksichtigen 2373 long SvTreeListBox::GetTextOffset() const 2374 { 2375 DBG_CHKTHIS(SvTreeListBox,0); 2376 const WinBits nWindowStyle = GetStyle(); 2377 sal_Bool bHasButtons = (nWindowStyle & WB_HASBUTTONS)!=0; 2378 sal_Bool bHasButtonsAtRoot = (nWindowStyle & (WB_HASLINESATROOT | 2379 WB_HASBUTTONSATROOT))!=0; 2380 long nStartPos = TAB_STARTPOS; 2381 long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width(); 2382 2383 long nCheckWidth = 0; 2384 if( nTreeFlags & TREEFLAG_CHKBTN ) 2385 nCheckWidth = pCheckButtonData->aBmps[0].GetSizePixel().Width(); 2386 long nCheckWidthDIV2 = nCheckWidth / 2; 2387 2388 long nContextWidth = nContextBmpWidthMax; 2389 long nContextWidthDIV2 = nContextWidth / 2; 2390 2391 int nCase = NO_BUTTONS; 2392 if( !(nTreeFlags & TREEFLAG_CHKBTN) ) 2393 { 2394 if( bHasButtons ) 2395 nCase = NODE_BUTTONS; 2396 } 2397 else 2398 { 2399 if( bHasButtons ) 2400 nCase = NODE_AND_CHECK_BUTTONS; 2401 else 2402 nCase = CHECK_BUTTONS; 2403 } 2404 2405 switch( nCase ) 2406 { 2407 case NO_BUTTONS : 2408 nStartPos += nContextWidthDIV2; // wg. Zentrierung 2409 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 2410 if( nContextBmpWidthMax ) 2411 nStartPos += 5; // Abstand Context-Bmp - Text 2412 break; 2413 2414 case NODE_BUTTONS : 2415 if( bHasButtonsAtRoot ) 2416 nStartPos += ( nIndent + (nNodeWidthPixel/2) ); 2417 else 2418 nStartPos += nContextWidthDIV2; 2419 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 2420 if( nContextBmpWidthMax ) 2421 nStartPos += 5; // Abstand Context-Bmp - Text 2422 break; 2423 2424 case NODE_AND_CHECK_BUTTONS : 2425 if( bHasButtonsAtRoot ) 2426 nStartPos += ( nIndent + nNodeWidthPixel ); 2427 else 2428 nStartPos += nCheckWidthDIV2; 2429 nStartPos += nCheckWidthDIV2; // rechter Rand des CheckButtons 2430 nStartPos += 3; // Abstand CheckButton Context-Bmp 2431 nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp 2432 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 2433 // Abstand setzen nur wenn Bitmaps da 2434 if( nContextBmpWidthMax ) 2435 nStartPos += 5; // Abstand Context-Bmp - Text 2436 break; 2437 2438 case CHECK_BUTTONS : 2439 nStartPos += nCheckWidthDIV2; 2440 nStartPos += nCheckWidthDIV2; // rechter Rand CheckButton 2441 nStartPos += 3; // Abstand CheckButton Context-Bmp 2442 nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp 2443 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 2444 if( nContextBmpWidthMax ) 2445 nStartPos += 5; // Abstand Context-Bmp - Text 2446 break; 2447 } 2448 return nStartPos; 2449 } 2450 2451 void SvTreeListBox::EndSelection() 2452 { 2453 pImp->EndSelection(); 2454 } 2455 2456 sal_Bool SvTreeListBox::IsNodeButton( const Point& rPos ) const 2457 { 2458 SvLBoxEntry* pEntry = GetEntry( rPos ); 2459 if( pEntry ) 2460 return pImp->IsNodeButton( rPos, pEntry ); 2461 return sal_False; 2462 } 2463 2464 void SvTreeListBox::RepaintScrollBars() const 2465 { 2466 ((SvTreeListBox*)this)->pImp->RepaintScrollBars(); 2467 } 2468 2469 ScrollBar *SvTreeListBox::GetVScroll() 2470 { 2471 return &((SvTreeListBox*)this)->pImp->aVerSBar; 2472 } 2473 2474 ScrollBar *SvTreeListBox::GetHScroll() 2475 { 2476 return &((SvTreeListBox*)this)->pImp->aHorSBar; 2477 } 2478 2479 void SvTreeListBox::EnableAsyncDrag( sal_Bool b ) 2480 { 2481 pImp->EnableAsyncDrag( b ); 2482 } 2483 2484 SvLBoxEntry* SvTreeListBox::GetFirstEntryInView() const 2485 { 2486 Point aPos; 2487 return GetEntry( aPos ); 2488 } 2489 2490 SvLBoxEntry* SvTreeListBox::GetNextEntryInView(SvLBoxEntry* pEntry ) const 2491 { 2492 SvLBoxEntry* pNext = (SvLBoxEntry*)NextVisible( pEntry ); 2493 if( pNext ) 2494 { 2495 Point aPos( GetEntryPosition(pNext) ); 2496 const Size& rSize = pImp->GetOutputSize(); 2497 if( aPos.Y() < 0 || aPos.Y() >= rSize.Height() ) 2498 return 0; 2499 } 2500 return pNext; 2501 } 2502 2503 void SvTreeListBox::ShowFocusRect( const SvLBoxEntry* pEntry ) 2504 { 2505 pImp->ShowFocusRect( pEntry ); 2506 } 2507 2508 void SvTreeListBox::SetTabBar( TabBar* pTabBar ) 2509 { 2510 pImp->SetTabBar( pTabBar ); 2511 } 2512 2513 void SvTreeListBox::DataChanged( const DataChangedEvent& rDCEvt ) 2514 { 2515 if( (rDCEvt.GetType()==DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 2516 { 2517 nEntryHeight = 0; // _together_ with sal_True of 1. par (bFont) of InitSettings() a zero-height 2518 // forces complete recalc of heights! 2519 InitSettings( sal_True, sal_True, sal_True ); 2520 Invalidate(); 2521 } 2522 else 2523 Control::DataChanged( rDCEvt ); 2524 } 2525 2526 void SvTreeListBox::StateChanged( StateChangedType i_nStateChange ) 2527 { 2528 SvLBox::StateChanged( i_nStateChange ); 2529 if ( i_nStateChange == STATE_CHANGE_STYLE ) 2530 ImplInitStyle(); 2531 } 2532 2533 void SvTreeListBox::InitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground) 2534 { 2535 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 2536 if( bFont ) 2537 { 2538 Font aFont; 2539 aFont = rStyleSettings.GetFieldFont(); 2540 aFont.SetColor( rStyleSettings.GetWindowTextColor() ); 2541 SetPointFont( aFont ); 2542 AdjustEntryHeight( aFont ); 2543 RecalcViewData(); 2544 } 2545 2546 if( bForeground || bFont ) 2547 { 2548 SetTextColor( rStyleSettings.GetFieldTextColor() ); 2549 SetTextFillColor(); 2550 } 2551 2552 if( bBackground ) 2553 SetBackground( rStyleSettings.GetFieldColor() ); 2554 2555 // always try to re-create default-SvLBoxButtonData 2556 if( pCheckButtonData && pCheckButtonData->HasDefaultImages() ) 2557 pCheckButtonData->SetDefaultImages( this ); 2558 } 2559 2560 sal_Bool SvTreeListBox::IsCellFocusEnabled() const 2561 { 2562 return pImp->IsCellFocusEnabled(); 2563 } 2564 2565 bool SvTreeListBox::SetCurrentTabPos( sal_uInt16 _nNewPos ) 2566 { 2567 return pImp->SetCurrentTabPos( _nNewPos ); 2568 } 2569 2570 sal_uInt16 SvTreeListBox::GetCurrentTabPos() const 2571 { 2572 return pImp->GetCurrentTabPos(); 2573 } 2574 2575 void SvTreeListBox::InitStartEntry() 2576 { 2577 if( !pImp->pStartEntry ) 2578 pImp->pStartEntry = GetModel()->First(); 2579 } 2580 2581 void SvTreeListBox::CancelPendingEdit() 2582 { 2583 if( pImp ) 2584 pImp->CancelPendingEdit(); 2585 } 2586 2587 PopupMenu* SvTreeListBox::CreateContextMenu( void ) 2588 { 2589 return NULL; 2590 } 2591 2592 void SvTreeListBox::ExcecuteContextMenuAction( sal_uInt16 ) 2593 { 2594 DBG_WARNING( "SvTreeListBox::ExcecuteContextMenuAction(): now there's happening nothing!" ); 2595 } 2596 2597 void SvTreeListBox::EnableContextMenuHandling( void ) 2598 { 2599 DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" ); 2600 2601 pImp->bContextMenuHandling = sal_True; 2602 } 2603 2604 void SvTreeListBox::EnableContextMenuHandling( sal_Bool b ) 2605 { 2606 DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" ); 2607 2608 pImp->bContextMenuHandling = b; 2609 } 2610 2611 sal_Bool SvTreeListBox::IsContextMenuHandlingEnabled( void ) const 2612 { 2613 DBG_ASSERT( pImp, "-SvTreeListBox::IsContextMenuHandlingEnabled(): No implementation!" ); 2614 2615 return pImp->bContextMenuHandling; 2616 } 2617 2618 void SvTreeListBox::EnableList( bool _bEnable ) 2619 { 2620 // call base class method 2621 Window::Enable( _bEnable != false ); 2622 // then paint immediately 2623 Paint( Rectangle( Point(), GetSizePixel() ) ); 2624 } 2625 2626 ::com::sun::star::uno::Reference< XAccessible > SvTreeListBox::CreateAccessible() 2627 { 2628 Window* pParent = GetAccessibleParentWindow(); 2629 DBG_ASSERT( pParent, "SvTreeListBox::CreateAccessible - accessible parent not found" ); 2630 2631 ::com::sun::star::uno::Reference< XAccessible > xAccessible; 2632 if ( pParent ) 2633 { 2634 ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible(); 2635 if ( xAccParent.is() ) 2636 { 2637 // need to be done here to get the vclxwindow later on in the accessbile 2638 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xTemp(GetComponentInterface()); 2639 xAccessible = pImp->m_aFactoryAccess.getFactory().createAccessibleTreeListBox( *this, xAccParent ); 2640 } 2641 } 2642 return xAccessible; 2643 } 2644 2645 void SvTreeListBox::FillAccessibleEntryStateSet( SvLBoxEntry* pEntry, ::utl::AccessibleStateSetHelper& rStateSet ) const 2646 { 2647 DBG_ASSERT( pEntry, "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry" ); 2648 2649 if ( pEntry->HasChildsOnDemand() || pEntry->HasChilds() ) 2650 { 2651 rStateSet.AddState( AccessibleStateType::EXPANDABLE ); 2652 if ( IsExpanded( pEntry ) ) 2653 rStateSet.AddState( (sal_Int16)AccessibleStateType::EXPANDED ); 2654 } 2655 2656 if ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) 2657 rStateSet.AddState( AccessibleStateType::CHECKED ); 2658 if ( IsEntryVisible( pEntry ) ) 2659 rStateSet.AddState( AccessibleStateType::VISIBLE ); 2660 if ( IsSelected( pEntry ) ) 2661 rStateSet.AddState( AccessibleStateType::SELECTED ); 2662 } 2663 2664 Rectangle SvTreeListBox::GetBoundingRect( SvLBoxEntry* pEntry ) 2665 { 2666 Point aPos = GetEntryPosition( pEntry ); 2667 Rectangle aRect = GetFocusRect( pEntry, aPos.Y() ); 2668 return aRect; 2669 } 2670 2671 void SvTreeListBox::EnableCellFocus() 2672 { 2673 pImp->EnableCellFocus(); 2674 } 2675 2676 void SvTreeListBox::CallImplEventListeners(sal_uLong nEvent, void* pData) 2677 { 2678 CallEventListeners(nEvent, pData); 2679 } 2680 2681 void SvTreeListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& rStateSet ) const 2682 { 2683 SvLBox::FillAccessibleStateSet( rStateSet ); 2684 } 2685