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 10cdf0e10cSrcweir * 110841af79SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 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: 53cdf0e10cSrcweir inline Paragraph(::rtl::Reference< Document > const & rDocument, 54cdf0e10cSrcweir Paragraphs::size_type nNumber): 55cdf0e10cSrcweir ParagraphImpl(rDocument, nNumber, *this) {} 56cdf0e10cSrcweir }; 57cdf0e10cSrcweir 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 65cdf0e10cSrcweir void SfxListenerGuard::endListening() 66cdf0e10cSrcweir { 67cdf0e10cSrcweir if (m_pNotifier != 0) 68cdf0e10cSrcweir { 69cdf0e10cSrcweir m_rListener.EndListening(*m_pNotifier); 70cdf0e10cSrcweir m_pNotifier = 0; 71cdf0e10cSrcweir } 72cdf0e10cSrcweir } 73cdf0e10cSrcweir 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 81cdf0e10cSrcweir void WindowListenerGuard::endListening() 82cdf0e10cSrcweir { 83cdf0e10cSrcweir if (m_pNotifier != 0) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir m_pNotifier->RemoveEventListener(m_aListener); 86cdf0e10cSrcweir m_pNotifier = 0; 87cdf0e10cSrcweir } 88cdf0e10cSrcweir } 89cdf0e10cSrcweir 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 102cdf0e10cSrcweir ParagraphImpl::numberChanged(bool bIncremented) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir if (bIncremented) 105cdf0e10cSrcweir ++m_nNumber; 106cdf0e10cSrcweir else 107cdf0e10cSrcweir --m_nNumber; 108cdf0e10cSrcweir } 109cdf0e10cSrcweir 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 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 135cdf0e10cSrcweir ParagraphImpl::getAccessibleContext() throw (::css::uno::RuntimeException) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir checkDisposed(); 138cdf0e10cSrcweir return this; 139cdf0e10cSrcweir } 140cdf0e10cSrcweir 141cdf0e10cSrcweir // virtual 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 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 166cdf0e10cSrcweir ParagraphImpl::getAccessibleParent() 167cdf0e10cSrcweir throw (::css::uno::RuntimeException) 168cdf0e10cSrcweir { 169cdf0e10cSrcweir checkDisposed(); 170cdf0e10cSrcweir return m_xDocument->getAccessible(); 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir // virtual 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 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 190cdf0e10cSrcweir ::rtl::OUString SAL_CALL ParagraphImpl::getAccessibleDescription() 191cdf0e10cSrcweir throw (::css::uno::RuntimeException) 192cdf0e10cSrcweir { 193cdf0e10cSrcweir checkDisposed(); 194cdf0e10cSrcweir return ::rtl::OUString(); 195cdf0e10cSrcweir } 196cdf0e10cSrcweir 197cdf0e10cSrcweir // virtual 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 > 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 > 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 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 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 249cdf0e10cSrcweir ParagraphImpl::getAccessibleAtPoint(::css::awt::Point const &) 250cdf0e10cSrcweir throw (::css::uno::RuntimeException) 251cdf0e10cSrcweir { 252cdf0e10cSrcweir checkDisposed(); 253cdf0e10cSrcweir return 0; 254cdf0e10cSrcweir } 255cdf0e10cSrcweir 256cdf0e10cSrcweir // virtual 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 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 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 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 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 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 326cdf0e10cSrcweir ::css::util::Color SAL_CALL ParagraphImpl::getForeground() 327cdf0e10cSrcweir throw (::css::uno::RuntimeException) 328cdf0e10cSrcweir { 329cdf0e10cSrcweir return 0; // TODO 330cdf0e10cSrcweir } 331cdf0e10cSrcweir 332cdf0e10cSrcweir // virtual 333cdf0e10cSrcweir ::css::util::Color SAL_CALL ParagraphImpl::getBackground() 334cdf0e10cSrcweir throw (::css::uno::RuntimeException) 335cdf0e10cSrcweir { 336cdf0e10cSrcweir return 0; // TODO 337cdf0e10cSrcweir } 338cdf0e10cSrcweir 339cdf0e10cSrcweir // virtual 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 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 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 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 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 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 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 412cdf0e10cSrcweir ::rtl::OUString SAL_CALL ParagraphImpl::getSelectedText() 413cdf0e10cSrcweir throw (::css::uno::RuntimeException) 414cdf0e10cSrcweir { 415cdf0e10cSrcweir checkDisposed(); 416cdf0e10cSrcweir 417cdf0e10cSrcweir return OCommonAccessibleText::getSelectedText(); 418cdf0e10cSrcweir } 419cdf0e10cSrcweir 420cdf0e10cSrcweir // virtual 421cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getSelectionStart() 422cdf0e10cSrcweir throw (::css::uno::RuntimeException) 423cdf0e10cSrcweir { 424cdf0e10cSrcweir checkDisposed(); 425cdf0e10cSrcweir return OCommonAccessibleText::getSelectionStart(); 426cdf0e10cSrcweir } 427cdf0e10cSrcweir 428cdf0e10cSrcweir // virtual 429cdf0e10cSrcweir ::sal_Int32 SAL_CALL ParagraphImpl::getSelectionEnd() 430cdf0e10cSrcweir throw (::css::uno::RuntimeException) 431cdf0e10cSrcweir { 432cdf0e10cSrcweir checkDisposed(); 433cdf0e10cSrcweir return OCommonAccessibleText::getSelectionEnd(); 434cdf0e10cSrcweir } 435cdf0e10cSrcweir 436cdf0e10cSrcweir // virtual 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 448cdf0e10cSrcweir ::rtl::OUString SAL_CALL ParagraphImpl::getText() 449cdf0e10cSrcweir throw (::css::uno::RuntimeException) 450cdf0e10cSrcweir { 451cdf0e10cSrcweir checkDisposed(); 452cdf0e10cSrcweir return OCommonAccessibleText::getText(); 453cdf0e10cSrcweir } 454cdf0e10cSrcweir 455cdf0e10cSrcweir // virtual 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 720cdf0e10cSrcweir ::rtl::OUString ParagraphImpl::implGetText() 721cdf0e10cSrcweir { 722cdf0e10cSrcweir return m_xDocument->retrieveParagraphText(this); 723cdf0e10cSrcweir } 724cdf0e10cSrcweir 725cdf0e10cSrcweir // virtual 726cdf0e10cSrcweir ::css::lang::Locale ParagraphImpl::implGetLocale() 727cdf0e10cSrcweir { 728cdf0e10cSrcweir return m_xDocument->retrieveLocale(); 729cdf0e10cSrcweir } 730cdf0e10cSrcweir 731cdf0e10cSrcweir // virtual 732cdf0e10cSrcweir void ParagraphImpl::implGetSelection(::sal_Int32 & rStartIndex, 733cdf0e10cSrcweir ::sal_Int32 & rEndIndex) 734cdf0e10cSrcweir { 735cdf0e10cSrcweir m_xDocument->retrieveParagraphSelection(this, &rStartIndex, &rEndIndex); 736cdf0e10cSrcweir } 737cdf0e10cSrcweir 738cdf0e10cSrcweir // virtual 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 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 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 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 799cdf0e10cSrcweir ::css::lang::Locale Document::retrieveLocale() 800cdf0e10cSrcweir { 801cdf0e10cSrcweir ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); 802cdf0e10cSrcweir return m_rEngine.GetLocale(); 803cdf0e10cSrcweir } 804cdf0e10cSrcweir 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 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 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 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 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 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 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 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; 102021075d77SSteve Yin IndexCompare( const ::css::beans::PropertyValue* pVals ) : pValues(pVals) {} 102121075d77SSteve 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 > 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) ); 116307a3d7f1SPedro Giffuni // create sorted sequences according 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 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 > 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 > 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 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 > 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 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 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 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 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 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 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 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 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 > 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 1534cdf0e10cSrcweir void Document::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) 1535cdf0e10cSrcweir { 1536cdf0e10cSrcweir VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); 1537cdf0e10cSrcweir } 1538cdf0e10cSrcweir 1539cdf0e10cSrcweir // virtual 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 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 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 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 } 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 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 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 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 1650*7950f2afSmseidel // 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 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 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 > 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 > 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 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 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 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(); 1958144e4e62SHerbert Dürr else if ( !rText.isEmpty() ) 1959cdf0e10cSrcweir m_rView.InsertText(rText); 1960cdf0e10cSrcweir } 1961cdf0e10cSrcweir 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 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 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 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 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 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 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 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 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 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 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