10841af79SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
30841af79SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
40841af79SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
50841af79SAndrew Rist  * distributed with this work for additional information
60841af79SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
70841af79SAndrew Rist  * to you under the Apache License, Version 2.0 (the
80841af79SAndrew Rist  * "License"); you may not use this file except in compliance
90841af79SAndrew Rist  * with the License.  You may obtain a copy of the License at
100841af79SAndrew Rist  *
110841af79SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
120841af79SAndrew Rist  *
130841af79SAndrew Rist  * Unless required by applicable law or agreed to in writing,
140841af79SAndrew Rist  * software distributed under the License is distributed on an
150841af79SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
160841af79SAndrew Rist  * KIND, either express or implied.  See the License for the
170841af79SAndrew Rist  * specific language governing permissions and limitations
180841af79SAndrew Rist  * under the License.
190841af79SAndrew Rist  *
200841af79SAndrew Rist  *************************************************************/
210841af79SAndrew Rist 
220841af79SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_accessibility.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #ifndef _TOOLKIT_AWT_VCLXACCESSIBLECOMPONENT_HXX_
28cdf0e10cSrcweir #include <accessibility/extended/textwindowaccessibility.hxx>
29cdf0e10cSrcweir #endif
30cdf0e10cSrcweir #include "comphelper/accessibleeventnotifier.hxx"
31cdf0e10cSrcweir #include "unotools/accessiblerelationsethelper.hxx"
32cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
33cdf0e10cSrcweir #include <vcl/window.hxx>
34cdf0e10cSrcweir #include <toolkit/helper/convert.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <algorithm>
37cdf0e10cSrcweir #include <vector>
38cdf0e10cSrcweir #include <hash_map>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir namespace css = ::com::sun::star;
41cdf0e10cSrcweir 
42cdf0e10cSrcweir namespace accessibility
43cdf0e10cSrcweir {
4421075d77SSteve Yin     ::sal_Int32 getSelectionType(::sal_Int32 nNewFirstPara, ::sal_Int32 nNewFirstPos, ::sal_Int32 nNewLastPara, ::sal_Int32 nNewLastPos);
4521075d77SSteve Yin     void sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId);
46cdf0e10cSrcweir 
47cdf0e10cSrcweir // Both ::osl::Mutex and ParagraphBase implement acquire and release, and thus
48cdf0e10cSrcweir // ::rtl::Reference< Paragraph > does not work.  So ParagraphImpl was factored
49cdf0e10cSrcweir // out and ::rtl::Reference< ParagraphImpl > is used instead.
50cdf0e10cSrcweir class Paragraph: private ::osl::Mutex, public ParagraphImpl
51cdf0e10cSrcweir {
52cdf0e10cSrcweir public:
Paragraph(::rtl::Reference<Document> const & rDocument,Paragraphs::size_type nNumber)53cdf0e10cSrcweir     inline Paragraph(::rtl::Reference< Document > const & rDocument,
54cdf0e10cSrcweir                      Paragraphs::size_type nNumber):
55cdf0e10cSrcweir         ParagraphImpl(rDocument, nNumber, *this) {}
56cdf0e10cSrcweir };
57cdf0e10cSrcweir 
startListening(::SfxBroadcaster & rNotifier)58cdf0e10cSrcweir void SfxListenerGuard::startListening(::SfxBroadcaster & rNotifier)
59cdf0e10cSrcweir {
60cdf0e10cSrcweir     OSL_ENSURE(m_pNotifier == 0, "called more than once");
61cdf0e10cSrcweir     m_pNotifier = &rNotifier;
62cdf0e10cSrcweir     m_rListener.StartListening(*m_pNotifier, true);
63cdf0e10cSrcweir }
64cdf0e10cSrcweir 
endListening()65cdf0e10cSrcweir void SfxListenerGuard::endListening()
66cdf0e10cSrcweir {
67cdf0e10cSrcweir     if (m_pNotifier != 0)
68cdf0e10cSrcweir     {
69cdf0e10cSrcweir         m_rListener.EndListening(*m_pNotifier);
70cdf0e10cSrcweir         m_pNotifier = 0;
71cdf0e10cSrcweir     }
72cdf0e10cSrcweir }
73cdf0e10cSrcweir 
startListening(::Window & rNotifier)74cdf0e10cSrcweir void WindowListenerGuard::startListening(::Window & rNotifier)
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     OSL_ENSURE(m_pNotifier == 0, "called more than once");
77cdf0e10cSrcweir     m_pNotifier = &rNotifier;
78cdf0e10cSrcweir     m_pNotifier->AddEventListener(m_aListener);
79cdf0e10cSrcweir }
80cdf0e10cSrcweir 
endListening()81cdf0e10cSrcweir void WindowListenerGuard::endListening()
82cdf0e10cSrcweir {
83cdf0e10cSrcweir     if (m_pNotifier != 0)
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir         m_pNotifier->RemoveEventListener(m_aListener);
86cdf0e10cSrcweir         m_pNotifier = 0;
87cdf0e10cSrcweir     }
88cdf0e10cSrcweir }
89cdf0e10cSrcweir 
ParagraphImpl(::rtl::Reference<Document> const & rDocument,Paragraphs::size_type nNumber,::osl::Mutex & rMutex)90cdf0e10cSrcweir ParagraphImpl::ParagraphImpl(::rtl::Reference< Document > const & rDocument,
91cdf0e10cSrcweir                              Paragraphs::size_type nNumber,
92cdf0e10cSrcweir                              ::osl::Mutex & rMutex):
93cdf0e10cSrcweir     ParagraphBase(rMutex),
94cdf0e10cSrcweir     m_xDocument(rDocument),
95cdf0e10cSrcweir     m_nNumber(nNumber),
96cdf0e10cSrcweir     m_nClientId(0)
97cdf0e10cSrcweir {
98cdf0e10cSrcweir     m_aParagraphText = m_xDocument->retrieveParagraphText(this);
99cdf0e10cSrcweir }
100cdf0e10cSrcweir 
101cdf0e10cSrcweir void
numberChanged(bool bIncremented)102cdf0e10cSrcweir ParagraphImpl::numberChanged(bool bIncremented)
103cdf0e10cSrcweir {
104cdf0e10cSrcweir     if (bIncremented)
105cdf0e10cSrcweir         ++m_nNumber;
106cdf0e10cSrcweir     else
107cdf0e10cSrcweir         --m_nNumber;
108cdf0e10cSrcweir }
109cdf0e10cSrcweir 
textChanged()110cdf0e10cSrcweir void ParagraphImpl::textChanged()
111cdf0e10cSrcweir {
112cdf0e10cSrcweir     ::rtl::OUString aParagraphText = implGetText();
113cdf0e10cSrcweir 	::css::uno::Any aOldValue, aNewValue;
114cdf0e10cSrcweir     if ( implInitTextChangedEvent( m_aParagraphText, aParagraphText, aOldValue, aNewValue ) )
115cdf0e10cSrcweir     {
116cdf0e10cSrcweir         m_aParagraphText = aParagraphText;
117cdf0e10cSrcweir         notifyEvent(::css::accessibility::AccessibleEventId::
118cdf0e10cSrcweir                     TEXT_CHANGED,
119cdf0e10cSrcweir                     aOldValue, aNewValue);
120cdf0e10cSrcweir     }
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
notifyEvent(::sal_Int16 nEventId,::css::uno::Any const & rOldValue,::css::uno::Any const & rNewValue)123cdf0e10cSrcweir void ParagraphImpl::notifyEvent(::sal_Int16 nEventId,
124cdf0e10cSrcweir                                 ::css::uno::Any const & rOldValue,
125cdf0e10cSrcweir                                 ::css::uno::Any const & rNewValue)
126cdf0e10cSrcweir {
127cdf0e10cSrcweir 	if (m_nClientId)
128cdf0e10cSrcweir 		comphelper::AccessibleEventNotifier::addEvent( m_nClientId, ::css::accessibility::AccessibleEventObject(
129cdf0e10cSrcweir                              static_cast< ::cppu::OWeakObject * >(this),
130cdf0e10cSrcweir                              nEventId, rNewValue, rOldValue) );
131cdf0e10cSrcweir }
132cdf0e10cSrcweir 
133cdf0e10cSrcweir // virtual
134cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessibleContext > SAL_CALL
getAccessibleContext()135cdf0e10cSrcweir ParagraphImpl::getAccessibleContext() throw (::css::uno::RuntimeException)
136cdf0e10cSrcweir {
137cdf0e10cSrcweir     checkDisposed();
138cdf0e10cSrcweir     return this;
139cdf0e10cSrcweir }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir // virtual
getAccessibleChildCount()142cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getAccessibleChildCount()
143cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
144cdf0e10cSrcweir {
145cdf0e10cSrcweir     checkDisposed();
146cdf0e10cSrcweir     return 0;
147cdf0e10cSrcweir }
148cdf0e10cSrcweir 
149cdf0e10cSrcweir // virtual
150cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL
getAccessibleChild(::sal_Int32)151cdf0e10cSrcweir ParagraphImpl::getAccessibleChild(::sal_Int32)
152cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
153cdf0e10cSrcweir            ::css::uno::RuntimeException)
154cdf0e10cSrcweir {
155cdf0e10cSrcweir     checkDisposed();
156cdf0e10cSrcweir     throw ::css::lang::IndexOutOfBoundsException(
157cdf0e10cSrcweir         ::rtl::OUString(
158cdf0e10cSrcweir             RTL_CONSTASCII_USTRINGPARAM(
159cdf0e10cSrcweir                 "textwindowaccessibility.cxx:"
160cdf0e10cSrcweir                 " ParagraphImpl::getAccessibleChild")),
161cdf0e10cSrcweir         static_cast< ::css::uno::XWeak * >(this));
162cdf0e10cSrcweir }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir // virtual
165cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL
getAccessibleParent()166cdf0e10cSrcweir ParagraphImpl::getAccessibleParent()
167cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     checkDisposed();
170cdf0e10cSrcweir     return m_xDocument->getAccessible();
171cdf0e10cSrcweir }
172cdf0e10cSrcweir 
173cdf0e10cSrcweir // virtual
getAccessibleIndexInParent()174cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getAccessibleIndexInParent()
175cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
176cdf0e10cSrcweir {
177cdf0e10cSrcweir     checkDisposed();
178cdf0e10cSrcweir     return m_xDocument->retrieveParagraphIndex(this);
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir // virtual
getAccessibleRole()182cdf0e10cSrcweir ::sal_Int16 SAL_CALL ParagraphImpl::getAccessibleRole()
183cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
184cdf0e10cSrcweir {
185cdf0e10cSrcweir     checkDisposed();
186cdf0e10cSrcweir     return ::css::accessibility::AccessibleRole::PARAGRAPH;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir // virtual
getAccessibleDescription()190cdf0e10cSrcweir ::rtl::OUString SAL_CALL ParagraphImpl::getAccessibleDescription()
191cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
192cdf0e10cSrcweir {
193cdf0e10cSrcweir     checkDisposed();
194cdf0e10cSrcweir     return ::rtl::OUString();
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir // virtual
getAccessibleName()198cdf0e10cSrcweir ::rtl::OUString SAL_CALL ParagraphImpl::getAccessibleName()
199cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
200cdf0e10cSrcweir {
201cdf0e10cSrcweir     checkDisposed();
202cdf0e10cSrcweir     return ::rtl::OUString();
203cdf0e10cSrcweir }
204cdf0e10cSrcweir 
205cdf0e10cSrcweir // virtual
206cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet >
getAccessibleRelationSet()207cdf0e10cSrcweir SAL_CALL ParagraphImpl::getAccessibleRelationSet()
208cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
209cdf0e10cSrcweir {
210cdf0e10cSrcweir     checkDisposed();
211cdf0e10cSrcweir     return m_xDocument->retrieveParagraphRelationSet( this );
212cdf0e10cSrcweir }
213cdf0e10cSrcweir 
214cdf0e10cSrcweir // virtual
215cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessibleStateSet >
getAccessibleStateSet()216cdf0e10cSrcweir SAL_CALL ParagraphImpl::getAccessibleStateSet()
217cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     checkDisposed();
220cdf0e10cSrcweir 
221cdf0e10cSrcweir     // FIXME  Notification of changes (STATE_CHANGED) missing when
222cdf0e10cSrcweir     // m_rView.IsReadOnly() changes:
223cdf0e10cSrcweir     return new ::utl::AccessibleStateSetHelper(
224cdf0e10cSrcweir         m_xDocument->retrieveParagraphState(this));
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir // virtual
getLocale()228cdf0e10cSrcweir ::css::lang::Locale SAL_CALL ParagraphImpl::getLocale()
229cdf0e10cSrcweir     throw (::css::accessibility::IllegalAccessibleComponentStateException,
230cdf0e10cSrcweir            ::css::uno::RuntimeException)
231cdf0e10cSrcweir {
232cdf0e10cSrcweir     checkDisposed();
233cdf0e10cSrcweir     return m_xDocument->retrieveLocale();
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir // virtual
containsPoint(::css::awt::Point const & rPoint)237cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::containsPoint(::css::awt::Point const & rPoint)
238cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
239cdf0e10cSrcweir {
240cdf0e10cSrcweir     checkDisposed();
241cdf0e10cSrcweir     ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this,
242cdf0e10cSrcweir                                                                      false));
243cdf0e10cSrcweir     return rPoint.X >= 0 && rPoint.X < aRect.Width
244cdf0e10cSrcweir         && rPoint.Y >= 0 && rPoint.Y < aRect.Height;
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir // virtual
248cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL
getAccessibleAtPoint(::css::awt::Point const &)249cdf0e10cSrcweir ParagraphImpl::getAccessibleAtPoint(::css::awt::Point const &)
250cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
251cdf0e10cSrcweir {
252cdf0e10cSrcweir     checkDisposed();
253cdf0e10cSrcweir     return 0;
254cdf0e10cSrcweir }
255cdf0e10cSrcweir 
256cdf0e10cSrcweir // virtual
getBounds()257cdf0e10cSrcweir ::css::awt::Rectangle SAL_CALL ParagraphImpl::getBounds()
258cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
259cdf0e10cSrcweir {
260cdf0e10cSrcweir     checkDisposed();
261cdf0e10cSrcweir     return m_xDocument->retrieveParagraphBounds(this, false);
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir // virtual
getLocation()265cdf0e10cSrcweir ::css::awt::Point SAL_CALL ParagraphImpl::getLocation()
266cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
267cdf0e10cSrcweir {
268cdf0e10cSrcweir     checkDisposed();
269cdf0e10cSrcweir     ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this,
270cdf0e10cSrcweir                                                                      false));
271cdf0e10cSrcweir     return ::css::awt::Point(aRect.X, aRect.Y);
272cdf0e10cSrcweir }
273cdf0e10cSrcweir 
274cdf0e10cSrcweir // virtual
getLocationOnScreen()275cdf0e10cSrcweir ::css::awt::Point SAL_CALL ParagraphImpl::getLocationOnScreen()
276cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
277cdf0e10cSrcweir {
278cdf0e10cSrcweir     checkDisposed();
279cdf0e10cSrcweir     ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this,
280cdf0e10cSrcweir                                                                      true));
281cdf0e10cSrcweir     return ::css::awt::Point(aRect.X, aRect.Y);
282cdf0e10cSrcweir }
283cdf0e10cSrcweir 
284cdf0e10cSrcweir // virtual
getSize()285cdf0e10cSrcweir ::css::awt::Size SAL_CALL ParagraphImpl::getSize()
286cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
287cdf0e10cSrcweir {
288cdf0e10cSrcweir     checkDisposed();
289cdf0e10cSrcweir     ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this,
290cdf0e10cSrcweir                                                                      false));
291cdf0e10cSrcweir     return ::css::awt::Size(aRect.Width, aRect.Height);
292cdf0e10cSrcweir }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir // virtual
grabFocus()295cdf0e10cSrcweir void SAL_CALL ParagraphImpl::grabFocus() throw (::css::uno::RuntimeException)
296cdf0e10cSrcweir {
297cdf0e10cSrcweir     checkDisposed();
298cdf0e10cSrcweir     Window* pWindow = m_xDocument->GetWindow();
299cdf0e10cSrcweir     if ( pWindow )
300cdf0e10cSrcweir     {
301cdf0e10cSrcweir         pWindow->GrabFocus();
302cdf0e10cSrcweir     }
303cdf0e10cSrcweir     try
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         m_xDocument->changeParagraphSelection(this, 0, 0);
306cdf0e10cSrcweir     }
307cdf0e10cSrcweir     catch (::css::lang::IndexOutOfBoundsException & rEx)
308cdf0e10cSrcweir     {
309cdf0e10cSrcweir         OSL_TRACE(
310cdf0e10cSrcweir             "textwindowaccessibility.cxx: ParagraphImpl::grabFocus:"
311cdf0e10cSrcweir             " caught unexpected %s\n",
312cdf0e10cSrcweir             ::rtl::OUStringToOString(rEx.Message, RTL_TEXTENCODING_UTF8).
313cdf0e10cSrcweir             getStr());
314cdf0e10cSrcweir     }
315cdf0e10cSrcweir }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir // virtual
getAccessibleKeyBinding()318cdf0e10cSrcweir ::css::uno::Any SAL_CALL ParagraphImpl::getAccessibleKeyBinding()
319cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
320cdf0e10cSrcweir {
321cdf0e10cSrcweir     checkDisposed();
322cdf0e10cSrcweir     return ::css::uno::Any();
323cdf0e10cSrcweir }
324cdf0e10cSrcweir 
325cdf0e10cSrcweir // virtual
getForeground()326cdf0e10cSrcweir ::css::util::Color SAL_CALL ParagraphImpl::getForeground()
327cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
328cdf0e10cSrcweir {
329cdf0e10cSrcweir     return 0; // TODO
330cdf0e10cSrcweir }
331cdf0e10cSrcweir 
332cdf0e10cSrcweir // virtual
getBackground()333cdf0e10cSrcweir ::css::util::Color SAL_CALL ParagraphImpl::getBackground()
334cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
335cdf0e10cSrcweir {
336cdf0e10cSrcweir     return 0; // TODO
337cdf0e10cSrcweir }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir // virtual
getCaretPosition()340cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getCaretPosition()
341cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
342cdf0e10cSrcweir {
343cdf0e10cSrcweir     checkDisposed();
344cdf0e10cSrcweir     return m_xDocument->retrieveParagraphCaretPosition(this);
345cdf0e10cSrcweir }
346cdf0e10cSrcweir 
347cdf0e10cSrcweir // virtual
setCaretPosition(::sal_Int32 nIndex)348cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::setCaretPosition(::sal_Int32 nIndex)
349cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
350cdf0e10cSrcweir            ::css::uno::RuntimeException)
351cdf0e10cSrcweir {
352cdf0e10cSrcweir     checkDisposed();
353cdf0e10cSrcweir     m_xDocument->changeParagraphSelection(this, nIndex, nIndex);
354cdf0e10cSrcweir     return true;
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir // virtual
getCharacter(::sal_Int32 nIndex)358cdf0e10cSrcweir ::sal_Unicode SAL_CALL ParagraphImpl::getCharacter(::sal_Int32 nIndex)
359cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
360cdf0e10cSrcweir            ::css::uno::RuntimeException)
361cdf0e10cSrcweir {
362cdf0e10cSrcweir     checkDisposed();
363cdf0e10cSrcweir     return OCommonAccessibleText::getCharacter(nIndex);
364cdf0e10cSrcweir }
365cdf0e10cSrcweir 
366cdf0e10cSrcweir // virtual
367cdf0e10cSrcweir ::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL
getCharacterAttributes(::sal_Int32 nIndex,const::com::sun::star::uno::Sequence<::rtl::OUString> & aRequestedAttributes)368cdf0e10cSrcweir ParagraphImpl::getCharacterAttributes(::sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes)
369cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
370cdf0e10cSrcweir            ::css::uno::RuntimeException)
371cdf0e10cSrcweir {
372cdf0e10cSrcweir     checkDisposed();
373cdf0e10cSrcweir     return m_xDocument->retrieveCharacterAttributes( this, nIndex, aRequestedAttributes );
374cdf0e10cSrcweir }
375cdf0e10cSrcweir 
376cdf0e10cSrcweir // virtual
377cdf0e10cSrcweir ::css::awt::Rectangle SAL_CALL
getCharacterBounds(::sal_Int32 nIndex)378cdf0e10cSrcweir ParagraphImpl::getCharacterBounds(::sal_Int32 nIndex)
379cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
380cdf0e10cSrcweir            ::css::uno::RuntimeException)
381cdf0e10cSrcweir {
382cdf0e10cSrcweir     checkDisposed();
383cdf0e10cSrcweir     ::css::awt::Rectangle aBounds(m_xDocument->retrieveCharacterBounds(this, nIndex));
384cdf0e10cSrcweir     ::css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false));
385cdf0e10cSrcweir 	aBounds.X -= aParaBounds.X;
386cdf0e10cSrcweir 	aBounds.Y -= aParaBounds.Y;
387cdf0e10cSrcweir 	return aBounds;
388cdf0e10cSrcweir }
389cdf0e10cSrcweir 
390cdf0e10cSrcweir // virtual
getCharacterCount()391cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getCharacterCount()
392cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
393cdf0e10cSrcweir {
394cdf0e10cSrcweir     checkDisposed();
395cdf0e10cSrcweir     return OCommonAccessibleText::getCharacterCount();
396cdf0e10cSrcweir }
397cdf0e10cSrcweir 
398cdf0e10cSrcweir // virtual
399cdf0e10cSrcweir ::sal_Int32 SAL_CALL
getIndexAtPoint(::css::awt::Point const & rPoint)400cdf0e10cSrcweir ParagraphImpl::getIndexAtPoint(::css::awt::Point const & rPoint)
401cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
402cdf0e10cSrcweir {
403cdf0e10cSrcweir     checkDisposed();
404cdf0e10cSrcweir 	::css::awt::Point aPoint(rPoint);
405cdf0e10cSrcweir     ::css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false));
406cdf0e10cSrcweir 	aPoint.X += aParaBounds.X;
407cdf0e10cSrcweir 	aPoint.Y += aParaBounds.Y;
408cdf0e10cSrcweir     return m_xDocument->retrieveCharacterIndex(this, aPoint);
409cdf0e10cSrcweir }
410cdf0e10cSrcweir 
411cdf0e10cSrcweir // virtual
getSelectedText()412cdf0e10cSrcweir ::rtl::OUString SAL_CALL ParagraphImpl::getSelectedText()
413cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
414cdf0e10cSrcweir {
415cdf0e10cSrcweir     checkDisposed();
416cdf0e10cSrcweir 
417cdf0e10cSrcweir     return OCommonAccessibleText::getSelectedText();
418cdf0e10cSrcweir }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir // virtual
getSelectionStart()421cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getSelectionStart()
422cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
423cdf0e10cSrcweir {
424cdf0e10cSrcweir     checkDisposed();
425cdf0e10cSrcweir     return OCommonAccessibleText::getSelectionStart();
426cdf0e10cSrcweir }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir // virtual
getSelectionEnd()429cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getSelectionEnd()
430cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
431cdf0e10cSrcweir {
432cdf0e10cSrcweir     checkDisposed();
433cdf0e10cSrcweir     return OCommonAccessibleText::getSelectionEnd();
434cdf0e10cSrcweir }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir // virtual
setSelection(::sal_Int32 nStartIndex,::sal_Int32 nEndIndex)437cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::setSelection(::sal_Int32 nStartIndex,
438cdf0e10cSrcweir                                                 ::sal_Int32 nEndIndex)
439cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
440cdf0e10cSrcweir            ::css::uno::RuntimeException)
441cdf0e10cSrcweir {
442cdf0e10cSrcweir     checkDisposed();
443cdf0e10cSrcweir     m_xDocument->changeParagraphSelection(this, nStartIndex, nEndIndex);
444cdf0e10cSrcweir     return true;
445cdf0e10cSrcweir }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir // virtual
getText()448cdf0e10cSrcweir ::rtl::OUString SAL_CALL ParagraphImpl::getText()
449cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
450cdf0e10cSrcweir {
451cdf0e10cSrcweir     checkDisposed();
452cdf0e10cSrcweir     return OCommonAccessibleText::getText();
453cdf0e10cSrcweir }
454cdf0e10cSrcweir 
455cdf0e10cSrcweir // virtual
getTextRange(::sal_Int32 nStartIndex,::sal_Int32 nEndIndex)456cdf0e10cSrcweir ::rtl::OUString SAL_CALL ParagraphImpl::getTextRange(::sal_Int32 nStartIndex,
457cdf0e10cSrcweir                                                      ::sal_Int32 nEndIndex)
458cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
459cdf0e10cSrcweir            ::css::uno::RuntimeException)
460cdf0e10cSrcweir {
461cdf0e10cSrcweir     checkDisposed();
462cdf0e10cSrcweir     return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex);
463cdf0e10cSrcweir }
464cdf0e10cSrcweir 
465cdf0e10cSrcweir // virtual
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)466cdf0e10cSrcweir ::com::sun::star::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
467cdf0e10cSrcweir {
468cdf0e10cSrcweir     checkDisposed();
469cdf0e10cSrcweir     return OCommonAccessibleText::getTextAtIndex(nIndex, aTextType);
470cdf0e10cSrcweir }
471cdf0e10cSrcweir 
472cdf0e10cSrcweir // virtual
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)473cdf0e10cSrcweir ::com::sun::star::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
474cdf0e10cSrcweir {
475cdf0e10cSrcweir     checkDisposed();
476cdf0e10cSrcweir     return OCommonAccessibleText::getTextBeforeIndex(nIndex, aTextType);
477cdf0e10cSrcweir }
478cdf0e10cSrcweir 
479cdf0e10cSrcweir // virtual
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)480cdf0e10cSrcweir ::com::sun::star::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
481cdf0e10cSrcweir {
482cdf0e10cSrcweir     checkDisposed();
483cdf0e10cSrcweir     return OCommonAccessibleText::getTextBehindIndex(nIndex, aTextType);
484cdf0e10cSrcweir }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir // virtual
copyText(::sal_Int32 nStartIndex,::sal_Int32 nEndIndex)487cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::copyText(::sal_Int32 nStartIndex,
488cdf0e10cSrcweir                                             ::sal_Int32 nEndIndex)
489cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
490cdf0e10cSrcweir            ::css::uno::RuntimeException)
491cdf0e10cSrcweir {
492cdf0e10cSrcweir     checkDisposed();
493cdf0e10cSrcweir     m_xDocument->copyParagraphText(this, nStartIndex, nEndIndex);
494cdf0e10cSrcweir     return true;
495cdf0e10cSrcweir }
496cdf0e10cSrcweir 
497cdf0e10cSrcweir // virtual
cutText(::sal_Int32 nStartIndex,::sal_Int32 nEndIndex)498cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::cutText(::sal_Int32 nStartIndex,
499cdf0e10cSrcweir                                            ::sal_Int32 nEndIndex)
500cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
501cdf0e10cSrcweir            ::css::uno::RuntimeException)
502cdf0e10cSrcweir {
503cdf0e10cSrcweir     checkDisposed();
504cdf0e10cSrcweir     m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, true, false,
505cdf0e10cSrcweir                                      ::rtl::OUString());
506cdf0e10cSrcweir     return true;
507cdf0e10cSrcweir }
508cdf0e10cSrcweir 
509cdf0e10cSrcweir // virtual
pasteText(::sal_Int32 nIndex)510cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::pasteText(::sal_Int32 nIndex)
511cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
512cdf0e10cSrcweir            ::css::uno::RuntimeException)
513cdf0e10cSrcweir {
514cdf0e10cSrcweir     checkDisposed();
515cdf0e10cSrcweir     m_xDocument->changeParagraphText(this, nIndex, nIndex, false, true,
516cdf0e10cSrcweir                                      ::rtl::OUString());
517cdf0e10cSrcweir     return true;
518cdf0e10cSrcweir }
519cdf0e10cSrcweir 
520cdf0e10cSrcweir // virtual
deleteText(::sal_Int32 nStartIndex,::sal_Int32 nEndIndex)521cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::deleteText(::sal_Int32 nStartIndex,
522cdf0e10cSrcweir                                           ::sal_Int32 nEndIndex)
523cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
524cdf0e10cSrcweir            ::css::uno::RuntimeException)
525cdf0e10cSrcweir {
526cdf0e10cSrcweir     checkDisposed();
527cdf0e10cSrcweir     m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false,
528cdf0e10cSrcweir                                      ::rtl::OUString());
529cdf0e10cSrcweir     return true;
530cdf0e10cSrcweir }
531cdf0e10cSrcweir 
532cdf0e10cSrcweir // virtual
insertText(::rtl::OUString const & rText,::sal_Int32 nIndex)533cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::insertText(::rtl::OUString const & rText,
534cdf0e10cSrcweir                                               ::sal_Int32 nIndex)
535cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
536cdf0e10cSrcweir            ::css::uno::RuntimeException)
537cdf0e10cSrcweir {
538cdf0e10cSrcweir     checkDisposed();
539cdf0e10cSrcweir     m_xDocument->changeParagraphText(this, nIndex, nIndex, false, false, rText);
540cdf0e10cSrcweir     return true;
541cdf0e10cSrcweir }
542cdf0e10cSrcweir 
543cdf0e10cSrcweir // virtual
544cdf0e10cSrcweir ::sal_Bool SAL_CALL
replaceText(::sal_Int32 nStartIndex,::sal_Int32 nEndIndex,::rtl::OUString const & rReplacement)545cdf0e10cSrcweir ParagraphImpl::replaceText(::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex,
546cdf0e10cSrcweir                            ::rtl::OUString const & rReplacement)
547cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
548cdf0e10cSrcweir            ::css::uno::RuntimeException)
549cdf0e10cSrcweir {
550cdf0e10cSrcweir     checkDisposed();
551cdf0e10cSrcweir     m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false,
552cdf0e10cSrcweir                                      rReplacement);
553cdf0e10cSrcweir     return true;
554cdf0e10cSrcweir }
555cdf0e10cSrcweir 
556cdf0e10cSrcweir // virtual
setAttributes(::sal_Int32 nStartIndex,::sal_Int32 nEndIndex,::css::uno::Sequence<::css::beans::PropertyValue> const & rAttributeSet)557cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::setAttributes(
558cdf0e10cSrcweir     ::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex,
559cdf0e10cSrcweir     ::css::uno::Sequence< ::css::beans::PropertyValue > const & rAttributeSet)
560cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
561cdf0e10cSrcweir            ::css::uno::RuntimeException)
562cdf0e10cSrcweir {
563cdf0e10cSrcweir     checkDisposed();
564cdf0e10cSrcweir     m_xDocument->changeParagraphAttributes(this, nStartIndex, nEndIndex,
565cdf0e10cSrcweir                                            rAttributeSet);
566cdf0e10cSrcweir     return true;
567cdf0e10cSrcweir }
568cdf0e10cSrcweir 
569cdf0e10cSrcweir // virtual
setText(::rtl::OUString const & rText)570cdf0e10cSrcweir ::sal_Bool SAL_CALL ParagraphImpl::setText(::rtl::OUString const & rText)
571cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
572cdf0e10cSrcweir {
573cdf0e10cSrcweir     checkDisposed();
574cdf0e10cSrcweir     m_xDocument->changeParagraphText(this, rText);
575cdf0e10cSrcweir     return true;
576cdf0e10cSrcweir }
577cdf0e10cSrcweir 
578cdf0e10cSrcweir // virtual
579cdf0e10cSrcweir ::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL
getDefaultAttributes(const::css::uno::Sequence<::rtl::OUString> & RequestedAttributes)580cdf0e10cSrcweir ParagraphImpl::getDefaultAttributes(const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes)
581cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
582cdf0e10cSrcweir {
583cdf0e10cSrcweir     checkDisposed();
584cdf0e10cSrcweir     return m_xDocument->retrieveDefaultAttributes( this, RequestedAttributes );
585cdf0e10cSrcweir }
586cdf0e10cSrcweir 
587cdf0e10cSrcweir // virtual
588cdf0e10cSrcweir ::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL
getRunAttributes(::sal_Int32 Index,const::css::uno::Sequence<::rtl::OUString> & RequestedAttributes)589cdf0e10cSrcweir ParagraphImpl::getRunAttributes(::sal_Int32 Index, const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes)
590cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
591cdf0e10cSrcweir            ::css::uno::RuntimeException)
592cdf0e10cSrcweir {
593cdf0e10cSrcweir     checkDisposed();
594cdf0e10cSrcweir     return m_xDocument->retrieveRunAttributes( this, Index, RequestedAttributes );
595cdf0e10cSrcweir }
596cdf0e10cSrcweir 
597cdf0e10cSrcweir // virtual
getLineNumberAtIndex(::sal_Int32 nIndex)598cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getLineNumberAtIndex( ::sal_Int32 nIndex )
599cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
600cdf0e10cSrcweir            ::css::uno::RuntimeException)
601cdf0e10cSrcweir {
602cdf0e10cSrcweir     checkDisposed();
603cdf0e10cSrcweir 
604cdf0e10cSrcweir     ::sal_Int32 nLineNo = -1;
605cdf0e10cSrcweir     ::css::i18n::Boundary aBoundary =
606cdf0e10cSrcweir         m_xDocument->retrieveParagraphLineBoundary( this, nIndex, &nLineNo );
607cdf0e10cSrcweir 
608cdf0e10cSrcweir     return nLineNo;
609cdf0e10cSrcweir }
610cdf0e10cSrcweir 
611cdf0e10cSrcweir // virtual
getTextAtLineNumber(::sal_Int32 nLineNo)612cdf0e10cSrcweir ::css::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextAtLineNumber( ::sal_Int32 nLineNo )
613cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
614cdf0e10cSrcweir            ::css::uno::RuntimeException)
615cdf0e10cSrcweir {
616cdf0e10cSrcweir     checkDisposed();
617cdf0e10cSrcweir 
618cdf0e10cSrcweir     ::css::i18n::Boundary aBoundary =
619cdf0e10cSrcweir         m_xDocument->retrieveParagraphBoundaryOfLine( this, nLineNo );
620cdf0e10cSrcweir 
621cdf0e10cSrcweir     return ::css::accessibility::TextSegment( getTextRange(aBoundary.startPos, aBoundary.endPos),
622cdf0e10cSrcweir         aBoundary.startPos, aBoundary.endPos);
623cdf0e10cSrcweir }
624cdf0e10cSrcweir 
625cdf0e10cSrcweir // virtual
getTextAtLineWithCaret()626cdf0e10cSrcweir ::css::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextAtLineWithCaret(  )
627cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
628cdf0e10cSrcweir {
629cdf0e10cSrcweir     checkDisposed();
630cdf0e10cSrcweir 
631cdf0e10cSrcweir     sal_Int32 nLineNo = getNumberOfLineWithCaret();
632cdf0e10cSrcweir 
633cdf0e10cSrcweir     try {
634cdf0e10cSrcweir         return ( nLineNo >= 0 ) ?
635cdf0e10cSrcweir             getTextAtLineNumber( nLineNo ) :
636cdf0e10cSrcweir             ::css::accessibility::TextSegment();
637cdf0e10cSrcweir     } catch (const ::css::lang::IndexOutOfBoundsException&) {
638cdf0e10cSrcweir         throw ::css::uno::RuntimeException(
639cdf0e10cSrcweir             ::rtl::OUString(
640cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
641cdf0e10cSrcweir                     "textwindowaccessibility.cxx:"
642cdf0e10cSrcweir                     " ParagraphImpl::getTextAtLineWithCaret") ),
643cdf0e10cSrcweir             static_cast< ::css::uno::XWeak * >( this ) );
644cdf0e10cSrcweir     }
645cdf0e10cSrcweir }
646cdf0e10cSrcweir 
647cdf0e10cSrcweir // virtual
getNumberOfLineWithCaret()648cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getNumberOfLineWithCaret(  )
649cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
650cdf0e10cSrcweir {
651cdf0e10cSrcweir     checkDisposed();
652cdf0e10cSrcweir     return m_xDocument->retrieveParagraphLineWithCursor(this);
653cdf0e10cSrcweir }
654cdf0e10cSrcweir 
655cdf0e10cSrcweir 
656cdf0e10cSrcweir // virtual
addEventListener(::css::uno::Reference<::css::accessibility::XAccessibleEventListener> const & rListener)657cdf0e10cSrcweir void SAL_CALL ParagraphImpl::addEventListener(
658cdf0e10cSrcweir     ::css::uno::Reference<
659cdf0e10cSrcweir     ::css::accessibility::XAccessibleEventListener > const & rListener)
660cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
661cdf0e10cSrcweir {
662cdf0e10cSrcweir     if (rListener.is())
663cdf0e10cSrcweir     {
664cdf0e10cSrcweir         ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
665cdf0e10cSrcweir         if (rBHelper.bDisposed || rBHelper.bInDispose)
666cdf0e10cSrcweir         {
667cdf0e10cSrcweir             aGuard.clear();
668cdf0e10cSrcweir             rListener->disposing(::css::lang::EventObject(
669cdf0e10cSrcweir                                     static_cast< ::cppu::OWeakObject * >(this)));
670cdf0e10cSrcweir         }
671cdf0e10cSrcweir         else
672cdf0e10cSrcweir         {
673cdf0e10cSrcweir 			if (!m_nClientId)
674cdf0e10cSrcweir                 m_nClientId = comphelper::AccessibleEventNotifier::registerClient( );
675cdf0e10cSrcweir 			comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, rListener );
676cdf0e10cSrcweir 		}
677cdf0e10cSrcweir     }
678cdf0e10cSrcweir }
679cdf0e10cSrcweir 
680cdf0e10cSrcweir // virtual
removeEventListener(::css::uno::Reference<::css::accessibility::XAccessibleEventListener> const & rListener)681cdf0e10cSrcweir void SAL_CALL ParagraphImpl::removeEventListener(
682cdf0e10cSrcweir     ::css::uno::Reference<
683cdf0e10cSrcweir     ::css::accessibility::XAccessibleEventListener > const & rListener)
684cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
685cdf0e10cSrcweir {
686cdf0e10cSrcweir 	comphelper::AccessibleEventNotifier::TClientId nId = 0;
687cdf0e10cSrcweir 	{
688cdf0e10cSrcweir         ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
689cdf0e10cSrcweir 		if (rListener.is() && m_nClientId != 0
690cdf0e10cSrcweir 			&& comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, rListener ) == 0)
691cdf0e10cSrcweir 		{
692cdf0e10cSrcweir 			nId = m_nClientId;
693cdf0e10cSrcweir 			m_nClientId = 0;
694cdf0e10cSrcweir 		}
695cdf0e10cSrcweir 	}
696cdf0e10cSrcweir 	if (nId != 0)
697cdf0e10cSrcweir 	{
698cdf0e10cSrcweir 		// no listeners anymore
699cdf0e10cSrcweir 		// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
700cdf0e10cSrcweir 		// and at least to us not firing any events anymore, in case somebody calls
701cdf0e10cSrcweir 		// NotifyAccessibleEvent, again
702cdf0e10cSrcweir 		comphelper::AccessibleEventNotifier::revokeClient(nId);
703cdf0e10cSrcweir 	}
704cdf0e10cSrcweir }
705cdf0e10cSrcweir 
706cdf0e10cSrcweir // virtual
disposing()707cdf0e10cSrcweir void SAL_CALL ParagraphImpl::disposing()
708cdf0e10cSrcweir {
709cdf0e10cSrcweir 	comphelper::AccessibleEventNotifier::TClientId nId = 0;
710cdf0e10cSrcweir 	{
711cdf0e10cSrcweir         ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
712cdf0e10cSrcweir 		nId = m_nClientId;
713cdf0e10cSrcweir 		m_nClientId = 0;
714cdf0e10cSrcweir 	}
715cdf0e10cSrcweir 	if (nId != 0)
716cdf0e10cSrcweir         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(nId, *this);
717cdf0e10cSrcweir }
718cdf0e10cSrcweir 
719cdf0e10cSrcweir // virtual
implGetText()720cdf0e10cSrcweir ::rtl::OUString ParagraphImpl::implGetText()
721cdf0e10cSrcweir {
722cdf0e10cSrcweir     return m_xDocument->retrieveParagraphText(this);
723cdf0e10cSrcweir }
724cdf0e10cSrcweir 
725cdf0e10cSrcweir // virtual
implGetLocale()726cdf0e10cSrcweir ::css::lang::Locale ParagraphImpl::implGetLocale()
727cdf0e10cSrcweir {
728cdf0e10cSrcweir     return m_xDocument->retrieveLocale();
729cdf0e10cSrcweir }
730cdf0e10cSrcweir 
731cdf0e10cSrcweir // virtual
implGetSelection(::sal_Int32 & rStartIndex,::sal_Int32 & rEndIndex)732cdf0e10cSrcweir void ParagraphImpl::implGetSelection(::sal_Int32 & rStartIndex,
733cdf0e10cSrcweir                                      ::sal_Int32 & rEndIndex)
734cdf0e10cSrcweir {
735cdf0e10cSrcweir     m_xDocument->retrieveParagraphSelection(this, &rStartIndex, &rEndIndex);
736cdf0e10cSrcweir }
737cdf0e10cSrcweir 
738cdf0e10cSrcweir // virtual
implGetParagraphBoundary(::css::i18n::Boundary & rBoundary,::sal_Int32 nIndex)739cdf0e10cSrcweir void ParagraphImpl::implGetParagraphBoundary( ::css::i18n::Boundary& rBoundary,
740cdf0e10cSrcweir                                               ::sal_Int32 nIndex )
741cdf0e10cSrcweir {
742cdf0e10cSrcweir     ::rtl::OUString sText( implGetText() );
743cdf0e10cSrcweir     ::sal_Int32 nLength = sText.getLength();
744cdf0e10cSrcweir 
745cdf0e10cSrcweir     if ( implIsValidIndex( nIndex, nLength ) )
746cdf0e10cSrcweir     {
747cdf0e10cSrcweir         rBoundary.startPos = 0;
748cdf0e10cSrcweir         rBoundary.endPos = nLength;
749cdf0e10cSrcweir     }
750cdf0e10cSrcweir     else
751cdf0e10cSrcweir     {
752cdf0e10cSrcweir         rBoundary.startPos = nIndex;
753cdf0e10cSrcweir         rBoundary.endPos = nIndex;
754cdf0e10cSrcweir     }
755cdf0e10cSrcweir }
756cdf0e10cSrcweir 
757cdf0e10cSrcweir // virtual
implGetLineBoundary(::css::i18n::Boundary & rBoundary,::sal_Int32 nIndex)758cdf0e10cSrcweir void ParagraphImpl::implGetLineBoundary( ::css::i18n::Boundary& rBoundary,
759cdf0e10cSrcweir                                          ::sal_Int32 nIndex )
760cdf0e10cSrcweir {
761cdf0e10cSrcweir     ::rtl::OUString sText( implGetText() );
762cdf0e10cSrcweir     ::sal_Int32 nLength = sText.getLength();
763cdf0e10cSrcweir 
764cdf0e10cSrcweir     if ( implIsValidIndex( nIndex, nLength ) || nIndex == nLength )
765cdf0e10cSrcweir     {
766cdf0e10cSrcweir         ::css::i18n::Boundary aBoundary =
767cdf0e10cSrcweir             m_xDocument->retrieveParagraphLineBoundary( this, nIndex );
768cdf0e10cSrcweir         rBoundary.startPos = aBoundary.startPos;
769cdf0e10cSrcweir         rBoundary.endPos = aBoundary.endPos;
770cdf0e10cSrcweir     }
771cdf0e10cSrcweir     else
772cdf0e10cSrcweir     {
773cdf0e10cSrcweir         rBoundary.startPos = nIndex;
774cdf0e10cSrcweir         rBoundary.endPos = nIndex;
775cdf0e10cSrcweir     }
776cdf0e10cSrcweir }
777cdf0e10cSrcweir 
778cdf0e10cSrcweir 
checkDisposed()779cdf0e10cSrcweir void ParagraphImpl::checkDisposed()
780cdf0e10cSrcweir {
781cdf0e10cSrcweir     ::osl::MutexGuard aGuard(rBHelper.rMutex);
782cdf0e10cSrcweir     if (!(rBHelper.bDisposed || rBHelper.bInDispose))
783cdf0e10cSrcweir         return;
784cdf0e10cSrcweir     throw ::css::lang::DisposedException(
785cdf0e10cSrcweir         ::rtl::OUString(), static_cast< ::css::uno::XWeak * >(this));
786cdf0e10cSrcweir }
787cdf0e10cSrcweir 
Document(::VCLXWindow * pVclXWindow,::TextEngine & rEngine,::TextView & rView,bool bCompoundControlChild)788cdf0e10cSrcweir Document::Document(::VCLXWindow * pVclXWindow, ::TextEngine & rEngine,
789cdf0e10cSrcweir                    ::TextView & rView, bool bCompoundControlChild):
790cdf0e10cSrcweir     VCLXAccessibleComponent(pVclXWindow),
791cdf0e10cSrcweir     m_xAccessible(pVclXWindow),
792cdf0e10cSrcweir     m_rEngine(rEngine),
793cdf0e10cSrcweir     m_rView(rView),
794cdf0e10cSrcweir     m_aEngineListener(*this),
795cdf0e10cSrcweir     m_aViewListener(LINK(this, Document, WindowEventHandler)),
796cdf0e10cSrcweir 	m_bCompoundControlChild(bCompoundControlChild)
797cdf0e10cSrcweir {}
798cdf0e10cSrcweir 
retrieveLocale()799cdf0e10cSrcweir ::css::lang::Locale Document::retrieveLocale()
800cdf0e10cSrcweir {
801cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
802cdf0e10cSrcweir     return m_rEngine.GetLocale();
803cdf0e10cSrcweir }
804cdf0e10cSrcweir 
retrieveParagraphIndex(ParagraphImpl const * pParagraph)805cdf0e10cSrcweir ::sal_Int32 Document::retrieveParagraphIndex(ParagraphImpl const * pParagraph)
806cdf0e10cSrcweir {
807cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
808cdf0e10cSrcweir 
809cdf0e10cSrcweir     // If a client holds on to a Paragraph that is no longer visible, it can
810cdf0e10cSrcweir     // happen that this Paragraph lies outside the range from m_aVisibleBegin
811cdf0e10cSrcweir     // to m_aVisibleEnd.  In that case, return -1 instead of a valid index:
812cdf0e10cSrcweir     Paragraphs::iterator aPara(m_xParagraphs->begin()
813cdf0e10cSrcweir                                + pParagraph->getNumber());
814cdf0e10cSrcweir     return aPara < m_aVisibleBegin || aPara >= m_aVisibleEnd
815cdf0e10cSrcweir         ? -1 : static_cast< ::sal_Int32 >(aPara - m_aVisibleBegin);
816cdf0e10cSrcweir         // XXX  numeric overflow
817cdf0e10cSrcweir }
818cdf0e10cSrcweir 
retrieveParagraphState(ParagraphImpl const * pParagraph)819cdf0e10cSrcweir ::sal_Int64 Document::retrieveParagraphState(ParagraphImpl const * pParagraph)
820cdf0e10cSrcweir {
821cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
822cdf0e10cSrcweir 
823cdf0e10cSrcweir     // If a client holds on to a Paragraph that is no longer visible, it can
824cdf0e10cSrcweir     // happen that this Paragraph lies outside the range from m_aVisibleBegin
825cdf0e10cSrcweir     // to m_aVisibleEnd.  In that case, it is neither VISIBLE nor SHOWING:
826cdf0e10cSrcweir     ::sal_Int64 nState
827cdf0e10cSrcweir           = (static_cast< ::sal_Int64 >(1)
828cdf0e10cSrcweir              << ::css::accessibility::AccessibleStateType::ENABLED)
829cdf0e10cSrcweir           | (static_cast< ::sal_Int64 >(1)
830cdf0e10cSrcweir              << ::css::accessibility::AccessibleStateType::SENSITIVE)
831cdf0e10cSrcweir           | (static_cast< ::sal_Int64 >(1)
832cdf0e10cSrcweir              << ::css::accessibility::AccessibleStateType::FOCUSABLE)
833cdf0e10cSrcweir           | (static_cast< ::sal_Int64 >(1)
834cdf0e10cSrcweir              << ::css::accessibility::AccessibleStateType::MULTI_LINE);
835cdf0e10cSrcweir     if (!m_rView.IsReadOnly())
836cdf0e10cSrcweir         nState |= (static_cast< ::sal_Int64 >(1)
837cdf0e10cSrcweir                    << ::css::accessibility::AccessibleStateType::EDITABLE);
838cdf0e10cSrcweir     Paragraphs::iterator aPara(m_xParagraphs->begin()
839cdf0e10cSrcweir                                + pParagraph->getNumber());
840cdf0e10cSrcweir     if (aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd)
841cdf0e10cSrcweir     {
842cdf0e10cSrcweir         nState
843cdf0e10cSrcweir             |= (static_cast< ::sal_Int64 >(1)
844cdf0e10cSrcweir                 << ::css::accessibility::AccessibleStateType::VISIBLE)
845cdf0e10cSrcweir             | (static_cast< ::sal_Int64 >(1)
846cdf0e10cSrcweir                << ::css::accessibility::AccessibleStateType::SHOWING);
847cdf0e10cSrcweir         if (aPara == m_aFocused)
848cdf0e10cSrcweir             nState |= (static_cast< ::sal_Int64 >(1)
849cdf0e10cSrcweir                        << ::css::accessibility::AccessibleStateType::FOCUSED);
850cdf0e10cSrcweir     }
851cdf0e10cSrcweir     return nState;
852cdf0e10cSrcweir };
853cdf0e10cSrcweir 
854cdf0e10cSrcweir ::css::awt::Rectangle
retrieveParagraphBounds(ParagraphImpl const * pParagraph,bool bAbsolute)855cdf0e10cSrcweir Document::retrieveParagraphBounds(ParagraphImpl const * pParagraph,
856cdf0e10cSrcweir                                   bool bAbsolute)
857cdf0e10cSrcweir {
858cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
859cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
860cdf0e10cSrcweir 
861cdf0e10cSrcweir     // If a client holds on to a Paragraph that is no longer visible (as it
862cdf0e10cSrcweir     // scrolled out the top of the view), it can happen that this Paragraph
863cdf0e10cSrcweir     // lies before m_aVisibleBegin.  In that case, calculate the vertical
864cdf0e10cSrcweir     // position of the Paragraph starting at paragraph 0, otherwise optimize
865cdf0e10cSrcweir     // and start at m_aVisibleBegin:
866cdf0e10cSrcweir     Paragraphs::iterator aPara(m_xParagraphs->begin()
867cdf0e10cSrcweir                                + pParagraph->getNumber());
868cdf0e10cSrcweir     ::sal_Int32 nPos;
869cdf0e10cSrcweir     Paragraphs::iterator aIt;
870cdf0e10cSrcweir     if (aPara < m_aVisibleBegin)
871cdf0e10cSrcweir     {
872cdf0e10cSrcweir         nPos = 0;
873cdf0e10cSrcweir         aIt = m_xParagraphs->begin();
874cdf0e10cSrcweir     }
875cdf0e10cSrcweir     else
876cdf0e10cSrcweir     {
877cdf0e10cSrcweir         nPos = m_nViewOffset - m_nVisibleBeginOffset;
878cdf0e10cSrcweir         aIt = m_aVisibleBegin;
879cdf0e10cSrcweir     }
880cdf0e10cSrcweir     for (; aIt != aPara; ++aIt)
881cdf0e10cSrcweir         nPos += aIt->getHeight();
882cdf0e10cSrcweir 
883cdf0e10cSrcweir     Point aOrig(0, 0);
884cdf0e10cSrcweir     if (bAbsolute)
885cdf0e10cSrcweir         aOrig = m_rView.GetWindow()->OutputToAbsoluteScreenPixel(aOrig);
886cdf0e10cSrcweir 
887cdf0e10cSrcweir     return ::css::awt::Rectangle(
888cdf0e10cSrcweir         static_cast< ::sal_Int32 >(aOrig.X()),
889cdf0e10cSrcweir         static_cast< ::sal_Int32 >(aOrig.Y()) + nPos - m_nViewOffset,
890cdf0e10cSrcweir         m_rView.GetWindow()->GetOutputSizePixel().Width(), aPara->getHeight());
891cdf0e10cSrcweir         // XXX  numeric overflow (3x)
892cdf0e10cSrcweir }
893cdf0e10cSrcweir 
894cdf0e10cSrcweir ::rtl::OUString
retrieveParagraphText(ParagraphImpl const * pParagraph)895cdf0e10cSrcweir Document::retrieveParagraphText(ParagraphImpl const * pParagraph)
896cdf0e10cSrcweir {
897cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
898cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
899cdf0e10cSrcweir     return m_rEngine.GetText(static_cast< ::sal_uLong >(pParagraph->getNumber()));
900cdf0e10cSrcweir         // numeric overflow cannot happen here
901cdf0e10cSrcweir }
902cdf0e10cSrcweir 
retrieveParagraphSelection(ParagraphImpl const * pParagraph,::sal_Int32 * pBegin,::sal_Int32 * pEnd)903cdf0e10cSrcweir void Document::retrieveParagraphSelection(ParagraphImpl const * pParagraph,
904cdf0e10cSrcweir                                           ::sal_Int32 * pBegin,
905cdf0e10cSrcweir                                           ::sal_Int32 * pEnd)
906cdf0e10cSrcweir {
907cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
908cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
909cdf0e10cSrcweir     ::TextSelection const & rSelection = m_rView.GetSelection();
910cdf0e10cSrcweir     Paragraphs::size_type nNumber = pParagraph->getNumber();
911cdf0e10cSrcweir     TextPaM aStartPaM( rSelection.GetStart() );
912cdf0e10cSrcweir     TextPaM aEndPaM( rSelection.GetEnd() );
913cdf0e10cSrcweir     TextPaM aMinPaM( ::std::min( aStartPaM, aEndPaM ) );
914cdf0e10cSrcweir     TextPaM aMaxPaM( ::std::max( aStartPaM, aEndPaM ) );
915cdf0e10cSrcweir 
916cdf0e10cSrcweir     if ( nNumber >= aMinPaM.GetPara() && nNumber <= aMaxPaM.GetPara() )
917cdf0e10cSrcweir     {
918cdf0e10cSrcweir         *pBegin = nNumber > aMinPaM.GetPara()
919cdf0e10cSrcweir             ? 0
920cdf0e10cSrcweir             : static_cast< ::sal_Int32 >( aMinPaM.GetIndex() );
921cdf0e10cSrcweir             // XXX numeric overflow
922cdf0e10cSrcweir         *pEnd = nNumber < aMaxPaM.GetPara()
923cdf0e10cSrcweir             ? static_cast< ::sal_Int32 >( m_rEngine.GetText(static_cast< ::sal_uLong >(nNumber)).Len() )
924cdf0e10cSrcweir             : static_cast< ::sal_Int32 >( aMaxPaM.GetIndex() );
925cdf0e10cSrcweir             // XXX  numeric overflow (3x)
926cdf0e10cSrcweir 
927cdf0e10cSrcweir         if ( aStartPaM > aEndPaM )
928cdf0e10cSrcweir             ::std::swap( *pBegin, *pEnd );
929cdf0e10cSrcweir     }
930cdf0e10cSrcweir     else
931cdf0e10cSrcweir     {
932cdf0e10cSrcweir         *pBegin = 0;
933cdf0e10cSrcweir         *pEnd = 0;
934cdf0e10cSrcweir     }
935cdf0e10cSrcweir }
936cdf0e10cSrcweir 
retrieveParagraphCaretPosition(ParagraphImpl const * pParagraph)937cdf0e10cSrcweir ::sal_Int32 Document::retrieveParagraphCaretPosition(ParagraphImpl const * pParagraph)
938cdf0e10cSrcweir {
939cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
940cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
941cdf0e10cSrcweir     ::TextSelection const & rSelection = m_rView.GetSelection();
942cdf0e10cSrcweir     Paragraphs::size_type nNumber = pParagraph->getNumber();
943cdf0e10cSrcweir     TextPaM aEndPaM( rSelection.GetEnd() );
944cdf0e10cSrcweir 
945cdf0e10cSrcweir     return aEndPaM.GetPara() == nNumber
946cdf0e10cSrcweir         ? static_cast< ::sal_Int32 >(aEndPaM.GetIndex()) : -1;
947cdf0e10cSrcweir }
948cdf0e10cSrcweir 
949cdf0e10cSrcweir ::css::awt::Rectangle
retrieveCharacterBounds(ParagraphImpl const * pParagraph,::sal_Int32 nIndex)950cdf0e10cSrcweir Document::retrieveCharacterBounds(ParagraphImpl const * pParagraph,
951cdf0e10cSrcweir                                   ::sal_Int32 nIndex)
952cdf0e10cSrcweir {
953cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
954cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
955cdf0e10cSrcweir     ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
956cdf0e10cSrcweir     sal_Int32 nLength = m_rEngine.GetText(nNumber).Len();
957cdf0e10cSrcweir         // XXX  numeric overflow
958cdf0e10cSrcweir     if (nIndex < 0 || nIndex > nLength)
959cdf0e10cSrcweir         throw ::css::lang::IndexOutOfBoundsException(
960cdf0e10cSrcweir             ::rtl::OUString(
961cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
962cdf0e10cSrcweir                     "textwindowaccessibility.cxx:"
963cdf0e10cSrcweir                     " Document::retrieveCharacterAttributes")),
964cdf0e10cSrcweir             static_cast< ::css::uno::XWeak * >(this));
965cdf0e10cSrcweir     ::css::awt::Rectangle aBounds( 0, 0, 0, 0 );
966cdf0e10cSrcweir     if ( nIndex == nLength )
967cdf0e10cSrcweir     {
968cdf0e10cSrcweir         aBounds = AWTRectangle(
969cdf0e10cSrcweir             m_rEngine.PaMtoEditCursor(::TextPaM(nNumber,
970cdf0e10cSrcweir                                                 static_cast< ::sal_uInt16 >(nIndex))));
971cdf0e10cSrcweir     }
972cdf0e10cSrcweir     else
973cdf0e10cSrcweir     {
974cdf0e10cSrcweir         ::Rectangle aLeft(
975cdf0e10cSrcweir             m_rEngine.PaMtoEditCursor(::TextPaM(nNumber,
976cdf0e10cSrcweir                                                 static_cast< ::sal_uInt16 >(nIndex))));
977cdf0e10cSrcweir             // XXX  numeric overflow
978cdf0e10cSrcweir         ::Rectangle aRight(
979cdf0e10cSrcweir             m_rEngine.PaMtoEditCursor(::TextPaM(nNumber,
980cdf0e10cSrcweir                                                 static_cast< ::sal_uInt16 >(nIndex)
981cdf0e10cSrcweir                                                 + 1)));
982cdf0e10cSrcweir             // XXX  numeric overflow (2x)
983cdf0e10cSrcweir         // FIXME  If the vertical extends of the two cursors do not match, assume
984cdf0e10cSrcweir         // nIndex is the last character on the line; the bounding box will then
985cdf0e10cSrcweir         // extend to m_rEnginge.GetMaxTextWidth():
986cdf0e10cSrcweir         ::sal_Int32 nWidth = (aLeft.Top() == aRight.Top()
987cdf0e10cSrcweir                             && aLeft.Bottom() == aRight.Bottom())
988cdf0e10cSrcweir             ? static_cast< ::sal_Int32 >(aRight.Left() - aLeft.Left())
989cdf0e10cSrcweir             : static_cast< ::sal_Int32 >(m_rEngine.GetMaxTextWidth()
990cdf0e10cSrcweir                                         - aLeft.Left());
991cdf0e10cSrcweir             // XXX  numeric overflow (4x)
992cdf0e10cSrcweir         aBounds = ::css::awt::Rectangle(static_cast< ::sal_Int32 >(aLeft.Left()),
993cdf0e10cSrcweir                                         static_cast< ::sal_Int32 >(aLeft.Top() - m_nViewOffset),
994cdf0e10cSrcweir                                         nWidth,
995cdf0e10cSrcweir                                         static_cast< ::sal_Int32 >(aLeft.Bottom()
996cdf0e10cSrcweir                                                                     - aLeft.Top()));
997cdf0e10cSrcweir             // XXX  numeric overflow (4x)
998cdf0e10cSrcweir     }
999cdf0e10cSrcweir     return aBounds;
1000cdf0e10cSrcweir }
1001cdf0e10cSrcweir 
retrieveCharacterIndex(ParagraphImpl const * pParagraph,::css::awt::Point const & rPoint)1002cdf0e10cSrcweir ::sal_Int32 Document::retrieveCharacterIndex(ParagraphImpl const * pParagraph,
1003cdf0e10cSrcweir                                              ::css::awt::Point const & rPoint)
1004cdf0e10cSrcweir {
1005cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
1006cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
1007cdf0e10cSrcweir     ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
1008cdf0e10cSrcweir         // XXX  numeric overflow
1009cdf0e10cSrcweir     ::TextPaM aPaM(m_rEngine.GetPaM(::Point(static_cast< long >(rPoint.X),
1010cdf0e10cSrcweir                                             static_cast< long >(rPoint.Y))));
1011cdf0e10cSrcweir         // XXX  numeric overflow (2x)
1012cdf0e10cSrcweir     return aPaM.GetPara() == nNumber
1013cdf0e10cSrcweir         ? static_cast< ::sal_Int32 >(aPaM.GetIndex()) : -1;
1014cdf0e10cSrcweir         // XXX  numeric overflow
1015cdf0e10cSrcweir }
1016cdf0e10cSrcweir 
101721075d77SSteve Yin struct IndexCompare
101821075d77SSteve Yin {
101921075d77SSteve Yin 	const ::css::beans::PropertyValue* pValues;
IndexCompareaccessibility::IndexCompare102021075d77SSteve Yin 	IndexCompare( const ::css::beans::PropertyValue* pVals ) : pValues(pVals) {}
operator ()accessibility::IndexCompare102121075d77SSteve Yin 	bool operator() ( const sal_Int32& a, const sal_Int32& b ) const
102221075d77SSteve Yin 	{
102321075d77SSteve Yin 		return (pValues[a].Name < pValues[b].Name) ? true : false;
102421075d77SSteve Yin 	}
102521075d77SSteve Yin };
102621075d77SSteve Yin 
1027cdf0e10cSrcweir ::css::uno::Sequence< ::css::beans::PropertyValue >
retrieveCharacterAttributes(ParagraphImpl const * pParagraph,::sal_Int32 nIndex,const::css::uno::Sequence<::rtl::OUString> & aRequestedAttributes)1028cdf0e10cSrcweir Document::retrieveCharacterAttributes(
1029cdf0e10cSrcweir     ParagraphImpl const * pParagraph, ::sal_Int32 nIndex,
1030cdf0e10cSrcweir     const ::css::uno::Sequence< ::rtl::OUString >& aRequestedAttributes)
1031cdf0e10cSrcweir {
1032cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
103321075d77SSteve Yin 
103421075d77SSteve Yin 	Font aFont = m_rEngine.GetFont();
103521075d77SSteve Yin 	const sal_Int32 AttributeCount = 9;
103621075d77SSteve Yin 	sal_Int32 i = 0;
103721075d77SSteve Yin 	::css::uno::Sequence< ::css::beans::PropertyValue > aAttribs( AttributeCount );
103821075d77SSteve Yin 	//character background color
103921075d77SSteve Yin 	{
104021075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharBackColor"));
104121075d77SSteve Yin 		aAttribs[i].Handle = -1;
104221075d77SSteve Yin 		aAttribs[i].Value = mapFontColor( aFont.GetFillColor() );
104321075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
104421075d77SSteve Yin 		i++;
104521075d77SSteve Yin 	}
104621075d77SSteve Yin 	//character color
104721075d77SSteve Yin 	{
104821075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharColor"));
104921075d77SSteve Yin 		aAttribs[i].Handle = -1;
105021075d77SSteve Yin 		//aAttribs[i].Value = mapFontColor( aFont.GetColor() );
105121075d77SSteve Yin 		aAttribs[i].Value = mapFontColor( m_rEngine.GetTextColor() );
105221075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
105321075d77SSteve Yin 		i++;
105421075d77SSteve Yin 	}
105521075d77SSteve Yin 	//character font name
105621075d77SSteve Yin 	{
105721075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontName"));
105821075d77SSteve Yin 		aAttribs[i].Handle = -1;
105921075d77SSteve Yin 		aAttribs[i].Value = ::css::uno::makeAny( (::rtl::OUString)aFont.GetName() );
106021075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
106121075d77SSteve Yin 		i++;
106221075d77SSteve Yin 	}
106321075d77SSteve Yin 	//character height
106421075d77SSteve Yin 	{
106521075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharHeight"));
106621075d77SSteve Yin 		aAttribs[i].Handle = -1;
106721075d77SSteve Yin 		aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetHeight() );
106821075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
106921075d77SSteve Yin 		i++;
107021075d77SSteve Yin 	}
107121075d77SSteve Yin 	//character posture
107221075d77SSteve Yin 	{
107321075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharPosture"));
107421075d77SSteve Yin 		aAttribs[i].Handle = -1;
107521075d77SSteve Yin 		aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetItalic() );
107621075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
107721075d77SSteve Yin 		i++;
107821075d77SSteve Yin 	}
107921075d77SSteve Yin 	//character relief
108021075d77SSteve Yin 	/*{
108121075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharRelief"));
108221075d77SSteve Yin 		aAttribs[i].Handle = -1;
108321075d77SSteve Yin 		aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetRelief() );
108421075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
108521075d77SSteve Yin 		i++;
108621075d77SSteve Yin 	}*/
108721075d77SSteve Yin 	//character strikeout
108821075d77SSteve Yin 	{
108921075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharStrikeout"));
109021075d77SSteve Yin 		aAttribs[i].Handle = -1;
109121075d77SSteve Yin 		aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetStrikeout() );
109221075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
109321075d77SSteve Yin 		i++;
109421075d77SSteve Yin 	}
109521075d77SSteve Yin 	//character underline
109621075d77SSteve Yin 	{
109721075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderline"));
109821075d77SSteve Yin 		aAttribs[i].Handle = -1;
109921075d77SSteve Yin 		aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetUnderline() );
110021075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
110121075d77SSteve Yin 		i++;
110221075d77SSteve Yin 	}
110321075d77SSteve Yin 	//character weight
110421075d77SSteve Yin 	{
110521075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeight"));
110621075d77SSteve Yin 		aAttribs[i].Handle = -1;
110721075d77SSteve Yin 		aAttribs[i].Value = ::css::uno::makeAny( (float)aFont.GetWeight() );
110821075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
110921075d77SSteve Yin 		i++;
111021075d77SSteve Yin 	}
111121075d77SSteve Yin 	//character alignment
111221075d77SSteve Yin 	{
111321075d77SSteve Yin 		aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaAdjust"));
111421075d77SSteve Yin 		aAttribs[i].Handle = -1;
111521075d77SSteve Yin 		aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)m_rEngine.GetTextAlign() );
111621075d77SSteve Yin 		aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
111721075d77SSteve Yin 		i++;
111821075d77SSteve Yin 	}
1119cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
1120cdf0e10cSrcweir     ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
1121cdf0e10cSrcweir         // XXX  numeric overflow
112221075d77SSteve Yin 	// nIndex can be equal to Len();
112321075d77SSteve Yin     //if (nIndex < 0 || nIndex >= m_rEngine.GetText(nNumber).Len())
112421075d77SSteve Yin 	if (nIndex < 0 || nIndex > m_rEngine.GetText(nNumber).Len())
1125cdf0e10cSrcweir         throw ::css::lang::IndexOutOfBoundsException(
1126cdf0e10cSrcweir             ::rtl::OUString(
1127cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
1128cdf0e10cSrcweir                     "textwindowaccessibility.cxx:"
1129cdf0e10cSrcweir                     " Document::retrieveCharacterAttributes")),
1130cdf0e10cSrcweir             static_cast< ::css::uno::XWeak * >(this));
1131cdf0e10cSrcweir 
1132cdf0e10cSrcweir     // retrieve default attributes
1133cdf0e10cSrcweir     tPropValMap aCharAttrSeq;
1134cdf0e10cSrcweir     retrieveDefaultAttributesImpl( pParagraph, aRequestedAttributes, aCharAttrSeq );
1135cdf0e10cSrcweir 
1136cdf0e10cSrcweir     // retrieve run attributes
1137cdf0e10cSrcweir     tPropValMap aRunAttrSeq;
1138cdf0e10cSrcweir     retrieveRunAttributesImpl( pParagraph, nIndex, aRequestedAttributes, aRunAttrSeq );
1139cdf0e10cSrcweir 
1140cdf0e10cSrcweir     // merge default and run attributes
1141cdf0e10cSrcweir     for ( tPropValMap::const_iterator aRunIter  = aRunAttrSeq.begin();
1142cdf0e10cSrcweir           aRunIter != aRunAttrSeq.end();
1143cdf0e10cSrcweir           ++aRunIter )
1144cdf0e10cSrcweir     {
1145cdf0e10cSrcweir         aCharAttrSeq[ aRunIter->first ] = aRunIter->second;
1146cdf0e10cSrcweir     }
1147cdf0e10cSrcweir 
114821075d77SSteve Yin 	::css::beans::PropertyValue* pValues = aAttribs.getArray();
114921075d77SSteve Yin 	for (i = 0; i < AttributeCount; i++,pValues++)
115021075d77SSteve Yin 	{
115121075d77SSteve Yin 		aCharAttrSeq[ pValues->Name ] = *pValues;
115221075d77SSteve Yin 	}
115321075d77SSteve Yin 
115421075d77SSteve Yin     ::css::uno::Sequence< ::css::beans::PropertyValue > aRes = convertHashMapToSequence( aCharAttrSeq );
115521075d77SSteve Yin 
11560deba7fbSSteve Yin 	// sort the attributes
115721075d77SSteve Yin 	sal_Int32 nLength = aRes.getLength();
115821075d77SSteve Yin 	const ::css::beans::PropertyValue* pPairs = aRes.getConstArray();
115921075d77SSteve Yin 	sal_Int32* pIndices = new sal_Int32[nLength];
116021075d77SSteve Yin 	for( i = 0; i < nLength; i++ )
116121075d77SSteve Yin 		pIndices[i] = i;
116221075d77SSteve Yin 	std::sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) );
116321075d77SSteve Yin 	// create sorted sequences accoring to index array
116421075d77SSteve Yin 	::css::uno::Sequence< ::css::beans::PropertyValue > aNewValues( nLength );
116521075d77SSteve Yin 	::css::beans::PropertyValue* pNewValues = aNewValues.getArray();
116621075d77SSteve Yin 	for( i = 0; i < nLength; i++ )
116721075d77SSteve Yin 	{
116821075d77SSteve Yin 		pNewValues[i] = pPairs[pIndices[i]];
116921075d77SSteve Yin 	}
117021075d77SSteve Yin 	delete[] pIndices;
117121075d77SSteve Yin 
117221075d77SSteve Yin 	return aNewValues;
1173cdf0e10cSrcweir }
1174cdf0e10cSrcweir 
retrieveDefaultAttributesImpl(ParagraphImpl const * pParagraph,const::css::uno::Sequence<::rtl::OUString> & RequestedAttributes,tPropValMap & rDefAttrSeq)1175cdf0e10cSrcweir void Document::retrieveDefaultAttributesImpl(
1176cdf0e10cSrcweir     ParagraphImpl const * pParagraph,
1177cdf0e10cSrcweir     const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes,
1178cdf0e10cSrcweir     tPropValMap& rDefAttrSeq)
1179cdf0e10cSrcweir {
1180cdf0e10cSrcweir     // default attributes are not supported by text engine
1181cdf0e10cSrcweir     (void) pParagraph;
1182cdf0e10cSrcweir     (void) RequestedAttributes;
1183cdf0e10cSrcweir     (void) rDefAttrSeq;
1184cdf0e10cSrcweir }
1185cdf0e10cSrcweir 
1186cdf0e10cSrcweir ::css::uno::Sequence< ::css::beans::PropertyValue >
retrieveDefaultAttributes(ParagraphImpl const * pParagraph,const::css::uno::Sequence<::rtl::OUString> & RequestedAttributes)1187cdf0e10cSrcweir Document::retrieveDefaultAttributes(
1188cdf0e10cSrcweir     ParagraphImpl const * pParagraph,
1189cdf0e10cSrcweir     const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes)
1190cdf0e10cSrcweir {
1191cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
1192cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard( GetMutex() );
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir     tPropValMap aDefAttrSeq;
1195cdf0e10cSrcweir     retrieveDefaultAttributesImpl( pParagraph, RequestedAttributes, aDefAttrSeq );
1196cdf0e10cSrcweir     return convertHashMapToSequence( aDefAttrSeq );
1197cdf0e10cSrcweir }
1198cdf0e10cSrcweir 
1199cdf0e10cSrcweir // static
1200cdf0e10cSrcweir ::css::uno::Sequence< ::css::beans::PropertyValue >
convertHashMapToSequence(tPropValMap & rAttrSeq)1201cdf0e10cSrcweir Document::convertHashMapToSequence(tPropValMap& rAttrSeq)
1202cdf0e10cSrcweir {
1203cdf0e10cSrcweir     ::css::uno::Sequence< ::css::beans::PropertyValue > aValues( rAttrSeq.size() );
1204cdf0e10cSrcweir     ::css::beans::PropertyValue* pValues = aValues.getArray();
1205cdf0e10cSrcweir     ::sal_Int32 i = 0;
1206cdf0e10cSrcweir     for ( tPropValMap::const_iterator aIter  = rAttrSeq.begin();
1207cdf0e10cSrcweir           aIter != rAttrSeq.end();
1208cdf0e10cSrcweir           ++aIter )
1209cdf0e10cSrcweir     {
1210cdf0e10cSrcweir         pValues[i] = aIter->second;
1211cdf0e10cSrcweir         ++i;
1212cdf0e10cSrcweir     }
1213cdf0e10cSrcweir     return aValues;
1214cdf0e10cSrcweir }
1215cdf0e10cSrcweir 
retrieveRunAttributesImpl(ParagraphImpl const * pParagraph,::sal_Int32 Index,const::css::uno::Sequence<::rtl::OUString> & RequestedAttributes,tPropValMap & rRunAttrSeq)1216cdf0e10cSrcweir void Document::retrieveRunAttributesImpl(
1217cdf0e10cSrcweir     ParagraphImpl const * pParagraph, ::sal_Int32 Index,
1218cdf0e10cSrcweir     const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes,
1219cdf0e10cSrcweir     tPropValMap& rRunAttrSeq)
1220cdf0e10cSrcweir {
1221cdf0e10cSrcweir     ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
1222cdf0e10cSrcweir     ::TextPaM aPaM( nNumber, static_cast< ::sal_uInt16 >( Index ) );
1223cdf0e10cSrcweir         // XXX  numeric overflow
1224cdf0e10cSrcweir     // FIXME  TEXTATTR_HYPERLINK ignored:
1225cdf0e10cSrcweir     ::TextAttribFontColor const * pColor
1226cdf0e10cSrcweir           = static_cast< ::TextAttribFontColor const * >(
1227cdf0e10cSrcweir               m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTCOLOR ) );
1228cdf0e10cSrcweir     ::TextAttribFontWeight const * pWeight
1229cdf0e10cSrcweir           = static_cast< ::TextAttribFontWeight const * >(
1230cdf0e10cSrcweir               m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTWEIGHT ) );
1231cdf0e10cSrcweir     tPropValMap aRunAttrSeq;
1232cdf0e10cSrcweir     if ( pColor )
1233cdf0e10cSrcweir     {
1234cdf0e10cSrcweir         ::css::beans::PropertyValue aPropVal;
1235cdf0e10cSrcweir         aPropVal.Name =
1236cdf0e10cSrcweir             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) );
1237cdf0e10cSrcweir         aPropVal.Handle = -1;
1238cdf0e10cSrcweir         aPropVal.Value = mapFontColor( pColor->GetColor() );
1239cdf0e10cSrcweir         aPropVal.State = ::css::beans::PropertyState_DIRECT_VALUE;
1240cdf0e10cSrcweir         aRunAttrSeq[ aPropVal.Name ] = aPropVal;
1241cdf0e10cSrcweir     }
1242cdf0e10cSrcweir     if ( pWeight )
1243cdf0e10cSrcweir     {
1244cdf0e10cSrcweir         ::css::beans::PropertyValue aPropVal;
1245cdf0e10cSrcweir         aPropVal.Name =
1246cdf0e10cSrcweir             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) );
1247cdf0e10cSrcweir         aPropVal.Handle = -1;
1248cdf0e10cSrcweir         aPropVal.Value = mapFontWeight( pWeight->getFontWeight() );
1249cdf0e10cSrcweir         aPropVal.State = ::css::beans::PropertyState_DIRECT_VALUE;
1250cdf0e10cSrcweir         aRunAttrSeq[ aPropVal.Name ] = aPropVal;
1251cdf0e10cSrcweir     }
1252cdf0e10cSrcweir     if ( RequestedAttributes.getLength() == 0 )
1253cdf0e10cSrcweir     {
1254cdf0e10cSrcweir         rRunAttrSeq = aRunAttrSeq;
1255cdf0e10cSrcweir     }
1256cdf0e10cSrcweir     else
1257cdf0e10cSrcweir     {
1258cdf0e10cSrcweir         const ::rtl::OUString* pReqAttrs = RequestedAttributes.getConstArray();
1259cdf0e10cSrcweir         const ::sal_Int32 nLength = RequestedAttributes.getLength();
1260cdf0e10cSrcweir         for ( ::sal_Int32 i = 0; i < nLength; ++i )
1261cdf0e10cSrcweir         {
1262cdf0e10cSrcweir             tPropValMap::iterator aIter = aRunAttrSeq.find( pReqAttrs[i] );
1263cdf0e10cSrcweir             if ( aIter != aRunAttrSeq.end() )
1264cdf0e10cSrcweir             {
1265cdf0e10cSrcweir                 rRunAttrSeq[ (*aIter).first ] = (*aIter).second;
1266cdf0e10cSrcweir             }
1267cdf0e10cSrcweir         }
1268cdf0e10cSrcweir     }
1269cdf0e10cSrcweir }
1270cdf0e10cSrcweir 
1271cdf0e10cSrcweir ::css::uno::Sequence< ::css::beans::PropertyValue >
retrieveRunAttributes(ParagraphImpl const * pParagraph,::sal_Int32 Index,const::css::uno::Sequence<::rtl::OUString> & RequestedAttributes)1272cdf0e10cSrcweir Document::retrieveRunAttributes(
1273cdf0e10cSrcweir     ParagraphImpl const * pParagraph, ::sal_Int32 Index,
1274cdf0e10cSrcweir     const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes)
1275cdf0e10cSrcweir {
1276cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
1277cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard( GetMutex() );
1278cdf0e10cSrcweir     ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
1279cdf0e10cSrcweir         // XXX  numeric overflow
1280cdf0e10cSrcweir     if ( Index < 0 || Index >= m_rEngine.GetText(nNumber).Len() )
1281cdf0e10cSrcweir         throw ::css::lang::IndexOutOfBoundsException(
1282cdf0e10cSrcweir             ::rtl::OUString(
1283cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
1284cdf0e10cSrcweir                     "textwindowaccessibility.cxx:"
1285cdf0e10cSrcweir                     " Document::retrieveRunAttributes") ),
1286cdf0e10cSrcweir             static_cast< ::css::uno::XWeak * >( this ) );
1287cdf0e10cSrcweir 
1288cdf0e10cSrcweir     tPropValMap aRunAttrSeq;
1289cdf0e10cSrcweir     retrieveRunAttributesImpl( pParagraph, Index, RequestedAttributes, aRunAttrSeq );
1290cdf0e10cSrcweir     return convertHashMapToSequence( aRunAttrSeq );
1291cdf0e10cSrcweir }
1292cdf0e10cSrcweir 
changeParagraphText(ParagraphImpl * pParagraph,::rtl::OUString const & rText)1293cdf0e10cSrcweir void Document::changeParagraphText(ParagraphImpl * pParagraph,
1294cdf0e10cSrcweir                                    ::rtl::OUString const & rText)
1295cdf0e10cSrcweir {
1296cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
1297cdf0e10cSrcweir     {
1298cdf0e10cSrcweir         ::osl::MutexGuard aInternalGuard(GetMutex());
1299cdf0e10cSrcweir         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
1300cdf0e10cSrcweir             // XXX  numeric overflow
1301cdf0e10cSrcweir         changeParagraphText(nNumber, 0, m_rEngine.GetTextLen(nNumber), false,
1302cdf0e10cSrcweir                             false, rText);
1303cdf0e10cSrcweir     }
1304cdf0e10cSrcweir }
1305cdf0e10cSrcweir 
changeParagraphText(ParagraphImpl * pParagraph,::sal_Int32 nBegin,::sal_Int32 nEnd,bool bCut,bool bPaste,::rtl::OUString const & rText)1306cdf0e10cSrcweir void Document::changeParagraphText(ParagraphImpl * pParagraph,
1307cdf0e10cSrcweir                                    ::sal_Int32 nBegin, ::sal_Int32 nEnd,
1308cdf0e10cSrcweir                                    bool bCut, bool bPaste,
1309cdf0e10cSrcweir                                    ::rtl::OUString const & rText)
1310cdf0e10cSrcweir {
1311cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
1312cdf0e10cSrcweir     {
1313cdf0e10cSrcweir         ::osl::MutexGuard aInternalGuard(GetMutex());
1314cdf0e10cSrcweir         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
1315cdf0e10cSrcweir             // XXX  numeric overflow
1316cdf0e10cSrcweir         if (nBegin < 0 || nBegin > nEnd
1317cdf0e10cSrcweir             || nEnd > m_rEngine.GetText(nNumber).Len())
1318cdf0e10cSrcweir             throw ::css::lang::IndexOutOfBoundsException(
1319cdf0e10cSrcweir                 ::rtl::OUString(
1320cdf0e10cSrcweir                     RTL_CONSTASCII_USTRINGPARAM(
1321cdf0e10cSrcweir                         "textwindowaccessibility.cxx:"
1322cdf0e10cSrcweir                         " Document::changeParagraphText")),
1323cdf0e10cSrcweir                 static_cast< ::css::uno::XWeak * >(this));
1324cdf0e10cSrcweir         changeParagraphText(nNumber, static_cast< ::sal_uInt16 >(nBegin),
1325cdf0e10cSrcweir                             static_cast< ::sal_uInt16 >(nEnd), bCut, bPaste, rText);
1326cdf0e10cSrcweir             // XXX  numeric overflow (2x)
1327cdf0e10cSrcweir     }
1328cdf0e10cSrcweir }
1329cdf0e10cSrcweir 
copyParagraphText(ParagraphImpl const * pParagraph,::sal_Int32 nBegin,::sal_Int32 nEnd)1330cdf0e10cSrcweir void Document::copyParagraphText(ParagraphImpl const * pParagraph,
1331cdf0e10cSrcweir                                  ::sal_Int32 nBegin, ::sal_Int32 nEnd)
1332cdf0e10cSrcweir {
1333cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
1334cdf0e10cSrcweir     {
1335cdf0e10cSrcweir         ::osl::MutexGuard aInternalGuard(GetMutex());
1336cdf0e10cSrcweir         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
1337cdf0e10cSrcweir             // XXX  numeric overflow
1338cdf0e10cSrcweir         if (nBegin < 0 || nBegin > nEnd
1339cdf0e10cSrcweir             || nEnd > m_rEngine.GetText(nNumber).Len())
1340cdf0e10cSrcweir             throw ::css::lang::IndexOutOfBoundsException(
1341cdf0e10cSrcweir                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1342cdf0e10cSrcweir                                     "textwindowaccessibility.cxx:"
1343cdf0e10cSrcweir                                     " Document::copyParagraphText")),
1344cdf0e10cSrcweir                 static_cast< ::css::uno::XWeak * >(this));
1345cdf0e10cSrcweir         m_rView.SetSelection(
1346cdf0e10cSrcweir             ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)),
1347cdf0e10cSrcweir                             ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd))));
1348cdf0e10cSrcweir             // XXX  numeric overflow (2x)
1349cdf0e10cSrcweir         m_rView.Copy();
1350cdf0e10cSrcweir     }
1351cdf0e10cSrcweir }
1352cdf0e10cSrcweir 
changeParagraphAttributes(ParagraphImpl * pParagraph,::sal_Int32 nBegin,::sal_Int32 nEnd,::css::uno::Sequence<::css::beans::PropertyValue> const & rAttributeSet)1353cdf0e10cSrcweir void Document::changeParagraphAttributes(
1354cdf0e10cSrcweir     ParagraphImpl * pParagraph, ::sal_Int32 nBegin, ::sal_Int32 nEnd,
1355cdf0e10cSrcweir     ::css::uno::Sequence< ::css::beans::PropertyValue > const & rAttributeSet)
1356cdf0e10cSrcweir {
1357cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
1358cdf0e10cSrcweir     {
1359cdf0e10cSrcweir         ::osl::MutexGuard aInternalGuard(GetMutex());
1360cdf0e10cSrcweir         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
1361cdf0e10cSrcweir         // XXX  numeric overflow
1362cdf0e10cSrcweir         if (nBegin < 0 || nBegin > nEnd
1363cdf0e10cSrcweir             || nEnd > m_rEngine.GetText(nNumber).Len())
1364cdf0e10cSrcweir             throw ::css::lang::IndexOutOfBoundsException(
1365cdf0e10cSrcweir                 ::rtl::OUString(
1366cdf0e10cSrcweir                     RTL_CONSTASCII_USTRINGPARAM(
1367cdf0e10cSrcweir                         "textwindowaccessibility.cxx:"
1368cdf0e10cSrcweir                         " Document::changeParagraphAttributes")),
1369cdf0e10cSrcweir                 static_cast< ::css::uno::XWeak * >(this));
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir         // FIXME  The new attributes are added to any attributes already set,
1372cdf0e10cSrcweir         // they do not replace the old attributes as required by
1373cdf0e10cSrcweir         // XAccessibleEditableText.setAttributes:
1374cdf0e10cSrcweir         for (::sal_Int32 i = 0; i < rAttributeSet.getLength(); ++i)
1375cdf0e10cSrcweir             if (rAttributeSet[i].Name.equalsAsciiL(
1376cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM("CharColor")))
1377cdf0e10cSrcweir                 m_rEngine.SetAttrib(::TextAttribFontColor(
1378cdf0e10cSrcweir                                         mapFontColor(rAttributeSet[i].Value)),
1379cdf0e10cSrcweir                                     nNumber, static_cast< ::sal_uInt16 >(nBegin),
1380cdf0e10cSrcweir                                     static_cast< ::sal_uInt16 >(nEnd));
1381cdf0e10cSrcweir                     // XXX  numeric overflow (2x)
1382cdf0e10cSrcweir             else if (rAttributeSet[i].Name.equalsAsciiL(
1383cdf0e10cSrcweir                          RTL_CONSTASCII_STRINGPARAM("CharWeight")))
1384cdf0e10cSrcweir                 m_rEngine.SetAttrib(::TextAttribFontWeight(
1385cdf0e10cSrcweir                                         mapFontWeight(rAttributeSet[i].Value)),
1386cdf0e10cSrcweir                                     nNumber, static_cast< ::sal_uInt16 >(nBegin),
1387cdf0e10cSrcweir                                     static_cast< ::sal_uInt16 >(nEnd));
1388cdf0e10cSrcweir                     // XXX  numeric overflow (2x)
1389cdf0e10cSrcweir     }
1390cdf0e10cSrcweir }
1391cdf0e10cSrcweir 
changeParagraphSelection(ParagraphImpl * pParagraph,::sal_Int32 nBegin,::sal_Int32 nEnd)1392cdf0e10cSrcweir void Document::changeParagraphSelection(ParagraphImpl * pParagraph,
1393cdf0e10cSrcweir                                         ::sal_Int32 nBegin, ::sal_Int32 nEnd)
1394cdf0e10cSrcweir {
1395cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
1396cdf0e10cSrcweir     {
1397cdf0e10cSrcweir         ::osl::MutexGuard aInternalGuard(GetMutex());
1398cdf0e10cSrcweir         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
1399cdf0e10cSrcweir             // XXX  numeric overflow
1400cdf0e10cSrcweir         if (nBegin < 0 || nBegin > nEnd
1401cdf0e10cSrcweir             || nEnd > m_rEngine.GetText(nNumber).Len())
1402cdf0e10cSrcweir             throw ::css::lang::IndexOutOfBoundsException(
1403cdf0e10cSrcweir                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1404cdf0e10cSrcweir                                     "textwindowaccessibility.cxx:"
1405cdf0e10cSrcweir                                     " Document::changeParagraphSelection")),
1406cdf0e10cSrcweir                 static_cast< ::css::uno::XWeak * >(this));
1407cdf0e10cSrcweir         m_rView.SetSelection(
1408cdf0e10cSrcweir             ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)),
1409cdf0e10cSrcweir                             ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd))));
1410cdf0e10cSrcweir             // XXX  numeric overflow (2x)
1411cdf0e10cSrcweir     }
1412cdf0e10cSrcweir }
1413cdf0e10cSrcweir 
1414cdf0e10cSrcweir ::css::i18n::Boundary
retrieveParagraphLineBoundary(ParagraphImpl const * pParagraph,::sal_Int32 nIndex,::sal_Int32 * pLineNo)1415cdf0e10cSrcweir Document::retrieveParagraphLineBoundary( ParagraphImpl const * pParagraph,
1416cdf0e10cSrcweir                                          ::sal_Int32 nIndex, ::sal_Int32 *pLineNo )
1417cdf0e10cSrcweir {
1418cdf0e10cSrcweir     ::css::i18n::Boundary aBoundary;
1419cdf0e10cSrcweir     aBoundary.startPos = nIndex;
1420cdf0e10cSrcweir     aBoundary.endPos = nIndex;
1421cdf0e10cSrcweir 
1422cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
1423cdf0e10cSrcweir     {
1424cdf0e10cSrcweir         ::osl::MutexGuard aInternalGuard( GetMutex() );
1425cdf0e10cSrcweir         ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
1426cdf0e10cSrcweir         if ( nIndex < 0 || nIndex > m_rEngine.GetText( nNumber ).Len() )
1427cdf0e10cSrcweir             throw ::css::lang::IndexOutOfBoundsException(
1428cdf0e10cSrcweir                 ::rtl::OUString(
1429cdf0e10cSrcweir                     RTL_CONSTASCII_USTRINGPARAM(
1430cdf0e10cSrcweir                         "textwindowaccessibility.cxx:"
1431cdf0e10cSrcweir                         " Document::retrieveParagraphLineBoundary" ) ),
1432cdf0e10cSrcweir                 static_cast< ::css::uno::XWeak * >( this ) );
1433cdf0e10cSrcweir         ::sal_Int32 nLineStart = 0;
1434cdf0e10cSrcweir         ::sal_Int32 nLineEnd = 0;
1435cdf0e10cSrcweir         ::sal_uInt16 nLineCount = m_rEngine.GetLineCount( nNumber );
1436cdf0e10cSrcweir         for ( ::sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine )
1437cdf0e10cSrcweir         {
1438cdf0e10cSrcweir             ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >(
1439cdf0e10cSrcweir                 m_rEngine.GetLineLen( nNumber, nLine ) );
1440cdf0e10cSrcweir             nLineStart = nLineEnd;
1441cdf0e10cSrcweir             nLineEnd += nLineLength;
1442cdf0e10cSrcweir             if ( nIndex >= nLineStart && ( ( nLine == nLineCount - 1 ) ? nIndex <= nLineEnd : nIndex < nLineEnd ) )
1443cdf0e10cSrcweir             {
1444cdf0e10cSrcweir                 aBoundary.startPos = nLineStart;
1445cdf0e10cSrcweir                 aBoundary.endPos = nLineEnd;
1446cdf0e10cSrcweir                 if( pLineNo )
1447cdf0e10cSrcweir                     pLineNo[0] = nLine;
1448cdf0e10cSrcweir                 break;
1449cdf0e10cSrcweir             }
1450cdf0e10cSrcweir         }
1451cdf0e10cSrcweir     }
1452cdf0e10cSrcweir 
1453cdf0e10cSrcweir     return aBoundary;
1454cdf0e10cSrcweir }
1455cdf0e10cSrcweir 
1456cdf0e10cSrcweir ::css::i18n::Boundary
retrieveParagraphBoundaryOfLine(ParagraphImpl const * pParagraph,::sal_Int32 nLineNo)1457cdf0e10cSrcweir Document::retrieveParagraphBoundaryOfLine( ParagraphImpl const * pParagraph,
1458cdf0e10cSrcweir                                            ::sal_Int32 nLineNo )
1459cdf0e10cSrcweir {
1460cdf0e10cSrcweir     ::css::i18n::Boundary aBoundary;
1461cdf0e10cSrcweir     aBoundary.startPos = 0;
1462cdf0e10cSrcweir     aBoundary.endPos = 0;
1463cdf0e10cSrcweir 
1464cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
1465cdf0e10cSrcweir     {
1466cdf0e10cSrcweir         ::osl::MutexGuard aInternalGuard( GetMutex() );
1467cdf0e10cSrcweir         ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
1468cdf0e10cSrcweir         if ( nLineNo >= m_rEngine.GetLineCount( nNumber ) )
1469cdf0e10cSrcweir             throw ::css::lang::IndexOutOfBoundsException(
1470cdf0e10cSrcweir                 ::rtl::OUString(
1471cdf0e10cSrcweir                     RTL_CONSTASCII_USTRINGPARAM(
1472cdf0e10cSrcweir                         "textwindowaccessibility.cxx:"
1473cdf0e10cSrcweir                         " Document::retrieveParagraphBoundaryOfLine" ) ),
1474cdf0e10cSrcweir                 static_cast< ::css::uno::XWeak * >( this ) );
1475cdf0e10cSrcweir         ::sal_Int32 nLineStart = 0;
1476cdf0e10cSrcweir         ::sal_Int32 nLineEnd = 0;
1477cdf0e10cSrcweir         for ( ::sal_uInt16 nLine = 0; nLine <= nLineNo; ++nLine )
1478cdf0e10cSrcweir         {
1479cdf0e10cSrcweir             ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >(
1480cdf0e10cSrcweir                 m_rEngine.GetLineLen( nNumber, nLine ) );
1481cdf0e10cSrcweir             nLineStart = nLineEnd;
1482cdf0e10cSrcweir             nLineEnd += nLineLength;
1483cdf0e10cSrcweir         }
1484cdf0e10cSrcweir 
1485cdf0e10cSrcweir         aBoundary.startPos = nLineStart;
1486cdf0e10cSrcweir         aBoundary.endPos = nLineEnd;
1487cdf0e10cSrcweir     }
1488cdf0e10cSrcweir 
1489cdf0e10cSrcweir     return aBoundary;
1490cdf0e10cSrcweir }
1491cdf0e10cSrcweir 
retrieveParagraphLineWithCursor(ParagraphImpl const * pParagraph)1492cdf0e10cSrcweir sal_Int32 Document::retrieveParagraphLineWithCursor( ParagraphImpl const * pParagraph )
1493cdf0e10cSrcweir {
1494cdf0e10cSrcweir     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
1495cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard(GetMutex());
1496cdf0e10cSrcweir     ::TextSelection const & rSelection = m_rView.GetSelection();
1497cdf0e10cSrcweir     Paragraphs::size_type nNumber = pParagraph->getNumber();
1498cdf0e10cSrcweir     TextPaM aEndPaM( rSelection.GetEnd() );
1499cdf0e10cSrcweir 
1500cdf0e10cSrcweir     return aEndPaM.GetPara() == nNumber
1501cdf0e10cSrcweir         ? m_rView.GetLineNumberOfCursorInSelection() : -1;
1502cdf0e10cSrcweir }
1503cdf0e10cSrcweir 
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet >
retrieveParagraphRelationSet(ParagraphImpl const * pParagraph)1506cdf0e10cSrcweir Document::retrieveParagraphRelationSet( ParagraphImpl const * pParagraph )
1507cdf0e10cSrcweir {
1508cdf0e10cSrcweir     ::osl::MutexGuard aInternalGuard( GetMutex() );
1509cdf0e10cSrcweir 
1510cdf0e10cSrcweir     ::utl::AccessibleRelationSetHelper* pRelationSetHelper = new ::utl::AccessibleRelationSetHelper();
1511cdf0e10cSrcweir     ::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper;
1512cdf0e10cSrcweir 
1513cdf0e10cSrcweir     Paragraphs::iterator aPara( m_xParagraphs->begin() + pParagraph->getNumber() );
1514cdf0e10cSrcweir 
1515cdf0e10cSrcweir     if ( aPara > m_aVisibleBegin && aPara < m_aVisibleEnd )
1516cdf0e10cSrcweir     {
1517cdf0e10cSrcweir         ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > aSequence(1);
1518cdf0e10cSrcweir         aSequence[0] = getAccessibleChild( aPara - 1 );
1519cdf0e10cSrcweir         ::css::accessibility::AccessibleRelation aRelation( ::css::accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM, aSequence );
1520cdf0e10cSrcweir         pRelationSetHelper->AddRelation( aRelation );
1521cdf0e10cSrcweir     }
1522cdf0e10cSrcweir 
1523cdf0e10cSrcweir     if ( aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd -1 )
1524cdf0e10cSrcweir     {
1525cdf0e10cSrcweir         ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > aSequence(1);
1526cdf0e10cSrcweir         aSequence[0] = getAccessibleChild( aPara + 1 );
1527cdf0e10cSrcweir         ::css::accessibility::AccessibleRelation aRelation( ::css::accessibility::AccessibleRelationType::CONTENT_FLOWS_TO, aSequence );
1528cdf0e10cSrcweir         pRelationSetHelper->AddRelation( aRelation );
1529cdf0e10cSrcweir     }
1530cdf0e10cSrcweir 
1531cdf0e10cSrcweir     return xSet;
1532cdf0e10cSrcweir }
1533cdf0e10cSrcweir 
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)1534cdf0e10cSrcweir void Document::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
1535cdf0e10cSrcweir {
15363ea0c3d5SHerbert Dürr 	VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
1537cdf0e10cSrcweir }
1538cdf0e10cSrcweir 
1539cdf0e10cSrcweir // virtual
getAccessibleChildCount()1540cdf0e10cSrcweir ::sal_Int32 SAL_CALL Document::getAccessibleChildCount()
1541cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
1542cdf0e10cSrcweir {
1543cdf0e10cSrcweir     ::comphelper::OExternalLockGuard aGuard(this);
1544cdf0e10cSrcweir     init();
1545cdf0e10cSrcweir     return m_aVisibleEnd - m_aVisibleBegin;
1546cdf0e10cSrcweir }
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir // virtual
1549cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL
getAccessibleChild(::sal_Int32 i)1550cdf0e10cSrcweir Document::getAccessibleChild(::sal_Int32 i)
1551cdf0e10cSrcweir     throw (::css::lang::IndexOutOfBoundsException,
1552cdf0e10cSrcweir            ::css::uno::RuntimeException)
1553cdf0e10cSrcweir {
1554cdf0e10cSrcweir     ::comphelper::OExternalLockGuard aGuard(this);
1555cdf0e10cSrcweir     init();
1556cdf0e10cSrcweir     if (i < 0 || i >= m_aVisibleEnd - m_aVisibleBegin)
1557cdf0e10cSrcweir         throw ::css::lang::IndexOutOfBoundsException(
1558cdf0e10cSrcweir             ::rtl::OUString(
1559cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
1560cdf0e10cSrcweir                     "textwindowaccessibility.cxx:"
1561cdf0e10cSrcweir                     " Document::getAccessibleChild")),
1562cdf0e10cSrcweir             static_cast< ::css::uno::XWeak * >(this));
1563cdf0e10cSrcweir     return getAccessibleChild(m_aVisibleBegin
1564cdf0e10cSrcweir                               + static_cast< Paragraphs::size_type >(i));
1565cdf0e10cSrcweir }
1566cdf0e10cSrcweir 
1567cdf0e10cSrcweir // virtual
getAccessibleRole()1568cdf0e10cSrcweir ::sal_Int16 SAL_CALL Document::getAccessibleRole()
1569cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
1570cdf0e10cSrcweir {
1571cdf0e10cSrcweir     return ::css::accessibility::AccessibleRole::TEXT_FRAME;
1572cdf0e10cSrcweir }
1573cdf0e10cSrcweir 
1574cdf0e10cSrcweir // virtual
1575cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL
getAccessibleAtPoint(::css::awt::Point const & rPoint)1576cdf0e10cSrcweir Document::getAccessibleAtPoint(::css::awt::Point const & rPoint)
1577cdf0e10cSrcweir     throw (::css::uno::RuntimeException)
1578cdf0e10cSrcweir {
1579cdf0e10cSrcweir     ::comphelper::OExternalLockGuard aGuard(this);
1580cdf0e10cSrcweir     init();
1581cdf0e10cSrcweir     if (rPoint.X >= 0
1582cdf0e10cSrcweir         && rPoint.X < m_rView.GetWindow()->GetOutputSizePixel().Width()
1583cdf0e10cSrcweir         && rPoint.Y >= 0 && rPoint.Y < m_nViewHeight)
1584cdf0e10cSrcweir     {
1585cdf0e10cSrcweir         ::sal_Int32 nOffset = m_nViewOffset + rPoint.Y; // XXX  numeric overflow
1586cdf0e10cSrcweir         ::sal_Int32 nPos = m_nViewOffset - m_nVisibleBeginOffset;
1587cdf0e10cSrcweir         for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd;
1588cdf0e10cSrcweir              ++aIt)
1589cdf0e10cSrcweir         {
1590cdf0e10cSrcweir             nPos += aIt->getHeight(); // XXX  numeric overflow
1591cdf0e10cSrcweir             if (nOffset < nPos)
1592cdf0e10cSrcweir                 return getAccessibleChild(aIt);
1593cdf0e10cSrcweir         }
1594cdf0e10cSrcweir     }
1595cdf0e10cSrcweir     return 0;
1596cdf0e10cSrcweir }
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)159721075d77SSteve Yin void Document::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
159821075d77SSteve Yin {
159921075d77SSteve Yin 	VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
160021075d77SSteve Yin 	if (!m_rView.IsReadOnly())
160121075d77SSteve Yin 		rStateSet.AddState( ::css::accessibility::AccessibleStateType::EDITABLE );
160221075d77SSteve Yin }
1603cdf0e10cSrcweir 
FillAccessibleRelationSet(utl::AccessibleRelationSetHelper & rRelationSet)160421075d77SSteve Yin void	Document::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
160521075d77SSteve Yin {
160621075d77SSteve Yin 	if( getAccessibleParent()->getAccessibleContext()->getAccessibleRole() == ::css::accessibility::AccessibleRole::SCROLL_PANE )
160721075d77SSteve Yin 	{
160821075d77SSteve Yin 		::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > aSequence(1);
160921075d77SSteve Yin 		aSequence[0] = getAccessibleParent();
161021075d77SSteve Yin 		rRelationSet.AddRelation( ::css::accessibility::AccessibleRelation( ::css::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
161121075d77SSteve Yin 	}
161221075d77SSteve Yin 	else
161321075d77SSteve Yin 	{
161421075d77SSteve Yin 		 VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet);
161521075d77SSteve Yin 	}
161621075d77SSteve Yin }
1617cdf0e10cSrcweir // virtual
disposing()1618cdf0e10cSrcweir void SAL_CALL Document::disposing()
1619cdf0e10cSrcweir {
1620cdf0e10cSrcweir     m_aEngineListener.endListening();
1621cdf0e10cSrcweir     m_aViewListener.endListening();
1622cdf0e10cSrcweir     if (m_xParagraphs.get() != 0)
1623cdf0e10cSrcweir         disposeParagraphs();
1624cdf0e10cSrcweir     VCLXAccessibleComponent::disposing();
1625cdf0e10cSrcweir }
1626cdf0e10cSrcweir 
1627cdf0e10cSrcweir // virtual
Notify(::SfxBroadcaster &,::SfxHint const & rHint)1628cdf0e10cSrcweir void Document::Notify(::SfxBroadcaster &, ::SfxHint const & rHint)
1629cdf0e10cSrcweir {
1630cdf0e10cSrcweir     if (rHint.ISA(::TextHint))
1631cdf0e10cSrcweir     {
1632cdf0e10cSrcweir         ::TextHint const & rTextHint
1633cdf0e10cSrcweir               = static_cast< ::TextHint const & >(rHint);
1634cdf0e10cSrcweir         switch (rTextHint.GetId())
1635cdf0e10cSrcweir         {
1636cdf0e10cSrcweir         case TEXT_HINT_PARAINSERTED:
1637cdf0e10cSrcweir         case TEXT_HINT_PARAREMOVED:
1638cdf0e10cSrcweir             // TEXT_HINT_PARAINSERTED and TEXT_HINT_PARAREMOVED are sent at
1639cdf0e10cSrcweir             // "unsafe" times (when the text engine has not yet re-formatted its
1640cdf0e10cSrcweir             // content), so that for example calling ::TextEngine::GetTextHeight
1641cdf0e10cSrcweir             // from within the code that handles TEXT_HINT_PARAINSERTED causes
1642cdf0e10cSrcweir             // trouble within the text engine.  Therefore, these hints are just
1643cdf0e10cSrcweir             // buffered until a following ::TextEngine::FormatDoc causes a
1644cdf0e10cSrcweir             // TEXT_HINT_TEXTFORMATTED to come in:
1645cdf0e10cSrcweir         case TEXT_HINT_FORMATPARA:
1646cdf0e10cSrcweir             // ::TextEngine::FormatDoc sends a sequence of
1647cdf0e10cSrcweir             // TEXT_HINT_FORMATPARAs, followed by an optional
1648cdf0e10cSrcweir             // TEXT_HINT_TEXTHEIGHTCHANGED, followed in all cases by one
1649cdf0e10cSrcweir             // TEXT_HINT_TEXTFORMATTED.  Only the TEXT_HINT_FORMATPARAs contain
1650cdf0e10cSrcweir             // the the numbers of the affected paragraphs, but they are sent
1651cdf0e10cSrcweir             // before the changes are applied.  Therefore, TEXT_HINT_FORMATPARAs
1652cdf0e10cSrcweir             // are just buffered until another hint comes in:
1653cdf0e10cSrcweir             {
1654cdf0e10cSrcweir                 ::osl::MutexGuard aInternalGuard(GetMutex());
1655cdf0e10cSrcweir                 if (!isAlive())
1656cdf0e10cSrcweir                     break;
1657cdf0e10cSrcweir 
1658cdf0e10cSrcweir                 m_aParagraphNotifications.push(rTextHint);
1659cdf0e10cSrcweir                 break;
1660cdf0e10cSrcweir             }
1661cdf0e10cSrcweir         case TEXT_HINT_TEXTFORMATTED:
1662cdf0e10cSrcweir         case TEXT_HINT_TEXTHEIGHTCHANGED:
1663cdf0e10cSrcweir         case TEXT_HINT_MODIFIED:
1664cdf0e10cSrcweir             {
1665cdf0e10cSrcweir                 ::osl::MutexGuard aInternalGuard(GetMutex());
1666cdf0e10cSrcweir                 if (!isAlive())
1667cdf0e10cSrcweir                     break;
1668cdf0e10cSrcweir                 handleParagraphNotifications();
1669cdf0e10cSrcweir                 break;
1670cdf0e10cSrcweir             }
1671cdf0e10cSrcweir         case TEXT_HINT_VIEWSCROLLED:
1672cdf0e10cSrcweir             {
1673cdf0e10cSrcweir                 ::osl::MutexGuard aInternalGuard(GetMutex());
1674cdf0e10cSrcweir                 if (!isAlive())
1675cdf0e10cSrcweir                     break;
1676cdf0e10cSrcweir                 handleParagraphNotifications();
1677cdf0e10cSrcweir 
1678cdf0e10cSrcweir                 ::sal_Int32 nOffset = static_cast< ::sal_Int32 >(
1679cdf0e10cSrcweir                     m_rView.GetStartDocPos().Y());
1680cdf0e10cSrcweir                     // XXX  numeric overflow
1681cdf0e10cSrcweir                 if (nOffset != m_nViewOffset)
1682cdf0e10cSrcweir                 {
1683cdf0e10cSrcweir                     m_nViewOffset = nOffset;
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir                     Paragraphs::iterator aOldVisibleBegin(
1686cdf0e10cSrcweir                         m_aVisibleBegin);
1687cdf0e10cSrcweir                     Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd);
1688cdf0e10cSrcweir 
1689cdf0e10cSrcweir                     determineVisibleRange();
1690cdf0e10cSrcweir 
1691cdf0e10cSrcweir                     notifyVisibleRangeChanges(aOldVisibleBegin,
1692cdf0e10cSrcweir                                                 aOldVisibleEnd,
1693cdf0e10cSrcweir                                                 m_xParagraphs->end());
1694cdf0e10cSrcweir                 }
1695cdf0e10cSrcweir                 break;
1696cdf0e10cSrcweir             }
1697cdf0e10cSrcweir         case TEXT_HINT_VIEWSELECTIONCHANGED:
1698cdf0e10cSrcweir             {
1699cdf0e10cSrcweir                 ::osl::MutexGuard aInternalGuard(GetMutex());
1700cdf0e10cSrcweir                 if (!isAlive())
1701cdf0e10cSrcweir                     break;
1702cdf0e10cSrcweir 
1703cdf0e10cSrcweir                 if (m_aParagraphNotifications.empty())
1704cdf0e10cSrcweir                 {
1705cdf0e10cSrcweir                     handleSelectionChangeNotification();
1706cdf0e10cSrcweir                 }
1707cdf0e10cSrcweir                 else
1708cdf0e10cSrcweir                 {
1709cdf0e10cSrcweir                     // TEXT_HINT_VIEWSELECTIONCHANGED is sometimes sent at
1710cdf0e10cSrcweir                     // "unsafe" times (when the text engine has not yet re-
1711cdf0e10cSrcweir                     // formatted its content), so that for example calling
1712cdf0e10cSrcweir                     // ::TextEngine::GetTextHeight from within the code that
1713cdf0e10cSrcweir                     // handles a previous TEXT_HINT_PARAINSERTED causes
1714cdf0e10cSrcweir                     // trouble within the text engine.  Therefore, these
1715cdf0e10cSrcweir                     // hints are just buffered (along with
1716cdf0e10cSrcweir                     // TEXT_HINT_PARAINSERTED/REMOVED/FORMATPARA) until a
1717cdf0e10cSrcweir                     // following ::TextEngine::FormatDoc causes a
1718cdf0e10cSrcweir                     // TEXT_HINT_TEXTFORMATTED to come in:
1719cdf0e10cSrcweir                     m_bSelectionChangedNotification = true;
1720cdf0e10cSrcweir                 }
1721cdf0e10cSrcweir                 break;
1722cdf0e10cSrcweir             }
1723cdf0e10cSrcweir         }
1724cdf0e10cSrcweir     }
1725cdf0e10cSrcweir }
1726cdf0e10cSrcweir 
IMPL_LINK(Document,WindowEventHandler,::VclSimpleEvent *,pEvent)1727cdf0e10cSrcweir IMPL_LINK(Document, WindowEventHandler, ::VclSimpleEvent *, pEvent)
1728cdf0e10cSrcweir {
1729cdf0e10cSrcweir     switch (pEvent->GetId())
1730cdf0e10cSrcweir     {
1731cdf0e10cSrcweir     case VCLEVENT_WINDOW_RESIZE:
1732cdf0e10cSrcweir         {
1733cdf0e10cSrcweir             ::osl::MutexGuard aInternalGuard(GetMutex());
1734cdf0e10cSrcweir             if (!isAlive())
1735cdf0e10cSrcweir                 break;
1736cdf0e10cSrcweir 
1737cdf0e10cSrcweir             ::sal_Int32 nHeight = static_cast< ::sal_Int32 >(
1738cdf0e10cSrcweir                 m_rView.GetWindow()->GetOutputSizePixel().Height());
1739cdf0e10cSrcweir                 // XXX  numeric overflow
1740cdf0e10cSrcweir             if (nHeight != m_nViewHeight)
1741cdf0e10cSrcweir             {
1742cdf0e10cSrcweir                 m_nViewHeight = nHeight;
1743cdf0e10cSrcweir 
1744cdf0e10cSrcweir                 Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin);
1745cdf0e10cSrcweir                 Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd);
1746cdf0e10cSrcweir 
1747cdf0e10cSrcweir                 determineVisibleRange();
1748cdf0e10cSrcweir 
1749cdf0e10cSrcweir                 notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd,
1750cdf0e10cSrcweir                                             m_xParagraphs->end());
1751cdf0e10cSrcweir             }
1752cdf0e10cSrcweir             break;
1753cdf0e10cSrcweir         }
1754cdf0e10cSrcweir     case VCLEVENT_WINDOW_GETFOCUS:
1755cdf0e10cSrcweir         {
1756cdf0e10cSrcweir             ::osl::MutexGuard aInternalGuard(GetMutex());
1757cdf0e10cSrcweir             if (!isAlive())
1758cdf0e10cSrcweir                 break;
175921075d77SSteve Yin 			//to enable the PARAGRAPH to get focus for multiline edit
176021075d77SSteve Yin 			::sal_Int32 count = getAccessibleChildCount();
176121075d77SSteve Yin 			::sal_Bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1;
176221075d77SSteve Yin             if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty)
1763cdf0e10cSrcweir             {
176421075d77SSteve Yin 				Paragraphs::iterator m_aTemp = bEmpty ? m_aVisibleBegin : m_aFocused;
176521075d77SSteve Yin                 ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(m_aTemp));
176621075d77SSteve Yin 				if (xParagraph.is())
176721075d77SSteve Yin 				{
176821075d77SSteve Yin 					xParagraph->notifyEvent(
176921075d77SSteve Yin 						::css::accessibility::AccessibleEventId::
177021075d77SSteve Yin 						STATE_CHANGED,
177121075d77SSteve Yin 						::css::uno::Any(),
177221075d77SSteve Yin 						::css::uno::makeAny(
177321075d77SSteve Yin 							::css::accessibility::AccessibleStateType::
177421075d77SSteve Yin 							FOCUSED));
177521075d77SSteve Yin 				}
177621075d77SSteve Yin             }
177721075d77SSteve Yin 			/*
1778cdf0e10cSrcweir                 ::rtl::Reference< ParagraphImpl > xParagraph(
1779cdf0e10cSrcweir                     getParagraph(m_aFocused));
1780cdf0e10cSrcweir                 if (xParagraph.is())
1781cdf0e10cSrcweir                     xParagraph->notifyEvent(
1782cdf0e10cSrcweir                         ::css::accessibility::AccessibleEventId::
1783cdf0e10cSrcweir                         STATE_CHANGED,
1784cdf0e10cSrcweir                         ::css::uno::Any(),
1785cdf0e10cSrcweir                         ::css::uno::makeAny(
1786cdf0e10cSrcweir                             ::css::accessibility::AccessibleStateType::
1787cdf0e10cSrcweir                             FOCUSED));
178821075d77SSteve Yin 			*/
1789cdf0e10cSrcweir             break;
1790cdf0e10cSrcweir         }
1791cdf0e10cSrcweir     case VCLEVENT_WINDOW_LOSEFOCUS:
1792cdf0e10cSrcweir         {
1793cdf0e10cSrcweir             ::osl::MutexGuard aInternalGuard(GetMutex());
1794cdf0e10cSrcweir             if (!isAlive())
1795cdf0e10cSrcweir                 break;
179621075d77SSteve Yin 			//to enable the PARAGRAPH to get focus for multiline edit
179721075d77SSteve Yin 			::sal_Int32 count = getAccessibleChildCount();
179821075d77SSteve Yin 			::sal_Bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1;
179921075d77SSteve Yin             if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty)
180021075d77SSteve Yin             {
180121075d77SSteve Yin 				Paragraphs::iterator m_aTemp = bEmpty ? m_aVisibleBegin : m_aFocused;
180221075d77SSteve Yin                 ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(m_aTemp));
180321075d77SSteve Yin                 if (xParagraph.is())
180421075d77SSteve Yin                     xParagraph->notifyEvent(
180521075d77SSteve Yin                         ::css::accessibility::AccessibleEventId::
180621075d77SSteve Yin                         STATE_CHANGED,
180721075d77SSteve Yin                         ::css::uno::makeAny(
180821075d77SSteve Yin                             ::css::accessibility::AccessibleStateType::
180921075d77SSteve Yin                             FOCUSED),
181021075d77SSteve Yin                         ::css::uno::Any());
181121075d77SSteve Yin             }
1812cdf0e10cSrcweir 
181321075d77SSteve Yin 			/*
1814cdf0e10cSrcweir             if (m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd)
1815cdf0e10cSrcweir             {
1816cdf0e10cSrcweir                 ::rtl::Reference< ParagraphImpl > xParagraph(
1817cdf0e10cSrcweir                     getParagraph(m_aFocused));
1818cdf0e10cSrcweir                 if (xParagraph.is())
1819cdf0e10cSrcweir                     xParagraph->notifyEvent(
1820cdf0e10cSrcweir                         ::css::accessibility::AccessibleEventId::
1821cdf0e10cSrcweir                         STATE_CHANGED,
1822cdf0e10cSrcweir                         ::css::uno::makeAny(
1823cdf0e10cSrcweir                             ::css::accessibility::AccessibleStateType::
1824cdf0e10cSrcweir                             FOCUSED),
1825cdf0e10cSrcweir                         ::css::uno::Any());
1826cdf0e10cSrcweir             }
182721075d77SSteve Yin 			*/
1828cdf0e10cSrcweir             break;
1829cdf0e10cSrcweir         }
1830cdf0e10cSrcweir     }
1831cdf0e10cSrcweir     return 0;
1832cdf0e10cSrcweir }
1833cdf0e10cSrcweir 
init()1834cdf0e10cSrcweir void Document::init()
1835cdf0e10cSrcweir {
1836cdf0e10cSrcweir     if (m_xParagraphs.get() == 0)
1837cdf0e10cSrcweir     {
1838cdf0e10cSrcweir         ::sal_uLong nCount = m_rEngine.GetParagraphCount();
1839cdf0e10cSrcweir         ::std::auto_ptr< Paragraphs > p(new Paragraphs);
1840cdf0e10cSrcweir         p->reserve(static_cast< Paragraphs::size_type >(nCount));
1841cdf0e10cSrcweir             // numeric overflow is harmless here
1842cdf0e10cSrcweir         for (::sal_uLong i = 0; i < nCount; ++i)
1843cdf0e10cSrcweir             p->push_back(ParagraphInfo(static_cast< ::sal_Int32 >(
1844cdf0e10cSrcweir                                            m_rEngine.GetTextHeight(i))));
1845cdf0e10cSrcweir                 // XXX  numeric overflow
1846cdf0e10cSrcweir         m_nViewOffset = static_cast< ::sal_Int32 >(
1847cdf0e10cSrcweir             m_rView.GetStartDocPos().Y()); // XXX  numeric overflow
1848cdf0e10cSrcweir         m_nViewHeight = static_cast< ::sal_Int32 >(
1849cdf0e10cSrcweir             m_rView.GetWindow()->GetOutputSizePixel().Height());
1850cdf0e10cSrcweir             // XXX  numeric overflow
1851cdf0e10cSrcweir         m_xParagraphs = p;
1852cdf0e10cSrcweir         determineVisibleRange();
1853cdf0e10cSrcweir         m_nSelectionFirstPara = -1;
1854cdf0e10cSrcweir         m_nSelectionFirstPos = -1;
1855cdf0e10cSrcweir         m_nSelectionLastPara = -1;
1856cdf0e10cSrcweir         m_nSelectionLastPos = -1;
1857cdf0e10cSrcweir         m_aFocused = m_xParagraphs->end();
1858cdf0e10cSrcweir         m_bSelectionChangedNotification = false;
1859cdf0e10cSrcweir         m_aEngineListener.startListening(m_rEngine);
1860cdf0e10cSrcweir         m_aViewListener.startListening(*m_rView.GetWindow());
1861cdf0e10cSrcweir     }
1862cdf0e10cSrcweir }
1863cdf0e10cSrcweir 
1864cdf0e10cSrcweir ::rtl::Reference< ParagraphImpl >
getParagraph(Paragraphs::iterator const & rIt)1865cdf0e10cSrcweir Document::getParagraph(Paragraphs::iterator const & rIt)
1866cdf0e10cSrcweir {
1867cdf0e10cSrcweir     return static_cast< ParagraphImpl * >(
1868cdf0e10cSrcweir         ::css::uno::Reference< ::css::accessibility::XAccessible >(
1869cdf0e10cSrcweir             rIt->getParagraph()).get());
1870cdf0e10cSrcweir }
1871cdf0e10cSrcweir 
1872cdf0e10cSrcweir ::css::uno::Reference< ::css::accessibility::XAccessible >
getAccessibleChild(Paragraphs::iterator const & rIt)1873cdf0e10cSrcweir Document::getAccessibleChild(Paragraphs::iterator const & rIt)
1874cdf0e10cSrcweir {
1875cdf0e10cSrcweir     ::css::uno::Reference< ::css::accessibility::XAccessible > xParagraph(
1876cdf0e10cSrcweir         rIt->getParagraph());
1877cdf0e10cSrcweir     if (!xParagraph.is())
1878cdf0e10cSrcweir     {
1879cdf0e10cSrcweir         xParagraph = new Paragraph(this, rIt - m_xParagraphs->begin());
1880cdf0e10cSrcweir         rIt->setParagraph(xParagraph);
1881cdf0e10cSrcweir     }
1882cdf0e10cSrcweir     return xParagraph;
1883cdf0e10cSrcweir }
1884cdf0e10cSrcweir 
determineVisibleRange()1885cdf0e10cSrcweir void Document::determineVisibleRange()
1886cdf0e10cSrcweir {
1887cdf0e10cSrcweir     m_aVisibleBegin = m_xParagraphs->end();
1888cdf0e10cSrcweir     m_aVisibleEnd = m_aVisibleBegin;
1889cdf0e10cSrcweir     ::sal_Int32 nPos = 0;
1890cdf0e10cSrcweir     for (Paragraphs::iterator aIt = m_xParagraphs->begin();;)
1891cdf0e10cSrcweir     {
1892cdf0e10cSrcweir         if (aIt == m_xParagraphs->end())
1893cdf0e10cSrcweir         {
1894cdf0e10cSrcweir             m_nVisibleBeginOffset = 0;
1895cdf0e10cSrcweir             break;
1896cdf0e10cSrcweir         }
1897cdf0e10cSrcweir         ::sal_Int32 nOldPos = nPos;
1898cdf0e10cSrcweir         nPos += aIt->getHeight(); // XXX  numeric overflow
1899cdf0e10cSrcweir         if (m_aVisibleBegin == m_xParagraphs->end() && nPos >= m_nViewOffset)
1900cdf0e10cSrcweir         {
1901cdf0e10cSrcweir             m_aVisibleBegin = aIt;
1902cdf0e10cSrcweir             m_nVisibleBeginOffset = m_nViewOffset - nOldPos;
1903cdf0e10cSrcweir         }
1904cdf0e10cSrcweir         ++aIt;
1905cdf0e10cSrcweir         if (m_aVisibleBegin != m_xParagraphs->end()
1906cdf0e10cSrcweir             && (aIt == m_xParagraphs->end()
1907cdf0e10cSrcweir                 || nPos >= m_nViewOffset + m_nViewHeight))
1908cdf0e10cSrcweir             // XXX  numeric overflow
1909cdf0e10cSrcweir         {
1910cdf0e10cSrcweir             m_aVisibleEnd = aIt;
1911cdf0e10cSrcweir             break;
1912cdf0e10cSrcweir         }
1913cdf0e10cSrcweir     }
1914cdf0e10cSrcweir }
1915cdf0e10cSrcweir 
notifyVisibleRangeChanges(Paragraphs::iterator const & rOldVisibleBegin,Paragraphs::iterator const & rOldVisibleEnd,Paragraphs::iterator const & rInserted)1916cdf0e10cSrcweir void Document::notifyVisibleRangeChanges(
1917cdf0e10cSrcweir     Paragraphs::iterator const & rOldVisibleBegin,
1918cdf0e10cSrcweir     Paragraphs::iterator const & rOldVisibleEnd,
1919cdf0e10cSrcweir     Paragraphs::iterator const & rInserted)
1920cdf0e10cSrcweir {
1921cdf0e10cSrcweir     // XXX  Replace this code that determines which paragraphs have changed from
1922cdf0e10cSrcweir     // invisible to visible or vice versa with a better algorithm.
1923cdf0e10cSrcweir     {for (Paragraphs::iterator aIt(rOldVisibleBegin); aIt != rOldVisibleEnd;
1924cdf0e10cSrcweir           ++aIt)
1925cdf0e10cSrcweir         if (aIt != rInserted
1926cdf0e10cSrcweir             && (aIt < m_aVisibleBegin || aIt >= m_aVisibleEnd))
1927cdf0e10cSrcweir             NotifyAccessibleEvent(
1928cdf0e10cSrcweir                 ::css::accessibility::AccessibleEventId::
1929cdf0e10cSrcweir                 CHILD,
1930cdf0e10cSrcweir                 ::css::uno::makeAny(getAccessibleChild(aIt)),
1931cdf0e10cSrcweir                 ::css::uno::Any());
1932cdf0e10cSrcweir     }
1933cdf0e10cSrcweir     {for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd;
1934cdf0e10cSrcweir           ++aIt)
1935cdf0e10cSrcweir         if (aIt == rInserted
1936cdf0e10cSrcweir             || aIt < rOldVisibleBegin || aIt >= rOldVisibleEnd)
1937cdf0e10cSrcweir             NotifyAccessibleEvent(
1938cdf0e10cSrcweir                 ::css::accessibility::AccessibleEventId::
1939cdf0e10cSrcweir                 CHILD,
1940cdf0e10cSrcweir                 ::css::uno::Any(),
1941cdf0e10cSrcweir                 ::css::uno::makeAny(getAccessibleChild(aIt)));
1942cdf0e10cSrcweir     }
1943cdf0e10cSrcweir }
1944cdf0e10cSrcweir 
1945cdf0e10cSrcweir void
changeParagraphText(::sal_uLong nNumber,::sal_uInt16 nBegin,::sal_uInt16 nEnd,bool bCut,bool bPaste,::rtl::OUString const & rText)1946cdf0e10cSrcweir Document::changeParagraphText(::sal_uLong nNumber, ::sal_uInt16 nBegin, ::sal_uInt16 nEnd,
1947cdf0e10cSrcweir                               bool bCut, bool bPaste,
1948cdf0e10cSrcweir                               ::rtl::OUString const & rText)
1949cdf0e10cSrcweir {
1950cdf0e10cSrcweir     m_rView.SetSelection(::TextSelection(::TextPaM(nNumber, nBegin),
1951cdf0e10cSrcweir                                          ::TextPaM(nNumber, nEnd)));
1952cdf0e10cSrcweir     if (bCut)
1953cdf0e10cSrcweir         m_rView.Cut();
1954cdf0e10cSrcweir     else if (nBegin != nEnd)
1955cdf0e10cSrcweir         m_rView.DeleteSelected();
1956cdf0e10cSrcweir     if (bPaste)
1957cdf0e10cSrcweir         m_rView.Paste();
1958*144e4e62SHerbert Dürr     else if ( !rText.isEmpty() )
1959cdf0e10cSrcweir         m_rView.InsertText(rText);
1960cdf0e10cSrcweir }
1961cdf0e10cSrcweir 
handleParagraphNotifications()1962cdf0e10cSrcweir void Document::handleParagraphNotifications()
1963cdf0e10cSrcweir {
1964cdf0e10cSrcweir     while (!m_aParagraphNotifications.empty())
1965cdf0e10cSrcweir     {
1966cdf0e10cSrcweir         ::TextHint aHint(m_aParagraphNotifications.front());
1967cdf0e10cSrcweir         m_aParagraphNotifications.pop();
1968cdf0e10cSrcweir         switch (aHint.GetId())
1969cdf0e10cSrcweir         {
1970cdf0e10cSrcweir         case TEXT_HINT_PARAINSERTED:
1971cdf0e10cSrcweir             {
1972cdf0e10cSrcweir                 ::sal_uLong n = aHint.GetValue();
1973cdf0e10cSrcweir                 OSL_ENSURE(n <= m_xParagraphs->size(),
1974cdf0e10cSrcweir                            "bad TEXT_HINT_PARAINSERTED event");
1975cdf0e10cSrcweir 
1976cdf0e10cSrcweir                 // Save the values of old iterators (the iterators themselves
1977cdf0e10cSrcweir                 // will get invalidated), and adjust the old values so that they
1978cdf0e10cSrcweir                 // reflect the insertion of the new paragraph:
1979cdf0e10cSrcweir                 Paragraphs::size_type nOldVisibleBegin
1980cdf0e10cSrcweir                     = m_aVisibleBegin - m_xParagraphs->begin();
1981cdf0e10cSrcweir                 Paragraphs::size_type nOldVisibleEnd
1982cdf0e10cSrcweir                     = m_aVisibleEnd - m_xParagraphs->begin();
1983cdf0e10cSrcweir                 Paragraphs::size_type nOldFocused
1984cdf0e10cSrcweir                     = m_aFocused - m_xParagraphs->begin();
1985cdf0e10cSrcweir                 if (n <= nOldVisibleBegin)
1986cdf0e10cSrcweir                     ++nOldVisibleBegin; // XXX  numeric overflow
1987cdf0e10cSrcweir                 if (n <= nOldVisibleEnd)
1988cdf0e10cSrcweir                     ++nOldVisibleEnd; // XXX  numeric overflow
1989cdf0e10cSrcweir                 if (n <= nOldFocused)
1990cdf0e10cSrcweir                     ++nOldFocused; // XXX  numeric overflow
1991cdf0e10cSrcweir                 if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionFirstPara)
1992cdf0e10cSrcweir                     ++m_nSelectionFirstPara; // XXX  numeric overflow
1993cdf0e10cSrcweir                 if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionLastPara)
1994cdf0e10cSrcweir                     ++m_nSelectionLastPara; // XXX  numeric overflow
1995cdf0e10cSrcweir 
1996cdf0e10cSrcweir                 Paragraphs::iterator aIns(
1997cdf0e10cSrcweir                     m_xParagraphs->insert(
1998cdf0e10cSrcweir                         m_xParagraphs->begin() + n,
1999cdf0e10cSrcweir                         ParagraphInfo(static_cast< ::sal_Int32 >(
2000cdf0e10cSrcweir                                           m_rEngine.GetTextHeight(n)))));
2001cdf0e10cSrcweir                     // XXX  numeric overflow (2x)
2002cdf0e10cSrcweir 
2003cdf0e10cSrcweir                 determineVisibleRange();
2004cdf0e10cSrcweir                 m_aFocused = m_xParagraphs->begin() + nOldFocused;
2005cdf0e10cSrcweir 
2006cdf0e10cSrcweir                 for (Paragraphs::iterator aIt(aIns);;)
2007cdf0e10cSrcweir                 {
2008cdf0e10cSrcweir                     ++aIt;
2009cdf0e10cSrcweir                     if (aIt == m_xParagraphs->end())
2010cdf0e10cSrcweir                         break;
2011cdf0e10cSrcweir                     ::rtl::Reference< ParagraphImpl > xParagraph(
2012cdf0e10cSrcweir                         getParagraph(aIt));
2013cdf0e10cSrcweir                     if (xParagraph.is())
2014cdf0e10cSrcweir                         xParagraph->numberChanged(true);
2015cdf0e10cSrcweir                 }
2016cdf0e10cSrcweir 
2017cdf0e10cSrcweir                 notifyVisibleRangeChanges(
2018cdf0e10cSrcweir                     m_xParagraphs->begin() + nOldVisibleBegin,
2019cdf0e10cSrcweir                     m_xParagraphs->begin() + nOldVisibleEnd, aIns);
2020cdf0e10cSrcweir                 break;
2021cdf0e10cSrcweir             }
2022cdf0e10cSrcweir         case TEXT_HINT_PARAREMOVED:
2023cdf0e10cSrcweir             {
2024cdf0e10cSrcweir                 ::sal_uLong n = aHint.GetValue();
2025cdf0e10cSrcweir                 if (n == TEXT_PARA_ALL)
2026cdf0e10cSrcweir                 {
2027cdf0e10cSrcweir                     {for (Paragraphs::iterator aIt(m_aVisibleBegin);
2028cdf0e10cSrcweir                           aIt != m_aVisibleEnd; ++aIt)
2029cdf0e10cSrcweir                         NotifyAccessibleEvent(
2030cdf0e10cSrcweir                             ::css::accessibility::AccessibleEventId::
2031cdf0e10cSrcweir                             CHILD,
2032cdf0e10cSrcweir                             ::css::uno::makeAny(getAccessibleChild(aIt)),
2033cdf0e10cSrcweir                             ::css::uno::Any());
2034cdf0e10cSrcweir                     }
2035cdf0e10cSrcweir                     disposeParagraphs();
2036cdf0e10cSrcweir                     m_xParagraphs->clear();
2037cdf0e10cSrcweir                     determineVisibleRange();
2038cdf0e10cSrcweir                     m_nSelectionFirstPara = -1;
2039cdf0e10cSrcweir                     m_nSelectionFirstPos = -1;
2040cdf0e10cSrcweir                     m_nSelectionLastPara = -1;
2041cdf0e10cSrcweir                     m_nSelectionLastPos = -1;
2042cdf0e10cSrcweir                     m_aFocused = m_xParagraphs->end();
2043cdf0e10cSrcweir                 }
2044cdf0e10cSrcweir                 else
2045cdf0e10cSrcweir                 {
2046cdf0e10cSrcweir                     OSL_ENSURE(n < m_xParagraphs->size(),
2047cdf0e10cSrcweir                                "Bad TEXT_HINT_PARAREMOVED event");
2048cdf0e10cSrcweir 
2049cdf0e10cSrcweir                     Paragraphs::iterator aIt(m_xParagraphs->begin() + n);
2050cdf0e10cSrcweir                         // numeric overflow cannot occur
2051cdf0e10cSrcweir 
2052cdf0e10cSrcweir                     // Save the values of old iterators (the iterators
2053cdf0e10cSrcweir                     // themselves will get invalidated), and adjust the old
2054cdf0e10cSrcweir                     // values so that they reflect the removal of the paragraph:
2055cdf0e10cSrcweir                     Paragraphs::size_type nOldVisibleBegin
2056cdf0e10cSrcweir                         = m_aVisibleBegin - m_xParagraphs->begin();
2057cdf0e10cSrcweir                     Paragraphs::size_type nOldVisibleEnd
2058cdf0e10cSrcweir                         = m_aVisibleEnd - m_xParagraphs->begin();
2059cdf0e10cSrcweir                     bool bWasVisible
2060cdf0e10cSrcweir                         = nOldVisibleBegin <= n && n < nOldVisibleEnd;
2061cdf0e10cSrcweir                     Paragraphs::size_type nOldFocused
2062cdf0e10cSrcweir                         = m_aFocused - m_xParagraphs->begin();
2063cdf0e10cSrcweir                     bool bWasFocused = aIt == m_aFocused;
2064cdf0e10cSrcweir                     if (n < nOldVisibleBegin)
2065cdf0e10cSrcweir                         --nOldVisibleBegin;
2066cdf0e10cSrcweir                     if (n < nOldVisibleEnd)
2067cdf0e10cSrcweir                         --nOldVisibleEnd;
2068cdf0e10cSrcweir                     if (n < nOldFocused)
2069cdf0e10cSrcweir                         --nOldFocused;
2070cdf0e10cSrcweir                     if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionFirstPara)
2071cdf0e10cSrcweir                         --m_nSelectionFirstPara;
2072cdf0e10cSrcweir                     else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionFirstPara)
2073cdf0e10cSrcweir                     {
2074cdf0e10cSrcweir                         if (m_nSelectionFirstPara == m_nSelectionLastPara)
2075cdf0e10cSrcweir                         {
2076cdf0e10cSrcweir                             m_nSelectionFirstPara = -1;
2077cdf0e10cSrcweir                             m_nSelectionFirstPos = -1;
2078cdf0e10cSrcweir                             m_nSelectionLastPara = -1;
2079cdf0e10cSrcweir                             m_nSelectionLastPos = -1;
2080cdf0e10cSrcweir                         }
2081cdf0e10cSrcweir                         else
2082cdf0e10cSrcweir                         {
2083cdf0e10cSrcweir                             ++m_nSelectionFirstPara;
2084cdf0e10cSrcweir                             m_nSelectionFirstPos = 0;
2085cdf0e10cSrcweir                         }
2086cdf0e10cSrcweir                     }
2087cdf0e10cSrcweir                     if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionLastPara)
2088cdf0e10cSrcweir                         --m_nSelectionLastPara;
2089cdf0e10cSrcweir                     else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionLastPara)
2090cdf0e10cSrcweir                     {
2091cdf0e10cSrcweir                         OSL_ENSURE(m_nSelectionFirstPara < m_nSelectionLastPara,
2092cdf0e10cSrcweir                                    "logic error");
2093cdf0e10cSrcweir                         --m_nSelectionLastPara;
2094cdf0e10cSrcweir                         m_nSelectionLastPos = 0x7FFFFFFF;
2095cdf0e10cSrcweir                     }
2096cdf0e10cSrcweir 
2097cdf0e10cSrcweir                     ::css::uno::Reference< ::css::accessibility::XAccessible >
2098cdf0e10cSrcweir                           xStrong;
2099cdf0e10cSrcweir                     if (bWasVisible)
2100cdf0e10cSrcweir                         xStrong = getAccessibleChild(aIt);
2101cdf0e10cSrcweir                     ::css::uno::WeakReference<
2102cdf0e10cSrcweir                           ::css::accessibility::XAccessible > xWeak(
2103cdf0e10cSrcweir                               aIt->getParagraph());
2104cdf0e10cSrcweir                     aIt = m_xParagraphs->erase(aIt);
2105cdf0e10cSrcweir 
2106cdf0e10cSrcweir                     determineVisibleRange();
2107cdf0e10cSrcweir                     m_aFocused = bWasFocused ? m_xParagraphs->end()
2108cdf0e10cSrcweir                         : m_xParagraphs->begin() + nOldFocused;
2109cdf0e10cSrcweir 
2110cdf0e10cSrcweir                     for (; aIt != m_xParagraphs->end(); ++aIt)
2111cdf0e10cSrcweir                     {
2112cdf0e10cSrcweir                         ::rtl::Reference< ParagraphImpl > xParagraph(
2113cdf0e10cSrcweir                             getParagraph(aIt));
2114cdf0e10cSrcweir                         if (xParagraph.is())
2115cdf0e10cSrcweir                             xParagraph->numberChanged(false);
2116cdf0e10cSrcweir                     }
2117cdf0e10cSrcweir 
2118cdf0e10cSrcweir                     if (bWasVisible)
2119cdf0e10cSrcweir                         NotifyAccessibleEvent(
2120cdf0e10cSrcweir                             ::css::accessibility::AccessibleEventId::
2121cdf0e10cSrcweir                             CHILD,
2122cdf0e10cSrcweir                             ::css::uno::makeAny(getAccessibleChild(aIt)),
2123cdf0e10cSrcweir                             ::css::uno::Any());
2124cdf0e10cSrcweir 
2125cdf0e10cSrcweir                     ::css::uno::Reference< ::css::lang::XComponent > xComponent(
2126cdf0e10cSrcweir                         xWeak.get(), ::css::uno::UNO_QUERY);
2127cdf0e10cSrcweir                     if (xComponent.is())
2128cdf0e10cSrcweir                         xComponent->dispose();
2129cdf0e10cSrcweir 
2130cdf0e10cSrcweir                     notifyVisibleRangeChanges(
2131cdf0e10cSrcweir                         m_xParagraphs->begin() + nOldVisibleBegin,
2132cdf0e10cSrcweir                         m_xParagraphs->begin() + nOldVisibleEnd,
2133cdf0e10cSrcweir                         m_xParagraphs->end());
2134cdf0e10cSrcweir                 }
2135cdf0e10cSrcweir                 break;
2136cdf0e10cSrcweir             }
2137cdf0e10cSrcweir         case TEXT_HINT_FORMATPARA:
2138cdf0e10cSrcweir             {
2139cdf0e10cSrcweir                 ::sal_uLong n = aHint.GetValue();
2140cdf0e10cSrcweir                 OSL_ENSURE(n < m_xParagraphs->size(),
2141cdf0e10cSrcweir                            "Bad TEXT_HINT_FORMATPARA event");
2142cdf0e10cSrcweir 
2143cdf0e10cSrcweir                 (*m_xParagraphs)[static_cast< Paragraphs::size_type >(n)].
2144cdf0e10cSrcweir                     changeHeight(static_cast< ::sal_Int32 >(
2145cdf0e10cSrcweir                                      m_rEngine.GetTextHeight(n)));
2146cdf0e10cSrcweir                     // XXX  numeric overflow
2147cdf0e10cSrcweir                 Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin);
2148cdf0e10cSrcweir                 Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd);
2149cdf0e10cSrcweir                 determineVisibleRange();
2150cdf0e10cSrcweir                 notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd,
2151cdf0e10cSrcweir                                           m_xParagraphs->end());
2152cdf0e10cSrcweir 
2153cdf0e10cSrcweir                 if (n < m_xParagraphs->size())
2154cdf0e10cSrcweir                 {
2155cdf0e10cSrcweir                     Paragraphs::iterator aIt(m_xParagraphs->begin() + n);
2156cdf0e10cSrcweir                     ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(aIt));
2157cdf0e10cSrcweir                     if (xParagraph.is())
2158cdf0e10cSrcweir                         xParagraph->textChanged();
2159cdf0e10cSrcweir                 }
2160cdf0e10cSrcweir                 break;
2161cdf0e10cSrcweir             }
2162cdf0e10cSrcweir         default:
2163cdf0e10cSrcweir             OSL_ENSURE(false, "bad buffered hint");
2164cdf0e10cSrcweir             break;
2165cdf0e10cSrcweir         }
2166cdf0e10cSrcweir     }
2167cdf0e10cSrcweir     if (m_bSelectionChangedNotification)
2168cdf0e10cSrcweir     {
2169cdf0e10cSrcweir         m_bSelectionChangedNotification = false;
2170cdf0e10cSrcweir         handleSelectionChangeNotification();
2171cdf0e10cSrcweir     }
2172cdf0e10cSrcweir }
2173cdf0e10cSrcweir 
getSelectionType(::sal_Int32 nNewFirstPara,::sal_Int32 nNewFirstPos,::sal_Int32 nNewLastPara,::sal_Int32 nNewLastPos)217421075d77SSteve Yin ::sal_Int32 Document::getSelectionType(::sal_Int32 nNewFirstPara, ::sal_Int32 nNewFirstPos, ::sal_Int32 nNewLastPara, ::sal_Int32 nNewLastPos)
217521075d77SSteve Yin {
217621075d77SSteve Yin 	if (m_nSelectionFirstPara == -1)
217721075d77SSteve Yin 		return -1;
217821075d77SSteve Yin 	::sal_Int32 Osp = m_nSelectionFirstPara, Osl = m_nSelectionFirstPos, Oep = m_nSelectionLastPara, Oel = m_nSelectionLastPos;
217921075d77SSteve Yin 	::sal_Int32 Nsp = nNewFirstPara, Nsl = nNewFirstPos, Nep = nNewLastPara, Nel = nNewLastPos;
218021075d77SSteve Yin 	TextPaM Ns(Nsp, sal_uInt16(Nsl));
218121075d77SSteve Yin 	TextPaM Ne(Nep, sal_uInt16(Nel));
218221075d77SSteve Yin 	TextPaM Os(Osp, sal_uInt16(Osl));
218321075d77SSteve Yin 	TextPaM Oe(Oep, sal_uInt16(Oel));
218421075d77SSteve Yin 
218521075d77SSteve Yin 	if (Os == Oe && Ns == Ne)
218621075d77SSteve Yin 	{
218721075d77SSteve Yin 		//only caret moves.
218821075d77SSteve Yin 		return 1;
218921075d77SSteve Yin 	}
219021075d77SSteve Yin 	else if (Os == Oe && Ns != Ne)
219121075d77SSteve Yin 	{
219221075d77SSteve Yin 		//old has no selection but new has selection
219321075d77SSteve Yin 		return 2;
219421075d77SSteve Yin 	}
219521075d77SSteve Yin 	else if (Os != Oe && Ns == Ne)
219621075d77SSteve Yin 	{
219721075d77SSteve Yin 		//old has selection but new has no selection.
219821075d77SSteve Yin 		return 3;
219921075d77SSteve Yin 	}
220021075d77SSteve Yin 	else if (Os != Oe && Ns != Ne && Osp == Nsp && Osl == Nsl)
220121075d77SSteve Yin 	{
220221075d77SSteve Yin 		//both old and new have selections.
220321075d77SSteve Yin 		if (Oep == Nep )
220421075d77SSteve Yin 		{
220521075d77SSteve Yin 			//Send text_selection_change event on Nep
220621075d77SSteve Yin 
220721075d77SSteve Yin 			return 4;
220821075d77SSteve Yin 		}
220921075d77SSteve Yin 		else if (Oep < Nep)
221021075d77SSteve Yin 		{
221121075d77SSteve Yin 			//all the following examples like 1,2->1,3 means that old start select para is 1, old end select para is 2,
221221075d77SSteve Yin 			// then press shift up, the new start select para is 1, new end select para is 3;
221321075d77SSteve Yin 			//for example, 1, 2 -> 1, 3; 4,1 -> 4, 7; 4,1 -> 4, 2; 4,4->4,5
221421075d77SSteve Yin 			if (Nep >= Nsp)
221521075d77SSteve Yin 			{
221621075d77SSteve Yin 				// 1, 2 -> 1, 3; 4, 1 -> 4, 7; 4,4->4,5;
221721075d77SSteve Yin 				if (Oep < Osp)
221821075d77SSteve Yin 				{
221921075d77SSteve Yin 					// 4,1 -> 4,7;
222021075d77SSteve Yin 					return 5;
222121075d77SSteve Yin 				}
222221075d77SSteve Yin 				else if (Oep >= Osp)
222321075d77SSteve Yin 				{
222421075d77SSteve Yin 					// 1, 2 -> 1, 3; 4,4->4,5;
222521075d77SSteve Yin 					return 6;
222621075d77SSteve Yin 				}
222721075d77SSteve Yin 			}
222821075d77SSteve Yin 			else
222921075d77SSteve Yin 			{
223021075d77SSteve Yin 				// 4,1 -> 4,2,
223121075d77SSteve Yin 				if (Oep < Osp)
223221075d77SSteve Yin 				{
223321075d77SSteve Yin 					// 4,1 -> 4,2,
223421075d77SSteve Yin 					return 7;
223521075d77SSteve Yin 				}
223621075d77SSteve Yin 				else if (Oep >= Osp)
223721075d77SSteve Yin 				{
223821075d77SSteve Yin 					// no such condition. Oep > Osp = Nsp > Nep
223921075d77SSteve Yin 				}
224021075d77SSteve Yin 			}
224121075d77SSteve Yin 		}
224221075d77SSteve Yin 		else if (Oep > Nep)
224321075d77SSteve Yin 		{
224421075d77SSteve Yin 			// 3,2 -> 3,1; 4,7 -> 4,1; 4, 7 -> 4,6; 4,4 -> 4,3
224521075d77SSteve Yin 			if (Nep >= Nsp)
224621075d77SSteve Yin 			{
224721075d77SSteve Yin 				// 4,7 -> 4,6
224821075d77SSteve Yin 				if (Oep <= Osp)
224921075d77SSteve Yin 				{
225021075d77SSteve Yin 					//no such condition, Oep<Osp=Nsp <= Nep
225121075d77SSteve Yin 				}
225221075d77SSteve Yin 				else if (Oep > Osp)
225321075d77SSteve Yin 				{
225421075d77SSteve Yin 					// 4,7 ->4,6
225521075d77SSteve Yin 					return 8;
225621075d77SSteve Yin 				}
225721075d77SSteve Yin 			}
225821075d77SSteve Yin 			else
225921075d77SSteve Yin 			{
226021075d77SSteve Yin 				// 3,2 -> 3,1, 4,7 -> 4,1; 4,4->4,3
226121075d77SSteve Yin 				if (Oep <= Osp)
226221075d77SSteve Yin 				{
226321075d77SSteve Yin 					// 3,2 -> 3,1; 4,4->4,3
226421075d77SSteve Yin 					return 9;
226521075d77SSteve Yin 				}
226621075d77SSteve Yin 				else if (Oep > Osp)
226721075d77SSteve Yin 				{
226821075d77SSteve Yin 					// 4,7 -> 4,1
226921075d77SSteve Yin 					return 10;
227021075d77SSteve Yin 				}
227121075d77SSteve Yin 			}
227221075d77SSteve Yin 		}
227321075d77SSteve Yin 	}
227421075d77SSteve Yin 	return -1;
227521075d77SSteve Yin }
227621075d77SSteve Yin 
227721075d77SSteve Yin 
sendEvent(::sal_Int32 start,::sal_Int32 end,::sal_Int16 nEventId)227821075d77SSteve Yin void Document::sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId)
227921075d77SSteve Yin {
228021075d77SSteve Yin 	 Paragraphs::iterator aEnd = ::std::min(m_xParagraphs->begin() + end + 1, m_aVisibleEnd);
228121075d77SSteve Yin 	for (Paragraphs::iterator aIt = ::std::max(m_xParagraphs->begin() + start, m_aVisibleBegin);
228221075d77SSteve Yin 	     aIt < aEnd; ++aIt)
228321075d77SSteve Yin 	{
228421075d77SSteve Yin 	    ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(aIt));
228521075d77SSteve Yin 	    if (xParagraph.is())
228621075d77SSteve Yin 	        xParagraph->notifyEvent(
228721075d77SSteve Yin 			nEventId,
228821075d77SSteve Yin 	            ::css::uno::Any(), ::css::uno::Any());
228921075d77SSteve Yin 	}
229021075d77SSteve Yin }
229121075d77SSteve Yin 
handleSelectionChangeNotification()2292cdf0e10cSrcweir void Document::handleSelectionChangeNotification()
2293cdf0e10cSrcweir {
2294cdf0e10cSrcweir     ::TextSelection const & rSelection = m_rView.GetSelection();
2295cdf0e10cSrcweir     OSL_ENSURE(rSelection.GetStart().GetPara() < m_xParagraphs->size()
2296cdf0e10cSrcweir                && rSelection.GetEnd().GetPara() < m_xParagraphs->size(),
2297cdf0e10cSrcweir                "bad TEXT_HINT_VIEWSELECTIONCHANGED event");
2298cdf0e10cSrcweir     ::sal_Int32 nNewFirstPara
2299cdf0e10cSrcweir           = static_cast< ::sal_Int32 >(rSelection.GetStart().GetPara());
2300cdf0e10cSrcweir     ::sal_Int32 nNewFirstPos
2301cdf0e10cSrcweir           = static_cast< ::sal_Int32 >(rSelection.GetStart().GetIndex());
2302cdf0e10cSrcweir         // XXX  numeric overflow
2303cdf0e10cSrcweir     ::sal_Int32 nNewLastPara
2304cdf0e10cSrcweir           = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetPara());
2305cdf0e10cSrcweir     ::sal_Int32 nNewLastPos
2306cdf0e10cSrcweir           = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetIndex());
2307cdf0e10cSrcweir         // XXX  numeric overflow
2308cdf0e10cSrcweir 
2309cdf0e10cSrcweir     // Lose focus:
2310cdf0e10cSrcweir     Paragraphs::iterator aIt(m_xParagraphs->begin() + nNewLastPara);
2311cdf0e10cSrcweir     if (m_aFocused != m_xParagraphs->end() && m_aFocused != aIt
2312cdf0e10cSrcweir         && m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd)
2313cdf0e10cSrcweir     {
2314cdf0e10cSrcweir         ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(m_aFocused));
2315cdf0e10cSrcweir         if (xParagraph.is())
2316cdf0e10cSrcweir             xParagraph->notifyEvent(
2317cdf0e10cSrcweir                 ::css::accessibility::AccessibleEventId::
2318cdf0e10cSrcweir                 STATE_CHANGED,
2319cdf0e10cSrcweir                 ::css::uno::makeAny(
2320cdf0e10cSrcweir                     ::css::accessibility::AccessibleStateType::FOCUSED),
2321cdf0e10cSrcweir                 ::css::uno::Any());
2322cdf0e10cSrcweir     }
2323cdf0e10cSrcweir 
2324cdf0e10cSrcweir     // Gain focus and update cursor position:
2325cdf0e10cSrcweir     if (aIt >= m_aVisibleBegin && aIt < m_aVisibleEnd
2326cdf0e10cSrcweir         && (aIt != m_aFocused
2327cdf0e10cSrcweir             || nNewLastPara != m_nSelectionLastPara
2328cdf0e10cSrcweir             || nNewLastPos != m_nSelectionLastPos))
2329cdf0e10cSrcweir     {
2330cdf0e10cSrcweir         ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(aIt));
2331cdf0e10cSrcweir         if (xParagraph.is())
2332cdf0e10cSrcweir         {
233321075d77SSteve Yin 		//disable the first event when user types in empty field.
233421075d77SSteve Yin 		::sal_Int32 count = getAccessibleChildCount();
233521075d77SSteve Yin 		::sal_Bool bEmpty = count > 1;
233621075d77SSteve Yin             //if (aIt != m_aFocused)
233721075d77SSteve Yin 			if (aIt != m_aFocused && bEmpty)
2338cdf0e10cSrcweir                 xParagraph->notifyEvent(
2339cdf0e10cSrcweir                     ::css::accessibility::AccessibleEventId::
2340cdf0e10cSrcweir                     STATE_CHANGED,
2341cdf0e10cSrcweir                     ::css::uno::Any(),
2342cdf0e10cSrcweir                     ::css::uno::makeAny(
2343cdf0e10cSrcweir                         ::css::accessibility::AccessibleStateType::FOCUSED));
2344cdf0e10cSrcweir             if (nNewLastPara != m_nSelectionLastPara
2345cdf0e10cSrcweir                 || nNewLastPos != m_nSelectionLastPos)
2346cdf0e10cSrcweir                 xParagraph->notifyEvent(
2347cdf0e10cSrcweir                     ::css::accessibility::AccessibleEventId::
2348cdf0e10cSrcweir                     CARET_CHANGED,
2349cdf0e10cSrcweir                     ::css::uno::makeAny< ::sal_Int32 >(
2350cdf0e10cSrcweir                         nNewLastPara == m_nSelectionLastPara
2351cdf0e10cSrcweir                         ? m_nSelectionLastPos : 0),
2352cdf0e10cSrcweir                     ::css::uno::makeAny(nNewLastPos));
2353cdf0e10cSrcweir         }
2354cdf0e10cSrcweir     }
2355cdf0e10cSrcweir     m_aFocused = aIt;
2356cdf0e10cSrcweir 
235721075d77SSteve Yin     ::sal_Int32 nMin;
235821075d77SSteve Yin     ::sal_Int32 nMax;
235921075d77SSteve Yin     ::sal_Int32 ret = getSelectionType(nNewFirstPara, nNewFirstPos, nNewLastPara, nNewLastPos);
236021075d77SSteve Yin 	switch (ret)
236121075d77SSteve Yin 	{
236221075d77SSteve Yin 		case -1:
236321075d77SSteve Yin 			{
236421075d77SSteve Yin 				//no event
236521075d77SSteve Yin 			}
236621075d77SSteve Yin 			break;
236721075d77SSteve Yin 		case 1:
236821075d77SSteve Yin 			{
236921075d77SSteve Yin 				//only caret moved, already handled in above
237021075d77SSteve Yin 			}
237121075d77SSteve Yin 			break;
237221075d77SSteve Yin 		case 2:
237321075d77SSteve Yin 			{
237421075d77SSteve Yin 				//old has no selection but new has selection
237521075d77SSteve Yin 				nMin = ::std::min(nNewFirstPara, nNewLastPara);
237621075d77SSteve Yin 				nMax = ::std::max(nNewFirstPara, nNewLastPara);
237721075d77SSteve Yin 				sendEvent(nMin, nMax,  ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
237821075d77SSteve Yin 				sendEvent(nMin, nMax,  ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
237921075d77SSteve Yin 			}
238021075d77SSteve Yin 			break;
238121075d77SSteve Yin 		case 3:
238221075d77SSteve Yin 			{
238321075d77SSteve Yin 				//old has selection but new has no selection.
238421075d77SSteve Yin 				nMin = ::std::min(m_nSelectionFirstPara, m_nSelectionLastPara);
238521075d77SSteve Yin 				nMax = ::std::max(m_nSelectionFirstPara, m_nSelectionLastPara);
238621075d77SSteve Yin 				sendEvent(nMin, nMax,  ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
238721075d77SSteve Yin 				sendEvent(nMin, nMax,  ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
238821075d77SSteve Yin 			}
238921075d77SSteve Yin 			break;
239021075d77SSteve Yin 		case 4:
239121075d77SSteve Yin 			{
239221075d77SSteve Yin 				//Send text_selection_change event on Nep
239321075d77SSteve Yin 				sendEvent(nNewLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
239421075d77SSteve Yin 			}
239521075d77SSteve Yin 			break;
239621075d77SSteve Yin 		case 5:
239721075d77SSteve Yin 			{
239821075d77SSteve Yin 				// 4, 1 -> 4, 7
239921075d77SSteve Yin 				sendEvent(m_nSelectionLastPara, m_nSelectionFirstPara-1, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
240021075d77SSteve Yin 				sendEvent(nNewFirstPara+1, nNewLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
240121075d77SSteve Yin 
240221075d77SSteve Yin 				sendEvent(m_nSelectionLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
240321075d77SSteve Yin 			}
240421075d77SSteve Yin 			break;
240521075d77SSteve Yin 		case 6:
240621075d77SSteve Yin 			{
240721075d77SSteve Yin 				// 1, 2 -> 1, 4; 4,4->4,5;
240821075d77SSteve Yin 				sendEvent(m_nSelectionLastPara+1, nNewLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
240921075d77SSteve Yin 
241021075d77SSteve Yin 				sendEvent(m_nSelectionLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
241121075d77SSteve Yin 			}
241221075d77SSteve Yin 			break;
241321075d77SSteve Yin 		case 7:
241421075d77SSteve Yin 			{
241521075d77SSteve Yin 				// 4,1 -> 4,3,
241621075d77SSteve Yin 				sendEvent(m_nSelectionLastPara +1, nNewLastPara , ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
241721075d77SSteve Yin 
241821075d77SSteve Yin 				sendEvent(m_nSelectionLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
241921075d77SSteve Yin 			}
242021075d77SSteve Yin 			break;
242121075d77SSteve Yin 		case 8:
242221075d77SSteve Yin 			{
242321075d77SSteve Yin 				// 4,7 ->4,5;
242421075d77SSteve Yin 				sendEvent(nNewLastPara + 1, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
242521075d77SSteve Yin 
242621075d77SSteve Yin 				sendEvent(nNewLastPara, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
242721075d77SSteve Yin 			}
242821075d77SSteve Yin 			break;
242921075d77SSteve Yin 		case 9:
243021075d77SSteve Yin 			{
243121075d77SSteve Yin 				// 3,2 -> 3,1; 4,4->4,3
243221075d77SSteve Yin 				sendEvent(nNewLastPara, m_nSelectionLastPara - 1, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
243321075d77SSteve Yin 
243421075d77SSteve Yin 				sendEvent(nNewLastPara, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
243521075d77SSteve Yin 			}
243621075d77SSteve Yin 			break;
243721075d77SSteve Yin 		case 10:
243821075d77SSteve Yin 			{
243921075d77SSteve Yin 				// 4,7 -> 4,1
244021075d77SSteve Yin 				sendEvent(m_nSelectionFirstPara + 1, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
244121075d77SSteve Yin 				sendEvent(nNewLastPara, nNewFirstPara - 1, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
244221075d77SSteve Yin 
244321075d77SSteve Yin 				sendEvent(nNewLastPara, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
244421075d77SSteve Yin 			}
244521075d77SSteve Yin 			break;
244621075d77SSteve Yin 		default:
244721075d77SSteve Yin 			break;
244821075d77SSteve Yin 	}
244921075d77SSteve Yin 
245021075d77SSteve Yin     /*
2451cdf0e10cSrcweir     // Update both old and new selection.  (Regardless of how the two selections
2452cdf0e10cSrcweir     // look like, there will always be two ranges to the left and right of the
2453cdf0e10cSrcweir     // overlap---the overlap and/or the range to the right of it possibly being
2454cdf0e10cSrcweir     // empty.  Only for these two ranges notifications have to be sent.)
2455cdf0e10cSrcweir 
2456cdf0e10cSrcweir     TextPaM aOldTextStart( static_cast< sal_uLong >( m_nSelectionFirstPara ), static_cast< sal_uInt16 >( m_nSelectionFirstPos ) );
2457cdf0e10cSrcweir     TextPaM aOldTextEnd( static_cast< sal_uLong >( m_nSelectionLastPara ), static_cast< sal_uInt16 >( m_nSelectionLastPos ) );
2458cdf0e10cSrcweir     TextPaM aNewTextStart( static_cast< sal_uLong >( nNewFirstPara ), static_cast< sal_uInt16 >( nNewFirstPos ) );
2459cdf0e10cSrcweir     TextPaM aNewTextEnd( static_cast< sal_uLong >( nNewLastPara ), static_cast< sal_uInt16 >( nNewLastPos ) );
2460cdf0e10cSrcweir 
2461cdf0e10cSrcweir     // justify selections
2462cdf0e10cSrcweir     justifySelection( aOldTextStart, aOldTextEnd );
2463cdf0e10cSrcweir     justifySelection( aNewTextStart, aNewTextEnd );
2464cdf0e10cSrcweir 
2465cdf0e10cSrcweir     sal_Int32 nFirst1;
2466cdf0e10cSrcweir     sal_Int32 nLast1;
2467cdf0e10cSrcweir     sal_Int32 nFirst2;
2468cdf0e10cSrcweir     sal_Int32 nLast2;
2469cdf0e10cSrcweir 
2470cdf0e10cSrcweir     if ( m_nSelectionFirstPara == -1 )
2471cdf0e10cSrcweir     {
2472cdf0e10cSrcweir         // old selection not initialized yet => notify events only for new selection (if not empty)
2473cdf0e10cSrcweir         nFirst1 = aNewTextStart.GetPara();
2474cdf0e10cSrcweir         nLast1 = aNewTextEnd.GetPara() + ( aNewTextStart != aNewTextEnd ? 1 : 0 );
2475cdf0e10cSrcweir         nFirst2 = 0;
2476cdf0e10cSrcweir         nLast2 = 0;
2477cdf0e10cSrcweir     }
2478cdf0e10cSrcweir     else if ( aOldTextStart == aOldTextEnd && aNewTextStart == aNewTextEnd )
2479cdf0e10cSrcweir     {
2480cdf0e10cSrcweir         // old an new selection empty => no events
2481cdf0e10cSrcweir         nFirst1 = 0;
2482cdf0e10cSrcweir         nLast1 = 0;
2483cdf0e10cSrcweir         nFirst2 = 0;
2484cdf0e10cSrcweir         nLast2 = 0;
2485cdf0e10cSrcweir     }
2486cdf0e10cSrcweir     else if ( aOldTextStart != aOldTextEnd && aNewTextStart == aNewTextEnd )
2487cdf0e10cSrcweir     {
2488cdf0e10cSrcweir         // old selection not empty + new selection empty => notify events only for old selection
2489cdf0e10cSrcweir         nFirst1 = aOldTextStart.GetPara();
2490cdf0e10cSrcweir         nLast1 = aOldTextEnd.GetPara() + 1;
2491cdf0e10cSrcweir         nFirst2 = 0;
2492cdf0e10cSrcweir         nLast2 = 0;
2493cdf0e10cSrcweir     }
2494cdf0e10cSrcweir     else if ( aOldTextStart == aOldTextEnd && aNewTextStart != aNewTextEnd )
2495cdf0e10cSrcweir     {
2496cdf0e10cSrcweir         // old selection empty + new selection not empty => notify events only for new selection
2497cdf0e10cSrcweir         nFirst1 = aNewTextStart.GetPara();
2498cdf0e10cSrcweir         nLast1 = aNewTextEnd.GetPara() + 1;
2499cdf0e10cSrcweir         nFirst2 = 0;
2500cdf0e10cSrcweir         nLast2 = 0;
2501cdf0e10cSrcweir     }
2502cdf0e10cSrcweir     else
2503cdf0e10cSrcweir     {
2504cdf0e10cSrcweir         // old and new selection not empty => notify events for the two ranges left and right of the overlap
2505cdf0e10cSrcweir         ::std::vector< TextPaM > aTextPaMs(4);
2506cdf0e10cSrcweir         aTextPaMs[0] = aOldTextStart;
2507cdf0e10cSrcweir         aTextPaMs[1] = aOldTextEnd;
2508cdf0e10cSrcweir         aTextPaMs[2] = aNewTextStart;
2509cdf0e10cSrcweir         aTextPaMs[3] = aNewTextEnd;
2510cdf0e10cSrcweir         ::std::sort( aTextPaMs.begin(), aTextPaMs.end() );
2511cdf0e10cSrcweir 
2512cdf0e10cSrcweir         nFirst1 = aTextPaMs[0].GetPara();
2513cdf0e10cSrcweir         nLast1 = aTextPaMs[1].GetPara() + ( aTextPaMs[0] != aTextPaMs[1] ? 1 : 0 );
2514cdf0e10cSrcweir 
2515cdf0e10cSrcweir         nFirst2 = aTextPaMs[2].GetPara();
2516cdf0e10cSrcweir         nLast2 = aTextPaMs[3].GetPara() + ( aTextPaMs[2] != aTextPaMs[3] ? 1 : 0 );
2517cdf0e10cSrcweir 
2518cdf0e10cSrcweir         // adjust overlapping ranges
2519cdf0e10cSrcweir         if ( nLast1 > nFirst2 )
2520cdf0e10cSrcweir             nLast1 = nFirst2;
2521cdf0e10cSrcweir     }
2522cdf0e10cSrcweir 
2523cdf0e10cSrcweir     // notify selection changes
2524cdf0e10cSrcweir     notifySelectionChange( nFirst1, nLast1 );
2525cdf0e10cSrcweir     notifySelectionChange( nFirst2, nLast2 );
252621075d77SSteve Yin 	*/
2527cdf0e10cSrcweir     m_nSelectionFirstPara = nNewFirstPara;
2528cdf0e10cSrcweir     m_nSelectionFirstPos = nNewFirstPos;
2529cdf0e10cSrcweir     m_nSelectionLastPara = nNewLastPara;
2530cdf0e10cSrcweir     m_nSelectionLastPos = nNewLastPos;
2531cdf0e10cSrcweir }
2532cdf0e10cSrcweir 
notifySelectionChange(sal_Int32 nFirst,sal_Int32 nLast)2533cdf0e10cSrcweir void Document::notifySelectionChange( sal_Int32 nFirst, sal_Int32 nLast )
2534cdf0e10cSrcweir {
2535cdf0e10cSrcweir     if ( nFirst < nLast )
2536cdf0e10cSrcweir     {
2537cdf0e10cSrcweir         Paragraphs::iterator aEnd( ::std::min( m_xParagraphs->begin() + nLast, m_aVisibleEnd ) );
2538cdf0e10cSrcweir         for ( Paragraphs::iterator aIt = ::std::max( m_xParagraphs->begin() + nFirst, m_aVisibleBegin ); aIt < aEnd; ++aIt )
2539cdf0e10cSrcweir         {
2540cdf0e10cSrcweir             ::rtl::Reference< ParagraphImpl > xParagraph( getParagraph( aIt ) );
2541cdf0e10cSrcweir             if ( xParagraph.is() )
2542cdf0e10cSrcweir             {
2543cdf0e10cSrcweir                 xParagraph->notifyEvent(
2544cdf0e10cSrcweir                     ::css::accessibility::AccessibleEventId::SELECTION_CHANGED,
2545cdf0e10cSrcweir                     ::css::uno::Any(), ::css::uno::Any() );
2546cdf0e10cSrcweir                 xParagraph->notifyEvent(
2547cdf0e10cSrcweir                     ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED,
2548cdf0e10cSrcweir                     ::css::uno::Any(), ::css::uno::Any() );
2549cdf0e10cSrcweir             }
2550cdf0e10cSrcweir         }
2551cdf0e10cSrcweir     }
2552cdf0e10cSrcweir }
2553cdf0e10cSrcweir 
justifySelection(TextPaM & rTextStart,TextPaM & rTextEnd)2554cdf0e10cSrcweir void Document::justifySelection( TextPaM& rTextStart, TextPaM& rTextEnd )
2555cdf0e10cSrcweir {
2556cdf0e10cSrcweir     if ( rTextStart > rTextEnd )
2557cdf0e10cSrcweir     {
2558cdf0e10cSrcweir         TextPaM aTextPaM( rTextStart );
2559cdf0e10cSrcweir         rTextStart = rTextEnd;
2560cdf0e10cSrcweir         rTextEnd = aTextPaM;
2561cdf0e10cSrcweir     }
2562cdf0e10cSrcweir }
2563cdf0e10cSrcweir 
disposeParagraphs()2564cdf0e10cSrcweir void Document::disposeParagraphs()
2565cdf0e10cSrcweir {
2566cdf0e10cSrcweir     for (Paragraphs::iterator aIt(m_xParagraphs->begin());
2567cdf0e10cSrcweir          aIt != m_xParagraphs->end(); ++aIt)
2568cdf0e10cSrcweir     {
2569cdf0e10cSrcweir         ::css::uno::Reference< ::css::lang::XComponent > xComponent(
2570cdf0e10cSrcweir             aIt->getParagraph().get(), ::css::uno::UNO_QUERY);
2571cdf0e10cSrcweir         if (xComponent.is())
2572cdf0e10cSrcweir             xComponent->dispose();
2573cdf0e10cSrcweir     }
2574cdf0e10cSrcweir }
2575cdf0e10cSrcweir 
2576cdf0e10cSrcweir // static
mapFontColor(::Color const & rColor)2577cdf0e10cSrcweir ::css::uno::Any Document::mapFontColor(::Color const & rColor)
2578cdf0e10cSrcweir {
2579cdf0e10cSrcweir     return ::css::uno::makeAny(
2580cdf0e10cSrcweir         static_cast< ::sal_Int32 >(COLORDATA_RGB(rColor.GetColor())));
2581cdf0e10cSrcweir         // FIXME  keep transparency?
2582cdf0e10cSrcweir }
2583cdf0e10cSrcweir 
2584cdf0e10cSrcweir // static
mapFontColor(::css::uno::Any const & rColor)2585cdf0e10cSrcweir ::Color Document::mapFontColor(::css::uno::Any const & rColor)
2586cdf0e10cSrcweir {
2587cdf0e10cSrcweir     ::sal_Int32 nColor = 0;
2588cdf0e10cSrcweir     rColor >>= nColor;
2589cdf0e10cSrcweir     return ::Color(static_cast< ::ColorData >(nColor));
2590cdf0e10cSrcweir }
2591cdf0e10cSrcweir 
2592cdf0e10cSrcweir // static
mapFontWeight(::FontWeight nWeight)2593cdf0e10cSrcweir ::css::uno::Any Document::mapFontWeight(::FontWeight nWeight)
2594cdf0e10cSrcweir {
2595cdf0e10cSrcweir     // Map from ::FontWeight to ::css:awt::FontWeight, depends on order of
2596cdf0e10cSrcweir     // elements in ::FontWeight (vcl/vclenum.hxx):
2597cdf0e10cSrcweir     static float const aWeight[]
2598cdf0e10cSrcweir         = { ::css::awt::FontWeight::DONTKNOW, // WEIGHT_DONTKNOW
2599cdf0e10cSrcweir             ::css::awt::FontWeight::THIN, // WEIGHT_THIN
2600cdf0e10cSrcweir             ::css::awt::FontWeight::ULTRALIGHT, // WEIGHT_ULTRALIGHT
2601cdf0e10cSrcweir             ::css::awt::FontWeight::LIGHT, // WEIGHT_LIGHT
2602cdf0e10cSrcweir             ::css::awt::FontWeight::SEMILIGHT, // WEIGHT_SEMILIGHT
2603cdf0e10cSrcweir             ::css::awt::FontWeight::NORMAL, // WEIGHT_NORMAL
2604cdf0e10cSrcweir             ::css::awt::FontWeight::NORMAL, // WEIGHT_MEDIUM
2605cdf0e10cSrcweir             ::css::awt::FontWeight::SEMIBOLD, // WEIGHT_SEMIBOLD
2606cdf0e10cSrcweir             ::css::awt::FontWeight::BOLD, // WEIGHT_BOLD
2607cdf0e10cSrcweir             ::css::awt::FontWeight::ULTRABOLD, // WEIGHT_ULTRABOLD
2608cdf0e10cSrcweir             ::css::awt::FontWeight::BLACK }; // WEIGHT_BLACK
2609cdf0e10cSrcweir     return ::css::uno::makeAny(aWeight[nWeight]);
2610cdf0e10cSrcweir }
2611cdf0e10cSrcweir 
2612cdf0e10cSrcweir // static
mapFontWeight(::css::uno::Any const & rWeight)2613cdf0e10cSrcweir ::FontWeight Document::mapFontWeight(::css::uno::Any const & rWeight)
2614cdf0e10cSrcweir {
2615cdf0e10cSrcweir     float nWeight = ::css::awt::FontWeight::NORMAL;
2616cdf0e10cSrcweir     rWeight >>= nWeight;
2617cdf0e10cSrcweir     return nWeight <= ::css::awt::FontWeight::DONTKNOW ? WEIGHT_DONTKNOW
2618cdf0e10cSrcweir         : nWeight <= ::css::awt::FontWeight::THIN ? WEIGHT_THIN
2619cdf0e10cSrcweir         : nWeight <= ::css::awt::FontWeight::ULTRALIGHT ? WEIGHT_ULTRALIGHT
2620cdf0e10cSrcweir         : nWeight <= ::css::awt::FontWeight::LIGHT ? WEIGHT_LIGHT
2621cdf0e10cSrcweir         : nWeight <= ::css::awt::FontWeight::SEMILIGHT ? WEIGHT_SEMILIGHT
2622cdf0e10cSrcweir         : nWeight <= ::css::awt::FontWeight::NORMAL ? WEIGHT_NORMAL
2623cdf0e10cSrcweir         : nWeight <= ::css::awt::FontWeight::SEMIBOLD ? WEIGHT_SEMIBOLD
2624cdf0e10cSrcweir         : nWeight <= ::css::awt::FontWeight::BOLD ? WEIGHT_BOLD
2625cdf0e10cSrcweir         : nWeight <= ::css::awt::FontWeight::ULTRABOLD ? WEIGHT_ULTRABOLD
2626cdf0e10cSrcweir         : WEIGHT_BLACK;
2627cdf0e10cSrcweir }
2628cdf0e10cSrcweir 
2629cdf0e10cSrcweir }
2630cdf0e10cSrcweir 
2631