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 #ifndef _SVX_ACCESSIBLE_PARA_MANAGER_HXX 25 #define _SVX_ACCESSIBLE_PARA_MANAGER_HXX 26 27 #include <vector> 28 #include <algorithm> 29 #include <functional> 30 #include <utility> 31 #include <tools/gen.hxx> 32 #include <com/sun/star/awt/Rectangle.hpp> 33 #include <com/sun/star/uno/Reference.hxx> 34 #include <cppuhelper/weakref.hxx> 35 #include <com/sun/star/accessibility/XAccessibleContext.hpp> 36 #include "editeng/editengdllapi.h" 37 38 class SvxEditSourceAdapter; 39 40 namespace accessibility 41 { 42 class AccessibleEditableTextPara; 43 44 /** Helper class for WeakCppRef 45 46 This class is returned by WeakChild::get() and contains a hard 47 reference and a reference to the c++ object. This combination 48 prevents the c++ object from destruction during usage. Hold 49 this object only as long as absolutely necessary, prevents 50 referenced object from vanishing otherwise 51 */ 52 template < class UnoType, class CppType > class HardCppRef 53 { 54 public: 55 56 typedef UnoType UnoInterfaceType; 57 typedef CppType InterfaceType; 58 HardCppRef(const::com::sun::star::uno::WeakReference<UnoInterfaceType> & xRef,InterfaceType * rImpl)59 HardCppRef( const ::com::sun::star::uno::WeakReference< UnoInterfaceType >& xRef, InterfaceType* rImpl ) : 60 mxRef( xRef ), 61 mpImpl( rImpl ) 62 { 63 } 64 65 /** Query whether the reference is still valid. 66 67 Hands off also from the implementation pointer if this 68 returns sal_False! 69 */ is() const70 sal_Bool is() const { return mxRef.is(); } operator ->() const71 InterfaceType* operator->() const { return mpImpl; } operator *() const72 InterfaceType& operator*() const { return *mpImpl; } getRef()73 ::com::sun::star::uno::Reference< UnoInterfaceType >& getRef() { return mxRef; } getRef() const74 const ::com::sun::star::uno::Reference< UnoInterfaceType >& getRef() const { return mxRef; } 75 76 // default copy constructor and assignment will do 77 // HardCppRef( const HardCppRef& ); 78 // HardCppRef& operator= ( const HardCppRef& ); 79 80 private: 81 82 // the interface, hard reference to prevent object from vanishing 83 ::com::sun::star::uno::Reference< UnoInterfaceType > mxRef; 84 85 // the c++ object, for our internal stuff 86 InterfaceType* mpImpl; 87 88 }; 89 90 /** Helper class for weak object references plus implementation 91 92 This class combines a weak reference (to facilitate automatic 93 object disposal if user drops last reference) and hard 94 reference to the c++ class (for fast access and bypassing of 95 the UNO interface) 96 */ 97 template < class UnoType, class CppType > class WeakCppRef 98 { 99 public: 100 101 typedef UnoType UnoInterfaceType; 102 typedef CppType InterfaceType; 103 typedef HardCppRef< UnoInterfaceType, InterfaceType > HardRefType; 104 WeakCppRef()105 WeakCppRef() : maWeakRef(), maUnsafeRef( NULL ) {} WeakCppRef(InterfaceType & rImpl)106 WeakCppRef( InterfaceType& rImpl ) : 107 maWeakRef( ::com::sun::star::uno::Reference< UnoInterfaceType >( rImpl, ::com::sun::star::uno::UNO_QUERY ) ), 108 maUnsafeRef( &rImpl ) 109 { 110 } 111 WeakCppRef(HardRefType & rImpl)112 WeakCppRef( HardRefType& rImpl ) : 113 maWeakRef( rImpl.getRef() ), 114 maUnsafeRef( rImpl.operator->() ) 115 { 116 } 117 118 // get object with c++ object and hard reference (which 119 // prevents the c++ object from destruction during use) get() const120 HardRefType get() const { return HardRefType( maWeakRef, maUnsafeRef ); } 121 122 // default copy constructor and assignment will do 123 // WeakCppRef( const WeakCppRef& ); 124 // WeakCppRef& operator= ( const WeakCppRef& ); 125 126 private: 127 128 // the interface, hold weakly 129 ::com::sun::star::uno::WeakReference< UnoInterfaceType > maWeakRef; 130 131 // hard ref to c++ class, _only_ valid if maWeakRef.is() is true 132 InterfaceType* maUnsafeRef; 133 }; 134 135 136 /** This class manages the paragraphs of an AccessibleTextHelper 137 138 To facilitate automatic deletion of paragraphs no longer used, 139 this class uses the WeakCppRef helper to hold the objects weakly. 140 */ 141 class EDITENG_DLLPUBLIC AccessibleParaManager 142 { 143 public: 144 typedef WeakCppRef < ::com::sun::star::accessibility::XAccessible, AccessibleEditableTextPara > WeakPara; 145 typedef ::std::pair< WeakPara, ::com::sun::star::awt::Rectangle > WeakChild; 146 typedef ::std::pair< ::com::sun::star::uno::Reference< 147 ::com::sun::star::accessibility::XAccessible > , ::com::sun::star::awt::Rectangle > Child; 148 typedef ::std::vector< WeakChild > VectorOfChildren; 149 typedef ::std::vector< sal_Int16 > VectorOfStates; 150 151 AccessibleParaManager(); 152 ~AccessibleParaManager(); 153 154 /** Sets a vector of additional accessible states. 155 156 The states are passed to every created child object 157 (text paragraph). The state values are defined in 158 com::sun::star::accessibility::AccessibleStateType. 159 */ 160 void SetAdditionalChildStates( const VectorOfStates& rChildStates ); 161 162 /** Returns the additional accessible states for children. 163 */ 164 const VectorOfStates& GetAdditionalChildStates() const; 165 166 /** Set the number of paragraphs 167 168 @param nNumPara 169 The total number of paragraphs the EditEngine currently 170 has (_not_ the number of currently visible children) 171 */ 172 void SetNum( sal_Int32 nNumParas ); 173 174 /** Get the number of paragraphs currently possible */ 175 sal_uInt32 GetNum() const; 176 177 // iterators 178 VectorOfChildren::iterator begin(); 179 VectorOfChildren::iterator end(); 180 VectorOfChildren::const_iterator begin() const; 181 VectorOfChildren::const_iterator end() const; 182 183 // dealing with single paragraphs (release reference, return reference etc) 184 void Release( sal_uInt32 nPara ); 185 /// Set focus to given child 186 void SetFocus( sal_Int32 nChild ); 187 188 void FireEvent( sal_uInt32 nPara, 189 const sal_Int16 nEventId, 190 const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(), 191 const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const; 192 193 static sal_Bool IsReferencable( WeakPara::HardRefType aChild ); 194 sal_Bool IsReferencable( sal_uInt32 nChild ) const; 195 static void ShutdownPara( const WeakChild& rChild ); 196 197 Child CreateChild( sal_Int32 nChild, 198 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& xFrontEnd, 199 SvxEditSourceAdapter& rEditSource, 200 sal_uInt32 nParagraphIndex ); 201 202 WeakChild GetChild( sal_uInt32 nParagraphIndex ) const; 203 204 // forwarder to all paragraphs 205 /// Make all children active and editable (or off) 206 void SetActive( sal_Bool bActive = sal_True ); 207 /// Set state of all children 208 void SetState( const sal_Int16 nStateId ); 209 /// Unset state of all children 210 void UnSetState( const sal_Int16 nStateId ); 211 /// Set offset to edit engine for all children 212 void SetEEOffset ( const Point& rOffset ); 213 /// Change edit source on all living children 214 void SetEditSource ( SvxEditSourceAdapter* pEditSource ); 215 /// Dispose all living children 216 void Dispose (); 217 218 // forwarder to given paragraphs 219 //------------------------------------------------------------------------ 220 /** Release the given range of paragraphs 221 222 All ranges have the meaning [start,end), similar to STL 223 224 @param nStartPara 225 Index of paragraph to start with releasing 226 227 @param nEndPara 228 Index of first paragraph to stop with releasing 229 */ 230 void Release( sal_uInt32 nStartPara, sal_uInt32 nEndPara ); 231 232 /** Fire event for the given range of paragraphs 233 234 All ranges have the meaning [start,end), similar to STL 235 236 @param nStartPara 237 Index of paragraph to start with event firing 238 239 @param nEndPara 240 Index of first paragraph to stop with event firing 241 */ 242 void FireEvent( sal_uInt32 nStartPara, 243 sal_uInt32 nEndPara, 244 const sal_Int16 nEventId, 245 const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(), 246 const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const; 247 248 /** Functor adapter for ForEach template 249 250 Adapts giving functor such that only the paragraph objects 251 are accessed and the fact that our children are held 252 weakly is hidden 253 254 The functor must provide the following method: 255 void operator() ( AccessibleEditablePara& ) 256 257 */ 258 template < typename Functor > class WeakChildAdapter : public ::std::unary_function< const WeakChild&, void > 259 { 260 public: WeakChildAdapter(Functor & rFunctor)261 WeakChildAdapter( Functor& rFunctor ) : mrFunctor(rFunctor) {} operator ()(const WeakChild & rPara)262 void operator()( const WeakChild& rPara ) 263 { 264 // retrieve hard reference from weak one 265 WeakPara::HardRefType aHardRef( rPara.first.get() ); 266 267 if( aHardRef.is() ) 268 mrFunctor( *aHardRef ); 269 } 270 271 private: 272 Functor& mrFunctor; 273 }; 274 275 /** Adapter for unary member functions 276 277 Since STL's binder don't work with const& arguments (and 278 BOOST's neither, at least on MSVC), have to provide our 279 own adapter for unary member functions. 280 281 Create with pointer to member function of 282 AccessibleEditableTextPara and the corresponding argument. 283 */ 284 template < typename Argument > class MemFunAdapter : public ::std::unary_function< const WeakChild&, void > 285 { 286 public: 287 typedef void (::accessibility::AccessibleEditableTextPara::*FunctionPointer)( Argument ); 288 MemFunAdapter(FunctionPointer aFunPtr,Argument aArg)289 MemFunAdapter( FunctionPointer aFunPtr, Argument aArg ) : maFunPtr(aFunPtr), maArg(aArg) {} operator ()(const WeakChild & rPara)290 void operator()( const WeakChild& rPara ) 291 { 292 // retrieve hard reference from weak one 293 WeakPara::HardRefType aHardRef( rPara.first.get() ); 294 295 if( aHardRef.is() ) 296 (*aHardRef.*maFunPtr)( maArg ); 297 } 298 299 private: 300 FunctionPointer maFunPtr; 301 Argument maArg; 302 }; 303 304 /** Generic algorithm on given paragraphs 305 306 Convenience method, that already adapts the given functor with WeakChildAdapter 307 */ ForEach(Functor & rFunctor)308 template < typename Functor > void ForEach( Functor& rFunctor ) 309 { 310 ::std::for_each( begin(), end(), WeakChildAdapter< Functor >(rFunctor) ); 311 } 312 313 private: 314 /// Set state on given child 315 void SetState( sal_Int32 nChild, const sal_Int16 nStateId ); 316 /// Unset state on given child 317 void UnSetState( sal_Int32 nChild, const sal_Int16 nStateId ); 318 /// Init child with default state (as stored in previous SetFocus and SetActive calls) 319 void InitChild( AccessibleEditableTextPara& rChild, 320 SvxEditSourceAdapter& rEditSource, 321 sal_Int32 nChild, 322 sal_uInt32 nParagraphIndex ) const; 323 324 // vector the size of the paragraph number of the underlying EditEngine 325 VectorOfChildren maChildren; 326 327 /// Additional states that will be set at every created child object. 328 VectorOfStates maChildStates; 329 330 // cache EE offset for child creation 331 Point maEEOffset; 332 333 // which child currently has the focus (-1 for none) 334 sal_Int32 mnFocusedChild; 335 336 // whether children are active and editable 337 sal_Bool mbActive; 338 }; 339 340 } // end of namespace accessibility 341 342 #endif 343 344