1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svtools.hxx" 30 #include <svtools/brwbox.hxx> 31 #include <svtools/brwhead.hxx> 32 #include "datwin.hxx" 33 #include <tools/debug.hxx> 34 #include <tools/stream.hxx> 35 36 #include <functional> 37 #include <algorithm> 38 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> 39 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> 40 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 41 #include <com/sun/star/accessibility/XAccessible.hpp> 42 #include <tools/multisel.hxx> 43 #include "brwimpl.hxx" 44 45 DBG_NAME(BrowseBox) 46 47 extern const char* BrowseBoxCheckInvariants( const void* pVoid ); 48 49 DECLARE_LIST( BrowserColumns, BrowserColumn* ) 50 51 #define SCROLL_FLAGS (SCROLL_CLIP | SCROLL_NOCHILDREN) 52 #define getDataWindow() ((BrowserDataWin*)pDataWin) 53 54 using namespace com::sun::star::accessibility::AccessibleEventId; 55 using namespace com::sun::star::accessibility::AccessibleTableModelChangeType; 56 using com::sun::star::accessibility::AccessibleTableModelChange; 57 using com::sun::star::lang::XComponent; 58 using namespace ::com::sun::star::uno; 59 using namespace svt; 60 61 //------------------------------------------------------------------- 62 63 #ifdef DBG_MI 64 void DoLog_Impl( const BrowseBox *pThis, const char *pWhat, const char *pWho ) 65 { 66 SvFileStream aLog( "d:\\cursor.log", STREAM_WRITE|STREAM_NOCREATE ); 67 if ( aLog.IsOpen() ) 68 { 69 aLog.Seek( STREAM_SEEK_TO_END ); 70 String aEntry( (long) pThis ); 71 aEntry += "(row="; 72 aEntry += pThis->GetCurRow(); 73 aEntry += "): "; 74 aEntry += pWhat; 75 aEntry += " from "; 76 aEntry += pWho; 77 aEntry += " => "; 78 aEntry += pThis->GetCursorHideCount(); 79 aLog.WriteLine( aEntry ); 80 } 81 } 82 #endif 83 84 namespace 85 { 86 void disposeAndClearHeaderCell(::svt::BrowseBoxImpl::THeaderCellMap& _rHeaderCell) 87 { 88 ::std::for_each( 89 _rHeaderCell.begin(), 90 _rHeaderCell.end(), 91 ::svt::BrowseBoxImpl::THeaderCellMapFunctorDispose() 92 ); 93 _rHeaderCell.clear(); 94 } 95 } 96 97 //=================================================================== 98 99 void BrowseBox::ConstructImpl( BrowserMode nMode ) 100 { 101 DBG_TRACE1( "BrowseBox: %p->ConstructImpl", this ); 102 bMultiSelection = sal_False; 103 pColSel = 0; 104 pDataWin = 0; 105 pVScroll = 0; 106 107 pDataWin = new BrowserDataWin( this ); 108 pCols = new BrowserColumns; 109 m_pImpl.reset( new ::svt::BrowseBoxImpl() ); 110 111 aGridLineColor = Color( COL_LIGHTGRAY ); 112 InitSettings_Impl( this ); 113 InitSettings_Impl( pDataWin ); 114 115 bBootstrapped = sal_False; 116 nDataRowHeight = 0; 117 nTitleLines = 1; 118 nFirstCol = 0; 119 nTopRow = 0; 120 nCurRow = BROWSER_ENDOFSELECTION; 121 nCurColId = 0; 122 bResizing = sal_False; 123 bSelect = sal_False; 124 bSelecting = sal_False; 125 bScrolling = sal_False; 126 bSelectionIsVisible = sal_False; 127 bNotToggleSel = sal_False; 128 bRowDividerDrag = sal_False; 129 bHit = sal_False; 130 mbInteractiveRowHeight = sal_False; 131 bHideSelect = sal_False; 132 bHideCursor = NO_CURSOR_HIDE; 133 nRowCount = 0; 134 m_bFocusOnlyCursor = sal_True; 135 m_aCursorColor = COL_TRANSPARENT; 136 m_nCurrentMode = 0; 137 nControlAreaWidth = USHRT_MAX; 138 uRow.nSel = BROWSER_ENDOFSELECTION; 139 140 aHScroll.SetLineSize(1); 141 aHScroll.SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) ); 142 aHScroll.SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) ); 143 pDataWin->Show(); 144 145 SetMode( nMode ); 146 bSelectionIsVisible = bKeepHighlight; 147 bHasFocus = HasChildPathFocus(); 148 getDataWindow()->nCursorHidden = 149 ( bHasFocus ? 0 : 1 ) + ( GetUpdateMode() ? 0 : 1 ); 150 LOG( this, "ConstructImpl", "*" ); 151 } 152 153 //------------------------------------------------------------------- 154 155 BrowseBox::BrowseBox( Window* pParent, WinBits nBits, BrowserMode nMode ) 156 :Control( pParent, nBits | WB_3DLOOK ) 157 ,DragSourceHelper( this ) 158 ,DropTargetHelper( this ) 159 ,aHScroll( this, WinBits( WB_HSCROLL ) ) 160 { 161 DBG_CTOR( BrowseBox, NULL ); 162 ConstructImpl( nMode ); 163 } 164 165 //------------------------------------------------------------------- 166 167 BrowseBox::BrowseBox( Window* pParent, const ResId& rId, BrowserMode nMode ) 168 :Control( pParent, rId ) 169 ,DragSourceHelper( this ) 170 ,DropTargetHelper( this ) 171 ,aHScroll( this, WinBits(WB_HSCROLL) ) 172 { 173 DBG_CTOR( BrowseBox, NULL ); 174 ConstructImpl(nMode); 175 } 176 //------------------------------------------------------------------- 177 178 BrowseBox::~BrowseBox() 179 { 180 DBG_DTOR(BrowseBox,BrowseBoxCheckInvariants); 181 DBG_TRACE1( "BrowseBox: %p~", this ); 182 183 if ( m_pImpl->m_pAccessible ) 184 { 185 disposeAndClearHeaderCell(m_pImpl->m_aColHeaderCellMap); 186 disposeAndClearHeaderCell(m_pImpl->m_aRowHeaderCellMap); 187 m_pImpl->m_pAccessible->dispose(); 188 } 189 190 Hide(); 191 delete getDataWindow()->pHeaderBar; 192 delete getDataWindow()->pCornerWin; 193 delete pDataWin; 194 delete pVScroll; 195 196 // free columns-space 197 for ( sal_uInt16 n = 0; n < pCols->Count(); ++n ) 198 delete pCols->GetObject(n); 199 delete pCols; 200 delete pColSel; 201 if ( bMultiSelection ) 202 delete uRow.pSel; 203 } 204 205 //------------------------------------------------------------------- 206 207 short BrowseBox::GetCursorHideCount() const 208 { 209 return getDataWindow()->nCursorHidden; 210 } 211 212 //------------------------------------------------------------------- 213 214 void BrowseBox::DoShowCursor( const char * 215 #ifdef DBG_MI 216 pWhoLogs 217 #endif 218 ) 219 { 220 short nHiddenCount = --getDataWindow()->nCursorHidden; 221 if (PaintCursorIfHiddenOnce()) 222 { 223 if (1 == nHiddenCount) 224 DrawCursor(); 225 } 226 else 227 { 228 if (0 == nHiddenCount) 229 DrawCursor(); 230 } 231 LOG( this, "DoShowCursor", pWhoLogs ); 232 } 233 234 //------------------------------------------------------------------- 235 236 void BrowseBox::DoHideCursor( const char * 237 #ifdef DBG_MI 238 pWhoLogs 239 #endif 240 ) 241 { 242 short nHiddenCount = ++getDataWindow()->nCursorHidden; 243 if (PaintCursorIfHiddenOnce()) 244 { 245 if (2 == nHiddenCount) 246 DrawCursor(); 247 } 248 else 249 { 250 if (1 == nHiddenCount) 251 DrawCursor(); 252 } 253 LOG( this, "DoHideCursor", pWhoLogs ); 254 } 255 256 //------------------------------------------------------------------- 257 258 void BrowseBox::SetRealRowCount( const String &rRealRowCount ) 259 { 260 getDataWindow()->aRealRowCount = rRealRowCount; 261 } 262 263 //------------------------------------------------------------------- 264 265 void BrowseBox::SetFont( const Font& rNewFont ) 266 { 267 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 268 pDataWin->SetFont( rNewFont ); 269 ImpGetDataRowHeight(); 270 } 271 272 //------------------------------------------------------------------- 273 274 sal_uLong BrowseBox::GetDefaultColumnWidth( const String& _rText ) const 275 { 276 return GetDataWindow().GetTextWidth( _rText ) + GetDataWindow().GetTextWidth( '0' ) * 4; 277 } 278 279 //------------------------------------------------------------------- 280 281 void BrowseBox::InsertHandleColumn( sal_uLong nWidth ) 282 { 283 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 284 285 pCols->Insert( new BrowserColumn( 0, Image(), String(), nWidth, GetZoom(), 0 ), (sal_uLong) 0 ); 286 FreezeColumn( 0 ); 287 288 // Headerbar anpassen 289 if ( getDataWindow()->pHeaderBar ) 290 { 291 getDataWindow()->pHeaderBar->SetPosSizePixel( 292 Point(nWidth, 0), 293 Size( GetOutputSizePixel().Width() - nWidth, GetTitleHeight() ) 294 ); 295 } 296 297 /*if ( getDataWindow()->pHeaderBar ) 298 getDataWindow()->pHeaderBar->InsertItem( USHRT_MAX - 1, 299 "", nWidth, HIB_FIXEDPOS|HIB_FIXED, 0 );*/ 300 ColumnInserted( 0 ); 301 } 302 303 //------------------------------------------------------------------- 304 void BrowseBox::InsertDataColumn( sal_uInt16 nItemId, const Image& rImage, 305 long nWidth, HeaderBarItemBits nBits, sal_uInt16 nPos ) 306 { 307 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 308 309 pCols->Insert( new BrowserColumn( nItemId, rImage, String(), nWidth, GetZoom(), nBits ), 310 Min( nPos, (sal_uInt16)(pCols->Count()) ) ); 311 if ( nCurColId == 0 ) 312 nCurColId = nItemId; 313 if ( getDataWindow()->pHeaderBar ) 314 { 315 // Handlecolumn nicht in der Headerbar 316 sal_uInt16 nHeaderPos = nPos; 317 if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0)) 318 nHeaderPos--; 319 getDataWindow()->pHeaderBar->InsertItem( 320 nItemId, rImage, nWidth, nBits, nHeaderPos ); 321 } 322 ColumnInserted( nPos ); 323 } 324 325 //------------------------------------------------------------------- 326 327 void BrowseBox::InsertDataColumn( sal_uInt16 nItemId, const XubString& rText, 328 long nWidth, HeaderBarItemBits nBits, sal_uInt16 nPos ) 329 { 330 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 331 332 pCols->Insert( new BrowserColumn( nItemId, Image(), rText, nWidth, GetZoom(), nBits ), 333 Min( nPos, (sal_uInt16)(pCols->Count()) ) ); 334 if ( nCurColId == 0 ) 335 nCurColId = nItemId; 336 337 if ( getDataWindow()->pHeaderBar ) 338 { 339 // Handlecolumn nicht in der Headerbar 340 sal_uInt16 nHeaderPos = nPos; 341 if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0)) 342 nHeaderPos--; 343 getDataWindow()->pHeaderBar->InsertItem( 344 nItemId, rText, nWidth, nBits, nHeaderPos ); 345 } 346 ColumnInserted( nPos ); 347 } 348 349 //------------------------------------------------------------------- 350 351 void BrowseBox::InsertDataColumn( sal_uInt16 nItemId, 352 const Image& rImage, const XubString& rText, 353 long nWidth, HeaderBarItemBits nBits, sal_uInt16 nPos, 354 const String* pHelpText ) 355 { 356 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 357 358 pCols->Insert( new BrowserColumn( nItemId, rImage, rText, nWidth, GetZoom(), nBits ), 359 Min( nPos, (sal_uInt16)(pCols->Count()) ) ); 360 if ( nCurColId == 0 ) 361 nCurColId = nItemId; 362 if ( getDataWindow()->pHeaderBar ) 363 { 364 // Handlecolumn nicht in der Headerbar 365 sal_uInt16 nHeaderPos = nPos; 366 if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0)) 367 nHeaderPos--; 368 369 getDataWindow()->pHeaderBar->InsertItem( 370 nItemId, rImage, rText, nWidth, nBits, nHeaderPos ); 371 if( pHelpText && !rText.Len() ) 372 { 373 getDataWindow()->pHeaderBar->SetHelpText( 374 nItemId, *pHelpText ); 375 } 376 } 377 ColumnInserted( nPos ); 378 } 379 //------------------------------------------------------------------- 380 sal_uInt16 BrowseBox::ToggleSelectedColumn() 381 { 382 sal_uInt16 nSelectedColId = USHRT_MAX; 383 if ( pColSel && pColSel->GetSelectCount() ) 384 { 385 DoHideCursor( "ToggleSelectedColumn" ); 386 ToggleSelection(); 387 nSelectedColId = pCols->GetObject(pColSel->FirstSelected())->GetId(); 388 pColSel->SelectAll(sal_False); 389 } 390 return nSelectedColId; 391 } 392 // ----------------------------------------------------------------------------- 393 void BrowseBox::SetToggledSelectedColumn(sal_uInt16 _nSelectedColumnId) 394 { 395 if ( pColSel && _nSelectedColumnId != USHRT_MAX ) 396 { 397 pColSel->Select( GetColumnPos( _nSelectedColumnId ) ); 398 ToggleSelection(); 399 DBG_TRACE1( "BrowseBox: %p->SetToggledSelectedColumn", this ); 400 DoShowCursor( "SetToggledSelectedColumn" ); 401 } 402 } 403 // ----------------------------------------------------------------------------- 404 void BrowseBox::FreezeColumn( sal_uInt16 nItemId, sal_Bool bFreeze ) 405 { 406 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 407 408 // never unfreeze the handle-column 409 if ( nItemId == 0 && !bFreeze ) 410 return; 411 412 // get the position in the current array 413 sal_uInt16 nItemPos = GetColumnPos( nItemId ); 414 if ( nItemPos >= pCols->Count() ) 415 // not available! 416 return; 417 418 // doesn't the state change? 419 if ( pCols->GetObject(nItemPos)->IsFrozen() == bFreeze ) 420 return; 421 422 // remark the column selection 423 sal_uInt16 nSelectedColId = ToggleSelectedColumn(); 424 425 // freeze or unfreeze? 426 if ( bFreeze ) 427 { 428 // to be moved? 429 if ( nItemPos != 0 && !pCols->GetObject(nItemPos-1)->IsFrozen() ) 430 { 431 // move to the right of the last frozen column 432 sal_uInt16 nFirstScrollable = FrozenColCount(); 433 BrowserColumn *pColumn = pCols->GetObject(nItemPos); 434 pCols->Remove( (sal_uLong) nItemPos ); 435 nItemPos = nFirstScrollable; 436 pCols->Insert( pColumn, (sal_uLong) nItemPos ); 437 } 438 439 // adjust the number of the first scrollable and visible column 440 if ( nFirstCol <= nItemPos ) 441 nFirstCol = nItemPos + 1; 442 } 443 else 444 { 445 // to be moved? 446 if ( nItemPos != FrozenColCount()-1 ) 447 { 448 // move to the leftmost scrollable colum 449 sal_uInt16 nFirstScrollable = FrozenColCount(); 450 BrowserColumn *pColumn = pCols->GetObject(nItemPos); 451 pCols->Remove( (sal_uLong) nItemPos ); 452 nItemPos = nFirstScrollable; 453 pCols->Insert( pColumn, (sal_uLong) nItemPos ); 454 } 455 456 // adjust the number of the first scrollable and visible column 457 nFirstCol = nItemPos; 458 } 459 460 // toggle the freeze-state of the column 461 pCols->GetObject(nItemPos)->Freeze( bFreeze ); 462 463 // align the scrollbar-range 464 UpdateScrollbars(); 465 466 // repaint 467 Control::Invalidate(); 468 getDataWindow()->Invalidate(); 469 470 // remember the column selection 471 SetToggledSelectedColumn(nSelectedColId); 472 } 473 474 //------------------------------------------------------------------- 475 476 void BrowseBox::SetColumnPos( sal_uInt16 nColumnId, sal_uInt16 nPos ) 477 { 478 // never set pos of the handle-column 479 if ( nColumnId == 0 ) 480 return; 481 482 // do not move handle column 483 if (nPos == 0 && !pCols->GetObject(0)->GetId()) 484 return; 485 486 // get the position in the current array 487 sal_uInt16 nOldPos = GetColumnPos( nColumnId ); 488 if ( nOldPos >= pCols->Count() ) 489 // not available! 490 return; 491 492 // does the state change? 493 if (nOldPos != nPos) 494 { 495 // remark the column selection 496 sal_uInt16 nSelectedColId = ToggleSelectedColumn(); 497 498 // determine old column area 499 Size aDataWinSize( pDataWin->GetSizePixel() ); 500 if ( getDataWindow()->pHeaderBar ) 501 aDataWinSize.Height() += getDataWindow()->pHeaderBar->GetSizePixel().Height(); 502 503 Rectangle aFromRect( GetFieldRect( nColumnId) ); 504 aFromRect.Right() += 2*MIN_COLUMNWIDTH; 505 506 sal_uInt16 nNextPos = nOldPos + 1; 507 if ( nOldPos > nPos ) 508 nNextPos = nOldPos - 1; 509 510 BrowserColumn *pNextCol = pCols->GetObject(nNextPos); 511 Rectangle aNextRect(GetFieldRect( pNextCol->GetId() )); 512 513 // move column internally 514 pCols->Insert( pCols->Remove( nOldPos ), nPos ); 515 516 // determine new column area 517 Rectangle aToRect( GetFieldRect( nColumnId ) ); 518 aToRect.Right() += 2*MIN_COLUMNWIDTH; 519 520 // do scroll, let redraw 521 if( pDataWin->GetBackground().IsScrollable() ) 522 { 523 long nScroll = -aFromRect.GetWidth(); 524 Rectangle aScrollArea; 525 if ( nOldPos > nPos ) 526 { 527 long nFrozenWidth = GetFrozenWidth(); 528 if ( aToRect.Left() < nFrozenWidth ) 529 aToRect.Left() = nFrozenWidth; 530 aScrollArea = Rectangle(Point(aToRect.Left(),0), 531 Point(aNextRect.Right(),aDataWinSize.Height())); 532 nScroll *= -1; // reverse direction 533 } 534 else 535 aScrollArea = Rectangle(Point(aNextRect.Left(),0), 536 Point(aToRect.Right(),aDataWinSize.Height())); 537 538 pDataWin->Scroll( nScroll, 0, aScrollArea ); 539 aToRect.Top() = 0; 540 aToRect.Bottom() = aScrollArea.Bottom(); 541 Invalidate( aToRect ); 542 } 543 else 544 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN ); 545 546 // adjust header bar positions 547 if ( getDataWindow()->pHeaderBar ) 548 { 549 sal_uInt16 nNewPos = nPos; 550 if ( !GetColumnId(0) ) 551 --nNewPos; 552 getDataWindow()->pHeaderBar->MoveItem(nColumnId,nNewPos); 553 } 554 // remember the column selection 555 SetToggledSelectedColumn(nSelectedColId); 556 557 if ( isAccessibleAlive() ) 558 { 559 commitTableEvent( 560 TABLE_MODEL_CHANGED, 561 makeAny( AccessibleTableModelChange( 562 DELETE, 563 0, 564 GetRowCount(), 565 nOldPos, 566 nOldPos 567 ) 568 ), 569 Any() 570 ); 571 572 commitTableEvent( 573 TABLE_MODEL_CHANGED, 574 makeAny( AccessibleTableModelChange( 575 INSERT, 576 0, 577 GetRowCount(), 578 nPos, 579 nPos 580 ) 581 ), 582 Any() 583 ); 584 } 585 } 586 587 } 588 589 //------------------------------------------------------------------- 590 591 void BrowseBox::SetColumnMode( sal_uInt16 nColumnId, BrowserColumnMode nFlags ) 592 { 593 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 594 595 // never set mode of the handle-column 596 if ( nColumnId == 0 ) 597 return; 598 599 // get the position in the current array 600 sal_uInt16 nColumnPos = GetColumnPos( nColumnId ); 601 if ( nColumnPos >= pCols->Count() ) 602 // not available! 603 return; 604 605 // does the state change? 606 BrowserColumn *pCol = pCols->GetObject(nColumnPos); 607 if ( pCol->Flags() != nFlags ) 608 { 609 pCol->Flags() = sal::static_int_cast< HeaderBarItemBits >(nFlags); 610 611 // redraw visible colums 612 if ( GetUpdateMode() && ( pCol->IsFrozen() || nColumnPos > nFirstCol ) ) 613 Invalidate( Rectangle( Point(0,0), 614 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) ); 615 } 616 } 617 618 //------------------------------------------------------------------- 619 620 void BrowseBox::SetColumnTitle( sal_uInt16 nItemId, const String& rTitle ) 621 { 622 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 623 624 // never set title of the handle-column 625 if ( nItemId == 0 ) 626 return; 627 628 // get the position in the current array 629 sal_uInt16 nItemPos = GetColumnPos( nItemId ); 630 if ( nItemPos >= pCols->Count() ) 631 // not available! 632 return; 633 634 // does the state change? 635 BrowserColumn *pCol = pCols->GetObject(nItemPos); 636 if ( pCol->Title() != rTitle ) 637 { 638 ::rtl::OUString sNew(rTitle); 639 ::rtl::OUString sOld(pCol->Title()); 640 641 pCol->Title() = rTitle; 642 643 // Headerbar-Column anpassen 644 if ( getDataWindow()->pHeaderBar ) 645 getDataWindow()->pHeaderBar->SetItemText( 646 nItemId ? nItemId : USHRT_MAX - 1, rTitle ); 647 else 648 { 649 // redraw visible colums 650 if ( GetUpdateMode() && ( pCol->IsFrozen() || nItemPos > nFirstCol ) ) 651 Invalidate( Rectangle( Point(0,0), 652 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) ); 653 } 654 655 if ( isAccessibleAlive() ) 656 { 657 commitTableEvent( TABLE_COLUMN_DESCRIPTION_CHANGED, 658 makeAny( sNew ), 659 makeAny( sOld ) 660 ); 661 } 662 } 663 } 664 665 //------------------------------------------------------------------- 666 667 void BrowseBox::SetColumnWidth( sal_uInt16 nItemId, sal_uLong nWidth ) 668 { 669 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 670 671 // get the position in the current array 672 sal_uInt16 nItemPos = GetColumnPos( nItemId ); 673 if ( nItemPos >= pCols->Count() ) 674 return; 675 676 // does the state change? 677 nWidth = QueryColumnResize( nItemId, nWidth ); 678 if ( nWidth >= LONG_MAX || pCols->GetObject(nItemPos)->Width() != nWidth ) 679 { 680 long nOldWidth = pCols->GetObject(nItemPos)->Width(); 681 682 // ggf. letzte Spalte anpassen 683 if ( IsVisible() && nItemPos == pCols->Count() - 1 ) 684 { 685 long nMaxWidth = pDataWin->GetSizePixel().Width(); 686 nMaxWidth -= getDataWindow()->bAutoSizeLastCol 687 ? GetFieldRect(nItemId).Left() 688 : GetFrozenWidth(); 689 if ( ( (BrowserDataWin*)pDataWin )->bAutoSizeLastCol || nWidth > (sal_uLong)nMaxWidth ) 690 { 691 nWidth = nMaxWidth > 16 ? nMaxWidth : nOldWidth; 692 nWidth = QueryColumnResize( nItemId, nWidth ); 693 } 694 } 695 696 // OV 697 // In AutoSizeLastColumn() wird SetColumnWidth mit nWidth==0xffff 698 // gerufen. Deshalb muss hier nochmal geprueft werden, ob sich die 699 // Breite tatsaechlich geaendert hat. 700 if( (sal_uLong)nOldWidth == nWidth ) 701 return; 702 703 // soll die Aenderung sofort dargestellt werden? 704 sal_Bool bUpdate = GetUpdateMode() && 705 ( pCols->GetObject(nItemPos)->IsFrozen() || nItemPos >= nFirstCol ); 706 707 if ( bUpdate ) 708 { 709 // Selection hiden 710 DoHideCursor( "SetColumnWidth" ); 711 ToggleSelection(); 712 //!getDataWindow()->Update(); 713 //!Control::Update(); 714 } 715 716 // Breite setzen 717 pCols->GetObject(nItemPos)->SetWidth(nWidth, GetZoom()); 718 #if 0 719 if ( nItemPos != pCols->Count() - 1 ) 720 { 721 long nLastColMaxWidth = pDataWin->GetSizePixel().Width() - 722 GetFieldRect(GetColumnId(pCols->Count()-1)).Left(); 723 pCols->GetObject(pCols->Count()-1)->Width() = nLastColMaxWidth; 724 } 725 #endif 726 727 // scroll and invalidate 728 if ( bUpdate ) 729 { 730 // X-Pos der veraenderten Spalte ermitteln 731 long nX = 0; 732 for ( sal_uInt16 nCol = 0; nCol < nItemPos; ++nCol ) 733 { 734 BrowserColumn *pCol = pCols->GetObject(nCol); 735 if ( pCol->IsFrozen() || nCol >= nFirstCol ) 736 nX += pCol->Width(); 737 } 738 739 // eigentliches scroll+invalidate 740 pDataWin->SetClipRegion(); 741 sal_Bool bSelVis = bSelectionIsVisible; 742 bSelectionIsVisible = sal_False; 743 if( GetBackground().IsScrollable() ) 744 { 745 746 Rectangle aScrRect( nX + std::min( (sal_uLong)nOldWidth, nWidth ), 0, 747 GetSizePixel().Width() , // the header is longer than the datawin 748 pDataWin->GetPosPixel().Y() - 1 ); 749 Control::Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS ); 750 aScrRect.Bottom() = pDataWin->GetSizePixel().Height(); 751 getDataWindow()->Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS ); 752 Rectangle aInvRect( nX, 0, nX + std::max( nWidth, (sal_uLong)nOldWidth ), USHRT_MAX ); 753 Control::Invalidate( aInvRect, INVALIDATE_NOCHILDREN ); 754 ( (BrowserDataWin*)pDataWin )->Invalidate( aInvRect ); 755 } 756 else 757 { 758 Control::Invalidate( INVALIDATE_NOCHILDREN ); 759 getDataWindow()->Window::Invalidate( INVALIDATE_NOCHILDREN ); 760 } 761 762 763 //!getDataWindow()->Update(); 764 //!Control::Update(); 765 bSelectionIsVisible = bSelVis; 766 ToggleSelection(); 767 DoShowCursor( "SetColumnWidth" ); 768 } 769 UpdateScrollbars(); 770 771 // Headerbar-Column anpassen 772 if ( getDataWindow()->pHeaderBar ) 773 getDataWindow()->pHeaderBar->SetItemSize( 774 nItemId ? nItemId : USHRT_MAX - 1, nWidth ); 775 776 // adjust last column 777 if ( nItemPos != pCols->Count() - 1 ) 778 AutoSizeLastColumn(); 779 780 } 781 } 782 783 //------------------------------------------------------------------- 784 785 void BrowseBox::AutoSizeLastColumn() 786 { 787 if ( getDataWindow()->bAutoSizeLastCol && 788 getDataWindow()->GetUpdateMode() ) 789 { 790 sal_uInt16 nId = GetColumnId( (sal_uInt16)pCols->Count() - 1 ); 791 SetColumnWidth( nId, LONG_MAX ); 792 ColumnResized( nId ); 793 } 794 } 795 796 //------------------------------------------------------------------- 797 798 void BrowseBox::RemoveColumn( sal_uInt16 nItemId ) 799 { 800 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 801 802 // Spaltenposition ermitteln 803 sal_uInt16 nPos = GetColumnPos(nItemId); 804 if ( nPos >= ColCount() ) 805 // nicht vorhanden 806 return; 807 808 // Spaltenselektion korrigieren 809 if ( pColSel ) 810 pColSel->Remove( nPos ); 811 812 // Spaltencursor korrigieren 813 if ( nCurColId == nItemId ) 814 nCurColId = 0; 815 816 // Spalte entfernen 817 delete( pCols->Remove( (sal_uLong) nPos )); 818 // OJ #93534# 819 if ( nFirstCol >= nPos && nFirstCol > FrozenColCount() ) 820 { 821 OSL_ENSURE(nFirstCol > 0,"FirstCol must be greater zero!"); 822 --nFirstCol; 823 } 824 825 // Handlecolumn nicht in der Headerbar 826 if (nItemId) 827 { 828 if ( getDataWindow()->pHeaderBar ) 829 getDataWindow()->pHeaderBar->RemoveItem( nItemId ); 830 } 831 else 832 { 833 // Headerbar anpassen 834 if ( getDataWindow()->pHeaderBar ) 835 { 836 getDataWindow()->pHeaderBar->SetPosSizePixel( 837 Point(0, 0), 838 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) 839 ); 840 } 841 } 842 843 // vertikalen Scrollbar korrigieren 844 UpdateScrollbars(); 845 846 // ggf. Repaint ausl"osen 847 if ( GetUpdateMode() ) 848 { 849 getDataWindow()->Invalidate(); 850 Control::Invalidate(); 851 if ( getDataWindow()->bAutoSizeLastCol && nPos ==ColCount() ) 852 SetColumnWidth( GetColumnId( nPos - 1 ), LONG_MAX ); 853 } 854 855 if ( isAccessibleAlive() ) 856 { 857 commitTableEvent( 858 TABLE_MODEL_CHANGED, 859 makeAny( AccessibleTableModelChange( DELETE, 860 0, 861 GetRowCount(), 862 nPos, 863 nPos 864 ) 865 ), 866 Any() 867 ); 868 869 commitHeaderBarEvent( 870 CHILD, 871 Any(), 872 makeAny( CreateAccessibleColumnHeader( nPos ) ), 873 sal_True 874 ); 875 } 876 } 877 878 //------------------------------------------------------------------- 879 880 void BrowseBox::RemoveColumns() 881 { 882 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 883 884 unsigned int nOldCount = pCols->Count(); 885 // alle Spalten entfernen 886 while ( pCols->Count() ) 887 delete ( pCols->Remove( (sal_uLong) 0 )); 888 889 // Spaltenselektion korrigieren 890 if ( pColSel ) 891 { 892 pColSel->SelectAll(sal_False); 893 pColSel->SetTotalRange( Range( 0, 0 ) ); 894 } 895 896 // Spaltencursor korrigieren 897 nCurColId = 0; 898 nFirstCol = 0; 899 900 if ( getDataWindow()->pHeaderBar ) 901 getDataWindow()->pHeaderBar->Clear( ); 902 903 // vertikalen Scrollbar korrigieren 904 UpdateScrollbars(); 905 906 // ggf. Repaint ausl"osen 907 if ( GetUpdateMode() ) 908 { 909 getDataWindow()->Invalidate(); 910 Control::Invalidate(); 911 } 912 913 if ( isAccessibleAlive() ) 914 { 915 if ( pCols->Count() != nOldCount ) 916 { 917 // all columns should be removed, so we remove the column header bar and append it again 918 // to avoid to notify every column remove 919 commitBrowseBoxEvent( 920 CHILD, 921 Any(), 922 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR)) 923 ); 924 925 // and now append it again 926 commitBrowseBoxEvent( 927 CHILD, 928 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR)), 929 Any() 930 ); 931 932 // notify a table model change 933 commitTableEvent( 934 TABLE_MODEL_CHANGED, 935 makeAny ( AccessibleTableModelChange( DELETE, 936 0, 937 GetRowCount(), 938 0, 939 nOldCount 940 ) 941 ), 942 Any() 943 ); 944 } 945 } 946 } 947 948 //------------------------------------------------------------------- 949 950 String BrowseBox::GetColumnTitle( sal_uInt16 nId ) const 951 { 952 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 953 954 sal_uInt16 nItemPos = GetColumnPos( nId ); 955 if ( nItemPos >= pCols->Count() ) 956 return String(); 957 return pCols->GetObject(nItemPos)->Title(); 958 } 959 960 //------------------------------------------------------------------- 961 962 long BrowseBox::GetRowCount() const 963 { 964 return nRowCount; 965 } 966 967 //------------------------------------------------------------------- 968 969 sal_uInt16 BrowseBox::ColCount() const 970 { 971 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 972 973 return (sal_uInt16) pCols->Count(); 974 } 975 976 //------------------------------------------------------------------- 977 978 long BrowseBox::ImpGetDataRowHeight() const 979 { 980 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 981 982 BrowseBox *pThis = (BrowseBox*)this; 983 pThis->nDataRowHeight = pThis->CalcReverseZoom(pDataWin->GetTextHeight() + 2); 984 pThis->Resize(); 985 getDataWindow()->Invalidate(); 986 return nDataRowHeight; 987 } 988 989 //------------------------------------------------------------------- 990 991 void BrowseBox::SetDataRowHeight( long nPixel ) 992 { 993 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 994 995 nDataRowHeight = CalcReverseZoom(nPixel); 996 Resize(); 997 getDataWindow()->Invalidate(); 998 } 999 1000 //------------------------------------------------------------------- 1001 1002 void BrowseBox::SetTitleLines( sal_uInt16 nLines ) 1003 { 1004 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1005 1006 nTitleLines = nLines; 1007 } 1008 1009 //------------------------------------------------------------------- 1010 1011 long BrowseBox::ScrollColumns( long nCols ) 1012 { 1013 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1014 1015 if ( nFirstCol + nCols < 0 || 1016 nFirstCol + nCols >= (long)pCols->Count() ) 1017 //?MI: pCols->GetObject( nFirstCol + nCols )->IsFrozen() ) 1018 return 0; 1019 1020 // implicitly hides cursor while scrolling 1021 StartScroll(); 1022 bScrolling = sal_True; 1023 sal_Bool bScrollable = pDataWin->GetBackground().IsScrollable(); 1024 sal_Bool bInvalidateView = sal_False; 1025 1026 // scrolling one column to the right? 1027 if ( nCols == 1 ) 1028 { 1029 // update internal value and scrollbar 1030 ++nFirstCol; 1031 aHScroll.SetThumbPos( nFirstCol - FrozenColCount() ); 1032 1033 if ( !bScrollable ) 1034 { 1035 bInvalidateView = sal_True; 1036 } 1037 else 1038 { 1039 long nDelta = pCols->GetObject(nFirstCol-1)->Width(); 1040 long nFrozenWidth = GetFrozenWidth(); 1041 1042 Rectangle aScrollRect( Point( nFrozenWidth + nDelta, 0 ), 1043 Size ( GetOutputSizePixel().Width() - nFrozenWidth - nDelta, 1044 GetTitleHeight() - 1 1045 ) ); 1046 1047 // scroll the header bar area (if there is no dedicated HeaderBar control) 1048 if ( !getDataWindow()->pHeaderBar && nTitleLines ) 1049 { 1050 // actually scroll 1051 Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS ); 1052 1053 // invalidate the area of the column which was scrolled out to the left hand side 1054 Rectangle aInvalidateRect( aScrollRect ); 1055 aInvalidateRect.Left() = nFrozenWidth; 1056 aInvalidateRect.Right() = nFrozenWidth + nDelta - 1; 1057 Invalidate( aInvalidateRect ); 1058 } 1059 1060 // scroll the data-area 1061 aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height(); 1062 1063 // actually scroll 1064 pDataWin->Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS ); 1065 1066 // invalidate the area of the column which was scrolled out to the left hand side 1067 aScrollRect.Left() = nFrozenWidth; 1068 aScrollRect.Right() = nFrozenWidth + nDelta - 1; 1069 getDataWindow()->Invalidate( aScrollRect ); 1070 } 1071 } 1072 1073 // scrolling one column to the left? 1074 else if ( nCols == -1 ) 1075 { 1076 --nFirstCol; 1077 aHScroll.SetThumbPos( nFirstCol - FrozenColCount() ); 1078 1079 if ( !bScrollable ) 1080 { 1081 bInvalidateView = sal_True; 1082 } 1083 else 1084 { 1085 long nDelta = pCols->GetObject(nFirstCol)->Width(); 1086 long nFrozenWidth = GetFrozenWidth(); 1087 1088 Rectangle aScrollRect( Point( nFrozenWidth, 0 ), 1089 Size ( GetOutputSizePixel().Width() - nFrozenWidth, 1090 GetTitleHeight() - 1 1091 ) ); 1092 1093 // scroll the header bar area (if there is no dedicated HeaderBar control) 1094 if ( !getDataWindow()->pHeaderBar && nTitleLines ) 1095 { 1096 Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS ); 1097 } 1098 1099 // scroll the data-area 1100 aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height(); 1101 pDataWin->Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS ); 1102 } 1103 } 1104 else 1105 { 1106 if ( GetUpdateMode() ) 1107 { 1108 Invalidate( Rectangle( 1109 Point( GetFrozenWidth(), 0 ), 1110 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) ); 1111 getDataWindow()->Invalidate( Rectangle( 1112 Point( GetFrozenWidth(), 0 ), 1113 pDataWin->GetSizePixel() ) ); 1114 } 1115 1116 nFirstCol = nFirstCol + (sal_uInt16)nCols; 1117 aHScroll.SetThumbPos( nFirstCol - FrozenColCount() ); 1118 } 1119 1120 // ggf. externe Headerbar anpassen 1121 if ( getDataWindow()->pHeaderBar ) 1122 { 1123 long nWidth = 0; 1124 for ( sal_uInt16 nCol = 0; 1125 nCol < pCols->Count() && nCol < nFirstCol; 1126 ++nCol ) 1127 { 1128 // HandleColumn nicht 1129 if ( pCols->GetObject(nCol)->GetId() ) 1130 nWidth += pCols->GetObject(nCol)->Width(); 1131 } 1132 1133 getDataWindow()->pHeaderBar->SetOffset( nWidth ); 1134 } 1135 1136 if( bInvalidateView ) 1137 { 1138 Control::Invalidate( INVALIDATE_NOCHILDREN ); 1139 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN ); 1140 } 1141 1142 // implicitly show cursor after scrolling 1143 if ( nCols ) 1144 { 1145 getDataWindow()->Update(); 1146 Update(); 1147 } 1148 bScrolling = sal_False; 1149 EndScroll(); 1150 1151 return nCols; 1152 } 1153 1154 //------------------------------------------------------------------- 1155 1156 long BrowseBox::ScrollRows( long nRows ) 1157 { 1158 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1159 1160 // out of range? 1161 if ( getDataWindow()->bNoScrollBack && nRows < 0 ) 1162 return 0; 1163 1164 // compute new top row 1165 long nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) ); 1166 1167 long nNewTopRow = Max( (long)nTmpMin, (long)0 ); 1168 1169 if ( nNewTopRow == nTopRow ) 1170 return 0; 1171 1172 sal_uInt16 nVisibleRows = 1173 (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1); 1174 1175 VisibleRowsChanged(nNewTopRow, nVisibleRows); 1176 1177 // compute new top row again (nTopRow might have changed!) 1178 nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) ); 1179 1180 nNewTopRow = Max( (long)nTmpMin, (long)0 ); 1181 1182 StartScroll(); 1183 1184 // scroll area on screen and/or repaint 1185 long nDeltaY = GetDataRowHeight() * ( nNewTopRow - nTopRow ); 1186 long nOldTopRow = nTopRow; 1187 nTopRow = nNewTopRow; 1188 1189 if ( GetUpdateMode() ) 1190 { 1191 pVScroll->SetRange( Range( 0L, nRowCount ) ); 1192 pVScroll->SetThumbPos( nTopRow ); 1193 1194 if( pDataWin->GetBackground().IsScrollable() && 1195 Abs( nDeltaY ) > 0 && 1196 Abs( nDeltaY ) < pDataWin->GetSizePixel().Height() ) 1197 { 1198 pDataWin->Scroll( 0, (short)-nDeltaY, SCROLL_FLAGS ); 1199 } 1200 else 1201 getDataWindow()->Invalidate(); 1202 1203 if ( nTopRow - nOldTopRow ) 1204 getDataWindow()->Update(); 1205 } 1206 1207 EndScroll(); 1208 1209 return nTopRow - nOldTopRow; 1210 } 1211 1212 //------------------------------------------------------------------- 1213 1214 long BrowseBox::ScrollPages( long ) 1215 { 1216 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1217 1218 return ScrollRows( pDataWin->GetSizePixel().Height() / GetDataRowHeight() ); 1219 } 1220 1221 //------------------------------------------------------------------- 1222 1223 void BrowseBox::RowModified( long nRow, sal_uInt16 nColId ) 1224 { 1225 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1226 1227 if ( !GetUpdateMode() ) 1228 return; 1229 1230 Rectangle aRect; 1231 if ( nColId == USHRT_MAX ) 1232 // invalidate the whole row 1233 aRect = Rectangle( Point( 0, (nRow-nTopRow) * GetDataRowHeight() ), 1234 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ); 1235 else 1236 { 1237 // invalidate the specific field 1238 aRect = GetFieldRectPixel( nRow, nColId, sal_False ); 1239 } 1240 getDataWindow()->Invalidate( aRect ); 1241 } 1242 1243 //------------------------------------------------------------------- 1244 1245 void BrowseBox::Clear() 1246 { 1247 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1248 1249 // adjust the total number of rows 1250 DoHideCursor( "Clear" ); 1251 long nOldRowCount = nRowCount; 1252 nRowCount = 0; 1253 nCurRow = BROWSER_ENDOFSELECTION; 1254 nTopRow = 0; 1255 nCurColId = 0; 1256 1257 // nFirstCol darf nicht zurueckgesetzt werden, da ansonsten das Scrollen 1258 // total durcheinander kommt 1259 // nFirstCol darf nur beim Hinzufuegen oder Loeschen von Spalten geaendert werden 1260 // nFirstCol = 0; ->Falsch!!!! 1261 aHScroll.SetThumbPos( 0 ); 1262 pVScroll->SetThumbPos( 0 ); 1263 1264 Invalidate(); 1265 UpdateScrollbars(); 1266 SetNoSelection(); 1267 DoShowCursor( "Clear" ); 1268 CursorMoved(); 1269 1270 if ( isAccessibleAlive() ) 1271 { 1272 // all rows should be removed, so we remove the row header bar and append it again 1273 // to avoid to notify every row remove 1274 if ( nOldRowCount != nRowCount ) 1275 { 1276 commitBrowseBoxEvent( 1277 CHILD, 1278 Any(), 1279 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) ) 1280 ); 1281 1282 // and now append it again 1283 commitBrowseBoxEvent( 1284 CHILD, 1285 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) ), 1286 Any() 1287 ); 1288 1289 // notify a table model change 1290 commitTableEvent( 1291 TABLE_MODEL_CHANGED, 1292 makeAny( AccessibleTableModelChange( DELETE, 1293 0, 1294 nOldRowCount, 1295 0, 1296 GetColumnCount()) 1297 ), 1298 Any() 1299 ); 1300 } 1301 } 1302 } 1303 // ----------------------------------------------------------------------------- 1304 void BrowseBox::RowInserted( long nRow, long nNumRows, sal_Bool bDoPaint, sal_Bool bKeepSelection ) 1305 { 1306 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1307 1308 if (nRow < 0) 1309 nRow = 0; 1310 else if (nRow > nRowCount) // maximal = nRowCount 1311 nRow = nRowCount; 1312 1313 if ( nNumRows <= 0 ) 1314 return; 1315 1316 #if 0 1317 // Zerlegung in einzelne RowInserted-Aufrufe: 1318 if (nNumRows > 1) 1319 { 1320 for (long i = 0; i < nNumRows; i++) 1321 RowInserted(nRow + i,1,bDoPaint); 1322 return; 1323 } 1324 #endif 1325 1326 // adjust total row count 1327 sal_Bool bLastRow = nRow >= nRowCount; 1328 nRowCount += nNumRows; 1329 1330 DoHideCursor( "RowInserted" ); 1331 1332 // must we paint the new rows? 1333 long nOldCurRow = nCurRow; 1334 Size aSz = pDataWin->GetOutputSizePixel(); 1335 if ( bDoPaint && nRow >= nTopRow && 1336 nRow <= nTopRow + aSz.Height() / GetDataRowHeight() ) 1337 { 1338 long nY = (nRow-nTopRow) * GetDataRowHeight(); 1339 if ( !bLastRow ) 1340 { 1341 // scroll down the rows behind the new row 1342 pDataWin->SetClipRegion(); 1343 if( pDataWin->GetBackground().IsScrollable() ) 1344 { 1345 pDataWin->Scroll( 0, GetDataRowHeight() * nNumRows, 1346 Rectangle( Point( 0, nY ), 1347 Size( aSz.Width(), aSz.Height() - nY ) ), 1348 SCROLL_FLAGS ); 1349 } 1350 else 1351 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN ); 1352 } 1353 else 1354 // scroll would cause a repaint, so we must explicitly invalidate 1355 pDataWin->Invalidate( Rectangle( Point( 0, nY ), 1356 Size( aSz.Width(), nNumRows * GetDataRowHeight() ) ) ); 1357 } 1358 1359 // ggf. Top-Row korrigieren 1360 if ( nRow < nTopRow ) 1361 nTopRow += nNumRows; 1362 1363 // adjust the selection 1364 if ( bMultiSelection ) 1365 uRow.pSel->Insert( nRow, nNumRows ); 1366 else if ( uRow.nSel != BROWSER_ENDOFSELECTION && nRow <= uRow.nSel ) 1367 uRow.nSel += nNumRows; 1368 1369 // adjust the cursor 1370 if ( nCurRow == BROWSER_ENDOFSELECTION ) 1371 GoToRow( 0, sal_False, bKeepSelection ); 1372 else if ( nRow <= nCurRow ) 1373 GoToRow( nCurRow += nNumRows, sal_False, bKeepSelection ); 1374 1375 // adjust the vertical scrollbar 1376 if ( bDoPaint ) 1377 { 1378 UpdateScrollbars(); 1379 AutoSizeLastColumn(); 1380 } 1381 1382 DoShowCursor( "RowInserted" ); 1383 // notify accessible that rows were inserted 1384 if ( isAccessibleAlive() ) 1385 { 1386 commitTableEvent( 1387 TABLE_MODEL_CHANGED, 1388 makeAny( AccessibleTableModelChange( 1389 INSERT, 1390 nRow, 1391 nRow + nNumRows, 1392 0, 1393 GetColumnCount() 1394 ) 1395 ), 1396 Any() 1397 ); 1398 1399 for (sal_Int32 i = nRow+1 ; i <= nRowCount ; ++i) 1400 { 1401 commitHeaderBarEvent( 1402 CHILD, 1403 makeAny( CreateAccessibleRowHeader( i ) ), 1404 Any(), 1405 sal_False 1406 ); 1407 } 1408 } 1409 1410 if ( nCurRow != nOldCurRow ) 1411 CursorMoved(); 1412 1413 DBG_ASSERT(nRowCount > 0,"BrowseBox: nRowCount <= 0"); 1414 DBG_ASSERT(nCurRow >= 0,"BrowseBox: nCurRow < 0"); 1415 DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount"); 1416 } 1417 1418 //------------------------------------------------------------------- 1419 1420 void BrowseBox::RowRemoved( long nRow, long nNumRows, sal_Bool bDoPaint ) 1421 { 1422 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1423 1424 if ( nRow < 0 ) 1425 nRow = 0; 1426 else if ( nRow >= nRowCount ) 1427 nRow = nRowCount - 1; 1428 1429 if ( nNumRows <= 0 ) 1430 return; 1431 1432 if ( nRowCount <= 0 ) 1433 return; 1434 1435 if ( bDoPaint ) 1436 { 1437 // hide cursor and selection 1438 DBG_TRACE1( "BrowseBox: %p->HideCursor", this ); 1439 ToggleSelection(); 1440 DoHideCursor( "RowRemoved" ); 1441 } 1442 1443 // adjust total row count 1444 nRowCount -= nNumRows; 1445 if (nRowCount < 0) nRowCount = 0; 1446 long nOldCurRow = nCurRow; 1447 1448 // adjust the selection 1449 if ( bMultiSelection ) 1450 // uRow.pSel->Remove( nRow, nNumRows ); 1451 for ( long i = 0; i < nNumRows; i++ ) 1452 uRow.pSel->Remove( nRow ); 1453 else if ( nRow < uRow.nSel && uRow.nSel >= nNumRows ) 1454 uRow.nSel -= nNumRows; 1455 else if ( nRow <= uRow.nSel ) 1456 uRow.nSel = BROWSER_ENDOFSELECTION; 1457 1458 // adjust the cursor 1459 if ( nRowCount == 0 ) // don't compare nRowCount with nNumRows as nNumRows already was subtracted from nRowCount 1460 nCurRow = BROWSER_ENDOFSELECTION; 1461 else if ( nRow < nCurRow ) 1462 { 1463 nCurRow -= Min( nCurRow - nRow, nNumRows ); 1464 // with the above nCurRow points a) to the first row after the removed block or b) to the same line 1465 // as before, but moved up nNumRows 1466 // case a) needs an additional correction if the last n lines were deleted, as 'the first row after the 1467 // removed block' is an invalid position then 1468 // FS - 09/28/99 - 68429 1469 if (nCurRow == nRowCount) 1470 --nCurRow; 1471 } 1472 else if( nRow == nCurRow && nCurRow == nRowCount ) 1473 nCurRow = nRowCount-1; 1474 1475 // is the deleted row visible? 1476 Size aSz = pDataWin->GetOutputSizePixel(); 1477 if ( nRow >= nTopRow && 1478 nRow <= nTopRow + aSz.Height() / GetDataRowHeight() ) 1479 { 1480 if ( bDoPaint ) 1481 { 1482 // scroll up the rows behind the deleted row 1483 // if there are Rows behind 1484 if (nRow < nRowCount) 1485 { 1486 long nY = (nRow-nTopRow) * GetDataRowHeight(); 1487 pDataWin->SetClipRegion(); 1488 if( pDataWin->GetBackground().IsScrollable() ) 1489 { 1490 pDataWin->Scroll( 0, - (short) GetDataRowHeight() * nNumRows, 1491 Rectangle( Point( 0, nY ), Size( aSz.Width(), 1492 aSz.Height() - nY + nNumRows*GetDataRowHeight() ) ), 1493 SCROLL_FLAGS ); 1494 } 1495 else 1496 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN ); 1497 } 1498 else 1499 { 1500 // Repaint the Rect of the deleted row 1501 Rectangle aRect( 1502 Point( 0, (nRow-nTopRow)*GetDataRowHeight() ), 1503 Size( pDataWin->GetSizePixel().Width(), 1504 nNumRows * GetDataRowHeight() ) ); 1505 pDataWin->Invalidate( aRect ); 1506 } 1507 } 1508 } 1509 // is the deleted row above of the visible area? 1510 else if ( nRow < nTopRow ) 1511 nTopRow = nTopRow >= nNumRows ? nTopRow-nNumRows : 0; 1512 1513 if ( bDoPaint ) 1514 { 1515 // reshow cursor and selection 1516 ToggleSelection(); 1517 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this ); 1518 DoShowCursor( "RowRemoved" ); 1519 1520 // adjust the vertical scrollbar 1521 UpdateScrollbars(); 1522 AutoSizeLastColumn(); 1523 } 1524 1525 if ( isAccessibleAlive() ) 1526 { 1527 if ( nRowCount == 0 ) 1528 { 1529 // all columns should be removed, so we remove the column header bar and append it again 1530 // to avoid to notify every column remove 1531 commitBrowseBoxEvent( 1532 CHILD, 1533 Any(), 1534 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) ) 1535 ); 1536 1537 // and now append it again 1538 commitBrowseBoxEvent( 1539 CHILD, 1540 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_ROWHEADERBAR)), 1541 Any() 1542 ); 1543 commitBrowseBoxEvent( 1544 CHILD, 1545 Any(), 1546 makeAny( m_pImpl->getAccessibleTable() ) 1547 ); 1548 1549 // and now append it again 1550 commitBrowseBoxEvent( 1551 CHILD, 1552 makeAny( m_pImpl->getAccessibleTable() ), 1553 Any() 1554 ); 1555 } 1556 else 1557 { 1558 commitTableEvent( 1559 TABLE_MODEL_CHANGED, 1560 makeAny( AccessibleTableModelChange( 1561 DELETE, 1562 nRow, 1563 nRow + nNumRows, 1564 0, 1565 GetColumnCount() 1566 ) 1567 ), 1568 Any() 1569 ); 1570 1571 for (sal_Int32 i = nRow+1 ; i <= (nRow+nNumRows) ; ++i) 1572 { 1573 commitHeaderBarEvent( 1574 CHILD, 1575 Any(), 1576 makeAny( CreateAccessibleRowHeader( i ) ), 1577 sal_False 1578 ); 1579 } 1580 } 1581 } 1582 1583 if ( nOldCurRow != nCurRow ) 1584 CursorMoved(); 1585 1586 DBG_ASSERT(nRowCount >= 0,"BrowseBox: nRowCount < 0"); 1587 DBG_ASSERT(nCurRow >= 0 || nRowCount == 0,"BrowseBox: nCurRow < 0 && nRowCount != 0"); 1588 DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount"); 1589 } 1590 1591 //------------------------------------------------------------------- 1592 1593 sal_Bool BrowseBox::GoToRow( long nRow) 1594 { 1595 return GoToRow(nRow, sal_False, sal_False); 1596 } 1597 1598 //------------------------------------------------------------------- 1599 1600 sal_Bool BrowseBox::GoToRowAndDoNotModifySelection( long nRow ) 1601 { 1602 return GoToRow( nRow, sal_False, sal_True ); 1603 } 1604 1605 //------------------------------------------------------------------- 1606 sal_Bool BrowseBox::GoToRow( long nRow, sal_Bool bRowColMove, sal_Bool bKeepSelection ) 1607 { 1608 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1609 1610 long nOldCurRow = nCurRow; 1611 1612 // nothing to do? 1613 if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) ) 1614 return sal_True; 1615 1616 // out of range? 1617 if ( nRow < 0 || nRow >= nRowCount ) 1618 return sal_False; 1619 1620 // nicht erlaubt? 1621 if ( ( !bRowColMove && !IsCursorMoveAllowed( nRow, nCurColId ) ) ) 1622 return sal_False; 1623 1624 if ( getDataWindow()->bNoScrollBack && nRow < nTopRow ) 1625 nRow = nTopRow; 1626 1627 // compute the last visible row 1628 Size aSz( pDataWin->GetSizePixel() ); 1629 sal_uInt16 nVisibleRows = sal_uInt16( aSz.Height() / GetDataRowHeight() - 1 ); 1630 long nLastRow = nTopRow + nVisibleRows; 1631 1632 // suspend Updates 1633 getDataWindow()->EnterUpdateLock(); 1634 1635 // ggf. altes Highlight weg 1636 if ( !bMultiSelection && !bKeepSelection ) 1637 ToggleSelection(); 1638 DoHideCursor( "GoToRow" ); 1639 1640 // must we scroll? 1641 sal_Bool bWasVisible = bSelectionIsVisible; 1642 if (! bMultiSelection) 1643 { 1644 if( !bKeepSelection ) 1645 bSelectionIsVisible = sal_False; 1646 } 1647 if ( nRow < nTopRow ) 1648 ScrollRows( nRow - nTopRow ); 1649 else if ( nRow > nLastRow ) 1650 ScrollRows( nRow - nLastRow ); 1651 bSelectionIsVisible = bWasVisible; 1652 1653 // adjust cursor (selection) and thumb 1654 if ( GetUpdateMode() ) 1655 pVScroll->SetThumbPos( nTopRow ); 1656 1657 // relative positioning (because nCurRow might have changed in the meantime)! 1658 if (nCurRow != BROWSER_ENDOFSELECTION ) 1659 nCurRow = nCurRow + (nRow - nOldCurRow); 1660 1661 // make sure that the current position is valid 1662 if (nCurRow == BROWSER_ENDOFSELECTION && nRowCount > 0) 1663 nCurRow = 0; 1664 else if ( nCurRow >= nRowCount ) 1665 nCurRow = nRowCount - 1; 1666 aSelRange = Range( nCurRow, nCurRow ); 1667 1668 // ggf. neues Highlight anzeigen 1669 if ( !bMultiSelection && !bKeepSelection ) 1670 uRow.nSel = nRow; 1671 1672 // resume Updates 1673 getDataWindow()->LeaveUpdateLock(); 1674 1675 // Cursor+Highlight 1676 if ( !bMultiSelection && !bKeepSelection) 1677 ToggleSelection(); 1678 DoShowCursor( "GoToRow" ); 1679 if ( !bRowColMove && nOldCurRow != nCurRow ) 1680 CursorMoved(); 1681 1682 if ( !bMultiSelection && !bKeepSelection ) 1683 { 1684 if ( !bSelecting ) 1685 Select(); 1686 else 1687 bSelect = sal_True; 1688 } 1689 return sal_True; 1690 } 1691 1692 //------------------------------------------------------------------- 1693 1694 sal_Bool BrowseBox::GoToColumnId( sal_uInt16 nColId) 1695 { 1696 return GoToColumnId(nColId,sal_True,sal_False); 1697 } 1698 1699 1700 sal_Bool BrowseBox::GoToColumnId( sal_uInt16 nColId, sal_Bool bMakeVisible, sal_Bool bRowColMove) 1701 { 1702 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1703 1704 if (!bColumnCursor) 1705 return sal_False; 1706 1707 // erlaubt? 1708 if (!bRowColMove && !IsCursorMoveAllowed( nCurRow, nColId ) ) 1709 return sal_False; 1710 1711 if ( nColId != nCurColId || (bMakeVisible && !IsFieldVisible(nCurRow, nColId, sal_True))) 1712 { 1713 sal_uInt16 nNewPos = GetColumnPos(nColId); 1714 BrowserColumn* pColumn = pCols->GetObject( nNewPos ); 1715 DBG_ASSERT( pColumn, "no column object - invalid id?" ); 1716 if ( !pColumn ) 1717 return sal_False; 1718 1719 DoHideCursor( "GoToColumnId" ); 1720 nCurColId = nColId; 1721 1722 sal_uInt16 nFirstPos = nFirstCol; 1723 sal_uInt16 nWidth = (sal_uInt16)pColumn->Width(); 1724 sal_uInt16 nLastPos = GetColumnAtXPosPixel( 1725 pDataWin->GetSizePixel().Width()-nWidth, sal_False ); 1726 sal_uInt16 nFrozen = FrozenColCount(); 1727 if ( bMakeVisible && nLastPos && 1728 nNewPos >= nFrozen && ( nNewPos < nFirstPos || nNewPos > nLastPos ) ) 1729 { 1730 if ( nNewPos < nFirstPos ) 1731 ScrollColumns( nNewPos-nFirstPos ); 1732 else if ( nNewPos > nLastPos ) 1733 ScrollColumns( nNewPos-nLastPos ); 1734 } 1735 1736 DoShowCursor( "GoToColumnId" ); 1737 if (!bRowColMove) 1738 CursorMoved(); 1739 return sal_True; 1740 } 1741 return sal_True; 1742 } 1743 1744 //------------------------------------------------------------------- 1745 1746 sal_Bool BrowseBox::GoToRowColumnId( long nRow, sal_uInt16 nColId ) 1747 { 1748 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1749 1750 // out of range? 1751 if ( nRow < 0 || nRow >= nRowCount ) 1752 return sal_False; 1753 1754 if (!bColumnCursor) 1755 return sal_False; 1756 1757 // nothing to do ? 1758 if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) && 1759 nColId == nCurColId && IsFieldVisible(nCurRow, nColId, sal_True)) 1760 return sal_True; 1761 1762 // erlaubt? 1763 if (!IsCursorMoveAllowed(nRow, nColId)) 1764 return sal_False; 1765 1766 DoHideCursor( "GoToRowColumnId" ); 1767 sal_Bool bMoved = GoToRow(nRow, sal_True) && GoToColumnId(nColId, sal_True, sal_True); 1768 DoShowCursor( "GoToRowColumnId" ); 1769 1770 if (bMoved) 1771 CursorMoved(); 1772 1773 return bMoved; 1774 } 1775 1776 //------------------------------------------------------------------- 1777 1778 void BrowseBox::SetNoSelection() 1779 { 1780 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1781 1782 // is there no selection 1783 if ( ( !pColSel || !pColSel->GetSelectCount() ) && 1784 ( ( !bMultiSelection && uRow.nSel == BROWSER_ENDOFSELECTION ) || 1785 ( bMultiSelection && !uRow.pSel->GetSelectCount() ) ) ) 1786 // nothing to do 1787 return; 1788 1789 DBG_TRACE1( "BrowseBox: %p->HideCursor", this ); 1790 ToggleSelection(); 1791 1792 // unselect all 1793 if ( bMultiSelection ) 1794 uRow.pSel->SelectAll(sal_False); 1795 else 1796 uRow.nSel = BROWSER_ENDOFSELECTION; 1797 if ( pColSel ) 1798 pColSel->SelectAll(sal_False); 1799 if ( !bSelecting ) 1800 Select(); 1801 else 1802 bSelect = sal_True; 1803 1804 // restore screen 1805 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this ); 1806 1807 if ( isAccessibleAlive() ) 1808 { 1809 commitTableEvent( 1810 SELECTION_CHANGED, 1811 Any(), 1812 Any() 1813 ); 1814 } 1815 } 1816 1817 //------------------------------------------------------------------- 1818 1819 void BrowseBox::SetSelection( const MultiSelection &rSel ) 1820 { 1821 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1822 DBG_ASSERT( bMultiSelection, "SetSelection only allowed with Multi-Selection-Mode" ); 1823 1824 // prepare inverted areas 1825 DBG_TRACE1( "BrowseBox: %p->HideCursor", this ); 1826 ToggleSelection(); 1827 1828 // assign Selection 1829 *uRow.pSel = rSel; 1830 1831 // only highlight painted areas 1832 pDataWin->Update(); 1833 1834 // notify derived class 1835 if ( !bSelecting ) 1836 Select(); 1837 else 1838 bSelect = sal_True; 1839 1840 // restore screen 1841 ToggleSelection(); 1842 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this ); 1843 1844 if ( isAccessibleAlive() ) 1845 { 1846 commitTableEvent( 1847 SELECTION_CHANGED, 1848 Any(), 1849 Any() 1850 ); 1851 } 1852 } 1853 1854 //------------------------------------------------------------------- 1855 1856 void BrowseBox::SelectAll() 1857 { 1858 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1859 1860 if ( !bMultiSelection ) 1861 return; 1862 1863 DBG_TRACE1( "BrowseBox: %p->HideCursor", this ); 1864 ToggleSelection(); 1865 1866 // select all rows 1867 if ( pColSel ) 1868 pColSel->SelectAll(sal_False); 1869 uRow.pSel->SelectAll(sal_True); 1870 1871 // Handle-Column nicht highlighten 1872 BrowserColumn *pFirstCol = pCols->GetObject(0); 1873 long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width(); 1874 1875 // highlight the row selection 1876 if ( !bHideSelect ) 1877 { 1878 Rectangle aHighlightRect; 1879 sal_uInt16 nVisibleRows = 1880 (sal_uInt16)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1); 1881 for ( long nRow = Max( nTopRow, uRow.pSel->FirstSelected() ); 1882 nRow != BROWSER_ENDOFSELECTION && nRow < nTopRow + nVisibleRows; 1883 nRow = uRow.pSel->NextSelected() ) 1884 aHighlightRect.Union( Rectangle( 1885 Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ), 1886 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ) ); 1887 pDataWin->Invalidate( aHighlightRect ); 1888 } 1889 1890 if ( !bSelecting ) 1891 Select(); 1892 else 1893 bSelect = sal_True; 1894 1895 // restore screen 1896 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this ); 1897 1898 if ( isAccessibleAlive() ) 1899 { 1900 commitTableEvent( 1901 SELECTION_CHANGED, 1902 Any(), 1903 Any() 1904 ); 1905 commitHeaderBarEvent( 1906 SELECTION_CHANGED, 1907 Any(), 1908 Any(), 1909 sal_True 1910 ); // column header event 1911 1912 commitHeaderBarEvent( 1913 SELECTION_CHANGED, 1914 Any(), 1915 Any(), 1916 sal_False 1917 ); // row header event 1918 } 1919 } 1920 1921 //------------------------------------------------------------------- 1922 1923 void BrowseBox::SelectRow( long nRow, sal_Bool _bSelect, sal_Bool bExpand ) 1924 { 1925 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 1926 1927 if ( !bMultiSelection ) 1928 { 1929 // deselecting is impossible, selecting via cursor 1930 if ( _bSelect ) 1931 GoToRow(nRow, sal_False); 1932 return; 1933 } 1934 1935 DBG_TRACE1( "BrowseBox: %p->HideCursor", this ); 1936 1937 // remove old selection? 1938 if ( !bExpand || !bMultiSelection ) 1939 { 1940 ToggleSelection(); 1941 if ( bMultiSelection ) 1942 uRow.pSel->SelectAll(sal_False); 1943 else 1944 uRow.nSel = BROWSER_ENDOFSELECTION; 1945 if ( pColSel ) 1946 pColSel->SelectAll(sal_False); 1947 } 1948 1949 // set new selection 1950 if ( !bHideSelect 1951 && ( ( bMultiSelection 1952 && uRow.pSel->GetTotalRange().Max() >= nRow 1953 && uRow.pSel->Select( nRow, _bSelect ) 1954 ) 1955 || ( !bMultiSelection 1956 && ( uRow.nSel = nRow ) != BROWSER_ENDOFSELECTION ) 1957 ) 1958 ) 1959 { 1960 // Handle-Column nicht highlighten 1961 BrowserColumn *pFirstCol = pCols->GetObject(0); 1962 long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width(); 1963 1964 // highlight only newly selected part 1965 Rectangle aRect( 1966 Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ), 1967 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ); 1968 pDataWin->Invalidate( aRect ); 1969 } 1970 1971 if ( !bSelecting ) 1972 Select(); 1973 else 1974 bSelect = sal_True; 1975 1976 // restore screen 1977 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this ); 1978 1979 if ( isAccessibleAlive() ) 1980 { 1981 commitTableEvent( 1982 SELECTION_CHANGED, 1983 Any(), 1984 Any() 1985 ); 1986 commitHeaderBarEvent( 1987 SELECTION_CHANGED, 1988 Any(), 1989 Any(), 1990 sal_False 1991 ); // row header event 1992 } 1993 } 1994 1995 //------------------------------------------------------------------- 1996 1997 long BrowseBox::GetSelectRowCount() const 1998 { 1999 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2000 2001 return bMultiSelection ? uRow.pSel->GetSelectCount() : 2002 uRow.nSel == BROWSER_ENDOFSELECTION ? 0 : 1; 2003 } 2004 2005 //------------------------------------------------------------------- 2006 2007 void BrowseBox::SelectColumnPos( sal_uInt16 nNewColPos, sal_Bool _bSelect, sal_Bool bMakeVisible ) 2008 { 2009 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2010 2011 if ( !bColumnCursor || nNewColPos == BROWSER_INVALIDID ) 2012 return; 2013 2014 if ( !bMultiSelection ) 2015 { 2016 if ( _bSelect ) 2017 GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible ); 2018 return; 2019 } 2020 else 2021 { 2022 if ( !GoToColumnId( pCols->GetObject( nNewColPos )->GetId(), bMakeVisible ) ) 2023 return; 2024 } 2025 2026 DBG_TRACE1( "BrowseBox: %p->HideCursor", this ); 2027 ToggleSelection(); 2028 if ( bMultiSelection ) 2029 uRow.pSel->SelectAll(sal_False); 2030 else 2031 uRow.nSel = BROWSER_ENDOFSELECTION; 2032 pColSel->SelectAll(sal_False); 2033 2034 if ( pColSel->Select( nNewColPos, _bSelect ) ) 2035 { 2036 // GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible ); 2037 2038 // only highlight painted areas 2039 pDataWin->Update(); 2040 Rectangle aFieldRectPix( GetFieldRectPixel( nCurRow, nCurColId, sal_False ) ); 2041 Rectangle aRect( 2042 Point( aFieldRectPix.Left() - MIN_COLUMNWIDTH, 0 ), 2043 Size( pCols->GetObject(nNewColPos)->Width(), 2044 pDataWin->GetOutputSizePixel().Height() ) ); 2045 pDataWin->Invalidate( aRect ); 2046 if ( !bSelecting ) 2047 Select(); 2048 else 2049 bSelect = sal_True; 2050 2051 if ( isAccessibleAlive() ) 2052 { 2053 commitTableEvent( 2054 SELECTION_CHANGED, 2055 Any(), 2056 Any() 2057 ); 2058 commitHeaderBarEvent( 2059 SELECTION_CHANGED, 2060 Any(), 2061 Any(), 2062 sal_True 2063 ); // column header event 2064 } 2065 } 2066 2067 // restore screen 2068 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this ); 2069 } 2070 2071 //------------------------------------------------------------------- 2072 2073 sal_uInt16 BrowseBox::GetSelectColumnCount() const 2074 { 2075 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2076 2077 // while bAutoSelect (==!pColSel), 1 if any rows (yes rows!) else none 2078 return pColSel ? (sal_uInt16) pColSel->GetSelectCount() : 2079 nCurRow >= 0 ? 1 : 0; 2080 } 2081 2082 //------------------------------------------------------------------- 2083 long BrowseBox::FirstSelectedColumn( ) const 2084 { 2085 return pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION; 2086 } 2087 2088 //------------------------------------------------------------------- 2089 long BrowseBox::NextSelectedColumn( ) const 2090 { 2091 return pColSel ? pColSel->NextSelected() : BROWSER_ENDOFSELECTION; 2092 } 2093 2094 //------------------------------------------------------------------- 2095 2096 long BrowseBox::FirstSelectedRow( sal_Bool bInverse ) 2097 { 2098 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2099 2100 return bMultiSelection ? uRow.pSel->FirstSelected(bInverse) : uRow.nSel; 2101 } 2102 2103 //------------------------------------------------------------------- 2104 2105 long BrowseBox::NextSelectedRow() 2106 { 2107 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2108 2109 return bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION; 2110 } 2111 2112 //------------------------------------------------------------------- 2113 2114 long BrowseBox::PrevSelectedRow() 2115 { 2116 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2117 2118 return bMultiSelection ? uRow.pSel->PrevSelected() : BROWSER_ENDOFSELECTION; 2119 } 2120 2121 //------------------------------------------------------------------- 2122 2123 long BrowseBox::LastSelectedRow() 2124 { 2125 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2126 2127 return bMultiSelection ? uRow.pSel->LastSelected() : uRow.nSel; 2128 } 2129 2130 //------------------------------------------------------------------- 2131 2132 bool BrowseBox::IsRowSelected( long nRow ) const 2133 { 2134 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2135 2136 return bMultiSelection ? uRow.pSel->IsSelected(nRow) : nRow == uRow.nSel; 2137 } 2138 2139 //------------------------------------------------------------------- 2140 2141 bool BrowseBox::IsColumnSelected( sal_uInt16 nColumnId ) const 2142 { 2143 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2144 2145 return pColSel ? pColSel->IsSelected( GetColumnPos(nColumnId) ) : 2146 nCurColId == nColumnId; 2147 } 2148 2149 //------------------------------------------------------------------- 2150 2151 sal_Bool BrowseBox::IsAllSelected() const 2152 { 2153 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2154 2155 return bMultiSelection && uRow.pSel->IsAllSelected(); 2156 } 2157 2158 //------------------------------------------------------------------- 2159 2160 sal_Bool BrowseBox::MakeFieldVisible 2161 ( 2162 long nRow, // Zeilen-Nr des Feldes (beginnend mit 0) 2163 sal_uInt16 nColId, // Spalten-Id des Feldes 2164 sal_Bool bComplete // (== sal_False), sal_True => vollst"andig sichtbar machen 2165 ) 2166 2167 /* [Beschreibung] 2168 2169 Macht das durch 'nRow' und 'nColId' beschriebene Feld durch 2170 entsprechendes scrollen sichtbar. Ist 'bComplete' gesetzt, dann wird 2171 gefordert, da\s das Feld ganz sichtbar wird. 2172 2173 [R"uckgabewert] 2174 2175 sal_Bool sal_True 2176 Das angegebene Feld wurde sichtbar gemacht, bzw. war 2177 bereits sichtbar. 2178 2179 sal_False 2180 Das angegebene Feld konnte nicht sichtbar bzw. bei 2181 'bComplete' nicht vollst"andig sichtbar gemacht werden. 2182 */ 2183 2184 { 2185 Size aTestSize = pDataWin->GetSizePixel(); 2186 2187 if ( !bBootstrapped || 2188 ( aTestSize.Width() == 0 && aTestSize.Height() == 0 ) ) 2189 return sal_False; 2190 2191 // ist es schon sichtbar? 2192 sal_Bool bVisible = IsFieldVisible( nRow, nColId, bComplete ); 2193 if ( bVisible ) 2194 return sal_True; 2195 2196 // Spaltenposition und Feld-Rechteck und Ausgabebereich berechnen 2197 sal_uInt16 nColPos = GetColumnPos( nColId ); 2198 Rectangle aFieldRect = GetFieldRectPixel( nRow, nColId, sal_False ); 2199 Rectangle aDataRect = Rectangle( Point(0, 0), pDataWin->GetSizePixel() ); 2200 2201 // links au\serhalb? 2202 if ( nColPos >= FrozenColCount() && nColPos < nFirstCol ) 2203 // => nach rechts scrollen 2204 ScrollColumns( nColPos - nFirstCol ); 2205 2206 // solange rechts au\serhalb 2207 while ( aDataRect.Right() < ( bComplete 2208 ? aFieldRect.Right() 2209 : aFieldRect.Left()+aFieldRect.GetWidth()/2 ) ) 2210 { 2211 // => nach links scrollen 2212 if ( ScrollColumns( 1 ) != 1 ) 2213 // nichts mehr zu scrollen 2214 break; 2215 aFieldRect = GetFieldRectPixel( nRow, nColId, sal_False ); 2216 } 2217 2218 // oben au\serhalb? 2219 if ( nRow < nTopRow ) 2220 // nach unten scrollen 2221 ScrollRows( nRow - nTopRow ); 2222 2223 // unten au\serhalb? 2224 long nBottomRow = nTopRow + GetVisibleRows(); 2225 // OV: damit nBottomRow die Nummer der letzten sichtbaren Zeile ist 2226 // (Zaehlung ab Null!), muss sie dekrementiert werden. 2227 // Beispiel: BrowseBox enthaelt genau einen Eintrag. nBottomRow := 0 + 1 - 1 2228 if( nBottomRow ) 2229 nBottomRow--; 2230 2231 if ( nRow > nBottomRow ) 2232 // nach oben scrollen 2233 ScrollRows( nRow - nBottomRow ); 2234 2235 // jetzt kann es immer noch nicht passen, z.B. weil Window zu klein 2236 return IsFieldVisible( nRow, nColId, bComplete ); 2237 } 2238 2239 //------------------------------------------------------------------- 2240 2241 sal_Bool BrowseBox::IsFieldVisible( long nRow, sal_uInt16 nColumnId, 2242 sal_Bool bCompletely ) const 2243 { 2244 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2245 2246 // durch frozen-Column verdeckt? 2247 sal_uInt16 nColPos = GetColumnPos( nColumnId ); 2248 if ( nColPos >= FrozenColCount() && nColPos < nFirstCol ) 2249 return sal_False; 2250 2251 Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) ); 2252 if ( aRect.IsEmpty() ) 2253 return sal_False; 2254 2255 // get the visible area 2256 Rectangle aOutRect( Point(0, 0), pDataWin->GetOutputSizePixel() ); 2257 2258 if ( bCompletely ) 2259 // test if the field is completely visible 2260 return aOutRect.IsInside( aRect ); 2261 else 2262 // test if the field is partly of completely visible 2263 return !aOutRect.Intersection( aRect ).IsEmpty(); 2264 } 2265 2266 //------------------------------------------------------------------- 2267 2268 Rectangle BrowseBox::GetFieldRectPixel( long nRow, sal_uInt16 nColumnId, 2269 sal_Bool bRelToBrowser) const 2270 { 2271 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2272 2273 // get the rectangle relative to DataWin 2274 Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) ); 2275 if ( aRect.IsEmpty() ) 2276 return aRect; 2277 2278 // adjust relative to BrowseBox's output area 2279 Point aTopLeft( aRect.TopLeft() ); 2280 if ( bRelToBrowser ) 2281 { 2282 aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft ); 2283 aTopLeft = ScreenToOutputPixel( aTopLeft ); 2284 } 2285 2286 return Rectangle( aTopLeft, aRect.GetSize() ); 2287 } 2288 2289 //------------------------------------------------------------------- 2290 2291 Rectangle BrowseBox::GetRowRectPixel( long nRow, sal_Bool bRelToBrowser ) const 2292 { 2293 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2294 2295 // get the rectangle relative to DataWin 2296 Rectangle aRect; 2297 if ( nTopRow > nRow ) 2298 // row is above visible area 2299 return aRect; 2300 aRect = Rectangle( 2301 Point( 0, GetDataRowHeight() * (nRow-nTopRow) ), 2302 Size( pDataWin->GetOutputSizePixel().Width(), GetDataRowHeight() ) ); 2303 if ( aRect.TopLeft().Y() > pDataWin->GetOutputSizePixel().Height() ) 2304 // row is below visible area 2305 return aRect; 2306 2307 // adjust relative to BrowseBox's output area 2308 Point aTopLeft( aRect.TopLeft() ); 2309 if ( bRelToBrowser ) 2310 { 2311 aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft ); 2312 aTopLeft = ScreenToOutputPixel( aTopLeft ); 2313 } 2314 2315 return Rectangle( aTopLeft, aRect.GetSize() ); 2316 } 2317 2318 //------------------------------------------------------------------- 2319 2320 Rectangle BrowseBox::ImplFieldRectPixel( long nRow, sal_uInt16 nColumnId ) const 2321 { 2322 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2323 2324 // compute the X-coordinte realtiv to DataWin by accumulation 2325 long nColX = 0; 2326 sal_uInt16 nFrozenCols = FrozenColCount(); 2327 sal_uInt16 nCol; 2328 for ( nCol = 0; 2329 nCol < pCols->Count() && pCols->GetObject(nCol)->GetId() != nColumnId; 2330 ++nCol ) 2331 if ( pCols->GetObject(nCol)->IsFrozen() || nCol >= nFirstCol ) 2332 nColX += pCols->GetObject(nCol)->Width(); 2333 2334 if ( nCol >= pCols->Count() || ( nCol >= nFrozenCols && nCol < nFirstCol ) ) 2335 return Rectangle(); 2336 2337 // compute the Y-coordinate relative to DataWin 2338 long nRowY = GetDataRowHeight(); 2339 if ( nRow != BROWSER_ENDOFSELECTION ) // #105497# OJ 2340 nRowY = ( nRow - nTopRow ) * GetDataRowHeight(); 2341 2342 // assemble the Rectangle relative to DataWin 2343 return Rectangle( 2344 Point( nColX + MIN_COLUMNWIDTH, nRowY ), 2345 Size( pCols->GetObject(nCol)->Width() - 2*MIN_COLUMNWIDTH, 2346 GetDataRowHeight() - 1 ) ); 2347 } 2348 2349 //------------------------------------------------------------------- 2350 2351 long BrowseBox::GetRowAtYPosPixel( long nY, sal_Bool bRelToBrowser ) const 2352 { 2353 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2354 2355 // compute the Y-coord 2356 if ( bRelToBrowser ) 2357 { 2358 Point aDataTopLeft = pDataWin->OutputToScreenPixel( Point(0, 0) ); 2359 Point aTopLeft = OutputToScreenPixel( Point(0, 0) ); 2360 nY -= aDataTopLeft.Y() - aTopLeft.Y(); 2361 } 2362 2363 // no row there (e.g. in the header) 2364 if ( nY < 0 || nY >= pDataWin->GetOutputSizePixel().Height() ) 2365 return -1; 2366 2367 return nY / GetDataRowHeight() + nTopRow; 2368 } 2369 2370 //------------------------------------------------------------------- 2371 2372 Rectangle BrowseBox::GetFieldRect( sal_uInt16 nColumnId ) const 2373 { 2374 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2375 2376 return GetFieldRectPixel( nCurRow, nColumnId ); 2377 } 2378 2379 //------------------------------------------------------------------- 2380 2381 sal_uInt16 BrowseBox::GetColumnAtXPosPixel( long nX, sal_Bool ) const 2382 { 2383 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2384 2385 // accumulate the withds of the visible columns 2386 long nColX = 0; 2387 sal_uInt16 nCol; 2388 for ( nCol = 0; nCol < sal_uInt16(pCols->Count()); ++nCol ) 2389 { 2390 BrowserColumn *pCol = pCols->GetObject(nCol); 2391 if ( pCol->IsFrozen() || nCol >= nFirstCol ) 2392 nColX += pCol->Width(); 2393 2394 if ( nColX > nX ) 2395 return nCol; 2396 } 2397 2398 return BROWSER_INVALIDID; 2399 } 2400 2401 //------------------------------------------------------------------- 2402 2403 void BrowseBox::ReserveControlArea( sal_uInt16 nWidth ) 2404 { 2405 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2406 2407 if ( nWidth != nControlAreaWidth ) 2408 { 2409 OSL_ENSURE(nWidth,"Control aera of 0 is not allowed, Use USHRT_MAX instead!"); 2410 nControlAreaWidth = nWidth; 2411 UpdateScrollbars(); 2412 } 2413 } 2414 2415 //------------------------------------------------------------------- 2416 2417 Rectangle BrowseBox::GetControlArea() const 2418 { 2419 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2420 2421 return Rectangle( 2422 Point( 0, GetOutputSizePixel().Height() - aHScroll.GetSizePixel().Height() ), 2423 Size( GetOutputSizePixel().Width() - aHScroll.GetSizePixel().Width(), 2424 aHScroll.GetSizePixel().Height() ) ); 2425 } 2426 2427 //------------------------------------------------------------------- 2428 2429 void BrowseBox::SetMode( BrowserMode nMode ) 2430 { 2431 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2432 2433 #ifdef DBG_MIx 2434 Sound::Beep(); 2435 nMode = 2436 // BROWSER_COLUMNSELECTION | 2437 // BROWSER_MULTISELECTION | 2438 BROWSER_THUMBDRAGGING | 2439 BROWSER_KEEPHIGHLIGHT | 2440 BROWSER_HLINES | 2441 BROWSER_VLINES | 2442 // BROWSER_HIDECURSOR | 2443 // BROWSER_NO_HSCROLL | 2444 // BROWSER_NO_SCROLLBACK | 2445 BROWSER_AUTO_VSCROLL | 2446 BROWSER_AUTO_HSCROLL | 2447 BROWSER_TRACKING_TIPS | 2448 // BROWSER_HIGHLIGHT_NONE | 2449 BROWSER_HEADERBAR_NEW | 2450 // BROWSER_AUTOSIZE_LASTCOL | 2451 0; 2452 #endif 2453 2454 getDataWindow()->bAutoHScroll = BROWSER_AUTO_HSCROLL == ( nMode & BROWSER_AUTO_HSCROLL ); 2455 getDataWindow()->bAutoVScroll = BROWSER_AUTO_VSCROLL == ( nMode & BROWSER_AUTO_VSCROLL ); 2456 getDataWindow()->bNoHScroll = BROWSER_NO_HSCROLL == ( nMode & BROWSER_NO_HSCROLL ); 2457 getDataWindow()->bNoVScroll = BROWSER_NO_VSCROLL == ( nMode & BROWSER_NO_VSCROLL ); 2458 2459 DBG_ASSERT( !( getDataWindow()->bAutoHScroll && getDataWindow()->bNoHScroll ), 2460 "BrowseBox::SetMode: AutoHScroll *and* NoHScroll?" ); 2461 DBG_ASSERT( !( getDataWindow()->bAutoVScroll && getDataWindow()->bNoVScroll ), 2462 "BrowseBox::SetMode: AutoVScroll *and* NoVScroll?" ); 2463 if ( getDataWindow()->bAutoHScroll ) 2464 getDataWindow()->bNoHScroll = sal_False; 2465 if ( getDataWindow()->bAutoVScroll ) 2466 getDataWindow()->bNoVScroll = sal_False; 2467 2468 if ( getDataWindow()->bNoHScroll ) 2469 aHScroll.Hide(); 2470 2471 nControlAreaWidth = USHRT_MAX; 2472 2473 getDataWindow()->bNoScrollBack = 2474 BROWSER_NO_SCROLLBACK == ( nMode & BROWSER_NO_SCROLLBACK); 2475 2476 long nOldRowSel = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel; 2477 MultiSelection *pOldRowSel = bMultiSelection ? uRow.pSel : 0; 2478 MultiSelection *pOldColSel = pColSel; 2479 2480 delete pVScroll; 2481 2482 bThumbDragging = ( nMode & BROWSER_THUMBDRAGGING ) == BROWSER_THUMBDRAGGING; 2483 bMultiSelection = ( nMode & BROWSER_MULTISELECTION ) == BROWSER_MULTISELECTION; 2484 bColumnCursor = ( nMode & BROWSER_COLUMNSELECTION ) == BROWSER_COLUMNSELECTION; 2485 bKeepHighlight = ( nMode & BROWSER_KEEPSELECTION ) == BROWSER_KEEPSELECTION; 2486 2487 bHideSelect = ((nMode & BROWSER_HIDESELECT) == BROWSER_HIDESELECT); 2488 // default: do not hide the cursor at all (untaken scrolling and such) 2489 bHideCursor = NO_CURSOR_HIDE; 2490 2491 if ( BROWSER_SMART_HIDECURSOR == ( nMode & BROWSER_SMART_HIDECURSOR ) ) 2492 { // smart cursor hide overrules hard cursor hide 2493 bHideCursor = SMART_CURSOR_HIDE; 2494 } 2495 else if ( BROWSER_HIDECURSOR == ( nMode & BROWSER_HIDECURSOR ) ) 2496 { 2497 bHideCursor = HARD_CURSOR_HIDE; 2498 } 2499 2500 m_bFocusOnlyCursor = ((nMode & BROWSER_CURSOR_WO_FOCUS) == 0); 2501 2502 bHLines = ( nMode & BROWSER_HLINESFULL ) == BROWSER_HLINESFULL; 2503 bVLines = ( nMode & BROWSER_VLINESFULL ) == BROWSER_VLINESFULL; 2504 bHDots = ( nMode & BROWSER_HLINESDOTS ) == BROWSER_HLINESDOTS; 2505 bVDots = ( nMode & BROWSER_VLINESDOTS ) == BROWSER_VLINESDOTS; 2506 2507 WinBits nVScrollWinBits = 2508 WB_VSCROLL | ( ( nMode & BROWSER_THUMBDRAGGING ) ? WB_DRAG : 0 ); 2509 pVScroll = ( nMode & BROWSER_TRACKING_TIPS ) == BROWSER_TRACKING_TIPS 2510 ? new BrowserScrollBar( this, nVScrollWinBits, 2511 (BrowserDataWin*) pDataWin ) 2512 : new ScrollBar( this, nVScrollWinBits ); 2513 pVScroll->SetLineSize( 1 ); 2514 pVScroll->SetPageSize(1); 2515 pVScroll->SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) ); 2516 pVScroll->SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) ); 2517 2518 getDataWindow()->bAutoSizeLastCol = 2519 BROWSER_AUTOSIZE_LASTCOL == ( nMode & BROWSER_AUTOSIZE_LASTCOL ); 2520 getDataWindow()->bOwnDataChangedHdl = 2521 BROWSER_OWN_DATACHANGED == ( nMode & BROWSER_OWN_DATACHANGED ); 2522 2523 // Headerbar erzeugen, was passiert, wenn eine erzeugt werden mu� und schon Spalten bestehen ? 2524 if ( BROWSER_HEADERBAR_NEW == ( nMode & BROWSER_HEADERBAR_NEW ) ) 2525 { 2526 if (!getDataWindow()->pHeaderBar) 2527 getDataWindow()->pHeaderBar = CreateHeaderBar( this ); 2528 } 2529 else 2530 { 2531 DELETEZ(getDataWindow()->pHeaderBar); 2532 } 2533 2534 2535 2536 if ( bColumnCursor ) 2537 { 2538 pColSel = pOldColSel ? pOldColSel : new MultiSelection; 2539 pColSel->SetTotalRange( Range( 0, pCols->Count()-1 ) ); 2540 } 2541 else 2542 { 2543 pColSel = 0; 2544 delete pColSel; 2545 } 2546 2547 if ( bMultiSelection ) 2548 { 2549 if ( pOldRowSel ) 2550 uRow.pSel = pOldRowSel; 2551 else 2552 uRow.pSel = new MultiSelection; 2553 } 2554 else 2555 { 2556 uRow.nSel = nOldRowSel; 2557 delete pOldRowSel; 2558 } 2559 2560 if ( bBootstrapped ) 2561 { 2562 StateChanged( STATE_CHANGE_INITSHOW ); 2563 if ( bMultiSelection && !pOldRowSel && 2564 nOldRowSel != BROWSER_ENDOFSELECTION ) 2565 uRow.pSel->Select( nOldRowSel ); 2566 } 2567 2568 if ( pDataWin ) 2569 pDataWin->Invalidate(); 2570 2571 // kein Cursor auf Handle-Column 2572 if ( nCurColId == 0 ) 2573 nCurColId = GetColumnId( 1 ); 2574 2575 m_nCurrentMode = nMode; 2576 } 2577 2578 //------------------------------------------------------------------- 2579 2580 void BrowseBox::VisibleRowsChanged( long, sal_uInt16 ) 2581 { 2582 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2583 2584 // Das alte Verhalten: NumRows automatisch korrigieren: 2585 if ( nRowCount < GetRowCount() ) 2586 { 2587 RowInserted(nRowCount,GetRowCount() - nRowCount,sal_False); 2588 } 2589 else if ( nRowCount > GetRowCount() ) 2590 { 2591 RowRemoved(nRowCount-(nRowCount - GetRowCount()),nRowCount - GetRowCount(),sal_False); 2592 } 2593 } 2594 2595 //------------------------------------------------------------------- 2596 2597 sal_Bool BrowseBox::IsCursorMoveAllowed( long, sal_uInt16 ) const 2598 2599 /* [Beschreibung] 2600 2601 Diese virtuelle Methode wird immer gerufen bevor der Cursor direkt 2602 bewegt werden soll. Durch 'return sal_False' kann verhindert werden, da\s 2603 dies geschieht, wenn z.B. ein Datensatz irgendwelchen Rules widerspricht. 2604 2605 Diese Methode wird nicht gerufen, wenn die Cursorbewegung durch 2606 ein L"oschen oder Einf"ugen (einer Zeile/Spalte) ausgel"ost wird, also 2607 genaugenommen nur eine Cursor-Korrektur vorliegt. 2608 2609 Die Basisimplementierung liefert derzeit immer sal_True. 2610 */ 2611 2612 { 2613 return sal_True; 2614 } 2615 2616 //------------------------------------------------------------------- 2617 2618 long BrowseBox::GetDataRowHeight() const 2619 { 2620 return CalcZoom(nDataRowHeight ? nDataRowHeight : ImpGetDataRowHeight()); 2621 } 2622 2623 //------------------------------------------------------------------- 2624 2625 Window& BrowseBox::GetEventWindow() const 2626 { 2627 return *getDataWindow()->pEventWin; 2628 } 2629 2630 //------------------------------------------------------------------- 2631 2632 BrowserHeader* BrowseBox::CreateHeaderBar( BrowseBox* pParent ) 2633 { 2634 BrowserHeader* pNewBar = new BrowserHeader( pParent ); 2635 pNewBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) ); 2636 return pNewBar; 2637 } 2638 2639 void BrowseBox::SetHeaderBar( BrowserHeader* pHeaderBar ) 2640 { 2641 delete ( (BrowserDataWin*)pDataWin )->pHeaderBar; 2642 ( (BrowserDataWin*)pDataWin )->pHeaderBar = pHeaderBar; 2643 ( (BrowserDataWin*)pDataWin )->pHeaderBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) ); 2644 } 2645 //------------------------------------------------------------------- 2646 2647 #ifdef DBG_UTIL 2648 const char* BrowseBoxCheckInvariants( const void * pVoid ) 2649 { 2650 const BrowseBox * p = (const BrowseBox *)pVoid; 2651 2652 if (p->nRowCount < 0) return "BrowseBox: nRowCount < 0"; 2653 if (p->nTopRow < 0) return "BrowseBox: nTopRow < 0"; 2654 if (p->nTopRow >= p->nRowCount && p->nRowCount != 0) return "BrowseBox: nTopRow >= nRowCount && nRowCount != 0"; 2655 if (p->nCurRow < -1) return "BrowseBox: nCurRow < -1"; 2656 if (p->nCurRow > p->nRowCount) return "BrowseBox: nCurRow > nRowCount"; 2657 2658 // Leider waehrend der Bearbeitung nicht immer der Fall: 2659 //if (p->nCurRow < 0 && p->nRowCount != 0) return "nCurRow < 0 && nRowCount != 0"; 2660 //if (p->nCurRow >= p->nRowCount && p->nRowCount != 0) return "nCurRow >= nRowCount && nRowCount != 0"; 2661 2662 return NULL; 2663 } 2664 #endif 2665 2666 //------------------------------------------------------------------- 2667 long BrowseBox::GetTitleHeight() const 2668 { 2669 long nHeight; 2670 // ask the header bar for the text height (if possible), as the header bar's font is adjusted with 2671 // our (and the header's) zoom factor 2672 HeaderBar* pHeaderBar = ( (BrowserDataWin*)pDataWin )->pHeaderBar; 2673 if ( pHeaderBar ) 2674 nHeight = pHeaderBar->GetTextHeight(); 2675 else 2676 nHeight = GetTextHeight(); 2677 2678 return nTitleLines ? nTitleLines * nHeight + 4 : 0; 2679 } 2680 2681 //------------------------------------------------------------------- 2682 long BrowseBox::CalcReverseZoom(long nVal) 2683 { 2684 if (IsZoom()) 2685 { 2686 const Fraction& rZoom = GetZoom(); 2687 double n = (double)nVal; 2688 n *= (double)rZoom.GetDenominator(); 2689 n /= (double)rZoom.GetNumerator(); 2690 nVal = n>0 ? (long)(n + 0.5) : -(long)(-n + 0.5); 2691 } 2692 2693 return nVal; 2694 } 2695 2696 //------------------------------------------------------------------- 2697 HeaderBar* BrowseBox::GetHeaderBar() const 2698 { 2699 return getDataWindow()->pHeaderBar; 2700 } 2701 //------------------------------------------------------------------- 2702 2703 void BrowseBox::CursorMoved() 2704 { 2705 // before implementing more here, please adjust the EditBrowseBox 2706 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2707 2708 if ( isAccessibleAlive() && HasFocus() ) 2709 commitTableEvent( 2710 ACTIVE_DESCENDANT_CHANGED, 2711 makeAny( CreateAccessibleCell( GetCurRow(),GetColumnPos( GetCurColumnId() ) ) ), 2712 Any() 2713 ); 2714 } 2715 2716 //------------------------------------------------------------------- 2717 2718 void BrowseBox::LoseFocus() 2719 { 2720 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2721 DBG_TRACE1( "BrowseBox: %p->LoseFocus", this ); 2722 2723 if ( bHasFocus ) 2724 { 2725 DBG_TRACE1( "BrowseBox: %p->HideCursor", this ); 2726 DoHideCursor( "LoseFocus" ); 2727 2728 if ( !bKeepHighlight ) 2729 { 2730 ToggleSelection(); 2731 bSelectionIsVisible = sal_False; 2732 } 2733 2734 bHasFocus = sal_False; 2735 } 2736 Control::LoseFocus(); 2737 } 2738 2739 //------------------------------------------------------------------- 2740 2741 void BrowseBox::GetFocus() 2742 { 2743 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants); 2744 DBG_TRACE1( "BrowseBox: %p->GetFocus", this ); 2745 2746 if ( !bHasFocus ) 2747 { 2748 if ( !bSelectionIsVisible ) 2749 { 2750 bSelectionIsVisible = sal_True; 2751 if ( bBootstrapped ) 2752 ToggleSelection(); 2753 } 2754 2755 bHasFocus = sal_True; 2756 DoShowCursor( "GetFocus" ); 2757 } 2758 Control::GetFocus(); 2759 } 2760 2761 2762