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