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