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