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