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: acccell.cxx,v $
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_sw.hxx"
35 #include <vos/mutex.hxx>
36 #include <com/sun/star/accessibility/AccessibleRole.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
39 #include <unotools/accessiblestatesethelper.hxx>
41 #include <vcl/svapp.hxx>
42 #include <cellfrm.hxx>
44 #include <swtable.hxx>
47 #include <accfrmobjslist.hxx>
49 #include "cellatr.hxx"
51 #include <acccell.hxx>
59 using namespace ::com::sun::star
;
60 using namespace ::com::sun::star::accessibility
;
61 using ::rtl::OUString
;
63 const sal_Char sServiceName
[] = "com.sun.star.table.AccessibleCellView";
64 const sal_Char sImplementationName
[] = "com.sun.star.comp.Writer.SwAccessibleCellView";
66 sal_Bool
SwAccessibleCell::IsSelected()
68 sal_Bool bRet
= sal_False
;
70 DBG_ASSERT( GetMap(), "no map?" );
71 const ViewShell
*pVSh
= GetMap()->GetShell();
72 DBG_ASSERT( pVSh
, "no shell?" );
73 if( pVSh
->ISA( SwCrsrShell
) )
75 const SwCrsrShell
*pCSh
= static_cast< const SwCrsrShell
* >( pVSh
);
76 if( pCSh
->IsTableMode() )
78 const SwCellFrm
*pCFrm
=
79 static_cast< const SwCellFrm
* >( GetFrm() );
81 const_cast< SwTableBox
*>( pCFrm
->GetTabBox() ); //SVPtrArr!
82 bRet
= pCSh
->GetTableCrsr()->GetBoxes().Seek_Entry( pBox
);
89 void SwAccessibleCell::GetStates(
90 ::utl::AccessibleStateSetHelper
& rStateSet
)
92 SwAccessibleContext::GetStates( rStateSet
);
95 const ViewShell
*pVSh
= GetMap()->GetShell();
96 DBG_ASSERT( pVSh
, "no shell?" );
97 if( pVSh
->ISA( SwCrsrShell
) )
98 rStateSet
.AddState( AccessibleStateType::SELECTABLE
);
103 rStateSet
.AddState( AccessibleStateType::SELECTED
);
104 ASSERT( bIsSelected
, "bSelected out of sync" );
105 ::vos::ORef
< SwAccessibleContext
> xThis( this );
106 GetMap()->SetCursorContext( xThis
);
110 SwAccessibleCell::SwAccessibleCell(
111 SwAccessibleMap
*pInitMap
,
112 const SwCellFrm
*pCellFrm
) :
113 SwAccessibleContext( pInitMap
, AccessibleRole::TABLE_CELL
, pCellFrm
),
114 bIsSelected( sal_False
)
116 vos::OGuard
aGuard(Application::GetSolarMutex());
117 OUString
sBoxName( pCellFrm
->GetTabBox()->GetName() );
120 bIsSelected
= IsSelected();
123 sal_Bool
SwAccessibleCell::_InvalidateMyCursorPos()
125 sal_Bool bNew
= IsSelected();
128 vos::OGuard
aGuard( aMutex
);
134 // remember that object as the one that has the caret. This is
135 // neccessary to notify that object if the cursor leaves it.
136 ::vos::ORef
< SwAccessibleContext
> xThis( this );
137 GetMap()->SetCursorContext( xThis
);
140 sal_Bool bChanged
= bOld
!= bNew
;
142 FireStateChangedEvent( AccessibleStateType::SELECTED
, bNew
);
147 sal_Bool
SwAccessibleCell::_InvalidateChildrenCursorPos( const SwFrm
*pFrm
)
149 sal_Bool bChanged
= sal_False
;
151 const SwFrmOrObjSList
aVisList( GetVisArea(), pFrm
);
152 SwFrmOrObjSList::const_iterator
aIter( aVisList
.begin() );
153 while( aIter
!= aVisList
.end() )
155 const SwFrmOrObj
& rLower
= *aIter
;
156 const SwFrm
*pLower
= rLower
.GetSwFrm();
159 if( rLower
.IsAccessible( GetMap()->GetShell()->IsPreView() ) )
161 ::vos::ORef
< SwAccessibleContext
> xAccImpl(
162 GetMap()->GetContextImpl( pLower
, sal_False
) );
163 if( xAccImpl
.isValid() )
165 ASSERT( xAccImpl
->GetFrm()->IsCellFrm(),
166 "table child is not a cell frame" )
167 bChanged
|= static_cast< SwAccessibleCell
*>(
168 xAccImpl
.getBodyPtr() )->_InvalidateMyCursorPos();
171 bChanged
= sal_True
; // If the context is not know we
172 // don't know whether the selection
177 // This is a box with sub rows.
178 bChanged
|= _InvalidateChildrenCursorPos( pLower
);
187 void SwAccessibleCell::_InvalidateCursorPos()
190 const SwFrm
*pParent
= GetParent( GetFrm(), IsInPagePreview() );
191 ASSERT( pParent
->IsTabFrm(), "parent is not a tab frame" );
192 const SwTabFrm
*pTabFrm
= static_cast< const SwTabFrm
* >( pParent
);
193 if( pTabFrm
->IsFollow() )
194 pTabFrm
= pTabFrm
->FindMaster();
198 sal_Bool bChanged
= _InvalidateChildrenCursorPos( pTabFrm
);
201 ::vos::ORef
< SwAccessibleContext
> xAccImpl(
202 GetMap()->GetContextImpl( pTabFrm
, sal_False
) );
203 if( xAccImpl
.isValid() )
205 AccessibleEventObject aEvent
;
206 aEvent
.EventId
= AccessibleEventId::SELECTION_CHANGED
;
207 xAccImpl
->FireAccessibleEvent( aEvent
);
211 pTabFrm
= pTabFrm
->GetFollow();
215 sal_Bool
SwAccessibleCell::HasCursor()
217 vos::OGuard
aGuard( aMutex
);
221 SwAccessibleCell::~SwAccessibleCell()
225 OUString SAL_CALL
SwAccessibleCell::getAccessibleDescription (void)
226 throw (uno::RuntimeException
)
231 OUString SAL_CALL
SwAccessibleCell::getImplementationName()
232 throw( uno::RuntimeException
)
234 return OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationName
));
237 sal_Bool SAL_CALL
SwAccessibleCell::supportsService(
238 const ::rtl::OUString
& sTestServiceName
)
239 throw (uno::RuntimeException
)
241 return sTestServiceName
.equalsAsciiL( sServiceName
,
242 sizeof(sServiceName
)-1 ) ||
243 sTestServiceName
.equalsAsciiL( sAccessibleServiceName
,
244 sizeof(sAccessibleServiceName
)-1 );
247 uno::Sequence
< OUString
> SAL_CALL
SwAccessibleCell::getSupportedServiceNames()
248 throw( uno::RuntimeException
)
250 uno::Sequence
< OUString
> aRet(2);
251 OUString
* pArray
= aRet
.getArray();
252 pArray
[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceName
) );
253 pArray
[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName
) );
257 void SwAccessibleCell::Dispose( sal_Bool bRecursive
)
259 const SwFrm
*pParent
= GetParent( GetFrm(), IsInPagePreview() );
260 ::vos::ORef
< SwAccessibleContext
> xAccImpl(
261 GetMap()->GetContextImpl( pParent
, sal_False
) );
262 if( xAccImpl
.isValid() )
263 xAccImpl
->DisposeChild( GetFrm(), bRecursive
);
264 SwAccessibleContext::Dispose( bRecursive
);
267 void SwAccessibleCell::InvalidatePosOrSize( const SwRect
& rOldBox
)
269 const SwFrm
*pParent
= GetParent( GetFrm(), IsInPagePreview() );
270 ::vos::ORef
< SwAccessibleContext
> xAccImpl(
271 GetMap()->GetContextImpl( pParent
, sal_False
) );
272 if( xAccImpl
.isValid() )
273 xAccImpl
->InvalidateChildPosOrSize( GetFrm(), rOldBox
);
274 SwAccessibleContext::InvalidatePosOrSize( rOldBox
);
278 // ===== XAccessibleInterface ===========================================
280 uno::Any
SwAccessibleCell::queryInterface( const uno::Type
& rType
)
281 throw( uno::RuntimeException
)
283 if ( rType
== ::getCppuType( static_cast< uno::Reference
< XAccessibleValue
> * >( 0 ) ) )
285 uno::Reference
<XAccessibleValue
> xValue
= this;
292 return SwAccessibleContext::queryInterface( rType
);
296 //====== XTypeProvider ====================================================
297 uno::Sequence
< uno::Type
> SAL_CALL
SwAccessibleCell::getTypes()
298 throw(uno::RuntimeException
)
300 uno::Sequence
< uno::Type
> aTypes( SwAccessibleContext::getTypes() );
302 sal_Int32 nIndex
= aTypes
.getLength();
303 aTypes
.realloc( nIndex
+ 1 );
305 uno::Type
* pTypes
= aTypes
.getArray();
306 pTypes
[nIndex
] = ::getCppuType( static_cast< uno::Reference
< XAccessibleValue
> * >( 0 ) );
311 uno::Sequence
< sal_Int8
> SAL_CALL
SwAccessibleCell::getImplementationId()
312 throw(uno::RuntimeException
)
314 vos::OGuard
aGuard(Application::GetSolarMutex());
315 static uno::Sequence
< sal_Int8
> aId( 16 );
316 static sal_Bool bInit
= sal_False
;
319 rtl_createUuid( (sal_uInt8
*)(aId
.getArray() ), 0, sal_True
);
325 // ===== XAccessibleValue ===============================================
327 SwFrmFmt
* SwAccessibleCell::GetTblBoxFormat() const
329 DBG_ASSERT( GetFrm() != NULL
, "no frame?" );
330 DBG_ASSERT( GetFrm()->IsCellFrm(), "no cell frame?" );
332 const SwCellFrm
* pCellFrm
= static_cast<const SwCellFrm
*>( GetFrm() );
333 return pCellFrm
->GetTabBox()->GetFrmFmt();
337 uno::Any
SwAccessibleCell::getCurrentValue( )
338 throw( uno::RuntimeException
)
340 vos::OGuard
aGuard(Application::GetSolarMutex());
341 CHECK_FOR_DEFUNC( XAccessibleValue
);
344 aAny
<<= GetTblBoxFormat()->GetTblBoxValue().GetValue();
348 sal_Bool
SwAccessibleCell::setCurrentValue( const uno::Any
& aNumber
)
349 throw( uno::RuntimeException
)
351 vos::OGuard
aGuard(Application::GetSolarMutex());
352 CHECK_FOR_DEFUNC( XAccessibleValue
);
355 sal_Bool bValid
= (aNumber
>>= fValue
);
358 SwTblBoxValue
aValue( fValue
);
359 GetTblBoxFormat()->SetFmtAttr( aValue
);
364 uno::Any
SwAccessibleCell::getMaximumValue( )
365 throw( uno::RuntimeException
)
372 uno::Any
SwAccessibleCell::getMinimumValue( )
373 throw( uno::RuntimeException
)