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