xref: /trunk/main/svtools/source/contnr/svtabbx.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 #include <svtools/svtabbx.hxx>
31 #include <svtools/headbar.hxx>
32 #include <svtools/svtdata.hxx>
33 #ifndef _SVTOOLS_HRC
34 #include <svtools/svtools.hrc>
35 #endif
36 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
37 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
38 #ifndef SVTOOLS_ACCESSIBLE_FACTORY_HXX
39 #include "svtaccessiblefactory.hxx"
40 #endif
41 
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::accessibility;
44 
45 #define MYTABMASK \
46 	( SV_LBOXTAB_ADJUST_RIGHT | SV_LBOXTAB_ADJUST_LEFT | SV_LBOXTAB_ADJUST_CENTER | SV_LBOXTAB_ADJUST_NUMERIC )
47 
48 // SvTreeListBox-Callback
49 
50 void SvTabListBox::SetTabs()
51 {
52 	SvTreeListBox::SetTabs();
53 	if( nTabCount )
54 	{
55 		DBG_ASSERT(pTabList,"TabList ?");
56 
57 		// die TreeListBox hat jetzt ihre Tabulatoren in die Liste eingefuegt.
58 		// jetzt plustern wir die Liste mit zusaetzlichen Tabulatoren auf,
59 		// und passen den ganz rechten Tab der Treelistbox an.
60 
61 		// den ganz rechten Tab nehmen
62 		// HACK fuer den Explorer! Wenn der ViewParent != 0 ist, dann wird
63 		// der erste Tab der TreeListBox von der TreelistBox berechnet!
64 		// Dies wird fuer ButtonsOnRoot benoetigt, da der Explorer nicht
65 		// weiss, welchen zusaetzlichen Offset er in diesem Modus auf
66 		// den Tabulator addieren muss. Die TreeListBox weiss es!
67 		/*
68 		if( !pViewParent )
69 		{
70 		SvLBoxTab* pFirstTab = (SvLBoxTab*)aTabs.GetObject( aTabs.Count()-1 );
71 		pFirstTab->SetPos( pTabList[0].GetPos() );
72 		pFirstTab->nFlags &= ~MYTABMASK;
73 		pFirstTab->nFlags |= pTabList[0].nFlags;
74 		}
75 		*/
76 
77 		// alle anderen Tabs an Liste haengen
78 		for( sal_uInt16 nCurTab = 1; nCurTab < nTabCount; nCurTab++ )
79 		{
80 			SvLBoxTab* pTab = pTabList+nCurTab;
81 			AddTab( pTab->GetPos(), pTab->nFlags );
82 		}
83 	}
84 }
85 
86 void SvTabListBox::InitEntry( SvLBoxEntry* pEntry, const XubString& rStr,
87 	const Image& rColl, const Image& rExp, SvLBoxButtonKind eButtonKind )
88 {
89 	SvTreeListBox::InitEntry( pEntry, rStr, rColl, rExp, eButtonKind );
90 	XubString aToken;
91 
92 	const xub_Unicode* pCurToken = aCurEntry.GetBuffer();
93 	sal_uInt16 nCurTokenLen;
94 	const xub_Unicode* pNextToken = GetToken( pCurToken, nCurTokenLen );
95 	sal_uInt16 nCount = nTabCount; nCount--;
96 	for( sal_uInt16 nToken = 0; nToken < nCount; nToken++ )
97 	{
98 		if( pCurToken && nCurTokenLen )
99 			// aToken.Assign( pCurToken, nCurTokenLen );
100 			aToken = XubString( pCurToken, nCurTokenLen );
101 		else
102 			aToken.Erase();
103 		SvLBoxString* pStr = new SvLBoxString( pEntry, 0, aToken );
104 		pEntry->AddItem( pStr );
105 		pCurToken = pNextToken;
106 		if( pCurToken )
107 			pNextToken = GetToken( pCurToken, nCurTokenLen );
108 		else
109 			nCurTokenLen = 0;
110 	}
111 }
112 
113 
114 SvTabListBox::SvTabListBox( Window* pParent, WinBits nBits )
115 	: SvTreeListBox( pParent, nBits )
116 {
117 	pTabList = 0;
118 	nTabCount = 0;
119 	pViewParent = 0;
120 	SetHighlightRange();	// ueber volle Breite selektieren
121 }
122 
123 SvTabListBox::SvTabListBox( Window* pParent, const ResId& rResId )
124 	: SvTreeListBox( pParent, rResId )
125 {
126 	pTabList = 0;
127 	nTabCount = 0;
128 	pViewParent = 0;
129 	SvTabListBox::Resize();
130 	SetHighlightRange();
131 }
132 
133 SvTabListBox::~SvTabListBox()
134 {
135 	// array-delete
136 	delete [] pTabList;
137 #ifdef DBG_UTIL
138 	pTabList = 0;
139 	nTabCount = 0;
140 #endif
141 }
142 
143 void SvTabListBox::SetTabs( long* pTabs, MapUnit eMapUnit )
144 {
145 	DBG_ASSERT(pTabs,"SetTabs:NULL-Ptr");
146 	if( !pTabs )
147 		return;
148 
149 	delete [] pTabList;
150 	sal_uInt16 nCount = (sal_uInt16)(*pTabs);
151 	pTabList = new SvLBoxTab[ nCount ];
152 	nTabCount = nCount;
153 
154 	MapMode aMMSource( eMapUnit );
155 	MapMode aMMDest( MAP_PIXEL );
156 
157 	pTabs++;
158 	for( sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++, pTabs++ )
159 	{
160 		Size aSize( *pTabs, 0 );
161 		aSize = LogicToLogic( aSize, &aMMSource, &aMMDest );
162 		long nNewTab = aSize.Width();
163 		pTabList[nIdx].SetPos( nNewTab );
164 		pTabList[nIdx].nFlags=(SV_LBOXTAB_ADJUST_LEFT| SV_LBOXTAB_INV_ALWAYS);
165 	}
166 	SvTreeListBox::nTreeFlags |= TREEFLAG_RECALCTABS;
167 	if( IsUpdateMode() )
168 		Invalidate();
169 }
170 
171 void SvTabListBox::SetTab( sal_uInt16 nTab,long nValue,MapUnit eMapUnit )
172 {
173 	DBG_ASSERT(nTab<nTabCount,"Invalid Tab-Pos");
174 	if( nTab < nTabCount )
175 	{
176 		DBG_ASSERT(pTabList,"TabList?");
177 		MapMode aMMSource( eMapUnit );
178 		MapMode aMMDest( MAP_PIXEL );
179 		Size aSize( nValue, 0 );
180 		aSize = LogicToLogic( aSize, &aMMSource, &aMMDest );
181 		nValue = aSize.Width();
182 		pTabList[ nTab ].SetPos( nValue );
183 		SvTreeListBox::nTreeFlags |= TREEFLAG_RECALCTABS;
184 		if( IsUpdateMode() )
185 			Invalidate();
186 	}
187 }
188 
189 SvLBoxEntry* SvTabListBox::InsertEntry( const XubString& rText, SvLBoxEntry* pParent,
190 						                sal_Bool /*bChildsOnDemand*/,
191                                         sal_uLong nPos, void* pUserData,
192                                         SvLBoxButtonKind )
193 {
194     return InsertEntryToColumn( rText, pParent, nPos, 0xffff, pUserData );
195 }
196 
197 SvLBoxEntry* SvTabListBox::InsertEntry( const XubString& rText,
198 						                const Image& rExpandedEntryBmp,
199                                         const Image& rCollapsedEntryBmp,
200                                         SvLBoxEntry* pParent,
201                                         sal_Bool /*bChildsOnDemand*/,
202                                         sal_uLong nPos, void* pUserData,
203                                         SvLBoxButtonKind )
204 {
205     return InsertEntryToColumn( rText, rExpandedEntryBmp, rCollapsedEntryBmp,
206                                 pParent, nPos, 0xffff, pUserData );
207 }
208 
209 SvLBoxEntry* SvTabListBox::InsertEntryToColumn(const XubString& rStr,SvLBoxEntry* pParent,sal_uLong nPos,sal_uInt16 nCol,
210 	void* pUser )
211 {
212 	XubString aStr;
213 	if( nCol != 0xffff )
214 	{
215 		while( nCol )
216 		{
217 			aStr += '\t';
218 			nCol--;
219 		}
220 	}
221 	aStr += rStr;
222 	XubString aFirstStr( aStr );
223 	sal_uInt16 nEnd = aFirstStr.Search( '\t' );
224 	if( nEnd != STRING_NOTFOUND )
225 	{
226 		aFirstStr.Erase( nEnd );
227 		aCurEntry = aStr;
228 		aCurEntry.Erase( 0, ++nEnd );
229 	}
230 	else
231 		aCurEntry.Erase();
232 	return SvTreeListBox::InsertEntry( aFirstStr, pParent, sal_False, nPos, pUser );
233 }
234 
235 SvLBoxEntry* SvTabListBox::InsertEntryToColumn( const XubString& rStr,
236 	const Image& rExpandedEntryBmp,	const Image& rCollapsedEntryBmp,
237 	SvLBoxEntry* pParent,sal_uLong nPos,sal_uInt16 nCol, void* pUser )
238 {
239 	XubString aStr;
240 	if( nCol != 0xffff )
241 	{
242 		while( nCol )
243 		{
244 			aStr += '\t';
245 			nCol--;
246 		}
247 	}
248 	aStr += rStr;
249 	XubString aFirstStr( aStr );
250 	sal_uInt16 nEnd = aFirstStr.Search( '\t' );
251 	if( nEnd != STRING_NOTFOUND )
252 	{
253 		aFirstStr.Erase( nEnd );
254 		aCurEntry = aStr;
255 		aCurEntry.Erase( 0, ++nEnd );
256 	}
257 	else
258 		aCurEntry.Erase();
259 
260 	return SvTreeListBox::InsertEntry(
261 		aFirstStr,
262 		rExpandedEntryBmp, rCollapsedEntryBmp,
263 		pParent, sal_False, nPos, pUser );
264 }
265 
266 SvLBoxEntry* SvTabListBox::InsertEntryToColumn( const XubString& rStr, sal_uLong nPos,
267 	sal_uInt16 nCol, void* pUser )
268 {
269     return InsertEntryToColumn( rStr,0,nPos, nCol, pUser );
270 }
271 
272 String SvTabListBox::GetEntryText( SvLBoxEntry* pEntry ) const
273 {
274 	return GetEntryText( pEntry, 0xffff );
275 }
276 
277 String SvTabListBox::GetEntryText( SvLBoxEntry* pEntry, sal_uInt16 nCol ) const
278 {
279     DBG_ASSERT(pEntry,"GetEntryText:Invalid Entry");
280     XubString aResult;
281     if( pEntry )
282     {
283         sal_uInt16 nCount = pEntry->ItemCount();
284         sal_uInt16 nCur = 0;
285         while( nCur < nCount )
286         {
287             SvLBoxItem* pStr = pEntry->GetItem( nCur );
288             if( pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
289             {
290                 if( nCol == 0xffff )
291                 {
292                     if( aResult.Len() )
293                         aResult += '\t';
294                     aResult += static_cast<SvLBoxString*>( pStr )->GetText();
295                 }
296                 else
297                 {
298                     if( nCol == 0 )
299                         return static_cast<SvLBoxString*>( pStr )->GetText();
300                     nCol--;
301                 }
302             }
303             nCur++;
304         }
305     }
306     return aResult;
307 }
308 
309 String SvTabListBox::GetEntryText( sal_uLong nPos, sal_uInt16 nCol ) const
310 {
311 	SvLBoxEntry* pEntry = GetEntryOnPos( nPos );
312 	return GetEntryText( pEntry, nCol );
313 }
314 
315 void SvTabListBox::SetEntryText( const XubString& rStr, sal_uLong nPos, sal_uInt16 nCol )
316 {
317 	SvLBoxEntry* pEntry = SvTreeListBox::GetEntry( nPos );
318 	SetEntryText( rStr, pEntry, nCol );
319 }
320 
321 void SvTabListBox::SetEntryText( const XubString& rStr, SvLBoxEntry* pEntry, sal_uInt16 nCol )
322 {
323 	DBG_ASSERT(pEntry,"SetEntryText:Invalid Entry");
324 	if( !pEntry )
325 		return;
326 
327     String sOldText = GetEntryText( pEntry, nCol );
328     if ( sOldText == rStr )
329         return;
330 
331     sal_uInt16 nTextColumn = nCol;
332     const xub_Unicode* pCurToken = rStr.GetBuffer();
333 	sal_uInt16 nCurTokenLen;
334 	const xub_Unicode* pNextToken = GetToken( pCurToken, nCurTokenLen );
335 
336 	XubString aTemp;
337 	sal_uInt16 nCount = pEntry->ItemCount();
338 	sal_uInt16 nCur = 0;
339 	while( nCur < nCount )
340 	{
341 		SvLBoxItem* pStr = pEntry->GetItem( nCur );
342 		if( pStr && pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
343 		{
344 			if( nCol == 0xffff )
345 			{
346 				if( pCurToken )
347 					aTemp = XubString( pCurToken, nCurTokenLen );
348 				else
349 					aTemp.Erase(); // alle Spalten ohne Token loeschen
350 				((SvLBoxString*)pStr)->SetText( pEntry, aTemp );
351 				pCurToken = pNextToken;
352 				pNextToken = GetToken( pCurToken, nCurTokenLen );
353 			}
354 			else
355 			{
356 				if( !nCol )
357 				{
358 					aTemp = XubString( pCurToken, nCurTokenLen );
359 					((SvLBoxString*)pStr)->SetText( pEntry, aTemp );
360 					if( !pNextToken )
361 						break;
362 					pCurToken = pNextToken;
363 					pNextToken = GetToken( pCurToken, nCurTokenLen );
364 				}
365 				else
366 					nCol--;
367 			}
368 		}
369 		nCur++;
370 	}
371 	GetModel()->InvalidateEntry( pEntry );
372 
373     TabListBoxEventData* pData = new TabListBoxEventData( pEntry, nTextColumn, sOldText );
374     ImplCallEventListeners( VCLEVENT_TABLECELL_NAMECHANGED, pData );
375     delete pData;
376 }
377 
378 String SvTabListBox::GetCellText( sal_uLong nPos, sal_uInt16 nCol ) const
379 {
380     SvLBoxEntry* pEntry = GetEntryOnPos( nPos );
381     DBG_ASSERT( pEntry, "SvTabListBox::GetCellText(): Invalid Entry" );
382     XubString aResult;
383     if ( pEntry && pEntry->ItemCount() > ( nCol + 1 ) )
384     {
385         SvLBoxItem* pStr = pEntry->GetItem( nCol + 1 );
386         if ( pStr && pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
387             aResult = static_cast< SvLBoxString* >( pStr )->GetText();
388     }
389     return aResult;
390 }
391 
392 sal_uLong SvTabListBox::GetEntryPos( const XubString& rStr, sal_uInt16 nCol )
393 {
394 	sal_uLong nPos = 0;
395 	SvLBoxEntry* pEntry = First();
396 	while( pEntry )
397 	{
398 		XubString aStr( GetEntryText( pEntry, nCol ));
399 		if( aStr == rStr )
400 			return nPos;
401 		pEntry = Next( pEntry );
402 		nPos++;
403 	}
404 	return 0xffffffff;
405 }
406 
407 sal_uLong SvTabListBox::GetEntryPos( const SvLBoxEntry* pEntry ) const
408 {
409 	sal_uLong nPos = 0;
410 	SvLBoxEntry* pTmpEntry = First();
411 	while( pTmpEntry )
412 	{
413 		if ( pTmpEntry == pEntry )
414 			return nPos;
415 		pTmpEntry = Next( pTmpEntry );
416 		++nPos;
417 	}
418 	return 0xffffffff;
419 }
420 
421 void __EXPORT SvTabListBox::Resize()
422 {
423 	SvTreeListBox::Resize();
424 }
425 
426 // static
427 const xub_Unicode* SvTabListBox::GetToken( const xub_Unicode* pPtr, sal_uInt16& rLen )
428 {
429 	if( !pPtr || *pPtr == 0 )
430 	{
431 		rLen = 0;
432 		return 0;
433 	}
434 	xub_Unicode c = *pPtr;
435 	sal_uInt16 nLen = 0;
436 	while( c != '\t' && c != 0 )
437 	{
438 		pPtr++;
439 		nLen++;
440 		c = *pPtr;
441 	}
442 	if( c )
443 		pPtr++; // Tab ueberspringen
444 	else
445 		pPtr = 0;
446 	rLen = nLen;
447 	return pPtr;
448 }
449 
450 String SvTabListBox::GetTabEntryText( sal_uLong nPos, sal_uInt16 nCol ) const
451 {
452 	SvLBoxEntry* pEntry = SvTreeListBox::GetEntry( nPos );
453 	DBG_ASSERT( pEntry, "GetTabEntryText(): Invalid entry " );
454 	XubString aResult;
455 	if ( pEntry )
456 	{
457 		sal_uInt16 nCount = pEntry->ItemCount();
458 		sal_uInt16 nCur = ( 0 == nCol && IsCellFocusEnabled() ) ? GetCurrentTabPos() : 0;
459 		while( nCur < nCount )
460 		{
461 			SvLBoxItem* pStr = pEntry->GetItem( nCur );
462 			if ( pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
463 			{
464 				if ( nCol == 0xffff )
465 				{
466 					if ( aResult.Len() )
467 						aResult += '\t';
468 					aResult += static_cast<SvLBoxString*>( pStr )->GetText();
469 				}
470 				else
471 				{
472 					if ( nCol == 0 )
473 					{
474 						String sRet = static_cast<SvLBoxString*>( pStr )->GetText();
475 						if ( sRet.Len() == 0 )
476 							sRet = String( SvtResId( STR_SVT_ACC_EMPTY_FIELD ) );
477 						return sRet;
478 					}
479 					--nCol;
480 				}
481 			}
482 			++nCur;
483 		}
484 	}
485 	return aResult;
486 }
487 
488 SvLBoxEntry* SvTabListBox::GetEntryOnPos( sal_uLong _nEntryPos ) const
489 {
490 	SvLBoxEntry* pEntry = NULL;
491 	sal_uLong i, nPos = 0, nCount = GetLevelChildCount( NULL );
492 	for ( i = 0; i < nCount; ++i )
493 	{
494 		SvLBoxEntry* pParent = GetEntry(i);
495 		if ( nPos == _nEntryPos )
496 		{
497 			pEntry = pParent;
498 			break;
499 		}
500 		else
501 		{
502 			nPos++;
503 			pEntry = GetChildOnPos( pParent, _nEntryPos, nPos );
504 			if ( pEntry )
505 				break;
506 		}
507 	}
508 
509 	return pEntry;
510 }
511 
512 SvLBoxEntry* SvTabListBox::GetChildOnPos( SvLBoxEntry* _pParent, sal_uLong _nEntryPos, sal_uLong& _rPos ) const
513 {
514 	sal_uLong i, nCount = GetLevelChildCount( _pParent );
515 	for ( i = 0; i < nCount; ++i )
516 	{
517 		SvLBoxEntry* pParent = GetEntry( _pParent, i );
518 		if ( _rPos == _nEntryPos )
519 			return pParent;
520 		else
521 		{
522 			_rPos++;
523 			SvLBoxEntry* pEntry = GetChildOnPos( pParent, _nEntryPos, _rPos );
524 			if ( pEntry )
525 				return pEntry;
526 		}
527 	}
528 
529 	return NULL;
530 }
531 
532 void SvTabListBox::SetTabJustify( sal_uInt16 nTab, SvTabJustify eJustify)
533 {
534 	if( nTab >= nTabCount )
535 		return;
536 	SvLBoxTab* pTab = &(pTabList[ nTab ]);
537 	sal_uInt16 nFlags = pTab->nFlags;
538 	nFlags &= (~MYTABMASK);
539 	nFlags |= (sal_uInt16)eJustify;
540 	pTab->nFlags = nFlags;
541 	SvTreeListBox::nTreeFlags |= TREEFLAG_RECALCTABS;
542 	if( IsUpdateMode() )
543 		Invalidate();
544 }
545 
546 SvTabJustify SvTabListBox::GetTabJustify( sal_uInt16 nTab ) const
547 {
548 	SvTabJustify eResult = AdjustLeft;
549 	if( nTab >= nTabCount )
550 		return eResult;
551 	SvLBoxTab* pTab = &(pTabList[ nTab ]);
552 	sal_uInt16 nFlags = pTab->nFlags;
553 	nFlags &= MYTABMASK;
554 	eResult = (SvTabJustify)nFlags;
555 	return eResult;
556 }
557 
558 long SvTabListBox::GetLogicTab( sal_uInt16 nTab )
559 {
560 	if( SvTreeListBox::nTreeFlags & TREEFLAG_RECALCTABS )
561 		((SvTabListBox*)this)->SetTabs();
562 
563 	DBG_ASSERT(nTab<nTabCount,"GetTabPos:Invalid Tab");
564 	return ((SvLBoxTab*)aTabs.GetObject( nTab ))->GetPos();
565 }
566 
567 // class SvHeaderTabListBoxImpl ------------------------------------------
568 
569 namespace svt
570 {
571     struct SvHeaderTabListBoxImpl
572     {
573 	    HeaderBar*              m_pHeaderBar;
574         AccessibleFactoryAccess m_aFactoryAccess;
575 
576         SvHeaderTabListBoxImpl() : m_pHeaderBar( NULL ) { }
577     };
578 }
579 
580 // class SvHeaderTabListBox ----------------------------------------------
581 
582 SvHeaderTabListBox::SvHeaderTabListBox( Window* pParent, WinBits nWinStyle ) :
583 
584 	SvTabListBox( pParent, nWinStyle ),
585 
586 	m_bFirstPaint	( sal_True ),
587     m_pImpl         ( new ::svt::SvHeaderTabListBoxImpl ),
588 	m_pAccessible	( NULL )
589 {
590 }
591 
592 // -----------------------------------------------------------------------
593 
594 SvHeaderTabListBox::SvHeaderTabListBox( Window* pParent, const ResId& rResId ) :
595 
596 	SvTabListBox( pParent, rResId ),
597 
598 	m_bFirstPaint	( sal_True ),
599     m_pImpl         ( new ::svt::SvHeaderTabListBoxImpl ),
600 	m_pAccessible	( NULL )
601 {
602 }
603 
604 // -----------------------------------------------------------------------
605 
606 SvHeaderTabListBox::~SvHeaderTabListBox()
607 {
608     delete m_pImpl;
609 }
610 
611 // -----------------------------------------------------------------------
612 
613 void SvHeaderTabListBox::Paint( const Rectangle& rRect )
614 {
615 	if ( m_bFirstPaint )
616 	{
617 		m_bFirstPaint = sal_False;
618 		RepaintScrollBars();
619 	}
620 	SvTabListBox::Paint( rRect );
621 }
622 
623 // -----------------------------------------------------------------------
624 
625 void SvHeaderTabListBox::InitHeaderBar( HeaderBar* pHeaderBar )
626 {
627 	DBG_ASSERT( !m_pImpl->m_pHeaderBar, "header bar already initialized" );
628 	DBG_ASSERT( pHeaderBar, "invalid header bar initialization" );
629 	m_pImpl->m_pHeaderBar = pHeaderBar;
630 	SetScrolledHdl( LINK( this, SvHeaderTabListBox, ScrollHdl_Impl ) );
631 	m_pImpl->m_pHeaderBar->SetCreateAccessibleHdl( LINK( this, SvHeaderTabListBox, CreateAccessibleHdl_Impl ) );
632 }
633 
634 // -----------------------------------------------------------------------
635 
636 sal_Bool SvHeaderTabListBox::IsItemChecked( SvLBoxEntry* pEntry, sal_uInt16 nCol ) const
637 {
638     SvButtonState eState = SV_BUTTON_UNCHECKED;
639     SvLBoxButton* pItem = (SvLBoxButton*)( pEntry->GetItem( nCol + 1 ) );
640 
641     if ( pItem && ( (SvLBoxItem*)pItem )->IsA() == SV_ITEM_ID_LBOXBUTTON )
642     {
643         sal_uInt16 nButtonFlags = pItem->GetButtonFlags();
644         eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
645     }
646 
647     return ( eState == SV_BUTTON_CHECKED );
648 }
649 
650 // -----------------------------------------------------------------------
651 
652 SvLBoxEntry* SvHeaderTabListBox::InsertEntryToColumn(
653     const XubString& rStr, sal_uLong nPos, sal_uInt16 nCol, void* pUserData )
654 {
655     SvLBoxEntry* pEntry = SvTabListBox::InsertEntryToColumn( rStr, nPos, nCol, pUserData );
656     RecalculateAccessibleChildren();
657     return pEntry;
658 }
659 
660 // -----------------------------------------------------------------------
661 
662 SvLBoxEntry* SvHeaderTabListBox::InsertEntryToColumn(
663     const XubString& rStr, SvLBoxEntry* pParent, sal_uLong nPos, sal_uInt16 nCol, void* pUserData )
664 {
665     SvLBoxEntry* pEntry = SvTabListBox::InsertEntryToColumn( rStr, pParent, nPos, nCol, pUserData );
666     RecalculateAccessibleChildren();
667     return pEntry;
668 }
669 
670 // -----------------------------------------------------------------------
671 
672 SvLBoxEntry* SvHeaderTabListBox::InsertEntryToColumn(
673     const XubString& rStr, const Image& rExpandedEntryBmp, const Image& rCollapsedEntryBmp,
674     SvLBoxEntry* pParent, sal_uLong nPos, sal_uInt16 nCol, void* pUserData )
675 {
676     SvLBoxEntry* pEntry = SvTabListBox::InsertEntryToColumn(
677         rStr, rExpandedEntryBmp, rCollapsedEntryBmp, pParent, nPos, nCol, pUserData );
678     RecalculateAccessibleChildren();
679     return pEntry;
680 }
681 
682 // -----------------------------------------------------------------------
683 
684 sal_uLong SvHeaderTabListBox::Insert(
685     SvLBoxEntry* pEnt, SvLBoxEntry* pPar, sal_uLong nPos )
686 {
687     sal_uLong n = SvTabListBox::Insert( pEnt, pPar, nPos );
688     RecalculateAccessibleChildren();
689     return n;
690 }
691 
692 // -----------------------------------------------------------------------
693 
694 sal_uLong SvHeaderTabListBox::Insert( SvLBoxEntry* pEntry, sal_uLong nRootPos )
695 {
696     sal_uLong nPos = SvTabListBox::Insert( pEntry, nRootPos );
697     RecalculateAccessibleChildren();
698     return nPos;
699 }
700 
701 // -----------------------------------------------------------------------
702 
703 void SvHeaderTabListBox::RemoveEntry( SvLBoxEntry* _pEntry )
704 {
705     GetModel()->Remove( _pEntry );
706     m_aAccessibleChildren.clear();
707 }
708 
709 // -----------------------------------------------------------------------
710 
711 void SvHeaderTabListBox::Clear()
712 {
713     SvTabListBox::Clear();
714     m_aAccessibleChildren.clear();
715 }
716 
717 // -----------------------------------------------------------------------
718 
719 IMPL_LINK( SvHeaderTabListBox, ScrollHdl_Impl, SvTabListBox*, EMPTYARG )
720 {
721 	m_pImpl->m_pHeaderBar->SetOffset( -GetXOffset() );
722 	return 0;
723 }
724 
725 // -----------------------------------------------------------------------
726 
727 IMPL_LINK( SvHeaderTabListBox, CreateAccessibleHdl_Impl, HeaderBar*, EMPTYARG )
728 {
729     Window* pParent = m_pImpl->m_pHeaderBar->GetAccessibleParentWindow();
730     DBG_ASSERT( pParent, "SvHeaderTabListBox..CreateAccessibleHdl_Impl - accessible parent not found" );
731     if ( pParent )
732     {
733         ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
734         if ( xAccParent.is() )
735 		{
736             Reference< XAccessible > xAccessible = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxHeaderBar(
737                 xAccParent, *this, ::svt::BBTYPE_COLUMNHEADERBAR );
738 			m_pImpl->m_pHeaderBar->SetAccessible( xAccessible );
739 		}
740 	}
741 	return 0;
742 }
743 
744 // -----------------------------------------------------------------------
745 
746 void SvHeaderTabListBox::RecalculateAccessibleChildren()
747 {
748     if ( !m_aAccessibleChildren.empty() )
749     {
750         sal_uInt32 nCount = ( GetRowCount() + 1 ) * GetColumnCount();
751         if ( m_aAccessibleChildren.size() < nCount )
752             m_aAccessibleChildren.resize( nCount );
753         else
754         {
755             DBG_ASSERT( m_aAccessibleChildren.size() == nCount, "wrong children count" );
756         }
757     }
758 }
759 
760 // -----------------------------------------------------------------------
761 
762 sal_Bool SvHeaderTabListBox::IsCellCheckBox( long _nRow, sal_uInt16 _nColumn, TriState& _rState )
763 {
764     sal_Bool bRet = sal_False;
765     SvLBoxEntry* pEntry = GetEntry( _nRow );
766     if ( pEntry )
767     {
768         sal_uInt16 nItemCount = pEntry->ItemCount();
769         if ( nItemCount > ( _nColumn + 1 ) )
770         {
771             SvLBoxButton* pItem = (SvLBoxButton*)( pEntry->GetItem( _nColumn + 1 ) );
772             if ( pItem && ( (SvLBoxItem*)pItem )->IsA() == SV_ITEM_ID_LBOXBUTTON )
773             {
774                 bRet = sal_True;
775                 _rState = ( ( pItem->GetButtonFlags() & SV_ITEMSTATE_UNCHECKED ) == 0 )
776                             ? STATE_CHECK : STATE_NOCHECK;
777             }
778         }
779         else
780         {
781             DBG_ERRORFILE( "SvHeaderTabListBox::IsCellCheckBox(): column out of range" );
782         }
783     }
784     return bRet;
785 }
786 
787 // -----------------------------------------------------------------------
788 long SvHeaderTabListBox::GetRowCount() const
789 {
790     return GetEntryCount();
791 }
792 // -----------------------------------------------------------------------
793 sal_uInt16 SvHeaderTabListBox::GetColumnCount() const
794 {
795 	return m_pImpl->m_pHeaderBar->GetItemCount();
796 }
797 // -----------------------------------------------------------------------
798 sal_Int32 SvHeaderTabListBox::GetCurrRow() const
799 {
800 	sal_Int32 nRet = -1;
801 	SvLBoxEntry* pEntry = GetCurEntry();
802 	if ( pEntry )
803 	{
804 		sal_uLong nCount = GetEntryCount();
805 		for ( sal_uLong i = 0; i < nCount; ++i )
806 		{
807 			if ( pEntry == GetEntry(i) )
808 			{
809 				nRet = i;
810 				break;
811 			}
812 		}
813 	}
814 
815 	return nRet;
816 }
817 // -----------------------------------------------------------------------
818 sal_uInt16 SvHeaderTabListBox::GetCurrColumn() const
819 {
820 	sal_uInt16 nPos = GetCurrentTabPos() - 1;
821 	return nPos;
822 }
823 // -----------------------------------------------------------------------
824 ::rtl::OUString SvHeaderTabListBox::GetRowDescription( sal_Int32 _nRow ) const
825 {
826 	return ::rtl::OUString( GetEntryText( _nRow ) );
827 }
828 // -----------------------------------------------------------------------
829 ::rtl::OUString SvHeaderTabListBox::GetColumnDescription( sal_uInt16 _nColumn ) const
830 {
831 	return ::rtl::OUString( m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( _nColumn ) ) );
832 }
833 // -----------------------------------------------------------------------
834 sal_Bool SvHeaderTabListBox::HasRowHeader() const
835 {
836 	return sal_False;
837 }
838 // -----------------------------------------------------------------------
839 sal_Bool SvHeaderTabListBox::IsCellFocusable() const
840 {
841 	return IsCellFocusEnabled();
842 }
843 // -----------------------------------------------------------------------
844 sal_Bool SvHeaderTabListBox::GoToCell( sal_Int32 _nRow, sal_uInt16 _nColumn )
845 {
846 	sal_Bool bRet = ( IsCellFocusEnabled() == sal_True );
847 	if ( bRet )
848 	{
849 		// first set cursor to _nRow
850 		SetCursor( GetEntry( _nRow ), sal_True );
851 		// then set the focus into _nColumn
852 		bRet = ( SetCurrentTabPos( _nColumn ) == true );
853 	}
854 	return bRet;
855 }
856 // -----------------------------------------------------------------------
857 void SvHeaderTabListBox::SetNoSelection()
858 {
859 	SvLBox::SelectAll( sal_False );
860 }
861 // -----------------------------------------------------------------------
862 void SvHeaderTabListBox::SelectAll()
863 {
864 	SvLBox::SelectAll( sal_True );
865 }
866 // -----------------------------------------------------------------------
867 void SvHeaderTabListBox::SelectAll( sal_Bool bSelect, sal_Bool bPaint )
868 {
869 	// overwritten just to disambiguate the SelectAll() from the base' class SelectAll( BOOl, sal_Bool )
870 	SvTabListBox::SelectAll( bSelect, bPaint );
871 }
872 
873 // -----------------------------------------------------------------------
874 void SvHeaderTabListBox::SelectRow( long _nRow, sal_Bool _bSelect, sal_Bool )
875 {
876 	Select( GetEntry( _nRow ), _bSelect );
877 }
878 // -----------------------------------------------------------------------
879 void SvHeaderTabListBox::SelectColumn( sal_uInt16, sal_Bool )
880 {
881 }
882 // -----------------------------------------------------------------------
883 sal_Int32 SvHeaderTabListBox::GetSelectedRowCount() const
884 {
885 	return GetSelectionCount();
886 }
887 // -----------------------------------------------------------------------
888 sal_Int32 SvHeaderTabListBox::GetSelectedColumnCount() const
889 {
890 	return 0;
891 }
892 // -----------------------------------------------------------------------
893 bool SvHeaderTabListBox::IsRowSelected( long _nRow ) const
894 {
895 	SvLBoxEntry* pEntry = GetEntry( _nRow );
896 	return ( pEntry && IsSelected( pEntry ) );
897 }
898 // -----------------------------------------------------------------------
899 sal_Bool SvHeaderTabListBox::IsColumnSelected( long ) const
900 {
901 	return sal_False;
902 }
903 // -----------------------------------------------------------------------
904 void SvHeaderTabListBox::GetAllSelectedRows( ::com::sun::star::uno::Sequence< sal_Int32 >& ) const
905 {
906 }
907 // -----------------------------------------------------------------------
908 void SvHeaderTabListBox::GetAllSelectedColumns( ::com::sun::star::uno::Sequence< sal_Int32 >& ) const
909 {
910 }
911 // -----------------------------------------------------------------------
912 sal_Bool SvHeaderTabListBox::IsCellVisible( sal_Int32, sal_uInt16 ) const
913 {
914 	return sal_True;
915 }
916 // -----------------------------------------------------------------------
917 String SvHeaderTabListBox::GetAccessibleCellText( long _nRow, sal_uInt16 _nColumnPos ) const
918 {
919 	return ::rtl::OUString( GetTabEntryText( _nRow, _nColumnPos ) );
920 }
921 // -----------------------------------------------------------------------
922 Rectangle SvHeaderTabListBox::calcHeaderRect( sal_Bool _bIsColumnBar, sal_Bool _bOnScreen )
923 {
924 	Rectangle aRect;
925 	if ( _bIsColumnBar )
926 	{
927 		Window* pParent = NULL;
928 		if ( !_bOnScreen )
929 			pParent = m_pImpl->m_pHeaderBar->GetAccessibleParentWindow();
930 
931 		aRect = m_pImpl->m_pHeaderBar->GetWindowExtentsRelative( pParent );
932 	}
933 	return aRect;
934 }
935 // -----------------------------------------------------------------------
936 Rectangle SvHeaderTabListBox::calcTableRect( sal_Bool _bOnScreen )
937 {
938 	Window* pParent = NULL;
939 	if ( !_bOnScreen )
940 		pParent = GetAccessibleParentWindow();
941 
942 	Rectangle aRect( GetWindowExtentsRelative( pParent ) );
943 	return aRect;
944 }
945 // -----------------------------------------------------------------------
946 Rectangle SvHeaderTabListBox::GetFieldRectPixelAbs( sal_Int32 _nRow, sal_uInt16 _nColumn, sal_Bool _bIsHeader, sal_Bool _bOnScreen )
947 {
948 	DBG_ASSERT( !_bIsHeader || 0 == _nRow, "invalid parameters" );
949 	Rectangle aRect;
950 	SvLBoxEntry* pEntry = GetEntry( _nRow );
951 	if ( pEntry )
952 	{
953 		aRect = _bIsHeader ? calcHeaderRect( sal_True, sal_False ) : GetBoundingRect( pEntry );
954 		Point aTopLeft = aRect.TopLeft();
955 		DBG_ASSERT( m_pImpl->m_pHeaderBar->GetItemCount() > _nColumn, "invalid column" );
956 		Rectangle aItemRect = m_pImpl->m_pHeaderBar->GetItemRect( m_pImpl->m_pHeaderBar->GetItemId( _nColumn ) );
957 		aTopLeft.X() = aItemRect.Left();
958 		Size aSize = aItemRect.GetSize();
959 		aRect = Rectangle( aTopLeft, aSize );
960 		Window* pParent = NULL;
961 		if ( !_bOnScreen )
962 			pParent = GetAccessibleParentWindow();
963 		aTopLeft = aRect.TopLeft();
964 		aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
965 		aRect = Rectangle( aTopLeft, aRect.GetSize() );
966 	}
967 
968 	return aRect;
969 }
970 // -----------------------------------------------------------------------
971 Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
972 {
973 	OSL_ENSURE( m_pAccessible, "Invalid call: Accessible is null" );
974 
975     Reference< XAccessible > xChild;
976     sal_Int32 nIndex = -1;
977 
978     if ( !AreChildrenTransient() )
979     {
980         const sal_uInt16 nColumnCount = GetColumnCount();
981 
982         // first call? -> initial list
983         if ( m_aAccessibleChildren.empty() )
984         {
985             sal_Int32 nCount = ( GetRowCount() + 1 ) * nColumnCount;
986             m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() );
987         }
988 
989         nIndex = ( _nRow * nColumnCount ) + _nColumnPos + nColumnCount;
990         xChild = m_aAccessibleChildren[ nIndex ];
991     }
992 
993     if ( !xChild.is() )
994     {
995         TriState eState = STATE_DONTKNOW;
996         sal_Bool bIsCheckBox = IsCellCheckBox( _nRow, _nColumnPos, eState );
997         if ( bIsCheckBox )
998             xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleCheckBoxCell(
999                 m_pAccessible->getAccessibleChild( 0 ), *this, NULL, _nRow, _nColumnPos, eState, sal_True, sal_False );
1000         else
1001             xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxTableCell(
1002                 m_pAccessible->getAccessibleChild( 0 ), *this, NULL, _nRow, _nColumnPos, OFFSET_NONE );
1003 
1004         // insert into list
1005         if ( !AreChildrenTransient() )
1006             m_aAccessibleChildren[ nIndex ] = xChild;
1007     }
1008 
1009     return xChild;
1010 }
1011 // -----------------------------------------------------------------------
1012 Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleRowHeader( sal_Int32 )
1013 {
1014 	Reference< XAccessible > xHeader;
1015 	return xHeader;
1016 }
1017 // -----------------------------------------------------------------------
1018 Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleColumnHeader( sal_uInt16 _nColumn )
1019 {
1020 	// first call? -> initial list
1021 	if ( m_aAccessibleChildren.empty() )
1022     {
1023         const sal_uInt16 nColumnCount = GetColumnCount();
1024         sal_Int32 nCount = AreChildrenTransient() ?
1025                 nColumnCount : ( GetRowCount() + 1 ) * nColumnCount;
1026         m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() );
1027     }
1028 
1029 	// get header
1030 	Reference< XAccessible > xChild = m_aAccessibleChildren[ _nColumn ];
1031 	// already exists?
1032     if ( !xChild.is() && m_pAccessible )
1033 	{
1034 		// no -> create new header cell
1035         xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxHeaderCell(
1036 			_nColumn, m_pAccessible->getHeaderBar( ::svt::BBTYPE_COLUMNHEADERBAR ),
1037 			*this, NULL, ::svt::BBTYPE_COLUMNHEADERCELL
1038         );
1039 
1040 		// insert into list
1041 		m_aAccessibleChildren[ _nColumn ] = xChild;
1042 	}
1043 
1044     return xChild;
1045 }
1046 // -----------------------------------------------------------------------
1047 sal_Int32 SvHeaderTabListBox::GetAccessibleControlCount() const
1048 {
1049 	return -1;
1050 }
1051 // -----------------------------------------------------------------------
1052 Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleControl( sal_Int32 )
1053 {
1054 	Reference< XAccessible > xControl;
1055 	return xControl;
1056 }
1057 // -----------------------------------------------------------------------
1058 sal_Bool SvHeaderTabListBox::ConvertPointToControlIndex( sal_Int32&, const Point& )
1059 {
1060 	return sal_False;
1061 }
1062 // -----------------------------------------------------------------------
1063 sal_Bool SvHeaderTabListBox::ConvertPointToCellAddress( sal_Int32&, sal_uInt16&, const Point& )
1064 {
1065 	return sal_False;
1066 }
1067 // -----------------------------------------------------------------------
1068 sal_Bool SvHeaderTabListBox::ConvertPointToRowHeader( sal_Int32&, const Point& )
1069 {
1070 	return sal_False;
1071 }
1072 // -----------------------------------------------------------------------
1073 sal_Bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Point& )
1074 {
1075 	return sal_False;
1076 }
1077 // -----------------------------------------------------------------------
1078 ::rtl::OUString SvHeaderTabListBox::GetAccessibleObjectName( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
1079 {
1080     ::rtl::OUString aRetText;
1081     switch( _eType )
1082     {
1083         case ::svt::BBTYPE_BROWSEBOX:
1084         case ::svt::BBTYPE_TABLE:
1085         case ::svt::BBTYPE_COLUMNHEADERBAR:
1086             // should be empty now (see #i63983)
1087             aRetText = ::rtl::OUString();
1088 			break;
1089 
1090 		case ::svt::BBTYPE_TABLECELL:
1091 		{
1092 			// here we need a valid pos, we can not handle -1
1093 			if ( _nPos >= 0 )
1094 			{
1095 				sal_uInt16 nColumnCount = GetColumnCount();
1096                 if (nColumnCount > 0)
1097                 {
1098 				    sal_Int32 nRow = _nPos / nColumnCount;
1099 				    sal_uInt16 nColumn  = static_cast< sal_uInt16 >( _nPos % nColumnCount );
1100                     aRetText = GetCellText( nRow, nColumn );
1101                 }
1102 			}
1103 			break;
1104 		}
1105         case ::svt::BBTYPE_CHECKBOXCELL:
1106         {
1107             break; // checkbox cells have no name
1108         }
1109         case ::svt::BBTYPE_COLUMNHEADERCELL:
1110 		{
1111 			aRetText = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( (sal_uInt16)_nPos ) );
1112 			break;
1113 		}
1114 
1115         case ::svt::BBTYPE_ROWHEADERBAR:
1116 		case ::svt::BBTYPE_ROWHEADERCELL:
1117 			aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "error" ) );
1118 			break;
1119 
1120 		default:
1121 			OSL_ENSURE(0,"BrowseBox::GetAccessibleName: invalid enum!");
1122     }
1123     return aRetText;
1124 }
1125 // -----------------------------------------------------------------------
1126 ::rtl::OUString SvHeaderTabListBox::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
1127 {
1128     ::rtl::OUString aRetText;
1129 
1130 	if( _eType == ::svt::BBTYPE_TABLECELL && _nPos != -1 )
1131     {
1132         static const String sVar1( RTL_CONSTASCII_USTRINGPARAM( "%1" ) );
1133         static const String sVar2( RTL_CONSTASCII_USTRINGPARAM( "%2" ) );
1134 
1135         sal_uInt16 nColumnCount = GetColumnCount();
1136         if (nColumnCount > 0)
1137         {
1138             sal_Int32 nRow = _nPos / nColumnCount;
1139             sal_uInt16 nColumn  = static_cast< sal_uInt16 >( _nPos % nColumnCount );
1140 
1141             String aText( SvtResId( STR_SVT_ACC_DESC_TABLISTBOX ) );
1142             aText.SearchAndReplace( sVar1, String::CreateFromInt32( nRow ) );
1143             String sColHeader = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( nColumn ) );
1144             if ( sColHeader.Len() == 0 )
1145                 sColHeader = String::CreateFromInt32( nColumn );
1146             aText.SearchAndReplace( sVar2, sColHeader );
1147             aRetText = aText;
1148         }
1149     }
1150 
1151 	return aRetText;
1152 }
1153 // -----------------------------------------------------------------------
1154 void SvHeaderTabListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& _rStateSet, ::svt::AccessibleBrowseBoxObjType _eType ) const
1155 {
1156 	switch( _eType )
1157     {
1158         case ::svt::BBTYPE_BROWSEBOX:
1159 		case ::svt::BBTYPE_TABLE:
1160 		{
1161 			_rStateSet.AddState( AccessibleStateType::FOCUSABLE );
1162 			if ( HasFocus() )
1163 				_rStateSet.AddState( AccessibleStateType::FOCUSED );
1164 			if ( IsActive() )
1165 				_rStateSet.AddState( AccessibleStateType::ACTIVE );
1166 			if ( IsEnabled() )
1167             {
1168 				_rStateSet.AddState( AccessibleStateType::ENABLED );
1169                 _rStateSet.AddState( AccessibleStateType::SENSITIVE );
1170             }
1171 			if ( IsReallyVisible() )
1172 				_rStateSet.AddState( AccessibleStateType::VISIBLE );
1173 			if ( _eType == ::svt::BBTYPE_TABLE )
1174 			{
1175 
1176                 if ( AreChildrenTransient() )
1177                     _rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
1178 				_rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
1179 			}
1180 			break;
1181 		}
1182 
1183         case ::svt::BBTYPE_COLUMNHEADERBAR:
1184 		{
1185 			sal_Int32 nCurRow = GetCurrRow();
1186 			sal_uInt16 nCurColumn = GetCurrColumn();
1187 			if ( IsCellVisible( nCurRow, nCurColumn ) )
1188 				_rStateSet.AddState( AccessibleStateType::VISIBLE );
1189 			_rStateSet.AddState( AccessibleStateType::TRANSIENT );
1190 			break;
1191 		}
1192 
1193 		case ::svt::BBTYPE_ROWHEADERCELL:
1194 		case ::svt::BBTYPE_COLUMNHEADERCELL:
1195 		{
1196 			_rStateSet.AddState( AccessibleStateType::VISIBLE );
1197 			_rStateSet.AddState( AccessibleStateType::FOCUSABLE );
1198 			_rStateSet.AddState( AccessibleStateType::TRANSIENT );
1199 			break;
1200 		}
1201         default:
1202             break;
1203     }
1204 }
1205 // -----------------------------------------------------------------------
1206 void SvHeaderTabListBox::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumn ) const
1207 {
1208 	_rStateSet.AddState( AccessibleStateType::SELECTABLE );
1209     if ( AreChildrenTransient() )
1210         _rStateSet.AddState( AccessibleStateType::TRANSIENT );
1211 
1212 	if ( IsCellVisible( _nRow, _nColumn ) )
1213     {
1214         _rStateSet.AddState( AccessibleStateType::VISIBLE );
1215         _rStateSet.AddState( AccessibleStateType::ENABLED );
1216     }
1217 
1218     if ( IsRowSelected( _nRow ) )
1219 	{
1220 		_rStateSet.AddState( AccessibleStateType::ACTIVE );
1221 		_rStateSet.AddState( AccessibleStateType::SELECTED );
1222 	}
1223 }
1224 // -----------------------------------------------------------------------
1225 void SvHeaderTabListBox::GrabTableFocus()
1226 {
1227 	GrabFocus();
1228 }
1229 // -----------------------------------------------------------------------
1230 sal_Bool SvHeaderTabListBox::GetGlyphBoundRects( const Point& rOrigin, const String& rStr, int nIndex, int nLen, int nBase, MetricVector& rVector )
1231 {
1232 	return Control::GetGlyphBoundRects( rOrigin, rStr, nIndex, nLen, nBase, rVector );
1233 }
1234 // -----------------------------------------------------------------------
1235 Rectangle SvHeaderTabListBox::GetWindowExtentsRelative( Window *pRelativeWindow ) const
1236 {
1237 	return Control::GetWindowExtentsRelative( pRelativeWindow );
1238 }
1239 // -----------------------------------------------------------------------
1240 void SvHeaderTabListBox::GrabFocus()
1241 {
1242 	Control::GrabFocus();
1243 }
1244 // -----------------------------------------------------------------------
1245 Reference< XAccessible > SvHeaderTabListBox::GetAccessible( sal_Bool bCreate )
1246 {
1247 	return Control::GetAccessible( bCreate );
1248 }
1249 // -----------------------------------------------------------------------
1250 Window* SvHeaderTabListBox::GetAccessibleParentWindow() const
1251 {
1252 	return Control::GetAccessibleParentWindow();
1253 }
1254 // -----------------------------------------------------------------------
1255 Window* SvHeaderTabListBox::GetWindowInstance()
1256 {
1257 	return this;
1258 }
1259 // -----------------------------------------------------------------------
1260 Reference< XAccessible > SvHeaderTabListBox::CreateAccessible()
1261 {
1262     Window* pParent = GetAccessibleParentWindow();
1263     DBG_ASSERT( pParent, "SvHeaderTabListBox::::CreateAccessible - accessible parent not found" );
1264 
1265 	Reference< XAccessible > xAccessible;
1266     if ( m_pAccessible ) xAccessible = m_pAccessible->getMyself();
1267 
1268     if( pParent && !m_pAccessible )
1269     {
1270 	    Reference< XAccessible > xAccParent = pParent->GetAccessible();
1271 	    if ( xAccParent.is() )
1272 		{
1273             m_pAccessible = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleTabListBox( xAccParent, *this );
1274             if ( m_pAccessible )
1275 			    xAccessible = m_pAccessible->getMyself();
1276 		}
1277 	}
1278 	return xAccessible;
1279 }
1280 // -----------------------------------------------------------------------------
1281 Rectangle SvHeaderTabListBox::GetFieldCharacterBounds(sal_Int32,sal_Int32,sal_Int32)
1282 {
1283 	Rectangle aRect;
1284 	return aRect;
1285 }
1286 // -----------------------------------------------------------------------------
1287 sal_Int32 SvHeaderTabListBox::GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)
1288 {
1289 	String sText = GetAccessibleCellText( _nRow, static_cast< sal_uInt16 >( _nColumnPos ) );
1290 	MetricVector aRects;
1291 	if ( GetGlyphBoundRects(Point(0,0),sText,0,STRING_LEN,0,aRects) )
1292 	{
1293 		for (MetricVector::iterator aIter = aRects.begin(); aIter != aRects.end(); ++aIter)
1294 		{
1295 			if( aIter->IsInside(_rPoint) )
1296 				return aIter - aRects.begin();
1297 		}
1298 	}
1299 
1300 	return -1;
1301 }
1302 // -----------------------------------------------------------------------------
1303 
1304 
1305