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 #if !defined INCLUDED_ACCESSIBILITY_TEXTWINDOWACCESSIBILITY_HXX
25 #define INCLUDED_ACCESSIBILITY_TEXTWINDOWACCESSIBILITY_HXX
26 
27 #include <toolkit/awt/vclxaccessiblecomponent.hxx>
28 #include <svl/lstner.hxx>
29 #include <svtools/textdata.hxx>
30 #include <svtools/texteng.hxx>
31 #include <svtools/textview.hxx>
32 #include <svtools/txtattr.hxx>
33 #include <com/sun/star/awt/FontWeight.hpp>
34 #include <com/sun/star/lang/EventObject.hpp>
35 #include <com/sun/star/uno/Reference.hxx>
36 #include <com/sun/star/util/Color.hpp>
37 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
38 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
39 #include <com/sun/star/accessibility/AccessibleRole.hpp>
40 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
41 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
42 #include <com/sun/star/accessibility/XAccessible.hpp>
43 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
44 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
45 #include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp>
46 #include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
47 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
48 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
49 #include <toolkit/awt/vclxwindow.hxx>
50 #include <cppuhelper/compbase7.hxx>
51 #include <comphelper/accessiblecontexthelper.hxx>
52 #include <comphelper/accessibletexthelper.hxx>
53 #include <rtl/ref.hxx>
54 
55 // IAccessible2 implementation, 2009
56 #ifndef _SVTOOLS_HRC
57 #include "svtools/svtools.hrc"
58 #endif
59 #ifndef _SVTOOLS_SVTDATA_HXX
60 #include "svtools/svtdata.hxx"
61 #endif
62 #ifndef _SV_SVAPP_HXX
63 #include <vcl/svapp.hxx>
64 #endif
65 #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_
66 #include <unotools/accessiblerelationsethelper.hxx>
67 #endif
68 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_
69 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
70 #endif
71 #include <memory>
72 #include <queue>
73 #include <hash_map>
74 
75 class TextEngine;
76 class TextView;
77 
78 namespace css = ::com::sun::star;
79 
80 namespace accessibility
81 {
82 
83 class Paragraph;
84 class Document;
85 
86 class SfxListenerGuard
87 {
88 public:
89     inline SfxListenerGuard(::SfxListener & rListener):
90         m_rListener(rListener), m_pNotifier(0) {}
91 
92     inline ~SfxListenerGuard() { endListening(); }
93 
94     // Not thread safe:
95     void startListening(::SfxBroadcaster & rNotifier);
96 
97     // Not thread safe:
98     void endListening();
99 
100 private:
101     ::SfxListener & m_rListener;
102     ::SfxBroadcaster * m_pNotifier;
103 };
104 
105 class WindowListenerGuard
106 {
107 public:
108     inline WindowListenerGuard(::Link const & rListener):
109         m_aListener(rListener), m_pNotifier(0) {}
110 
111     inline ~WindowListenerGuard() { endListening(); }
112 
113     // Not thread safe:
114     void startListening(::Window & rNotifier);
115 
116     // Not thread safe:
117     void endListening();
118 
119 private:
120     ::Link m_aListener;
121     ::Window * m_pNotifier;
122 };
123 
124 class ParagraphInfo
125 {
126 public:
127     inline ParagraphInfo(::sal_Int32 nHeight): m_nHeight(nHeight) {}
128 
129     inline
130     ::css::uno::WeakReference< ::css::accessibility::XAccessible > const &
131     getParagraph() const { return m_xParagraph; }
132 
133     inline ::sal_Int32 getHeight() const { return m_nHeight; }
134 
135     inline void setParagraph(
136         ::css::uno::Reference< ::css::accessibility::XAccessible > const &
137         rParagraph) { m_xParagraph = rParagraph; }
138 
139     inline void changeHeight(::sal_Int32 nHeight) { m_nHeight = nHeight; }
140 
141 private:
142     ::css::uno::WeakReference< ::css::accessibility::XAccessible >
143     m_xParagraph;
144     ::sal_Int32 m_nHeight;
145 };
146 
147 typedef ::std::vector< ParagraphInfo > Paragraphs;
148 
149 typedef ::cppu::WeakAggComponentImplHelper7<
150     ::css::accessibility::XAccessible,
151     ::css::accessibility::XAccessibleContext,
152     ::css::accessibility::XAccessibleComponent,
153     ::css::accessibility::XAccessibleEditableText,
154     ::css::accessibility::XAccessibleMultiLineText,
155     ::css::accessibility::XAccessibleTextAttributes,
156     ::css::accessibility::XAccessibleEventBroadcaster > ParagraphBase;
157 
158 // The Paragraph's number is the absolute position within the text engine (from
159 // 0 to N - 1), whereas the Paragraph's index is the position within the text
160 // view/accessible parent (from 0 to M - 1).  Paragraphs outside the currently
161 // visible range have an index of -1.
162 class ParagraphImpl:
163     public ParagraphBase, private ::comphelper::OCommonAccessibleText
164 {
165 public:
166     ParagraphImpl(::rtl::Reference< Document > const & rDocument,
167                   Paragraphs::size_type nNumber, ::osl::Mutex & rMutex);
168 
169     // Not thread-safe.
170     inline Paragraphs::size_type getNumber() const { return m_nNumber; }
171 
172     // Not thread-safe.
173     void numberChanged(bool bIncremented);
174 
175     // Not thread-safe.
176     void textChanged();
177 
178     // Thread-safe.
179     void notifyEvent(::sal_Int16 nEventId, ::css::uno::Any const & rOldValue,
180                      ::css::uno::Any const & rNewValue);
181 
182 protected:
183     // OCommonAccessibleText
184     virtual void implGetParagraphBoundary( ::css::i18n::Boundary& rBoundary,
185                                            ::sal_Int32 nIndex );
186     virtual void implGetLineBoundary( ::css::i18n::Boundary& rBoundary,
187                                       ::sal_Int32 nIndex );
188 
189 private:
190     virtual ::css::uno::Reference< ::css::accessibility::XAccessibleContext >
191     SAL_CALL getAccessibleContext() throw (::css::uno::RuntimeException);
192 
193     virtual ::sal_Int32 SAL_CALL getAccessibleChildCount()
194         throw (::css::uno::RuntimeException);
195 
196     virtual ::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL
197     getAccessibleChild(::sal_Int32 i)
198         throw (::css::lang::IndexOutOfBoundsException,
199                ::css::uno::RuntimeException);
200 
201     virtual ::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL
202     getAccessibleParent() throw (::css::uno::RuntimeException);
203 
204     virtual ::sal_Int32 SAL_CALL getAccessibleIndexInParent()
205         throw (::css::uno::RuntimeException);
206 
207     virtual ::sal_Int16 SAL_CALL getAccessibleRole()
208         throw (::css::uno::RuntimeException);
209 
210     virtual ::rtl::OUString SAL_CALL getAccessibleDescription()
211         throw (::css::uno::RuntimeException);
212 
213     virtual ::rtl::OUString SAL_CALL getAccessibleName()
214         throw (::css::uno::RuntimeException);
215 
216     virtual
217     ::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet >
218     SAL_CALL getAccessibleRelationSet() throw (::css::uno::RuntimeException);
219 
220     virtual
221     ::css::uno::Reference< ::css::accessibility::XAccessibleStateSet > SAL_CALL
222     getAccessibleStateSet() throw (::css::uno::RuntimeException);
223 
224     virtual ::css::lang::Locale SAL_CALL getLocale()
225         throw (::css::accessibility::IllegalAccessibleComponentStateException,
226                ::css::uno::RuntimeException);
227 
228     virtual ::sal_Bool SAL_CALL containsPoint(::css::awt::Point const & rPoint)
229         throw (::css::uno::RuntimeException);
230 
231     virtual ::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL
232     getAccessibleAtPoint(::css::awt::Point const & rPoint)
233         throw (::css::uno::RuntimeException);
234 
235     virtual ::css::awt::Rectangle SAL_CALL getBounds()
236         throw (::css::uno::RuntimeException);
237 
238     virtual ::css::awt::Point SAL_CALL getLocation()
239         throw (::css::uno::RuntimeException);
240 
241     virtual ::css::awt::Point SAL_CALL getLocationOnScreen()
242         throw (::css::uno::RuntimeException);
243 
244     virtual ::css::awt::Size SAL_CALL getSize()
245         throw (::css::uno::RuntimeException);
246 
247     virtual void SAL_CALL grabFocus() throw (::css::uno::RuntimeException);
248 
249     virtual ::css::uno::Any SAL_CALL getAccessibleKeyBinding()
250         throw (::css::uno::RuntimeException);
251 
252     virtual ::css::util::Color SAL_CALL getForeground()
253         throw (::css::uno::RuntimeException);
254 
255     virtual ::css::util::Color SAL_CALL getBackground()
256         throw (::css::uno::RuntimeException);
257 
258     virtual ::sal_Int32 SAL_CALL getCaretPosition()
259         throw (::css::uno::RuntimeException);
260 
261     virtual ::sal_Bool SAL_CALL setCaretPosition(::sal_Int32 nIndex)
262         throw (::css::lang::IndexOutOfBoundsException,
263                ::css::uno::RuntimeException);
264 
265     virtual ::sal_Unicode SAL_CALL getCharacter(::sal_Int32 nIndex)
266         throw (::css::lang::IndexOutOfBoundsException,
267                ::css::uno::RuntimeException);
268 
269     virtual ::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL
270     getCharacterAttributes(::sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes )
271         throw (::css::lang::IndexOutOfBoundsException,
272                ::css::uno::RuntimeException);
273 
274     virtual ::css::awt::Rectangle SAL_CALL
275     getCharacterBounds(::sal_Int32 nIndex)
276         throw (::css::lang::IndexOutOfBoundsException,
277                ::css::uno::RuntimeException);
278 
279     virtual ::sal_Int32 SAL_CALL getCharacterCount()
280         throw (::css::uno::RuntimeException);
281 
282     virtual ::sal_Int32 SAL_CALL
283     getIndexAtPoint(::css::awt::Point const & rPoint)
284         throw (::css::uno::RuntimeException);
285 
286     virtual ::rtl::OUString SAL_CALL getSelectedText()
287         throw (::css::uno::RuntimeException);
288 
289     virtual ::sal_Int32 SAL_CALL getSelectionStart()
290         throw (::css::uno::RuntimeException);
291 
292     virtual ::sal_Int32 SAL_CALL getSelectionEnd()
293         throw (::css::uno::RuntimeException);
294 
295     virtual ::sal_Bool SAL_CALL setSelection(::sal_Int32 nStartIndex,
296                                              ::sal_Int32 nEndIndex)
297         throw (::css::lang::IndexOutOfBoundsException,
298                ::css::uno::RuntimeException);
299 
300     virtual ::rtl::OUString SAL_CALL getText()
301         throw (::css::uno::RuntimeException);
302 
303     virtual ::rtl::OUString SAL_CALL getTextRange(::sal_Int32 nStartIndex,
304                                                   ::sal_Int32 nEndIndex)
305         throw (::css::lang::IndexOutOfBoundsException,
306                ::css::uno::RuntimeException);
307 
308     virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
309     virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
310     virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
311 
312     virtual ::sal_Bool SAL_CALL copyText(::sal_Int32 nStartIndex,
313                                          ::sal_Int32 nEndIndex)
314         throw (::css::lang::IndexOutOfBoundsException,
315                ::css::uno::RuntimeException);
316 
317     virtual ::sal_Bool SAL_CALL cutText(::sal_Int32 nStartIndex,
318                                         ::sal_Int32 nEndIndex)
319         throw (::css::lang::IndexOutOfBoundsException,
320                ::css::uno::RuntimeException);
321 
322     virtual ::sal_Bool SAL_CALL pasteText(::sal_Int32 nIndex)
323         throw (::css::lang::IndexOutOfBoundsException,
324                ::css::uno::RuntimeException);
325 
326     virtual ::sal_Bool SAL_CALL deleteText(::sal_Int32 nStartIndex,
327                                            ::sal_Int32 nEndIndex)
328         throw (::css::lang::IndexOutOfBoundsException,
329                ::css::uno::RuntimeException);
330 
331     virtual ::sal_Bool SAL_CALL insertText(::rtl::OUString const & rText,
332                                            ::sal_Int32 nIndex)
333         throw (::css::lang::IndexOutOfBoundsException,
334                ::css::uno::RuntimeException);
335 
336     virtual ::sal_Bool SAL_CALL replaceText(
337         ::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex,
338         ::rtl::OUString const & rReplacement)
339         throw (::css::lang::IndexOutOfBoundsException,
340                ::css::uno::RuntimeException);
341 
342     virtual ::sal_Bool SAL_CALL setAttributes(
343         ::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex,
344         ::css::uno::Sequence< ::css::beans::PropertyValue > const &
345         rAttributeSet)
346         throw (::css::lang::IndexOutOfBoundsException,
347                ::css::uno::RuntimeException);
348 
349     virtual ::sal_Bool SAL_CALL setText(::rtl::OUString const & rText)
350         throw (::css::uno::RuntimeException);
351 
352     virtual ::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL
353     getDefaultAttributes(const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes)
354         throw (::css::uno::RuntimeException);
355 
356     virtual ::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL
357     getRunAttributes(::sal_Int32 Index, const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes)
358         throw (::css::lang::IndexOutOfBoundsException,
359                ::css::uno::RuntimeException);
360 
361     virtual ::sal_Int32 SAL_CALL getLineNumberAtIndex( ::sal_Int32 nIndex )
362         throw (::com::sun::star::lang::IndexOutOfBoundsException,
363                ::com::sun::star::uno::RuntimeException);
364 
365     virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtLineNumber( ::sal_Int32 nLineNo )
366         throw (::com::sun::star::lang::IndexOutOfBoundsException,
367                ::com::sun::star::uno::RuntimeException);
368 
369     virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtLineWithCaret(  )
370         throw (::com::sun::star::uno::RuntimeException);
371 
372     virtual ::sal_Int32 SAL_CALL getNumberOfLineWithCaret(  )
373         throw (::com::sun::star::uno::RuntimeException);
374 
375     using cppu::WeakAggComponentImplHelperBase::addEventListener;
376     virtual void SAL_CALL addEventListener(
377         ::css::uno::Reference<
378         ::css::accessibility::XAccessibleEventListener > const & rListener)
379         throw (::css::uno::RuntimeException);
380 
381     using cppu::WeakAggComponentImplHelperBase::removeEventListener;
382     virtual void SAL_CALL removeEventListener(
383         ::css::uno::Reference<
384         ::css::accessibility::XAccessibleEventListener > const & rListener)
385         throw (::css::uno::RuntimeException);
386 
387     virtual void SAL_CALL disposing();
388 
389     virtual ::rtl::OUString implGetText();
390 
391     virtual ::css::lang::Locale implGetLocale();
392 
393     virtual void implGetSelection(::sal_Int32 & rStartIndex,
394                                   ::sal_Int32 & rEndIndex);
395 
396     // Throws ::css::lang::DisposedException:
397     void checkDisposed();
398 
399     ::rtl::Reference< Document > m_xDocument;
400     Paragraphs::size_type m_nNumber;
401 
402 //    ::cppu::OInterfaceContainerHelper m_aListeners;
403     /// client id in the AccessibleEventNotifier queue
404     sal_uInt32 m_nClientId;
405 
406     ::rtl::OUString m_aParagraphText;
407 };
408 
409 
410 typedef ::std::hash_map< ::rtl::OUString,
411                          ::css::beans::PropertyValue,
412                          ::rtl::OUStringHash,
413                          ::std::equal_to< ::rtl::OUString > > tPropValMap;
414 
415 class Document: public ::VCLXAccessibleComponent, public ::SfxListener
416 {
417 public:
418     Document(::VCLXWindow * pVclXWindow, ::TextEngine & rEngine,
419              ::TextView & rView, bool bCompoundControlChild);
420 
421     inline ::css::uno::Reference< ::css::accessibility::XAccessible >
422     getAccessible() { return m_xAccessible; }
423 
424     // Must be called only after init has been called.
425     ::css::lang::Locale retrieveLocale();
426 
427     // Must be called only after init has been called.
428     // To make it possible for this method to be (indirectly) called from
429     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
430     // still zero), pass a "ParagraphImpl const *" instead of a
431     // "::rtl::Reference< ParagraphImpl > const &".
432     ::sal_Int32 retrieveParagraphIndex(ParagraphImpl const * pParagraph);
433 
434     // Must be called only after init has been called.
435     // To make it possible for this method to be (indirectly) called from
436     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
437     // still zero), pass a "ParagraphImpl const *" instead of a
438     // "::rtl::Reference< ParagraphImpl > const &".
439     ::sal_Int64 retrieveParagraphState(ParagraphImpl const * pParagraph);
440 
441     // Must be called only after init has been called.
442     // To make it possible for this method to be (indirectly) called from
443     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
444     // still zero), pass a "ParagraphImpl const &" instead of a
445     // "::rtl::Reference< ParagraphImpl > const &".
446     ::css::awt::Rectangle
447     retrieveParagraphBounds(ParagraphImpl const * pParagraph, bool bAbsolute);
448 
449     // Must be called only after init has been called.
450     // To make it possible for this method to be (indirectly) called from
451     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
452     // still zero), pass a "ParagraphImpl const &" instead of a
453     // "::rtl::Reference< ParagraphImpl > const &".
454     ::rtl::OUString retrieveParagraphText(ParagraphImpl const * pParagraph);
455 
456     // Must be called only after init has been called.
457     // To make it possible for this method to be (indirectly) called from
458     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
459     // still zero), pass a "ParagraphImpl const &" instead of a
460     // "::rtl::Reference< ParagraphImpl > const &".
461     void retrieveParagraphSelection(ParagraphImpl const * pParagraph,
462                                     ::sal_Int32 * pBegin, ::sal_Int32 * pEnd);
463 
464     // Must be called only after init has been called.
465     // To make it possible for this method to be (indirectly) called from
466     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
467     // still zero), pass a "ParagraphImpl const *" instead of a
468     // "::rtl::Reference< ParagraphImpl > const &".
469     ::sal_Int32 retrieveParagraphCaretPosition(ParagraphImpl const * pParagraph);
470 
471     // Must be called only after init has been called.
472     // To make it possible for this method to be (indirectly) called from
473     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
474     // still zero), pass a "ParagraphImpl const &" instead of a
475     // "::rtl::Reference< ParagraphImpl > const &".
476     // Throws ::css::lang::IndexOutOfBoundsException.
477     ::css::awt::Rectangle
478     retrieveCharacterBounds(ParagraphImpl const * pParagraph,
479                             ::sal_Int32 nIndex);
480 
481     // Must be called only after init has been called.
482     // To make it possible for this method to be (indirectly) called from
483     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
484     // still zero), pass a "ParagraphImpl const &" instead of a
485     // "::rtl::Reference< ParagraphImpl > const &".
486     ::sal_Int32 retrieveCharacterIndex(ParagraphImpl const * pParagraph,
487                                        ::css::awt::Point const & rPoint);
488 
489     // Must be called only after init has been called.
490     // To make it possible for this method to be (indirectly) called from
491     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
492     // still zero), pass a "ParagraphImpl const &" instead of a
493     // "::rtl::Reference< ParagraphImpl > const &".
494     // Throws ::css::lang::IndexOutOfBoundsException.
495     ::css::uno::Sequence< ::css::beans::PropertyValue > retrieveCharacterAttributes(
496         ParagraphImpl const * pParagraph, ::sal_Int32 nIndex,
497         const ::css::uno::Sequence< ::rtl::OUString >& aRequestedAttributes);
498 
499     // Must be called only after init has been called.
500     // To make it possible for this method to be (indirectly) called from
501     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
502     // still zero), pass a "ParagraphImpl const &" instead of a
503     // "::rtl::Reference< ParagraphImpl > const &".
504     ::css::uno::Sequence< ::css::beans::PropertyValue > retrieveDefaultAttributes(
505         ParagraphImpl const * pParagraph,
506         const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes);
507 
508     // Must be called only after init has been called.
509     // To make it possible for this method to be (indirectly) called from
510     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
511     // still zero), pass a "ParagraphImpl const &" instead of a
512     // "::rtl::Reference< ParagraphImpl > const &".
513     // Throws ::css::lang::IndexOutOfBoundsException.
514     ::css::uno::Sequence< ::css::beans::PropertyValue > retrieveRunAttributes(
515         ParagraphImpl const * pParagraph, ::sal_Int32 Index,
516         const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes);
517 
518     // Must be called only after init has been called.
519     // To make it possible for this method to be (indirectly) called from
520     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
521     // still zero), pass a "ParagraphImpl const &" instead of a
522     // "::rtl::Reference< ParagraphImpl > const &".
523     void changeParagraphText(ParagraphImpl * pParagraph,
524                              ::rtl::OUString const & rText);
525 
526     // Must be called only after init has been called.
527     // To make it possible for this method to be (indirectly) called from
528     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
529     // still zero), pass a "ParagraphImpl const &" instead of a
530     // "::rtl::Reference< ParagraphImpl > const &".
531     // Throws ::css::lang::IndexOutOfBoundsException.
532     void changeParagraphText(ParagraphImpl * pParagraph, ::sal_Int32 nBegin,
533                              ::sal_Int32 nEnd, bool bCut, bool bPaste,
534                              ::rtl::OUString const & rText);
535 
536     // Must be called only after init has been called.
537     // To make it possible for this method to be (indirectly) called from
538     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
539     // still zero), pass a "ParagraphImpl const &" instead of a
540     // "::rtl::Reference< ParagraphImpl > const &".
541     // Throws ::css::lang::IndexOutOfBoundsException.
542     void copyParagraphText(ParagraphImpl const * pParagraph,
543                            ::sal_Int32 nBegin, ::sal_Int32 nEnd);
544 
545     // Must be called only after init has been called.
546     // To make it possible for this method to be (indirectly) called from
547     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
548     // still zero), pass a "ParagraphImpl const &" instead of a
549     // "::rtl::Reference< ParagraphImpl > const &".
550     // Throws ::css::lang::IndexOutOfBoundsException.
551     void changeParagraphAttributes(
552         ParagraphImpl * pParagraph, ::sal_Int32 nBegin, ::sal_Int32 nEnd,
553         ::css::uno::Sequence< ::css::beans::PropertyValue > const &
554         rAttributeSet);
555 
556     // Must be called only after init has been called.
557     // To make it possible for this method to be (indirectly) called from
558     // within Paragraph's constructor (i.e., when the Paragraph's ref count is
559     // still zero), pass a "ParagraphImpl const &" instead of a
560     // "::rtl::Reference< ParagraphImpl > const &".
561     // Throws ::css::lang::IndexOutOfBoundsException.
562     void changeParagraphSelection(ParagraphImpl * pParagraph,
563                                   ::sal_Int32 nBegin, ::sal_Int32 nEnd);
564 
565     ::css::i18n::Boundary
566     retrieveParagraphLineBoundary( ParagraphImpl const * pParagraph,
567                                    ::sal_Int32 nIndex, ::sal_Int32 *pLineNo = NULL);
568 
569     ::css::i18n::Boundary
570     retrieveParagraphBoundaryOfLine( ParagraphImpl const * pParagraph,
571                                      ::sal_Int32 nIndex );
572 
573     sal_Int32 retrieveParagraphLineWithCursor( ParagraphImpl const * pParagraph );
574 
575     ::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet >
576     retrieveParagraphRelationSet( ParagraphImpl const * pParagraph );
577 
578 protected:
579 	// window event listener from base class
580 	virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
581 
582 private:
583     virtual ::sal_Int32 SAL_CALL getAccessibleChildCount()
584         throw (::css::uno::RuntimeException);
585 
586     virtual ::css::uno::Reference< ::css::accessibility::XAccessible >
587     SAL_CALL getAccessibleChild(::sal_Int32 i)
588         throw (::css::lang::IndexOutOfBoundsException,
589                ::css::uno::RuntimeException);
590 
591     virtual ::sal_Int16 SAL_CALL getAccessibleRole()
592         throw (::css::uno::RuntimeException);
593 
594     virtual ::css::uno::Reference< ::css::accessibility::XAccessible >
595     SAL_CALL getAccessibleAtPoint(::css::awt::Point const & rPoint)
596         throw (::css::uno::RuntimeException);
597 // IAccessible2 implementation, 2009
598     virtual void	FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet );
599    virtual void	FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet );
600     // ??? Will be called with both the external (Solar) and internal mutex
601     // locked:
602     virtual void SAL_CALL disposing();
603 
604     // ??? Will be called with the external (Solar) mutex locked.
605     // init will already have been called.
606     virtual void Notify(::SfxBroadcaster & rBC, ::SfxHint const & rHint);
607 
608     // Assuming that this will only be called with the external (Solar) mutex
609     // locked.
610     // init will already have been called.
611     DECL_LINK(WindowEventHandler, VclSimpleEvent *);
612 
613     // Must be called with both the external (Solar) and internal mutex
614     // locked.
615     void init();
616 
617     // Must be called with both the external (Solar) and internal mutex
618     // locked, and after init has been called:
619     ::rtl::Reference< ParagraphImpl >
620     getParagraph(Paragraphs::iterator const & rIt);
621 
622     // Must be called with both the external (Solar) and internal mutex
623     // locked, and after init has been called.
624     // Throws ::css::uno::RuntimeException.
625     ::css::uno::Reference< ::css::accessibility::XAccessible >
626     getAccessibleChild(Paragraphs::iterator const & rIt);
627 
628     // Must be called with both the external (Solar) and internal mutex
629     // locked, and after init has been called:
630     void determineVisibleRange();
631 
632     // Must be called with both the external (Solar) and internal mutex
633     // locked, and after init has been called:
634     void notifyVisibleRangeChanges(
635         Paragraphs::iterator const & rOldVisibleBegin,
636         Paragraphs::iterator const & rOldVisibleEnd,
637         Paragraphs::iterator const & rInserted);
638 
639     // Must be called with both the external (Solar) and internal mutex
640     // locked, and after init has been called:
641     void changeParagraphText(::sal_uLong nNumber, ::sal_uInt16 nBegin, ::sal_uInt16 nEnd,
642                              bool bCut, bool bPaste,
643                              ::rtl::OUString const & rText);
644 
645     void
646     handleParagraphNotifications();
647 
648     void handleSelectionChangeNotification();
649 
650     void notifySelectionChange( sal_Int32 nFirst, sal_Int32 nLast );
651 // IAccessible2 implementation, 2009
652     ::sal_Int32 getSelectionType(::sal_Int32 nNewFirstPara, ::sal_Int32 nNewFirstPos, ::sal_Int32 nNewLastPara, ::sal_Int32 nNewLastPos);
653     void sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId);
654 
655     void justifySelection( TextPaM& rTextStart, TextPaM& rTextEnd );
656 
657     void disposeParagraphs();
658 
659     static ::css::uno::Any mapFontColor(::Color const & rColor);
660 
661     static ::Color mapFontColor(::css::uno::Any const & rColor);
662 
663     static ::css::uno::Any mapFontWeight(::FontWeight nWeight);
664 
665     static ::FontWeight mapFontWeight(::css::uno::Any const & rWeight);
666 
667     void retrieveDefaultAttributesImpl(
668         ParagraphImpl const * pParagraph,
669         const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes,
670         tPropValMap& rDefAttrSeq);
671 
672     void retrieveRunAttributesImpl(
673         ParagraphImpl const * pParagraph, ::sal_Int32 Index,
674         const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes,
675         tPropValMap& rRunAttrSeq);
676 
677     static ::css::uno::Sequence< ::css::beans::PropertyValue >
678     convertHashMapToSequence(tPropValMap& rAttrSeq);
679 
680     ::css::uno::Reference< ::css::accessibility::XAccessible > m_xAccessible;
681     ::TextEngine & m_rEngine;
682     ::TextView & m_rView;
683 
684     SfxListenerGuard m_aEngineListener;
685     WindowListenerGuard m_aViewListener;
686 
687     // All the following members have valid values only after calling init:
688 
689     ::std::auto_ptr< Paragraphs > m_xParagraphs;
690 
691     // m_nViewOffset is from the start of the document (0) to the start of the
692     // current view, and m_nViewHeight is the height of the view:
693     ::sal_Int32 m_nViewOffset;
694     ::sal_Int32 m_nViewHeight;
695 
696     // m_aVisibleBegin points to the first Paragraph that is (partially)
697     // contained in the view, and m_aVisibleEnd points past the last Paragraph
698     // that is (partially) contained.  If no Paragraphs are (partially) in the
699     // view, both m_aVisibleBegin and m_aVisibleEnd are set to
700     // m_xParagraphs->end().  These values are only changed by
701     // determineVisibleRange.
702     Paragraphs::iterator m_aVisibleBegin;
703     Paragraphs::iterator m_aVisibleEnd;
704 
705     // m_nVisibleBeginOffset is from m_nViewOffset back to the start of the
706     // Paragraph pointed to by m_aVisibleBegin (and always has a non-negative
707     // value).  If m_aVisibleBegin == m_xParagraphs->end(),
708     // m_nVisibleBeginOffset is set to 0.  These values are only changed by
709     // determineVisibleRange.
710     ::sal_Int32 m_nVisibleBeginOffset;
711 
712     // If no selection has yet been set, all the following four variables are
713     // set to -1.  m_nSelectionLastPara/Pos is also the cursor position.
714     ::sal_Int32 m_nSelectionFirstPara;
715     ::sal_Int32 m_nSelectionFirstPos;
716     ::sal_Int32 m_nSelectionLastPara;
717     ::sal_Int32 m_nSelectionLastPos;
718 
719     Paragraphs::iterator m_aFocused;
720 
721     ::std::queue< ::TextHint > m_aParagraphNotifications;
722     bool m_bSelectionChangedNotification;
723 	bool m_bCompoundControlChild;
724 };
725 
726 }
727 
728 #endif // INCLUDED_ACCESSIBILITY_TEXTWINDOWACCESSIBILITY_HXX
729