update dev300-m57
[ooovba.git] / svtools / source / brwbox / brwbox1.cxx
blobff003d5653c51c8eee27949070101f6ef8258467
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: brwbox1.cxx,v $
10 * $Revision: 1.47 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <svtools/brwbox.hxx>
34 #include <svtools/brwhead.hxx>
35 #include "datwin.hxx"
36 #include <tools/debug.hxx>
37 #include <tools/stream.hxx>
39 #include <functional>
40 #include <algorithm>
41 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
42 #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp>
43 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
44 #include <com/sun/star/accessibility/XAccessible.hpp>
45 #include <tools/multisel.hxx>
46 #include "brwimpl.hxx"
48 DBG_NAME(BrowseBox)
50 extern const char* BrowseBoxCheckInvariants( const void* pVoid );
52 DECLARE_LIST( BrowserColumns, BrowserColumn* )
54 #define SCROLL_FLAGS (SCROLL_CLIP | SCROLL_NOCHILDREN)
55 #define getDataWindow() ((BrowserDataWin*)pDataWin)
57 using namespace com::sun::star::accessibility::AccessibleEventId;
58 using namespace com::sun::star::accessibility::AccessibleTableModelChangeType;
59 using com::sun::star::accessibility::AccessibleTableModelChange;
60 using com::sun::star::lang::XComponent;
61 using namespace ::com::sun::star::uno;
62 using namespace svt;
64 //-------------------------------------------------------------------
66 #ifdef DBG_MI
67 void DoLog_Impl( const BrowseBox *pThis, const char *pWhat, const char *pWho )
69 SvFileStream aLog( "d:\\cursor.log", STREAM_WRITE|STREAM_NOCREATE );
70 if ( aLog.IsOpen() )
72 aLog.Seek( STREAM_SEEK_TO_END );
73 String aEntry( (long) pThis );
74 aEntry += "(row=";
75 aEntry += pThis->GetCurRow();
76 aEntry += "): ";
77 aEntry += pWhat;
78 aEntry += " from ";
79 aEntry += pWho;
80 aEntry += " => ";
81 aEntry += pThis->GetCursorHideCount();
82 aLog.WriteLine( aEntry );
85 #endif
87 namespace
89 void disposeAndClearHeaderCell(::svt::BrowseBoxImpl::THeaderCellMap& _rHeaderCell)
91 ::std::for_each(
92 _rHeaderCell.begin(),
93 _rHeaderCell.end(),
94 ::svt::BrowseBoxImpl::THeaderCellMapFunctorDispose()
96 _rHeaderCell.clear();
100 //===================================================================
102 void BrowseBox::ConstructImpl( BrowserMode nMode )
104 DBG_TRACE1( "BrowseBox: %p->ConstructImpl", this );
105 bMultiSelection = FALSE;
106 pColSel = 0;
107 pDataWin = 0;
108 pVScroll = 0;
110 pDataWin = new BrowserDataWin( this );
111 pCols = new BrowserColumns;
112 m_pImpl.reset( new ::svt::BrowseBoxImpl() );
114 aGridLineColor = Color( COL_LIGHTGRAY );
115 InitSettings_Impl( this );
116 InitSettings_Impl( pDataWin );
118 bBootstrapped = FALSE;
119 nDataRowHeight = 0;
120 nTitleLines = 1;
121 nFirstCol = 0;
122 nTopRow = 0;
123 nCurRow = BROWSER_ENDOFSELECTION;
124 nCurColId = 0;
125 bResizing = FALSE;
126 bSelect = FALSE;
127 bSelecting = FALSE;
128 bScrolling = FALSE;
129 bSelectionIsVisible = FALSE;
130 bNotToggleSel = FALSE;
131 bRowDividerDrag = FALSE;
132 bHit = FALSE;
133 mbInteractiveRowHeight = FALSE;
134 bHideSelect = FALSE;
135 bHideCursor = NO_CURSOR_HIDE;
136 nRowCount = 0;
137 m_bFocusOnlyCursor = TRUE;
138 m_aCursorColor = COL_TRANSPARENT;
139 m_nCurrentMode = 0;
140 nControlAreaWidth = USHRT_MAX;
141 uRow.nSel = BROWSER_ENDOFSELECTION;
143 aHScroll.SetLineSize(1);
144 aHScroll.SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
145 aHScroll.SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
146 pDataWin->Show();
148 SetMode( nMode );
149 bSelectionIsVisible = bKeepHighlight;
150 bHasFocus = HasChildPathFocus();
151 getDataWindow()->nCursorHidden =
152 ( bHasFocus ? 0 : 1 ) + ( GetUpdateMode() ? 0 : 1 );
153 LOG( this, "ConstructImpl", "*" );
156 //-------------------------------------------------------------------
158 BrowseBox::BrowseBox( Window* pParent, WinBits nBits, BrowserMode nMode )
159 :Control( pParent, nBits | WB_3DLOOK )
160 ,DragSourceHelper( this )
161 ,DropTargetHelper( this )
162 ,aHScroll( this, WinBits( WB_HSCROLL ) )
164 DBG_CTOR( BrowseBox, NULL );
165 ConstructImpl( nMode );
168 //-------------------------------------------------------------------
170 BrowseBox::BrowseBox( Window* pParent, const ResId& rId, BrowserMode nMode )
171 :Control( pParent, rId )
172 ,DragSourceHelper( this )
173 ,DropTargetHelper( this )
174 ,aHScroll( this, WinBits(WB_HSCROLL) )
176 DBG_CTOR( BrowseBox, NULL );
177 ConstructImpl(nMode);
179 //-------------------------------------------------------------------
181 BrowseBox::~BrowseBox()
183 DBG_DTOR(BrowseBox,BrowseBoxCheckInvariants);
184 DBG_TRACE1( "BrowseBox: %p~", this );
186 if ( m_pImpl->m_pAccessible )
188 disposeAndClearHeaderCell(m_pImpl->m_aColHeaderCellMap);
189 disposeAndClearHeaderCell(m_pImpl->m_aRowHeaderCellMap);
190 m_pImpl->m_pAccessible->dispose();
193 Hide();
194 delete getDataWindow()->pHeaderBar;
195 delete getDataWindow()->pCornerWin;
196 delete pDataWin;
197 delete pVScroll;
199 // free columns-space
200 for ( USHORT n = 0; n < pCols->Count(); ++n )
201 delete pCols->GetObject(n);
202 delete pCols;
203 delete pColSel;
204 if ( bMultiSelection )
205 delete uRow.pSel;
208 //-------------------------------------------------------------------
210 short BrowseBox::GetCursorHideCount() const
212 return getDataWindow()->nCursorHidden;
215 //-------------------------------------------------------------------
217 void BrowseBox::DoShowCursor( const char *
218 #ifdef DBG_MI
219 pWhoLogs
220 #endif
223 short nHiddenCount = --getDataWindow()->nCursorHidden;
224 if (PaintCursorIfHiddenOnce())
226 if (1 == nHiddenCount)
227 DrawCursor();
229 else
231 if (0 == nHiddenCount)
232 DrawCursor();
234 LOG( this, "DoShowCursor", pWhoLogs );
237 //-------------------------------------------------------------------
239 void BrowseBox::DoHideCursor( const char *
240 #ifdef DBG_MI
241 pWhoLogs
242 #endif
245 short nHiddenCount = ++getDataWindow()->nCursorHidden;
246 if (PaintCursorIfHiddenOnce())
248 if (2 == nHiddenCount)
249 DrawCursor();
251 else
253 if (1 == nHiddenCount)
254 DrawCursor();
256 LOG( this, "DoHideCursor", pWhoLogs );
259 //-------------------------------------------------------------------
261 void BrowseBox::SetRealRowCount( const String &rRealRowCount )
263 getDataWindow()->aRealRowCount = rRealRowCount;
266 //-------------------------------------------------------------------
268 void BrowseBox::SetFont( const Font& rNewFont )
270 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
271 pDataWin->SetFont( rNewFont );
272 ImpGetDataRowHeight();
275 //-------------------------------------------------------------------
277 ULONG BrowseBox::GetDefaultColumnWidth( const String& _rText ) const
279 return GetDataWindow().GetTextWidth( _rText ) + GetDataWindow().GetTextWidth( '0' ) * 4;
282 //-------------------------------------------------------------------
284 void BrowseBox::InsertHandleColumn( ULONG nWidth )
286 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
288 pCols->Insert( new BrowserColumn( 0, Image(), String(), nWidth, GetZoom(), 0 ), (ULONG) 0 );
289 FreezeColumn( 0 );
291 // Headerbar anpassen
292 if ( getDataWindow()->pHeaderBar )
294 getDataWindow()->pHeaderBar->SetPosSizePixel(
295 Point(nWidth, 0),
296 Size( GetOutputSizePixel().Width() - nWidth, GetTitleHeight() )
300 /*if ( getDataWindow()->pHeaderBar )
301 getDataWindow()->pHeaderBar->InsertItem( USHRT_MAX - 1,
302 "", nWidth, HIB_FIXEDPOS|HIB_FIXED, 0 );*/
303 ColumnInserted( 0 );
306 //-------------------------------------------------------------------
307 void BrowseBox::InsertDataColumn( USHORT nItemId, const Image& rImage,
308 long nWidth, HeaderBarItemBits nBits, USHORT nPos )
310 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
312 pCols->Insert( new BrowserColumn( nItemId, rImage, String(), nWidth, GetZoom(), nBits ),
313 Min( nPos, (USHORT)(pCols->Count()) ) );
314 if ( nCurColId == 0 )
315 nCurColId = nItemId;
316 if ( getDataWindow()->pHeaderBar )
318 // Handlecolumn nicht in der Headerbar
319 USHORT nHeaderPos = nPos;
320 if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
321 nHeaderPos--;
322 getDataWindow()->pHeaderBar->InsertItem(
323 nItemId, rImage, nWidth, nBits, nHeaderPos );
325 ColumnInserted( nPos );
328 //-------------------------------------------------------------------
330 void BrowseBox::InsertDataColumn( USHORT nItemId, const XubString& rText,
331 long nWidth, HeaderBarItemBits nBits, USHORT nPos )
333 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
335 pCols->Insert( new BrowserColumn( nItemId, Image(), rText, nWidth, GetZoom(), nBits ),
336 Min( nPos, (USHORT)(pCols->Count()) ) );
337 if ( nCurColId == 0 )
338 nCurColId = nItemId;
340 if ( getDataWindow()->pHeaderBar )
342 // Handlecolumn nicht in der Headerbar
343 USHORT nHeaderPos = nPos;
344 if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
345 nHeaderPos--;
346 getDataWindow()->pHeaderBar->InsertItem(
347 nItemId, rText, nWidth, nBits, nHeaderPos );
349 ColumnInserted( nPos );
352 //-------------------------------------------------------------------
354 void BrowseBox::InsertDataColumn( USHORT nItemId,
355 const Image& rImage, const XubString& rText,
356 long nWidth, HeaderBarItemBits nBits, USHORT nPos,
357 const String* pHelpText )
359 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
361 pCols->Insert( new BrowserColumn( nItemId, rImage, rText, nWidth, GetZoom(), nBits ),
362 Min( nPos, (USHORT)(pCols->Count()) ) );
363 if ( nCurColId == 0 )
364 nCurColId = nItemId;
365 if ( getDataWindow()->pHeaderBar )
367 // Handlecolumn nicht in der Headerbar
368 USHORT nHeaderPos = nPos;
369 if (nHeaderPos != HEADERBAR_APPEND && !GetColumnId(0))
370 nHeaderPos--;
372 getDataWindow()->pHeaderBar->InsertItem(
373 nItemId, rImage, rText, nWidth, nBits, nHeaderPos );
374 if( pHelpText && !rText.Len() )
376 getDataWindow()->pHeaderBar->SetHelpText(
377 nItemId, *pHelpText );
380 ColumnInserted( nPos );
382 //-------------------------------------------------------------------
383 USHORT BrowseBox::ToggleSelectedColumn()
385 USHORT nSelectedColId = USHRT_MAX;
386 if ( pColSel && pColSel->GetSelectCount() )
388 DoHideCursor( "ToggleSelectedColumn" );
389 ToggleSelection();
390 nSelectedColId = pCols->GetObject(pColSel->FirstSelected())->GetId();
391 pColSel->SelectAll(FALSE);
393 return nSelectedColId;
395 // -----------------------------------------------------------------------------
396 void BrowseBox::SetToggledSelectedColumn(USHORT _nSelectedColumnId)
398 if ( pColSel && _nSelectedColumnId != USHRT_MAX )
400 pColSel->Select( GetColumnPos( _nSelectedColumnId ) );
401 ToggleSelection();
402 DBG_TRACE1( "BrowseBox: %p->SetToggledSelectedColumn", this );
403 DoShowCursor( "SetToggledSelectedColumn" );
406 // -----------------------------------------------------------------------------
407 void BrowseBox::FreezeColumn( USHORT nItemId, BOOL bFreeze )
409 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
411 // never unfreeze the handle-column
412 if ( nItemId == 0 && !bFreeze )
413 return;
415 // get the position in the current array
416 USHORT nItemPos = GetColumnPos( nItemId );
417 if ( nItemPos >= pCols->Count() )
418 // not available!
419 return;
421 // doesn't the state change?
422 if ( pCols->GetObject(nItemPos)->IsFrozen() == bFreeze )
423 return;
425 // remark the column selection
426 USHORT nSelectedColId = ToggleSelectedColumn();
428 // freeze or unfreeze?
429 if ( bFreeze )
431 // to be moved?
432 if ( nItemPos != 0 && !pCols->GetObject(nItemPos-1)->IsFrozen() )
434 // move to the right of the last frozen column
435 USHORT nFirstScrollable = FrozenColCount();
436 BrowserColumn *pColumn = pCols->GetObject(nItemPos);
437 pCols->Remove( (ULONG) nItemPos );
438 nItemPos = nFirstScrollable;
439 pCols->Insert( pColumn, (ULONG) nItemPos );
442 // adjust the number of the first scrollable and visible column
443 if ( nFirstCol <= nItemPos )
444 nFirstCol = nItemPos + 1;
446 else
448 // to be moved?
449 if ( nItemPos != FrozenColCount()-1 )
451 // move to the leftmost scrollable colum
452 USHORT nFirstScrollable = FrozenColCount();
453 BrowserColumn *pColumn = pCols->GetObject(nItemPos);
454 pCols->Remove( (ULONG) nItemPos );
455 nItemPos = nFirstScrollable;
456 pCols->Insert( pColumn, (ULONG) nItemPos );
459 // adjust the number of the first scrollable and visible column
460 nFirstCol = nItemPos;
463 // toggle the freeze-state of the column
464 pCols->GetObject(nItemPos)->Freeze( bFreeze );
466 // align the scrollbar-range
467 UpdateScrollbars();
469 // repaint
470 Control::Invalidate();
471 getDataWindow()->Invalidate();
473 // remember the column selection
474 SetToggledSelectedColumn(nSelectedColId);
477 //-------------------------------------------------------------------
479 void BrowseBox::SetColumnPos( USHORT nColumnId, USHORT nPos )
481 // never set pos of the handle-column
482 if ( nColumnId == 0 )
483 return;
485 // do not move handle column
486 if (nPos == 0 && !pCols->GetObject(0)->GetId())
487 return;
489 // get the position in the current array
490 USHORT nOldPos = GetColumnPos( nColumnId );
491 if ( nOldPos >= pCols->Count() )
492 // not available!
493 return;
495 // does the state change?
496 if (nOldPos != nPos)
498 // remark the column selection
499 USHORT nSelectedColId = ToggleSelectedColumn();
501 // determine old column area
502 Size aDataWinSize( pDataWin->GetSizePixel() );
503 if ( getDataWindow()->pHeaderBar )
504 aDataWinSize.Height() += getDataWindow()->pHeaderBar->GetSizePixel().Height();
506 Rectangle aFromRect( GetFieldRect( nColumnId) );
507 aFromRect.Right() += 2*MIN_COLUMNWIDTH;
509 USHORT nNextPos = nOldPos + 1;
510 if ( nOldPos > nPos )
511 nNextPos = nOldPos - 1;
513 BrowserColumn *pNextCol = pCols->GetObject(nNextPos);
514 Rectangle aNextRect(GetFieldRect( pNextCol->GetId() ));
516 // move column internally
517 pCols->Insert( pCols->Remove( nOldPos ), nPos );
519 // determine new column area
520 Rectangle aToRect( GetFieldRect( nColumnId ) );
521 aToRect.Right() += 2*MIN_COLUMNWIDTH;
523 // do scroll, let redraw
524 if( pDataWin->GetBackground().IsScrollable() )
526 long nScroll = -aFromRect.GetWidth();
527 Rectangle aScrollArea;
528 if ( nOldPos > nPos )
530 long nFrozenWidth = GetFrozenWidth();
531 if ( aToRect.Left() < nFrozenWidth )
532 aToRect.Left() = nFrozenWidth;
533 aScrollArea = Rectangle(Point(aToRect.Left(),0),
534 Point(aNextRect.Right(),aDataWinSize.Height()));
535 nScroll *= -1; // reverse direction
537 else
538 aScrollArea = Rectangle(Point(aNextRect.Left(),0),
539 Point(aToRect.Right(),aDataWinSize.Height()));
541 pDataWin->Scroll( nScroll, 0, aScrollArea, SCROLL_FLAGS );
542 aToRect.Top() = 0;
543 aToRect.Bottom() = aScrollArea.Bottom();
544 Invalidate( aToRect );
546 else
547 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
549 // adjust header bar positions
550 if ( getDataWindow()->pHeaderBar )
552 USHORT nNewPos = nPos;
553 if ( !GetColumnId(0) )
554 --nNewPos;
555 getDataWindow()->pHeaderBar->MoveItem(nColumnId,nNewPos);
557 // remember the column selection
558 SetToggledSelectedColumn(nSelectedColId);
560 if ( isAccessibleAlive() )
562 commitTableEvent(
563 TABLE_MODEL_CHANGED,
564 makeAny( AccessibleTableModelChange(
565 DELETE,
567 GetRowCount(),
568 nOldPos,
569 nOldPos
572 Any()
575 commitTableEvent(
576 TABLE_MODEL_CHANGED,
577 makeAny( AccessibleTableModelChange(
578 INSERT,
580 GetRowCount(),
581 nPos,
582 nPos
585 Any()
592 //-------------------------------------------------------------------
594 void BrowseBox::SetColumnMode( USHORT nColumnId, BrowserColumnMode nFlags )
596 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
598 // never set mode of the handle-column
599 if ( nColumnId == 0 )
600 return;
602 // get the position in the current array
603 USHORT nColumnPos = GetColumnPos( nColumnId );
604 if ( nColumnPos >= pCols->Count() )
605 // not available!
606 return;
608 // does the state change?
609 BrowserColumn *pCol = pCols->GetObject(nColumnPos);
610 if ( pCol->Flags() != nFlags )
612 pCol->Flags() = sal::static_int_cast< HeaderBarItemBits >(nFlags);
614 // redraw visible colums
615 if ( GetUpdateMode() && ( pCol->IsFrozen() || nColumnPos > nFirstCol ) )
616 Invalidate( Rectangle( Point(0,0),
617 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
621 //-------------------------------------------------------------------
623 void BrowseBox::SetColumnTitle( USHORT nItemId, const String& rTitle )
625 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
627 // never set title of the handle-column
628 if ( nItemId == 0 )
629 return;
631 // get the position in the current array
632 USHORT nItemPos = GetColumnPos( nItemId );
633 if ( nItemPos >= pCols->Count() )
634 // not available!
635 return;
637 // does the state change?
638 BrowserColumn *pCol = pCols->GetObject(nItemPos);
639 if ( pCol->Title() != rTitle )
641 ::rtl::OUString sNew(rTitle);
642 ::rtl::OUString sOld(pCol->Title());
644 pCol->Title() = rTitle;
646 // Headerbar-Column anpassen
647 if ( getDataWindow()->pHeaderBar )
648 getDataWindow()->pHeaderBar->SetItemText(
649 nItemId ? nItemId : USHRT_MAX - 1, rTitle );
650 else
652 // redraw visible colums
653 if ( GetUpdateMode() && ( pCol->IsFrozen() || nItemPos > nFirstCol ) )
654 Invalidate( Rectangle( Point(0,0),
655 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
658 if ( isAccessibleAlive() )
660 commitTableEvent( TABLE_COLUMN_DESCRIPTION_CHANGED,
661 makeAny( sNew ),
662 makeAny( sOld )
668 //-------------------------------------------------------------------
670 void BrowseBox::SetColumnWidth( USHORT nItemId, ULONG nWidth )
672 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
674 // get the position in the current array
675 USHORT nItemPos = GetColumnPos( nItemId );
676 if ( nItemPos >= pCols->Count() )
677 return;
679 // does the state change?
680 nWidth = QueryColumnResize( nItemId, nWidth );
681 if ( nWidth >= LONG_MAX || pCols->GetObject(nItemPos)->Width() != nWidth )
683 long nOldWidth = pCols->GetObject(nItemPos)->Width();
685 // ggf. letzte Spalte anpassen
686 if ( IsVisible() && nItemPos == pCols->Count() - 1 )
688 long nMaxWidth = pDataWin->GetSizePixel().Width();
689 nMaxWidth -= getDataWindow()->bAutoSizeLastCol
690 ? GetFieldRect(nItemId).Left()
691 : GetFrozenWidth();
692 if ( ( (BrowserDataWin*)pDataWin )->bAutoSizeLastCol || nWidth > (ULONG)nMaxWidth )
694 nWidth = nMaxWidth > 16 ? nMaxWidth : nOldWidth;
695 nWidth = QueryColumnResize( nItemId, nWidth );
699 // OV
700 // In AutoSizeLastColumn() wird SetColumnWidth mit nWidth==0xffff
701 // gerufen. Deshalb muss hier nochmal geprueft werden, ob sich die
702 // Breite tatsaechlich geaendert hat.
703 if( (ULONG)nOldWidth == nWidth )
704 return;
706 // soll die Aenderung sofort dargestellt werden?
707 BOOL bUpdate = GetUpdateMode() &&
708 ( pCols->GetObject(nItemPos)->IsFrozen() || nItemPos >= nFirstCol );
710 if ( bUpdate )
712 // Selection hiden
713 DoHideCursor( "SetColumnWidth" );
714 ToggleSelection();
715 //!getDataWindow()->Update();
716 //!Control::Update();
719 // Breite setzen
720 pCols->GetObject(nItemPos)->SetWidth(nWidth, GetZoom());
721 #if 0
722 if ( nItemPos != pCols->Count() - 1 )
724 long nLastColMaxWidth = pDataWin->GetSizePixel().Width() -
725 GetFieldRect(GetColumnId(pCols->Count()-1)).Left();
726 pCols->GetObject(pCols->Count()-1)->Width() = nLastColMaxWidth;
728 #endif
730 // scroll and invalidate
731 if ( bUpdate )
733 // X-Pos der veraenderten Spalte ermitteln
734 long nX = 0;
735 for ( USHORT nCol = 0; nCol < nItemPos; ++nCol )
737 BrowserColumn *pCol = pCols->GetObject(nCol);
738 if ( pCol->IsFrozen() || nCol >= nFirstCol )
739 nX += pCol->Width();
742 // eigentliches scroll+invalidate
743 pDataWin->SetClipRegion();
744 BOOL bSelVis = bSelectionIsVisible;
745 bSelectionIsVisible = FALSE;
746 if( GetBackground().IsScrollable() )
749 Rectangle aScrRect( nX + std::min( (ULONG)nOldWidth, nWidth ), 0,
750 GetSizePixel().Width() , // the header is longer than the datawin
751 pDataWin->GetPosPixel().Y() - 1 );
752 Control::Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
753 aScrRect.Bottom() = pDataWin->GetSizePixel().Height();
754 getDataWindow()->Scroll( nWidth-nOldWidth, 0, aScrRect, SCROLL_FLAGS );
755 Rectangle aInvRect( nX, 0, nX + std::max( nWidth, (ULONG)nOldWidth ), USHRT_MAX );
756 Control::Invalidate( aInvRect, INVALIDATE_NOCHILDREN );
757 ( (BrowserDataWin*)pDataWin )->Invalidate( aInvRect );
759 else
761 Control::Invalidate( INVALIDATE_NOCHILDREN );
762 getDataWindow()->Window::Invalidate( INVALIDATE_NOCHILDREN );
766 //!getDataWindow()->Update();
767 //!Control::Update();
768 bSelectionIsVisible = bSelVis;
769 ToggleSelection();
770 DoShowCursor( "SetColumnWidth" );
772 UpdateScrollbars();
774 // Headerbar-Column anpassen
775 if ( getDataWindow()->pHeaderBar )
776 getDataWindow()->pHeaderBar->SetItemSize(
777 nItemId ? nItemId : USHRT_MAX - 1, nWidth );
779 // adjust last column
780 if ( nItemPos != pCols->Count() - 1 )
781 AutoSizeLastColumn();
786 //-------------------------------------------------------------------
788 void BrowseBox::AutoSizeLastColumn()
790 if ( getDataWindow()->bAutoSizeLastCol &&
791 getDataWindow()->GetUpdateMode() )
793 USHORT nId = GetColumnId( (USHORT)pCols->Count() - 1 );
794 SetColumnWidth( nId, LONG_MAX );
795 ColumnResized( nId );
799 //-------------------------------------------------------------------
801 void BrowseBox::RemoveColumn( USHORT nItemId )
803 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
805 // Spaltenposition ermitteln
806 USHORT nPos = GetColumnPos(nItemId);
807 if ( nPos >= ColCount() )
808 // nicht vorhanden
809 return;
811 // Spaltenselektion korrigieren
812 if ( pColSel )
813 pColSel->Remove( nPos );
815 // Spaltencursor korrigieren
816 if ( nCurColId == nItemId )
817 nCurColId = 0;
819 // Spalte entfernen
820 delete( pCols->Remove( (ULONG) nPos ));
821 // OJ #93534#
822 if ( nFirstCol >= nPos && nFirstCol > FrozenColCount() )
824 OSL_ENSURE(nFirstCol > 0,"FirstCol must be greater zero!");
825 --nFirstCol;
828 // Handlecolumn nicht in der Headerbar
829 if (nItemId)
831 if ( getDataWindow()->pHeaderBar )
832 getDataWindow()->pHeaderBar->RemoveItem( nItemId );
834 else
836 // Headerbar anpassen
837 if ( getDataWindow()->pHeaderBar )
839 getDataWindow()->pHeaderBar->SetPosSizePixel(
840 Point(0, 0),
841 Size( GetOutputSizePixel().Width(), GetTitleHeight() )
846 // vertikalen Scrollbar korrigieren
847 UpdateScrollbars();
849 // ggf. Repaint ausl"osen
850 if ( GetUpdateMode() )
852 getDataWindow()->Invalidate();
853 Control::Invalidate();
854 if ( getDataWindow()->bAutoSizeLastCol && nPos ==ColCount() )
855 SetColumnWidth( GetColumnId( nPos - 1 ), LONG_MAX );
858 if ( isAccessibleAlive() )
860 commitTableEvent(
861 TABLE_MODEL_CHANGED,
862 makeAny( AccessibleTableModelChange( DELETE,
864 GetRowCount(),
865 nPos,
866 nPos
869 Any()
872 commitHeaderBarEvent(
873 CHILD,
874 Any(),
875 makeAny( CreateAccessibleColumnHeader( nPos ) ),
876 sal_True
881 //-------------------------------------------------------------------
883 void BrowseBox::RemoveColumns()
885 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
887 unsigned int nOldCount = pCols->Count();
888 // alle Spalten entfernen
889 while ( pCols->Count() )
890 delete ( pCols->Remove( (ULONG) 0 ));
892 // Spaltenselektion korrigieren
893 if ( pColSel )
895 pColSel->SelectAll(FALSE);
896 pColSel->SetTotalRange( Range( 0, 0 ) );
899 // Spaltencursor korrigieren
900 nCurColId = 0;
901 nFirstCol = 0;
903 if ( getDataWindow()->pHeaderBar )
904 getDataWindow()->pHeaderBar->Clear( );
906 // vertikalen Scrollbar korrigieren
907 UpdateScrollbars();
909 // ggf. Repaint ausl"osen
910 if ( GetUpdateMode() )
912 getDataWindow()->Invalidate();
913 Control::Invalidate();
916 if ( isAccessibleAlive() )
918 if ( pCols->Count() != nOldCount )
920 // all columns should be removed, so we remove the column header bar and append it again
921 // to avoid to notify every column remove
922 commitBrowseBoxEvent(
923 CHILD,
924 Any(),
925 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR))
928 // and now append it again
929 commitBrowseBoxEvent(
930 CHILD,
931 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_COLUMNHEADERBAR)),
932 Any()
935 // notify a table model change
936 commitTableEvent(
937 TABLE_MODEL_CHANGED,
938 makeAny ( AccessibleTableModelChange( DELETE,
940 GetRowCount(),
942 nOldCount
945 Any()
951 //-------------------------------------------------------------------
953 String BrowseBox::GetColumnTitle( USHORT nId ) const
955 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
957 USHORT nItemPos = GetColumnPos( nId );
958 if ( nItemPos >= pCols->Count() )
959 return String();
960 return pCols->GetObject(nItemPos)->Title();
963 //-------------------------------------------------------------------
965 long BrowseBox::GetRowCount() const
967 return nRowCount;
970 //-------------------------------------------------------------------
972 USHORT BrowseBox::ColCount() const
974 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
976 return (USHORT) pCols->Count();
979 //-------------------------------------------------------------------
981 long BrowseBox::ImpGetDataRowHeight() const
983 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
985 BrowseBox *pThis = (BrowseBox*)this;
986 pThis->nDataRowHeight = pThis->CalcReverseZoom(pDataWin->GetTextHeight() + 2);
987 pThis->Resize();
988 getDataWindow()->Invalidate();
989 return nDataRowHeight;
992 //-------------------------------------------------------------------
994 void BrowseBox::SetDataRowHeight( long nPixel )
996 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
998 nDataRowHeight = CalcReverseZoom(nPixel);
999 Resize();
1000 getDataWindow()->Invalidate();
1003 //-------------------------------------------------------------------
1005 void BrowseBox::SetTitleLines( USHORT nLines )
1007 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1009 nTitleLines = nLines;
1012 //-------------------------------------------------------------------
1014 long BrowseBox::ScrollColumns( long nCols )
1016 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1018 if ( nFirstCol + nCols < 0 ||
1019 nFirstCol + nCols >= (long)pCols->Count() )
1020 //?MI: pCols->GetObject( nFirstCol + nCols )->IsFrozen() )
1021 return 0;
1023 // implicitly hides cursor while scrolling
1024 StartScroll();
1025 bScrolling = TRUE;
1026 BOOL bScrollable = pDataWin->GetBackground().IsScrollable();
1027 BOOL bInvalidateView = FALSE;
1029 // scrolling one column to the right?
1030 if ( nCols == 1 )
1032 // update internal value and scrollbar
1033 ++nFirstCol;
1034 aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
1036 if ( !bScrollable )
1038 bInvalidateView = TRUE;
1040 else
1042 long nDelta = pCols->GetObject(nFirstCol-1)->Width();
1043 long nFrozenWidth = GetFrozenWidth();
1045 Rectangle aScrollRect( Point( nFrozenWidth + nDelta, 0 ),
1046 Size ( GetOutputSizePixel().Width() - nFrozenWidth - nDelta,
1047 GetTitleHeight() - 1
1048 ) );
1050 // scroll the header bar area (if there is no dedicated HeaderBar control)
1051 if ( !getDataWindow()->pHeaderBar && nTitleLines )
1053 // actually scroll
1054 Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
1056 // invalidate the area of the column which was scrolled out to the left hand side
1057 Rectangle aInvalidateRect( aScrollRect );
1058 aInvalidateRect.Left() = nFrozenWidth;
1059 aInvalidateRect.Right() = nFrozenWidth + nDelta - 1;
1060 Invalidate( aInvalidateRect );
1063 // scroll the data-area
1064 aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
1066 // actually scroll
1067 pDataWin->Scroll( -nDelta, 0, aScrollRect, SCROLL_FLAGS );
1069 // invalidate the area of the column which was scrolled out to the left hand side
1070 aScrollRect.Left() = nFrozenWidth;
1071 aScrollRect.Right() = nFrozenWidth + nDelta - 1;
1072 getDataWindow()->Invalidate( aScrollRect );
1076 // scrolling one column to the left?
1077 else if ( nCols == -1 )
1079 --nFirstCol;
1080 aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
1082 if ( !bScrollable )
1084 bInvalidateView = TRUE;
1086 else
1088 long nDelta = pCols->GetObject(nFirstCol)->Width();
1089 long nFrozenWidth = GetFrozenWidth();
1091 Rectangle aScrollRect( Point( nFrozenWidth, 0 ),
1092 Size ( GetOutputSizePixel().Width() - nFrozenWidth,
1093 GetTitleHeight() - 1
1094 ) );
1096 // scroll the header bar area (if there is no dedicated HeaderBar control)
1097 if ( !getDataWindow()->pHeaderBar && nTitleLines )
1099 Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
1102 // scroll the data-area
1103 aScrollRect.Bottom() = pDataWin->GetOutputSizePixel().Height();
1104 pDataWin->Scroll( nDelta, 0, aScrollRect, SCROLL_FLAGS );
1107 else
1109 if ( GetUpdateMode() )
1111 Invalidate( Rectangle(
1112 Point( GetFrozenWidth(), 0 ),
1113 Size( GetOutputSizePixel().Width(), GetTitleHeight() ) ) );
1114 getDataWindow()->Invalidate( Rectangle(
1115 Point( GetFrozenWidth(), 0 ),
1116 pDataWin->GetSizePixel() ) );
1119 nFirstCol = nFirstCol + (USHORT)nCols;
1120 aHScroll.SetThumbPos( nFirstCol - FrozenColCount() );
1123 // ggf. externe Headerbar anpassen
1124 if ( getDataWindow()->pHeaderBar )
1126 long nWidth = 0;
1127 for ( USHORT nCol = 0;
1128 nCol < pCols->Count() && nCol < nFirstCol;
1129 ++nCol )
1131 // HandleColumn nicht
1132 if ( pCols->GetObject(nCol)->GetId() )
1133 nWidth += pCols->GetObject(nCol)->Width();
1136 getDataWindow()->pHeaderBar->SetOffset( nWidth );
1139 if( bInvalidateView )
1141 Control::Invalidate( INVALIDATE_NOCHILDREN );
1142 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1145 // implicitly show cursor after scrolling
1146 if ( nCols )
1148 getDataWindow()->Update();
1149 Update();
1151 bScrolling = FALSE;
1152 EndScroll();
1154 return nCols;
1157 //-------------------------------------------------------------------
1159 long BrowseBox::ScrollRows( long nRows )
1161 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1163 // out of range?
1164 if ( getDataWindow()->bNoScrollBack && nRows < 0 )
1165 return 0;
1167 // compute new top row
1168 long nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
1170 long nNewTopRow = Max( (long)nTmpMin, (long)0 );
1172 if ( nNewTopRow == nTopRow )
1173 return 0;
1175 USHORT nVisibleRows =
1176 (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1178 VisibleRowsChanged(nNewTopRow, nVisibleRows);
1180 // compute new top row again (nTopRow might have changed!)
1181 nTmpMin = Min( (long)(nTopRow + nRows), (long)(nRowCount - 1) );
1183 nNewTopRow = Max( (long)nTmpMin, (long)0 );
1185 StartScroll();
1187 // scroll area on screen and/or repaint
1188 long nDeltaY = GetDataRowHeight() * ( nNewTopRow - nTopRow );
1189 long nOldTopRow = nTopRow;
1190 nTopRow = nNewTopRow;
1192 if ( GetUpdateMode() )
1194 pVScroll->SetRange( Range( 0L, nRowCount ) );
1195 pVScroll->SetThumbPos( nTopRow );
1197 if( pDataWin->GetBackground().IsScrollable() &&
1198 Abs( nDeltaY ) > 0 &&
1199 Abs( nDeltaY ) < pDataWin->GetSizePixel().Height() )
1201 pDataWin->Scroll( 0, (short)-nDeltaY, SCROLL_FLAGS );
1203 else
1204 getDataWindow()->Invalidate();
1206 if ( nTopRow - nOldTopRow )
1207 getDataWindow()->Update();
1210 EndScroll();
1212 return nTopRow - nOldTopRow;
1215 //-------------------------------------------------------------------
1217 long BrowseBox::ScrollPages( long )
1219 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1221 return ScrollRows( pDataWin->GetSizePixel().Height() / GetDataRowHeight() );
1224 //-------------------------------------------------------------------
1226 void BrowseBox::RowModified( long nRow, USHORT nColId )
1228 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1230 if ( !GetUpdateMode() )
1231 return;
1233 Rectangle aRect;
1234 if ( nColId == USHRT_MAX )
1235 // invalidate the whole row
1236 aRect = Rectangle( Point( 0, (nRow-nTopRow) * GetDataRowHeight() ),
1237 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
1238 else
1240 // invalidate the specific field
1241 aRect = GetFieldRectPixel( nRow, nColId, FALSE );
1243 getDataWindow()->Invalidate( aRect );
1246 //-------------------------------------------------------------------
1248 void BrowseBox::Clear()
1250 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1252 // adjust the total number of rows
1253 DoHideCursor( "Clear" );
1254 long nOldRowCount = nRowCount;
1255 nRowCount = 0;
1256 nCurRow = BROWSER_ENDOFSELECTION;
1257 nTopRow = 0;
1258 nCurColId = 0;
1260 // nFirstCol darf nicht zurueckgesetzt werden, da ansonsten das Scrollen
1261 // total durcheinander kommt
1262 // nFirstCol darf nur beim Hinzufuegen oder Loeschen von Spalten geaendert werden
1263 // nFirstCol = 0; ->Falsch!!!!
1264 aHScroll.SetThumbPos( 0 );
1265 pVScroll->SetThumbPos( 0 );
1267 Invalidate();
1268 UpdateScrollbars();
1269 SetNoSelection();
1270 DoShowCursor( "Clear" );
1271 CursorMoved();
1273 if ( isAccessibleAlive() )
1275 // all rows should be removed, so we remove the row header bar and append it again
1276 // to avoid to notify every row remove
1277 if ( nOldRowCount != nRowCount )
1279 commitBrowseBoxEvent(
1280 CHILD,
1281 Any(),
1282 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
1285 // and now append it again
1286 commitBrowseBoxEvent(
1287 CHILD,
1288 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) ),
1289 Any()
1292 // notify a table model change
1293 commitTableEvent(
1294 TABLE_MODEL_CHANGED,
1295 makeAny( AccessibleTableModelChange( DELETE,
1297 nOldRowCount,
1299 GetColumnCount())
1301 Any()
1306 // -----------------------------------------------------------------------------
1307 void BrowseBox::RowInserted( long nRow, long nNumRows, BOOL bDoPaint, BOOL bKeepSelection )
1309 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1311 if (nRow < 0)
1312 nRow = 0;
1313 else if (nRow > nRowCount) // maximal = nRowCount
1314 nRow = nRowCount;
1316 if ( nNumRows <= 0 )
1317 return;
1319 #if 0
1320 // Zerlegung in einzelne RowInserted-Aufrufe:
1321 if (nNumRows > 1)
1323 for (long i = 0; i < nNumRows; i++)
1324 RowInserted(nRow + i,1,bDoPaint);
1325 return;
1327 #endif
1329 // adjust total row count
1330 BOOL bLastRow = nRow >= nRowCount;
1331 nRowCount += nNumRows;
1333 DoHideCursor( "RowInserted" );
1335 // must we paint the new rows?
1336 long nOldCurRow = nCurRow;
1337 Size aSz = pDataWin->GetOutputSizePixel();
1338 if ( bDoPaint && nRow >= nTopRow &&
1339 nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
1341 long nY = (nRow-nTopRow) * GetDataRowHeight();
1342 if ( !bLastRow )
1344 // scroll down the rows behind the new row
1345 pDataWin->SetClipRegion();
1346 if( pDataWin->GetBackground().IsScrollable() )
1348 pDataWin->Scroll( 0, GetDataRowHeight() * nNumRows,
1349 Rectangle( Point( 0, nY ),
1350 Size( aSz.Width(), aSz.Height() - nY ) ),
1351 SCROLL_FLAGS );
1353 else
1354 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1356 else
1357 // scroll would cause a repaint, so we must explicitly invalidate
1358 pDataWin->Invalidate( Rectangle( Point( 0, nY ),
1359 Size( aSz.Width(), nNumRows * GetDataRowHeight() ) ) );
1362 // ggf. Top-Row korrigieren
1363 if ( nRow < nTopRow )
1364 nTopRow += nNumRows;
1366 // adjust the selection
1367 if ( bMultiSelection )
1368 uRow.pSel->Insert( nRow, nNumRows );
1369 else if ( uRow.nSel != BROWSER_ENDOFSELECTION && nRow <= uRow.nSel )
1370 uRow.nSel += nNumRows;
1372 // adjust the cursor
1373 if ( nCurRow == BROWSER_ENDOFSELECTION )
1374 GoToRow( 0, FALSE, bKeepSelection );
1375 else if ( nRow <= nCurRow )
1376 GoToRow( nCurRow += nNumRows, FALSE, bKeepSelection );
1378 // adjust the vertical scrollbar
1379 if ( bDoPaint )
1381 UpdateScrollbars();
1382 AutoSizeLastColumn();
1385 DoShowCursor( "RowInserted" );
1386 // notify accessible that rows were inserted
1387 if ( isAccessibleAlive() )
1389 commitTableEvent(
1390 TABLE_MODEL_CHANGED,
1391 makeAny( AccessibleTableModelChange(
1392 INSERT,
1393 nRow,
1394 nRow + nNumRows,
1396 GetColumnCount()
1399 Any()
1402 for (sal_Int32 i = nRow+1 ; i <= nRowCount ; ++i)
1404 commitHeaderBarEvent(
1405 CHILD,
1406 makeAny( CreateAccessibleRowHeader( i ) ),
1407 Any(),
1408 sal_False
1413 if ( nCurRow != nOldCurRow )
1414 CursorMoved();
1416 DBG_ASSERT(nRowCount > 0,"BrowseBox: nRowCount <= 0");
1417 DBG_ASSERT(nCurRow >= 0,"BrowseBox: nCurRow < 0");
1418 DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
1421 //-------------------------------------------------------------------
1423 void BrowseBox::RowRemoved( long nRow, long nNumRows, BOOL bDoPaint )
1425 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1427 if ( nRow < 0 )
1428 nRow = 0;
1429 else if ( nRow >= nRowCount )
1430 nRow = nRowCount - 1;
1432 if ( nNumRows <= 0 )
1433 return;
1435 if ( nRowCount <= 0 )
1436 return;
1438 if ( bDoPaint )
1440 // hide cursor and selection
1441 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1442 ToggleSelection();
1443 DoHideCursor( "RowRemoved" );
1446 // adjust total row count
1447 nRowCount -= nNumRows;
1448 if (nRowCount < 0) nRowCount = 0;
1449 long nOldCurRow = nCurRow;
1451 // adjust the selection
1452 if ( bMultiSelection )
1453 // uRow.pSel->Remove( nRow, nNumRows );
1454 for ( long i = 0; i < nNumRows; i++ )
1455 uRow.pSel->Remove( nRow );
1456 else if ( nRow < uRow.nSel && uRow.nSel >= nNumRows )
1457 uRow.nSel -= nNumRows;
1458 else if ( nRow <= uRow.nSel )
1459 uRow.nSel = BROWSER_ENDOFSELECTION;
1461 // adjust the cursor
1462 if ( nRowCount == 0 ) // don't compare nRowCount with nNumRows as nNumRows already was subtracted from nRowCount
1463 nCurRow = BROWSER_ENDOFSELECTION;
1464 else if ( nRow < nCurRow )
1466 nCurRow -= Min( nCurRow - nRow, nNumRows );
1467 // with the above nCurRow points a) to the first row after the removed block or b) to the same line
1468 // as before, but moved up nNumRows
1469 // case a) needs an additional correction if the last n lines were deleted, as 'the first row after the
1470 // removed block' is an invalid position then
1471 // FS - 09/28/99 - 68429
1472 if (nCurRow == nRowCount)
1473 --nCurRow;
1475 else if( nRow == nCurRow && nCurRow == nRowCount )
1476 nCurRow = nRowCount-1;
1478 // is the deleted row visible?
1479 Size aSz = pDataWin->GetOutputSizePixel();
1480 if ( nRow >= nTopRow &&
1481 nRow <= nTopRow + aSz.Height() / GetDataRowHeight() )
1483 if ( bDoPaint )
1485 // scroll up the rows behind the deleted row
1486 // if there are Rows behind
1487 if (nRow < nRowCount)
1489 long nY = (nRow-nTopRow) * GetDataRowHeight();
1490 pDataWin->SetClipRegion();
1491 if( pDataWin->GetBackground().IsScrollable() )
1493 pDataWin->Scroll( 0, - (short) GetDataRowHeight() * nNumRows,
1494 Rectangle( Point( 0, nY ), Size( aSz.Width(),
1495 aSz.Height() - nY + nNumRows*GetDataRowHeight() ) ),
1496 SCROLL_FLAGS );
1498 else
1499 pDataWin->Window::Invalidate( INVALIDATE_NOCHILDREN );
1501 else
1503 // Repaint the Rect of the deleted row
1504 Rectangle aRect(
1505 Point( 0, (nRow-nTopRow)*GetDataRowHeight() ),
1506 Size( pDataWin->GetSizePixel().Width(),
1507 nNumRows * GetDataRowHeight() ) );
1508 pDataWin->Invalidate( aRect );
1512 // is the deleted row above of the visible area?
1513 else if ( nRow < nTopRow )
1514 nTopRow = nTopRow >= nNumRows ? nTopRow-nNumRows : 0;
1516 if ( bDoPaint )
1518 // reshow cursor and selection
1519 ToggleSelection();
1520 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1521 DoShowCursor( "RowRemoved" );
1523 // adjust the vertical scrollbar
1524 UpdateScrollbars();
1525 AutoSizeLastColumn();
1528 if ( isAccessibleAlive() )
1530 if ( nRowCount == 0 )
1532 // all columns should be removed, so we remove the column header bar and append it again
1533 // to avoid to notify every column remove
1534 commitBrowseBoxEvent(
1535 CHILD,
1536 Any(),
1537 makeAny( m_pImpl->getAccessibleHeaderBar( BBTYPE_ROWHEADERBAR ) )
1540 // and now append it again
1541 commitBrowseBoxEvent(
1542 CHILD,
1543 makeAny(m_pImpl->getAccessibleHeaderBar(BBTYPE_ROWHEADERBAR)),
1544 Any()
1546 commitBrowseBoxEvent(
1547 CHILD,
1548 Any(),
1549 makeAny( m_pImpl->getAccessibleTable() )
1552 // and now append it again
1553 commitBrowseBoxEvent(
1554 CHILD,
1555 makeAny( m_pImpl->getAccessibleTable() ),
1556 Any()
1559 else
1561 commitTableEvent(
1562 TABLE_MODEL_CHANGED,
1563 makeAny( AccessibleTableModelChange(
1564 DELETE,
1565 nRow,
1566 nRow + nNumRows,
1568 GetColumnCount()
1571 Any()
1574 for (sal_Int32 i = nRow+1 ; i <= (nRow+nNumRows) ; ++i)
1576 commitHeaderBarEvent(
1577 CHILD,
1578 Any(),
1579 makeAny( CreateAccessibleRowHeader( i ) ),
1580 sal_False
1586 if ( nOldCurRow != nCurRow )
1587 CursorMoved();
1589 DBG_ASSERT(nRowCount >= 0,"BrowseBox: nRowCount < 0");
1590 DBG_ASSERT(nCurRow >= 0 || nRowCount == 0,"BrowseBox: nCurRow < 0 && nRowCount != 0");
1591 DBG_ASSERT(nCurRow < nRowCount,"nCurRow >= nRowCount");
1594 //-------------------------------------------------------------------
1596 BOOL BrowseBox::GoToRow( long nRow)
1598 return GoToRow(nRow, FALSE, FALSE);
1601 //-------------------------------------------------------------------
1603 BOOL BrowseBox::GoToRowAndDoNotModifySelection( long nRow )
1605 return GoToRow( nRow, FALSE, TRUE );
1608 //-------------------------------------------------------------------
1609 BOOL BrowseBox::GoToRow( long nRow, BOOL bRowColMove, BOOL bKeepSelection )
1611 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1613 long nOldCurRow = nCurRow;
1615 // nothing to do?
1616 if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) )
1617 return TRUE;
1619 // out of range?
1620 if ( nRow < 0 || nRow >= nRowCount )
1621 return FALSE;
1623 // nicht erlaubt?
1624 if ( ( !bRowColMove && !IsCursorMoveAllowed( nRow, nCurColId ) ) )
1625 return FALSE;
1627 if ( getDataWindow()->bNoScrollBack && nRow < nTopRow )
1628 nRow = nTopRow;
1630 // compute the last visible row
1631 Size aSz( pDataWin->GetSizePixel() );
1632 USHORT nVisibleRows = USHORT( aSz.Height() / GetDataRowHeight() - 1 );
1633 long nLastRow = nTopRow + nVisibleRows;
1635 // suspend Updates
1636 getDataWindow()->EnterUpdateLock();
1638 // ggf. altes Highlight weg
1639 if ( !bMultiSelection && !bKeepSelection )
1640 ToggleSelection();
1641 DoHideCursor( "GoToRow" );
1643 // must we scroll?
1644 BOOL bWasVisible = bSelectionIsVisible;
1645 if (! bMultiSelection)
1647 if( !bKeepSelection )
1648 bSelectionIsVisible = FALSE;
1650 if ( nRow < nTopRow )
1651 ScrollRows( nRow - nTopRow );
1652 else if ( nRow > nLastRow )
1653 ScrollRows( nRow - nLastRow );
1654 bSelectionIsVisible = bWasVisible;
1656 // adjust cursor (selection) and thumb
1657 if ( GetUpdateMode() )
1658 pVScroll->SetThumbPos( nTopRow );
1660 // relative positioning (because nCurRow might have changed in the meantime)!
1661 if (nCurRow != BROWSER_ENDOFSELECTION )
1662 nCurRow = nCurRow + (nRow - nOldCurRow);
1664 // make sure that the current position is valid
1665 if (nCurRow == BROWSER_ENDOFSELECTION && nRowCount > 0)
1666 nCurRow = 0;
1667 else if ( nCurRow >= nRowCount )
1668 nCurRow = nRowCount - 1;
1669 aSelRange = Range( nCurRow, nCurRow );
1671 // ggf. neues Highlight anzeigen
1672 if ( !bMultiSelection && !bKeepSelection )
1673 uRow.nSel = nRow;
1675 // resume Updates
1676 getDataWindow()->LeaveUpdateLock();
1678 // Cursor+Highlight
1679 if ( !bMultiSelection && !bKeepSelection)
1680 ToggleSelection();
1681 DoShowCursor( "GoToRow" );
1682 if ( !bRowColMove && nOldCurRow != nCurRow )
1683 CursorMoved();
1685 if ( !bMultiSelection && !bKeepSelection )
1687 if ( !bSelecting )
1688 Select();
1689 else
1690 bSelect = TRUE;
1692 return TRUE;
1695 //-------------------------------------------------------------------
1697 BOOL BrowseBox::GoToColumnId( USHORT nColId)
1699 return GoToColumnId(nColId,TRUE,FALSE);
1703 BOOL BrowseBox::GoToColumnId( USHORT nColId, BOOL bMakeVisible, BOOL bRowColMove)
1705 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1707 if (!bColumnCursor)
1708 return FALSE;
1710 // erlaubt?
1711 if (!bRowColMove && !IsCursorMoveAllowed( nCurRow, nColId ) )
1712 return FALSE;
1714 if ( nColId != nCurColId || (bMakeVisible && !IsFieldVisible(nCurRow, nColId, TRUE)))
1716 USHORT nNewPos = GetColumnPos(nColId);
1717 BrowserColumn* pColumn = pCols->GetObject( nNewPos );
1718 DBG_ASSERT( pColumn, "no column object - invalid id?" );
1719 if ( !pColumn )
1720 return FALSE;
1722 DoHideCursor( "GoToColumnId" );
1723 nCurColId = nColId;
1725 USHORT nFirstPos = nFirstCol;
1726 USHORT nWidth = (USHORT)pColumn->Width();
1727 USHORT nLastPos = GetColumnAtXPosPixel(
1728 pDataWin->GetSizePixel().Width()-nWidth, FALSE );
1729 USHORT nFrozen = FrozenColCount();
1730 if ( bMakeVisible && nLastPos &&
1731 nNewPos >= nFrozen && ( nNewPos < nFirstPos || nNewPos > nLastPos ) )
1733 if ( nNewPos < nFirstPos )
1734 ScrollColumns( nNewPos-nFirstPos );
1735 else if ( nNewPos > nLastPos )
1736 ScrollColumns( nNewPos-nLastPos );
1739 DoShowCursor( "GoToColumnId" );
1740 if (!bRowColMove)
1741 CursorMoved();
1742 return TRUE;
1744 return TRUE;
1747 //-------------------------------------------------------------------
1749 BOOL BrowseBox::GoToRowColumnId( long nRow, USHORT nColId )
1751 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1753 // out of range?
1754 if ( nRow < 0 || nRow >= nRowCount )
1755 return FALSE;
1757 if (!bColumnCursor)
1758 return FALSE;
1760 // nothing to do ?
1761 if ( nRow == nCurRow && ( bMultiSelection || uRow.nSel == nRow ) &&
1762 nColId == nCurColId && IsFieldVisible(nCurRow, nColId, TRUE))
1763 return TRUE;
1765 // erlaubt?
1766 if (!IsCursorMoveAllowed(nRow, nColId))
1767 return FALSE;
1769 DoHideCursor( "GoToRowColumnId" );
1770 BOOL bMoved = GoToRow(nRow, TRUE) && GoToColumnId(nColId, TRUE, TRUE);
1771 DoShowCursor( "GoToRowColumnId" );
1773 if (bMoved)
1774 CursorMoved();
1776 return bMoved;
1779 //-------------------------------------------------------------------
1781 void BrowseBox::SetNoSelection()
1783 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1785 // is there no selection
1786 if ( ( !pColSel || !pColSel->GetSelectCount() ) &&
1787 ( ( !bMultiSelection && uRow.nSel == BROWSER_ENDOFSELECTION ) ||
1788 ( bMultiSelection && !uRow.pSel->GetSelectCount() ) ) )
1789 // nothing to do
1790 return;
1792 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1793 ToggleSelection();
1795 // unselect all
1796 if ( bMultiSelection )
1797 uRow.pSel->SelectAll(FALSE);
1798 else
1799 uRow.nSel = BROWSER_ENDOFSELECTION;
1800 if ( pColSel )
1801 pColSel->SelectAll(FALSE);
1802 if ( !bSelecting )
1803 Select();
1804 else
1805 bSelect = TRUE;
1807 // restore screen
1808 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1810 if ( isAccessibleAlive() )
1812 commitTableEvent(
1813 SELECTION_CHANGED,
1814 Any(),
1815 Any()
1820 //-------------------------------------------------------------------
1822 void BrowseBox::SetSelection( const MultiSelection &rSel )
1824 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1825 DBG_ASSERT( bMultiSelection, "SetSelection only allowed with Multi-Selection-Mode" );
1827 // prepare inverted areas
1828 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1829 ToggleSelection();
1831 // assign Selection
1832 *uRow.pSel = rSel;
1834 // only highlight painted areas
1835 pDataWin->Update();
1837 // notify derived class
1838 if ( !bSelecting )
1839 Select();
1840 else
1841 bSelect = TRUE;
1843 // restore screen
1844 ToggleSelection();
1845 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1847 if ( isAccessibleAlive() )
1849 commitTableEvent(
1850 SELECTION_CHANGED,
1851 Any(),
1852 Any()
1857 //-------------------------------------------------------------------
1859 void BrowseBox::SelectAll()
1861 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1863 if ( !bMultiSelection )
1864 return;
1866 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1867 ToggleSelection();
1869 // select all rows
1870 if ( pColSel )
1871 pColSel->SelectAll(FALSE);
1872 uRow.pSel->SelectAll(TRUE);
1874 // Handle-Column nicht highlighten
1875 BrowserColumn *pFirstCol = pCols->GetObject(0);
1876 long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
1878 // highlight the row selection
1879 if ( !bHideSelect )
1881 Rectangle aHighlightRect;
1882 USHORT nVisibleRows =
1883 (USHORT)(pDataWin->GetOutputSizePixel().Height() / GetDataRowHeight() + 1);
1884 for ( long nRow = Max( nTopRow, uRow.pSel->FirstSelected() );
1885 nRow != BROWSER_ENDOFSELECTION && nRow < nTopRow + nVisibleRows;
1886 nRow = uRow.pSel->NextSelected() )
1887 aHighlightRect.Union( Rectangle(
1888 Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
1889 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) ) );
1890 pDataWin->Invalidate( aHighlightRect );
1893 if ( !bSelecting )
1894 Select();
1895 else
1896 bSelect = TRUE;
1898 // restore screen
1899 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1901 if ( isAccessibleAlive() )
1903 commitTableEvent(
1904 SELECTION_CHANGED,
1905 Any(),
1906 Any()
1908 commitHeaderBarEvent(
1909 SELECTION_CHANGED,
1910 Any(),
1911 Any(),
1912 sal_True
1913 ); // column header event
1915 commitHeaderBarEvent(
1916 SELECTION_CHANGED,
1917 Any(),
1918 Any(),
1919 sal_False
1920 ); // row header event
1924 //-------------------------------------------------------------------
1926 void BrowseBox::SelectRow( long nRow, BOOL _bSelect, BOOL bExpand )
1928 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
1930 if ( !bMultiSelection )
1932 // deselecting is impossible, selecting via cursor
1933 if ( _bSelect )
1934 GoToRow(nRow, FALSE);
1935 return;
1938 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
1940 // remove old selection?
1941 if ( !bExpand || !bMultiSelection )
1943 ToggleSelection();
1944 if ( bMultiSelection )
1945 uRow.pSel->SelectAll(FALSE);
1946 else
1947 uRow.nSel = BROWSER_ENDOFSELECTION;
1948 if ( pColSel )
1949 pColSel->SelectAll(FALSE);
1952 // set new selection
1953 if ( !bHideSelect
1954 && ( ( bMultiSelection
1955 && uRow.pSel->GetTotalRange().Max() >= nRow
1956 && uRow.pSel->Select( nRow, _bSelect )
1958 || ( !bMultiSelection
1959 && ( uRow.nSel = nRow ) != BROWSER_ENDOFSELECTION )
1963 // Handle-Column nicht highlighten
1964 BrowserColumn *pFirstCol = pCols->GetObject(0);
1965 long nOfsX = pFirstCol->GetId() ? 0 : pFirstCol->Width();
1967 // highlight only newly selected part
1968 Rectangle aRect(
1969 Point( nOfsX, (nRow-nTopRow)*GetDataRowHeight() ),
1970 Size( pDataWin->GetSizePixel().Width(), GetDataRowHeight() ) );
1971 pDataWin->Invalidate( aRect );
1974 if ( !bSelecting )
1975 Select();
1976 else
1977 bSelect = TRUE;
1979 // restore screen
1980 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
1982 if ( isAccessibleAlive() )
1984 commitTableEvent(
1985 SELECTION_CHANGED,
1986 Any(),
1987 Any()
1989 commitHeaderBarEvent(
1990 SELECTION_CHANGED,
1991 Any(),
1992 Any(),
1993 sal_False
1994 ); // row header event
1998 //-------------------------------------------------------------------
2000 long BrowseBox::GetSelectRowCount() const
2002 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2004 return bMultiSelection ? uRow.pSel->GetSelectCount() :
2005 uRow.nSel == BROWSER_ENDOFSELECTION ? 0 : 1;
2008 //-------------------------------------------------------------------
2010 void BrowseBox::SelectColumnPos( USHORT nNewColPos, BOOL _bSelect, BOOL bMakeVisible )
2012 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2014 if ( !bColumnCursor || nNewColPos == BROWSER_INVALIDID )
2015 return;
2017 if ( !bMultiSelection )
2019 if ( _bSelect )
2020 GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
2021 return;
2023 else
2025 if ( !GoToColumnId( pCols->GetObject( nNewColPos )->GetId(), bMakeVisible ) )
2026 return;
2029 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
2030 ToggleSelection();
2031 if ( bMultiSelection )
2032 uRow.pSel->SelectAll(FALSE);
2033 else
2034 uRow.nSel = BROWSER_ENDOFSELECTION;
2035 pColSel->SelectAll(FALSE);
2037 if ( pColSel->Select( nNewColPos, _bSelect ) )
2039 // GoToColumnId( pCols->GetObject(nNewColPos)->GetId(), bMakeVisible );
2041 // only highlight painted areas
2042 pDataWin->Update();
2043 Rectangle aFieldRectPix( GetFieldRectPixel( nCurRow, nCurColId, FALSE ) );
2044 Rectangle aRect(
2045 Point( aFieldRectPix.Left() - MIN_COLUMNWIDTH, 0 ),
2046 Size( pCols->GetObject(nNewColPos)->Width(),
2047 pDataWin->GetOutputSizePixel().Height() ) );
2048 pDataWin->Invalidate( aRect );
2049 if ( !bSelecting )
2050 Select();
2051 else
2052 bSelect = TRUE;
2054 if ( isAccessibleAlive() )
2056 commitTableEvent(
2057 SELECTION_CHANGED,
2058 Any(),
2059 Any()
2061 commitHeaderBarEvent(
2062 SELECTION_CHANGED,
2063 Any(),
2064 Any(),
2065 sal_True
2066 ); // column header event
2070 // restore screen
2071 DBG_TRACE1( "BrowseBox: %p->ShowCursor", this );
2074 //-------------------------------------------------------------------
2076 USHORT BrowseBox::GetSelectColumnCount() const
2078 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2080 // while bAutoSelect (==!pColSel), 1 if any rows (yes rows!) else none
2081 return pColSel ? (USHORT) pColSel->GetSelectCount() :
2082 nCurRow >= 0 ? 1 : 0;
2085 //-------------------------------------------------------------------
2086 long BrowseBox::FirstSelectedColumn( ) const
2088 return pColSel ? pColSel->FirstSelected() : BROWSER_ENDOFSELECTION;
2091 //-------------------------------------------------------------------
2092 long BrowseBox::NextSelectedColumn( ) const
2094 return pColSel ? pColSel->NextSelected() : BROWSER_ENDOFSELECTION;
2097 //-------------------------------------------------------------------
2099 long BrowseBox::FirstSelectedRow( BOOL bInverse )
2101 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2103 return bMultiSelection ? uRow.pSel->FirstSelected(bInverse) : uRow.nSel;
2106 //-------------------------------------------------------------------
2108 long BrowseBox::NextSelectedRow()
2110 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2112 return bMultiSelection ? uRow.pSel->NextSelected() : BROWSER_ENDOFSELECTION;
2115 //-------------------------------------------------------------------
2117 long BrowseBox::PrevSelectedRow()
2119 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2121 return bMultiSelection ? uRow.pSel->PrevSelected() : BROWSER_ENDOFSELECTION;
2124 //-------------------------------------------------------------------
2126 long BrowseBox::LastSelectedRow()
2128 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2130 return bMultiSelection ? uRow.pSel->LastSelected() : uRow.nSel;
2133 //-------------------------------------------------------------------
2135 bool BrowseBox::IsRowSelected( long nRow ) const
2137 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2139 return bMultiSelection ? uRow.pSel->IsSelected(nRow) : nRow == uRow.nSel;
2142 //-------------------------------------------------------------------
2144 bool BrowseBox::IsColumnSelected( USHORT nColumnId ) const
2146 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2148 return pColSel ? pColSel->IsSelected( GetColumnPos(nColumnId) ) :
2149 nCurColId == nColumnId;
2152 //-------------------------------------------------------------------
2154 sal_Bool BrowseBox::IsAllSelected() const
2156 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2158 return bMultiSelection && uRow.pSel->IsAllSelected();
2161 //-------------------------------------------------------------------
2163 BOOL BrowseBox::MakeFieldVisible
2165 long nRow, // Zeilen-Nr des Feldes (beginnend mit 0)
2166 USHORT nColId, // Spalten-Id des Feldes
2167 BOOL bComplete // (== FALSE), TRUE => vollst"andig sichtbar machen
2170 /* [Beschreibung]
2172 Macht das durch 'nRow' und 'nColId' beschriebene Feld durch
2173 entsprechendes scrollen sichtbar. Ist 'bComplete' gesetzt, dann wird
2174 gefordert, da\s das Feld ganz sichtbar wird.
2176 [R"uckgabewert]
2178 BOOL TRUE
2179 Das angegebene Feld wurde sichtbar gemacht, bzw. war
2180 bereits sichtbar.
2182 FALSE
2183 Das angegebene Feld konnte nicht sichtbar bzw. bei
2184 'bComplete' nicht vollst"andig sichtbar gemacht werden.
2188 Size aTestSize = pDataWin->GetSizePixel();
2190 if ( !bBootstrapped ||
2191 ( aTestSize.Width() == 0 && aTestSize.Height() == 0 ) )
2192 return FALSE;
2194 // ist es schon sichtbar?
2195 BOOL bVisible = IsFieldVisible( nRow, nColId, bComplete );
2196 if ( bVisible )
2197 return TRUE;
2199 // Spaltenposition und Feld-Rechteck und Ausgabebereich berechnen
2200 USHORT nColPos = GetColumnPos( nColId );
2201 Rectangle aFieldRect = GetFieldRectPixel( nRow, nColId, FALSE );
2202 Rectangle aDataRect = Rectangle( Point(0, 0), pDataWin->GetSizePixel() );
2204 // links au\serhalb?
2205 if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
2206 // => nach rechts scrollen
2207 ScrollColumns( nColPos - nFirstCol );
2209 // solange rechts au\serhalb
2210 while ( aDataRect.Right() < ( bComplete
2211 ? aFieldRect.Right()
2212 : aFieldRect.Left()+aFieldRect.GetWidth()/2 ) )
2214 // => nach links scrollen
2215 if ( ScrollColumns( 1 ) != 1 )
2216 // nichts mehr zu scrollen
2217 break;
2218 aFieldRect = GetFieldRectPixel( nRow, nColId, FALSE );
2221 // oben au\serhalb?
2222 if ( nRow < nTopRow )
2223 // nach unten scrollen
2224 ScrollRows( nRow - nTopRow );
2226 // unten au\serhalb?
2227 long nBottomRow = nTopRow + GetVisibleRows();
2228 // OV: damit nBottomRow die Nummer der letzten sichtbaren Zeile ist
2229 // (Zaehlung ab Null!), muss sie dekrementiert werden.
2230 // Beispiel: BrowseBox enthaelt genau einen Eintrag. nBottomRow := 0 + 1 - 1
2231 if( nBottomRow )
2232 nBottomRow--;
2234 if ( nRow > nBottomRow )
2235 // nach oben scrollen
2236 ScrollRows( nRow - nBottomRow );
2238 // jetzt kann es immer noch nicht passen, z.B. weil Window zu klein
2239 return IsFieldVisible( nRow, nColId, bComplete );
2242 //-------------------------------------------------------------------
2244 BOOL BrowseBox::IsFieldVisible( long nRow, USHORT nColumnId,
2245 BOOL bCompletely ) const
2247 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2249 // durch frozen-Column verdeckt?
2250 USHORT nColPos = GetColumnPos( nColumnId );
2251 if ( nColPos >= FrozenColCount() && nColPos < nFirstCol )
2252 return FALSE;
2254 Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
2255 if ( aRect.IsEmpty() )
2256 return FALSE;
2258 // get the visible area
2259 Rectangle aOutRect( Point(0, 0), pDataWin->GetOutputSizePixel() );
2261 if ( bCompletely )
2262 // test if the field is completely visible
2263 return aOutRect.IsInside( aRect );
2264 else
2265 // test if the field is partly of completely visible
2266 return !aOutRect.Intersection( aRect ).IsEmpty();
2269 //-------------------------------------------------------------------
2271 Rectangle BrowseBox::GetFieldRectPixel( long nRow, USHORT nColumnId,
2272 BOOL bRelToBrowser) const
2274 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2276 // get the rectangle relative to DataWin
2277 Rectangle aRect( ImplFieldRectPixel( nRow, nColumnId ) );
2278 if ( aRect.IsEmpty() )
2279 return aRect;
2281 // adjust relative to BrowseBox's output area
2282 Point aTopLeft( aRect.TopLeft() );
2283 if ( bRelToBrowser )
2285 aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
2286 aTopLeft = ScreenToOutputPixel( aTopLeft );
2289 return Rectangle( aTopLeft, aRect.GetSize() );
2292 //-------------------------------------------------------------------
2294 Rectangle BrowseBox::GetRowRectPixel( long nRow, BOOL bRelToBrowser ) const
2296 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2298 // get the rectangle relative to DataWin
2299 Rectangle aRect;
2300 if ( nTopRow > nRow )
2301 // row is above visible area
2302 return aRect;
2303 aRect = Rectangle(
2304 Point( 0, GetDataRowHeight() * (nRow-nTopRow) ),
2305 Size( pDataWin->GetOutputSizePixel().Width(), GetDataRowHeight() ) );
2306 if ( aRect.TopLeft().Y() > pDataWin->GetOutputSizePixel().Height() )
2307 // row is below visible area
2308 return aRect;
2310 // adjust relative to BrowseBox's output area
2311 Point aTopLeft( aRect.TopLeft() );
2312 if ( bRelToBrowser )
2314 aTopLeft = pDataWin->OutputToScreenPixel( aTopLeft );
2315 aTopLeft = ScreenToOutputPixel( aTopLeft );
2318 return Rectangle( aTopLeft, aRect.GetSize() );
2321 //-------------------------------------------------------------------
2323 Rectangle BrowseBox::ImplFieldRectPixel( long nRow, USHORT nColumnId ) const
2325 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2327 // compute the X-coordinte realtiv to DataWin by accumulation
2328 long nColX = 0;
2329 USHORT nFrozenCols = FrozenColCount();
2330 USHORT nCol;
2331 for ( nCol = 0;
2332 nCol < pCols->Count() && pCols->GetObject(nCol)->GetId() != nColumnId;
2333 ++nCol )
2334 if ( pCols->GetObject(nCol)->IsFrozen() || nCol >= nFirstCol )
2335 nColX += pCols->GetObject(nCol)->Width();
2337 if ( nCol >= pCols->Count() || ( nCol >= nFrozenCols && nCol < nFirstCol ) )
2338 return Rectangle();
2340 // compute the Y-coordinate relative to DataWin
2341 long nRowY = GetDataRowHeight();
2342 if ( nRow != BROWSER_ENDOFSELECTION ) // #105497# OJ
2343 nRowY = ( nRow - nTopRow ) * GetDataRowHeight();
2345 // assemble the Rectangle relative to DataWin
2346 return Rectangle(
2347 Point( nColX + MIN_COLUMNWIDTH, nRowY ),
2348 Size( pCols->GetObject(nCol)->Width() - 2*MIN_COLUMNWIDTH,
2349 GetDataRowHeight() - 1 ) );
2352 //-------------------------------------------------------------------
2354 long BrowseBox::GetRowAtYPosPixel( long nY, BOOL bRelToBrowser ) const
2356 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2358 // compute the Y-coord
2359 if ( bRelToBrowser )
2361 Point aDataTopLeft = pDataWin->OutputToScreenPixel( Point(0, 0) );
2362 Point aTopLeft = OutputToScreenPixel( Point(0, 0) );
2363 nY -= aDataTopLeft.Y() - aTopLeft.Y();
2366 // no row there (e.g. in the header)
2367 if ( nY < 0 || nY >= pDataWin->GetOutputSizePixel().Height() )
2368 return -1;
2370 return nY / GetDataRowHeight() + nTopRow;
2373 //-------------------------------------------------------------------
2375 Rectangle BrowseBox::GetFieldRect( USHORT nColumnId ) const
2377 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2379 return GetFieldRectPixel( nCurRow, nColumnId );
2382 //-------------------------------------------------------------------
2384 USHORT BrowseBox::GetColumnAtXPosPixel( long nX, BOOL ) const
2386 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2388 // accumulate the withds of the visible columns
2389 long nColX = 0;
2390 USHORT nCol;
2391 for ( nCol = 0; nCol < USHORT(pCols->Count()); ++nCol )
2393 BrowserColumn *pCol = pCols->GetObject(nCol);
2394 if ( pCol->IsFrozen() || nCol >= nFirstCol )
2395 nColX += pCol->Width();
2397 if ( nColX > nX )
2398 return nCol;
2401 return BROWSER_INVALIDID;
2404 //-------------------------------------------------------------------
2406 void BrowseBox::ReserveControlArea( USHORT nWidth )
2408 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2410 if ( nWidth != nControlAreaWidth )
2412 OSL_ENSURE(nWidth,"Control aera of 0 is not allowed, Use USHRT_MAX instead!");
2413 nControlAreaWidth = nWidth;
2414 UpdateScrollbars();
2418 //-------------------------------------------------------------------
2420 Rectangle BrowseBox::GetControlArea() const
2422 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2424 return Rectangle(
2425 Point( 0, GetOutputSizePixel().Height() - aHScroll.GetSizePixel().Height() ),
2426 Size( GetOutputSizePixel().Width() - aHScroll.GetSizePixel().Width(),
2427 aHScroll.GetSizePixel().Height() ) );
2430 //-------------------------------------------------------------------
2432 void BrowseBox::SetMode( BrowserMode nMode )
2434 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2436 #ifdef DBG_MIx
2437 Sound::Beep();
2438 nMode =
2439 // BROWSER_COLUMNSELECTION |
2440 // BROWSER_MULTISELECTION |
2441 BROWSER_THUMBDRAGGING |
2442 BROWSER_KEEPHIGHLIGHT |
2443 BROWSER_HLINES |
2444 BROWSER_VLINES |
2445 // BROWSER_HIDECURSOR |
2446 // BROWSER_NO_HSCROLL |
2447 // BROWSER_NO_SCROLLBACK |
2448 BROWSER_AUTO_VSCROLL |
2449 BROWSER_AUTO_HSCROLL |
2450 BROWSER_TRACKING_TIPS |
2451 // BROWSER_HIGHLIGHT_NONE |
2452 BROWSER_HIGHLIGHT_AUTO |
2453 // BROWSER_HIGHLIGHT_MANU |
2454 BROWSER_HEADERBAR_NEW |
2455 // BROWSER_AUTOSIZE_LASTCOL |
2457 #endif
2459 getDataWindow()->bAutoHScroll = BROWSER_AUTO_HSCROLL == ( nMode & BROWSER_AUTO_HSCROLL );
2460 getDataWindow()->bAutoVScroll = BROWSER_AUTO_VSCROLL == ( nMode & BROWSER_AUTO_VSCROLL );
2461 getDataWindow()->bNoHScroll = BROWSER_NO_HSCROLL == ( nMode & BROWSER_NO_HSCROLL );
2462 getDataWindow()->bNoVScroll = BROWSER_NO_VSCROLL == ( nMode & BROWSER_NO_VSCROLL );
2464 DBG_ASSERT( !( getDataWindow()->bAutoHScroll && getDataWindow()->bNoHScroll ),
2465 "BrowseBox::SetMode: AutoHScroll *and* NoHScroll?" );
2466 DBG_ASSERT( !( getDataWindow()->bAutoVScroll && getDataWindow()->bNoVScroll ),
2467 "BrowseBox::SetMode: AutoVScroll *and* NoVScroll?" );
2468 if ( getDataWindow()->bAutoHScroll )
2469 getDataWindow()->bNoHScroll = FALSE;
2470 if ( getDataWindow()->bAutoVScroll )
2471 getDataWindow()->bNoVScroll = FALSE;
2473 if ( getDataWindow()->bNoHScroll )
2474 aHScroll.Hide();
2476 nControlAreaWidth = USHRT_MAX;
2478 getDataWindow()->bNoScrollBack =
2479 BROWSER_NO_SCROLLBACK == ( nMode & BROWSER_NO_SCROLLBACK);
2481 long nOldRowSel = bMultiSelection ? uRow.pSel->FirstSelected() : uRow.nSel;
2482 MultiSelection *pOldRowSel = bMultiSelection ? uRow.pSel : 0;
2483 MultiSelection *pOldColSel = pColSel;
2485 delete pVScroll;
2487 bThumbDragging = ( nMode & BROWSER_THUMBDRAGGING ) == BROWSER_THUMBDRAGGING;
2488 bMultiSelection = ( nMode & BROWSER_MULTISELECTION ) == BROWSER_MULTISELECTION;
2489 bColumnCursor = ( nMode & BROWSER_COLUMNSELECTION ) == BROWSER_COLUMNSELECTION;
2490 bKeepHighlight = ( nMode & BROWSER_KEEPSELECTION ) == BROWSER_KEEPSELECTION;
2492 bHideSelect = ((nMode & BROWSER_HIDESELECT) == BROWSER_HIDESELECT);
2493 // default: do not hide the cursor at all (untaken scrolling and such)
2494 bHideCursor = NO_CURSOR_HIDE;
2496 if ( BROWSER_SMART_HIDECURSOR == ( nMode & BROWSER_SMART_HIDECURSOR ) )
2497 { // smart cursor hide overrules hard cursor hide
2498 bHideCursor = SMART_CURSOR_HIDE;
2500 else if ( BROWSER_HIDECURSOR == ( nMode & BROWSER_HIDECURSOR ) )
2502 bHideCursor = HARD_CURSOR_HIDE;
2505 m_bFocusOnlyCursor = ((nMode & BROWSER_CURSOR_WO_FOCUS) == 0);
2507 bHLines = ( nMode & BROWSER_HLINESFULL ) == BROWSER_HLINESFULL;
2508 bVLines = ( nMode & BROWSER_VLINESFULL ) == BROWSER_VLINESFULL;
2509 bHDots = ( nMode & BROWSER_HLINESDOTS ) == BROWSER_HLINESDOTS;
2510 bVDots = ( nMode & BROWSER_VLINESDOTS ) == BROWSER_VLINESDOTS;
2512 WinBits nVScrollWinBits =
2513 WB_VSCROLL | ( ( nMode & BROWSER_THUMBDRAGGING ) ? WB_DRAG : 0 );
2514 pVScroll = ( nMode & BROWSER_TRACKING_TIPS ) == BROWSER_TRACKING_TIPS
2515 ? new BrowserScrollBar( this, nVScrollWinBits,
2516 (BrowserDataWin*) pDataWin )
2517 : new ScrollBar( this, nVScrollWinBits );
2518 pVScroll->SetLineSize( 1 );
2519 pVScroll->SetPageSize(1);
2520 pVScroll->SetScrollHdl( LINK( this, BrowseBox, ScrollHdl ) );
2521 pVScroll->SetEndScrollHdl( LINK( this, BrowseBox, EndScrollHdl ) );
2523 getDataWindow()->bHighlightAuto =
2524 BROWSER_HIGHLIGHT_AUTO == ( nMode & BROWSER_HIGHLIGHT_AUTO ) ||
2525 BROWSER_HIGHLIGHT_MANU != ( nMode & BROWSER_HIGHLIGHT_MANU );
2526 getDataWindow()->bAutoSizeLastCol =
2527 BROWSER_AUTOSIZE_LASTCOL == ( nMode & BROWSER_AUTOSIZE_LASTCOL );
2528 getDataWindow()->bOwnDataChangedHdl =
2529 BROWSER_OWN_DATACHANGED == ( nMode & BROWSER_OWN_DATACHANGED );
2531 // Headerbar erzeugen, was passiert, wenn eine erzeugt werden mu� und schon Spalten bestehen ?
2532 if ( BROWSER_HEADERBAR_NEW == ( nMode & BROWSER_HEADERBAR_NEW ) )
2534 if (!getDataWindow()->pHeaderBar)
2535 getDataWindow()->pHeaderBar = CreateHeaderBar( this );
2537 else
2539 DELETEZ(getDataWindow()->pHeaderBar);
2544 if ( bColumnCursor )
2546 pColSel = pOldColSel ? pOldColSel : new MultiSelection;
2547 pColSel->SetTotalRange( Range( 0, pCols->Count()-1 ) );
2549 else
2551 pColSel = 0;
2552 delete pColSel;
2555 if ( bMultiSelection )
2557 if ( pOldRowSel )
2558 uRow.pSel = pOldRowSel;
2559 else
2560 uRow.pSel = new MultiSelection;
2562 else
2564 uRow.nSel = nOldRowSel;
2565 delete pOldRowSel;
2568 if ( bBootstrapped )
2570 StateChanged( STATE_CHANGE_INITSHOW );
2571 if ( bMultiSelection && !pOldRowSel &&
2572 nOldRowSel != BROWSER_ENDOFSELECTION )
2573 uRow.pSel->Select( nOldRowSel );
2576 if ( pDataWin )
2577 pDataWin->Invalidate();
2579 // kein Cursor auf Handle-Column
2580 if ( nCurColId == 0 )
2581 nCurColId = GetColumnId( 1 );
2583 m_nCurrentMode = nMode;
2586 //-------------------------------------------------------------------
2588 void BrowseBox::VisibleRowsChanged( long, USHORT )
2590 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2592 // Das alte Verhalten: NumRows automatisch korrigieren:
2593 if ( nRowCount < GetRowCount() )
2595 RowInserted(nRowCount,GetRowCount() - nRowCount,FALSE);
2597 else if ( nRowCount > GetRowCount() )
2599 RowRemoved(nRowCount-(nRowCount - GetRowCount()),nRowCount - GetRowCount(),FALSE);
2603 //-------------------------------------------------------------------
2605 BOOL BrowseBox::IsCursorMoveAllowed( long, USHORT ) const
2607 /* [Beschreibung]
2609 Diese virtuelle Methode wird immer gerufen bevor der Cursor direkt
2610 bewegt werden soll. Durch 'return FALSE' kann verhindert werden, da\s
2611 dies geschieht, wenn z.B. ein Datensatz irgendwelchen Rules widerspricht.
2613 Diese Methode wird nicht gerufen, wenn die Cursorbewegung durch
2614 ein L"oschen oder Einf"ugen (einer Zeile/Spalte) ausgel"ost wird, also
2615 genaugenommen nur eine Cursor-Korrektur vorliegt.
2617 Die Basisimplementierung liefert derzeit immer TRUE.
2621 return TRUE;
2624 //-------------------------------------------------------------------
2626 long BrowseBox::GetDataRowHeight() const
2628 return CalcZoom(nDataRowHeight ? nDataRowHeight : ImpGetDataRowHeight());
2631 //-------------------------------------------------------------------
2633 Window& BrowseBox::GetEventWindow() const
2635 return *getDataWindow()->pEventWin;
2638 //-------------------------------------------------------------------
2640 BrowserHeader* BrowseBox::CreateHeaderBar( BrowseBox* pParent )
2642 BrowserHeader* pNewBar = new BrowserHeader( pParent );
2643 pNewBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
2644 return pNewBar;
2647 void BrowseBox::SetHeaderBar( BrowserHeader* pHeaderBar )
2649 delete ( (BrowserDataWin*)pDataWin )->pHeaderBar;
2650 ( (BrowserDataWin*)pDataWin )->pHeaderBar = pHeaderBar;
2651 ( (BrowserDataWin*)pDataWin )->pHeaderBar->SetStartDragHdl( LINK( this, BrowseBox, StartDragHdl ) );
2653 //-------------------------------------------------------------------
2655 #ifdef DBG_UTIL
2656 const char* BrowseBoxCheckInvariants( const void * pVoid )
2658 const BrowseBox * p = (const BrowseBox *)pVoid;
2660 if (p->nRowCount < 0) return "BrowseBox: nRowCount < 0";
2661 if (p->nTopRow < 0) return "BrowseBox: nTopRow < 0";
2662 if (p->nTopRow >= p->nRowCount && p->nRowCount != 0) return "BrowseBox: nTopRow >= nRowCount && nRowCount != 0";
2663 if (p->nCurRow < -1) return "BrowseBox: nCurRow < -1";
2664 if (p->nCurRow > p->nRowCount) return "BrowseBox: nCurRow > nRowCount";
2666 // Leider waehrend der Bearbeitung nicht immer der Fall:
2667 //if (p->nCurRow < 0 && p->nRowCount != 0) return "nCurRow < 0 && nRowCount != 0";
2668 //if (p->nCurRow >= p->nRowCount && p->nRowCount != 0) return "nCurRow >= nRowCount && nRowCount != 0";
2670 return NULL;
2672 #endif
2674 //-------------------------------------------------------------------
2675 long BrowseBox::GetTitleHeight() const
2677 long nHeight;
2678 // ask the header bar for the text height (if possible), as the header bar's font is adjusted with
2679 // our (and the header's) zoom factor
2680 HeaderBar* pHeaderBar = ( (BrowserDataWin*)pDataWin )->pHeaderBar;
2681 if ( pHeaderBar )
2682 nHeight = pHeaderBar->GetTextHeight();
2683 else
2684 nHeight = GetTextHeight();
2686 return nTitleLines ? nTitleLines * nHeight + 4 : 0;
2689 //-------------------------------------------------------------------
2690 long BrowseBox::CalcReverseZoom(long nVal)
2692 if (IsZoom())
2694 const Fraction& rZoom = GetZoom();
2695 double n = (double)nVal;
2696 n *= (double)rZoom.GetDenominator();
2697 n /= (double)rZoom.GetNumerator();
2698 nVal = n>0 ? (long)(n + 0.5) : -(long)(-n + 0.5);
2701 return nVal;
2704 //-------------------------------------------------------------------
2705 HeaderBar* BrowseBox::GetHeaderBar() const
2707 return getDataWindow()->pHeaderBar;
2709 //-------------------------------------------------------------------
2711 void BrowseBox::CursorMoved()
2713 // before implementing more here, please adjust the EditBrowseBox
2714 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2716 if ( isAccessibleAlive() && HasFocus() )
2717 commitTableEvent(
2718 ACTIVE_DESCENDANT_CHANGED,
2719 makeAny( CreateAccessibleCell( GetCurRow(),GetColumnPos( GetCurColumnId() ) ) ),
2720 Any()
2724 //-------------------------------------------------------------------
2726 void BrowseBox::LoseFocus()
2728 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2729 DBG_TRACE1( "BrowseBox: %p->LoseFocus", this );
2731 if ( bHasFocus )
2733 DBG_TRACE1( "BrowseBox: %p->HideCursor", this );
2734 DoHideCursor( "LoseFocus" );
2736 if ( !bKeepHighlight )
2738 ToggleSelection();
2739 bSelectionIsVisible = FALSE;
2742 bHasFocus = FALSE;
2744 Control::LoseFocus();
2747 //-------------------------------------------------------------------
2749 void BrowseBox::GetFocus()
2751 DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);
2752 DBG_TRACE1( "BrowseBox: %p->GetFocus", this );
2754 if ( !bHasFocus )
2756 if ( !bSelectionIsVisible )
2758 bSelectionIsVisible = TRUE;
2759 if ( bBootstrapped )
2760 ToggleSelection();
2763 bHasFocus = TRUE;
2764 DoShowCursor( "GetFocus" );
2766 Control::GetFocus();