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