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_sw.hxx"
26 
27 
28 #include <vos/mutex.hxx>
29 #include <vcl/svapp.hxx>
30 #include <com/sun/star/accessibility/AccessibleRole.hpp>
31 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
32 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33 #include <unotools/accessiblestatesethelper.hxx>
34 #include <frmfmt.hxx>
35 #include <ndnotxt.hxx>
36 #include <flyfrm.hxx>
37 #include <cntfrm.hxx>
38 // --> OD 2009-07-14 #i73249#
39 #include <hints.hxx>
40 // <--
41 #include "accnotextframe.hxx"
42 
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::accessibility;
45 using ::rtl::OUString;
46 
47 const SwNoTxtNode *SwAccessibleNoTextFrame::GetNoTxtNode() const
48 {
49 	const SwNoTxtNode *pNd  = 0;
50 	const SwFlyFrm *pFlyFrm = static_cast< const SwFlyFrm *>( GetFrm() );
51 	if( pFlyFrm->Lower() && pFlyFrm->Lower()->IsNoTxtFrm() )
52 	{
53 		const SwCntntFrm *pCntFrm =
54 			static_cast<const SwCntntFrm *>( pFlyFrm->Lower() );
55 		pNd = pCntFrm->GetNode()->GetNoTxtNode();
56 	}
57 
58 	return pNd;
59 }
60 
61 SwAccessibleNoTextFrame::SwAccessibleNoTextFrame(
62         SwAccessibleMap* pInitMap,
63         sal_Int16 nInitRole,
64         const SwFlyFrm* pFlyFrm  ) :
65     SwAccessibleFrameBase( pInitMap, nInitRole, pFlyFrm ),
66     aDepend( this, const_cast < SwNoTxtNode * >( GetNoTxtNode() ) ),
67     msTitle(),
68     msDesc()
69 {
70     const SwNoTxtNode* pNd = GetNoTxtNode();
71     // --> OD 2009-07-14 #i73249#
72     // consider new attributes Title and Description
73     if( pNd )
74     {
75         msTitle = pNd->GetTitle();
76 
77         msDesc = pNd->GetDescription();
78         if ( msDesc.getLength() == 0 &&
79              msTitle != GetName() )
80         {
81             msDesc = msTitle;
82         }
83     }
84     // <--
85 }
86 
87 SwAccessibleNoTextFrame::~SwAccessibleNoTextFrame()
88 {
89 }
90 
91 void SwAccessibleNoTextFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
92 {
93     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ;
94     // --> OD 2009-07-14 #i73249#
95     // suppress handling of RES_NAME_CHANGED in case that attribute Title is
96     // used as the accessible name.
97     if ( nWhich != RES_NAME_CHANGED ||
98          msTitle.getLength() == 0 )
99     {
100         SwAccessibleFrameBase::Modify( pOld, pNew );
101     }
102 
103     const SwNoTxtNode *pNd = GetNoTxtNode();
104     ASSERT( pNd == aDepend.GetRegisteredIn(), "invalid frame" );
105     switch( nWhich )
106 	{
107         // --> OD 2009-07-14 #i73249#
108         case RES_TITLE_CHANGED:
109         {
110             const String& sOldTitle(
111                         dynamic_cast<const SwStringMsgPoolItem*>(pOld)->GetString() );
112             const String& sNewTitle(
113                         dynamic_cast<const SwStringMsgPoolItem*>(pNew)->GetString() );
114             if ( sOldTitle == sNewTitle )
115             {
116                 break;
117             }
118             msTitle = sNewTitle;
119             AccessibleEventObject aEvent;
120             aEvent.EventId = AccessibleEventId::NAME_CHANGED;
121             aEvent.OldValue <<= OUString( sOldTitle );
122             aEvent.NewValue <<= msTitle;
123             FireAccessibleEvent( aEvent );
124 
125             if ( pNd->GetDescription().Len() != 0 )
126             {
127                 break;
128             }
129         }
130         // intentional no break here
131         case RES_DESCRIPTION_CHANGED:
132         {
133             if ( pNd && GetFrm() )
134             {
135                 const OUString sOldDesc( msDesc );
136 
137                 const String& rDesc = pNd->GetDescription();
138                 msDesc = rDesc;
139                 if ( msDesc.getLength() == 0 &&
140                      msTitle != GetName() )
141                 {
142                     msDesc = msTitle;
143                 }
144 
145                 if ( msDesc != sOldDesc )
146                 {
147                     AccessibleEventObject aEvent;
148                     aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
149                     aEvent.OldValue <<= sOldDesc;
150                     aEvent.NewValue <<= msDesc;
151                     FireAccessibleEvent( aEvent );
152                 }
153             }
154         }
155         break;
156         // <--
157         /*
158 	case RES_OBJECTDYING:
159 		if( aDepend.GetRegisteredIn() ==
160 				static_cast< SwModify *>( static_cast< SwPtrMsgPoolItem * >( pOld )->pObject ) )
161 			const_cast < SwModify *>( aDepend.GetRegisteredIn()->Remove( aDepend );
162 		break;
163 
164 	case RES_FMT_CHG:
165 		if( static_cast< SwFmtChg * >(pNew)->pChangedFmt == GetRegisteredIn() &&
166 			static_cast< SwFmtChg * >(pOld)->pChangedFmt->IsFmtInDTOR() )
167 			GetRegisteredIn()->Remove( this );
168 		break;
169 	*/
170 	}
171 }
172 
173 void SwAccessibleNoTextFrame::Dispose( sal_Bool bRecursive )
174 {
175 	vos::OGuard aGuard(Application::GetSolarMutex());
176 
177 	if( aDepend.GetRegisteredIn() )
178 		const_cast < SwModify *>( aDepend.GetRegisteredIn() )->Remove( &aDepend );
179 
180 	SwAccessibleFrameBase::Dispose( bRecursive );
181 }
182 
183 // --> OD 2009-07-14 #i73249#
184 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleName (void)
185         throw (uno::RuntimeException)
186 {
187     vos::OGuard aGuard(Application::GetSolarMutex());
188 
189     CHECK_FOR_DEFUNC( XAccessibleContext )
190 
191     if ( msTitle.getLength() != 0 )
192     {
193         return msTitle;
194     }
195 
196     return SwAccessibleFrameBase::getAccessibleName();
197 }
198 // <--
199 
200 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleDescription (void)
201         throw (uno::RuntimeException)
202 {
203 	vos::OGuard aGuard(Application::GetSolarMutex());
204 
205 	CHECK_FOR_DEFUNC( XAccessibleContext )
206 
207     return msDesc;
208 }
209 
210 
211 
212 //
213 // XInterface
214 //
215 
216 uno::Any SAL_CALL SwAccessibleNoTextFrame::queryInterface( const uno::Type& aType )
217     throw (uno::RuntimeException)
218 {
219     if( aType ==
220         ::getCppuType( static_cast<uno::Reference<XAccessibleImage>*>( NULL ) ) )
221     {
222         uno::Reference<XAccessibleImage> xImage = this;
223         uno::Any aAny;
224         aAny <<= xImage;
225         return aAny;
226     }
227     else
228         return SwAccessibleContext::queryInterface( aType );
229 }
230 
231 
232 //====== XTypeProvider ====================================================
233 uno::Sequence< uno::Type > SAL_CALL SwAccessibleNoTextFrame::getTypes() throw(uno::RuntimeException)
234 {
235 	uno::Sequence< uno::Type > aTypes( SwAccessibleFrameBase::getTypes() );
236 
237 	sal_Int32 nIndex = aTypes.getLength();
238 	aTypes.realloc( nIndex + 1 );
239 
240 	uno::Type* pTypes = aTypes.getArray();
241 	pTypes[nIndex] = ::getCppuType( static_cast< uno::Reference< XAccessibleImage > * >( 0 ) );
242 
243 	return aTypes;
244 }
245 
246 
247 //
248 // XAccessibleImage
249 //
250 
251 // implementation of the XAccessibleImage methods is a no-brainer, as
252 // all releveant information is already accessible through other
253 // methods. So we just delegate to those.
254 
255 OUString SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageDescription()
256     throw ( uno::RuntimeException )
257 {
258     return getAccessibleDescription();
259 }
260 
261 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageHeight(  )
262     throw ( uno::RuntimeException )
263 {
264     return getSize().Height;
265 }
266 
267 sal_Int32 SAL_CALL SwAccessibleNoTextFrame::getAccessibleImageWidth(  )
268     throw ( uno::RuntimeException )
269 {
270     return getSize().Width;
271 }
272