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