1  /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <vos/mutex.hxx>
33 #include <vcl/svapp.hxx>
34 #include <com/sun/star/accessibility/AccessibleRole.hpp>
35 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 #include <unotools/accessiblestatesethelper.hxx>
38 #include <frmfmt.hxx>
39 #include <ndnotxt.hxx>
40 #include <flyfrm.hxx>
41 #include <cntfrm.hxx>
42 // --> OD 2009-07-14 #i73249#
43 #include <hints.hxx>
44 // <--
45 #include "accnotextframe.hxx"
46 
47 using namespace ::com::sun::star;
48 using namespace ::com::sun::star::accessibility;
49 using ::rtl::OUString;
50 
51 const SwNoTxtNode *SwAccessibleNoTextFrame::GetNoTxtNode() const
52 {
53 	const SwNoTxtNode *pNd  = 0;
54 	const SwFlyFrm *pFlyFrm = static_cast< const SwFlyFrm *>( GetFrm() );
55 	if( pFlyFrm->Lower() && pFlyFrm->Lower()->IsNoTxtFrm() )
56 	{
57 		const SwCntntFrm *pCntFrm =
58 			static_cast<const SwCntntFrm *>( pFlyFrm->Lower() );
59 		pNd = pCntFrm->GetNode()->GetNoTxtNode();
60 	}
61 
62 	return pNd;
63 }
64 
65 SwAccessibleNoTextFrame::SwAccessibleNoTextFrame(
66         SwAccessibleMap* pInitMap,
67         sal_Int16 nInitRole,
68         const SwFlyFrm* pFlyFrm  ) :
69     SwAccessibleFrameBase( pInitMap, nInitRole, pFlyFrm ),
70     aDepend( this, const_cast < SwNoTxtNode * >( GetNoTxtNode() ) ),
71     msTitle(),
72     msDesc()
73 {
74     const SwNoTxtNode* pNd = GetNoTxtNode();
75     // --> OD 2009-07-14 #i73249#
76     // consider new attributes Title and Description
77     if( pNd )
78     {
79         msTitle = pNd->GetTitle();
80 
81         msDesc = pNd->GetDescription();
82         if ( msDesc.getLength() == 0 &&
83              msTitle != GetName() )
84         {
85             msDesc = msTitle;
86         }
87     }
88     // <--
89 }
90 
91 SwAccessibleNoTextFrame::~SwAccessibleNoTextFrame()
92 {
93 }
94 
95 void SwAccessibleNoTextFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
96 {
97     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ;
98     // --> OD 2009-07-14 #i73249#
99     // suppress handling of RES_NAME_CHANGED in case that attribute Title is
100     // used as the accessible name.
101     if ( nWhich != RES_NAME_CHANGED ||
102          msTitle.getLength() == 0 )
103     {
104         SwAccessibleFrameBase::Modify( pOld, pNew );
105     }
106 
107     const SwNoTxtNode *pNd = GetNoTxtNode();
108     ASSERT( pNd == aDepend.GetRegisteredIn(), "invalid frame" );
109     switch( nWhich )
110 	{
111         // --> OD 2009-07-14 #i73249#
112         case RES_TITLE_CHANGED:
113         {
114             const String& sOldTitle(
115                         dynamic_cast<const SwStringMsgPoolItem*>(pOld)->GetString() );
116             const String& sNewTitle(
117                         dynamic_cast<const SwStringMsgPoolItem*>(pNew)->GetString() );
118             if ( sOldTitle == sNewTitle )
119             {
120                 break;
121             }
122             msTitle = sNewTitle;
123             AccessibleEventObject aEvent;
124             aEvent.EventId = AccessibleEventId::NAME_CHANGED;
125             aEvent.OldValue <<= OUString( sOldTitle );
126             aEvent.NewValue <<= msTitle;
127             FireAccessibleEvent( aEvent );
128 
129             if ( pNd->GetDescription().Len() != 0 )
130             {
131                 break;
132             }
133         }
134         // intentional no break here
135         case RES_DESCRIPTION_CHANGED:
136         {
137             if ( pNd && GetFrm() )
138             {
139                 const OUString sOldDesc( msDesc );
140 
141                 const String& rDesc = pNd->GetDescription();
142                 msDesc = rDesc;
143                 if ( msDesc.getLength() == 0 &&
144                      msTitle != GetName() )
145                 {
146                     msDesc = msTitle;
147                 }
148 
149                 if ( msDesc != sOldDesc )
150                 {
151                     AccessibleEventObject aEvent;
152                     aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
153                     aEvent.OldValue <<= sOldDesc;
154                     aEvent.NewValue <<= msDesc;
155                     FireAccessibleEvent( aEvent );
156                 }
157             }
158         }
159         break;
160         // <--
161         /*
162 	case RES_OBJECTDYING:
163 		if( aDepend.GetRegisteredIn() ==
164 				static_cast< SwModify *>( static_cast< SwPtrMsgPoolItem * >( pOld )->pObject ) )
165 			const_cast < SwModify *>( aDepend.GetRegisteredIn()->Remove( aDepend );
166 		break;
167 
168 	case RES_FMT_CHG:
169 		if( static_cast< SwFmtChg * >(pNew)->pChangedFmt == GetRegisteredIn() &&
170 			static_cast< SwFmtChg * >(pOld)->pChangedFmt->IsFmtInDTOR() )
171 			GetRegisteredIn()->Remove( this );
172 		break;
173 	*/
174 	}
175 }
176 
177 void SwAccessibleNoTextFrame::Dispose( sal_Bool bRecursive )
178 {
179 	vos::OGuard aGuard(Application::GetSolarMutex());
180 
181 	if( aDepend.GetRegisteredIn() )
182 		const_cast < SwModify *>( aDepend.GetRegisteredIn() )->Remove( &aDepend );
183 
184 	SwAccessibleFrameBase::Dispose( bRecursive );
185 }
186 
187 // --> OD 2009-07-14 #i73249#
188 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleName (void)
189         throw (uno::RuntimeException)
190 {
191     vos::OGuard aGuard(Application::GetSolarMutex());
192 
193     CHECK_FOR_DEFUNC( XAccessibleContext )
194 
195     if ( msTitle.getLength() != 0 )
196     {
197         return msTitle;
198     }
199 
200     return SwAccessibleFrameBase::getAccessibleName();
201 }
202 // <--
203 
204 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleDescription (void)
205         throw (uno::RuntimeException)
206 {
207 	vos::OGuard aGuard(Application::GetSolarMutex());
208 
209 	CHECK_FOR_DEFUNC( XAccessibleContext )
210 
211     return msDesc;
212 }
213 
214 
215 
216 //
217 // XInterface
218 //
219 
220 uno::Any SAL_CALL SwAccessibleNoTextFrame::queryInterface( const uno::Type& aType )
221     throw (uno::RuntimeException)
222 {
223     if( aType ==
224         ::getCppuType( static_cast<uno::Reference<XAccessibleImage>*>( NULL ) ) )
225     {
226         uno::Reference<XAccessibleImage> xImage = this;
227         uno::Any aAny;
228         aAny <<= xImage;
229         return aAny;
230     }
231     else
232         return SwAccessibleContext::queryInterface( aType );
233 }
234 
235 
236 //====== XTypeProvider ====================================================
237 uno::Sequence< uno::Type > SAL_CALL SwAccessibleNoTextFrame::getTypes() throw(uno::RuntimeException)
238 {
239 	uno::Sequence< uno::Type > aTypes( SwAccessibleFrameBase::getTypes() );
240 
241 	sal_Int32 nIndex = aTypes.getLength();
242 	aTypes.realloc( nIndex + 1 );
243 
244 	uno::Type* pTypes = aTypes.getArray();
245 	pTypes[nIndex] = ::getCppuType( static_cast< uno::Reference< XAccessibleImage > * >( 0 ) );
246 
247 	return aTypes;
248 }
249 
250 
251 //
252 // XAccessibleImage
253 //
254 
255 // implementation of the XAccessibleImage methods is a no-brainer, as
256 // all releveant information is already accessible through other
257 // methods. So we just delegate to those.
258 
259 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageDescription()
260     throw ( uno::RuntimeException )
261 {
262     return getAccessibleDescription();
263 }
264 
265 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageHeight(  )
266     throw ( uno::RuntimeException )
267 {
268     return getSize().Height;
269 }
270 
271 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageWidth(  )
272     throw ( uno::RuntimeException )
273 {
274     return getSize().Width;
275 }
276