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 #ifdef OS2 1512 nWindowStyle |= WB_VSCROLL; 1513 #endif 1514 pImp->SetStyle( nWindowStyle ); 1515 pImp->Resize(); 1516 Invalidate(); 1517 } 1518 1519 void SvTreeListBox::PaintEntry( SvLBoxEntry* pEntry ) 1520 { 1521 DBG_CHKTHIS(SvTreeListBox,0); 1522 DBG_ASSERT(pEntry,"PaintEntry:No Entry"); 1523 if( pEntry ) 1524 pImp->PaintEntry( pEntry ); 1525 } 1526 1527 void SvTreeListBox::InvalidateEntry( SvLBoxEntry* pEntry ) 1528 { 1529 DBG_CHKTHIS(SvTreeListBox,0); 1530 DBG_ASSERT(pEntry,"InvalidateEntry:No Entry"); 1531 if( pEntry ) 1532 { 1533 GetModel()->InvalidateEntry( pEntry ); 1534 // pImp->InvalidateEntry( pEntry ); 1535 } 1536 } 1537 1538 1539 long SvTreeListBox::PaintEntry(SvLBoxEntry* pEntry,long nLine,sal_uInt16 nTabFlags) 1540 { 1541 return PaintEntry1(pEntry,nLine,nTabFlags); 1542 } 1543 1544 #define SV_TAB_BORDER 8 1545 1546 long SvTreeListBox::PaintEntry1(SvLBoxEntry* pEntry,long nLine,sal_uInt16 nTabFlags, 1547 sal_Bool bHasClipRegion ) 1548 { 1549 DBG_CHKTHIS(SvTreeListBox,0); 1550 1551 Rectangle aRect; // multi purpose 1552 1553 sal_Bool bHorSBar = pImp->HasHorScrollBar(); 1554 PreparePaint( pEntry ); 1555 1556 // #97680# ------------------ 1557 pImp->UpdateContextBmpWidthMax( pEntry ); 1558 1559 if( nTreeFlags & TREEFLAG_RECALCTABS ) 1560 SetTabs(); 1561 1562 short nTempEntryHeight = GetEntryHeight(); 1563 long nWidth = pImp->GetOutputSize().Width(); 1564 1565 // wurde innerhalb des PreparePaints die horizontale ScrollBar 1566 // angeschaltet? Wenn ja, muss die ClipRegion neu gesetzt werden 1567 if( !bHorSBar && pImp->HasHorScrollBar() ) 1568 SetClipRegion( Region(pImp->GetClipRegionRect()) ); 1569 1570 Point aEntryPos( GetMapMode().GetOrigin() ); 1571 aEntryPos.X() *= -1; // Umrechnung Dokumentkoord. 1572 long nMaxRight = nWidth + aEntryPos.X() - 1; 1573 1574 Color aBackupTextColor( GetTextColor() ); 1575 Font aBackupFont( GetFont() ); 1576 Color aBackupColor = GetFillColor(); 1577 1578 bool bCurFontIsSel = false; 1579 sal_Bool bInUse = pEntry->HasInUseEmphasis(); 1580 // wenn eine ClipRegion von aussen gesetzt wird, dann 1581 // diese nicht zuruecksetzen 1582 const WinBits nWindowStyle = GetStyle(); 1583 const sal_Bool bResetClipRegion = !bHasClipRegion; 1584 const sal_Bool bHideSelection = ((nWindowStyle & WB_HIDESELECTION) && !HasFocus())!=0; 1585 const StyleSettings& rSettings = GetSettings().GetStyleSettings(); 1586 1587 Font aHighlightFont( GetFont() ); 1588 const Color aHighlightTextColor( rSettings.GetHighlightTextColor() ); 1589 aHighlightFont.SetColor( aHighlightTextColor ); 1590 1591 Size aRectSize( 0, nTempEntryHeight ); 1592 1593 if( !bHasClipRegion && nWindowStyle & WB_HSCROLL ) 1594 { 1595 SetClipRegion( Region(pImp->GetClipRegionRect()) ); 1596 bHasClipRegion = sal_True; 1597 } 1598 1599 SvViewDataEntry* pViewDataEntry = GetViewDataEntry( pEntry ); 1600 1601 sal_uInt16 nTabCount = aTabs.Count(); 1602 sal_uInt16 nItemCount = pEntry->ItemCount(); 1603 sal_uInt16 nCurTab = 0; 1604 sal_uInt16 nCurItem = 0; 1605 1606 while( nCurTab < nTabCount && nCurItem < nItemCount ) 1607 { 1608 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nCurTab ); 1609 sal_uInt16 nNextTab = nCurTab + 1; 1610 SvLBoxTab* pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0; 1611 SvLBoxItem* pItem = nCurItem < nItemCount ? pEntry->GetItem(nCurItem) : 0; 1612 1613 sal_uInt16 nFlags = pTab->nFlags; 1614 Size aSize( pItem->GetSize( pViewDataEntry, nCurItem )); 1615 long nTabPos = GetTabPos( pEntry, pTab ); 1616 1617 long nNextTabPos; 1618 if( pNextTab ) 1619 nNextTabPos = GetTabPos( pEntry, pNextTab ); 1620 else 1621 { 1622 nNextTabPos = nMaxRight; 1623 if( nTabPos > nMaxRight ) 1624 nNextTabPos += 50; 1625 } 1626 1627 long nX; 1628 if( pTab->nFlags & SV_LBOXTAB_ADJUST_RIGHT ) 1629 //verhindern, das rechter Rand von der Tabtrennung abgeschnitten wird 1630 nX = nTabPos + pTab->CalcOffset(aSize.Width(), (nNextTabPos-SV_TAB_BORDER-1) -nTabPos); 1631 else 1632 nX = nTabPos + pTab->CalcOffset(aSize.Width(), nNextTabPos-nTabPos); 1633 1634 if( nFlags & nTabFlags ) 1635 { 1636 if( !bHasClipRegion && nX + aSize.Width() >= nMaxRight ) 1637 { 1638 SetClipRegion( Region(pImp->GetClipRegionRect()) ); 1639 bHasClipRegion = sal_True; 1640 } 1641 aEntryPos.X() = nX; 1642 aEntryPos.Y() = nLine; 1643 1644 // Hintergrund-Muster & Farbe bestimmen 1645 1646 Wallpaper aWallpaper = GetBackground(); 1647 1648 int bSelTab = nFlags & SV_LBOXTAB_SHOW_SELECTION; 1649 sal_uInt16 nItemType = pItem->IsA(); 1650 1651 if ( pViewDataEntry->IsSelected() && bSelTab && !pViewDataEntry->IsCursored() ) 1652 { 1653 Color aNewWallColor = rSettings.GetHighlightColor(); 1654 if ( !bInUse || nItemType != SV_ITEM_ID_LBOXCONTEXTBMP ) 1655 { 1656 // if the face color is bright then the deactive color is also bright 1657 // -> so you can't see any deactive selection 1658 if ( bHideSelection && !rSettings.GetFaceColor().IsBright() && 1659 aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright() ) 1660 aNewWallColor = rSettings.GetDeactiveColor(); 1661 // set font color to highlight 1662 if ( !bCurFontIsSel ) 1663 { 1664 SetTextColor( aHighlightTextColor ); 1665 SetFont( aHighlightFont ); 1666 bCurFontIsSel = true; 1667 } 1668 } 1669 aWallpaper.SetColor( aNewWallColor ); 1670 } 1671 else // keine Selektion 1672 { 1673 if( bInUse && nItemType == SV_ITEM_ID_LBOXCONTEXTBMP ) 1674 aWallpaper.SetColor( rSettings.GetFieldColor() ); 1675 else if( bCurFontIsSel ) 1676 { 1677 bCurFontIsSel = false; 1678 SetTextColor( aBackupTextColor ); 1679 SetFont( aBackupFont ); 1680 } 1681 } 1682 1683 // Hintergrund zeichnen 1684 if( !(nTreeFlags & TREEFLAG_USESEL)) 1685 { 1686 // nur den Bereich zeichnen, den das Item einnimmt 1687 aRectSize.Width() = aSize.Width(); 1688 aRect.SetPos( aEntryPos ); 1689 aRect.SetSize( aRectSize ); 1690 } 1691 else 1692 { 1693 // vom aktuellen bis zum naechsten Tab zeichnen 1694 if( nCurTab != 0 ) 1695 aRect.Left() = nTabPos; 1696 else 1697 // beim nullten Tab immer ab Spalte 0 zeichnen 1698 // (sonst Probleme bei Tabs mit Zentrierung) 1699 aRect.Left() = 0; 1700 aRect.Top() = nLine; 1701 aRect.Bottom() = nLine + nTempEntryHeight - 1; 1702 if( pNextTab ) 1703 { 1704 long nRight; 1705 nRight = GetTabPos(pEntry,pNextTab)-1; 1706 if( nRight > nMaxRight ) 1707 nRight = nMaxRight; 1708 aRect.Right() = nRight; 1709 } 1710 else 1711 aRect.Right() = nMaxRight; 1712 } 1713 // bei anwenderdefinierter Selektion, die bei einer Tabposition 1714 // groesser 0 beginnt den Hintergrund des 0.ten Items nicht 1715 // fuellen, da sonst z.B. TablistBoxen mit Linien nicht 1716 // realisiert werden koennen. 1717 if( !(nCurTab==0 && (nTreeFlags & TREEFLAG_USESEL) && nFirstSelTab) ) 1718 { 1719 SetFillColor( aWallpaper.GetColor() ); 1720 // Bei kleinen hor. Resizes tritt dieser Fall auf 1721 if( aRect.Left() < aRect.Right() ) 1722 DrawRect( aRect ); 1723 } 1724 // Item zeichnen 1725 // vertikal zentrieren 1726 aEntryPos.Y() += ( nTempEntryHeight - aSize.Height() ) / 2; 1727 pItem->Paint( aEntryPos, *this, pViewDataEntry->GetFlags(), pEntry ); 1728 1729 // Trennungslinie zwischen Tabs 1730 if( pNextTab && pItem->IsA() == SV_ITEM_ID_LBOXSTRING && 1731 // nicht am rechten Fensterrand! 1732 aRect.Right() < nMaxRight ) 1733 { 1734 aRect.Left() = aRect.Right() - SV_TAB_BORDER; 1735 DrawRect( aRect ); 1736 } 1737 1738 SetFillColor( aBackupColor ); 1739 } 1740 nCurItem++; 1741 nCurTab++; 1742 } 1743 if( pViewDataEntry->IsCursored() && !HasFocus() ) 1744 { 1745 // Cursor-Emphasis 1746 SetFillColor(); 1747 Color aOldLineColor = GetLineColor(); 1748 SetLineColor( Color( COL_BLACK ) ); 1749 aRect = GetFocusRect( pEntry, nLine ); 1750 aRect.Top()++; 1751 aRect.Bottom()--; 1752 DrawRect( aRect ); 1753 SetLineColor( aOldLineColor ); 1754 SetFillColor( aBackupColor ); 1755 } 1756 1757 if( bCurFontIsSel ) 1758 { 1759 SetTextColor( aBackupTextColor ); 1760 SetFont( aBackupFont ); 1761 } 1762 1763 sal_uInt16 nFirstDynTabPos; 1764 SvLBoxTab* pFirstDynamicTab = GetFirstDynamicTab( nFirstDynTabPos ); 1765 long nDynTabPos = GetTabPos( pEntry, pFirstDynamicTab ); 1766 nDynTabPos += pImp->nNodeBmpTabDistance; 1767 nDynTabPos += pImp->nNodeBmpWidth / 2; 1768 nDynTabPos += 4; // 4 Pixel Reserve, damit die Node-Bitmap 1769 // nicht zu nah am naechsten Tab steht 1770 1771 if( (!(pEntry->GetFlags() & SV_ENTRYFLAG_NO_NODEBMP)) && 1772 (nWindowStyle & WB_HASBUTTONS) && pFirstDynamicTab && 1773 ( pEntry->HasChilds() || pEntry->HasChildsOnDemand() ) ) 1774 { 1775 // ersten festen Tab suchen, und pruefen ob die Node-Bitmap 1776 // in ihn hineinragt 1777 sal_uInt16 nNextTab = nFirstDynTabPos; 1778 SvLBoxTab* pNextTab; 1779 do 1780 { 1781 nNextTab++; 1782 pNextTab = nNextTab < nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextTab) : 0; 1783 } while( pNextTab && pNextTab->IsDynamic() ); 1784 1785 if( !pNextTab || (GetTabPos( pEntry, pNextTab ) > nDynTabPos) ) 1786 { 1787 if((nWindowStyle & WB_HASBUTTONSATROOT) || pModel->GetDepth(pEntry) > 0) 1788 { 1789 Point aPos( GetTabPos(pEntry,pFirstDynamicTab), nLine ); 1790 aPos.X() += pImp->nNodeBmpTabDistance; 1791 1792 const Image* pImg = 0; 1793 BmpColorMode eBitmapMode = BMP_COLOR_NORMAL; 1794 if ( GetSettings().GetStyleSettings().GetHighContrastMode() ) 1795 eBitmapMode = BMP_COLOR_HIGHCONTRAST; 1796 1797 if( IsExpanded(pEntry) ) 1798 pImg = &pImp->GetExpandedNodeBmp( eBitmapMode ); 1799 else 1800 { 1801 if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() && 1802 (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) && 1803 pImp->GetDontKnowNodeBmp().GetSizePixel().Width() ) 1804 pImg = &pImp->GetDontKnowNodeBmp( eBitmapMode ); 1805 else 1806 pImg = &pImp->GetCollapsedNodeBmp( eBitmapMode ); 1807 } 1808 aPos.Y() += (nTempEntryHeight - pImg->GetSizePixel().Height()) / 2; 1809 1810 sal_uInt16 nStyle = 0; 1811 if ( !IsEnabled() ) 1812 nStyle |= IMAGE_DRAW_DISABLE; 1813 1814 //native 1815 sal_Bool bNativeOK = sal_False; 1816 if ( IsNativeControlSupported( CTRL_LISTNODE, PART_ENTIRE_CONTROL) ) 1817 { 1818 ImplControlValue aControlValue; 1819 Rectangle aCtrlRegion( aPos, pImg->GetSizePixel() ); 1820 ControlState nState = 0; 1821 1822 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED; 1823 1824 if ( IsExpanded(pEntry) ) 1825 aControlValue.setTristateVal( BUTTONVALUE_ON );//expanded node 1826 else 1827 { 1828 if( (!pEntry->HasChilds()) && pEntry->HasChildsOnDemand() && 1829 (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) && 1830 pImp->GetDontKnowNodeBmp().GetSizePixel().Width() ) 1831 aControlValue.setTristateVal( BUTTONVALUE_DONTKNOW );//dont know 1832 else 1833 aControlValue.setTristateVal( BUTTONVALUE_OFF );//collapsed node 1834 } 1835 1836 bNativeOK = DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL, 1837 aCtrlRegion, nState, aControlValue, rtl::OUString() ); 1838 } 1839 1840 if( !bNativeOK) { 1841 //non native 1842 DrawImage( aPos, *pImg ,nStyle); 1843 } 1844 } 1845 } 1846 } 1847 1848 1849 if( bHasClipRegion && bResetClipRegion ) 1850 SetClipRegion(); 1851 return 0; // nRowLen; 1852 } 1853 1854 void SvTreeListBox::PreparePaint( SvLBoxEntry* ) 1855 { 1856 } 1857 1858 Rectangle SvTreeListBox::GetFocusRect( SvLBoxEntry* pEntry, long nLine ) 1859 { 1860 DBG_CHKTHIS(SvTreeListBox,0); 1861 Size aSize; 1862 Rectangle aRect; 1863 aRect.Top() = nLine; 1864 aSize.Height() = GetEntryHeight(); 1865 1866 long nRealWidth = pImp->GetOutputSize().Width(); 1867 nRealWidth -= GetMapMode().GetOrigin().X(); 1868 1869 sal_uInt16 nCurTab; 1870 SvLBoxTab* pTab = GetFirstTab( SV_LBOXTAB_SHOW_SELECTION, nCurTab ); 1871 long nTabPos = 0; 1872 if( pTab ) 1873 nTabPos = GetTabPos( pEntry, pTab ); 1874 long nNextTabPos; 1875 if( pTab && nCurTab < aTabs.Count() - 1 ) 1876 { 1877 SvLBoxTab* pNextTab = (SvLBoxTab*)aTabs.GetObject( nCurTab + 1 ); 1878 nNextTabPos = GetTabPos( pEntry, pNextTab ); 1879 } 1880 else 1881 { 1882 nNextTabPos = nRealWidth; 1883 if( nTabPos > nRealWidth ) 1884 nNextTabPos += 50; 1885 } 1886 1887 sal_Bool bUserSelection = (sal_Bool)( nTreeFlags & TREEFLAG_USESEL ) != 0; 1888 if( !bUserSelection ) 1889 { 1890 if( pTab && nCurTab < pEntry->ItemCount() ) 1891 { 1892 SvLBoxItem* pItem = pEntry->GetItem( nCurTab ); 1893 aSize.Width() = pItem->GetSize( this, pEntry ).Width(); 1894 if( !aSize.Width() ) 1895 aSize.Width() = 15; 1896 long nX = nTabPos; //GetTabPos( pEntry, pTab ); 1897 // Ausrichtung 1898 nX += pTab->CalcOffset( aSize.Width(), nNextTabPos - nTabPos ); 1899 aRect.Left() = nX; 1900 // damit erster & letzter Buchstabe nicht angeknabbert werden 1901 aRect.SetSize( aSize ); 1902 if( aRect.Left() > 0 ) 1903 aRect.Left()--; 1904 aRect.Right()++; 1905 } 1906 } 1907 else 1908 { 1909 // wenn erster SelTab != 0, dann muessen wir auch rechnen 1910 if( nFocusWidth == -1 || nFirstSelTab ) 1911 { 1912 sal_uInt16 nLastTab; 1913 SvLBoxTab* pLastTab = GetLastTab(SV_LBOXTAB_SHOW_SELECTION,nLastTab); 1914 nLastTab++; 1915 if( nLastTab < aTabs.Count() ) // gibts noch einen ? 1916 pLastTab = (SvLBoxTab*)aTabs.GetObject( nLastTab ); 1917 else 1918 pLastTab = 0; // ueber gesamte Breite selektieren 1919 aSize.Width() = pLastTab ? pLastTab->GetPos() : 0x0fffffff; 1920 nFocusWidth = (short)aSize.Width(); 1921 if( pTab ) 1922 nFocusWidth = nFocusWidth - (short)nTabPos; //pTab->GetPos(); 1923 } 1924 else 1925 { 1926 aSize.Width() = nFocusWidth; 1927 if( pTab ) 1928 { 1929 if( nCurTab ) 1930 aSize.Width() += nTabPos; 1931 else 1932 aSize.Width() += pTab->GetPos(); // Tab0 immer ab ganz links 1933 } 1934 } 1935 // wenn Sel. beim nullten Tab anfaengt, dann ab Spalte 0 sel. zeichnen 1936 if( nCurTab != 0 ) 1937 { 1938 aRect.Left() = nTabPos; 1939 aSize.Width() -= nTabPos; 1940 } 1941 aRect.SetSize( aSize ); 1942 } 1943 // rechten Rand anpassen wg. Clipping 1944 if( aRect.Right() >= nRealWidth ) 1945 { 1946 aRect.Right() = nRealWidth-1; 1947 nFocusWidth = (short)aRect.GetWidth(); 1948 } 1949 return aRect; 1950 } 1951 1952 1953 long SvTreeListBox::GetTabPos( SvLBoxEntry* pEntry, SvLBoxTab* pTab) 1954 { 1955 DBG_CHKTHIS(SvTreeListBox,0); 1956 DBG_ASSERT(pTab,"No Tab"); 1957 long nPos = pTab->GetPos(); 1958 if( pTab->IsDynamic() ) 1959 { 1960 sal_uInt16 nDepth = pModel->GetDepth( pEntry ); 1961 nDepth = nDepth * (sal_uInt16)nIndent; 1962 nPos += (long)nDepth; 1963 } 1964 return nPos; 1965 } 1966 1967 SvLBoxItem* SvTreeListBox::GetItem_Impl( SvLBoxEntry* pEntry, long nX, 1968 SvLBoxTab** ppTab, sal_uInt16 nEmptyWidth ) 1969 { 1970 DBG_CHKTHIS(SvTreeListBox,0); 1971 SvLBoxItem* pItemClicked = 0; 1972 sal_uInt16 nTabCount = aTabs.Count(); 1973 sal_uInt16 nItemCount = pEntry->ItemCount(); 1974 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0); 1975 SvLBoxItem* pItem = pEntry->GetItem(0); 1976 sal_uInt16 nNextItem = 1; 1977 nX -= GetMapMode().GetOrigin().X(); 1978 long nRealWidth = pImp->GetOutputSize().Width(); 1979 nRealWidth -= GetMapMode().GetOrigin().X(); 1980 1981 while( 1 ) 1982 { 1983 SvLBoxTab* pNextTab=nNextItem<nTabCount ? (SvLBoxTab*)aTabs.GetObject(nNextItem) : 0; 1984 long nStart = GetTabPos( pEntry, pTab ); 1985 1986 long nNextTabPos; 1987 if( pNextTab ) 1988 nNextTabPos = GetTabPos( pEntry, pNextTab ); 1989 else 1990 { 1991 nNextTabPos = nRealWidth; 1992 if( nStart > nRealWidth ) 1993 nNextTabPos += 50; 1994 } 1995 1996 Size aItemSize( pItem->GetSize(this, pEntry)); 1997 nStart += pTab->CalcOffset( aItemSize.Width(), nNextTabPos - nStart ); 1998 long nLen = aItemSize.Width(); 1999 if( pNextTab ) 2000 { 2001 long nTabWidth = GetTabPos( pEntry, pNextTab ) - nStart; 2002 if( nTabWidth < nLen ) 2003 nLen = nTabWidth; 2004 } 2005 2006 if( !nLen ) 2007 nLen = nEmptyWidth; 2008 2009 if( nX >= nStart && nX < (nStart+nLen ) ) 2010 { 2011 pItemClicked = pItem; 2012 if( ppTab ) 2013 { 2014 *ppTab = pTab; 2015 break; 2016 } 2017 } 2018 if( nNextItem >= nItemCount || nNextItem >= nTabCount) 2019 break; 2020 pTab = (SvLBoxTab*)aTabs.GetObject( nNextItem ); 2021 pItem = pEntry->GetItem( nNextItem ); 2022 nNextItem++; 2023 } 2024 return pItemClicked; 2025 } 2026 2027 SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX,SvLBoxTab** ppTab) 2028 { 2029 return GetItem_Impl( pEntry, nX, ppTab, 0 ); 2030 } 2031 2032 SvLBoxItem* SvTreeListBox::GetItem(SvLBoxEntry* pEntry,long nX ) 2033 { 2034 DBG_CHKTHIS(SvTreeListBox,0); 2035 SvLBoxTab* pDummyTab; 2036 return GetItem_Impl( pEntry, nX, &pDummyTab, 0 ); 2037 } 2038 2039 SvLBoxItem* SvTreeListBox::GetFirstDynamicItem( SvLBoxEntry* pEntry ) 2040 { 2041 DBG_CHKTHIS(SvTreeListBox,0); 2042 2043 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(0); 2044 SvLBoxItem* pItem = pEntry->GetItem(0); 2045 sal_uInt16 nTabCount = aTabs.Count(); 2046 2047 sal_uInt16 nNext = 1; 2048 while ( !pTab->IsDynamic() && nNext < nTabCount ) 2049 { 2050 pItem = pEntry->GetItem( nNext ); 2051 pTab = (SvLBoxTab*)aTabs.GetObject( nNext ); 2052 nNext++; 2053 } 2054 return pItem; 2055 } 2056 2057 void SvTreeListBox::AddTab(long nTabPos,sal_uInt16 nFlags,void* pUserData ) 2058 { 2059 DBG_CHKTHIS(SvTreeListBox,0); 2060 nFocusWidth = -1; 2061 SvLBoxTab* pTab = new SvLBoxTab( nTabPos, nFlags ); 2062 pTab->SetUserData( pUserData ); 2063 aTabs.Insert( pTab, aTabs.Count() ); 2064 if( nTreeFlags & TREEFLAG_USESEL ) 2065 { 2066 sal_uInt16 nPos = aTabs.Count() - 1; 2067 if( nPos >= nFirstSelTab && nPos <= nLastSelTab ) 2068 pTab->nFlags |= SV_LBOXTAB_SHOW_SELECTION; 2069 else 2070 // String-Items werden normalerweise immer selektiert 2071 // deshalb explizit ausschalten 2072 pTab->nFlags &= ~SV_LBOXTAB_SHOW_SELECTION; 2073 } 2074 } 2075 2076 2077 2078 SvLBoxTab* SvTreeListBox::GetFirstDynamicTab( sal_uInt16& rPos ) const 2079 { 2080 DBG_CHKTHIS(SvTreeListBox,0); 2081 sal_uInt16 nCurTab = 0; 2082 sal_uInt16 nTabCount = aTabs.Count(); 2083 while( nCurTab < nTabCount ) 2084 { 2085 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject(nCurTab); 2086 if( pTab->nFlags & SV_LBOXTAB_DYNAMIC ) 2087 { 2088 rPos = nCurTab; 2089 return pTab; 2090 } 2091 nCurTab++; 2092 } 2093 return 0; 2094 } 2095 2096 SvLBoxTab* SvTreeListBox::GetFirstDynamicTab() const 2097 { 2098 sal_uInt16 nDummy; 2099 return GetFirstDynamicTab( nDummy ); 2100 } 2101 2102 SvLBoxTab* SvTreeListBox::GetTab( SvLBoxEntry* pEntry, SvLBoxItem* pItem) const 2103 { 2104 DBG_CHKTHIS(SvTreeListBox,0); 2105 sal_uInt16 nPos = pEntry->GetPos( pItem ); 2106 return (SvLBoxTab*)aTabs.GetObject( nPos ); 2107 } 2108 2109 void SvTreeListBox::ClearTabList() 2110 { 2111 DBG_CHKTHIS(SvTreeListBox,0); 2112 sal_uInt16 nTabCount = aTabs.Count(); 2113 while( nTabCount ) 2114 { 2115 nTabCount--; 2116 SvLBoxTab* pDelTab = (SvLBoxTab*)aTabs.GetObject( nTabCount ); 2117 delete pDelTab; 2118 } 2119 aTabs.Remove(0,aTabs.Count()); 2120 } 2121 2122 2123 Size SvTreeListBox::GetOutputSizePixel() const 2124 { 2125 DBG_CHKTHIS(SvTreeListBox,0); 2126 Size aSize = pImp->GetOutputSize(); 2127 return aSize; 2128 } 2129 2130 void SvTreeListBox::NotifyBeginScroll() 2131 { 2132 DBG_CHKTHIS(SvTreeListBox,0); 2133 } 2134 2135 void SvTreeListBox::NotifyEndScroll() 2136 { 2137 DBG_CHKTHIS(SvTreeListBox,0); 2138 } 2139 2140 void SvTreeListBox::NotifyScrolling( long ) 2141 { 2142 DBG_CHKTHIS(SvTreeListBox,0); 2143 } 2144 2145 void SvTreeListBox::NotifyScrolled() 2146 { 2147 DBG_CHKTHIS(SvTreeListBox,0); 2148 aScrolledHdl.Call( this ); 2149 } 2150 2151 void SvTreeListBox::NotifyInvalidating() 2152 { 2153 DBG_CHKTHIS(SvTreeListBox,0); 2154 } 2155 2156 void SvTreeListBox::Invalidate( sal_uInt16 nInvalidateFlags ) 2157 { 2158 DBG_CHKTHIS(SvTreeListBox,0); 2159 if( nFocusWidth == -1 ) 2160 // damit Control nicht nach dem Paint ein falsches FocusRect anzeigt 2161 pImp->RecalcFocusRect(); 2162 NotifyInvalidating(); 2163 SvLBox::Invalidate( nInvalidateFlags ); 2164 pImp->Invalidate(); 2165 } 2166 2167 void SvTreeListBox::Invalidate( const Rectangle& rRect, sal_uInt16 nInvalidateFlags ) 2168 { 2169 DBG_CHKTHIS(SvTreeListBox,0); 2170 if( nFocusWidth == -1 ) 2171 // damit Control nicht nach dem Paint ein falsches FocusRect anzeigt 2172 pImp->RecalcFocusRect(); 2173 NotifyInvalidating(); 2174 SvLBox::Invalidate( rRect, nInvalidateFlags ); 2175 } 2176 2177 2178 void SvTreeListBox::SetHighlightRange( sal_uInt16 nStart, sal_uInt16 nEnd) 2179 { 2180 DBG_CHKTHIS(SvTreeListBox,0); 2181 2182 sal_uInt16 nTemp; 2183 nTreeFlags |= TREEFLAG_USESEL; 2184 if( nStart > nEnd ) 2185 { 2186 nTemp = nStart; 2187 nStart = nEnd; 2188 nEnd = nTemp; 2189 } 2190 // alle Tabs markieren, die im Bereich liegen 2191 nTreeFlags |= TREEFLAG_RECALCTABS; 2192 nFirstSelTab = nStart; 2193 nLastSelTab = nEnd; 2194 pImp->RecalcFocusRect(); 2195 } 2196 2197 void SvTreeListBox::RemoveHighlightRange() 2198 { 2199 DBG_CHKTHIS(SvTreeListBox,0); 2200 nTreeFlags &= (~TREEFLAG_USESEL); 2201 if( IsUpdateMode() ) 2202 Invalidate(); 2203 } 2204 2205 sal_uLong SvTreeListBox::GetAscInsertionPos(SvLBoxEntry*,SvLBoxEntry*) 2206 { 2207 return LIST_APPEND; 2208 } 2209 2210 sal_uLong SvTreeListBox::GetDescInsertionPos(SvLBoxEntry*,SvLBoxEntry*) 2211 { 2212 DBG_CHKTHIS(SvTreeListBox,0); 2213 return LIST_APPEND; 2214 } 2215 2216 Region SvTreeListBox::GetDragRegion() const 2217 { 2218 DBG_CHKTHIS(SvTreeListBox,0); 2219 Rectangle aRect; 2220 SvLBoxEntry* pEntry = GetCurEntry(); 2221 if( pEntry ) 2222 { 2223 Point aPos = GetEntryPosition( pEntry ); 2224 aRect = ((SvTreeListBox*)this)->GetFocusRect( pEntry, aPos.Y() ); 2225 } 2226 Region aRegion( aRect ); 2227 return aRegion; 2228 } 2229 2230 2231 void SvTreeListBox::Command( const CommandEvent& rCEvt ) 2232 { 2233 DBG_CHKTHIS(SvTreeListBox,0); 2234 // FIXME gnumake2 resync to DEV300_m84 2235 pImp->Command( rCEvt ); 2236 } 2237 2238 2239 void SvTreeListBox::RemoveParentKeepChilds( SvLBoxEntry* pParent ) 2240 { 2241 DBG_CHKTHIS(SvTreeListBox,0); 2242 DBG_ASSERT(pParent,"RemoveParentKeepChilds:No Parent"); 2243 SvLBoxEntry* pNewParent = GetParent( pParent ); 2244 if( pParent->HasChilds()) 2245 { 2246 SvLBoxEntry* pChild = FirstChild( pParent ); 2247 while( pChild ) 2248 { 2249 pModel->Move( pChild, pNewParent, LIST_APPEND ); 2250 pChild = FirstChild( pParent ); 2251 } 2252 } 2253 pModel->Remove( pParent ); 2254 } 2255 2256 SvLBoxTab* SvTreeListBox::GetFirstTab( sal_uInt16 nFlagMask, sal_uInt16& rPos ) 2257 { 2258 sal_uInt16 nTabCount = aTabs.Count(); 2259 for( sal_uInt16 nPos = 0; nPos < nTabCount; nPos++ ) 2260 { 2261 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( nPos ); 2262 if( (pTab->nFlags & nFlagMask) ) 2263 { 2264 rPos = nPos; 2265 return pTab; 2266 } 2267 } 2268 rPos = 0xffff; 2269 return 0; 2270 } 2271 2272 SvLBoxTab* SvTreeListBox::GetLastTab( sal_uInt16 nFlagMask, sal_uInt16& rTabPos ) 2273 { 2274 short nTabCount = (short)aTabs.Count(); 2275 if( nTabCount ) 2276 { 2277 for( short nPos = nTabCount-1; nPos >= 0; nPos-- ) 2278 { 2279 SvLBoxTab* pTab = (SvLBoxTab*)aTabs.GetObject( (sal_uInt16)nPos ); 2280 if( (pTab->nFlags & nFlagMask) ) 2281 { 2282 rTabPos = (sal_uInt16)nPos; 2283 return pTab; 2284 } 2285 } 2286 } 2287 rTabPos = 0xffff; 2288 return 0; 2289 } 2290 2291 void SvTreeListBox::SetAddMode( sal_Bool bAdd ) 2292 { 2293 pImp->SetAddMode( bAdd ); 2294 } 2295 2296 sal_Bool SvTreeListBox::IsAddMode() const 2297 { 2298 return pImp->IsAddMode(); 2299 } 2300 2301 void SvTreeListBox::RequestHelp( const HelpEvent& rHEvt ) 2302 { 2303 if( !pImp->RequestHelp( rHEvt ) ) 2304 SvLBox::RequestHelp( rHEvt ); 2305 } 2306 2307 void SvTreeListBox::CursorMoved( SvLBoxEntry* ) 2308 { 2309 } 2310 2311 IMPL_LINK( SvTreeListBox, DefaultCompare, SvSortData*, pData ) 2312 { 2313 SvLBoxEntry* pLeft = (SvLBoxEntry*)(pData->pLeft ); 2314 SvLBoxEntry* pRight = (SvLBoxEntry*)(pData->pRight ); 2315 String aLeft( ((SvLBoxString*)(pLeft->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText()); 2316 String aRight( ((SvLBoxString*)(pRight->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText()); 2317 // #102891# ---------------- 2318 pImp->UpdateIntlWrapper(); 2319 return pImp->pIntlWrapper->getCaseCollator()->compareString( aLeft, aRight ); 2320 } 2321 2322 void SvTreeListBox::ModelNotification( sal_uInt16 nActionId, SvListEntry* pEntry1, 2323 SvListEntry* pEntry2, sal_uLong nPos ) 2324 { 2325 if( nActionId == LISTACTION_CLEARING ) 2326 CancelTextEditing(); 2327 2328 SvLBox::ModelNotification( nActionId, pEntry1, pEntry2, nPos ); 2329 switch( nActionId ) 2330 { 2331 case LISTACTION_INSERTED: 2332 { 2333 SvLBoxEntry* pEntry( dynamic_cast< SvLBoxEntry* >( pEntry1 ) ); 2334 ENSURE_OR_BREAK( pEntry, "SvTreeListBox::ModelNotification: invalid entry!" ); 2335 SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) ); 2336 if ( !pBmpItem ) 2337 break; 2338 const Image& rBitmap1( pBmpItem->GetBitmap1() ); 2339 const Image& rBitmap2( pBmpItem->GetBitmap2() ); 2340 short nMaxWidth = short( Max( rBitmap1.GetSizePixel().Width(), rBitmap2.GetSizePixel().Width() ) ); 2341 nMaxWidth = pImp->UpdateContextBmpWidthVector( pEntry, nMaxWidth ); 2342 if( nMaxWidth > nContextBmpWidthMax ) 2343 { 2344 nContextBmpWidthMax = nMaxWidth; 2345 SetTabs(); 2346 } 2347 } 2348 break; 2349 2350 case LISTACTION_RESORTING: 2351 SetUpdateMode( sal_False ); 2352 break; 2353 2354 case LISTACTION_RESORTED: 2355 // nach Sortierung den ersten Eintrag anzeigen, dabei die 2356 // Selektion erhalten. 2357 MakeVisible( (SvLBoxEntry*)pModel->First(), sal_True ); 2358 SetUpdateMode( sal_True ); 2359 break; 2360 2361 case LISTACTION_CLEARED: 2362 if( IsUpdateMode() ) 2363 Update(); 2364 break; 2365 } 2366 } 2367 2368 // bei Aenderungen SetTabs beruecksichtigen 2369 long SvTreeListBox::GetTextOffset() const 2370 { 2371 DBG_CHKTHIS(SvTreeListBox,0); 2372 const WinBits nWindowStyle = GetStyle(); 2373 sal_Bool bHasButtons = (nWindowStyle & WB_HASBUTTONS)!=0; 2374 sal_Bool bHasButtonsAtRoot = (nWindowStyle & (WB_HASLINESATROOT | 2375 WB_HASBUTTONSATROOT))!=0; 2376 long nStartPos = TAB_STARTPOS; 2377 long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width(); 2378 2379 long nCheckWidth = 0; 2380 if( nTreeFlags & TREEFLAG_CHKBTN ) 2381 nCheckWidth = pCheckButtonData->aBmps[0].GetSizePixel().Width(); 2382 long nCheckWidthDIV2 = nCheckWidth / 2; 2383 2384 long nContextWidth = nContextBmpWidthMax; 2385 long nContextWidthDIV2 = nContextWidth / 2; 2386 2387 int nCase = NO_BUTTONS; 2388 if( !(nTreeFlags & TREEFLAG_CHKBTN) ) 2389 { 2390 if( bHasButtons ) 2391 nCase = NODE_BUTTONS; 2392 } 2393 else 2394 { 2395 if( bHasButtons ) 2396 nCase = NODE_AND_CHECK_BUTTONS; 2397 else 2398 nCase = CHECK_BUTTONS; 2399 } 2400 2401 switch( nCase ) 2402 { 2403 case NO_BUTTONS : 2404 nStartPos += nContextWidthDIV2; // wg. Zentrierung 2405 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 2406 if( nContextBmpWidthMax ) 2407 nStartPos += 5; // Abstand Context-Bmp - Text 2408 break; 2409 2410 case NODE_BUTTONS : 2411 if( bHasButtonsAtRoot ) 2412 nStartPos += ( nIndent + (nNodeWidthPixel/2) ); 2413 else 2414 nStartPos += nContextWidthDIV2; 2415 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 2416 if( nContextBmpWidthMax ) 2417 nStartPos += 5; // Abstand Context-Bmp - Text 2418 break; 2419 2420 case NODE_AND_CHECK_BUTTONS : 2421 if( bHasButtonsAtRoot ) 2422 nStartPos += ( nIndent + nNodeWidthPixel ); 2423 else 2424 nStartPos += nCheckWidthDIV2; 2425 nStartPos += nCheckWidthDIV2; // rechter Rand des CheckButtons 2426 nStartPos += 3; // Abstand CheckButton Context-Bmp 2427 nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp 2428 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 2429 // Abstand setzen nur wenn Bitmaps da 2430 if( nContextBmpWidthMax ) 2431 nStartPos += 5; // Abstand Context-Bmp - Text 2432 break; 2433 2434 case CHECK_BUTTONS : 2435 nStartPos += nCheckWidthDIV2; 2436 nStartPos += nCheckWidthDIV2; // rechter Rand CheckButton 2437 nStartPos += 3; // Abstand CheckButton Context-Bmp 2438 nStartPos += nContextWidthDIV2; // Mitte der Context-Bmp 2439 nStartPos += nContextWidthDIV2; // rechter Rand der Context-Bmp 2440 if( nContextBmpWidthMax ) 2441 nStartPos += 5; // Abstand Context-Bmp - Text 2442 break; 2443 } 2444 return nStartPos; 2445 } 2446 2447 void SvTreeListBox::EndSelection() 2448 { 2449 pImp->EndSelection(); 2450 } 2451 2452 sal_Bool SvTreeListBox::IsNodeButton( const Point& rPos ) const 2453 { 2454 SvLBoxEntry* pEntry = GetEntry( rPos ); 2455 if( pEntry ) 2456 return pImp->IsNodeButton( rPos, pEntry ); 2457 return sal_False; 2458 } 2459 2460 void SvTreeListBox::RepaintScrollBars() const 2461 { 2462 ((SvTreeListBox*)this)->pImp->RepaintScrollBars(); 2463 } 2464 2465 ScrollBar *SvTreeListBox::GetVScroll() 2466 { 2467 return &((SvTreeListBox*)this)->pImp->aVerSBar; 2468 } 2469 2470 ScrollBar *SvTreeListBox::GetHScroll() 2471 { 2472 return &((SvTreeListBox*)this)->pImp->aHorSBar; 2473 } 2474 2475 void SvTreeListBox::EnableAsyncDrag( sal_Bool b ) 2476 { 2477 pImp->EnableAsyncDrag( b ); 2478 } 2479 2480 SvLBoxEntry* SvTreeListBox::GetFirstEntryInView() const 2481 { 2482 Point aPos; 2483 return GetEntry( aPos ); 2484 } 2485 2486 SvLBoxEntry* SvTreeListBox::GetNextEntryInView(SvLBoxEntry* pEntry ) const 2487 { 2488 SvLBoxEntry* pNext = (SvLBoxEntry*)NextVisible( pEntry ); 2489 if( pNext ) 2490 { 2491 Point aPos( GetEntryPosition(pNext) ); 2492 const Size& rSize = pImp->GetOutputSize(); 2493 if( aPos.Y() < 0 || aPos.Y() >= rSize.Height() ) 2494 return 0; 2495 } 2496 return pNext; 2497 } 2498 2499 void SvTreeListBox::ShowFocusRect( const SvLBoxEntry* pEntry ) 2500 { 2501 pImp->ShowFocusRect( pEntry ); 2502 } 2503 2504 void SvTreeListBox::SetTabBar( TabBar* pTabBar ) 2505 { 2506 pImp->SetTabBar( pTabBar ); 2507 } 2508 2509 void SvTreeListBox::DataChanged( const DataChangedEvent& rDCEvt ) 2510 { 2511 if( (rDCEvt.GetType()==DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 2512 { 2513 nEntryHeight = 0; // _together_ with sal_True of 1. par (bFont) of InitSettings() a zero-height 2514 // forces complete recalc of heights! 2515 InitSettings( sal_True, sal_True, sal_True ); 2516 Invalidate(); 2517 } 2518 else 2519 Control::DataChanged( rDCEvt ); 2520 } 2521 2522 void SvTreeListBox::StateChanged( StateChangedType i_nStateChange ) 2523 { 2524 SvLBox::StateChanged( i_nStateChange ); 2525 if ( i_nStateChange == STATE_CHANGE_STYLE ) 2526 ImplInitStyle(); 2527 } 2528 2529 void SvTreeListBox::InitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground) 2530 { 2531 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 2532 if( bFont ) 2533 { 2534 Font aFont; 2535 aFont = rStyleSettings.GetFieldFont(); 2536 aFont.SetColor( rStyleSettings.GetWindowTextColor() ); 2537 SetPointFont( aFont ); 2538 AdjustEntryHeight( aFont ); 2539 RecalcViewData(); 2540 } 2541 2542 if( bForeground || bFont ) 2543 { 2544 SetTextColor( rStyleSettings.GetFieldTextColor() ); 2545 SetTextFillColor(); 2546 } 2547 2548 if( bBackground ) 2549 SetBackground( rStyleSettings.GetFieldColor() ); 2550 2551 // always try to re-create default-SvLBoxButtonData 2552 if( pCheckButtonData && pCheckButtonData->HasDefaultImages() ) 2553 pCheckButtonData->SetDefaultImages( this ); 2554 } 2555 2556 sal_Bool SvTreeListBox::IsCellFocusEnabled() const 2557 { 2558 return pImp->IsCellFocusEnabled(); 2559 } 2560 2561 bool SvTreeListBox::SetCurrentTabPos( sal_uInt16 _nNewPos ) 2562 { 2563 return pImp->SetCurrentTabPos( _nNewPos ); 2564 } 2565 2566 sal_uInt16 SvTreeListBox::GetCurrentTabPos() const 2567 { 2568 return pImp->GetCurrentTabPos(); 2569 } 2570 2571 void SvTreeListBox::InitStartEntry() 2572 { 2573 if( !pImp->pStartEntry ) 2574 pImp->pStartEntry = GetModel()->First(); 2575 } 2576 2577 void SvTreeListBox::CancelPendingEdit() 2578 { 2579 if( pImp ) 2580 pImp->CancelPendingEdit(); 2581 } 2582 2583 PopupMenu* SvTreeListBox::CreateContextMenu( void ) 2584 { 2585 return NULL; 2586 } 2587 2588 void SvTreeListBox::ExcecuteContextMenuAction( sal_uInt16 ) 2589 { 2590 DBG_WARNING( "SvTreeListBox::ExcecuteContextMenuAction(): now there's happening nothing!" ); 2591 } 2592 2593 void SvTreeListBox::EnableContextMenuHandling( void ) 2594 { 2595 DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" ); 2596 2597 pImp->bContextMenuHandling = sal_True; 2598 } 2599 2600 void SvTreeListBox::EnableContextMenuHandling( sal_Bool b ) 2601 { 2602 DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" ); 2603 2604 pImp->bContextMenuHandling = b; 2605 } 2606 2607 sal_Bool SvTreeListBox::IsContextMenuHandlingEnabled( void ) const 2608 { 2609 DBG_ASSERT( pImp, "-SvTreeListBox::IsContextMenuHandlingEnabled(): No implementation!" ); 2610 2611 return pImp->bContextMenuHandling; 2612 } 2613 2614 void SvTreeListBox::EnableList( bool _bEnable ) 2615 { 2616 // call base class method 2617 Window::Enable( _bEnable != false ); 2618 // then paint immediately 2619 Paint( Rectangle( Point(), GetSizePixel() ) ); 2620 } 2621 2622 ::com::sun::star::uno::Reference< XAccessible > SvTreeListBox::CreateAccessible() 2623 { 2624 Window* pParent = GetAccessibleParentWindow(); 2625 DBG_ASSERT( pParent, "SvTreeListBox::CreateAccessible - accessible parent not found" ); 2626 2627 ::com::sun::star::uno::Reference< XAccessible > xAccessible; 2628 if ( pParent ) 2629 { 2630 ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible(); 2631 if ( xAccParent.is() ) 2632 { 2633 // need to be done here to get the vclxwindow later on in the accessbile 2634 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xTemp(GetComponentInterface()); 2635 xAccessible = pImp->m_aFactoryAccess.getFactory().createAccessibleTreeListBox( *this, xAccParent ); 2636 } 2637 } 2638 return xAccessible; 2639 } 2640 2641 void SvTreeListBox::FillAccessibleEntryStateSet( SvLBoxEntry* pEntry, ::utl::AccessibleStateSetHelper& rStateSet ) const 2642 { 2643 DBG_ASSERT( pEntry, "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry" ); 2644 2645 if ( pEntry->HasChildsOnDemand() || pEntry->HasChilds() ) 2646 { 2647 rStateSet.AddState( AccessibleStateType::EXPANDABLE ); 2648 if ( IsExpanded( pEntry ) ) 2649 rStateSet.AddState( (sal_Int16)AccessibleStateType::EXPANDED ); 2650 } 2651 2652 if ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) 2653 rStateSet.AddState( AccessibleStateType::CHECKED ); 2654 if ( IsEntryVisible( pEntry ) ) 2655 rStateSet.AddState( AccessibleStateType::VISIBLE ); 2656 if ( IsSelected( pEntry ) ) 2657 rStateSet.AddState( AccessibleStateType::SELECTED ); 2658 } 2659 2660 Rectangle SvTreeListBox::GetBoundingRect( SvLBoxEntry* pEntry ) 2661 { 2662 Point aPos = GetEntryPosition( pEntry ); 2663 Rectangle aRect = GetFocusRect( pEntry, aPos.Y() ); 2664 return aRect; 2665 } 2666 2667 void SvTreeListBox::EnableCellFocus() 2668 { 2669 pImp->EnableCellFocus(); 2670 } 2671 2672 void SvTreeListBox::CallImplEventListeners(sal_uLong nEvent, void* pData) 2673 { 2674 CallEventListeners(nEvent, pData); 2675 } 2676 2677 void SvTreeListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& rStateSet ) const 2678 { 2679 SvLBox::FillAccessibleStateSet( rStateSet ); 2680 } 2681