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