merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / contnr / svtabbx.cxx
blob3cfe607296a126a418c132f47544be0bb03e50ef
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svtabbx.cxx,v $
10 * $Revision: 1.30 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <svtools/svtabbx.hxx>
34 #include <svtools/headbar.hxx>
35 #include <svtools/svtdata.hxx>
36 #ifndef _SVTOOLS_HRC
37 #include <svtools/svtools.hrc>
38 #endif
39 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
40 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
41 #ifndef SVTOOLS_ACCESSIBLE_FACTORY_HXX
42 #include "svtaccessiblefactory.hxx"
43 #endif
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::accessibility;
48 #define MYTABMASK \
49 ( SV_LBOXTAB_ADJUST_RIGHT | SV_LBOXTAB_ADJUST_LEFT | SV_LBOXTAB_ADJUST_CENTER | SV_LBOXTAB_ADJUST_NUMERIC )
51 // SvTreeListBox-Callback
53 void SvTabListBox::SetTabs()
55 SvTreeListBox::SetTabs();
56 if( nTabCount )
58 DBG_ASSERT(pTabList,"TabList ?");
60 // die TreeListBox hat jetzt ihre Tabulatoren in die Liste eingefuegt.
61 // jetzt plustern wir die Liste mit zusaetzlichen Tabulatoren auf,
62 // und passen den ganz rechten Tab der Treelistbox an.
64 // den ganz rechten Tab nehmen
65 // HACK fuer den Explorer! Wenn der ViewParent != 0 ist, dann wird
66 // der erste Tab der TreeListBox von der TreelistBox berechnet!
67 // Dies wird fuer ButtonsOnRoot benoetigt, da der Explorer nicht
68 // weiss, welchen zusaetzlichen Offset er in diesem Modus auf
69 // den Tabulator addieren muss. Die TreeListBox weiss es!
71 if( !pViewParent )
73 SvLBoxTab* pFirstTab = (SvLBoxTab*)aTabs.GetObject( aTabs.Count()-1 );
74 pFirstTab->SetPos( pTabList[0].GetPos() );
75 pFirstTab->nFlags &= ~MYTABMASK;
76 pFirstTab->nFlags |= pTabList[0].nFlags;
80 // alle anderen Tabs an Liste haengen
81 for( USHORT nCurTab = 1; nCurTab < nTabCount; nCurTab++ )
83 SvLBoxTab* pTab = pTabList+nCurTab;
84 AddTab( pTab->GetPos(), pTab->nFlags );
89 void SvTabListBox::InitEntry( SvLBoxEntry* pEntry, const XubString& rStr,
90 const Image& rColl, const Image& rExp, SvLBoxButtonKind eButtonKind )
92 SvTreeListBox::InitEntry( pEntry, rStr, rColl, rExp, eButtonKind );
93 XubString aToken;
95 const xub_Unicode* pCurToken = aCurEntry.GetBuffer();
96 USHORT nCurTokenLen;
97 const xub_Unicode* pNextToken = GetToken( pCurToken, nCurTokenLen );
98 USHORT nCount = nTabCount; nCount--;
99 for( USHORT nToken = 0; nToken < nCount; nToken++ )
101 if( pCurToken && nCurTokenLen )
102 // aToken.Assign( pCurToken, nCurTokenLen );
103 aToken = XubString( pCurToken, nCurTokenLen );
104 else
105 aToken.Erase();
106 SvLBoxString* pStr = new SvLBoxString( pEntry, 0, aToken );
107 pEntry->AddItem( pStr );
108 pCurToken = pNextToken;
109 if( pCurToken )
110 pNextToken = GetToken( pCurToken, nCurTokenLen );
111 else
112 nCurTokenLen = 0;
117 SvTabListBox::SvTabListBox( Window* pParent, WinBits nBits )
118 : SvTreeListBox( pParent, nBits )
120 pTabList = 0;
121 nTabCount = 0;
122 pViewParent = 0;
123 SetHighlightRange(); // ueber volle Breite selektieren
126 SvTabListBox::SvTabListBox( Window* pParent, const ResId& rResId )
127 : SvTreeListBox( pParent, rResId )
129 pTabList = 0;
130 nTabCount = 0;
131 pViewParent = 0;
132 SvTabListBox::Resize();
133 SetHighlightRange();
136 SvTabListBox::~SvTabListBox()
138 // array-delete
139 delete [] pTabList;
140 #ifdef DBG_UTIL
141 pTabList = 0;
142 nTabCount = 0;
143 #endif
146 void SvTabListBox::SetTabs( long* pTabs, MapUnit eMapUnit )
148 DBG_ASSERT(pTabs,"SetTabs:NULL-Ptr");
149 if( !pTabs )
150 return;
152 delete [] pTabList;
153 USHORT nCount = (USHORT)(*pTabs);
154 pTabList = new SvLBoxTab[ nCount ];
155 nTabCount = nCount;
157 MapMode aMMSource( eMapUnit );
158 MapMode aMMDest( MAP_PIXEL );
160 pTabs++;
161 for( USHORT nIdx = 0; nIdx < nCount; nIdx++, pTabs++ )
163 Size aSize( *pTabs, 0 );
164 aSize = LogicToLogic( aSize, &aMMSource, &aMMDest );
165 long nNewTab = aSize.Width();
166 pTabList[nIdx].SetPos( nNewTab );
167 pTabList[nIdx].nFlags=(SV_LBOXTAB_ADJUST_LEFT| SV_LBOXTAB_INV_ALWAYS);
169 SvTreeListBox::nTreeFlags |= TREEFLAG_RECALCTABS;
170 if( IsUpdateMode() )
171 Invalidate();
174 void SvTabListBox::SetTab( USHORT nTab,long nValue,MapUnit eMapUnit )
176 DBG_ASSERT(nTab<nTabCount,"Invalid Tab-Pos");
177 if( nTab < nTabCount )
179 DBG_ASSERT(pTabList,"TabList?");
180 MapMode aMMSource( eMapUnit );
181 MapMode aMMDest( MAP_PIXEL );
182 Size aSize( nValue, 0 );
183 aSize = LogicToLogic( aSize, &aMMSource, &aMMDest );
184 nValue = aSize.Width();
185 pTabList[ nTab ].SetPos( nValue );
186 SvTreeListBox::nTreeFlags |= TREEFLAG_RECALCTABS;
187 if( IsUpdateMode() )
188 Invalidate();
192 SvLBoxEntry* SvTabListBox::InsertEntry( const XubString& rText, SvLBoxEntry* pParent,
193 BOOL /*bChildsOnDemand*/,
194 ULONG nPos, void* pUserData,
195 SvLBoxButtonKind )
197 return InsertEntryToColumn( rText, pParent, nPos, 0xffff, pUserData );
200 SvLBoxEntry* SvTabListBox::InsertEntry( const XubString& rText,
201 const Image& rExpandedEntryBmp,
202 const Image& rCollapsedEntryBmp,
203 SvLBoxEntry* pParent,
204 BOOL /*bChildsOnDemand*/,
205 ULONG nPos, void* pUserData,
206 SvLBoxButtonKind )
208 return InsertEntryToColumn( rText, rExpandedEntryBmp, rCollapsedEntryBmp,
209 pParent, nPos, 0xffff, pUserData );
212 SvLBoxEntry* SvTabListBox::InsertEntryToColumn(const XubString& rStr,SvLBoxEntry* pParent,ULONG nPos,USHORT nCol,
213 void* pUser )
215 XubString aStr;
216 if( nCol != 0xffff )
218 while( nCol )
220 aStr += '\t';
221 nCol--;
224 aStr += rStr;
225 XubString aFirstStr( aStr );
226 USHORT nEnd = aFirstStr.Search( '\t' );
227 if( nEnd != STRING_NOTFOUND )
229 aFirstStr.Erase( nEnd );
230 aCurEntry = aStr;
231 aCurEntry.Erase( 0, ++nEnd );
233 else
234 aCurEntry.Erase();
235 return SvTreeListBox::InsertEntry( aFirstStr, pParent, FALSE, nPos, pUser );
238 SvLBoxEntry* SvTabListBox::InsertEntryToColumn( const XubString& rStr,
239 const Image& rExpandedEntryBmp, const Image& rCollapsedEntryBmp,
240 SvLBoxEntry* pParent,ULONG nPos,USHORT nCol, void* pUser )
242 XubString aStr;
243 if( nCol != 0xffff )
245 while( nCol )
247 aStr += '\t';
248 nCol--;
251 aStr += rStr;
252 XubString aFirstStr( aStr );
253 USHORT nEnd = aFirstStr.Search( '\t' );
254 if( nEnd != STRING_NOTFOUND )
256 aFirstStr.Erase( nEnd );
257 aCurEntry = aStr;
258 aCurEntry.Erase( 0, ++nEnd );
260 else
261 aCurEntry.Erase();
263 return SvTreeListBox::InsertEntry(
264 aFirstStr,
265 rExpandedEntryBmp, rCollapsedEntryBmp,
266 pParent, FALSE, nPos, pUser );
269 SvLBoxEntry* SvTabListBox::InsertEntryToColumn( const XubString& rStr, ULONG nPos,
270 USHORT nCol, void* pUser )
272 return InsertEntryToColumn( rStr,0,nPos, nCol, pUser );
275 String SvTabListBox::GetEntryText( SvLBoxEntry* pEntry ) const
277 return GetEntryText( pEntry, 0xffff );
280 String SvTabListBox::GetEntryText( SvLBoxEntry* pEntry, USHORT nCol ) const
282 DBG_ASSERT(pEntry,"GetEntryText:Invalid Entry");
283 XubString aResult;
284 if( pEntry )
286 USHORT nCount = pEntry->ItemCount();
287 USHORT nCur = 0;
288 while( nCur < nCount )
290 SvLBoxItem* pStr = pEntry->GetItem( nCur );
291 if( pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
293 if( nCol == 0xffff )
295 if( aResult.Len() )
296 aResult += '\t';
297 aResult += static_cast<SvLBoxString*>( pStr )->GetText();
299 else
301 if( nCol == 0 )
302 return static_cast<SvLBoxString*>( pStr )->GetText();
303 nCol--;
306 nCur++;
309 return aResult;
312 String SvTabListBox::GetEntryText( ULONG nPos, USHORT nCol ) const
314 SvLBoxEntry* pEntry = GetEntryOnPos( nPos );
315 return GetEntryText( pEntry, nCol );
318 void SvTabListBox::SetEntryText( const XubString& rStr, ULONG nPos, USHORT nCol )
320 SvLBoxEntry* pEntry = SvTreeListBox::GetEntry( nPos );
321 SetEntryText( rStr, pEntry, nCol );
324 void SvTabListBox::SetEntryText( const XubString& rStr, SvLBoxEntry* pEntry, USHORT nCol )
326 DBG_ASSERT(pEntry,"SetEntryText:Invalid Entry");
327 if( !pEntry )
328 return;
330 String sOldText = GetEntryText( pEntry, nCol );
331 if ( sOldText == rStr )
332 return;
334 USHORT nTextColumn = nCol;
335 const xub_Unicode* pCurToken = rStr.GetBuffer();
336 USHORT nCurTokenLen;
337 const xub_Unicode* pNextToken = GetToken( pCurToken, nCurTokenLen );
339 XubString aTemp;
340 USHORT nCount = pEntry->ItemCount();
341 USHORT nCur = 0;
342 while( nCur < nCount )
344 SvLBoxItem* pStr = pEntry->GetItem( nCur );
345 if( pStr && pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
347 if( nCol == 0xffff )
349 if( pCurToken )
350 aTemp = XubString( pCurToken, nCurTokenLen );
351 else
352 aTemp.Erase(); // alle Spalten ohne Token loeschen
353 ((SvLBoxString*)pStr)->SetText( pEntry, aTemp );
354 pCurToken = pNextToken;
355 pNextToken = GetToken( pCurToken, nCurTokenLen );
357 else
359 if( !nCol )
361 aTemp = XubString( pCurToken, nCurTokenLen );
362 ((SvLBoxString*)pStr)->SetText( pEntry, aTemp );
363 if( !pNextToken )
364 break;
365 pCurToken = pNextToken;
366 pNextToken = GetToken( pCurToken, nCurTokenLen );
368 else
369 nCol--;
372 nCur++;
374 GetModel()->InvalidateEntry( pEntry );
376 TabListBoxEventData* pData = new TabListBoxEventData( pEntry, nTextColumn, sOldText );
377 ImplCallEventListeners( VCLEVENT_TABLECELL_NAMECHANGED, pData );
378 delete pData;
381 String SvTabListBox::GetCellText( ULONG nPos, USHORT nCol ) const
383 SvLBoxEntry* pEntry = GetEntryOnPos( nPos );
384 DBG_ASSERT( pEntry, "SvTabListBox::GetCellText(): Invalid Entry" );
385 XubString aResult;
386 if ( pEntry && pEntry->ItemCount() > ( nCol + 1 ) )
388 SvLBoxItem* pStr = pEntry->GetItem( nCol + 1 );
389 if ( pStr && pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
390 aResult = static_cast< SvLBoxString* >( pStr )->GetText();
392 return aResult;
395 ULONG SvTabListBox::GetEntryPos( const XubString& rStr, USHORT nCol )
397 ULONG nPos = 0;
398 SvLBoxEntry* pEntry = First();
399 while( pEntry )
401 XubString aStr( GetEntryText( pEntry, nCol ));
402 if( aStr == rStr )
403 return nPos;
404 pEntry = Next( pEntry );
405 nPos++;
407 return 0xffffffff;
410 ULONG SvTabListBox::GetEntryPos( const SvLBoxEntry* pEntry ) const
412 ULONG nPos = 0;
413 SvLBoxEntry* pTmpEntry = First();
414 while( pTmpEntry )
416 if ( pTmpEntry == pEntry )
417 return nPos;
418 pTmpEntry = Next( pTmpEntry );
419 ++nPos;
421 return 0xffffffff;
424 void __EXPORT SvTabListBox::Resize()
426 SvTreeListBox::Resize();
429 // static
430 const xub_Unicode* SvTabListBox::GetToken( const xub_Unicode* pPtr, USHORT& rLen )
432 if( !pPtr || *pPtr == 0 )
434 rLen = 0;
435 return 0;
437 xub_Unicode c = *pPtr;
438 USHORT nLen = 0;
439 while( c != '\t' && c != 0 )
441 pPtr++;
442 nLen++;
443 c = *pPtr;
445 if( c )
446 pPtr++; // Tab ueberspringen
447 else
448 pPtr = 0;
449 rLen = nLen;
450 return pPtr;
453 String SvTabListBox::GetTabEntryText( ULONG nPos, USHORT nCol ) const
455 SvLBoxEntry* pEntry = SvTreeListBox::GetEntry( nPos );
456 DBG_ASSERT( pEntry, "GetTabEntryText(): Invalid entry " );
457 XubString aResult;
458 if ( pEntry )
460 USHORT nCount = pEntry->ItemCount();
461 USHORT nCur = ( 0 == nCol && IsCellFocusEnabled() ) ? GetCurrentTabPos() : 0;
462 while( nCur < nCount )
464 SvLBoxItem* pStr = pEntry->GetItem( nCur );
465 if ( pStr->IsA() == SV_ITEM_ID_LBOXSTRING )
467 if ( nCol == 0xffff )
469 if ( aResult.Len() )
470 aResult += '\t';
471 aResult += static_cast<SvLBoxString*>( pStr )->GetText();
473 else
475 if ( nCol == 0 )
477 String sRet = static_cast<SvLBoxString*>( pStr )->GetText();
478 if ( sRet.Len() == 0 )
479 sRet = String( SvtResId( STR_SVT_ACC_EMPTY_FIELD ) );
480 return sRet;
482 --nCol;
485 ++nCur;
488 return aResult;
491 SvLBoxEntry* SvTabListBox::GetEntryOnPos( ULONG _nEntryPos ) const
493 SvLBoxEntry* pEntry = NULL;
494 ULONG i, nPos = 0, nCount = GetLevelChildCount( NULL );
495 for ( i = 0; i < nCount; ++i )
497 SvLBoxEntry* pParent = GetEntry(i);
498 if ( nPos == _nEntryPos )
500 pEntry = pParent;
501 break;
503 else
505 nPos++;
506 pEntry = GetChildOnPos( pParent, _nEntryPos, nPos );
507 if ( pEntry )
508 break;
512 return pEntry;
515 SvLBoxEntry* SvTabListBox::GetChildOnPos( SvLBoxEntry* _pParent, ULONG _nEntryPos, ULONG& _rPos ) const
517 ULONG i, nCount = GetLevelChildCount( _pParent );
518 for ( i = 0; i < nCount; ++i )
520 SvLBoxEntry* pParent = GetEntry( _pParent, i );
521 if ( _rPos == _nEntryPos )
522 return pParent;
523 else
525 _rPos++;
526 SvLBoxEntry* pEntry = GetChildOnPos( pParent, _nEntryPos, _rPos );
527 if ( pEntry )
528 return pEntry;
532 return NULL;
535 void SvTabListBox::SetTabJustify( USHORT nTab, SvTabJustify eJustify)
537 if( nTab >= nTabCount )
538 return;
539 SvLBoxTab* pTab = &(pTabList[ nTab ]);
540 USHORT nFlags = pTab->nFlags;
541 nFlags &= (~MYTABMASK);
542 nFlags |= (USHORT)eJustify;
543 pTab->nFlags = nFlags;
544 SvTreeListBox::nTreeFlags |= TREEFLAG_RECALCTABS;
545 if( IsUpdateMode() )
546 Invalidate();
549 SvTabJustify SvTabListBox::GetTabJustify( USHORT nTab ) const
551 SvTabJustify eResult = AdjustLeft;
552 if( nTab >= nTabCount )
553 return eResult;
554 SvLBoxTab* pTab = &(pTabList[ nTab ]);
555 USHORT nFlags = pTab->nFlags;
556 nFlags &= MYTABMASK;
557 eResult = (SvTabJustify)nFlags;
558 return eResult;
561 long SvTabListBox::GetLogicTab( USHORT nTab )
563 if( SvTreeListBox::nTreeFlags & TREEFLAG_RECALCTABS )
564 ((SvTabListBox*)this)->SetTabs();
566 DBG_ASSERT(nTab<nTabCount,"GetTabPos:Invalid Tab");
567 return ((SvLBoxTab*)aTabs.GetObject( nTab ))->GetPos();
570 // class SvHeaderTabListBoxImpl ------------------------------------------
572 namespace svt
574 struct SvHeaderTabListBoxImpl
576 HeaderBar* m_pHeaderBar;
577 AccessibleFactoryAccess m_aFactoryAccess;
579 SvHeaderTabListBoxImpl() : m_pHeaderBar( NULL ) { }
583 // class SvHeaderTabListBox ----------------------------------------------
585 SvHeaderTabListBox::SvHeaderTabListBox( Window* pParent, WinBits nWinStyle ) :
587 SvTabListBox( pParent, nWinStyle ),
589 m_bFirstPaint ( TRUE ),
590 m_pImpl ( new ::svt::SvHeaderTabListBoxImpl ),
591 m_pAccessible ( NULL )
595 // -----------------------------------------------------------------------
597 SvHeaderTabListBox::SvHeaderTabListBox( Window* pParent, const ResId& rResId ) :
599 SvTabListBox( pParent, rResId ),
601 m_bFirstPaint ( TRUE ),
602 m_pImpl ( new ::svt::SvHeaderTabListBoxImpl ),
603 m_pAccessible ( NULL )
607 // -----------------------------------------------------------------------
609 SvHeaderTabListBox::~SvHeaderTabListBox()
611 delete m_pImpl;
614 // -----------------------------------------------------------------------
616 void SvHeaderTabListBox::Paint( const Rectangle& rRect )
618 if ( m_bFirstPaint )
620 m_bFirstPaint = FALSE;
621 RepaintScrollBars();
623 SvTabListBox::Paint( rRect );
626 // -----------------------------------------------------------------------
628 void SvHeaderTabListBox::InitHeaderBar( HeaderBar* pHeaderBar )
630 DBG_ASSERT( !m_pImpl->m_pHeaderBar, "header bar already initialized" );
631 DBG_ASSERT( pHeaderBar, "invalid header bar initialization" );
632 m_pImpl->m_pHeaderBar = pHeaderBar;
633 SetScrolledHdl( LINK( this, SvHeaderTabListBox, ScrollHdl_Impl ) );
634 m_pImpl->m_pHeaderBar->SetCreateAccessibleHdl( LINK( this, SvHeaderTabListBox, CreateAccessibleHdl_Impl ) );
637 // -----------------------------------------------------------------------
639 sal_Bool SvHeaderTabListBox::IsItemChecked( SvLBoxEntry* pEntry, USHORT nCol ) const
641 SvButtonState eState = SV_BUTTON_UNCHECKED;
642 SvLBoxButton* pItem = (SvLBoxButton*)( pEntry->GetItem( nCol + 1 ) );
644 if ( pItem && ( (SvLBoxItem*)pItem )->IsA() == SV_ITEM_ID_LBOXBUTTON )
646 USHORT nButtonFlags = pItem->GetButtonFlags();
647 eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
650 return ( eState == SV_BUTTON_CHECKED );
653 // -----------------------------------------------------------------------
655 SvLBoxEntry* SvHeaderTabListBox::InsertEntryToColumn(
656 const XubString& rStr, ULONG nPos, USHORT nCol, void* pUserData )
658 SvLBoxEntry* pEntry = SvTabListBox::InsertEntryToColumn( rStr, nPos, nCol, pUserData );
659 RecalculateAccessibleChildren();
660 return pEntry;
663 // -----------------------------------------------------------------------
665 SvLBoxEntry* SvHeaderTabListBox::InsertEntryToColumn(
666 const XubString& rStr, SvLBoxEntry* pParent, ULONG nPos, USHORT nCol, void* pUserData )
668 SvLBoxEntry* pEntry = SvTabListBox::InsertEntryToColumn( rStr, pParent, nPos, nCol, pUserData );
669 RecalculateAccessibleChildren();
670 return pEntry;
673 // -----------------------------------------------------------------------
675 SvLBoxEntry* SvHeaderTabListBox::InsertEntryToColumn(
676 const XubString& rStr, const Image& rExpandedEntryBmp, const Image& rCollapsedEntryBmp,
677 SvLBoxEntry* pParent, ULONG nPos, USHORT nCol, void* pUserData )
679 SvLBoxEntry* pEntry = SvTabListBox::InsertEntryToColumn(
680 rStr, rExpandedEntryBmp, rCollapsedEntryBmp, pParent, nPos, nCol, pUserData );
681 RecalculateAccessibleChildren();
682 return pEntry;
685 // -----------------------------------------------------------------------
687 ULONG SvHeaderTabListBox::Insert(
688 SvLBoxEntry* pEnt, SvLBoxEntry* pPar, ULONG nPos )
690 ULONG n = SvTabListBox::Insert( pEnt, pPar, nPos );
691 RecalculateAccessibleChildren();
692 return n;
695 // -----------------------------------------------------------------------
697 ULONG SvHeaderTabListBox::Insert( SvLBoxEntry* pEntry, ULONG nRootPos )
699 ULONG nPos = SvTabListBox::Insert( pEntry, nRootPos );
700 RecalculateAccessibleChildren();
701 return nPos;
704 // -----------------------------------------------------------------------
706 void SvHeaderTabListBox::RemoveEntry( SvLBoxEntry* _pEntry )
708 GetModel()->Remove( _pEntry );
709 m_aAccessibleChildren.clear();
712 // -----------------------------------------------------------------------
714 void SvHeaderTabListBox::Clear()
716 SvTabListBox::Clear();
717 m_aAccessibleChildren.clear();
720 // -----------------------------------------------------------------------
722 IMPL_LINK( SvHeaderTabListBox, ScrollHdl_Impl, SvTabListBox*, EMPTYARG )
724 m_pImpl->m_pHeaderBar->SetOffset( -GetXOffset() );
725 return 0;
728 // -----------------------------------------------------------------------
730 IMPL_LINK( SvHeaderTabListBox, CreateAccessibleHdl_Impl, HeaderBar*, EMPTYARG )
732 Window* pParent = m_pImpl->m_pHeaderBar->GetAccessibleParentWindow();
733 DBG_ASSERT( pParent, "SvHeaderTabListBox..CreateAccessibleHdl_Impl - accessible parent not found" );
734 if ( pParent )
736 ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
737 if ( xAccParent.is() )
739 Reference< XAccessible > xAccessible = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxHeaderBar(
740 xAccParent, *this, ::svt::BBTYPE_COLUMNHEADERBAR );
741 m_pImpl->m_pHeaderBar->SetAccessible( xAccessible );
744 return 0;
747 // -----------------------------------------------------------------------
749 void SvHeaderTabListBox::RecalculateAccessibleChildren()
751 if ( !m_aAccessibleChildren.empty() )
753 sal_uInt32 nCount = ( GetRowCount() + 1 ) * GetColumnCount();
754 if ( m_aAccessibleChildren.size() < nCount )
755 m_aAccessibleChildren.resize( nCount );
756 else
758 DBG_ASSERT( m_aAccessibleChildren.size() == nCount, "wrong children count" );
763 // -----------------------------------------------------------------------
765 sal_Bool SvHeaderTabListBox::IsCellCheckBox( long _nRow, sal_uInt16 _nColumn, TriState& _rState )
767 sal_Bool bRet = sal_False;
768 SvLBoxEntry* pEntry = GetEntry( _nRow );
769 if ( pEntry )
771 USHORT nItemCount = pEntry->ItemCount();
772 if ( nItemCount > ( _nColumn + 1 ) )
774 SvLBoxButton* pItem = (SvLBoxButton*)( pEntry->GetItem( _nColumn + 1 ) );
775 if ( pItem && ( (SvLBoxItem*)pItem )->IsA() == SV_ITEM_ID_LBOXBUTTON )
777 bRet = sal_True;
778 _rState = ( ( pItem->GetButtonFlags() & SV_ITEMSTATE_UNCHECKED ) == 0 )
779 ? STATE_CHECK : STATE_NOCHECK;
782 else
784 DBG_ERRORFILE( "SvHeaderTabListBox::IsCellCheckBox(): column out of range" );
787 return bRet;
790 // -----------------------------------------------------------------------
791 long SvHeaderTabListBox::GetRowCount() const
793 return GetEntryCount();
795 // -----------------------------------------------------------------------
796 sal_uInt16 SvHeaderTabListBox::GetColumnCount() const
798 return m_pImpl->m_pHeaderBar->GetItemCount();
800 // -----------------------------------------------------------------------
801 sal_Int32 SvHeaderTabListBox::GetCurrRow() const
803 sal_Int32 nRet = -1;
804 SvLBoxEntry* pEntry = GetCurEntry();
805 if ( pEntry )
807 ULONG nCount = GetEntryCount();
808 for ( ULONG i = 0; i < nCount; ++i )
810 if ( pEntry == GetEntry(i) )
812 nRet = i;
813 break;
818 return nRet;
820 // -----------------------------------------------------------------------
821 sal_uInt16 SvHeaderTabListBox::GetCurrColumn() const
823 sal_uInt16 nPos = GetCurrentTabPos() - 1;
824 return nPos;
826 // -----------------------------------------------------------------------
827 ::rtl::OUString SvHeaderTabListBox::GetRowDescription( sal_Int32 _nRow ) const
829 return ::rtl::OUString( GetEntryText( _nRow ) );
831 // -----------------------------------------------------------------------
832 ::rtl::OUString SvHeaderTabListBox::GetColumnDescription( sal_uInt16 _nColumn ) const
834 return ::rtl::OUString( m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( _nColumn ) ) );
836 // -----------------------------------------------------------------------
837 sal_Bool SvHeaderTabListBox::HasRowHeader() const
839 return sal_False;
841 // -----------------------------------------------------------------------
842 sal_Bool SvHeaderTabListBox::IsCellFocusable() const
844 return IsCellFocusEnabled();
846 // -----------------------------------------------------------------------
847 sal_Bool SvHeaderTabListBox::GoToCell( sal_Int32 _nRow, sal_uInt16 _nColumn )
849 sal_Bool bRet = ( IsCellFocusEnabled() == TRUE );
850 if ( bRet )
852 // first set cursor to _nRow
853 SetCursor( GetEntry( _nRow ), TRUE );
854 // then set the focus into _nColumn
855 bRet = ( SetCurrentTabPos( _nColumn ) == true );
857 return bRet;
859 // -----------------------------------------------------------------------
860 void SvHeaderTabListBox::SetNoSelection()
862 SvLBox::SelectAll( FALSE );
864 // -----------------------------------------------------------------------
865 void SvHeaderTabListBox::SelectAll()
867 SvLBox::SelectAll( TRUE );
869 // -----------------------------------------------------------------------
870 void SvHeaderTabListBox::SelectAll( BOOL bSelect, BOOL bPaint )
872 // overwritten just to disambiguate the SelectAll() from the base' class SelectAll( BOOl, BOOL )
873 SvTabListBox::SelectAll( bSelect, bPaint );
876 // -----------------------------------------------------------------------
877 void SvHeaderTabListBox::SelectRow( long _nRow, BOOL _bSelect, BOOL )
879 Select( GetEntry( _nRow ), _bSelect );
881 // -----------------------------------------------------------------------
882 void SvHeaderTabListBox::SelectColumn( sal_uInt16, sal_Bool )
885 // -----------------------------------------------------------------------
886 sal_Int32 SvHeaderTabListBox::GetSelectedRowCount() const
888 return GetSelectionCount();
890 // -----------------------------------------------------------------------
891 sal_Int32 SvHeaderTabListBox::GetSelectedColumnCount() const
893 return 0;
895 // -----------------------------------------------------------------------
896 bool SvHeaderTabListBox::IsRowSelected( long _nRow ) const
898 SvLBoxEntry* pEntry = GetEntry( _nRow );
899 return ( pEntry && IsSelected( pEntry ) );
901 // -----------------------------------------------------------------------
902 sal_Bool SvHeaderTabListBox::IsColumnSelected( long ) const
904 return FALSE;
906 // -----------------------------------------------------------------------
907 void SvHeaderTabListBox::GetAllSelectedRows( ::com::sun::star::uno::Sequence< sal_Int32 >& ) const
910 // -----------------------------------------------------------------------
911 void SvHeaderTabListBox::GetAllSelectedColumns( ::com::sun::star::uno::Sequence< sal_Int32 >& ) const
914 // -----------------------------------------------------------------------
915 sal_Bool SvHeaderTabListBox::IsCellVisible( sal_Int32, sal_uInt16 ) const
917 return sal_True;
919 // -----------------------------------------------------------------------
920 String SvHeaderTabListBox::GetAccessibleCellText( long _nRow, USHORT _nColumnPos ) const
922 return ::rtl::OUString( GetTabEntryText( _nRow, _nColumnPos ) );
924 // -----------------------------------------------------------------------
925 Rectangle SvHeaderTabListBox::calcHeaderRect( sal_Bool _bIsColumnBar, BOOL _bOnScreen )
927 Rectangle aRect;
928 if ( _bIsColumnBar )
930 Window* pParent = NULL;
931 if ( !_bOnScreen )
932 pParent = m_pImpl->m_pHeaderBar->GetAccessibleParentWindow();
934 aRect = m_pImpl->m_pHeaderBar->GetWindowExtentsRelative( pParent );
936 return aRect;
938 // -----------------------------------------------------------------------
939 Rectangle SvHeaderTabListBox::calcTableRect( BOOL _bOnScreen )
941 Window* pParent = NULL;
942 if ( !_bOnScreen )
943 pParent = GetAccessibleParentWindow();
945 Rectangle aRect( GetWindowExtentsRelative( pParent ) );
946 return aRect;
948 // -----------------------------------------------------------------------
949 Rectangle SvHeaderTabListBox::GetFieldRectPixelAbs( sal_Int32 _nRow, sal_uInt16 _nColumn, BOOL _bIsHeader, BOOL _bOnScreen )
951 DBG_ASSERT( !_bIsHeader || 0 == _nRow, "invalid parameters" );
952 Rectangle aRect;
953 SvLBoxEntry* pEntry = GetEntry( _nRow );
954 if ( pEntry )
956 aRect = _bIsHeader ? calcHeaderRect( sal_True, FALSE ) : GetBoundingRect( pEntry );
957 Point aTopLeft = aRect.TopLeft();
958 DBG_ASSERT( m_pImpl->m_pHeaderBar->GetItemCount() > _nColumn, "invalid column" );
959 Rectangle aItemRect = m_pImpl->m_pHeaderBar->GetItemRect( m_pImpl->m_pHeaderBar->GetItemId( _nColumn ) );
960 aTopLeft.X() = aItemRect.Left();
961 Size aSize = aItemRect.GetSize();
962 aRect = Rectangle( aTopLeft, aSize );
963 Window* pParent = NULL;
964 if ( !_bOnScreen )
965 pParent = GetAccessibleParentWindow();
966 aTopLeft = aRect.TopLeft();
967 aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
968 aRect = Rectangle( aTopLeft, aRect.GetSize() );
971 return aRect;
973 // -----------------------------------------------------------------------
974 Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
976 OSL_ENSURE( m_pAccessible, "Invalid call: Accessible is null" );
978 Reference< XAccessible > xChild;
979 sal_Int32 nIndex = -1;
981 if ( !AreChildrenTransient() )
983 const sal_uInt16 nColumnCount = GetColumnCount();
985 // first call? -> initial list
986 if ( m_aAccessibleChildren.empty() )
988 sal_Int32 nCount = ( GetRowCount() + 1 ) * nColumnCount;
989 m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() );
992 nIndex = ( _nRow * nColumnCount ) + _nColumnPos + nColumnCount;
993 xChild = m_aAccessibleChildren[ nIndex ];
996 if ( !xChild.is() )
998 TriState eState = STATE_DONTKNOW;
999 sal_Bool bIsCheckBox = IsCellCheckBox( _nRow, _nColumnPos, eState );
1000 if ( bIsCheckBox )
1001 xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleCheckBoxCell(
1002 m_pAccessible->getAccessibleChild( 0 ), *this, NULL, _nRow, _nColumnPos, eState, sal_True, sal_False );
1003 else
1004 xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxTableCell(
1005 m_pAccessible->getAccessibleChild( 0 ), *this, NULL, _nRow, _nColumnPos, OFFSET_NONE );
1007 // insert into list
1008 if ( !AreChildrenTransient() )
1009 m_aAccessibleChildren[ nIndex ] = xChild;
1012 return xChild;
1014 // -----------------------------------------------------------------------
1015 Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleRowHeader( sal_Int32 )
1017 Reference< XAccessible > xHeader;
1018 return xHeader;
1020 // -----------------------------------------------------------------------
1021 Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleColumnHeader( sal_uInt16 _nColumn )
1023 // first call? -> initial list
1024 if ( m_aAccessibleChildren.empty() )
1026 const sal_uInt16 nColumnCount = GetColumnCount();
1027 sal_Int32 nCount = AreChildrenTransient() ?
1028 nColumnCount : ( GetRowCount() + 1 ) * nColumnCount;
1029 m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() );
1032 // get header
1033 Reference< XAccessible > xChild = m_aAccessibleChildren[ _nColumn ];
1034 // already exists?
1035 if ( !xChild.is() && m_pAccessible )
1037 // no -> create new header cell
1038 xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxHeaderCell(
1039 _nColumn, m_pAccessible->getHeaderBar( ::svt::BBTYPE_COLUMNHEADERBAR ),
1040 *this, NULL, ::svt::BBTYPE_COLUMNHEADERCELL
1043 // insert into list
1044 m_aAccessibleChildren[ _nColumn ] = xChild;
1047 return xChild;
1049 // -----------------------------------------------------------------------
1050 sal_Int32 SvHeaderTabListBox::GetAccessibleControlCount() const
1052 return -1;
1054 // -----------------------------------------------------------------------
1055 Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleControl( sal_Int32 )
1057 Reference< XAccessible > xControl;
1058 return xControl;
1060 // -----------------------------------------------------------------------
1061 sal_Bool SvHeaderTabListBox::ConvertPointToControlIndex( sal_Int32&, const Point& )
1063 return sal_False;
1065 // -----------------------------------------------------------------------
1066 sal_Bool SvHeaderTabListBox::ConvertPointToCellAddress( sal_Int32&, sal_uInt16&, const Point& )
1068 return sal_False;
1070 // -----------------------------------------------------------------------
1071 sal_Bool SvHeaderTabListBox::ConvertPointToRowHeader( sal_Int32&, const Point& )
1073 return sal_False;
1075 // -----------------------------------------------------------------------
1076 sal_Bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Point& )
1078 return sal_False;
1080 // -----------------------------------------------------------------------
1081 ::rtl::OUString SvHeaderTabListBox::GetAccessibleObjectName( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
1083 ::rtl::OUString aRetText;
1084 switch( _eType )
1086 case ::svt::BBTYPE_BROWSEBOX:
1087 case ::svt::BBTYPE_TABLE:
1088 case ::svt::BBTYPE_COLUMNHEADERBAR:
1089 // should be empty now (see #i63983)
1090 aRetText = ::rtl::OUString();
1091 break;
1093 case ::svt::BBTYPE_TABLECELL:
1095 // here we need a valid pos, we can not handle -1
1096 if ( _nPos >= 0 )
1098 sal_uInt16 nColumnCount = GetColumnCount();
1099 if (nColumnCount > 0)
1101 sal_Int32 nRow = _nPos / nColumnCount;
1102 sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount );
1103 aRetText = GetCellText( nRow, nColumn );
1106 break;
1108 case ::svt::BBTYPE_CHECKBOXCELL:
1110 break; // checkbox cells have no name
1112 case ::svt::BBTYPE_COLUMNHEADERCELL:
1114 aRetText = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( (USHORT)_nPos ) );
1115 break;
1118 case ::svt::BBTYPE_ROWHEADERBAR:
1119 case ::svt::BBTYPE_ROWHEADERCELL:
1120 aRetText = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "error" ) );
1121 break;
1123 default:
1124 OSL_ENSURE(0,"BrowseBox::GetAccessibleName: invalid enum!");
1126 return aRetText;
1128 // -----------------------------------------------------------------------
1129 ::rtl::OUString SvHeaderTabListBox::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
1131 ::rtl::OUString aRetText;
1133 if( _eType == ::svt::BBTYPE_TABLECELL && _nPos != -1 )
1135 static const String sVar1( RTL_CONSTASCII_USTRINGPARAM( "%1" ) );
1136 static const String sVar2( RTL_CONSTASCII_USTRINGPARAM( "%2" ) );
1138 sal_uInt16 nColumnCount = GetColumnCount();
1139 if (nColumnCount > 0)
1141 sal_Int32 nRow = _nPos / nColumnCount;
1142 sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount );
1144 String aText( SvtResId( STR_SVT_ACC_DESC_TABLISTBOX ) );
1145 aText.SearchAndReplace( sVar1, String::CreateFromInt32( nRow ) );
1146 String sColHeader = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( nColumn ) );
1147 if ( sColHeader.Len() == 0 )
1148 sColHeader = String::CreateFromInt32( nColumn );
1149 aText.SearchAndReplace( sVar2, sColHeader );
1150 aRetText = aText;
1154 return aRetText;
1156 // -----------------------------------------------------------------------
1157 void SvHeaderTabListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& _rStateSet, ::svt::AccessibleBrowseBoxObjType _eType ) const
1159 switch( _eType )
1161 case ::svt::BBTYPE_BROWSEBOX:
1162 case ::svt::BBTYPE_TABLE:
1164 _rStateSet.AddState( AccessibleStateType::FOCUSABLE );
1165 if ( HasFocus() )
1166 _rStateSet.AddState( AccessibleStateType::FOCUSED );
1167 if ( IsActive() )
1168 _rStateSet.AddState( AccessibleStateType::ACTIVE );
1169 if ( IsEnabled() )
1171 _rStateSet.AddState( AccessibleStateType::ENABLED );
1172 _rStateSet.AddState( AccessibleStateType::SENSITIVE );
1174 if ( IsReallyVisible() )
1175 _rStateSet.AddState( AccessibleStateType::VISIBLE );
1176 if ( _eType == ::svt::BBTYPE_TABLE )
1179 if ( AreChildrenTransient() )
1180 _rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
1181 _rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
1183 break;
1186 case ::svt::BBTYPE_COLUMNHEADERBAR:
1188 sal_Int32 nCurRow = GetCurrRow();
1189 sal_uInt16 nCurColumn = GetCurrColumn();
1190 if ( IsCellVisible( nCurRow, nCurColumn ) )
1191 _rStateSet.AddState( AccessibleStateType::VISIBLE );
1192 _rStateSet.AddState( AccessibleStateType::TRANSIENT );
1193 break;
1196 case ::svt::BBTYPE_ROWHEADERCELL:
1197 case ::svt::BBTYPE_COLUMNHEADERCELL:
1199 _rStateSet.AddState( AccessibleStateType::VISIBLE );
1200 _rStateSet.AddState( AccessibleStateType::FOCUSABLE );
1201 _rStateSet.AddState( AccessibleStateType::TRANSIENT );
1202 break;
1204 default:
1205 break;
1208 // -----------------------------------------------------------------------
1209 void SvHeaderTabListBox::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumn ) const
1211 _rStateSet.AddState( AccessibleStateType::SELECTABLE );
1212 if ( AreChildrenTransient() )
1213 _rStateSet.AddState( AccessibleStateType::TRANSIENT );
1215 if ( IsCellVisible( _nRow, _nColumn ) )
1217 _rStateSet.AddState( AccessibleStateType::VISIBLE );
1218 _rStateSet.AddState( AccessibleStateType::ENABLED );
1221 if ( IsRowSelected( _nRow ) )
1223 _rStateSet.AddState( AccessibleStateType::ACTIVE );
1224 _rStateSet.AddState( AccessibleStateType::SELECTED );
1227 // -----------------------------------------------------------------------
1228 void SvHeaderTabListBox::GrabTableFocus()
1230 GrabFocus();
1232 // -----------------------------------------------------------------------
1233 BOOL SvHeaderTabListBox::GetGlyphBoundRects( const Point& rOrigin, const String& rStr, int nIndex, int nLen, int nBase, MetricVector& rVector )
1235 return Control::GetGlyphBoundRects( rOrigin, rStr, nIndex, nLen, nBase, rVector );
1237 // -----------------------------------------------------------------------
1238 Rectangle SvHeaderTabListBox::GetWindowExtentsRelative( Window *pRelativeWindow )
1240 return Control::GetWindowExtentsRelative( pRelativeWindow );
1242 // -----------------------------------------------------------------------
1243 void SvHeaderTabListBox::GrabFocus()
1245 Control::GrabFocus();
1247 // -----------------------------------------------------------------------
1248 Reference< XAccessible > SvHeaderTabListBox::GetAccessible( BOOL bCreate )
1250 return Control::GetAccessible( bCreate );
1252 // -----------------------------------------------------------------------
1253 Window* SvHeaderTabListBox::GetAccessibleParentWindow() const
1255 return Control::GetAccessibleParentWindow();
1257 // -----------------------------------------------------------------------
1258 Window* SvHeaderTabListBox::GetWindowInstance()
1260 return this;
1262 // -----------------------------------------------------------------------
1263 Reference< XAccessible > SvHeaderTabListBox::CreateAccessible()
1265 Window* pParent = GetAccessibleParentWindow();
1266 DBG_ASSERT( pParent, "SvHeaderTabListBox::::CreateAccessible - accessible parent not found" );
1268 Reference< XAccessible > xAccessible;
1269 if ( m_pAccessible ) xAccessible = m_pAccessible->getMyself();
1271 if( pParent && !m_pAccessible )
1273 Reference< XAccessible > xAccParent = pParent->GetAccessible();
1274 if ( xAccParent.is() )
1276 m_pAccessible = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleTabListBox( xAccParent, *this );
1277 if ( m_pAccessible )
1278 xAccessible = m_pAccessible->getMyself();
1281 return xAccessible;
1283 // -----------------------------------------------------------------------------
1284 Rectangle SvHeaderTabListBox::GetFieldCharacterBounds(sal_Int32,sal_Int32,sal_Int32)
1286 Rectangle aRect;
1287 return aRect;
1289 // -----------------------------------------------------------------------------
1290 sal_Int32 SvHeaderTabListBox::GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)
1292 String sText = GetAccessibleCellText( _nRow, static_cast< USHORT >( _nColumnPos ) );
1293 MetricVector aRects;
1294 if ( GetGlyphBoundRects(Point(0,0),sText,0,STRING_LEN,0,aRects) )
1296 for (MetricVector::iterator aIter = aRects.begin(); aIter != aRects.end(); ++aIter)
1298 if( aIter->IsInside(_rPoint) )
1299 return aIter - aRects.begin();
1303 return -1;
1305 // -----------------------------------------------------------------------------