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 #include <vcl/svapp.hxx> 27 #include <vcl/salnativewidgets.hxx> 28 #include <vcl/help.hxx> 29 #include <svtools/tabbar.hxx> 30 31 #include <stack> 32 33 #define _SVTREEBX_CXX 34 #include <svtools/svtreebx.hxx> 35 #include <svtools/svlbox.hxx> 36 #include <svimpbox.hxx> 37 #include <rtl/instance.hxx> 38 #include <svtools/svtdata.hxx> 39 #include <tools/wintypes.hxx> 40 #include <svtools/svtools.hrc> 41 #include <comphelper/processfactory.hxx> 42 43 #define NODE_BMP_TABDIST_NOTVALID -2000000 44 #define FIRST_ENTRY_TAB 1 45 46 // #i27063# (pl), #i32300# (pb) never access VCL after DeInitVCL - also no destructors 47 Image* SvImpLBox::s_pDefCollapsed = NULL; 48 Image* SvImpLBox::s_pDefExpanded = NULL; 49 Image* SvImpLBox::s_pDefCollapsedHC = NULL; 50 Image* SvImpLBox::s_pDefExpandedHC = NULL; 51 sal_Int32 SvImpLBox::s_nImageRefCount = 0; 52 53 SvImpLBox::SvImpLBox( SvTreeListBox* pLBView, SvLBoxTreeList* pLBTree, WinBits nWinStyle) : 54 55 pTabBar( NULL ), 56 aVerSBar( pLBView, WB_DRAG | WB_VSCROLL ), 57 aHorSBar( pLBView, WB_DRAG | WB_HSCROLL ), 58 aScrBarBox( pLBView ), 59 aOutputSize( 0, 0 ), 60 aSelEng( pLBView, (FunctionSet*)0 ), 61 aFctSet( this, &aSelEng, pLBView ), 62 nExtendedWinBits( 0 ), 63 bAreChildrenTransient( sal_True ), 64 pIntlWrapper( NULL ) // #102891# ----------------------- 65 { 66 osl_incrementInterlockedCount(&s_nImageRefCount); 67 pView = pLBView; 68 pTree = pLBTree; 69 aSelEng.SetFunctionSet( (FunctionSet*)&aFctSet ); 70 aSelEng.ExpandSelectionOnMouseMove( sal_False ); 71 SetStyle( nWinStyle ); 72 SetSelectionMode( SINGLE_SELECTION ); 73 SetDragDropMode( 0 ); 74 75 aVerSBar.SetScrollHdl( LINK( this, SvImpLBox, ScrollUpDownHdl ) ); 76 aHorSBar.SetScrollHdl( LINK( this, SvImpLBox, ScrollLeftRightHdl ) ); 77 aHorSBar.SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) ); 78 aVerSBar.SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) ); 79 aVerSBar.SetRange( Range(0,0) ); 80 aVerSBar.Hide(); 81 aHorSBar.SetRange( Range(0,0) ); 82 aHorSBar.SetPageSize( 24 ); // Pixel 83 aHorSBar.SetLineSize( 8 ); // Pixel 84 85 nHorSBarHeight = (short)aHorSBar.GetSizePixel().Height(); 86 nVerSBarWidth = (short)aVerSBar.GetSizePixel().Width(); 87 88 pStartEntry = 0; 89 pCursor = 0; 90 pAnchor = 0; 91 nVisibleCount = 0; // Anzahl Daten-Zeilen im Control 92 nNodeBmpTabDistance = NODE_BMP_TABDIST_NOTVALID; 93 nYoffsNodeBmp = 0; 94 nNodeBmpWidth = 0; 95 96 bAsyncBeginDrag = sal_False; 97 aAsyncBeginDragTimer.SetTimeout( 0 ); 98 aAsyncBeginDragTimer.SetTimeoutHdl( LINK(this,SvImpLBox,BeginDragHdl)); 99 // Button-Animation in Listbox 100 pActiveButton = 0; 101 pActiveEntry = 0; 102 pActiveTab = 0; 103 104 nFlags = 0; 105 nCurTabPos = FIRST_ENTRY_TAB; 106 107 aEditTimer.SetTimeout( 800 ); 108 aEditTimer.SetTimeoutHdl( LINK(this,SvImpLBox,EditTimerCall) ); 109 110 nMostRight = -1; 111 pMostRightEntry = 0; 112 nCurUserEvent = 0xffffffff; 113 114 bUpdateMode = sal_True; 115 bInVScrollHdl = sal_False; 116 nFlags |= F_FILLING; 117 118 bSubLstOpRet = bSubLstOpLR = bContextMenuHandling = bIsCellFocusEnabled = sal_False; 119 } 120 121 SvImpLBox::~SvImpLBox() 122 { 123 aEditTimer.Stop(); 124 StopUserEvent(); 125 126 // #102891# --------------------- 127 if( pIntlWrapper ) 128 delete pIntlWrapper; 129 if ( osl_decrementInterlockedCount(&s_nImageRefCount) == 0 ) 130 { 131 DELETEZ(s_pDefCollapsed); 132 DELETEZ(s_pDefExpanded); 133 DELETEZ(s_pDefCollapsedHC); 134 DELETEZ(s_pDefExpandedHC); 135 } 136 } 137 138 // #102891# -------------------- 139 void SvImpLBox::UpdateIntlWrapper() 140 { 141 const ::com::sun::star::lang::Locale & aNewLocale = Application::GetSettings().GetLocale(); 142 if( !pIntlWrapper ) 143 pIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), aNewLocale ); 144 else 145 { 146 const ::com::sun::star::lang::Locale &aLocale = pIntlWrapper->getLocale(); 147 if( aLocale.Language != aNewLocale.Language || // different Locale from the older one 148 aLocale.Country != aNewLocale.Country || 149 aLocale.Variant != aNewLocale.Variant ) 150 { 151 delete pIntlWrapper; 152 pIntlWrapper = new IntlWrapper( ::comphelper::getProcessServiceFactory(), aNewLocale ); 153 } 154 } 155 } 156 157 // #97680# ---------------------- 158 short SvImpLBox::UpdateContextBmpWidthVector( SvLBoxEntry* pEntry, short nWidth ) 159 { 160 DBG_ASSERT( pView->pModel, "View and Model aren't valid!" ); 161 162 sal_uInt16 nDepth = pView->pModel->GetDepth( pEntry ); 163 // initialize vector if necessary 164 std::vector< short >::size_type nSize = aContextBmpWidthVector.size(); 165 while ( nDepth > nSize ) 166 { 167 aContextBmpWidthVector.resize( nSize + 1 ); 168 aContextBmpWidthVector.at( nSize ) = nWidth; 169 ++nSize; 170 } 171 if( aContextBmpWidthVector.size() == nDepth ) 172 { 173 aContextBmpWidthVector.resize( nDepth + 1 ); 174 aContextBmpWidthVector.at( nDepth ) = 0; 175 } 176 short nContextBmpWidth = aContextBmpWidthVector[ nDepth ]; 177 if( nContextBmpWidth < nWidth ) 178 { 179 aContextBmpWidthVector.at( nDepth ) = nWidth; 180 return nWidth; 181 } 182 else 183 return nContextBmpWidth; 184 } 185 186 void SvImpLBox::UpdateContextBmpWidthVectorFromMovedEntry( SvLBoxEntry* pEntry ) 187 { 188 DBG_ASSERT( pEntry, "Moved Entry is invalid!" ); 189 190 SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) ); 191 short nExpWidth = (short)pBmpItem->GetBitmap1().GetSizePixel().Width(); 192 short nColWidth = (short)pBmpItem->GetBitmap2().GetSizePixel().Width(); 193 short nMax = Max(nExpWidth, nColWidth); 194 UpdateContextBmpWidthVector( pEntry, nMax ); 195 196 if( pEntry->HasChilds() ) // recursive call, whether expanded or not 197 { 198 SvLBoxEntry* pChild = pView->FirstChild( pEntry ); 199 DBG_ASSERT( pChild, "The first child is invalid!" ); 200 do 201 { 202 UpdateContextBmpWidthVectorFromMovedEntry( pChild ); 203 pChild = pView->Next( pChild ); 204 } while ( pChild ); 205 } 206 } 207 208 void SvImpLBox::UpdateContextBmpWidthMax( SvLBoxEntry* pEntry ) 209 { 210 sal_uInt16 nDepth = pView->pModel->GetDepth( pEntry ); 211 if( aContextBmpWidthVector.size() < 1 ) 212 return; 213 short nWidth = aContextBmpWidthVector[ nDepth ]; 214 if( nWidth != pView->nContextBmpWidthMax ) { 215 pView->nContextBmpWidthMax = nWidth; 216 nFlags |= F_IGNORE_CHANGED_TABS; 217 pView->SetTabs(); 218 nFlags &= ~F_IGNORE_CHANGED_TABS; 219 } 220 } 221 222 void SvImpLBox::CalcCellFocusRect( SvLBoxEntry* pEntry, Rectangle& rRect ) 223 { 224 if ( pEntry && bIsCellFocusEnabled ) 225 { 226 if ( nCurTabPos > FIRST_ENTRY_TAB ) 227 { 228 SvLBoxItem* pItem = pCursor->GetItem( nCurTabPos ); 229 rRect.Left() = pView->GetTab( pCursor, pItem )->GetPos(); 230 } 231 if ( pCursor->ItemCount() > ( nCurTabPos + 1 ) ) 232 { 233 SvLBoxItem* pNextItem = pCursor->GetItem( nCurTabPos + 1 ); 234 long nRight = pView->GetTab( pCursor, pNextItem )->GetPos() - 1; 235 if ( nRight < rRect.Right() ) 236 rRect.Right() = nRight; 237 } 238 } 239 } 240 241 void SvImpLBox::SetStyle( WinBits i_nWinStyle ) 242 { 243 m_nStyle = i_nWinStyle; 244 if ( ( m_nStyle & WB_SIMPLEMODE) && ( aSelEng.GetSelectionMode() == MULTIPLE_SELECTION ) ) 245 aSelEng.AddAlways( sal_True ); 246 } 247 248 void SvImpLBox::SetExtendedWindowBits( ExtendedWinBits _nBits ) 249 { 250 nExtendedWinBits = _nBits; 251 } 252 253 // Das Model darf hier nicht mehr angefasst werden 254 void SvImpLBox::Clear() 255 { 256 StopUserEvent(); 257 pStartEntry = 0; 258 pAnchor = 0; 259 260 pActiveButton = 0; 261 pActiveEntry = 0; 262 pActiveTab = 0; 263 264 nMostRight = -1; 265 pMostRightEntry = 0; 266 267 // Der Cursor darf hier nicht mehr angefasst werden! 268 if( pCursor ) 269 { 270 if( pView->HasFocus() ) 271 pView->HideFocus(); 272 pCursor = 0; 273 } 274 aVerSBar.Hide(); 275 aVerSBar.SetThumbPos( 0 ); 276 Range aRange( 0, 0 ); 277 aVerSBar.SetRange( aRange ); 278 aOutputSize = pView->Control::GetOutputSizePixel(); 279 nFlags &= ~(F_VER_SBARSIZE_WITH_HBAR | F_HOR_SBARSIZE_WITH_VBAR ); 280 if( pTabBar ) 281 { 282 aOutputSize.Height() -= nHorSBarHeight; 283 nFlags |= F_VER_SBARSIZE_WITH_HBAR; 284 } 285 if( !pTabBar ) 286 aHorSBar.Hide(); 287 aHorSBar.SetThumbPos( 0 ); 288 MapMode aMapMode( pView->GetMapMode()); 289 aMapMode.SetOrigin( Point(0,0) ); 290 pView->Control::SetMapMode( aMapMode ); 291 aHorSBar.SetRange( aRange ); 292 aHorSBar.SetSizePixel(Size(aOutputSize.Width(),nHorSBarHeight)); 293 pView->SetClipRegion(); 294 if( GetUpdateMode() ) 295 pView->Invalidate( GetVisibleArea() ); 296 nFlags |= F_FILLING; 297 if( !aHorSBar.IsVisible() && !aVerSBar.IsVisible() ) 298 aScrBarBox.Hide(); 299 300 // #97680# --------- 301 aContextBmpWidthVector.clear(); 302 303 //IAccessibility2 Implementation 2009----- 304 CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED, NULL ); 305 //-----IAccessibility2 Implementation 2009 306 } 307 308 // ********************************************************************* 309 // Painten, Navigieren, Scrollen 310 // ********************************************************************* 311 312 IMPL_LINK_INLINE_START( SvImpLBox, EndScrollHdl, ScrollBar *, EMPTYARG ) 313 { 314 if( nFlags & F_ENDSCROLL_SET_VIS_SIZE ) 315 { 316 aVerSBar.SetVisibleSize( nNextVerVisSize ); 317 nFlags &= ~F_ENDSCROLL_SET_VIS_SIZE; 318 } 319 EndScroll(); 320 return 0; 321 } 322 IMPL_LINK_INLINE_END( SvImpLBox, EndScrollHdl, ScrollBar *, pScrollBar ) 323 324 325 // Handler vertikale ScrollBar 326 327 IMPL_LINK( SvImpLBox, ScrollUpDownHdl, ScrollBar *, pScrollBar ) 328 { 329 DBG_ASSERT(!bInVScrollHdl,"Scroll-Handler ueberholt sich!"); 330 long nDelta = pScrollBar->GetDelta(); 331 if( !nDelta ) 332 return 0; 333 334 nFlags &= (~F_FILLING); 335 336 bInVScrollHdl = sal_True; 337 338 if( pView->IsEditingActive() ) 339 { 340 pView->EndEditing( sal_True ); // Cancel 341 pView->Update(); 342 } 343 BeginScroll(); 344 345 if( nDelta > 0 ) 346 { 347 if( nDelta == 1 ) 348 CursorDown(); 349 else 350 PageDown( (sal_uInt16) nDelta ); 351 } 352 else 353 { 354 nDelta *= (-1); 355 if( nDelta == 1 ) 356 CursorUp(); 357 else 358 PageUp( (sal_uInt16) nDelta ); 359 } 360 bInVScrollHdl = sal_False; 361 return 0; 362 } 363 364 365 void SvImpLBox::CursorDown() 366 { 367 SvLBoxEntry* pNextFirstToDraw = (SvLBoxEntry*)(pView->NextVisible( pStartEntry)); 368 if( pNextFirstToDraw ) 369 { 370 nFlags &= (~F_FILLING); 371 pView->NotifyScrolling( -1 ); 372 ShowCursor( sal_False ); 373 pView->Update(); 374 pStartEntry = pNextFirstToDraw; 375 Rectangle aArea( GetVisibleArea() ); 376 pView->Scroll( 0, -(pView->GetEntryHeight()), aArea, SCROLL_NOCHILDREN ); 377 pView->Update(); 378 ShowCursor( sal_True ); 379 pView->NotifyScrolled(); 380 } 381 } 382 383 void SvImpLBox::CursorUp() 384 { 385 SvLBoxEntry* pPrevFirstToDraw = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry)); 386 if( pPrevFirstToDraw ) 387 { 388 nFlags &= (~F_FILLING); 389 long nEntryHeight = pView->GetEntryHeight(); 390 pView->NotifyScrolling( 1 ); 391 ShowCursor( sal_False ); 392 pView->Update(); 393 pStartEntry = pPrevFirstToDraw; 394 Rectangle aArea( GetVisibleArea() ); 395 aArea.Bottom() -= nEntryHeight; 396 pView->Scroll( 0, nEntryHeight, aArea, SCROLL_NOCHILDREN ); 397 pView->Update(); 398 ShowCursor( sal_True ); 399 pView->NotifyScrolled(); 400 } 401 } 402 403 void SvImpLBox::PageDown( sal_uInt16 nDelta ) 404 { 405 sal_uInt16 nRealDelta = nDelta; 406 407 if( !nDelta ) 408 return; 409 410 SvLBoxEntry* pNext; 411 pNext = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nRealDelta )); 412 if( (sal_uLong)pNext == (sal_uLong)pStartEntry ) 413 return; 414 415 ShowCursor( sal_False ); 416 417 nFlags &= (~F_FILLING); 418 pView->Update(); 419 pStartEntry = pNext; 420 421 if( nRealDelta >= nVisibleCount ) 422 { 423 pView->Invalidate( GetVisibleArea() ); 424 pView->Update(); 425 } 426 else 427 { 428 long nScroll = nRealDelta * (-1); 429 pView->NotifyScrolling( nScroll ); 430 Rectangle aArea( GetVisibleArea() ); 431 nScroll = pView->GetEntryHeight()*nRealDelta; 432 nScroll = -nScroll; 433 pView->Update(); 434 pView->Scroll( 0, nScroll, aArea, SCROLL_NOCHILDREN ); 435 pView->Update(); 436 pView->NotifyScrolled(); 437 } 438 439 ShowCursor( sal_True ); 440 } 441 442 void SvImpLBox::PageUp( sal_uInt16 nDelta ) 443 { 444 sal_uInt16 nRealDelta = nDelta; 445 if( !nDelta ) 446 return; 447 448 SvLBoxEntry* pPrev = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry, nRealDelta )); 449 if( (sal_uLong)pPrev == (sal_uLong)pStartEntry ) 450 return; 451 452 nFlags &= (~F_FILLING); 453 ShowCursor( sal_False ); 454 455 pView->Update(); 456 pStartEntry = pPrev; 457 if( nRealDelta >= nVisibleCount ) 458 { 459 pView->Invalidate( GetVisibleArea() ); 460 pView->Update(); 461 } 462 else 463 { 464 long nEntryHeight = pView->GetEntryHeight(); 465 pView->NotifyScrolling( (long)nRealDelta ); 466 Rectangle aArea( GetVisibleArea() ); 467 pView->Update(); 468 pView->Scroll( 0, nEntryHeight*nRealDelta, aArea, SCROLL_NOCHILDREN ); 469 pView->Update(); 470 pView->NotifyScrolled(); 471 } 472 473 ShowCursor( sal_True ); 474 } 475 476 void SvImpLBox::KeyUp( sal_Bool bPageUp, sal_Bool bNotifyScroll ) 477 { 478 if( !aVerSBar.IsVisible() ) 479 return; 480 481 long nDelta; 482 if( bPageUp ) 483 nDelta = aVerSBar.GetPageSize(); 484 else 485 nDelta = 1; 486 487 long nThumbPos = aVerSBar.GetThumbPos(); 488 489 if( nThumbPos < nDelta ) 490 nDelta = nThumbPos; 491 492 if( nDelta <= 0 ) 493 return; 494 495 nFlags &= (~F_FILLING); 496 if( bNotifyScroll ) 497 BeginScroll(); 498 499 aVerSBar.SetThumbPos( nThumbPos - nDelta ); 500 if( bPageUp ) 501 PageUp( (short)nDelta ); 502 else 503 CursorUp(); 504 505 if( bNotifyScroll ) 506 EndScroll(); 507 } 508 509 510 void SvImpLBox::KeyDown( sal_Bool bPageDown, sal_Bool bNotifyScroll ) 511 { 512 if( !aVerSBar.IsVisible() ) 513 return; 514 515 long nDelta; 516 if( bPageDown ) 517 nDelta = aVerSBar.GetPageSize(); 518 else 519 nDelta = 1; 520 521 long nThumbPos = aVerSBar.GetThumbPos(); 522 long nVisibleSize = aVerSBar.GetVisibleSize(); 523 long nRange = aVerSBar.GetRange().Len(); 524 525 long nTmp = nThumbPos+nVisibleSize; 526 while( (nDelta > 0) && (nTmp+nDelta) >= nRange ) 527 nDelta--; 528 529 if( nDelta <= 0 ) 530 return; 531 532 nFlags &= (~F_FILLING); 533 if( bNotifyScroll ) 534 BeginScroll(); 535 536 aVerSBar.SetThumbPos( nThumbPos+nDelta ); 537 if( bPageDown ) 538 PageDown( (short)nDelta ); 539 else 540 CursorDown(); 541 542 if( bNotifyScroll ) 543 EndScroll(); 544 } 545 546 547 548 void SvImpLBox::InvalidateEntriesFrom( long nY ) const 549 { 550 if( !(nFlags & F_IN_PAINT )) 551 { 552 Rectangle aRect( GetVisibleArea() ); 553 aRect.Top() = nY; 554 pView->Invalidate( aRect ); 555 } 556 } 557 558 void SvImpLBox::InvalidateEntry( long nY ) const 559 { 560 if( !(nFlags & F_IN_PAINT )) 561 { 562 Rectangle aRect( GetVisibleArea() ); 563 long nMaxBottom = aRect.Bottom(); 564 aRect.Top() = nY; 565 aRect.Bottom() = nY; aRect.Bottom() += pView->GetEntryHeight(); 566 if( aRect.Top() > nMaxBottom ) 567 return; 568 if( aRect.Bottom() > nMaxBottom ) 569 aRect.Bottom() = nMaxBottom; 570 pView->Invalidate( aRect ); 571 } 572 } 573 574 void SvImpLBox::InvalidateEntry( SvLBoxEntry* pEntry ) 575 { 576 if( GetUpdateMode() ) 577 { 578 long nPrev = nMostRight; 579 SetMostRight( pEntry ); 580 if( nPrev < nMostRight ) 581 ShowVerSBar(); 582 } 583 if( !(nFlags & F_IN_PAINT )) 584 { 585 sal_Bool bHasFocusRect = sal_False; 586 if( pEntry==pCursor && pView->HasFocus() ) 587 { 588 bHasFocusRect = sal_True; 589 ShowCursor( sal_False ); 590 } 591 InvalidateEntry( GetEntryLine( pEntry ) ); 592 if( bHasFocusRect ) 593 ShowCursor( sal_True ); 594 } 595 } 596 597 598 void SvImpLBox::RecalcFocusRect() 599 { 600 if( pView->HasFocus() && pCursor ) 601 { 602 pView->HideFocus(); 603 long nY = GetEntryLine( pCursor ); 604 Rectangle aRect = pView->GetFocusRect( pCursor, nY ); 605 CalcCellFocusRect( pCursor, aRect ); 606 Region aOldClip( pView->GetClipRegion()); 607 Region aClipRegion( GetClipRegionRect() ); 608 pView->SetClipRegion( aClipRegion ); 609 pView->ShowFocus( aRect ); 610 pView->SetClipRegion( aOldClip ); 611 } 612 } 613 614 // 615 // Setzt Cursor. Passt bei SingleSelection die Selektion an 616 // 617 618 void SvImpLBox::SetCursor( SvLBoxEntry* pEntry, sal_Bool bForceNoSelect ) 619 { 620 SvViewDataEntry* pViewDataNewCur = 0; 621 if( pEntry ) 622 pViewDataNewCur= pView->GetViewDataEntry(pEntry); 623 if( pEntry && 624 pEntry == pCursor && 625 pViewDataNewCur->HasFocus() && 626 pViewDataNewCur->IsSelected()) 627 { 628 return; 629 } 630 631 // if this cursor is not selectable, find first visible that is and use it 632 while( pEntry && pViewDataNewCur && !pViewDataNewCur->IsSelectable() ) 633 { 634 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 635 pViewDataNewCur = pEntry ? pView->GetViewDataEntry(pEntry) : 0; 636 } 637 638 SvLBoxEntry* pOldCursor = pCursor; 639 if( pCursor && pEntry != pCursor ) 640 { 641 pView->SetEntryFocus( pCursor, sal_False ); 642 if( bSimpleTravel ) 643 pView->Select( pCursor, sal_False ); 644 pView->HideFocus(); 645 } 646 pCursor = pEntry; 647 if( pCursor ) 648 { 649 pViewDataNewCur->SetFocus( sal_True ); 650 if(!bForceNoSelect && bSimpleTravel && !(nFlags & F_DESEL_ALL) && GetUpdateMode()) 651 { 652 pView->Select( pCursor, sal_True ); 653 //IAccessibility2 Implementation 2009----- 654 CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS, pCursor ); 655 //-----IAccessibility2 Implementation 2009 656 } 657 // Mehrfachselektion: Im Cursor-Move selektieren, wenn 658 // nicht im Add-Mode (Ctrl-F8) 659 else if( GetUpdateMode() && 660 pView->GetSelectionMode() == MULTIPLE_SELECTION && 661 !(nFlags & F_DESEL_ALL) && !aSelEng.IsAddMode() && 662 !bForceNoSelect ) 663 { 664 pView->Select( pCursor, sal_True ); 665 //IAccessibility2 Implementation 2009----- 666 CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS, pCursor ); 667 //-----IAccessibility2 Implementation 2009 668 } 669 else 670 { 671 ShowCursor( sal_True ); 672 //IAccessibility2 Implementation 2009----- 673 if (bForceNoSelect && GetUpdateMode()) 674 { 675 CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS, pCursor); 676 } 677 //-----IAccessibility2 Implementation 2009 678 } 679 680 if( pAnchor ) 681 { 682 DBG_ASSERT(aSelEng.GetSelectionMode() != SINGLE_SELECTION,"Mode?"); 683 SetAnchorSelection( pOldCursor, pCursor ); 684 } 685 } 686 nFlags &= (~F_DESEL_ALL); 687 688 pView->OnCurrentEntryChanged(); 689 } 690 691 void SvImpLBox::ShowCursor( sal_Bool bShow ) 692 { 693 if( !bShow || !pCursor || !pView->HasFocus() ) 694 { 695 Region aOldClip( pView->GetClipRegion()); 696 Region aClipRegion( GetClipRegionRect() ); 697 pView->SetClipRegion( aClipRegion ); 698 pView->HideFocus(); 699 pView->SetClipRegion( aOldClip ); 700 } 701 else 702 { 703 long nY = GetEntryLine( pCursor ); 704 Rectangle aRect = pView->GetFocusRect( pCursor, nY ); 705 CalcCellFocusRect( pCursor, aRect ); 706 Region aOldClip( pView->GetClipRegion()); 707 Region aClipRegion( GetClipRegionRect() ); 708 pView->SetClipRegion( aClipRegion ); 709 pView->ShowFocus( aRect ); 710 pView->SetClipRegion( aOldClip ); 711 } 712 } 713 714 715 716 void SvImpLBox::UpdateAll( sal_Bool bInvalidateCompleteView, 717 sal_Bool bUpdateVerScrollBar ) 718 { 719 if( bUpdateVerScrollBar ) 720 FindMostRight(0); 721 aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1 ) ); 722 SyncVerThumb(); 723 FillView(); 724 ShowVerSBar(); 725 if( bSimpleTravel && pCursor && pView->HasFocus() ) 726 pView->Select( pCursor, sal_True ); 727 ShowCursor( sal_True ); 728 if( bInvalidateCompleteView ) 729 pView->Invalidate(); 730 else 731 pView->Invalidate( GetVisibleArea() ); 732 } 733 734 IMPL_LINK_INLINE_START( SvImpLBox, ScrollLeftRightHdl, ScrollBar *, pScrollBar ) 735 { 736 long nDelta = pScrollBar->GetDelta(); 737 if( nDelta ) 738 { 739 if( pView->IsEditingActive() ) 740 { 741 pView->EndEditing( sal_True ); // Cancel 742 pView->Update(); 743 } 744 pView->nFocusWidth = -1; 745 KeyLeftRight( nDelta ); 746 } 747 return 0; 748 } 749 IMPL_LINK_INLINE_END( SvImpLBox, ScrollLeftRightHdl, ScrollBar *, pScrollBar ) 750 751 void SvImpLBox::KeyLeftRight( long nDelta ) 752 { 753 if( !(nFlags & F_IN_RESIZE) ) 754 pView->Update(); 755 BeginScroll(); 756 nFlags &= (~F_FILLING); 757 pView->NotifyScrolling( 0 ); // 0 == horizontales Scrolling 758 ShowCursor( sal_False ); 759 760 // neuen Origin berechnen 761 long nPos = aHorSBar.GetThumbPos(); 762 Point aOrigin( -nPos, 0 ); 763 764 MapMode aMapMode( pView->GetMapMode() ); 765 aMapMode.SetOrigin( aOrigin ); 766 pView->SetMapMode( aMapMode ); 767 768 if( !(nFlags & F_IN_RESIZE) ) 769 { 770 Rectangle aRect( GetVisibleArea() ); 771 pView->Scroll( -nDelta, 0, aRect, SCROLL_NOCHILDREN ); 772 } 773 else 774 pView->Invalidate(); 775 RecalcFocusRect(); 776 ShowCursor( sal_True ); 777 pView->NotifyScrolled(); 778 } 779 780 781 // gibt letzten Eintrag zurueck, wenn Position unter 782 // dem letzten Eintrag ist 783 SvLBoxEntry* SvImpLBox::GetClickedEntry( const Point& rPoint ) const 784 { 785 DBG_ASSERT( pView->GetModel(), "SvImpLBox::GetClickedEntry: how can this ever happen? Please tell me (frank.schoenheit@sun.com) how to reproduce!" ); 786 if ( !pView->GetModel() ) 787 // this is quite impossible. Nevertheless, stack traces from the crash reporter 788 // suggest it isn't. Okay, make it safe, and wait for somebody to reproduce it 789 // reliably :-\ .... 790 // #122359# / 2005-05-23 / frank.schoenheit@sun.com 791 return NULL; 792 if( pView->GetEntryCount() == 0 || !pStartEntry || !pView->GetEntryHeight()) 793 return 0; 794 795 sal_uInt16 nClickedEntry = (sal_uInt16)(rPoint.Y() / pView->GetEntryHeight() ); 796 sal_uInt16 nTemp = nClickedEntry; 797 SvLBoxEntry* pEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nTemp )); 798 return pEntry; 799 } 800 801 // 802 // prueft, ob der Eintrag "richtig" getroffen wurde 803 // (Focusrect+ ContextBitmap bei TreeListBox) 804 // 805 sal_Bool SvImpLBox::EntryReallyHit(SvLBoxEntry* pEntry,const Point& rPosPixel,long nLine) 806 { 807 sal_Bool bRet; 808 // bei "besonderen" Entries (mit CheckButtons usw.) sind wir 809 // nicht so pingelig 810 if( pEntry->ItemCount() >= 3 ) 811 return sal_True; 812 813 Rectangle aRect( pView->GetFocusRect( pEntry, nLine )); 814 aRect.Right() = GetOutputSize().Width() - pView->GetMapMode().GetOrigin().X(); 815 if( pView->IsA() == SV_LISTBOX_ID_TREEBOX ) 816 { 817 SvLBoxContextBmp* pBmp = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP)); 818 aRect.Left() -= pBmp->GetSize(pView,pEntry).Width(); 819 aRect.Left() -= 4; // etwas Speilraum lassen 820 } 821 Point aPos( rPosPixel ); 822 aPos -= pView->GetMapMode().GetOrigin(); 823 if( aRect.IsInside( aPos ) ) 824 bRet = sal_True; 825 else 826 bRet = sal_False; 827 return bRet; 828 } 829 830 831 // gibt 0 zurueck, wenn Position unter dem letzten Eintrag ist 832 SvLBoxEntry* SvImpLBox::GetEntry( const Point& rPoint ) const 833 { 834 if( (pView->GetEntryCount() == 0) || !pStartEntry || 835 (rPoint.Y() > aOutputSize.Height()) 836 || !pView->GetEntryHeight()) 837 return 0; 838 839 sal_uInt16 nClickedEntry = (sal_uInt16)(rPoint.Y() / pView->GetEntryHeight() ); 840 sal_uInt16 nTemp = nClickedEntry; 841 SvLBoxEntry* pEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nTemp )); 842 if( nTemp != nClickedEntry ) 843 pEntry = 0; 844 return pEntry; 845 } 846 847 848 SvLBoxEntry* SvImpLBox::MakePointVisible(const Point& rPoint,sal_Bool bNotifyScroll) 849 { 850 if( !pCursor ) 851 return 0; 852 long nY = rPoint.Y(); 853 SvLBoxEntry* pEntry = 0; 854 long nMax = aOutputSize.Height(); 855 if( nY < 0 || nY >= nMax ) // aOutputSize.Height() ) 856 { 857 if( nY < 0 ) 858 pEntry = (SvLBoxEntry*)(pView->PrevVisible( pCursor )); 859 else 860 pEntry = (SvLBoxEntry*)(pView->NextVisible( pCursor )); 861 862 if( pEntry && pEntry != pCursor ) 863 pView->SetEntryFocus( pCursor, sal_False ); 864 865 if( nY < 0 ) 866 KeyUp( sal_False, bNotifyScroll ); 867 else 868 KeyDown( sal_False, bNotifyScroll ); 869 } 870 else 871 { 872 pEntry = GetClickedEntry( rPoint ); 873 if( !pEntry ) 874 { 875 sal_uInt16 nSteps = 0xFFFF; 876 // LastVisible ist noch nicht implementiert! 877 pEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, nSteps )); 878 } 879 if( pEntry ) 880 { 881 if( pEntry != pCursor && 882 aSelEng.GetSelectionMode() == SINGLE_SELECTION 883 ) 884 pView->Select( pCursor, sal_False ); 885 } 886 } 887 return pEntry; 888 } 889 890 Rectangle SvImpLBox::GetClipRegionRect() const 891 { 892 Point aOrigin( pView->GetMapMode().GetOrigin() ); 893 aOrigin.X() *= -1; // Umrechnung Dokumentkoord. 894 Rectangle aClipRect( aOrigin, aOutputSize ); 895 aClipRect.Bottom()++; 896 return aClipRect; 897 } 898 899 900 void SvImpLBox::Paint( const Rectangle& rRect ) 901 { 902 if( !pView->GetVisibleCount() ) 903 return; 904 905 nFlags |= F_IN_PAINT; 906 907 if( nFlags & F_FILLING ) 908 { 909 SvLBoxEntry* pFirst = pView->First(); 910 if( pFirst != pStartEntry ) 911 { 912 ShowCursor( sal_False ); 913 pStartEntry = pView->First(); 914 aVerSBar.SetThumbPos( 0 ); 915 StopUserEvent(); 916 ShowCursor( sal_True ); 917 nCurUserEvent = Application::PostUserEvent(LINK(this,SvImpLBox,MyUserEvent),(void*)1); 918 return; 919 } 920 } 921 922 if( !pStartEntry ) 923 { 924 pStartEntry = pView->First(); 925 } 926 927 #ifdef XX_OV 928 sal_uLong nXAbsPos = (sal_uInt16)pTree->GetAbsPos( pStartEntry ); 929 sal_uLong nXVisPos = pView->GetVisiblePos( pStartEntry ); 930 SvLBoxString* pXStr = (SvLBoxString*)pStartEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING); 931 #endif 932 933 934 935 if( nNodeBmpTabDistance == NODE_BMP_TABDIST_NOTVALID ) 936 SetNodeBmpTabDistance(); 937 938 long nRectHeight = rRect.GetHeight(); 939 long nEntryHeight = pView->GetEntryHeight(); 940 941 // Bereich der zu zeichnenden Entries berechnen 942 sal_uInt16 nStartLine = (sal_uInt16)( rRect.Top() / nEntryHeight ); 943 sal_uInt16 nCount = (sal_uInt16)( nRectHeight / nEntryHeight ); 944 nCount += 2; // keine Zeile vergessen 945 946 long nY = nStartLine * nEntryHeight; 947 SvLBoxEntry* pEntry = pStartEntry; 948 while( nStartLine && pEntry ) 949 { 950 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 951 nStartLine--; 952 } 953 954 Region aClipRegion( GetClipRegionRect() ); 955 956 // erst die Linien Zeichnen, dann clippen! 957 pView->SetClipRegion(); 958 if( m_nStyle & ( WB_HASLINES | WB_HASLINESATROOT ) ) 959 DrawNet(); 960 961 pView->SetClipRegion( aClipRegion ); 962 963 for( sal_uInt16 n=0; n< nCount && pEntry; n++ ) 964 { 965 /*long nMaxRight=*/ 966 pView->PaintEntry1( pEntry, nY, 0xffff, sal_True ); 967 nY += nEntryHeight; 968 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 969 } 970 971 if ( !pCursor && ( ( nExtendedWinBits & EWB_NO_AUTO_CURENTRY ) == 0 ) ) 972 { 973 // do not select if multiselection or explicit set 974 sal_Bool bNotSelect = ( aSelEng.GetSelectionMode() == MULTIPLE_SELECTION ) 975 || ( ( m_nStyle & WB_NOINITIALSELECTION ) == WB_NOINITIALSELECTION ); 976 SetCursor( pStartEntry, bNotSelect ); 977 } 978 979 nFlags &= (~F_DESEL_ALL); 980 pView->SetClipRegion(); 981 Rectangle aRect; 982 if( !(nFlags & F_PAINTED) ) 983 { 984 nFlags |= F_PAINTED; 985 RepaintScrollBars(); 986 } 987 nFlags &= (~F_IN_PAINT); 988 } 989 990 void SvImpLBox::MakeVisible( SvLBoxEntry* pEntry, sal_Bool bMoveToTop ) 991 { 992 if( !pEntry ) 993 return; 994 995 sal_Bool bInView = IsEntryInView( pEntry ); 996 997 if( bInView && (!bMoveToTop || pStartEntry == pEntry) ) 998 return; // ist schon sichtbar 999 1000 if( pStartEntry || (m_nStyle & WB_FORCE_MAKEVISIBLE) ) 1001 nFlags &= (~F_FILLING); 1002 if( !bInView ) 1003 { 1004 if( !pView->IsEntryVisible(pEntry) ) // Parent(s) zugeklappt ? 1005 { 1006 SvLBoxEntry* pParent = pView->GetParent( pEntry ); 1007 while( pParent ) 1008 { 1009 if( !pView->IsExpanded( pParent ) ) 1010 { 1011 #ifdef DBG_UTIL 1012 sal_Bool bRet = 1013 #endif 1014 pView->Expand( pParent ); 1015 DBG_ASSERT(bRet,"Not expanded!"); 1016 } 1017 pParent = pView->GetParent( pParent ); 1018 } 1019 // Passen Childs der Parents in View oder muessen wir scrollen ? 1020 if( IsEntryInView( pEntry ) && !bMoveToTop ) 1021 return; // Scrollen nicht noetig -> tschuess 1022 } 1023 } 1024 1025 pStartEntry = pEntry; 1026 ShowCursor( sal_False ); 1027 FillView(); 1028 aVerSBar.SetThumbPos( (long)(pView->GetVisiblePos( pStartEntry )) ); 1029 ShowCursor( sal_True ); 1030 pView->Invalidate(); 1031 } 1032 1033 1034 void SvImpLBox::RepaintSelectionItems() 1035 { 1036 if( !pView->GetVisibleCount() ) 1037 return; 1038 1039 if( !pStartEntry ) 1040 pStartEntry = pView->First(); 1041 1042 if( nNodeBmpTabDistance == NODE_BMP_TABDIST_NOTVALID ) 1043 SetNodeBmpTabDistance(); 1044 1045 ShowCursor( sal_False ); 1046 1047 long nEntryHeight = pView->GetEntryHeight(); 1048 1049 sal_uLong nCount = nVisibleCount; 1050 long nY = 0; 1051 SvLBoxEntry* pEntry = pStartEntry; 1052 for( sal_uLong n=0; n< nCount && pEntry; n++ ) 1053 { 1054 pView->PaintEntry1( pEntry, nY, 0xffff ); //wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION ); 1055 nY += nEntryHeight; 1056 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 1057 } 1058 1059 ShowCursor( sal_True ); 1060 } 1061 1062 1063 void SvImpLBox::DrawNet() 1064 { 1065 if( pView->GetVisibleCount() < 2 && !pStartEntry->HasChildsOnDemand() && 1066 !pStartEntry->HasChilds() ) 1067 return; 1068 1069 //for platforms who don't have nets, DrawNativeControl does nothing and return true 1070 //so that SvImpLBox::DrawNet() doesn't draw anything too 1071 if(pView->IsNativeControlSupported( CTRL_LISTNET, PART_ENTIRE_CONTROL)) { 1072 ImplControlValue aControlValue; 1073 Point aTemp(0,0); // temporary needed for g++ 3.3.5 1074 Rectangle aCtrlRegion( aTemp, Size( 0, 0 ) ); 1075 ControlState nState = CTRL_STATE_ENABLED; 1076 if( pView->DrawNativeControl( CTRL_LISTNET, PART_ENTIRE_CONTROL, 1077 aCtrlRegion, nState, aControlValue, rtl::OUString() ) ) 1078 { 1079 return; 1080 } 1081 1082 } 1083 1084 long nEntryHeight = pView->GetEntryHeight(); 1085 long nEntryHeightDIV2 = nEntryHeight / 2; 1086 if( nEntryHeightDIV2 && !(nEntryHeight & 0x0001)) 1087 nEntryHeightDIV2--; 1088 1089 SvLBoxEntry* pChild; 1090 SvLBoxEntry* pEntry = pStartEntry; 1091 1092 SvLBoxTab* pFirstDynamicTab = pView->GetFirstDynamicTab(); 1093 while( pTree->GetDepth( pEntry ) > 0 ) 1094 pEntry = pView->GetParent( pEntry ); 1095 sal_uInt16 nOffs = (sal_uInt16)(pView->GetVisiblePos( pStartEntry ) - 1096 pView->GetVisiblePos( pEntry )); 1097 long nY = 0; 1098 nY -= ( nOffs * nEntryHeight ); 1099 1100 DBG_ASSERT(pFirstDynamicTab,"No Tree!"); 1101 1102 Color aOldLineColor = pView->GetLineColor(); 1103 const StyleSettings& rStyleSettings = pView->GetSettings().GetStyleSettings(); 1104 Color aCol= rStyleSettings.GetFaceColor(); 1105 1106 if( aCol.IsRGBEqual( pView->GetBackground().GetColor()) ) 1107 aCol = rStyleSettings.GetShadowColor(); 1108 pView->SetLineColor( aCol ); 1109 Point aPos1, aPos2; 1110 sal_uInt16 nDistance; 1111 sal_uLong nMax = nVisibleCount + nOffs + 1; 1112 1113 const Image& rExpandedNodeBitmap = GetExpandedNodeBmp(); 1114 1115 for( sal_uLong n=0; n< nMax && pEntry; n++ ) 1116 { 1117 if( pView->IsExpanded(pEntry) ) 1118 { 1119 aPos1.X() = pView->GetTabPos(pEntry, pFirstDynamicTab); 1120 // wenn keine ContextBitmap, dann etwas nach rechts 1121 // unter den ersten Text (Node.Bmp ebenfalls 1122 if( !pView->nContextBmpWidthMax ) 1123 aPos1.X() += rExpandedNodeBitmap.GetSizePixel().Width() / 2; 1124 1125 aPos1.Y() = nY; 1126 aPos1.Y() += nEntryHeightDIV2; 1127 1128 pChild = pView->FirstChild( pEntry ); 1129 DBG_ASSERT(pChild,"Child?"); 1130 pChild = pTree->LastSibling( pChild ); 1131 nDistance = (sal_uInt16)(pView->GetVisiblePos(pChild) - 1132 pView->GetVisiblePos(pEntry)); 1133 aPos2 = aPos1; 1134 aPos2.Y() += nDistance * nEntryHeight; 1135 pView->DrawLine( aPos1, aPos2 ); 1136 } 1137 // Sichtbar im Control ? 1138 if( n>= nOffs && ((m_nStyle & WB_HASLINESATROOT) || !pTree->IsAtRootDepth(pEntry))) 1139 { 1140 // kann aPos1 recyclet werden ? 1141 if( !pView->IsExpanded(pEntry) ) 1142 { 1143 // njet 1144 aPos1.X() = pView->GetTabPos(pEntry, pFirstDynamicTab); 1145 // wenn keine ContextBitmap, dann etwas nach rechts 1146 // unter den ersten Text (Node.Bmp ebenfalls 1147 if( !pView->nContextBmpWidthMax ) 1148 aPos1.X() += rExpandedNodeBitmap.GetSizePixel().Width() / 2; 1149 aPos1.Y() = nY; 1150 aPos1.Y() += nEntryHeightDIV2; 1151 aPos2.X() = aPos1.X(); 1152 } 1153 aPos2.Y() = aPos1.Y(); 1154 aPos2.X() -= pView->GetIndent(); 1155 pView->DrawLine( aPos1, aPos2 ); 1156 } 1157 nY += nEntryHeight; 1158 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 1159 } 1160 if( m_nStyle & WB_HASLINESATROOT ) 1161 { 1162 pEntry = pView->First(); 1163 aPos1.X() = pView->GetTabPos( pEntry, pFirstDynamicTab); 1164 // wenn keine ContextBitmap, dann etwas nach rechts 1165 // unter den ersten Text (Node.Bmp ebenfalls 1166 if( !pView->nContextBmpWidthMax ) 1167 aPos1.X() += rExpandedNodeBitmap.GetSizePixel().Width() / 2; 1168 aPos1.X() -= pView->GetIndent(); 1169 aPos1.Y() = GetEntryLine( pEntry ); 1170 aPos1.Y() += nEntryHeightDIV2; 1171 pChild = pTree->LastSibling( pEntry ); 1172 aPos2.X() = aPos1.X(); 1173 aPos2.Y() = GetEntryLine( pChild ); 1174 aPos2.Y() += nEntryHeightDIV2; 1175 pView->DrawLine( aPos1, aPos2 ); 1176 } 1177 pView->SetLineColor( aOldLineColor ); 1178 } 1179 1180 1181 static long GetOptSize( TabBar* pTabBar ) 1182 { 1183 return pTabBar->CalcWindowSizePixel().Width(); 1184 } 1185 1186 void SvImpLBox::PositionScrollBars( Size& rSize, sal_uInt16 nMask ) 1187 { 1188 long nOverlap = 0; 1189 1190 Size aVerSize( nVerSBarWidth, rSize.Height() ); 1191 Size aHorSize( rSize.Width(), nHorSBarHeight ); 1192 long nTabBarWidth = 0; 1193 if( pTabBar ) 1194 { 1195 nTabBarWidth = GetOptSize( pTabBar ); 1196 long nMaxWidth = (rSize.Width() * 700) / 1000; 1197 if( nTabBarWidth > nMaxWidth ) 1198 { 1199 nTabBarWidth = nMaxWidth; 1200 pTabBar->SetStyle( pTabBar->GetStyle() | WB_MINSCROLL ); 1201 } 1202 else 1203 { 1204 WinBits nStyle = pTabBar->GetStyle(); 1205 nStyle &= ~(WB_MINSCROLL); 1206 pTabBar->SetStyle( nStyle ); 1207 } 1208 aHorSize.Width() -= nTabBarWidth; 1209 Size aTabSize( pTabBar->GetSizePixel() ); 1210 aTabSize.Width() = nTabBarWidth; 1211 pTabBar->SetSizePixel( aTabSize ); 1212 } 1213 if( nMask & 0x0001 ) 1214 aHorSize.Width() -= nVerSBarWidth; 1215 if( nMask & 0x0002 ) 1216 aVerSize.Height() -= nHorSBarHeight; 1217 1218 aVerSize.Height() += 2 * nOverlap; 1219 Point aVerPos( rSize.Width() - aVerSize.Width() + nOverlap, -nOverlap ); 1220 aVerSBar.SetPosSizePixel( aVerPos, aVerSize ); 1221 1222 aHorSize.Width() += 2 * nOverlap; 1223 Point aHorPos( -nOverlap, rSize.Height() - aHorSize.Height() + nOverlap ); 1224 if( pTabBar ) 1225 pTabBar->SetPosPixel( aHorPos ); 1226 aHorPos.X() += nTabBarWidth; 1227 aHorSBar.SetPosSizePixel( aHorPos, aHorSize ); 1228 1229 if( nMask & 0x0001 ) 1230 rSize.Width() = aVerPos.X(); 1231 if( nMask & 0x0002 ) 1232 rSize.Height() = aHorPos.Y(); 1233 if( pTabBar ) 1234 pTabBar->Show(); 1235 1236 if( (nMask & (0x0001|0x0002)) == (0x0001|0x0002) ) 1237 aScrBarBox.Show(); 1238 else 1239 aScrBarBox.Hide(); 1240 1241 } 1242 1243 // nResult: Bit0 == VerSBar Bit1 == HorSBar 1244 sal_uInt16 SvImpLBox::AdjustScrollBars( Size& rSize ) 1245 { 1246 long nEntryHeight = pView->GetEntryHeight(); 1247 if( !nEntryHeight ) 1248 return 0; 1249 1250 sal_uInt16 nResult = 0; 1251 1252 Size aOSize( pView->Control::GetOutputSizePixel() ); 1253 1254 const WinBits nWindowStyle = pView->GetStyle(); 1255 sal_Bool bVerSBar = ( nWindowStyle & WB_VSCROLL ) != 0; 1256 sal_Bool bHorBar = sal_False; 1257 long nMaxRight = aOSize.Width(); //GetOutputSize().Width(); 1258 Point aOrigin( pView->GetMapMode().GetOrigin() ); 1259 aOrigin.X() *= -1; 1260 nMaxRight += aOrigin.X() - 1; 1261 long nVis = nMostRight - aOrigin.X(); 1262 if( pTabBar || ( 1263 (nWindowStyle & WB_HSCROLL) && 1264 (nVis < nMostRight || nMaxRight < nMostRight) )) 1265 bHorBar = sal_True; 1266 1267 // Anzahl aller nicht eingeklappten Eintraege 1268 sal_uLong nTotalCount = pView->GetVisibleCount(); 1269 1270 // Anzahl in der View sichtbarer Eintraege 1271 nVisibleCount = aOSize.Height() / nEntryHeight; 1272 1273 // muessen wir eine vertikale Scrollbar einblenden? 1274 if( bVerSBar || nTotalCount > nVisibleCount ) 1275 { 1276 nResult = 1; 1277 nFlags |= F_HOR_SBARSIZE_WITH_VBAR; 1278 nMaxRight -= nVerSBarWidth; 1279 if( !bHorBar ) 1280 { 1281 if( (nWindowStyle & WB_HSCROLL) && 1282 (nVis < nMostRight || nMaxRight < nMostRight) ) 1283 bHorBar = sal_True; 1284 } 1285 } 1286 1287 // muessen wir eine horizontale Scrollbar einblenden? 1288 if( bHorBar ) 1289 { 1290 nResult |= 0x0002; 1291 // die Anzahl der in der View sichtbaren Eintraege 1292 // muss neu berechnet werden, da die horizontale 1293 // ScrollBar eingeblendet wird 1294 nVisibleCount = (aOSize.Height() - nHorSBarHeight) / nEntryHeight; 1295 // eventuell brauchen wir jetzt doch eine vertikale ScrollBar 1296 if( !(nResult & 0x0001) && 1297 ((nTotalCount > nVisibleCount) || bVerSBar) ) 1298 { 1299 nResult = 3; 1300 nFlags |= F_VER_SBARSIZE_WITH_HBAR; 1301 } 1302 } 1303 1304 PositionScrollBars( aOSize, nResult ); 1305 1306 // Range, VisibleRange usw. anpassen 1307 1308 // Output-Size aktualisieren, falls wir scrollen muessen 1309 Rectangle aRect; 1310 aRect.SetSize( aOSize ); 1311 aSelEng.SetVisibleArea( aRect ); 1312 1313 // Vertikale ScrollBar 1314 long nTemp = (long)nVisibleCount; 1315 nTemp--; 1316 if( nTemp != aVerSBar.GetVisibleSize() ) 1317 { 1318 if( !bInVScrollHdl ) 1319 { 1320 aVerSBar.SetPageSize( nTemp - 1 ); 1321 aVerSBar.SetVisibleSize( nTemp ); 1322 } 1323 else 1324 { 1325 nFlags |= F_ENDSCROLL_SET_VIS_SIZE; 1326 nNextVerVisSize = nTemp; 1327 } 1328 } 1329 1330 // Horizontale ScrollBar 1331 nTemp = aHorSBar.GetThumbPos(); 1332 aHorSBar.SetVisibleSize( aOSize.Width() ); 1333 long nNewThumbPos = aHorSBar.GetThumbPos(); 1334 Range aRange( aHorSBar.GetRange() ); 1335 if( aRange.Max() < nMostRight+25 ) 1336 { 1337 aRange.Max() = nMostRight+25; 1338 aHorSBar.SetRange( aRange ); 1339 } 1340 1341 if( nTemp != nNewThumbPos ) 1342 { 1343 nTemp = nNewThumbPos - nTemp; 1344 if( pView->IsEditingActive() ) 1345 { 1346 pView->EndEditing( sal_True ); // Cancel 1347 pView->Update(); 1348 } 1349 pView->nFocusWidth = -1; 1350 KeyLeftRight( nTemp ); 1351 } 1352 1353 if( nResult & 0x0001 ) 1354 aVerSBar.Show(); 1355 else 1356 aVerSBar.Hide(); 1357 1358 if( nResult & 0x0002 ) 1359 aHorSBar.Show(); 1360 else 1361 { 1362 if( !pTabBar ) 1363 aHorSBar.Hide(); 1364 } 1365 rSize = aOSize; 1366 return nResult; 1367 } 1368 1369 void SvImpLBox::InitScrollBarBox() 1370 { 1371 aScrBarBox.SetSizePixel( Size(nVerSBarWidth, nHorSBarHeight) ); 1372 Size aSize( pView->Control::GetOutputSizePixel() ); 1373 aScrBarBox.SetPosPixel( Point(aSize.Width()-nVerSBarWidth, aSize.Height()-nHorSBarHeight)); 1374 } 1375 1376 void SvImpLBox::Resize() 1377 { 1378 Size aSize( pView->Control::GetOutputSizePixel()); 1379 if( aSize.Width() <= 0 || aSize.Height() <= 0 ) 1380 return; 1381 nFlags |= F_IN_RESIZE; 1382 InitScrollBarBox(); 1383 1384 if( pView->GetEntryHeight()) 1385 { 1386 AdjustScrollBars( aOutputSize ); 1387 FillView(); 1388 } 1389 // !!!HACK, da in Floating- & Docking-Windows nach Resizes 1390 // die Scrollbars nicht richtig, bzw. ueberhaupt nicht gezeichnet werden 1391 if( aHorSBar.IsVisible()) 1392 aHorSBar.Invalidate(); 1393 if( aVerSBar.IsVisible()) 1394 aVerSBar.Invalidate(); 1395 nFlags &= (~(F_IN_RESIZE | F_PAINTED)); 1396 } 1397 1398 void SvImpLBox::FillView() 1399 { 1400 if( !pStartEntry ) 1401 { 1402 sal_uInt16 nVisibleViewCount = (sal_uInt16)(pView->GetVisibleCount()); 1403 sal_uInt16 nTempThumb = (sal_uInt16)aVerSBar.GetThumbPos(); 1404 if( nTempThumb >= nVisibleViewCount ) 1405 nTempThumb = nVisibleViewCount - 1; 1406 pStartEntry = (SvLBoxEntry*)(pView->GetEntryAtVisPos(nTempThumb)); 1407 } 1408 if( pStartEntry ) 1409 { 1410 sal_uInt16 nLast = (sal_uInt16)(pView->GetVisiblePos( (SvLBoxEntry*)(pView->LastVisible()))); 1411 sal_uInt16 nThumb = (sal_uInt16)(pView->GetVisiblePos( pStartEntry )); 1412 sal_uInt16 nCurDispEntries = nLast-nThumb+1; 1413 if( nCurDispEntries < nVisibleCount ) 1414 { 1415 ShowCursor( sal_False ); 1416 // Fenster fuellen, indem der Thumb schrittweise 1417 // nach oben bewegt wird 1418 sal_Bool bFound = sal_False; 1419 SvLBoxEntry* pTemp = pStartEntry; 1420 while( nCurDispEntries < nVisibleCount && pTemp ) 1421 { 1422 pTemp = (SvLBoxEntry*)(pView->PrevVisible(pStartEntry)); 1423 if( pTemp ) 1424 { 1425 nThumb--; 1426 pStartEntry = pTemp; 1427 nCurDispEntries++; 1428 bFound = sal_True; 1429 } 1430 } 1431 if( bFound ) 1432 { 1433 aVerSBar.SetThumbPos( nThumb ); 1434 ShowCursor( sal_True ); // Focusrect neu berechnen 1435 pView->Invalidate(); 1436 } 1437 } 1438 } 1439 } 1440 1441 1442 1443 1444 void SvImpLBox::ShowVerSBar() 1445 { 1446 sal_Bool bVerBar = ( pView->GetStyle() & WB_VSCROLL ) != 0; 1447 sal_uLong nVis = 0; 1448 if( !bVerBar ) 1449 nVis = pView->GetVisibleCount(); 1450 if( bVerBar || (nVisibleCount && nVis > (sal_uLong)(nVisibleCount-1)) ) 1451 { 1452 if( !aVerSBar.IsVisible() ) 1453 { 1454 pView->nFocusWidth = -1; 1455 AdjustScrollBars( aOutputSize ); 1456 if( GetUpdateMode() ) 1457 aVerSBar.Update(); 1458 } 1459 } 1460 else 1461 { 1462 if( aVerSBar.IsVisible() ) 1463 { 1464 pView->nFocusWidth = -1; 1465 AdjustScrollBars( aOutputSize ); 1466 } 1467 } 1468 1469 long nMaxRight = GetOutputSize().Width(); 1470 Point aPos( pView->GetMapMode().GetOrigin() ); 1471 aPos.X() *= -1; // Umrechnung Dokumentkoord. 1472 nMaxRight = nMaxRight + aPos.X() - 1; 1473 if( nMaxRight < nMostRight ) 1474 { 1475 if( !aHorSBar.IsVisible() ) 1476 { 1477 pView->nFocusWidth = -1; 1478 AdjustScrollBars( aOutputSize ); 1479 if( GetUpdateMode() ) 1480 aHorSBar.Update(); 1481 } 1482 else 1483 { 1484 Range aRange( aHorSBar.GetRange() ); 1485 if( aRange.Max() < nMostRight+25 ) 1486 { 1487 aRange.Max() = nMostRight+25; 1488 aHorSBar.SetRange( aRange ); 1489 } 1490 else 1491 { 1492 pView->nFocusWidth = -1; 1493 AdjustScrollBars( aOutputSize ); 1494 } 1495 } 1496 } 1497 else 1498 { 1499 if( aHorSBar.IsVisible() ) 1500 { 1501 pView->nFocusWidth = -1; 1502 AdjustScrollBars( aOutputSize ); 1503 } 1504 } 1505 } 1506 1507 1508 void SvImpLBox::SyncVerThumb() 1509 { 1510 if( pStartEntry ) 1511 { 1512 long nEntryPos = pView->GetVisiblePos( pStartEntry ); 1513 aVerSBar.SetThumbPos( nEntryPos ); 1514 } 1515 else 1516 aVerSBar.SetThumbPos( 0 ); 1517 } 1518 1519 sal_Bool SvImpLBox::IsEntryInView( SvLBoxEntry* pEntry ) const 1520 { 1521 // Parent eingeklappt 1522 if( !pView->IsEntryVisible(pEntry) ) 1523 return sal_False; 1524 long nY = GetEntryLine( pEntry ); 1525 if( nY < 0 ) 1526 return sal_False; 1527 long nMax = nVisibleCount * pView->GetEntryHeight(); 1528 if( nY >= nMax ) 1529 return sal_False; 1530 return sal_True; 1531 } 1532 1533 1534 long SvImpLBox::GetEntryLine( SvLBoxEntry* pEntry ) const 1535 { 1536 if(!pStartEntry ) 1537 return -1; // unsichtbare Position 1538 1539 long nFirstVisPos = pView->GetVisiblePos( pStartEntry ); 1540 long nEntryVisPos = pView->GetVisiblePos( pEntry ); 1541 nFirstVisPos = nEntryVisPos - nFirstVisPos; 1542 nFirstVisPos *= pView->GetEntryHeight(); 1543 return nFirstVisPos; 1544 } 1545 1546 void SvImpLBox::SetEntryHeight( short /* nHeight */ ) 1547 { 1548 SetNodeBmpYOffset( GetExpandedNodeBmp() ); 1549 SetNodeBmpYOffset( GetCollapsedNodeBmp() ); 1550 if(!pView->HasViewData()) // stehen wir im Clear? 1551 { 1552 Size aSize = pView->Control::GetOutputSizePixel(); 1553 AdjustScrollBars( aSize ); 1554 } 1555 else 1556 { 1557 Resize(); 1558 if( GetUpdateMode() ) 1559 pView->Invalidate(); 1560 } 1561 } 1562 1563 1564 1565 // *********************************************************************** 1566 // Callback-Functions 1567 // *********************************************************************** 1568 1569 void SvImpLBox::IndentChanged( short /* nIndentPixel */ ) {} 1570 1571 void SvImpLBox::EntryExpanded( SvLBoxEntry* pEntry ) 1572 { 1573 // SelAllDestrAnch( sal_False, sal_True ); //DeselectAll(); 1574 if( GetUpdateMode() ) 1575 { 1576 ShowCursor( sal_False ); 1577 long nY = GetEntryLine( pEntry ); 1578 if( IsLineVisible(nY) ) 1579 { 1580 InvalidateEntriesFrom( nY ); 1581 FindMostRight( pEntry, 0 ); 1582 } 1583 aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1 ) ); 1584 // falls vor dem Thumb expandiert wurde, muss 1585 // die Thumb-Position korrigiert werden. 1586 SyncVerThumb(); 1587 ShowVerSBar(); 1588 ShowCursor( sal_True ); 1589 } 1590 } 1591 1592 void SvImpLBox::EntryCollapsed( SvLBoxEntry* pEntry ) 1593 { 1594 if( !pView->IsEntryVisible( pEntry ) ) 1595 return; 1596 1597 ShowCursor( sal_False ); 1598 1599 if( !pMostRightEntry || pTree->IsChild( pEntry,pMostRightEntry ) ) 1600 { 1601 FindMostRight(0); 1602 } 1603 1604 if( pStartEntry ) 1605 { 1606 long nOldThumbPos = aVerSBar.GetThumbPos(); 1607 sal_uLong nVisList = pView->GetVisibleCount(); 1608 aVerSBar.SetRange( Range(0, nVisList-1) ); 1609 long nNewThumbPos = aVerSBar.GetThumbPos(); 1610 if( nNewThumbPos != nOldThumbPos ) 1611 { 1612 pStartEntry = pView->First(); 1613 sal_uInt16 nDistance = (sal_uInt16)nNewThumbPos; 1614 if( nDistance ) 1615 pStartEntry = (SvLBoxEntry*)(pView->NextVisible( pStartEntry, 1616 nDistance)); 1617 if( GetUpdateMode() ) 1618 pView->Invalidate(); 1619 } 1620 else 1621 SyncVerThumb(); 1622 ShowVerSBar(); 1623 } 1624 // wurde Cursor eingeklappt ? 1625 if( pTree->IsChild( pEntry, pCursor ) ) 1626 SetCursor( pEntry ); 1627 if( GetUpdateMode() ) 1628 ShowVerSBar(); 1629 ShowCursor( sal_True ); 1630 if( GetUpdateMode() && pCursor ) 1631 pView->Select( pCursor, sal_True ); 1632 } 1633 1634 void SvImpLBox::CollapsingEntry( SvLBoxEntry* pEntry ) 1635 { 1636 if( !pView->IsEntryVisible( pEntry ) || !pStartEntry ) 1637 return; 1638 1639 SelAllDestrAnch( sal_False, sal_True ); // deselectall 1640 1641 // ist der eingeklappte Parent sichtbar ? 1642 long nY = GetEntryLine( pEntry ); 1643 if( IsLineVisible(nY) ) 1644 { 1645 if( GetUpdateMode() ) 1646 InvalidateEntriesFrom( nY ); 1647 } 1648 else 1649 { 1650 if( pTree->IsChild(pEntry, pStartEntry) ) 1651 { 1652 pStartEntry = pEntry; 1653 if( GetUpdateMode() ) 1654 pView->Invalidate(); 1655 } 1656 } 1657 } 1658 1659 1660 void SvImpLBox::SetNodeBmpYOffset( const Image& rBmp ) 1661 { 1662 Size aSize; 1663 nYoffsNodeBmp = pView->GetHeightOffset( rBmp, aSize ); 1664 nNodeBmpWidth = aSize.Width(); 1665 } 1666 1667 void SvImpLBox::SetNodeBmpTabDistance() 1668 { 1669 nNodeBmpTabDistance = -pView->GetIndent(); 1670 if( pView->nContextBmpWidthMax ) 1671 { 1672 // nur, wenn der erste dynamische Tab zentriert ist 1673 // (setze ich momentan voraus) 1674 Size aSize = GetExpandedNodeBmp().GetSizePixel(); 1675 nNodeBmpTabDistance -= aSize.Width() / 2; 1676 } 1677 } 1678 1679 // 1680 // korrigiert bei SingleSelection den Cursor 1681 // 1682 void SvImpLBox::EntrySelected( SvLBoxEntry* pEntry, sal_Bool bSelect ) 1683 { 1684 if( nFlags & F_IGNORE_SELECT ) 1685 return; 1686 1687 /* 1688 if( (m_nStyle & WB_HIDESELECTION) && pEntry && !pView->HasFocus() ) 1689 { 1690 SvViewData* pViewData = pView->GetViewData( pEntry ); 1691 pViewData->SetCursored( bSelect ); 1692 } 1693 */ 1694 1695 nFlags &= (~F_DESEL_ALL); 1696 if( bSelect && 1697 aSelEng.GetSelectionMode() == SINGLE_SELECTION && 1698 pEntry != pCursor ) 1699 { 1700 SetCursor( pEntry ); 1701 DBG_ASSERT(pView->GetSelectionCount()==1,"selection count?"); 1702 } 1703 1704 if( GetUpdateMode() && pView->IsEntryVisible(pEntry) ) 1705 { 1706 long nY = GetEntryLine( pEntry ); 1707 if( IsLineVisible( nY ) ) 1708 { 1709 ShowCursor( sal_False ); 1710 pView->PaintEntry1( pEntry, nY, 0xffff ); // wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION ); 1711 ShowCursor( sal_True ); 1712 } 1713 } 1714 } 1715 1716 1717 void SvImpLBox::RemovingEntry( SvLBoxEntry* pEntry ) 1718 { 1719 //IAccessibility2 Implementation 2009----- 1720 CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED , pEntry ); 1721 //-----IAccessibility2 Implementation 2009 1722 1723 DestroyAnchor(); 1724 1725 if( !pView->IsEntryVisible( pEntry ) ) 1726 { 1727 // wenn Parent eingeklappt, dann tschuess 1728 nFlags |= F_REMOVED_ENTRY_INVISIBLE; 1729 return; 1730 } 1731 1732 if( pEntry == pMostRightEntry || ( 1733 pEntry->HasChilds() && pView->IsExpanded(pEntry) && 1734 pTree->IsChild(pEntry, pMostRightEntry))) 1735 { 1736 nFlags |= F_REMOVED_RECALC_MOST_RIGHT; 1737 } 1738 1739 SvLBoxEntry* pOldStartEntry = pStartEntry; 1740 1741 SvLBoxEntry* pParent = (SvLBoxEntry*)(pView->GetModel()->GetParent(pEntry)); 1742 1743 if( pParent && pView->GetModel()->GetChildList(pParent)->Count() == 1 ) 1744 { 1745 DBG_ASSERT( pView->IsExpanded( pParent ), "Parent not expanded"); 1746 pParent->SetFlags( pParent->GetFlags() | SV_ENTRYFLAG_NO_NODEBMP); 1747 InvalidateEntry( pParent ); 1748 } 1749 1750 if( pCursor && pTree->IsChild( pEntry, pCursor) ) 1751 pCursor = pEntry; 1752 if( pStartEntry && pTree->IsChild(pEntry,pStartEntry) ) 1753 pStartEntry = pEntry; 1754 1755 SvLBoxEntry* pTemp; 1756 if( pCursor && pCursor == pEntry ) 1757 { 1758 if( bSimpleTravel ) 1759 pView->Select( pCursor, sal_False ); 1760 ShowCursor( sal_False ); // Focus-Rect weg 1761 // NextSibling, weil auch Childs des Cursors geloescht werden 1762 pTemp = pView->NextSibling( pCursor ); 1763 if( !pTemp ) 1764 pTemp = (SvLBoxEntry*)(pView->PrevVisible( pCursor )); 1765 1766 SetCursor( pTemp, sal_True ); 1767 } 1768 if( pStartEntry && pStartEntry == pEntry ) 1769 { 1770 pTemp = pView->NextSibling( pStartEntry ); 1771 if( !pTemp ) 1772 pTemp = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry )); 1773 pStartEntry = pTemp; 1774 } 1775 if( GetUpdateMode()) 1776 { 1777 // wenns der letzte ist, muss invalidiert werden, damit die Linien 1778 // richtig gezeichnet (in diesem Fall geloescht) werden. 1779 if( pStartEntry && (pStartEntry != pOldStartEntry || pEntry == (SvLBoxEntry*)pView->GetModel()->Last()) ) 1780 { 1781 aVerSBar.SetThumbPos( pView->GetVisiblePos( pStartEntry )); 1782 pView->Invalidate( GetVisibleArea() ); 1783 } 1784 else 1785 InvalidateEntriesFrom( GetEntryLine( pEntry ) ); 1786 } 1787 } 1788 1789 void SvImpLBox::EntryRemoved() 1790 { 1791 if( nFlags & F_REMOVED_ENTRY_INVISIBLE ) 1792 { 1793 nFlags &= (~F_REMOVED_ENTRY_INVISIBLE); 1794 return; 1795 } 1796 if( !pStartEntry ) 1797 pStartEntry = pTree->First(); 1798 if( !pCursor ) 1799 SetCursor( pStartEntry, sal_True ); 1800 1801 if( pCursor && (bSimpleTravel || !pView->GetSelectionCount() )) 1802 pView->Select( pCursor, sal_True ); 1803 1804 if( GetUpdateMode()) 1805 { 1806 if( nFlags & F_REMOVED_RECALC_MOST_RIGHT ) 1807 FindMostRight(0); 1808 aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1 ) ); 1809 FillView(); 1810 if( pStartEntry ) 1811 // falls ueber dem Thumb geloescht wurde 1812 aVerSBar.SetThumbPos( pView->GetVisiblePos( pStartEntry) ); 1813 1814 ShowVerSBar(); 1815 if( pCursor && pView->HasFocus() && !pView->IsSelected(pCursor) ) 1816 { 1817 if( pView->GetSelectionCount() ) 1818 { 1819 // ist ein benachbarter Eintrag selektiert? 1820 SvLBoxEntry* pNextCursor = (SvLBoxEntry*)pView->PrevVisible( pCursor ); 1821 if( !pNextCursor || !pView->IsSelected( pNextCursor )) 1822 pNextCursor = (SvLBoxEntry*)pView->NextVisible( pCursor ); 1823 if( !pNextCursor || !pView->IsSelected( pNextCursor )) 1824 // kein Nachbar selektiert: Ersten selektierten nehmen 1825 pNextCursor = pView->FirstSelected(); 1826 SetCursor( pNextCursor ); 1827 MakeVisible( pCursor ); 1828 } 1829 else 1830 pView->Select( pCursor, sal_True ); 1831 } 1832 ShowCursor( sal_True ); 1833 } 1834 nFlags &= (~F_REMOVED_RECALC_MOST_RIGHT); 1835 } 1836 1837 1838 void SvImpLBox::MovingEntry( SvLBoxEntry* pEntry ) 1839 { 1840 int bDeselAll = nFlags & F_DESEL_ALL; 1841 SelAllDestrAnch( sal_False, sal_True ); // DeselectAll(); 1842 if( !bDeselAll ) 1843 nFlags &= (~F_DESEL_ALL); 1844 1845 if( pEntry == pCursor ) 1846 ShowCursor( sal_False ); 1847 if( IsEntryInView( pEntry ) ) 1848 pView->Invalidate(); 1849 if( pEntry == pStartEntry ) 1850 { 1851 SvLBoxEntry* pNew = 0; 1852 if( !pEntry->HasChilds() ) 1853 { 1854 pNew = (SvLBoxEntry*)(pView->NextVisible( pStartEntry )); 1855 if( !pNew ) 1856 pNew = (SvLBoxEntry*)(pView->PrevVisible( pStartEntry )); 1857 } 1858 else 1859 { 1860 pNew = pTree->NextSibling( pEntry ); 1861 if( !pNew ) 1862 pNew = pTree->PrevSibling( pEntry ); 1863 } 1864 pStartEntry = pNew; 1865 } 1866 } 1867 1868 void SvImpLBox::EntryMoved( SvLBoxEntry* pEntry ) 1869 { 1870 // #97680# -------------- 1871 UpdateContextBmpWidthVectorFromMovedEntry( pEntry ); 1872 1873 if ( !pStartEntry ) 1874 // this might happen if the only entry in the view is moved to its very same position 1875 // #i97346# 1876 pStartEntry = pView->First(); 1877 1878 aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1)); 1879 sal_uInt16 nFirstPos = (sal_uInt16)pTree->GetAbsPos( pStartEntry ); 1880 sal_uInt16 nNewPos = (sal_uInt16)pTree->GetAbsPos( pEntry ); 1881 FindMostRight(0); 1882 if( nNewPos < nFirstPos ) //!!!Notloesung 1883 pStartEntry = pEntry; 1884 // #97702# --------------- 1885 SyncVerThumb(); 1886 if( pEntry == pCursor ) 1887 { 1888 if( pView->IsEntryVisible( pCursor ) ) 1889 ShowCursor( sal_True ); 1890 else 1891 { 1892 SvLBoxEntry* pParent = pEntry; 1893 do { 1894 pParent = pTree->GetParent( pParent ); 1895 } 1896 while( !pView->IsEntryVisible( pParent ) ); 1897 SetCursor( pParent ); 1898 } 1899 } 1900 if( IsEntryInView( pEntry ) ) 1901 pView->Invalidate(); 1902 } 1903 1904 1905 1906 void SvImpLBox::EntryInserted( SvLBoxEntry* pEntry ) 1907 { 1908 if( GetUpdateMode() ) 1909 { 1910 SvLBoxEntry* pParent = (SvLBoxEntry*)pTree->GetParent(pEntry); 1911 if( pParent && pTree->GetChildList(pParent)->Count() == 1 ) 1912 // Pluszeichen zeichnen 1913 pTree->InvalidateEntry( pParent ); 1914 1915 if( !pView->IsEntryVisible( pEntry ) ) 1916 return; 1917 int bDeselAll = nFlags & F_DESEL_ALL; 1918 if( bDeselAll ) 1919 SelAllDestrAnch( sal_False, sal_True ); 1920 else 1921 DestroyAnchor(); 1922 // nFlags &= (~F_DESEL_ALL); 1923 // ShowCursor( sal_False ); // falls sich Cursor nach unten verschiebt 1924 long nY = GetEntryLine( pEntry ); 1925 sal_Bool bEntryVisible = IsLineVisible( nY ); 1926 if( bEntryVisible ) 1927 { 1928 ShowCursor( sal_False ); // falls sich Cursor nach unten verschiebt 1929 nY -= pView->GetEntryHeight(); // wg. Linien 1930 InvalidateEntriesFrom( nY ); 1931 } 1932 else if( pStartEntry && nY < GetEntryLine(pStartEntry) ) 1933 { 1934 // pruefen, ob die View komplett gefuellt ist. Wenn 1935 // nicht, dann pStartEntry und den Cursor anpassen 1936 // (automatisches scrollen) 1937 sal_uInt16 nLast = (sal_uInt16)(pView->GetVisiblePos( (SvLBoxEntry*)(pView->LastVisible()))); 1938 sal_uInt16 nThumb = (sal_uInt16)(pView->GetVisiblePos( pStartEntry )); 1939 sal_uInt16 nCurDispEntries = nLast-nThumb+1; 1940 if( nCurDispEntries < nVisibleCount ) 1941 { 1942 // beim naechsten Paint-Event setzen 1943 pStartEntry = 0; 1944 SetCursor( 0 ); 1945 pView->Invalidate(); 1946 } 1947 } 1948 else if( !pStartEntry ) 1949 pView->Invalidate(); 1950 1951 // die Linien invalidieren 1952 /* 1953 if( (bEntryVisible || bPrevEntryVisible) && 1954 (m_nStyle & ( WB_HASLINES | WB_HASLINESATROOT )) ) 1955 { 1956 SvLBoxTab* pTab = pView->GetFirstDynamicTab(); 1957 if( pTab ) 1958 { 1959 long nDX = pView->GetTabPos( pEntry, pTab ); 1960 Point aTmpPoint; 1961 Size aSize( nDX, nY ); 1962 Rectangle aRect( aTmpPoint, aSize ); 1963 pView->Invalidate( aRect ); 1964 } 1965 } 1966 */ 1967 1968 SetMostRight( pEntry ); 1969 aVerSBar.SetRange( Range(0, pView->GetVisibleCount()-1)); 1970 SyncVerThumb(); // falls vor Thumb eingefuegt wurde 1971 ShowVerSBar(); 1972 ShowCursor( sal_True ); 1973 if( pStartEntry != pView->First() && (nFlags & F_FILLING) ) 1974 pView->Update(); 1975 } 1976 } 1977 1978 1979 1980 // ******************************************************************** 1981 // Eventhandler 1982 // ******************************************************************** 1983 1984 1985 // ****** Steuerung der Controlanimation 1986 1987 sal_Bool SvImpLBox::ButtonDownCheckCtrl(const MouseEvent& rMEvt, SvLBoxEntry* pEntry, 1988 long nY ) 1989 { 1990 SvLBoxItem* pItem = pView->GetItem(pEntry,rMEvt.GetPosPixel().X(),&pActiveTab); 1991 if( pItem && (pItem->IsA()==SV_ITEM_ID_LBOXBUTTON)) 1992 { 1993 pActiveButton = (SvLBoxButton*)pItem; 1994 pActiveEntry = pEntry; 1995 if( pCursor == pActiveEntry ) 1996 pView->HideFocus(); 1997 pView->CaptureMouse(); 1998 pActiveButton->SetStateHilighted( sal_True ); 1999 pView->PaintEntry1( pActiveEntry, nY, 2000 SV_LBOXTAB_PUSHABLE | SV_LBOXTAB_ADJUST_CENTER | 2001 SV_LBOXTAB_ADJUST_RIGHT ); 2002 return sal_True; 2003 } 2004 else 2005 pActiveButton = 0; 2006 return sal_False; 2007 } 2008 2009 sal_Bool SvImpLBox::MouseMoveCheckCtrl( const MouseEvent& rMEvt, SvLBoxEntry* pEntry) 2010 { 2011 if( pActiveButton ) 2012 { 2013 long nY; 2014 long nMouseX = rMEvt.GetPosPixel().X(); 2015 if( pEntry == pActiveEntry && 2016 pView->GetItem(pActiveEntry, nMouseX) == pActiveButton ) 2017 { 2018 if( !pActiveButton->IsStateHilighted() ) 2019 { 2020 pActiveButton->SetStateHilighted(sal_True ); 2021 nY = GetEntryLine( pActiveEntry ); 2022 pView->PaintEntry1( pActiveEntry, nY, 2023 SV_LBOXTAB_PUSHABLE | SV_LBOXTAB_ADJUST_CENTER | 2024 SV_LBOXTAB_ADJUST_RIGHT ); 2025 } 2026 } 2027 else 2028 { 2029 if( pActiveButton->IsStateHilighted() ) 2030 { 2031 pActiveButton->SetStateHilighted(sal_False ); 2032 nY = GetEntryLine( pActiveEntry ); 2033 pView->PaintEntry1( pActiveEntry, nY, SV_LBOXTAB_PUSHABLE ); 2034 } 2035 } 2036 return sal_True; 2037 } 2038 return sal_False; 2039 } 2040 2041 sal_Bool SvImpLBox::ButtonUpCheckCtrl( const MouseEvent& rMEvt ) 2042 { 2043 if( pActiveButton ) 2044 { 2045 pView->ReleaseMouse(); 2046 SvLBoxEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() ); 2047 long nY = GetEntryLine( pActiveEntry ); 2048 pActiveButton->SetStateHilighted( sal_False ); 2049 long nMouseX = rMEvt.GetPosPixel().X(); 2050 if( pEntry == pActiveEntry && 2051 pView->GetItem( pActiveEntry, nMouseX ) == pActiveButton ) 2052 pActiveButton->ClickHdl( pView, pActiveEntry ); 2053 pView->PaintEntry1( pActiveEntry, nY, 2054 SV_LBOXTAB_PUSHABLE | SV_LBOXTAB_ADJUST_CENTER | 2055 SV_LBOXTAB_ADJUST_RIGHT ); 2056 if( pCursor == pActiveEntry ) 2057 ShowCursor( sal_True ); 2058 pActiveButton = 0; 2059 pActiveEntry = 0; 2060 pActiveTab = 0; 2061 return sal_True; 2062 } 2063 return sal_False; 2064 } 2065 2066 // ******* Steuerung Plus/Minus-Button zum Expandieren/Kollabieren 2067 2068 // sal_False == kein Expand/Collapse-Button getroffen 2069 sal_Bool SvImpLBox::IsNodeButton( const Point& rPosPixel, SvLBoxEntry* pEntry ) const 2070 { 2071 if( !pEntry->HasChilds() && !pEntry->HasChildsOnDemand() ) 2072 return sal_False; 2073 2074 SvLBoxTab* pFirstDynamicTab = pView->GetFirstDynamicTab(); 2075 if( !pFirstDynamicTab ) 2076 return sal_False; 2077 2078 long nMouseX = rPosPixel.X(); 2079 // in Doc-Koords umrechnen 2080 Point aOrigin( pView->GetMapMode().GetOrigin() ); 2081 nMouseX -= aOrigin.X(); 2082 2083 long nX = pView->GetTabPos( pEntry, pFirstDynamicTab); 2084 nX += nNodeBmpTabDistance; 2085 if( nMouseX < nX ) 2086 return sal_False; 2087 nX += nNodeBmpWidth; 2088 if( nMouseX > nX ) 2089 return sal_False; 2090 return sal_True; 2091 } 2092 2093 // sal_False == hit no node button 2094 sal_Bool SvImpLBox::ButtonDownCheckExpand( const MouseEvent& rMEvt, SvLBoxEntry* pEntry, long /* nY */ ) 2095 { 2096 sal_Bool bRet = sal_False; 2097 2098 if ( pView->IsEditingActive() && pEntry == pView->pEdEntry ) 2099 // inplace editing -> nothing to do 2100 bRet = sal_True; 2101 else if ( IsNodeButton( rMEvt.GetPosPixel(), pEntry ) ) 2102 { 2103 if ( pView->IsExpanded( pEntry ) ) 2104 { 2105 pView->EndEditing( sal_True ); 2106 pView->Collapse( pEntry ); 2107 } 2108 else 2109 { 2110 // you can expand an entry, which is in editing 2111 pView->Expand( pEntry ); 2112 } 2113 bRet = sal_True; 2114 } 2115 2116 return bRet; 2117 } 2118 2119 void SvImpLBox::MouseButtonDown( const MouseEvent& rMEvt ) 2120 { 2121 if ( !rMEvt.IsLeft() && !rMEvt.IsRight()) 2122 return; 2123 2124 #ifdef OS2 2125 // unter OS/2 kommt zwischen MouseButtonDown und 2126 // MouseButtonUp ein MouseMove 2127 nFlags |= F_IGNORE_NEXT_MOUSEMOVE; 2128 #endif 2129 aEditTimer.Stop(); 2130 Point aPos( rMEvt.GetPosPixel()); 2131 2132 if( aPos.X() > aOutputSize.Width() || aPos.Y() > aOutputSize.Height() ) 2133 return; 2134 2135 SvLBoxEntry* pEntry = GetEntry( aPos ); 2136 if ( pEntry != pCursor ) 2137 // new entry selected -> reset current tab position to first tab 2138 nCurTabPos = FIRST_ENTRY_TAB; 2139 nFlags &= (~F_FILLING); 2140 pView->GrabFocus(); 2141 // #120417# the entry can still be invalid! 2142 if( !pEntry || !pView->GetViewData( pEntry )) 2143 return; 2144 2145 long nY = GetEntryLine( pEntry ); 2146 // Node-Button? 2147 if( ButtonDownCheckExpand( rMEvt, pEntry, nY ) ) 2148 return; 2149 2150 if( !EntryReallyHit(pEntry,aPos,nY)) 2151 return; 2152 2153 SvLBoxItem* pXItem = pView->GetItem( pEntry, aPos.X() ); 2154 if( pXItem ) 2155 { 2156 SvLBoxTab* pXTab = pView->GetTab( pEntry, pXItem ); 2157 if ( !rMEvt.IsMod1() && !rMEvt.IsMod2() && rMEvt.IsLeft() && pXTab->IsEditable() 2158 && pEntry == pView->FirstSelected() && NULL == pView->NextSelected( pEntry ) ) 2159 // #i8234# FirstSelected() and NextSelected() ensures, that inplace editing is only triggered, when only one entry is selected 2160 nFlags |= F_START_EDITTIMER; 2161 if ( !pView->IsSelected( pEntry ) ) 2162 nFlags &= ~F_START_EDITTIMER; 2163 } 2164 2165 2166 if( (rMEvt.GetClicks() % 2) == 0 ) 2167 { 2168 nFlags &= (~F_START_EDITTIMER); 2169 pView->pHdlEntry = pEntry; 2170 if( pView->DoubleClickHdl() ) 2171 { 2172 // falls im Handler der Eintrag geloescht wurde 2173 pEntry = GetClickedEntry( aPos ); 2174 if( !pEntry ) 2175 return; 2176 if( pEntry != pView->pHdlEntry ) 2177 { 2178 // neu selektieren & tschuess 2179 if( !bSimpleTravel && !aSelEng.IsAlwaysAdding()) 2180 SelAllDestrAnch( sal_False, sal_True ); // DeselectAll(); 2181 SetCursor( pEntry ); 2182 2183 return; 2184 } 2185 if( pEntry->HasChilds() || pEntry->HasChildsOnDemand() ) 2186 { 2187 if( pView->IsExpanded(pEntry) ) 2188 pView->Collapse( pEntry ); 2189 else 2190 pView->Expand( pEntry ); 2191 if( pEntry == pCursor ) // nur wenn Entryitem angeklickt wurde 2192 // (Nodebutton ist kein Entryitem!) 2193 pView->Select( pCursor, sal_True ); 2194 return; 2195 } 2196 } 2197 } 2198 else 2199 { 2200 // CheckButton? (TreeListBox: Check + Info) 2201 if( ButtonDownCheckCtrl(rMEvt, pEntry, nY) == sal_True) 2202 return; 2203 // Inplace-Editing? 2204 #if 0 2205 if( rMEvt.IsMod2() && pView->IsInplaceEditingEnabled() ) 2206 { 2207 SvLBoxItem* pItem = pView->GetItem( pEntry, aPos.X() ); 2208 if( pItem ) 2209 pView->EditingRequest( pEntry, pItem, aPos ); 2210 return; 2211 } 2212 #endif 2213 } 2214 if ( aSelEng.GetSelectionMode() != NO_SELECTION ) 2215 aSelEng.SelMouseButtonDown( rMEvt ); 2216 } 2217 2218 void SvImpLBox::MouseButtonUp( const MouseEvent& rMEvt) 2219 { 2220 #ifdef OS2 2221 nFlags &= (~F_IGNORE_NEXT_MOUSEMOVE); 2222 #endif 2223 if ( !ButtonUpCheckCtrl( rMEvt ) && ( aSelEng.GetSelectionMode() != NO_SELECTION ) ) 2224 aSelEng.SelMouseButtonUp( rMEvt ); 2225 EndScroll(); 2226 if( nFlags & F_START_EDITTIMER ) 2227 { 2228 nFlags &= (~F_START_EDITTIMER); 2229 aEditClickPos = rMEvt.GetPosPixel(); 2230 aEditTimer.Start(); 2231 } 2232 2233 return; 2234 } 2235 2236 void SvImpLBox::MouseMove( const MouseEvent& rMEvt) 2237 { 2238 #ifdef OS2 2239 if( nFlags & F_IGNORE_NEXT_MOUSEMOVE ) 2240 { 2241 nFlags &= (~F_IGNORE_NEXT_MOUSEMOVE); 2242 return; 2243 } 2244 #endif 2245 SvLBoxEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() ); 2246 if ( !MouseMoveCheckCtrl( rMEvt, pEntry ) && ( aSelEng.GetSelectionMode() != NO_SELECTION ) ) 2247 aSelEng.SelMouseMove( rMEvt ); 2248 return; 2249 } 2250 2251 sal_Bool SvImpLBox::KeyInput( const KeyEvent& rKEvt) 2252 { 2253 aEditTimer.Stop(); 2254 const KeyCode& rKeyCode = rKEvt.GetKeyCode(); 2255 2256 if( rKeyCode.IsMod2() ) 2257 return sal_False; // Alt-Taste nicht auswerten 2258 2259 nFlags &= (~F_FILLING); 2260 2261 if( !pCursor ) 2262 pCursor = pStartEntry; 2263 if( !pCursor ) 2264 return sal_False; 2265 2266 sal_Bool bKeyUsed = sal_True; 2267 2268 sal_uInt16 nDelta = (sal_uInt16)aVerSBar.GetPageSize(); 2269 sal_uInt16 aCode = rKeyCode.GetCode(); 2270 2271 sal_Bool bShift = rKeyCode.IsShift(); 2272 sal_Bool bMod1 = rKeyCode.IsMod1(); 2273 2274 SvLBoxEntry* pNewCursor; 2275 2276 const WinBits nWindowStyle = pView->GetStyle(); 2277 switch( aCode ) 2278 { 2279 case KEY_UP: 2280 if( !IsEntryInView( pCursor ) ) 2281 MakeVisible( pCursor ); 2282 2283 pNewCursor = pCursor; 2284 do 2285 { 2286 pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pNewCursor )); 2287 } while( pNewCursor && !IsSelectable(pNewCursor) ); 2288 2289 if ( pNewCursor ) 2290 // new entry selected -> reset current tab position to first tab 2291 nCurTabPos = FIRST_ENTRY_TAB; 2292 // if there is no next entry, take the current one 2293 // this ensures that in case of _one_ entry in the list, this entry is selected when pressing 2294 // the cursor key 2295 // 06.09.20001 - 83416 - fs@openoffice.org 2296 if ( !pNewCursor && pCursor ) 2297 pNewCursor = pCursor; 2298 2299 if( pNewCursor ) 2300 { 2301 aSelEng.CursorPosChanging( bShift, bMod1 ); 2302 SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on 2303 if( !IsEntryInView( pNewCursor ) ) 2304 KeyUp( sal_False ); 2305 } 2306 break; 2307 2308 case KEY_DOWN: 2309 if( !IsEntryInView( pCursor ) ) 2310 MakeVisible( pCursor ); 2311 2312 pNewCursor = pCursor; 2313 do 2314 { 2315 pNewCursor = (SvLBoxEntry*)(pView->NextVisible( pNewCursor )); 2316 } while( pNewCursor && !IsSelectable(pNewCursor) ); 2317 2318 if ( pNewCursor ) 2319 // new entry selected -> reset current tab position to first tab 2320 nCurTabPos = FIRST_ENTRY_TAB; 2321 2322 // if there is no next entry, take the current one 2323 // this ensures that in case of _one_ entry in the list, this entry is selected when pressing 2324 // the cursor key 2325 // 06.09.20001 - 83416 - frank.schoenheit@sun.com 2326 if ( !pNewCursor && pCursor ) 2327 pNewCursor = pCursor; 2328 2329 if( pNewCursor ) 2330 { 2331 aSelEng.CursorPosChanging( bShift, bMod1 ); 2332 if( IsEntryInView( pNewCursor ) ) 2333 SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on 2334 else 2335 { 2336 if( pCursor ) 2337 pView->Select( pCursor, sal_False ); 2338 KeyDown( sal_False ); 2339 SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on 2340 } 2341 } 2342 else 2343 KeyDown( sal_False ); // weil ScrollBar-Range evtl. noch 2344 // scrollen erlaubt 2345 break; 2346 2347 case KEY_RIGHT: 2348 { 2349 if( bSubLstOpLR && IsNowExpandable() ) 2350 pView->Expand( pCursor ); 2351 else if ( bIsCellFocusEnabled && pCursor ) 2352 { 2353 if ( nCurTabPos < ( pView->TabCount() - 1 /*!2*/ ) ) 2354 { 2355 ++nCurTabPos; 2356 ShowCursor( sal_True ); 2357 CallEventListeners( VCLEVENT_LISTBOX_SELECT, pCursor ); 2358 } 2359 } 2360 else if( nWindowStyle & WB_HSCROLL ) 2361 { 2362 long nThumb = aHorSBar.GetThumbPos(); 2363 nThumb += aHorSBar.GetLineSize(); 2364 long nOldThumb = aHorSBar.GetThumbPos(); 2365 aHorSBar.SetThumbPos( nThumb ); 2366 nThumb = nOldThumb; 2367 nThumb -= aHorSBar.GetThumbPos(); 2368 nThumb *= -1; 2369 if( nThumb ) 2370 { 2371 KeyLeftRight( nThumb ); 2372 EndScroll(); 2373 } 2374 } 2375 else 2376 bKeyUsed = sal_False; 2377 break; 2378 } 2379 2380 case KEY_LEFT: 2381 { 2382 //IAccessibility2 Implementation 2009----- 2383 // if ( bIsCellFocusEnabled ) 2384 if ( bIsCellFocusEnabled && pCursor ) 2385 //-----IAccessibility2 Implementation 2009 2386 { 2387 if ( nCurTabPos > FIRST_ENTRY_TAB ) 2388 { 2389 --nCurTabPos; 2390 ShowCursor( sal_True ); 2391 CallEventListeners( VCLEVENT_LISTBOX_SELECT, pCursor ); 2392 } 2393 } 2394 else if ( nWindowStyle & WB_HSCROLL ) 2395 { 2396 long nThumb = aHorSBar.GetThumbPos(); 2397 nThumb -= aHorSBar.GetLineSize(); 2398 long nOldThumb = aHorSBar.GetThumbPos(); 2399 aHorSBar.SetThumbPos( nThumb ); 2400 nThumb = nOldThumb; 2401 nThumb -= aHorSBar.GetThumbPos(); 2402 if( nThumb ) 2403 { 2404 KeyLeftRight( -nThumb ); 2405 EndScroll(); 2406 } 2407 else if( bSubLstOpLR ) 2408 { 2409 if( IsExpandable() && pView->IsExpanded( pCursor ) ) 2410 pView->Collapse( pCursor ); 2411 else 2412 { 2413 pNewCursor = pView->GetParent( pCursor ); 2414 if( pNewCursor ) 2415 SetCursor( pNewCursor ); 2416 } 2417 } 2418 } 2419 else if( bSubLstOpLR && IsExpandable() ) 2420 pView->Collapse( pCursor ); 2421 else 2422 bKeyUsed = sal_False; 2423 break; 2424 } 2425 2426 case KEY_PAGEUP: 2427 if( !bMod1 ) 2428 { 2429 pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pCursor, nDelta )); 2430 2431 while( nDelta && pNewCursor && !IsSelectable(pNewCursor) ) 2432 { 2433 pNewCursor = (SvLBoxEntry*)(pView->NextVisible( pNewCursor )); 2434 nDelta--; 2435 } 2436 2437 if( nDelta ) 2438 { 2439 DBG_ASSERT(pNewCursor&&(sal_uLong)pNewCursor!=(sal_uLong)pCursor,"Cursor?"); 2440 aSelEng.CursorPosChanging( bShift, bMod1 ); 2441 if( IsEntryInView( pNewCursor ) ) 2442 SetCursor( pNewCursor ); 2443 else 2444 { 2445 SetCursor( pNewCursor ); 2446 KeyUp( sal_True ); 2447 } 2448 } 2449 } 2450 else 2451 bKeyUsed = sal_False; 2452 break; 2453 2454 case KEY_PAGEDOWN: 2455 if( !bMod1 ) 2456 { 2457 pNewCursor= (SvLBoxEntry*)(pView->NextVisible( pCursor, nDelta )); 2458 2459 while( nDelta && pNewCursor && !IsSelectable(pNewCursor) ) 2460 { 2461 pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pNewCursor )); 2462 nDelta--; 2463 } 2464 2465 if( nDelta ) 2466 { 2467 DBG_ASSERT(pNewCursor&&(sal_uLong)pNewCursor!=(sal_uLong)pCursor,"Cursor?"); 2468 aSelEng.CursorPosChanging( bShift, bMod1 ); 2469 if( IsEntryInView( pNewCursor ) ) 2470 SetCursor( pNewCursor ); 2471 else 2472 { 2473 SetCursor( pNewCursor ); 2474 KeyDown( sal_True ); 2475 } 2476 } 2477 else 2478 KeyDown( sal_False ); // siehe KEY_DOWN 2479 } 2480 else 2481 bKeyUsed = sal_False; 2482 break; 2483 2484 case KEY_SPACE: 2485 if ( pView->GetSelectionMode() != NO_SELECTION ) 2486 { 2487 if ( bMod1 ) 2488 { 2489 if ( pView->GetSelectionMode() == MULTIPLE_SELECTION && !bShift ) 2490 // toggle selection 2491 pView->Select( pCursor, !pView->IsSelected( pCursor ) ); 2492 } 2493 else if ( !bShift /*&& !bMod1*/ ) 2494 { 2495 if ( aSelEng.IsAddMode() ) 2496 { 2497 // toggle selection 2498 pView->Select( pCursor, !pView->IsSelected( pCursor ) ); 2499 } 2500 else if ( !pView->IsSelected( pCursor ) ) 2501 { 2502 SelAllDestrAnch( sal_False ); 2503 pView->Select( pCursor, sal_True ); 2504 } 2505 else 2506 bKeyUsed = sal_False; 2507 } 2508 else 2509 bKeyUsed = sal_False; 2510 } 2511 else 2512 bKeyUsed = sal_False; 2513 break; 2514 2515 case KEY_RETURN: 2516 if( bSubLstOpRet && IsExpandable() ) 2517 { 2518 if( pView->IsExpanded( pCursor ) ) 2519 pView->Collapse( pCursor ); 2520 else 2521 pView->Expand( pCursor ); 2522 } 2523 else 2524 bKeyUsed = sal_False; 2525 break; 2526 2527 case KEY_F2: 2528 if( !bShift && !bMod1 ) 2529 { 2530 aEditClickPos = Point( -1, -1 ); 2531 EditTimerCall( 0 ); 2532 } 2533 else 2534 bKeyUsed = sal_False; 2535 break; 2536 2537 case KEY_F8: 2538 if( bShift && pView->GetSelectionMode()==MULTIPLE_SELECTION && 2539 !(m_nStyle & WB_SIMPLEMODE)) 2540 { 2541 if( aSelEng.IsAlwaysAdding() ) 2542 aSelEng.AddAlways( sal_False ); 2543 else 2544 aSelEng.AddAlways( sal_True ); 2545 } 2546 else 2547 bKeyUsed = sal_False; 2548 break; 2549 2550 2551 #ifdef OV_DEBUG 2552 case KEY_F9: 2553 MakeVisible( pCursor ); 2554 break; 2555 case KEY_F10: 2556 pView->RemoveSelection(); 2557 break; 2558 case KEY_DELETE: 2559 pView->RemoveEntry( pCursor ); 2560 break; 2561 #endif 2562 2563 case KEY_ADD: 2564 if( pCursor ) 2565 { 2566 if( !pView->IsExpanded(pCursor)) 2567 pView->Expand( pCursor ); 2568 if( bMod1 ) 2569 { 2570 sal_uInt16 nRefDepth = pTree->GetDepth( pCursor ); 2571 SvLBoxEntry* pCur = pTree->Next( pCursor ); 2572 while( pCur && pTree->GetDepth(pCur) > nRefDepth ) 2573 { 2574 if( pCur->HasChilds() && !pView->IsExpanded(pCur)) 2575 pView->Expand( pCur ); 2576 pCur = pTree->Next( pCur ); 2577 } 2578 } 2579 } 2580 else 2581 bKeyUsed = sal_False; 2582 break; 2583 2584 case KEY_A: 2585 if( bMod1 ) 2586 SelAllDestrAnch( sal_True ); 2587 else 2588 bKeyUsed = sal_False; 2589 break; 2590 2591 case KEY_SUBTRACT: 2592 if( pCursor ) 2593 { 2594 if( pView->IsExpanded(pCursor)) 2595 pView->Collapse( pCursor ); 2596 if( bMod1 ) 2597 { 2598 // bis zur Root alle Parents einklappen 2599 SvLBoxEntry* pParentToCollapse = (SvLBoxEntry*)pTree->GetRootLevelParent(pCursor); 2600 if( pParentToCollapse ) 2601 { 2602 sal_uInt16 nRefDepth; 2603 // Sonderbehandlung Explorer: Befindet sich auf der 2604 // Root nur ein Eintrag,dann den Root-Entry nicht 2605 // einklappen 2606 if( pTree->GetChildList(0)->Count() < 2 ) 2607 { 2608 nRefDepth = 1; 2609 pParentToCollapse = pCursor; 2610 while( pTree->GetParent(pParentToCollapse) && 2611 pTree->GetDepth( pTree->GetParent(pParentToCollapse)) > 0) 2612 { 2613 pParentToCollapse = pTree->GetParent(pParentToCollapse); 2614 } 2615 } 2616 else 2617 nRefDepth = 0; 2618 2619 if( pView->IsExpanded(pParentToCollapse) ) 2620 pView->Collapse( pParentToCollapse ); 2621 SvLBoxEntry* pCur = pTree->Next( pParentToCollapse ); 2622 while( pCur && pTree->GetDepth(pCur) > nRefDepth ) 2623 { 2624 if( pCur->HasChilds() && pView->IsExpanded(pCur) ) 2625 pView->Collapse( pCur ); 2626 pCur = pTree->Next( pCur ); 2627 } 2628 } 2629 } 2630 } 2631 else 2632 bKeyUsed = sal_False; 2633 break; 2634 2635 case KEY_DIVIDE : 2636 if( bMod1 ) 2637 SelAllDestrAnch( sal_True ); 2638 else 2639 bKeyUsed = sal_False; 2640 break; 2641 2642 case KEY_COMMA : 2643 if( bMod1 ) 2644 SelAllDestrAnch( sal_False ); 2645 else 2646 bKeyUsed = sal_False; 2647 break; 2648 2649 case KEY_HOME : 2650 pNewCursor = pView->GetModel()->First(); 2651 2652 while( pNewCursor && !IsSelectable(pNewCursor) ) 2653 { 2654 pNewCursor = (SvLBoxEntry*)(pView->NextVisible( pNewCursor )); 2655 } 2656 2657 if( pNewCursor && pNewCursor != pCursor ) 2658 { 2659 // SelAllDestrAnch( sal_False ); 2660 aSelEng.CursorPosChanging( bShift, bMod1 ); 2661 SetCursor( pNewCursor ); 2662 if( !IsEntryInView( pNewCursor ) ) 2663 MakeVisible( pNewCursor ); 2664 } 2665 else 2666 bKeyUsed = sal_False; 2667 break; 2668 2669 case KEY_END : 2670 pNewCursor = pView->GetModel()->Last(); 2671 2672 while( pNewCursor && !IsSelectable(pNewCursor) ) 2673 { 2674 pNewCursor = (SvLBoxEntry*)(pView->PrevVisible( pNewCursor )); 2675 } 2676 2677 if( pNewCursor && pNewCursor != pCursor) 2678 { 2679 // SelAllDestrAnch( sal_False ); 2680 aSelEng.CursorPosChanging( bShift, bMod1 ); 2681 SetCursor( pNewCursor ); 2682 if( !IsEntryInView( pNewCursor ) ) 2683 MakeVisible( pNewCursor ); 2684 } 2685 else 2686 bKeyUsed = sal_False; 2687 break; 2688 2689 case KEY_ESCAPE: 2690 case KEY_TAB: 2691 case KEY_DELETE: 2692 case KEY_BACKSPACE: 2693 // #105907# must not be handled because this quits dialogs and does other magic things... 2694 // if there are other single keys which should not be handled, they can be added here 2695 bKeyUsed = sal_False; 2696 break; 2697 2698 default: 2699 // is there any reason why we should eat the events here? The only place where this is called 2700 // is from SvTreeListBox::KeyInput. If we set bKeyUsed to sal_True here, then the key input 2701 // is just silenced. However, we want SvLBox::KeyInput to get a chance, to do the QuickSelection 2702 // handling. 2703 // (The old code here which intentionally set bKeyUsed to sal_True said this was because of "quick search" 2704 // handling, but actually there was no quick search handling anymore. We just re-implemented it.) 2705 // #i31275# / 2009-06-16 / frank.schoenheit@sun.com 2706 bKeyUsed = sal_False; 2707 break; 2708 } 2709 return bKeyUsed; 2710 } 2711 2712 void __EXPORT SvImpLBox::GetFocus() 2713 { 2714 if( pCursor ) 2715 { 2716 pView->SetEntryFocus( pCursor, sal_True ); 2717 ShowCursor( sal_True ); 2718 // auskommentiert wg. deselectall 2719 // if( bSimpleTravel && !pView->IsSelected(pCursor) ) 2720 // pView->Select( pCursor, sal_True ); 2721 } 2722 if( m_nStyle & WB_HIDESELECTION ) 2723 { 2724 SvLBoxEntry* pEntry = pView->FirstSelected(); 2725 while( pEntry ) 2726 { 2727 InvalidateEntry( pEntry ); 2728 pEntry = pView->NextSelected( pEntry ); 2729 } 2730 /* 2731 SvLBoxEntry* pEntry = pView->GetModel()->First(); 2732 while( pEntry ) 2733 { 2734 SvViewData* pViewData = pView->GetViewData( pEntry ); 2735 if( pViewData->IsCursored() ) 2736 { 2737 pViewData->SetCursored( sal_False ); 2738 InvalidateEntry( pEntry ); 2739 } 2740 pEntry = pView->GetModel()->Next( pEntry ); 2741 } 2742 */ 2743 2744 2745 } 2746 } 2747 2748 void __EXPORT SvImpLBox::LoseFocus() 2749 { 2750 aEditTimer.Stop(); 2751 if( pCursor ) 2752 pView->SetEntryFocus( pCursor,sal_False ); 2753 ShowCursor( sal_False ); 2754 2755 if( m_nStyle & WB_HIDESELECTION ) 2756 { 2757 SvLBoxEntry* pEntry = pView->FirstSelected(); 2758 while( pEntry ) 2759 { 2760 //SvViewData* pViewData = pView->GetViewData( pEntry ); 2761 //pViewData->SetCursored( sal_True ); 2762 InvalidateEntry( pEntry ); 2763 pEntry = pView->NextSelected( pEntry ); 2764 } 2765 } 2766 } 2767 2768 2769 // ******************************************************************** 2770 // SelectionEngine 2771 // ******************************************************************** 2772 2773 inline void SvImpLBox::SelectEntry( SvLBoxEntry* pEntry, sal_Bool bSelect ) 2774 { 2775 pView->Select( pEntry, bSelect ); 2776 } 2777 2778 __EXPORT ImpLBSelEng::ImpLBSelEng( SvImpLBox* pImpl, SelectionEngine* pSEng, 2779 SvTreeListBox* pV ) 2780 { 2781 pImp = pImpl; 2782 pSelEng = pSEng; 2783 pView = pV; 2784 } 2785 2786 __EXPORT ImpLBSelEng::~ImpLBSelEng() 2787 { 2788 } 2789 2790 void __EXPORT ImpLBSelEng::BeginDrag() 2791 { 2792 pImp->BeginDrag(); 2793 } 2794 2795 /* 2796 void __EXPORT ImpLBSelEng::EndDrag( const Point& ) 2797 { 2798 } 2799 */ 2800 2801 void __EXPORT ImpLBSelEng::CreateAnchor() 2802 { 2803 pImp->pAnchor = pImp->pCursor; 2804 } 2805 2806 void __EXPORT ImpLBSelEng::DestroyAnchor() 2807 { 2808 pImp->pAnchor = 0; 2809 } 2810 2811 /* 2812 void __EXPORT ImpLBSelEng::CreateCursor() 2813 { 2814 pImp->pAnchor = 0; 2815 } 2816 */ 2817 2818 2819 sal_Bool __EXPORT ImpLBSelEng::SetCursorAtPoint(const Point& rPoint, sal_Bool bDontSelectAtCursor) 2820 { 2821 SvLBoxEntry* pNewCursor = pImp->MakePointVisible( rPoint ); 2822 if( pNewCursor != pImp->pCursor ) 2823 pImp->BeginScroll(); 2824 2825 if( pNewCursor ) 2826 { 2827 // bei SimpleTravel wird in SetCursor selektiert und 2828 // der Select-Handler gerufen 2829 //if( !bDontSelectAtCursor && !pImp->bSimpleTravel ) 2830 // pImp->SelectEntry( pNewCursor, sal_True ); 2831 pImp->SetCursor( pNewCursor, bDontSelectAtCursor ); 2832 return sal_True; 2833 } 2834 return sal_False; 2835 } 2836 2837 sal_Bool __EXPORT ImpLBSelEng::IsSelectionAtPoint( const Point& rPoint ) 2838 { 2839 SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint ); 2840 if( pEntry ) 2841 return pView->IsSelected(pEntry); 2842 return sal_False; 2843 } 2844 2845 void __EXPORT ImpLBSelEng::DeselectAtPoint( const Point& rPoint ) 2846 { 2847 SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint ); 2848 if( !pEntry ) 2849 return; 2850 pImp->SelectEntry( pEntry, sal_False ); 2851 } 2852 2853 /* 2854 void __EXPORT ImpLBSelEng::SelectAtPoint( const Point& rPoint ) 2855 { 2856 SvLBoxEntry* pEntry = pImp->MakePointVisible( rPoint ); 2857 if( !pEntry ) 2858 return; 2859 pImp->SelectEntry( pEntry, sal_True ); 2860 } 2861 */ 2862 2863 void __EXPORT ImpLBSelEng::DeselectAll() 2864 { 2865 pImp->SelAllDestrAnch( sal_False, sal_False ); // SelectionEngine nicht resetten! 2866 pImp->nFlags &= (~F_DESEL_ALL); 2867 } 2868 2869 // *********************************************************************** 2870 // Selektion 2871 // *********************************************************************** 2872 2873 void SvImpLBox::SetAnchorSelection(SvLBoxEntry* pOldCursor,SvLBoxEntry* pNewCursor) 2874 { 2875 SvLBoxEntry* pEntry; 2876 sal_uLong nAnchorVisPos = pView->GetVisiblePos( pAnchor ); 2877 sal_uLong nOldVisPos = pView->GetVisiblePos( pOldCursor ); 2878 sal_uLong nNewVisPos = pView->GetVisiblePos( pNewCursor ); 2879 2880 if( nOldVisPos > nAnchorVisPos || 2881 ( nAnchorVisPos==nOldVisPos && nNewVisPos > nAnchorVisPos) ) 2882 { 2883 if( nNewVisPos > nOldVisPos ) 2884 { 2885 pEntry = pOldCursor; 2886 while( pEntry && pEntry != pNewCursor ) 2887 { 2888 pView->Select( pEntry, sal_True ); 2889 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 2890 } 2891 if( pEntry ) 2892 pView->Select( pEntry, sal_True ); 2893 return; 2894 } 2895 2896 if( nNewVisPos < nAnchorVisPos ) 2897 { 2898 pEntry = pAnchor; 2899 while( pEntry && pEntry != pOldCursor ) 2900 { 2901 pView->Select( pEntry, sal_False ); 2902 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 2903 } 2904 if( pEntry ) 2905 pView->Select( pEntry, sal_False ); 2906 2907 pEntry = pNewCursor; 2908 while( pEntry && pEntry != pAnchor ) 2909 { 2910 pView->Select( pEntry, sal_True ); 2911 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 2912 } 2913 if( pEntry ) 2914 pView->Select( pEntry, sal_True ); 2915 return; 2916 } 2917 2918 if( nNewVisPos < nOldVisPos ) 2919 { 2920 pEntry = pNewCursor; 2921 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 2922 while( pEntry && pEntry != pOldCursor ) 2923 { 2924 pView->Select( pEntry, sal_False ); 2925 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 2926 } 2927 if( pEntry ) 2928 pView->Select( pEntry, sal_False ); 2929 return; 2930 } 2931 } 2932 else 2933 { 2934 if( nNewVisPos < nOldVisPos ) // Vergroessern der Selektion 2935 { 2936 pEntry = pNewCursor; 2937 while( pEntry && pEntry != pOldCursor ) 2938 { 2939 pView->Select( pEntry, sal_True ); 2940 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 2941 } 2942 if( pEntry ) 2943 pView->Select( pEntry, sal_True ); 2944 return; 2945 } 2946 2947 if( nNewVisPos > nAnchorVisPos ) 2948 { 2949 pEntry = pOldCursor; 2950 while( pEntry && pEntry != pAnchor ) 2951 { 2952 pView->Select( pEntry, sal_False ); 2953 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 2954 } 2955 if( pEntry ) 2956 pView->Select( pEntry, sal_False ); 2957 pEntry = pAnchor; 2958 while( pEntry && pEntry != pNewCursor ) 2959 { 2960 pView->Select( pEntry, sal_True ); 2961 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 2962 } 2963 if( pEntry ) 2964 pView->Select( pEntry, sal_True ); 2965 return; 2966 } 2967 2968 if( nNewVisPos > nOldVisPos ) 2969 { 2970 pEntry = pOldCursor; 2971 while( pEntry && pEntry != pNewCursor ) 2972 { 2973 pView->Select( pEntry, sal_False ); 2974 pEntry = (SvLBoxEntry*)(pView->NextVisible( pEntry )); 2975 } 2976 return; 2977 } 2978 } 2979 } 2980 2981 void SvImpLBox::SelAllDestrAnch( sal_Bool bSelect, sal_Bool bDestroyAnchor, 2982 sal_Bool bSingleSelToo ) 2983 { 2984 SvLBoxEntry* pEntry; 2985 nFlags &= (~F_DESEL_ALL); 2986 if( bSelect && bSimpleTravel ) 2987 { 2988 if( pCursor && !pView->IsSelected( pCursor )) 2989 { 2990 pView->Select( pCursor, sal_True ); 2991 } 2992 return; 2993 } 2994 if( !bSelect && pView->GetSelectionCount() == 0 ) 2995 { 2996 if( bSimpleTravel && ( !GetUpdateMode() || !pCursor) ) 2997 nFlags |= F_DESEL_ALL; 2998 return; 2999 } 3000 if( bSelect && pView->GetSelectionCount() == pView->GetEntryCount()) 3001 return; 3002 if( !bSingleSelToo && bSimpleTravel ) 3003 return; 3004 3005 if( !bSelect && pView->GetSelectionCount()==1 && pCursor && 3006 pView->IsSelected( pCursor )) 3007 { 3008 pView->Select( pCursor, sal_False ); 3009 if( bDestroyAnchor ) 3010 DestroyAnchor(); // Anker loeschen & SelectionEngine zuruecksetzen 3011 else 3012 pAnchor = 0; // internen Anker immer loeschen 3013 return; 3014 } 3015 3016 if( bSimpleTravel && !pCursor && !GetUpdateMode() ) 3017 nFlags |= F_DESEL_ALL; 3018 3019 ShowCursor( sal_False ); 3020 sal_Bool bUpdate = GetUpdateMode(); 3021 3022 nFlags |= F_IGNORE_SELECT; // EntryInserted soll nix tun 3023 pEntry = pTree->First(); 3024 while( pEntry ) 3025 { 3026 if( pView->Select( pEntry, bSelect ) ) 3027 { 3028 if( bUpdate && pView->IsEntryVisible(pEntry) ) 3029 { 3030 long nY = GetEntryLine( pEntry ); 3031 if( IsLineVisible( nY ) ) 3032 pView->PaintEntry1( pEntry, nY, 0xffff ); // wg. ItemsetBrowser SV_LBOXTAB_SHOW_SELECTION ); 3033 } 3034 } 3035 pEntry = pTree->Next( pEntry ); 3036 } 3037 nFlags &= ~F_IGNORE_SELECT; 3038 3039 if( bDestroyAnchor ) 3040 DestroyAnchor(); // Anker loeschen & SelectionEngine zuruecksetzen 3041 else 3042 pAnchor = 0; // internen Anker immer loeschen 3043 ShowCursor( sal_True ); 3044 } 3045 3046 void SvImpLBox::SetSelectionMode( SelectionMode eSelMode ) 3047 { 3048 aSelEng.SetSelectionMode( eSelMode); 3049 if( eSelMode == SINGLE_SELECTION ) 3050 bSimpleTravel = sal_True; 3051 else 3052 bSimpleTravel = sal_False; 3053 if( (m_nStyle & WB_SIMPLEMODE) && (eSelMode == MULTIPLE_SELECTION) ) 3054 aSelEng.AddAlways( sal_True ); 3055 } 3056 3057 // *********************************************************************** 3058 // Drag & Drop 3059 // *********************************************************************** 3060 3061 void SvImpLBox::SetDragDropMode( DragDropMode eDDMode ) 3062 { 3063 if( eDDMode && eDDMode != SV_DRAGDROP_APP_DROP ) 3064 { 3065 aSelEng.ExpandSelectionOnMouseMove( sal_False ); 3066 aSelEng.EnableDrag( sal_True ); 3067 } 3068 else 3069 { 3070 aSelEng.ExpandSelectionOnMouseMove( sal_True ); 3071 aSelEng.EnableDrag( sal_False ); 3072 } 3073 } 3074 3075 void SvImpLBox::BeginDrag() 3076 { 3077 nFlags &= (~F_FILLING); 3078 if( !bAsyncBeginDrag ) 3079 { 3080 BeginScroll(); 3081 pView->StartDrag( 0, aSelEng.GetMousePosPixel() ); 3082 EndScroll(); 3083 } 3084 else 3085 { 3086 aAsyncBeginDragPos = aSelEng.GetMousePosPixel(); 3087 aAsyncBeginDragTimer.Start(); 3088 } 3089 } 3090 3091 IMPL_LINK( SvImpLBox, BeginDragHdl, void*, EMPTYARG ) 3092 { 3093 pView->StartDrag( 0, aAsyncBeginDragPos ); 3094 return 0; 3095 } 3096 3097 void SvImpLBox::PaintDDCursor( SvLBoxEntry* pInsertionPos ) 3098 { 3099 long nY; 3100 if( pInsertionPos ) 3101 { 3102 nY = GetEntryLine( pInsertionPos ); 3103 nY += pView->GetEntryHeight(); 3104 } 3105 else 3106 nY = 1; 3107 RasterOp eOldOp = pView->GetRasterOp(); 3108 pView->SetRasterOp( ROP_INVERT ); 3109 Color aOldLineColor = pView->GetLineColor(); 3110 pView->SetLineColor( Color( COL_BLACK ) ); 3111 pView->DrawLine( Point( 0, nY ), Point( aOutputSize.Width(), nY ) ); 3112 pView->SetLineColor( aOldLineColor ); 3113 pView->SetRasterOp( eOldOp ); 3114 } 3115 /* -----------------26.08.2003 12:52----------------- 3116 Delete all sub menues of a PopupMenu, recursively 3117 --------------------------------------------------*/ 3118 void lcl_DeleteSubPopups(PopupMenu* pPopup) 3119 { 3120 for(sal_uInt16 i = 0; i < pPopup->GetItemCount(); i++) 3121 { 3122 PopupMenu* pSubPopup = pPopup->GetPopupMenu( pPopup->GetItemId( i )); 3123 if(pSubPopup) 3124 { 3125 lcl_DeleteSubPopups(pSubPopup); 3126 delete pSubPopup; 3127 } 3128 } 3129 } 3130 3131 void SvImpLBox::Command( const CommandEvent& rCEvt ) 3132 { 3133 sal_uInt16 nCommand = rCEvt.GetCommand(); 3134 3135 if( nCommand == COMMAND_CONTEXTMENU ) 3136 aEditTimer.Stop(); 3137 3138 // Rollmaus-Event? 3139 if( ( ( nCommand == COMMAND_WHEEL ) || ( nCommand == COMMAND_STARTAUTOSCROLL ) || ( nCommand == COMMAND_AUTOSCROLL ) ) 3140 && pView->HandleScrollCommand( rCEvt, &aHorSBar, &aVerSBar ) ) 3141 return; 3142 3143 if( bContextMenuHandling && nCommand == COMMAND_CONTEXTMENU ) 3144 { 3145 Point aPopupPos; 3146 sal_Bool bClickedIsFreePlace = sal_False; 3147 std::stack<SvLBoxEntry*> aSelRestore; 3148 3149 if( rCEvt.IsMouseEvent() ) 3150 { // change selection, if mouse pos doesn't fit to selection 3151 3152 aPopupPos = rCEvt.GetMousePosPixel(); 3153 3154 SvLBoxEntry* pClickedEntry = GetEntry( aPopupPos ); 3155 if( pClickedEntry ) 3156 { // mouse in non empty area 3157 sal_Bool bClickedIsSelected = sal_False; 3158 3159 // collect the currently selected entries 3160 SvLBoxEntry* pSelected = pView->FirstSelected(); 3161 while( pSelected ) 3162 { 3163 bClickedIsSelected |= ( pClickedEntry == pSelected ); 3164 pSelected = pView->NextSelected( pSelected ); 3165 } 3166 3167 // if the entry which the user clicked at is not selected 3168 if( !bClickedIsSelected ) 3169 { // deselect all other and select the clicked one 3170 pView->SelectAll( sal_False ); 3171 pView->SetCursor( pClickedEntry ); 3172 } 3173 } 3174 else if( aSelEng.GetSelectionMode() == SINGLE_SELECTION ) 3175 {//modified by BerryJia for fixing Bug102739 2002-9-9 17:00(Beijing Time) 3176 bClickedIsFreePlace = sal_True; 3177 sal_Int32 nSelectedEntries = pView->GetSelectionCount(); 3178 SvLBoxEntry* pSelected = pView->FirstSelected(); 3179 for(sal_uInt16 nSel = 0; nSel < nSelectedEntries; nSel++ ) 3180 { 3181 aSelRestore.push(pSelected); 3182 pSelected = pView->NextSelected( pSelected ); 3183 } 3184 pView->SelectAll( sal_False ); 3185 } 3186 else 3187 { // deselect all 3188 pView->SelectAll( sal_False ); 3189 } 3190 3191 3192 } 3193 else 3194 { // key event (or at least no mouse event) 3195 sal_Int32 nSelectionCount = pView->GetSelectionCount(); 3196 3197 if( nSelectionCount ) 3198 { // now allways take first visible as base for positioning the menu 3199 SvLBoxEntry* pSelected = pView->FirstSelected(); 3200 while( pSelected ) 3201 { 3202 if( IsEntryInView( pSelected ) ) 3203 break; 3204 3205 pSelected = pView->NextSelected( pSelected ); 3206 } 3207 3208 if( !pSelected ) 3209 { 3210 // no one was visible 3211 pSelected = pView->FirstSelected(); 3212 pView->MakeVisible( pSelected ); 3213 } 3214 3215 aPopupPos = pView->GetFocusRect( pSelected, pView->GetEntryPosition( pSelected ).Y() ).Center(); 3216 } 3217 else 3218 aPopupPos = Point( 0, 0 ); 3219 } 3220 3221 PopupMenu* pPopup = pView->CreateContextMenu(); 3222 3223 if( pPopup ) 3224 { 3225 // do action for selected entry in popup menu 3226 sal_uInt16 nMenuAction = pPopup->Execute( pView, aPopupPos ); 3227 if ( nMenuAction ) 3228 pView->ExcecuteContextMenuAction( nMenuAction ); 3229 lcl_DeleteSubPopups(pPopup); 3230 delete pPopup; 3231 } 3232 //added by BerryJia for fixing Bug102739 2002-9-9 17:00(Beijing Time) 3233 if( bClickedIsFreePlace ) 3234 { 3235 while(!aSelRestore.empty()) 3236 { 3237 SvLBoxEntry* pEntry = aSelRestore.top(); 3238 //#i19717# the entry is maybe already deleted 3239 bool bFound = false; 3240 for(sal_uLong nEntry = 0; nEntry < pView->GetEntryCount(); nEntry++) 3241 if(pEntry == pView->GetEntry(nEntry)) 3242 { 3243 bFound = true; 3244 break; 3245 } 3246 if(bFound) 3247 SetCurEntry( pEntry ); 3248 aSelRestore.pop(); 3249 } 3250 } 3251 } 3252 #ifndef NOCOMMAND 3253 else 3254 { 3255 const Point& rPos = rCEvt.GetMousePosPixel(); 3256 if( rPos.X() < aOutputSize.Width() && rPos.Y() < aOutputSize.Height() ) 3257 aSelEng.Command( rCEvt ); 3258 } 3259 #endif 3260 } 3261 3262 void SvImpLBox::BeginScroll() 3263 { 3264 if( !(nFlags & F_IN_SCROLLING)) 3265 { 3266 pView->NotifyBeginScroll(); 3267 nFlags |= F_IN_SCROLLING; 3268 } 3269 } 3270 3271 void SvImpLBox::EndScroll() 3272 { 3273 if( nFlags & F_IN_SCROLLING) 3274 { 3275 pView->NotifyEndScroll(); 3276 nFlags &= (~F_IN_SCROLLING); 3277 } 3278 } 3279 3280 3281 Rectangle SvImpLBox::GetVisibleArea() const 3282 { 3283 Point aPos( pView->GetMapMode().GetOrigin() ); 3284 aPos.X() *= -1; 3285 Rectangle aRect( aPos, aOutputSize ); 3286 return aRect; 3287 } 3288 3289 void SvImpLBox::Invalidate() 3290 { 3291 pView->SetClipRegion(); 3292 } 3293 3294 void SvImpLBox::SetCurEntry( SvLBoxEntry* pEntry ) 3295 { 3296 if ( ( aSelEng.GetSelectionMode() != SINGLE_SELECTION ) 3297 && ( aSelEng.GetSelectionMode() != NO_SELECTION ) 3298 ) 3299 SelAllDestrAnch( sal_False, sal_True, sal_False ); 3300 if ( pEntry ) 3301 MakeVisible( pEntry ); 3302 SetCursor( pEntry ); 3303 if ( pEntry && ( aSelEng.GetSelectionMode() != NO_SELECTION ) ) 3304 pView->Select( pEntry, sal_True ); 3305 } 3306 3307 IMPL_LINK( SvImpLBox, EditTimerCall, Timer *, EMPTYARG ) 3308 { 3309 if( pView->IsInplaceEditingEnabled() ) 3310 { 3311 sal_Bool bIsMouseTriggered = aEditClickPos.X() >= 0; 3312 if ( bIsMouseTriggered ) 3313 { 3314 Point aCurrentMousePos = pView->GetPointerPosPixel(); 3315 if ( ( abs( aCurrentMousePos.X() - aEditClickPos.X() ) > 5 ) 3316 || ( abs( aCurrentMousePos.Y() - aEditClickPos.Y() ) > 5 ) 3317 ) 3318 { 3319 return 0L; 3320 } 3321 } 3322 3323 SvLBoxEntry* pEntry = GetCurEntry(); 3324 if( pEntry ) 3325 { 3326 ShowCursor( sal_False ); 3327 pView->ImplEditEntry( pEntry ); 3328 ShowCursor( sal_True ); 3329 } 3330 } 3331 return 0; 3332 } 3333 3334 sal_Bool SvImpLBox::RequestHelp( const HelpEvent& rHEvt ) 3335 { 3336 if( rHEvt.GetMode() & HELPMODE_QUICK ) 3337 { 3338 Point aPos( pView->ScreenToOutputPixel( rHEvt.GetMousePosPixel() )); 3339 if( !GetVisibleArea().IsInside( aPos )) 3340 return sal_False; 3341 3342 SvLBoxEntry* pEntry = GetEntry( aPos ); 3343 if( pEntry ) 3344 { 3345 // Rechteck des Textes berechnen 3346 SvLBoxTab* pTab; 3347 SvLBoxString* pItem = (SvLBoxString*)(pView->GetItem( pEntry, aPos.X(), &pTab )); 3348 if( !pItem || pItem->IsA() != SV_ITEM_ID_LBOXSTRING ) 3349 return sal_False; 3350 3351 aPos = GetEntryPosition( pEntry ); 3352 aPos.X() = pView->GetTabPos( pEntry, pTab ); //pTab->GetPos(); 3353 Size aSize( pItem->GetSize( pView, pEntry ) ); 3354 SvLBoxTab* pNextTab = NextTab( pTab ); 3355 sal_Bool bItemClipped = sal_False; 3356 // wurde das Item von seinem rechten Nachbarn abgeschnitten? 3357 if( pNextTab && pView->GetTabPos(pEntry,pNextTab) < aPos.X()+aSize.Width() ) 3358 { 3359 aSize.Width() = pNextTab->GetPos() - pTab->GetPos(); 3360 bItemClipped = sal_True; 3361 } 3362 Rectangle aItemRect( aPos, aSize ); 3363 3364 Rectangle aViewRect( GetVisibleArea() ); 3365 3366 if( bItemClipped || !aViewRect.IsInside( aItemRect ) ) 3367 { 3368 // rechten Item-Rand am View-Rand clippen 3369 //if( aItemRect.Right() > aViewRect.Right() ) 3370 // aItemRect.Right() = aViewRect.Right(); 3371 3372 Point aPt = pView->OutputToScreenPixel( aItemRect.TopLeft() ); 3373 aItemRect.Left() = aPt.X(); 3374 aItemRect.Top() = aPt.Y(); 3375 aPt = pView->OutputToScreenPixel( aItemRect.BottomRight() ); 3376 aItemRect.Right() = aPt.X(); 3377 aItemRect.Bottom() = aPt.Y(); 3378 3379 Help::ShowQuickHelp( pView, aItemRect, 3380 pItem->GetText(), QUICKHELP_LEFT | QUICKHELP_VCENTER ); 3381 return sal_True; 3382 } 3383 } 3384 } 3385 return sal_False; 3386 } 3387 3388 SvLBoxTab* SvImpLBox::NextTab( SvLBoxTab* pTab ) 3389 { 3390 sal_uInt16 nTabCount = pView->TabCount(); 3391 if( nTabCount <= 1 ) 3392 return 0; 3393 for( sal_uInt16 nTab=0; nTab < (nTabCount-1); nTab++) 3394 { 3395 if( pView->aTabs[nTab]==pTab ) 3396 return (SvLBoxTab*)(pView->aTabs[nTab+1]); 3397 } 3398 return 0; 3399 } 3400 3401 void SvImpLBox::EndSelection() 3402 { 3403 DestroyAnchor(); 3404 nFlags &= ~F_START_EDITTIMER; 3405 } 3406 3407 void SvImpLBox::RepaintScrollBars() 3408 { 3409 } 3410 3411 void SvImpLBox::SetUpdateMode( sal_Bool bMode ) 3412 { 3413 if( bUpdateMode != bMode ) 3414 { 3415 bUpdateMode = bMode; 3416 if( bUpdateMode ) 3417 UpdateAll( sal_False ); 3418 } 3419 } 3420 3421 void SvImpLBox::SetUpdateModeFast( sal_Bool bMode ) 3422 { 3423 if( bUpdateMode != bMode ) 3424 { 3425 bUpdateMode = bMode; 3426 if( bUpdateMode ) 3427 UpdateAll( sal_False, sal_False ); 3428 } 3429 } 3430 3431 3432 sal_Bool SvImpLBox::SetMostRight( SvLBoxEntry* pEntry ) 3433 { 3434 if( pView->nTreeFlags & TREEFLAG_RECALCTABS ) 3435 { 3436 nFlags |= F_IGNORE_CHANGED_TABS; 3437 pView->SetTabs(); 3438 nFlags &= ~F_IGNORE_CHANGED_TABS; 3439 } 3440 3441 sal_uInt16 nLastTab = pView->aTabs.Count() - 1; 3442 sal_uInt16 nLastItem = pEntry->ItemCount() - 1; 3443 if( nLastTab != USHRT_MAX && nLastItem != USHRT_MAX ) 3444 { 3445 if( nLastItem < nLastTab ) 3446 nLastTab = nLastItem; 3447 3448 SvLBoxTab* pTab = (SvLBoxTab*)pView->aTabs[ nLastTab ]; 3449 SvLBoxItem* pItem = pEntry->GetItem( nLastTab ); 3450 3451 long nTabPos = pView->GetTabPos( pEntry, pTab ); 3452 3453 long nMaxRight = GetOutputSize().Width(); 3454 Point aPos( pView->GetMapMode().GetOrigin() ); 3455 aPos.X() *= -1; // Umrechnung Dokumentkoord. 3456 nMaxRight = nMaxRight + aPos.X() - 1; 3457 3458 long nNextTab = nTabPos < nMaxRight ? nMaxRight : nMaxRight + 50; 3459 long nTabWidth = nNextTab - nTabPos + 1; 3460 long nItemSize = pItem->GetSize(pView,pEntry).Width(); 3461 long nOffset = pTab->CalcOffset( nItemSize, nTabWidth ); 3462 3463 long nRight = nTabPos + nOffset + nItemSize; 3464 if( nRight > nMostRight ) 3465 { 3466 nMostRight = nRight; 3467 pMostRightEntry = pEntry; 3468 return sal_True; 3469 } 3470 } 3471 return sal_False; 3472 } 3473 3474 void SvImpLBox::FindMostRight( SvLBoxEntry* pEntryToIgnore ) 3475 { 3476 nMostRight = -1; 3477 pMostRightEntry = 0; 3478 if( !pView->GetModel() ) 3479 return; 3480 3481 SvLBoxEntry* pEntry = (SvLBoxEntry*)pView->FirstVisible(); 3482 while( pEntry ) 3483 { 3484 if( pEntry != pEntryToIgnore ) 3485 SetMostRight( pEntry ); 3486 pEntry = (SvLBoxEntry*)pView->NextVisible( pEntry ); 3487 } 3488 } 3489 3490 void SvImpLBox::FindMostRight( SvLBoxEntry* pParent, SvLBoxEntry* pEntryToIgnore ) 3491 { 3492 if( !pParent ) 3493 FindMostRight( pEntryToIgnore ); 3494 else 3495 FindMostRight_Impl( pParent, pEntryToIgnore ); 3496 } 3497 3498 void SvImpLBox::FindMostRight_Impl( SvLBoxEntry* pParent, SvLBoxEntry* pEntryToIgnore ) 3499 { 3500 SvTreeEntryList* pList = pTree->GetChildList( pParent ); 3501 3502 if( !pList ) 3503 return; 3504 3505 sal_uLong nCount = pList->Count(); 3506 for( sal_uLong nCur = 0; nCur < nCount; nCur++ ) 3507 { 3508 SvLBoxEntry* pChild = (SvLBoxEntry*)pList->GetObject( nCur ); 3509 if( pChild != pEntryToIgnore ) 3510 { 3511 SetMostRight( pChild ); 3512 if( pChild->HasChilds() && pView->IsExpanded( pChild )) 3513 FindMostRight_Impl( pChild, pEntryToIgnore ); 3514 } 3515 } 3516 } 3517 3518 void SvImpLBox::NotifyTabsChanged() 3519 { 3520 if( GetUpdateMode() && !(nFlags & F_IGNORE_CHANGED_TABS ) && 3521 nCurUserEvent == 0xffffffff ) 3522 { 3523 nCurUserEvent = Application::PostUserEvent(LINK(this,SvImpLBox,MyUserEvent),(void*)0); 3524 } 3525 } 3526 3527 IMPL_LINK(SvImpLBox,MyUserEvent,void*, pArg ) 3528 { 3529 nCurUserEvent = 0xffffffff; 3530 if( !pArg ) 3531 { 3532 pView->Invalidate(); 3533 pView->Update(); 3534 } 3535 else 3536 { 3537 FindMostRight( 0 ); 3538 ShowVerSBar(); 3539 pView->Invalidate( GetVisibleArea() ); 3540 } 3541 return 0; 3542 } 3543 3544 3545 void SvImpLBox::StopUserEvent() 3546 { 3547 if( nCurUserEvent != 0xffffffff ) 3548 { 3549 Application::RemoveUserEvent( nCurUserEvent ); 3550 nCurUserEvent = 0xffffffff; 3551 } 3552 } 3553 3554 void SvImpLBox::ShowFocusRect( const SvLBoxEntry* pEntry ) 3555 { 3556 if( pEntry ) 3557 { 3558 long nY = GetEntryLine( (SvLBoxEntry*)pEntry ); 3559 Rectangle aRect = pView->GetFocusRect( (SvLBoxEntry*)pEntry, nY ); 3560 Region aOldClip( pView->GetClipRegion()); 3561 Region aClipRegion( GetClipRegionRect() ); 3562 pView->SetClipRegion( aClipRegion ); 3563 pView->ShowFocus( aRect ); 3564 pView->SetClipRegion( aOldClip ); 3565 3566 } 3567 else 3568 { 3569 pView->HideFocus(); 3570 } 3571 } 3572 3573 void SvImpLBox::SetTabBar( TabBar* _pTabBar ) 3574 { 3575 pTabBar = _pTabBar; 3576 } 3577 3578 void SvImpLBox::CancelPendingEdit() 3579 { 3580 if( aEditTimer.IsActive() ) 3581 aEditTimer.Stop(); 3582 nFlags &= ~F_START_EDITTIMER; 3583 } 3584 3585 // ----------------------------------------------------------------------- 3586 void SvImpLBox::implInitDefaultNodeImages() 3587 { 3588 if ( s_pDefCollapsed ) 3589 // assume that all or nothing is initialized 3590 return; 3591 3592 s_pDefCollapsed = new Image( SvtResId( RID_IMG_TREENODE_COLLAPSED ) ); 3593 s_pDefCollapsedHC = new Image( SvtResId( RID_IMG_TREENODE_COLLAPSED_HC ) ); 3594 s_pDefExpanded = new Image( SvtResId( RID_IMG_TREENODE_EXPANDED ) ); 3595 s_pDefExpandedHC = new Image( SvtResId( RID_IMG_TREENODE_EXPANDED_HC ) ); 3596 } 3597 3598 // ----------------------------------------------------------------------- 3599 const Image& SvImpLBox::GetDefaultExpandedNodeImage( BmpColorMode _eMode ) 3600 { 3601 implInitDefaultNodeImages(); 3602 return ( BMP_COLOR_NORMAL == _eMode ) ? *s_pDefExpanded : *s_pDefExpandedHC; 3603 } 3604 3605 // ----------------------------------------------------------------------- 3606 const Image& SvImpLBox::GetDefaultCollapsedNodeImage( BmpColorMode _eMode ) 3607 { 3608 implInitDefaultNodeImages(); 3609 return ( BMP_COLOR_NORMAL == _eMode ) ? *s_pDefCollapsed : *s_pDefCollapsedHC; 3610 } 3611 3612 // ----------------------------------------------------------------------- 3613 void SvImpLBox::CallEventListeners( sal_uLong nEvent, void* pData ) 3614 { 3615 if ( pView ) 3616 pView->CallImplEventListeners( nEvent, pData); 3617 } 3618 3619 // ----------------------------------------------------------------------- 3620 3621 bool SvImpLBox::SetCurrentTabPos( sal_uInt16 _nNewPos ) 3622 { 3623 bool bRet = false; 3624 3625 if ( pView && _nNewPos < ( pView->TabCount() - 2 ) ) 3626 { 3627 nCurTabPos = _nNewPos; 3628 ShowCursor( sal_True ); 3629 bRet = true; 3630 } 3631 3632 return bRet; 3633 } 3634 3635 // ----------------------------------------------------------------------- 3636 3637 bool SvImpLBox::IsSelectable( const SvLBoxEntry* pEntry ) 3638 { 3639 if( pEntry ) 3640 { 3641 SvViewDataEntry* pViewDataNewCur = pView->GetViewDataEntry(const_cast<SvLBoxEntry*>(pEntry)); 3642 return (pViewDataNewCur == 0) || pViewDataNewCur->IsSelectable(); 3643 } 3644 else 3645 { 3646 return false; 3647 } 3648 } 3649 3650