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 INCLUDED_EDITENG_ACCESSIBLEPARAMANAGER_HXX
21 : #define INCLUDED_EDITENG_ACCESSIBLEPARAMANAGER_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 798 : template < class UnoType, class CppType > class HardCppRef
49 : {
50 : public:
51 :
52 : typedef UnoType UnoInterfaceType;
53 : typedef CppType InterfaceType;
54 :
55 614 : HardCppRef( const ::com::sun::star::uno::WeakReference< UnoInterfaceType >& xRef, InterfaceType* rImpl ) :
56 : mxRef( xRef ),
57 614 : mpImpl( rImpl )
58 : {
59 614 : }
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 488 : bool is() const { return mxRef.is(); }
67 102 : InterfaceType* operator->() const { return mpImpl; }
68 89 : InterfaceType& operator*() const { return *mpImpl; }
69 126 : ::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 1184 : 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 252 : 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 52 : WeakCppRef( HardRefType& rImpl ) :
109 : maWeakRef( rImpl.getRef() ),
110 52 : maUnsafeRef( rImpl.operator->() )
111 : {
112 52 : }
113 :
114 : // get object with c++ object and hard reference (which
115 : // prevents the c++ object from destruction during use)
116 562 : 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_Int32 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 : /// Set focus to given child
176 : void SetFocus( sal_Int32 nChild );
177 :
178 : void FireEvent( sal_Int32 nPara,
179 : const sal_Int16 nEventId,
180 : const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(),
181 : const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const;
182 :
183 : static bool IsReferencable( WeakPara::HardRefType aChild );
184 : bool IsReferencable( sal_Int32 nChild ) const;
185 : static void ShutdownPara( const WeakChild& rChild );
186 :
187 : Child CreateChild( sal_Int32 nChild,
188 : const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& xFrontEnd,
189 : SvxEditSourceAdapter& rEditSource,
190 : sal_Int32 nParagraphIndex );
191 :
192 : WeakChild GetChild( sal_Int32 nParagraphIndex ) const;
193 :
194 : // forwarder to all paragraphs
195 : /// Make all children active and editable (or off)
196 : void SetActive( bool bActive = true );
197 : /// Set state of all children
198 : void SetState( const sal_Int16 nStateId );
199 : /// Unset state of all children
200 : void UnSetState( const sal_Int16 nStateId );
201 : /// Set offset to edit engine for all children
202 : void SetEEOffset ( const Point& rOffset );
203 : /// Dispose all living children
204 : void Dispose ();
205 :
206 : // forwarder to given paragraphs
207 :
208 : /** Release the given range of paragraphs
209 :
210 : All ranges have the meaning [start,end), similar to STL
211 :
212 : @param nStartPara
213 : Index of paragraph to start with releasing
214 :
215 : @param nEndPara
216 : Index of first paragraph to stop with releasing
217 : */
218 : void Release( sal_Int32 nStartPara, sal_Int32 nEndPara );
219 :
220 : /** Fire event for 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 event firing
226 :
227 : @param nEndPara
228 : Index of first paragraph to stop with event firing
229 : */
230 : void FireEvent( sal_Int32 nStartPara,
231 : sal_Int32 nEndPara,
232 : const sal_Int16 nEventId,
233 : const ::com::sun::star::uno::Any& rNewValue = ::com::sun::star::uno::Any(),
234 : const ::com::sun::star::uno::Any& rOldValue = ::com::sun::star::uno::Any() ) const;
235 :
236 : /** Functor adapter for ForEach template
237 :
238 : Adapts giving functor such that only the paragraph objects
239 : are accessed and the fact that our children are held
240 : weakly is hidden
241 :
242 : The functor must provide the following method:
243 : void operator() ( AccessibleEditablePara& )
244 :
245 : */
246 : template < typename Functor > class WeakChildAdapter : public ::std::unary_function< const WeakChild&, void >
247 : {
248 : public:
249 124 : WeakChildAdapter( Functor& rFunctor ) : mrFunctor(rFunctor) {}
250 116 : void operator()( const WeakChild& rPara )
251 : {
252 : // retrieve hard reference from weak one
253 116 : WeakPara::HardRefType aHardRef( rPara.first.get() );
254 :
255 116 : if( aHardRef.is() )
256 37 : mrFunctor( *aHardRef );
257 116 : }
258 :
259 : private:
260 : Functor& mrFunctor;
261 : };
262 :
263 : /** Adapter for unary member functions
264 :
265 : Since STL's binder don't work with const& arguments (and
266 : BOOST's neither, at least on MSVC), have to provide our
267 : own adapter for unary member functions.
268 :
269 : Create with pointer to member function of
270 : AccessibleEditableTextPara and the corresponding argument.
271 : */
272 : template < typename Argument > class MemFunAdapter : public ::std::unary_function< const WeakChild&, void >
273 : {
274 : public:
275 : typedef void (::accessibility::AccessibleEditableTextPara::*FunctionPointer)( Argument );
276 :
277 0 : MemFunAdapter( FunctionPointer aFunPtr, Argument aArg ) : maFunPtr(aFunPtr), maArg(aArg) {}
278 0 : void operator()( const WeakChild& rPara )
279 : {
280 : // retrieve hard reference from weak one
281 0 : WeakPara::HardRefType aHardRef( rPara.first.get() );
282 :
283 0 : if( aHardRef.is() )
284 0 : (*aHardRef.*maFunPtr)( maArg );
285 0 : }
286 :
287 : private:
288 : FunctionPointer maFunPtr;
289 : Argument maArg;
290 : };
291 :
292 : /** Generic algorithm on given paragraphs
293 :
294 : Convenience method, that already adapts the given functor with WeakChildAdapter
295 : */
296 : template < typename Functor > void ForEach( Functor& rFunctor )
297 : {
298 : ::std::for_each( begin(), end(), WeakChildAdapter< Functor >(rFunctor) );
299 : }
300 :
301 : private:
302 : /// Set state on given child
303 : void SetState( sal_Int32 nChild, const sal_Int16 nStateId );
304 : /// Unset state on given child
305 : void UnSetState( sal_Int32 nChild, const sal_Int16 nStateId );
306 : /// Init child with default state (as stored in previous SetFocus and SetActive calls)
307 : void InitChild( AccessibleEditableTextPara& rChild,
308 : SvxEditSourceAdapter& rEditSource,
309 : sal_Int32 nChild,
310 : sal_Int32 nParagraphIndex ) const;
311 :
312 : // vector the size of the paragraph number of the underlying EditEngine
313 : VectorOfChildren maChildren;
314 :
315 : /// Additional states that will be set at every created child object.
316 : VectorOfStates maChildStates;
317 :
318 : // cache EE offset for child creation
319 : Point maEEOffset;
320 :
321 : // which child currently has the focus (-1 for none)
322 : sal_Int32 mnFocusedChild;
323 :
324 : // whether children are active and editable
325 : bool mbActive;
326 : };
327 :
328 : } // end of namespace accessibility
329 :
330 : #endif
331 :
332 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|