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