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_editeng.hxx" 26 27 //------------------------------------------------------------------------ 28 // 29 // Global header 30 // 31 //------------------------------------------------------------------------ 32 #include <com/sun/star/uno/Any.hxx> 33 #include <com/sun/star/uno/Reference.hxx> 34 #include <cppuhelper/weakref.hxx> 35 #include <com/sun/star/accessibility/XAccessible.hpp> 36 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 37 38 //------------------------------------------------------------------------ 39 // 40 // Project-local header 41 // 42 //------------------------------------------------------------------------ 43 44 #include <editeng/unoedhlp.hxx> 45 #include <editeng/unopracc.hxx> 46 #include <editeng/unoedsrc.hxx> 47 #include "editeng/AccessibleParaManager.hxx" 48 #include "editeng/AccessibleEditableTextPara.hxx" 49 50 51 using namespace ::com::sun::star; 52 using namespace ::com::sun::star::accessibility; 53 54 55 56 namespace accessibility 57 { 58 AccessibleParaManager::AccessibleParaManager() : 59 maChildren(1), 60 maEEOffset( 0, 0 ), 61 mnFocusedChild( -1 ), 62 mbActive( sal_False ) 63 { 64 } 65 66 AccessibleParaManager::~AccessibleParaManager() 67 { 68 // owner is responsible for possible child defuncs 69 } 70 71 void AccessibleParaManager::SetAdditionalChildStates( const VectorOfStates& rChildStates ) 72 { 73 maChildStates = rChildStates; 74 } 75 76 const AccessibleParaManager::VectorOfStates& AccessibleParaManager::GetAdditionalChildStates() const 77 { 78 return maChildStates; 79 } 80 81 void AccessibleParaManager::SetNum( sal_Int32 nNumParas ) 82 { 83 if( (size_t)nNumParas < maChildren.size() ) 84 Release( nNumParas, maChildren.size() ); 85 86 maChildren.resize( nNumParas ); 87 88 if( mnFocusedChild >= nNumParas ) 89 mnFocusedChild = -1; 90 } 91 92 sal_uInt32 AccessibleParaManager::GetNum() const 93 { 94 return maChildren.size(); 95 } 96 97 AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::begin() 98 { 99 return maChildren.begin(); 100 } 101 102 AccessibleParaManager::VectorOfChildren::iterator AccessibleParaManager::end() 103 { 104 return maChildren.end(); 105 } 106 107 AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::begin() const 108 { 109 return maChildren.begin(); 110 } 111 112 AccessibleParaManager::VectorOfChildren::const_iterator AccessibleParaManager::end() const 113 { 114 return maChildren.end(); 115 } 116 117 void AccessibleParaManager::Release( sal_uInt32 nPara ) 118 { 119 DBG_ASSERT( maChildren.size() > nPara, "AccessibleParaManager::Release: invalid index" ); 120 121 if( maChildren.size() > nPara ) 122 { 123 ShutdownPara( GetChild( nPara ) ); 124 125 // clear reference and rect 126 maChildren[ nPara ] = WeakChild(); 127 } 128 } 129 130 void AccessibleParaManager::FireEvent( sal_uInt32 nPara, 131 const sal_Int16 nEventId, 132 const uno::Any& rNewValue, 133 const uno::Any& rOldValue ) const 134 { 135 DBG_ASSERT( maChildren.size() > nPara, "AccessibleParaManager::FireEvent: invalid index" ); 136 137 if( maChildren.size() > nPara ) 138 { 139 WeakPara::HardRefType maChild( GetChild( nPara ).first.get() ); 140 if( maChild.is() ) 141 maChild->FireEvent( nEventId, rNewValue, rOldValue ); 142 } 143 } 144 145 sal_Bool AccessibleParaManager::IsReferencable( WeakPara::HardRefType aChild ) 146 { 147 return aChild.is(); 148 } 149 150 sal_Bool AccessibleParaManager::IsReferencable( sal_uInt32 nChild ) const 151 { 152 DBG_ASSERT( maChildren.size() > nChild, "AccessibleParaManager::IsReferencable: invalid index" ); 153 154 if( maChildren.size() > nChild ) 155 { 156 // retrieve hard reference from weak one 157 return IsReferencable( GetChild( nChild ).first.get() ); 158 } 159 else 160 { 161 return sal_False; 162 } 163 } 164 165 AccessibleParaManager::WeakChild AccessibleParaManager::GetChild( sal_uInt32 nParagraphIndex ) const 166 { 167 DBG_ASSERT( maChildren.size() > nParagraphIndex, "AccessibleParaManager::GetChild: invalid index" ); 168 169 if( maChildren.size() > nParagraphIndex ) 170 { 171 return maChildren[ nParagraphIndex ]; 172 } 173 else 174 { 175 return WeakChild(); 176 } 177 } 178 179 AccessibleParaManager::Child AccessibleParaManager::CreateChild( sal_Int32 nChild, 180 const uno::Reference< XAccessible >& xFrontEnd, 181 SvxEditSourceAdapter& rEditSource, 182 sal_uInt32 nParagraphIndex ) 183 { 184 DBG_ASSERT( maChildren.size() > nParagraphIndex, "AccessibleParaManager::CreateChild: invalid index" ); 185 186 if( maChildren.size() > nParagraphIndex ) 187 { 188 // retrieve hard reference from weak one 189 WeakPara::HardRefType aChild( GetChild( nParagraphIndex ).first.get() ); 190 191 if( !IsReferencable( nParagraphIndex ) ) 192 { 193 // there is no hard reference available, create object then 194 // --> OD 2006-01-11 #i27138# 195 AccessibleEditableTextPara* pChild = new AccessibleEditableTextPara( xFrontEnd, this ); 196 // <-- 197 uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY ); 198 199 if( !xChild.is() ) 200 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Child creation failed")), xFrontEnd); 201 202 aChild = WeakPara::HardRefType( xChild, pChild ); 203 204 InitChild( *aChild, rEditSource, nChild, nParagraphIndex ); 205 206 maChildren[ nParagraphIndex ] = WeakChild( aChild, pChild->getBounds() ); 207 } 208 209 return Child( aChild.getRef(), GetChild( nParagraphIndex ).second ); 210 } 211 else 212 { 213 return Child(); 214 } 215 } 216 217 void AccessibleParaManager::SetEEOffset( const Point& rOffset ) 218 { 219 maEEOffset = rOffset; 220 221 MemFunAdapter< const Point& > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEEOffset, rOffset ); 222 ::std::for_each( begin(), end(), aAdapter ); 223 } 224 225 void AccessibleParaManager::SetActive( sal_Bool bActive ) 226 { 227 mbActive = bActive; 228 229 if( bActive ) 230 { 231 SetState( AccessibleStateType::ACTIVE ); 232 SetState( AccessibleStateType::EDITABLE ); 233 } 234 else 235 { 236 UnSetState( AccessibleStateType::ACTIVE ); 237 UnSetState( AccessibleStateType::EDITABLE ); 238 } 239 } 240 241 void AccessibleParaManager::SetFocus( sal_Int32 nChild ) 242 { 243 if( mnFocusedChild != -1 ) 244 UnSetState( mnFocusedChild, AccessibleStateType::FOCUSED ); 245 246 mnFocusedChild = nChild; 247 248 if( mnFocusedChild != -1 ) 249 SetState( mnFocusedChild, AccessibleStateType::FOCUSED ); 250 } 251 252 void AccessibleParaManager::InitChild( AccessibleEditableTextPara& rChild, 253 SvxEditSourceAdapter& rEditSource, 254 sal_Int32 nChild, 255 sal_uInt32 nParagraphIndex ) const 256 { 257 rChild.SetEditSource( &rEditSource ); 258 rChild.SetIndexInParent( nChild ); 259 rChild.SetParagraphIndex( nParagraphIndex ); 260 261 rChild.SetEEOffset( maEEOffset ); 262 263 if( mbActive ) 264 { 265 rChild.SetState( AccessibleStateType::ACTIVE ); 266 rChild.SetState( AccessibleStateType::EDITABLE ); 267 } 268 269 if( mnFocusedChild == static_cast<sal_Int32>(nParagraphIndex) ) 270 rChild.SetState( AccessibleStateType::FOCUSED ); 271 272 // add states passed from outside 273 for( VectorOfStates::const_iterator aIt = maChildStates.begin(), aEnd = maChildStates.end(); aIt != aEnd; ++aIt ) 274 rChild.SetState( *aIt ); 275 } 276 277 void AccessibleParaManager::SetState( sal_Int32 nChild, const sal_Int16 nStateId ) 278 { 279 MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::SetState, 280 nStateId ); 281 aFunc( GetChild(nChild) ); 282 } 283 284 void AccessibleParaManager::SetState( const sal_Int16 nStateId ) 285 { 286 ::std::for_each( begin(), end(), 287 MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::SetState, 288 nStateId ) ); 289 } 290 291 void AccessibleParaManager::UnSetState( sal_Int32 nChild, const sal_Int16 nStateId ) 292 { 293 MemFunAdapter< const sal_Int16 > aFunc( &AccessibleEditableTextPara::UnSetState, 294 nStateId ); 295 aFunc( GetChild(nChild) ); 296 } 297 298 void AccessibleParaManager::UnSetState( const sal_Int16 nStateId ) 299 { 300 ::std::for_each( begin(), end(), 301 MemFunAdapter< const sal_Int16 >( &AccessibleEditableTextPara::UnSetState, 302 nStateId ) ); 303 } 304 305 void AccessibleParaManager::SetEditSource( SvxEditSourceAdapter* pEditSource ) 306 { 307 MemFunAdapter< SvxEditSourceAdapter* > aAdapter( &::accessibility::AccessibleEditableTextPara::SetEditSource, pEditSource ); 308 ::std::for_each( begin(), end(), aAdapter ); 309 } 310 311 // not generic yet, no arguments... 312 class AccessibleParaManager_DisposeChildren : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void > 313 { 314 public: 315 AccessibleParaManager_DisposeChildren() {} 316 void operator()( ::accessibility::AccessibleEditableTextPara& rPara ) 317 { 318 rPara.Dispose(); 319 } 320 }; 321 322 void AccessibleParaManager::Dispose() 323 { 324 AccessibleParaManager_DisposeChildren aFunctor; 325 326 ::std::for_each( begin(), end(), 327 WeakChildAdapter< AccessibleParaManager_DisposeChildren > (aFunctor) ); 328 } 329 330 // not generic yet, too many method arguments... 331 class StateChangeEvent : public ::std::unary_function< ::accessibility::AccessibleEditableTextPara&, void > 332 { 333 public: 334 typedef void return_type; 335 StateChangeEvent( const sal_Int16 nEventId, 336 const uno::Any& rNewValue, 337 const uno::Any& rOldValue ) : 338 mnEventId( nEventId ), 339 mrNewValue( rNewValue ), 340 mrOldValue( rOldValue ) {} 341 void operator()( ::accessibility::AccessibleEditableTextPara& rPara ) 342 { 343 rPara.FireEvent( mnEventId, mrNewValue, mrOldValue ); 344 } 345 346 private: 347 const sal_Int16 mnEventId; 348 const uno::Any& mrNewValue; 349 const uno::Any& mrOldValue; 350 }; 351 352 void AccessibleParaManager::FireEvent( sal_uInt32 nStartPara, 353 sal_uInt32 nEndPara, 354 const sal_Int16 nEventId, 355 const uno::Any& rNewValue, 356 const uno::Any& rOldValue ) const 357 { 358 DBG_ASSERT( maChildren.size() > nStartPara && 359 maChildren.size() >= nEndPara , "AccessibleParaManager::FireEvent: invalid index" ); 360 361 if( maChildren.size() > nStartPara && 362 maChildren.size() >= nEndPara ) 363 { 364 VectorOfChildren::const_iterator front = maChildren.begin(); 365 VectorOfChildren::const_iterator back = front; 366 367 ::std::advance( front, nStartPara ); 368 ::std::advance( back, nEndPara ); 369 370 StateChangeEvent aFunctor( nEventId, rNewValue, rOldValue ); 371 372 ::std::for_each( front, back, AccessibleParaManager::WeakChildAdapter< StateChangeEvent >( aFunctor ) ); 373 } 374 } 375 376 class ReleaseChild : public ::std::unary_function< const AccessibleParaManager::WeakChild&, AccessibleParaManager::WeakChild > 377 { 378 public: 379 AccessibleParaManager::WeakChild operator()( const AccessibleParaManager::WeakChild& rPara ) 380 { 381 AccessibleParaManager::ShutdownPara( rPara ); 382 383 // clear reference 384 return AccessibleParaManager::WeakChild(); 385 } 386 }; 387 388 void AccessibleParaManager::Release( sal_uInt32 nStartPara, sal_uInt32 nEndPara ) 389 { 390 DBG_ASSERT( maChildren.size() > nStartPara && 391 maChildren.size() >= nEndPara, "AccessibleParaManager::Release: invalid index" ); 392 393 if( maChildren.size() > nStartPara && 394 maChildren.size() >= nEndPara ) 395 { 396 VectorOfChildren::iterator front = maChildren.begin(); 397 VectorOfChildren::iterator back = front; 398 399 ::std::advance( front, nStartPara ); 400 ::std::advance( back, nEndPara ); 401 402 ::std::transform( front, back, front, ReleaseChild() ); 403 } 404 } 405 406 void AccessibleParaManager::ShutdownPara( const WeakChild& rChild ) 407 { 408 WeakPara::HardRefType aChild( rChild.first.get() ); 409 410 if( IsReferencable( aChild ) ) 411 aChild->SetEditSource( NULL ); 412 } 413 414 } 415 416 //------------------------------------------------------------------------ 417