xref: /AOO41X/main/svtools/source/contnr/svtabbx.cxx (revision 4d7c9de063a797b8b4f3d45e3561e82ad1f8ef1f)
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