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