LCOV - code coverage report
Current view: top level - accessibility/source/extended - textwindowaccessibility.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 1097 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 119 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <accessibility/extended/textwindowaccessibility.hxx>
      21             : #include <comphelper/accessibleeventnotifier.hxx>
      22             : #include <unotools/accessiblerelationsethelper.hxx>
      23             : #include <unotools/accessiblestatesethelper.hxx>
      24             : #include <vcl/window.hxx>
      25             : #include <toolkit/helper/convert.hxx>
      26             : 
      27             : #include <algorithm>
      28             : #include <vector>
      29             : 
      30             : namespace accessibility
      31             : {
      32           0 : void SfxListenerGuard::startListening(::SfxBroadcaster & rNotifier)
      33             : {
      34             :     OSL_ENSURE(m_pNotifier == 0, "called more than once");
      35           0 :     m_pNotifier = &rNotifier;
      36           0 :     m_rListener.StartListening(*m_pNotifier, true);
      37           0 : }
      38             : 
      39           0 : void SfxListenerGuard::endListening()
      40             : {
      41           0 :     if (m_pNotifier != 0)
      42             :     {
      43           0 :         m_rListener.EndListening(*m_pNotifier);
      44           0 :         m_pNotifier = 0;
      45             :     }
      46           0 : }
      47             : 
      48           0 : void WindowListenerGuard::startListening(vcl::Window & rNotifier)
      49             : {
      50             :     OSL_ENSURE(m_pNotifier == nullptr, "called more than once");
      51           0 :     m_pNotifier = &rNotifier;
      52           0 :     m_pNotifier->AddEventListener(m_aListener);
      53           0 : }
      54             : 
      55           0 : void WindowListenerGuard::endListening()
      56             : {
      57           0 :     if (m_pNotifier)
      58             :     {
      59           0 :         m_pNotifier->RemoveEventListener(m_aListener);
      60           0 :         m_pNotifier = nullptr;
      61             :     }
      62           0 : }
      63             : 
      64           0 : Paragraph::Paragraph(::rtl::Reference< Document > const & rDocument,
      65             :                              Paragraphs::size_type nNumber):
      66             :     ParagraphBase(m_aMutex),
      67             :     m_xDocument(rDocument),
      68             :     m_nNumber(nNumber),
      69           0 :     m_nClientId(0)
      70             : {
      71           0 :     m_aParagraphText = m_xDocument->retrieveParagraphText(this);
      72           0 : }
      73             : 
      74             : void
      75           0 : Paragraph::numberChanged(bool bIncremented)
      76             : {
      77           0 :     if (bIncremented)
      78           0 :         ++m_nNumber;
      79             :     else
      80           0 :         --m_nNumber;
      81           0 : }
      82             : 
      83           0 : void Paragraph::textChanged()
      84             : {
      85           0 :     OUString aParagraphText = implGetText();
      86           0 :     css::uno::Any aOldValue, aNewValue;
      87           0 :     if ( implInitTextChangedEvent( m_aParagraphText, aParagraphText, aOldValue, aNewValue ) )
      88             :     {
      89           0 :         m_aParagraphText = aParagraphText;
      90             :         notifyEvent(css::accessibility::AccessibleEventId::
      91             :                     TEXT_CHANGED,
      92           0 :                     aOldValue, aNewValue);
      93           0 :     }
      94           0 : }
      95             : 
      96           0 : void Paragraph::notifyEvent(::sal_Int16 nEventId,
      97             :                                 css::uno::Any const & rOldValue,
      98             :                                 css::uno::Any const & rNewValue)
      99             : {
     100           0 :     if (m_nClientId)
     101             :         comphelper::AccessibleEventNotifier::addEvent( m_nClientId, css::accessibility::AccessibleEventObject(
     102             :                              static_cast< ::cppu::OWeakObject * >(this),
     103           0 :                              nEventId, rNewValue, rOldValue) );
     104           0 : }
     105             : 
     106             : // virtual
     107             : css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL
     108           0 : Paragraph::getAccessibleContext() throw (css::uno::RuntimeException, std::exception)
     109             : {
     110           0 :     checkDisposed();
     111           0 :     return this;
     112             : }
     113             : 
     114             : // virtual
     115           0 : ::sal_Int32 SAL_CALL Paragraph::getAccessibleChildCount()
     116             :     throw (css::uno::RuntimeException, std::exception)
     117             : {
     118           0 :     checkDisposed();
     119           0 :     return 0;
     120             : }
     121             : 
     122             : // virtual
     123             : css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
     124           0 : Paragraph::getAccessibleChild(::sal_Int32)
     125             :     throw (css::lang::IndexOutOfBoundsException,
     126             :            css::uno::RuntimeException, std::exception)
     127             : {
     128           0 :     checkDisposed();
     129             :     throw css::lang::IndexOutOfBoundsException(
     130             :         "textwindowaccessibility.cxx:"
     131             :         " Paragraph::getAccessibleChild",
     132           0 :         static_cast< css::uno::XWeak * >(this));
     133             : }
     134             : 
     135             : // virtual
     136             : css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
     137           0 : Paragraph::getAccessibleParent()
     138             :     throw (css::uno::RuntimeException, std::exception)
     139             : {
     140           0 :     checkDisposed();
     141           0 :     return m_xDocument->getAccessible();
     142             : }
     143             : 
     144             : // virtual
     145           0 : ::sal_Int32 SAL_CALL Paragraph::getAccessibleIndexInParent()
     146             :     throw (css::uno::RuntimeException, std::exception)
     147             : {
     148           0 :     checkDisposed();
     149           0 :     return m_xDocument->retrieveParagraphIndex(this);
     150             : }
     151             : 
     152             : // virtual
     153           0 : ::sal_Int16 SAL_CALL Paragraph::getAccessibleRole()
     154             :     throw (css::uno::RuntimeException, std::exception)
     155             : {
     156           0 :     checkDisposed();
     157           0 :     return css::accessibility::AccessibleRole::PARAGRAPH;
     158             : }
     159             : 
     160             : // virtual
     161           0 : OUString SAL_CALL Paragraph::getAccessibleDescription()
     162             :     throw (css::uno::RuntimeException, std::exception)
     163             : {
     164           0 :     checkDisposed();
     165           0 :     return OUString();
     166             : }
     167             : 
     168             : // virtual
     169           0 : OUString SAL_CALL Paragraph::getAccessibleName()
     170             :     throw (css::uno::RuntimeException, std::exception)
     171             : {
     172           0 :     checkDisposed();
     173           0 :     return OUString();
     174             : }
     175             : 
     176             : // virtual
     177             : css::uno::Reference< css::accessibility::XAccessibleRelationSet >
     178           0 : SAL_CALL Paragraph::getAccessibleRelationSet()
     179             :     throw (css::uno::RuntimeException, std::exception)
     180             : {
     181           0 :     checkDisposed();
     182           0 :     return m_xDocument->retrieveParagraphRelationSet( this );
     183             : }
     184             : 
     185             : // virtual
     186             : css::uno::Reference< css::accessibility::XAccessibleStateSet >
     187           0 : SAL_CALL Paragraph::getAccessibleStateSet()
     188             :     throw (css::uno::RuntimeException, std::exception)
     189             : {
     190           0 :     checkDisposed();
     191             : 
     192             :     // FIXME  Notification of changes (STATE_CHANGED) missing when
     193             :     // m_rView.IsReadOnly() changes:
     194             :     return new ::utl::AccessibleStateSetHelper(
     195           0 :         m_xDocument->retrieveParagraphState(this));
     196             : }
     197             : 
     198             : // virtual
     199           0 : css::lang::Locale SAL_CALL Paragraph::getLocale()
     200             :     throw (css::accessibility::IllegalAccessibleComponentStateException,
     201             :            css::uno::RuntimeException, std::exception)
     202             : {
     203           0 :     checkDisposed();
     204           0 :     return m_xDocument->retrieveLocale();
     205             : }
     206             : 
     207             : // virtual
     208           0 : sal_Bool SAL_CALL Paragraph::containsPoint(css::awt::Point const & rPoint)
     209             :     throw (css::uno::RuntimeException, std::exception)
     210             : {
     211           0 :     checkDisposed();
     212             :     css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this,
     213           0 :                                                                      false));
     214           0 :     return rPoint.X >= 0 && rPoint.X < aRect.Width
     215           0 :         && rPoint.Y >= 0 && rPoint.Y < aRect.Height;
     216             : }
     217             : 
     218             : // virtual
     219             : css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
     220           0 : Paragraph::getAccessibleAtPoint(css::awt::Point const &)
     221             :     throw (css::uno::RuntimeException, std::exception)
     222             : {
     223           0 :     checkDisposed();
     224           0 :     return 0;
     225             : }
     226             : 
     227             : // virtual
     228           0 : css::awt::Rectangle SAL_CALL Paragraph::getBounds()
     229             :     throw (css::uno::RuntimeException, std::exception)
     230             : {
     231           0 :     checkDisposed();
     232           0 :     return m_xDocument->retrieveParagraphBounds(this, false);
     233             : }
     234             : 
     235             : // virtual
     236           0 : css::awt::Point SAL_CALL Paragraph::getLocation()
     237             :     throw (css::uno::RuntimeException, std::exception)
     238             : {
     239           0 :     checkDisposed();
     240             :     css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this,
     241           0 :                                                                      false));
     242           0 :     return css::awt::Point(aRect.X, aRect.Y);
     243             : }
     244             : 
     245             : // virtual
     246           0 : css::awt::Point SAL_CALL Paragraph::getLocationOnScreen()
     247             :     throw (css::uno::RuntimeException, std::exception)
     248             : {
     249           0 :     checkDisposed();
     250             :     css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this,
     251           0 :                                                                      true));
     252           0 :     return css::awt::Point(aRect.X, aRect.Y);
     253             : }
     254             : 
     255             : // virtual
     256           0 : css::awt::Size SAL_CALL Paragraph::getSize()
     257             :     throw (css::uno::RuntimeException, std::exception)
     258             : {
     259           0 :     checkDisposed();
     260             :     css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this,
     261           0 :                                                                      false));
     262           0 :     return css::awt::Size(aRect.Width, aRect.Height);
     263             : }
     264             : 
     265             : // virtual
     266           0 : void SAL_CALL Paragraph::grabFocus() throw (css::uno::RuntimeException, std::exception)
     267             : {
     268           0 :     checkDisposed();
     269           0 :     vcl::Window* pWindow = m_xDocument->GetWindow();
     270           0 :     if ( pWindow )
     271             :     {
     272           0 :         pWindow->GrabFocus();
     273             :     }
     274             :     try
     275             :     {
     276           0 :         m_xDocument->changeParagraphSelection(this, 0, 0);
     277             :     }
     278           0 :     catch (const css::lang::IndexOutOfBoundsException & rEx)
     279             :     {
     280             :         OSL_TRACE(
     281             :             "textwindowaccessibility.cxx: Paragraph::grabFocus:"
     282             :             " caught unexpected %s\n",
     283             :             OUStringToOString(rEx.Message, RTL_TEXTENCODING_UTF8).
     284             :             getStr());
     285             :     }
     286           0 : }
     287             : 
     288             : // virtual
     289           0 : css::util::Color SAL_CALL Paragraph::getForeground()
     290             :     throw (css::uno::RuntimeException, std::exception)
     291             : {
     292           0 :     return 0; // TODO
     293             : }
     294             : 
     295             : // virtual
     296           0 : css::util::Color SAL_CALL Paragraph::getBackground()
     297             :     throw (css::uno::RuntimeException, std::exception)
     298             : {
     299           0 :     return 0; // TODO
     300             : }
     301             : 
     302             : // virtual
     303           0 : ::sal_Int32 SAL_CALL Paragraph::getCaretPosition()
     304             :     throw (css::uno::RuntimeException, std::exception)
     305             : {
     306           0 :     checkDisposed();
     307           0 :     return m_xDocument->retrieveParagraphCaretPosition(this);
     308             : }
     309             : 
     310             : // virtual
     311           0 : sal_Bool SAL_CALL Paragraph::setCaretPosition(::sal_Int32 nIndex)
     312             :     throw (css::lang::IndexOutOfBoundsException,
     313             :            css::uno::RuntimeException, std::exception)
     314             : {
     315           0 :     checkDisposed();
     316           0 :     m_xDocument->changeParagraphSelection(this, nIndex, nIndex);
     317           0 :     return true;
     318             : }
     319             : 
     320             : // virtual
     321           0 : ::sal_Unicode SAL_CALL Paragraph::getCharacter(::sal_Int32 nIndex)
     322             :     throw (css::lang::IndexOutOfBoundsException,
     323             :            css::uno::RuntimeException, std::exception)
     324             : {
     325           0 :     checkDisposed();
     326           0 :     return OCommonAccessibleText::getCharacter(nIndex);
     327             : }
     328             : 
     329             : // virtual
     330             : css::uno::Sequence< css::beans::PropertyValue > SAL_CALL
     331           0 : Paragraph::getCharacterAttributes(::sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< OUString >& aRequestedAttributes)
     332             :     throw (css::lang::IndexOutOfBoundsException,
     333             :            css::uno::RuntimeException, std::exception)
     334             : {
     335           0 :     checkDisposed();
     336           0 :     return m_xDocument->retrieveCharacterAttributes( this, nIndex, aRequestedAttributes );
     337             : }
     338             : 
     339             : // virtual
     340             : css::awt::Rectangle SAL_CALL
     341           0 : Paragraph::getCharacterBounds(::sal_Int32 nIndex)
     342             :     throw (css::lang::IndexOutOfBoundsException,
     343             :            css::uno::RuntimeException, std::exception)
     344             : {
     345           0 :     checkDisposed();
     346           0 :     css::awt::Rectangle aBounds(m_xDocument->retrieveCharacterBounds(this, nIndex));
     347           0 :     css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false));
     348           0 :     aBounds.X -= aParaBounds.X;
     349           0 :     aBounds.Y -= aParaBounds.Y;
     350           0 :     return aBounds;
     351             : }
     352             : 
     353             : // virtual
     354           0 : ::sal_Int32 SAL_CALL Paragraph::getCharacterCount()
     355             :     throw (css::uno::RuntimeException, std::exception)
     356             : {
     357           0 :     checkDisposed();
     358           0 :     return OCommonAccessibleText::getCharacterCount();
     359             : }
     360             : 
     361             : // virtual
     362             : ::sal_Int32 SAL_CALL
     363           0 : Paragraph::getIndexAtPoint(css::awt::Point const & rPoint)
     364             :     throw (css::uno::RuntimeException, std::exception)
     365             : {
     366           0 :     checkDisposed();
     367           0 :     css::awt::Point aPoint(rPoint);
     368           0 :     css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false));
     369           0 :     aPoint.X += aParaBounds.X;
     370           0 :     aPoint.Y += aParaBounds.Y;
     371           0 :     return m_xDocument->retrieveCharacterIndex(this, aPoint);
     372             : }
     373             : 
     374             : // virtual
     375           0 : OUString SAL_CALL Paragraph::getSelectedText()
     376             :     throw (css::uno::RuntimeException, std::exception)
     377             : {
     378           0 :     checkDisposed();
     379             : 
     380           0 :     return OCommonAccessibleText::getSelectedText();
     381             : }
     382             : 
     383             : // virtual
     384           0 : ::sal_Int32 SAL_CALL Paragraph::getSelectionStart()
     385             :     throw (css::uno::RuntimeException, std::exception)
     386             : {
     387           0 :     checkDisposed();
     388           0 :     return OCommonAccessibleText::getSelectionStart();
     389             : }
     390             : 
     391             : // virtual
     392           0 : ::sal_Int32 SAL_CALL Paragraph::getSelectionEnd()
     393             :     throw (css::uno::RuntimeException, std::exception)
     394             : {
     395           0 :     checkDisposed();
     396           0 :     return OCommonAccessibleText::getSelectionEnd();
     397             : }
     398             : 
     399             : // virtual
     400           0 : sal_Bool SAL_CALL Paragraph::setSelection(::sal_Int32 nStartIndex,
     401             :                                                 ::sal_Int32 nEndIndex)
     402             :     throw (css::lang::IndexOutOfBoundsException,
     403             :            css::uno::RuntimeException, std::exception)
     404             : {
     405           0 :     checkDisposed();
     406           0 :     m_xDocument->changeParagraphSelection(this, nStartIndex, nEndIndex);
     407           0 :     return true;
     408             : }
     409             : 
     410             : // virtual
     411           0 : OUString SAL_CALL Paragraph::getText()
     412             :     throw (css::uno::RuntimeException, std::exception)
     413             : {
     414           0 :     checkDisposed();
     415           0 :     return OCommonAccessibleText::getText();
     416             : }
     417             : 
     418             : // virtual
     419           0 : OUString SAL_CALL Paragraph::getTextRange(::sal_Int32 nStartIndex,
     420             :                                                      ::sal_Int32 nEndIndex)
     421             :     throw (css::lang::IndexOutOfBoundsException,
     422             :            css::uno::RuntimeException, std::exception)
     423             : {
     424           0 :     checkDisposed();
     425           0 :     return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex);
     426             : }
     427             : 
     428             : // virtual
     429           0 : ::com::sun::star::accessibility::TextSegment SAL_CALL Paragraph::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
     430             : {
     431           0 :     checkDisposed();
     432           0 :     return OCommonAccessibleText::getTextAtIndex(nIndex, aTextType);
     433             : }
     434             : 
     435             : // virtual
     436           0 : ::com::sun::star::accessibility::TextSegment SAL_CALL Paragraph::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
     437             : {
     438           0 :     checkDisposed();
     439           0 :     return OCommonAccessibleText::getTextBeforeIndex(nIndex, aTextType);
     440             : }
     441             : 
     442             : // virtual
     443           0 : ::com::sun::star::accessibility::TextSegment SAL_CALL Paragraph::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
     444             : {
     445           0 :     checkDisposed();
     446           0 :     return OCommonAccessibleText::getTextBehindIndex(nIndex, aTextType);
     447             : }
     448             : 
     449             : // virtual
     450           0 : sal_Bool SAL_CALL Paragraph::copyText(::sal_Int32 nStartIndex,
     451             :                                             ::sal_Int32 nEndIndex)
     452             :     throw (css::lang::IndexOutOfBoundsException,
     453             :            css::uno::RuntimeException, std::exception)
     454             : {
     455           0 :     checkDisposed();
     456           0 :     m_xDocument->copyParagraphText(this, nStartIndex, nEndIndex);
     457           0 :     return true;
     458             : }
     459             : 
     460             : // virtual
     461           0 : sal_Bool SAL_CALL Paragraph::cutText(::sal_Int32 nStartIndex,
     462             :                                            ::sal_Int32 nEndIndex)
     463             :     throw (css::lang::IndexOutOfBoundsException,
     464             :            css::uno::RuntimeException, std::exception)
     465             : {
     466           0 :     checkDisposed();
     467             :     m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, true, false,
     468           0 :                                      OUString());
     469           0 :     return true;
     470             : }
     471             : 
     472             : // virtual
     473           0 : sal_Bool SAL_CALL Paragraph::pasteText(::sal_Int32 nIndex)
     474             :     throw (css::lang::IndexOutOfBoundsException,
     475             :            css::uno::RuntimeException, std::exception)
     476             : {
     477           0 :     checkDisposed();
     478             :     m_xDocument->changeParagraphText(this, nIndex, nIndex, false, true,
     479           0 :                                      OUString());
     480           0 :     return true;
     481             : }
     482             : 
     483             : // virtual
     484           0 : sal_Bool SAL_CALL Paragraph::deleteText(::sal_Int32 nStartIndex,
     485             :                                           ::sal_Int32 nEndIndex)
     486             :     throw (css::lang::IndexOutOfBoundsException,
     487             :            css::uno::RuntimeException, std::exception)
     488             : {
     489           0 :     checkDisposed();
     490             :     m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false,
     491           0 :                                      OUString());
     492           0 :     return true;
     493             : }
     494             : 
     495             : // virtual
     496           0 : sal_Bool SAL_CALL Paragraph::insertText(OUString const & rText,
     497             :                                               ::sal_Int32 nIndex)
     498             :     throw (css::lang::IndexOutOfBoundsException,
     499             :            css::uno::RuntimeException, std::exception)
     500             : {
     501           0 :     checkDisposed();
     502           0 :     m_xDocument->changeParagraphText(this, nIndex, nIndex, false, false, rText);
     503           0 :     return true;
     504             : }
     505             : 
     506             : // virtual
     507             : sal_Bool SAL_CALL
     508           0 : Paragraph::replaceText(::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex,
     509             :                            OUString const & rReplacement)
     510             :     throw (css::lang::IndexOutOfBoundsException,
     511             :            css::uno::RuntimeException, std::exception)
     512             : {
     513           0 :     checkDisposed();
     514             :     m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false,
     515           0 :                                      rReplacement);
     516           0 :     return true;
     517             : }
     518             : 
     519             : // virtual
     520           0 : sal_Bool SAL_CALL Paragraph::setAttributes(
     521             :     ::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex,
     522             :     css::uno::Sequence< css::beans::PropertyValue > const & rAttributeSet)
     523             :     throw (css::lang::IndexOutOfBoundsException,
     524             :            css::uno::RuntimeException, std::exception)
     525             : {
     526           0 :     checkDisposed();
     527             :     m_xDocument->changeParagraphAttributes(this, nStartIndex, nEndIndex,
     528           0 :                                            rAttributeSet);
     529           0 :     return true;
     530             : }
     531             : 
     532             : // virtual
     533           0 : sal_Bool SAL_CALL Paragraph::setText(OUString const & rText)
     534             :     throw (css::uno::RuntimeException, std::exception)
     535             : {
     536           0 :     checkDisposed();
     537           0 :     m_xDocument->changeParagraphText(this, rText);
     538           0 :     return true;
     539             : }
     540             : 
     541             : // virtual
     542             : css::uno::Sequence< css::beans::PropertyValue > SAL_CALL
     543           0 : Paragraph::getDefaultAttributes(const css::uno::Sequence< OUString >& RequestedAttributes)
     544             :     throw (css::uno::RuntimeException, std::exception)
     545             : {
     546           0 :     checkDisposed();
     547           0 :     return m_xDocument->retrieveDefaultAttributes( this, RequestedAttributes );
     548             : }
     549             : 
     550             : // virtual
     551             : css::uno::Sequence< css::beans::PropertyValue > SAL_CALL
     552           0 : Paragraph::getRunAttributes(::sal_Int32 Index, const css::uno::Sequence< OUString >& RequestedAttributes)
     553             :     throw (css::lang::IndexOutOfBoundsException,
     554             :            css::uno::RuntimeException, std::exception)
     555             : {
     556           0 :     checkDisposed();
     557           0 :     return m_xDocument->retrieveRunAttributes( this, Index, RequestedAttributes );
     558             : }
     559             : 
     560             : // virtual
     561           0 : ::sal_Int32 SAL_CALL Paragraph::getLineNumberAtIndex( ::sal_Int32 nIndex )
     562             :     throw (css::lang::IndexOutOfBoundsException,
     563             :            css::uno::RuntimeException, std::exception)
     564             : {
     565           0 :     checkDisposed();
     566             : 
     567           0 :     ::sal_Int32 nLineNo = -1;
     568           0 :     m_xDocument->retrieveParagraphLineBoundary( this, nIndex, &nLineNo );
     569             : 
     570           0 :     return nLineNo;
     571             : }
     572             : 
     573             : // virtual
     574           0 : css::accessibility::TextSegment SAL_CALL Paragraph::getTextAtLineNumber( ::sal_Int32 nLineNo )
     575             :     throw (css::lang::IndexOutOfBoundsException,
     576             :            css::uno::RuntimeException, std::exception)
     577             : {
     578           0 :     checkDisposed();
     579             : 
     580             :     css::i18n::Boundary aBoundary =
     581           0 :         m_xDocument->retrieveParagraphBoundaryOfLine( this, nLineNo );
     582             : 
     583           0 :     return css::accessibility::TextSegment( getTextRange(aBoundary.startPos, aBoundary.endPos),
     584           0 :         aBoundary.startPos, aBoundary.endPos);
     585             : }
     586             : 
     587             : // virtual
     588           0 : css::accessibility::TextSegment SAL_CALL Paragraph::getTextAtLineWithCaret(  )
     589             :     throw (css::uno::RuntimeException, std::exception)
     590             : {
     591           0 :     checkDisposed();
     592             : 
     593           0 :     sal_Int32 nLineNo = getNumberOfLineWithCaret();
     594             : 
     595             :     try {
     596             :         return ( nLineNo >= 0 ) ?
     597           0 :             getTextAtLineNumber( nLineNo ) :
     598           0 :             css::accessibility::TextSegment();
     599           0 :     } catch (const css::lang::IndexOutOfBoundsException&) {
     600             :         throw css::uno::RuntimeException(
     601             :             "textwindowaccessibility.cxx:"
     602             :             " Paragraph::getTextAtLineWithCaret",
     603           0 :             static_cast< css::uno::XWeak * >( this ) );
     604             :     }
     605             : }
     606             : 
     607             : // virtual
     608           0 : ::sal_Int32 SAL_CALL Paragraph::getNumberOfLineWithCaret(  )
     609             :     throw (css::uno::RuntimeException, std::exception)
     610             : {
     611           0 :     checkDisposed();
     612           0 :     return m_xDocument->retrieveParagraphLineWithCursor(this);
     613             : }
     614             : 
     615             : 
     616             : // virtual
     617           0 : void SAL_CALL Paragraph::addAccessibleEventListener(
     618             :     css::uno::Reference<
     619             :     css::accessibility::XAccessibleEventListener > const & rListener)
     620             :     throw (css::uno::RuntimeException, std::exception)
     621             : {
     622           0 :     if (rListener.is())
     623             :     {
     624           0 :         ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
     625           0 :         if (rBHelper.bDisposed || rBHelper.bInDispose)
     626             :         {
     627           0 :             aGuard.clear();
     628           0 :             rListener->disposing(css::lang::EventObject(
     629           0 :                                     static_cast< ::cppu::OWeakObject * >(this)));
     630             :         }
     631             :         else
     632             :         {
     633           0 :             if (!m_nClientId)
     634           0 :                 m_nClientId = comphelper::AccessibleEventNotifier::registerClient( );
     635           0 :             comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, rListener );
     636           0 :         }
     637             :     }
     638           0 : }
     639             : 
     640             : // virtual
     641           0 : void SAL_CALL Paragraph::removeAccessibleEventListener(
     642             :     css::uno::Reference<
     643             :     css::accessibility::XAccessibleEventListener > const & rListener)
     644             :     throw (css::uno::RuntimeException, std::exception)
     645             : {
     646           0 :     comphelper::AccessibleEventNotifier::TClientId nId = 0;
     647             :     {
     648           0 :         ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
     649           0 :         if (rListener.is() && m_nClientId != 0
     650           0 :             && comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, rListener ) == 0)
     651             :         {
     652           0 :             nId = m_nClientId;
     653           0 :             m_nClientId = 0;
     654           0 :         }
     655             :     }
     656           0 :     if (nId != 0)
     657             :     {
     658             :         // no listeners anymore
     659             :         // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
     660             :         // and at least to us not firing any events anymore, in case somebody calls
     661             :         // NotifyAccessibleEvent, again
     662           0 :         comphelper::AccessibleEventNotifier::revokeClient(nId);
     663             :     }
     664           0 : }
     665             : 
     666             : // virtual
     667           0 : void SAL_CALL Paragraph::disposing()
     668             : {
     669           0 :     comphelper::AccessibleEventNotifier::TClientId nId = 0;
     670             :     {
     671           0 :         ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex);
     672           0 :         nId = m_nClientId;
     673           0 :         m_nClientId = 0;
     674             :     }
     675           0 :     if (nId != 0)
     676           0 :         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(nId, *this);
     677           0 : }
     678             : 
     679             : // virtual
     680           0 : OUString Paragraph::implGetText()
     681             : {
     682           0 :     return m_xDocument->retrieveParagraphText(this);
     683             : }
     684             : 
     685             : // virtual
     686           0 : css::lang::Locale Paragraph::implGetLocale()
     687             : {
     688           0 :     return m_xDocument->retrieveLocale();
     689             : }
     690             : 
     691             : // virtual
     692           0 : void Paragraph::implGetSelection(::sal_Int32 & rStartIndex,
     693             :                                      ::sal_Int32 & rEndIndex)
     694             : {
     695           0 :     m_xDocument->retrieveParagraphSelection(this, &rStartIndex, &rEndIndex);
     696           0 : }
     697             : 
     698             : // virtual
     699           0 : void Paragraph::implGetParagraphBoundary( css::i18n::Boundary& rBoundary,
     700             :                                               ::sal_Int32 nIndex )
     701             : {
     702           0 :     OUString sText( implGetText() );
     703           0 :     ::sal_Int32 nLength = sText.getLength();
     704             : 
     705           0 :     if ( implIsValidIndex( nIndex, nLength ) )
     706             :     {
     707           0 :         rBoundary.startPos = 0;
     708           0 :         rBoundary.endPos = nLength;
     709             :     }
     710             :     else
     711             :     {
     712           0 :         rBoundary.startPos = nIndex;
     713           0 :         rBoundary.endPos = nIndex;
     714           0 :     }
     715           0 : }
     716             : 
     717             : // virtual
     718           0 : void Paragraph::implGetLineBoundary( css::i18n::Boundary& rBoundary,
     719             :                                          ::sal_Int32 nIndex )
     720             : {
     721           0 :     OUString sText( implGetText() );
     722           0 :     ::sal_Int32 nLength = sText.getLength();
     723             : 
     724           0 :     if ( implIsValidIndex( nIndex, nLength ) || nIndex == nLength )
     725             :     {
     726             :         css::i18n::Boundary aBoundary =
     727           0 :             m_xDocument->retrieveParagraphLineBoundary( this, nIndex );
     728           0 :         rBoundary.startPos = aBoundary.startPos;
     729           0 :         rBoundary.endPos = aBoundary.endPos;
     730             :     }
     731             :     else
     732             :     {
     733           0 :         rBoundary.startPos = nIndex;
     734           0 :         rBoundary.endPos = nIndex;
     735           0 :     }
     736           0 : }
     737             : 
     738             : 
     739           0 : void Paragraph::checkDisposed()
     740             : {
     741           0 :     ::osl::MutexGuard aGuard(rBHelper.rMutex);
     742           0 :     if (!(rBHelper.bDisposed || rBHelper.bInDispose))
     743           0 :         return;
     744             :     throw css::lang::DisposedException(
     745           0 :         OUString(), static_cast< css::uno::XWeak * >(this));
     746             : }
     747             : 
     748           0 : Document::Document(::VCLXWindow * pVclXWindow, ::TextEngine & rEngine,
     749             :                    ::TextView & rView):
     750             :     VCLXAccessibleComponent(pVclXWindow),
     751             :     m_xAccessible(pVclXWindow),
     752             :     m_rEngine(rEngine),
     753             :     m_rView(rView),
     754             :     m_aEngineListener(*this),
     755             :     m_aViewListener(LINK(this, Document, WindowEventHandler)),
     756             :     m_nViewOffset(0),
     757             :     m_nViewHeight(0),
     758             :     m_nVisibleBeginOffset(0),
     759             :     m_nSelectionFirstPara(-1),
     760             :     m_nSelectionFirstPos(-1),
     761             :     m_nSelectionLastPara(-1),
     762             :     m_nSelectionLastPos(-1),
     763           0 :     m_bSelectionChangedNotification(false)
     764           0 : {}
     765             : 
     766           0 : css::lang::Locale Document::retrieveLocale()
     767             : {
     768           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
     769           0 :     return m_rEngine.GetLocale();
     770             : }
     771             : 
     772           0 : ::sal_Int32 Document::retrieveParagraphIndex(Paragraph const * pParagraph)
     773             : {
     774           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
     775             : 
     776             :     // If a client holds on to a Paragraph that is no longer visible, it can
     777             :     // happen that this Paragraph lies outside the range from m_aVisibleBegin
     778             :     // to m_aVisibleEnd.  In that case, return -1 instead of a valid index:
     779           0 :     Paragraphs::iterator aPara(m_xParagraphs->begin()
     780           0 :                                + pParagraph->getNumber());
     781           0 :     return aPara < m_aVisibleBegin || aPara >= m_aVisibleEnd
     782           0 :         ? -1 : static_cast< ::sal_Int32 >(aPara - m_aVisibleBegin);
     783             :         // XXX  numeric overflow
     784             : }
     785             : 
     786           0 : ::sal_Int64 Document::retrieveParagraphState(Paragraph const * pParagraph)
     787             : {
     788           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
     789             : 
     790             :     // If a client holds on to a Paragraph that is no longer visible, it can
     791             :     // happen that this Paragraph lies outside the range from m_aVisibleBegin
     792             :     // to m_aVisibleEnd.  In that case, it is neither VISIBLE nor SHOWING:
     793             :     ::sal_Int64 nState
     794             :           = (static_cast< ::sal_Int64 >(1)
     795             :              << css::accessibility::AccessibleStateType::ENABLED)
     796             :           | (static_cast< ::sal_Int64 >(1)
     797             :              << css::accessibility::AccessibleStateType::SENSITIVE)
     798             :           | (static_cast< ::sal_Int64 >(1)
     799             :              << css::accessibility::AccessibleStateType::FOCUSABLE)
     800             :           | (static_cast< ::sal_Int64 >(1)
     801           0 :              << css::accessibility::AccessibleStateType::MULTI_LINE);
     802           0 :     if (!m_rView.IsReadOnly())
     803             :         nState |= (static_cast< ::sal_Int64 >(1)
     804           0 :                    << css::accessibility::AccessibleStateType::EDITABLE);
     805           0 :     Paragraphs::iterator aPara(m_xParagraphs->begin()
     806           0 :                                + pParagraph->getNumber());
     807           0 :     if (aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd)
     808             :     {
     809             :         nState
     810             :             |= (static_cast< ::sal_Int64 >(1)
     811             :                 << css::accessibility::AccessibleStateType::VISIBLE)
     812             :             | (static_cast< ::sal_Int64 >(1)
     813           0 :                << css::accessibility::AccessibleStateType::SHOWING);
     814           0 :         if (aPara == m_aFocused)
     815             :             nState |= (static_cast< ::sal_Int64 >(1)
     816           0 :                        << css::accessibility::AccessibleStateType::FOCUSED);
     817             :     }
     818           0 :     return nState;
     819             : };
     820             : 
     821             : css::awt::Rectangle
     822           0 : Document::retrieveParagraphBounds(Paragraph const * pParagraph,
     823             :                                   bool bAbsolute)
     824             : {
     825           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
     826           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
     827             : 
     828             :     // If a client holds on to a Paragraph that is no longer visible (as it
     829             :     // scrolled out the top of the view), it can happen that this Paragraph
     830             :     // lies before m_aVisibleBegin.  In that case, calculate the vertical
     831             :     // position of the Paragraph starting at paragraph 0, otherwise optimize
     832             :     // and start at m_aVisibleBegin:
     833           0 :     Paragraphs::iterator aPara(m_xParagraphs->begin()
     834           0 :                                + pParagraph->getNumber());
     835             :     ::sal_Int32 nPos;
     836           0 :     Paragraphs::iterator aIt;
     837           0 :     if (aPara < m_aVisibleBegin)
     838             :     {
     839           0 :         nPos = 0;
     840           0 :         aIt = m_xParagraphs->begin();
     841             :     }
     842             :     else
     843             :     {
     844           0 :         nPos = m_nViewOffset - m_nVisibleBeginOffset;
     845           0 :         aIt = m_aVisibleBegin;
     846             :     }
     847           0 :     for (; aIt != aPara; ++aIt)
     848           0 :         nPos += aIt->getHeight();
     849             : 
     850           0 :     Point aOrig(0, 0);
     851           0 :     if (bAbsolute)
     852           0 :         aOrig = m_rView.GetWindow()->OutputToAbsoluteScreenPixel(aOrig);
     853             : 
     854             :     return css::awt::Rectangle(
     855           0 :         static_cast< ::sal_Int32 >(aOrig.X()),
     856           0 :         static_cast< ::sal_Int32 >(aOrig.Y()) + nPos - m_nViewOffset,
     857           0 :         m_rView.GetWindow()->GetOutputSizePixel().Width(), aPara->getHeight());
     858             :         // XXX  numeric overflow (3x)
     859             : }
     860             : 
     861             : OUString
     862           0 : Document::retrieveParagraphText(Paragraph const * pParagraph)
     863             : {
     864           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
     865           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
     866           0 :     return m_rEngine.GetText(static_cast< ::sal_uLong >(pParagraph->getNumber()));
     867             :         // numeric overflow cannot happen here
     868             : }
     869             : 
     870           0 : void Document::retrieveParagraphSelection(Paragraph const * pParagraph,
     871             :                                           ::sal_Int32 * pBegin,
     872             :                                           ::sal_Int32 * pEnd)
     873             : {
     874           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
     875           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
     876           0 :     ::TextSelection const & rSelection = m_rView.GetSelection();
     877           0 :     Paragraphs::size_type nNumber = pParagraph->getNumber();
     878           0 :     TextPaM aStartPaM( rSelection.GetStart() );
     879           0 :     TextPaM aEndPaM( rSelection.GetEnd() );
     880           0 :     TextPaM aMinPaM( ::std::min( aStartPaM, aEndPaM ) );
     881           0 :     TextPaM aMaxPaM( ::std::max( aStartPaM, aEndPaM ) );
     882             : 
     883           0 :     if ( nNumber >= aMinPaM.GetPara() && nNumber <= aMaxPaM.GetPara() )
     884             :     {
     885           0 :         *pBegin = nNumber > aMinPaM.GetPara()
     886             :             ? 0
     887           0 :             : static_cast< ::sal_Int32 >( aMinPaM.GetIndex() );
     888             :             // XXX numeric overflow
     889           0 :         *pEnd = nNumber < aMaxPaM.GetPara()
     890           0 :             ? static_cast< ::sal_Int32 >( m_rEngine.GetText(static_cast< ::sal_uLong >(nNumber)).getLength() )
     891           0 :             : static_cast< ::sal_Int32 >( aMaxPaM.GetIndex() );
     892             :             // XXX  numeric overflow (3x)
     893             : 
     894           0 :         if ( aStartPaM > aEndPaM )
     895           0 :             ::std::swap( *pBegin, *pEnd );
     896             :     }
     897             :     else
     898             :     {
     899           0 :         *pBegin = 0;
     900           0 :         *pEnd = 0;
     901           0 :     }
     902           0 : }
     903             : 
     904           0 : ::sal_Int32 Document::retrieveParagraphCaretPosition(Paragraph const * pParagraph)
     905             : {
     906           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
     907           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
     908           0 :     ::TextSelection const & rSelection = m_rView.GetSelection();
     909           0 :     Paragraphs::size_type nNumber = pParagraph->getNumber();
     910           0 :     TextPaM aEndPaM( rSelection.GetEnd() );
     911             : 
     912           0 :     return aEndPaM.GetPara() == nNumber
     913           0 :         ? static_cast< ::sal_Int32 >(aEndPaM.GetIndex()) : -1;
     914             : }
     915             : 
     916             : css::awt::Rectangle
     917           0 : Document::retrieveCharacterBounds(Paragraph const * pParagraph,
     918             :                                   ::sal_Int32 nIndex)
     919             : {
     920           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
     921           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
     922           0 :     ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
     923           0 :     sal_Int32 nLength = m_rEngine.GetText(nNumber).getLength();
     924             :         // XXX  numeric overflow
     925           0 :     if (nIndex < 0 || nIndex > nLength)
     926             :         throw css::lang::IndexOutOfBoundsException(
     927             :             "textwindowaccessibility.cxx:"
     928             :             " Document::retrieveCharacterAttributes",
     929           0 :             static_cast< css::uno::XWeak * >(this));
     930           0 :     css::awt::Rectangle aBounds( 0, 0, 0, 0 );
     931           0 :     if ( nIndex == nLength )
     932             :     {
     933             :         aBounds = AWTRectangle(
     934             :             m_rEngine.PaMtoEditCursor(::TextPaM(nNumber,
     935           0 :                                                 static_cast< ::sal_uInt16 >(nIndex))));
     936             :     }
     937             :     else
     938             :     {
     939             :         ::Rectangle aLeft(
     940             :             m_rEngine.PaMtoEditCursor(::TextPaM(nNumber,
     941           0 :                                                 static_cast< ::sal_uInt16 >(nIndex))));
     942             :             // XXX  numeric overflow
     943             :         ::Rectangle aRight(
     944             :             m_rEngine.PaMtoEditCursor(::TextPaM(nNumber,
     945             :                                                 static_cast< ::sal_uInt16 >(nIndex)
     946           0 :                                                 + 1)));
     947             :             // XXX  numeric overflow (2x)
     948             :         // FIXME  If the vertical extends of the two cursors do not match, assume
     949             :         // nIndex is the last character on the line; the bounding box will then
     950             :         // extend to m_rEnginge.GetMaxTextWidth():
     951           0 :         ::sal_Int32 nWidth = (aLeft.Top() == aRight.Top()
     952           0 :                             && aLeft.Bottom() == aRight.Bottom())
     953           0 :             ? static_cast< ::sal_Int32 >(aRight.Left() - aLeft.Left())
     954           0 :             : static_cast< ::sal_Int32 >(m_rEngine.GetMaxTextWidth()
     955           0 :                                         - aLeft.Left());
     956             :             // XXX  numeric overflow (4x)
     957           0 :         aBounds = css::awt::Rectangle(static_cast< ::sal_Int32 >(aLeft.Left()),
     958           0 :                                         static_cast< ::sal_Int32 >(aLeft.Top() - m_nViewOffset),
     959             :                                         nWidth,
     960           0 :                                         static_cast< ::sal_Int32 >(aLeft.Bottom()
     961           0 :                                                                     - aLeft.Top()));
     962             :             // XXX  numeric overflow (4x)
     963             :     }
     964           0 :     return aBounds;
     965             : }
     966             : 
     967           0 : ::sal_Int32 Document::retrieveCharacterIndex(Paragraph const * pParagraph,
     968             :                                              css::awt::Point const & rPoint)
     969             : {
     970           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
     971           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
     972           0 :     ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
     973             :         // XXX  numeric overflow
     974             :     ::TextPaM aPaM(m_rEngine.GetPaM(::Point(static_cast< long >(rPoint.X),
     975           0 :                                             static_cast< long >(rPoint.Y))));
     976             :         // XXX  numeric overflow (2x)
     977           0 :     return aPaM.GetPara() == nNumber
     978           0 :         ? static_cast< ::sal_Int32 >(aPaM.GetIndex()) : -1;
     979             :         // XXX  numeric overflow
     980             : }
     981             : 
     982             : struct IndexCompare
     983             : {
     984             :     const css::beans::PropertyValue* pValues;
     985           0 :     explicit IndexCompare(const css::beans::PropertyValue* pVals)
     986           0 :         : pValues(pVals)
     987             :     {
     988           0 :     }
     989           0 :     bool operator() ( const sal_Int32& a, const sal_Int32& b ) const
     990             :     {
     991           0 :         return pValues[a].Name < pValues[b].Name;
     992             :     }
     993             : };
     994             : 
     995             : css::uno::Sequence< css::beans::PropertyValue >
     996           0 : Document::retrieveCharacterAttributes(
     997             :     Paragraph const * pParagraph, ::sal_Int32 nIndex,
     998             :     const css::uno::Sequence< OUString >& aRequestedAttributes)
     999             : {
    1000           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1001             : 
    1002           0 :     vcl::Font aFont = m_rEngine.GetFont();
    1003           0 :     const sal_Int32 AttributeCount = 9;
    1004           0 :     sal_Int32 i = 0;
    1005           0 :     css::uno::Sequence< css::beans::PropertyValue > aAttribs( AttributeCount );
    1006             : 
    1007             :     //character background color
    1008           0 :     aAttribs[i].Name = "CharBackColor";
    1009           0 :     aAttribs[i].Handle = -1;
    1010           0 :     aAttribs[i].Value = mapFontColor( aFont.GetFillColor() );
    1011           0 :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1012           0 :     i++;
    1013             : 
    1014             :     //character color
    1015           0 :     aAttribs[i].Name = "CharColor";
    1016           0 :     aAttribs[i].Handle = -1;
    1017             :     //aAttribs[i].Value = mapFontColor( aFont.GetColor() );
    1018           0 :     aAttribs[i].Value = mapFontColor( m_rEngine.GetTextColor() );
    1019           0 :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1020           0 :     i++;
    1021             : 
    1022             :     //character font name
    1023           0 :     aAttribs[i].Name = "CharFontName";
    1024           0 :     aAttribs[i].Handle = -1;
    1025           0 :     aAttribs[i].Value = css::uno::makeAny( aFont.GetName() );
    1026           0 :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1027           0 :     i++;
    1028             : 
    1029             :     //character height
    1030           0 :     aAttribs[i].Name = "CharHeight";
    1031           0 :     aAttribs[i].Handle = -1;
    1032           0 :     aAttribs[i].Value = css::uno::makeAny( (sal_Int16)aFont.GetHeight() );
    1033           0 :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1034           0 :     i++;
    1035             : 
    1036             :     //character posture
    1037           0 :     aAttribs[i].Name = "CharPosture";
    1038           0 :     aAttribs[i].Handle = -1;
    1039           0 :     aAttribs[i].Value = css::uno::makeAny( (sal_Int16)aFont.GetItalic() );
    1040           0 :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1041           0 :     i++;
    1042             : 
    1043             :     //character relief
    1044             :     /*
    1045             :     aAttribs[i].Name = "CharRelief";
    1046             :     aAttribs[i].Handle = -1;
    1047             :     aAttribs[i].Value = css::uno::makeAny( (sal_Int16)aFont.GetRelief() );
    1048             :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1049             :     i++;
    1050             :     */
    1051             : 
    1052             :     //character strikeout
    1053           0 :     aAttribs[i].Name = "CharStrikeout";
    1054           0 :     aAttribs[i].Handle = -1;
    1055           0 :     aAttribs[i].Value = css::uno::makeAny( (sal_Int16)aFont.GetStrikeout() );
    1056           0 :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1057           0 :     i++;
    1058             : 
    1059             :     //character underline
    1060           0 :     aAttribs[i].Name = "CharUnderline";
    1061           0 :     aAttribs[i].Handle = -1;
    1062           0 :     aAttribs[i].Value = css::uno::makeAny( (sal_Int16)aFont.GetUnderline() );
    1063           0 :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1064           0 :     i++;
    1065             : 
    1066             :     //character weight
    1067           0 :     aAttribs[i].Name = "CharWeight";
    1068           0 :     aAttribs[i].Handle = -1;
    1069           0 :     aAttribs[i].Value = css::uno::makeAny( (float)aFont.GetWeight() );
    1070           0 :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1071           0 :     i++;
    1072             : 
    1073             :     //character alignment
    1074           0 :     aAttribs[i].Name = "ParaAdjust";
    1075           0 :     aAttribs[i].Handle = -1;
    1076           0 :     aAttribs[i].Value = css::uno::makeAny( (sal_Int16)m_rEngine.GetTextAlign() );
    1077           0 :     aAttribs[i].State = css::beans::PropertyState_DIRECT_VALUE;
    1078           0 :     i++;
    1079             : 
    1080           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
    1081           0 :     ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1082             :         // XXX  numeric overflow
    1083             :         // nIndex can be equal to getLength();
    1084           0 :     if (nIndex < 0 || nIndex > m_rEngine.GetText(nNumber).getLength())
    1085             :         throw css::lang::IndexOutOfBoundsException(
    1086             :             "textwindowaccessibility.cxx:"
    1087             :             " Document::retrieveCharacterAttributes",
    1088           0 :             static_cast< css::uno::XWeak * >(this));
    1089             : 
    1090             :     // retrieve default attributes
    1091           0 :     tPropValMap aCharAttrSeq;
    1092           0 :     retrieveDefaultAttributesImpl( pParagraph, aRequestedAttributes, aCharAttrSeq );
    1093             : 
    1094             :     // retrieve run attributes
    1095           0 :     tPropValMap aRunAttrSeq;
    1096           0 :     retrieveRunAttributesImpl( pParagraph, nIndex, aRequestedAttributes, aRunAttrSeq );
    1097             : 
    1098             :     // merge default and run attributes
    1099           0 :     for ( tPropValMap::const_iterator aRunIter  = aRunAttrSeq.begin();
    1100           0 :           aRunIter != aRunAttrSeq.end();
    1101             :           ++aRunIter )
    1102             :     {
    1103           0 :         aCharAttrSeq[ aRunIter->first ] = aRunIter->second;
    1104             :     }
    1105             : 
    1106           0 :     css::beans::PropertyValue* pValues = aAttribs.getArray();
    1107           0 :     for (i = 0; i < AttributeCount; i++,pValues++)
    1108             :     {
    1109           0 :         aCharAttrSeq[ pValues->Name ] = *pValues;
    1110             :     }
    1111             : 
    1112           0 :     css::uno::Sequence< css::beans::PropertyValue > aRes = convertHashMapToSequence( aCharAttrSeq );
    1113             : 
    1114             :     // sort the attributes
    1115           0 :     sal_Int32 nLength = aRes.getLength();
    1116           0 :     const css::beans::PropertyValue* pPairs = aRes.getConstArray();
    1117           0 :     sal_Int32* pIndices = new sal_Int32[nLength];
    1118           0 :     for( i = 0; i < nLength; i++ )
    1119           0 :         pIndices[i] = i;
    1120           0 :     std::sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) );
    1121             :     // create sorted sequences according to index array
    1122           0 :     css::uno::Sequence< css::beans::PropertyValue > aNewValues( nLength );
    1123           0 :     css::beans::PropertyValue* pNewValues = aNewValues.getArray();
    1124           0 :     for( i = 0; i < nLength; i++ )
    1125             :     {
    1126           0 :         pNewValues[i] = pPairs[pIndices[i]];
    1127             :     }
    1128           0 :     delete[] pIndices;
    1129             : 
    1130           0 :     return aNewValues;
    1131             : }
    1132             : 
    1133           0 : void Document::retrieveDefaultAttributesImpl(
    1134             :     Paragraph const * pParagraph,
    1135             :     const css::uno::Sequence< OUString >& RequestedAttributes,
    1136             :     tPropValMap& rDefAttrSeq)
    1137             : {
    1138             :     // default attributes are not supported by text engine
    1139             :     (void) pParagraph;
    1140             :     (void) RequestedAttributes;
    1141             :     (void) rDefAttrSeq;
    1142           0 : }
    1143             : 
    1144             : css::uno::Sequence< css::beans::PropertyValue >
    1145           0 : Document::retrieveDefaultAttributes(
    1146             :     Paragraph const * pParagraph,
    1147             :     const css::uno::Sequence< OUString >& RequestedAttributes)
    1148             : {
    1149           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
    1150           0 :     ::osl::MutexGuard aInternalGuard( GetMutex() );
    1151             : 
    1152           0 :     tPropValMap aDefAttrSeq;
    1153           0 :     retrieveDefaultAttributesImpl( pParagraph, RequestedAttributes, aDefAttrSeq );
    1154           0 :     return convertHashMapToSequence( aDefAttrSeq );
    1155             : }
    1156             : 
    1157             : // static
    1158             : css::uno::Sequence< css::beans::PropertyValue >
    1159           0 : Document::convertHashMapToSequence(tPropValMap& rAttrSeq)
    1160             : {
    1161           0 :     css::uno::Sequence< css::beans::PropertyValue > aValues( rAttrSeq.size() );
    1162           0 :     css::beans::PropertyValue* pValues = aValues.getArray();
    1163           0 :     ::sal_Int32 i = 0;
    1164           0 :     for ( tPropValMap::const_iterator aIter  = rAttrSeq.begin();
    1165           0 :           aIter != rAttrSeq.end();
    1166             :           ++aIter )
    1167             :     {
    1168           0 :         pValues[i] = aIter->second;
    1169           0 :         ++i;
    1170             :     }
    1171           0 :     return aValues;
    1172             : }
    1173             : 
    1174           0 : void Document::retrieveRunAttributesImpl(
    1175             :     Paragraph const * pParagraph, ::sal_Int32 Index,
    1176             :     const css::uno::Sequence< OUString >& RequestedAttributes,
    1177             :     tPropValMap& rRunAttrSeq)
    1178             : {
    1179           0 :     ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
    1180           0 :     ::TextPaM aPaM( nNumber, static_cast< ::sal_uInt16 >( Index ) );
    1181             :         // XXX  numeric overflow
    1182             :     // FIXME  TEXTATTR_HYPERLINK ignored:
    1183             :     ::TextAttribFontColor const * pColor
    1184             :           = static_cast< ::TextAttribFontColor const * >(
    1185           0 :               m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTCOLOR ) );
    1186             :     ::TextAttribFontWeight const * pWeight
    1187             :           = static_cast< ::TextAttribFontWeight const * >(
    1188           0 :               m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTWEIGHT ) );
    1189           0 :     tPropValMap aRunAttrSeq;
    1190           0 :     if ( pColor )
    1191             :     {
    1192           0 :         css::beans::PropertyValue aPropVal;
    1193           0 :         aPropVal.Name = "CharColor";
    1194           0 :         aPropVal.Handle = -1;
    1195           0 :         aPropVal.Value = mapFontColor( pColor->GetColor() );
    1196           0 :         aPropVal.State = css::beans::PropertyState_DIRECT_VALUE;
    1197           0 :         aRunAttrSeq[ aPropVal.Name ] = aPropVal;
    1198             :     }
    1199           0 :     if ( pWeight )
    1200             :     {
    1201           0 :         css::beans::PropertyValue aPropVal;
    1202           0 :         aPropVal.Name = "CharWeight";
    1203           0 :         aPropVal.Handle = -1;
    1204           0 :         aPropVal.Value = mapFontWeight( pWeight->getFontWeight() );
    1205           0 :         aPropVal.State = css::beans::PropertyState_DIRECT_VALUE;
    1206           0 :         aRunAttrSeq[ aPropVal.Name ] = aPropVal;
    1207             :     }
    1208           0 :     if ( RequestedAttributes.getLength() == 0 )
    1209             :     {
    1210           0 :         rRunAttrSeq = aRunAttrSeq;
    1211             :     }
    1212             :     else
    1213             :     {
    1214           0 :         const OUString* pReqAttrs = RequestedAttributes.getConstArray();
    1215           0 :         const ::sal_Int32 nLength = RequestedAttributes.getLength();
    1216           0 :         for ( ::sal_Int32 i = 0; i < nLength; ++i )
    1217             :         {
    1218           0 :             tPropValMap::iterator aIter = aRunAttrSeq.find( pReqAttrs[i] );
    1219           0 :             if ( aIter != aRunAttrSeq.end() )
    1220             :             {
    1221           0 :                 rRunAttrSeq[ (*aIter).first ] = (*aIter).second;
    1222             :             }
    1223             :         }
    1224           0 :     }
    1225           0 : }
    1226             : 
    1227             : css::uno::Sequence< css::beans::PropertyValue >
    1228           0 : Document::retrieveRunAttributes(
    1229             :     Paragraph const * pParagraph, ::sal_Int32 Index,
    1230             :     const css::uno::Sequence< OUString >& RequestedAttributes)
    1231             : {
    1232           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
    1233           0 :     ::osl::MutexGuard aInternalGuard( GetMutex() );
    1234           0 :     ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
    1235             :         // XXX  numeric overflow
    1236           0 :     if ( Index < 0 || Index >= m_rEngine.GetText(nNumber).getLength() )
    1237             :         throw css::lang::IndexOutOfBoundsException(
    1238             :             "textwindowaccessibility.cxx:"
    1239             :             " Document::retrieveRunAttributes",
    1240           0 :             static_cast< css::uno::XWeak * >( this ) );
    1241             : 
    1242           0 :     tPropValMap aRunAttrSeq;
    1243           0 :     retrieveRunAttributesImpl( pParagraph, Index, RequestedAttributes, aRunAttrSeq );
    1244           0 :     return convertHashMapToSequence( aRunAttrSeq );
    1245             : }
    1246             : 
    1247           0 : void Document::changeParagraphText(Paragraph * pParagraph,
    1248             :                                    OUString const & rText)
    1249             : {
    1250           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1251             :     {
    1252           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1253           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1254             :             // XXX  numeric overflow
    1255           0 :         changeParagraphText(nNumber, 0, m_rEngine.GetTextLen(nNumber), false,
    1256           0 :                             false, rText);
    1257           0 :     }
    1258           0 : }
    1259             : 
    1260           0 : void Document::changeParagraphText(Paragraph * pParagraph,
    1261             :                                    ::sal_Int32 nBegin, ::sal_Int32 nEnd,
    1262             :                                    bool bCut, bool bPaste,
    1263             :                                    OUString const & rText)
    1264             : {
    1265           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1266             :     {
    1267           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1268           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1269             :             // XXX  numeric overflow
    1270           0 :         if (nBegin < 0 || nBegin > nEnd
    1271           0 :             || nEnd > m_rEngine.GetText(nNumber).getLength())
    1272             :             throw css::lang::IndexOutOfBoundsException(
    1273             :                 "textwindowaccessibility.cxx:"
    1274             :                 " Document::changeParagraphText",
    1275           0 :                 static_cast< css::uno::XWeak * >(this));
    1276             :         changeParagraphText(nNumber, static_cast< ::sal_uInt16 >(nBegin),
    1277           0 :                             static_cast< ::sal_uInt16 >(nEnd), bCut, bPaste, rText);
    1278             :             // XXX  numeric overflow (2x)
    1279           0 :     }
    1280           0 : }
    1281             : 
    1282           0 : void Document::copyParagraphText(Paragraph const * pParagraph,
    1283             :                                  ::sal_Int32 nBegin, ::sal_Int32 nEnd)
    1284             : {
    1285           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1286             :     {
    1287           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1288           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1289             :             // XXX  numeric overflow
    1290           0 :         if (nBegin < 0 || nBegin > nEnd
    1291           0 :             || nEnd > m_rEngine.GetText(nNumber).getLength())
    1292             :             throw css::lang::IndexOutOfBoundsException(
    1293             :                 "textwindowaccessibility.cxx:"
    1294             :                 " Document::copyParagraphText",
    1295           0 :                 static_cast< css::uno::XWeak * >(this));
    1296             :         m_rView.SetSelection(
    1297             :             ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)),
    1298           0 :                             ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd))));
    1299             :             // XXX  numeric overflow (2x)
    1300           0 :         m_rView.Copy();
    1301           0 :     }
    1302           0 : }
    1303             : 
    1304           0 : void Document::changeParagraphAttributes(
    1305             :     Paragraph * pParagraph, ::sal_Int32 nBegin, ::sal_Int32 nEnd,
    1306             :     css::uno::Sequence< css::beans::PropertyValue > const & rAttributeSet)
    1307             : {
    1308           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1309             :     {
    1310           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1311           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1312             :         // XXX  numeric overflow
    1313           0 :         if (nBegin < 0 || nBegin > nEnd
    1314           0 :             || nEnd > m_rEngine.GetText(nNumber).getLength())
    1315             :             throw css::lang::IndexOutOfBoundsException(
    1316             :                 "textwindowaccessibility.cxx:"
    1317             :                 " Document::changeParagraphAttributes",
    1318           0 :                 static_cast< css::uno::XWeak * >(this));
    1319             : 
    1320             :         // FIXME  The new attributes are added to any attributes already set,
    1321             :         // they do not replace the old attributes as required by
    1322             :         // XAccessibleEditableText.setAttributes:
    1323           0 :         for (::sal_Int32 i = 0; i < rAttributeSet.getLength(); ++i)
    1324           0 :             if ( rAttributeSet[i].Name == "CharColor" )
    1325             :                 m_rEngine.SetAttrib(::TextAttribFontColor(
    1326           0 :                                         mapFontColor(rAttributeSet[i].Value)),
    1327             :                                     nNumber, static_cast< ::sal_uInt16 >(nBegin),
    1328           0 :                                     static_cast< ::sal_uInt16 >(nEnd));
    1329             :                     // XXX  numeric overflow (2x)
    1330           0 :             else if ( rAttributeSet[i].Name == "CharWeight" )
    1331             :                 m_rEngine.SetAttrib(::TextAttribFontWeight(
    1332           0 :                                         mapFontWeight(rAttributeSet[i].Value)),
    1333             :                                     nNumber, static_cast< ::sal_uInt16 >(nBegin),
    1334           0 :                                     static_cast< ::sal_uInt16 >(nEnd));
    1335             :                     // XXX  numeric overflow (2x)
    1336           0 :     }
    1337           0 : }
    1338             : 
    1339           0 : void Document::changeParagraphSelection(Paragraph * pParagraph,
    1340             :                                         ::sal_Int32 nBegin, ::sal_Int32 nEnd)
    1341             : {
    1342           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1343             :     {
    1344           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1345           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1346             :             // XXX  numeric overflow
    1347           0 :         if (nBegin < 0 || nBegin > nEnd
    1348           0 :             || nEnd > m_rEngine.GetText(nNumber).getLength())
    1349             :             throw css::lang::IndexOutOfBoundsException(
    1350             :                 "textwindowaccessibility.cxx:"
    1351             :                 " Document::changeParagraphSelection",
    1352           0 :                 static_cast< css::uno::XWeak * >(this));
    1353             :         m_rView.SetSelection(
    1354             :             ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)),
    1355           0 :                             ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd))));
    1356             :             // XXX  numeric overflow (2x)
    1357           0 :     }
    1358           0 : }
    1359             : 
    1360             : css::i18n::Boundary
    1361           0 : Document::retrieveParagraphLineBoundary( Paragraph const * pParagraph,
    1362             :                                          ::sal_Int32 nIndex, ::sal_Int32 *pLineNo )
    1363             : {
    1364           0 :     css::i18n::Boundary aBoundary;
    1365           0 :     aBoundary.startPos = nIndex;
    1366           0 :     aBoundary.endPos = nIndex;
    1367             : 
    1368           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
    1369             :     {
    1370           0 :         ::osl::MutexGuard aInternalGuard( GetMutex() );
    1371           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
    1372           0 :         if ( nIndex < 0 || nIndex > m_rEngine.GetText( nNumber ).getLength() )
    1373             :             throw css::lang::IndexOutOfBoundsException(
    1374             :                 "textwindowaccessibility.cxx:"
    1375             :                 " Document::retrieveParagraphLineBoundary",
    1376           0 :                 static_cast< css::uno::XWeak * >( this ) );
    1377           0 :         ::sal_Int32 nLineStart = 0;
    1378           0 :         ::sal_Int32 nLineEnd = 0;
    1379           0 :         ::sal_uInt16 nLineCount = m_rEngine.GetLineCount( nNumber );
    1380           0 :         for ( ::sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine )
    1381             :         {
    1382             :             ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >(
    1383           0 :                 m_rEngine.GetLineLen( nNumber, nLine ) );
    1384           0 :             nLineStart = nLineEnd;
    1385           0 :             nLineEnd += nLineLength;
    1386           0 :             if ( nIndex >= nLineStart && ( ( nLine == nLineCount - 1 ) ? nIndex <= nLineEnd : nIndex < nLineEnd ) )
    1387             :             {
    1388           0 :                 aBoundary.startPos = nLineStart;
    1389           0 :                 aBoundary.endPos = nLineEnd;
    1390           0 :                 if( pLineNo )
    1391           0 :                     pLineNo[0] = nLine;
    1392           0 :                 break;
    1393             :             }
    1394           0 :         }
    1395             :     }
    1396             : 
    1397           0 :     return aBoundary;
    1398             : }
    1399             : 
    1400             : css::i18n::Boundary
    1401           0 : Document::retrieveParagraphBoundaryOfLine( Paragraph const * pParagraph,
    1402             :                                            ::sal_Int32 nLineNo )
    1403             : {
    1404           0 :     css::i18n::Boundary aBoundary;
    1405           0 :     aBoundary.startPos = 0;
    1406           0 :     aBoundary.endPos = 0;
    1407             : 
    1408           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
    1409             :     {
    1410           0 :         ::osl::MutexGuard aInternalGuard( GetMutex() );
    1411           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
    1412           0 :         if ( nLineNo >= m_rEngine.GetLineCount( nNumber ) )
    1413             :             throw css::lang::IndexOutOfBoundsException(
    1414             :                 "textwindowaccessibility.cxx:"
    1415             :                 " Document::retrieveParagraphBoundaryOfLine",
    1416           0 :                 static_cast< css::uno::XWeak * >( this ) );
    1417           0 :         ::sal_Int32 nLineStart = 0;
    1418           0 :         ::sal_Int32 nLineEnd = 0;
    1419           0 :         for ( ::sal_Int32 nLine = 0; nLine <= nLineNo; ++nLine )
    1420             :         {
    1421             :             ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >(
    1422           0 :                 m_rEngine.GetLineLen( nNumber, nLine ) );
    1423           0 :             nLineStart = nLineEnd;
    1424           0 :             nLineEnd += nLineLength;
    1425             :         }
    1426             : 
    1427           0 :         aBoundary.startPos = nLineStart;
    1428           0 :         aBoundary.endPos = nLineEnd;
    1429             :     }
    1430             : 
    1431           0 :     return aBoundary;
    1432             : }
    1433             : 
    1434           0 : sal_Int32 Document::retrieveParagraphLineWithCursor( Paragraph const * pParagraph )
    1435             : {
    1436           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1437           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
    1438           0 :     ::TextSelection const & rSelection = m_rView.GetSelection();
    1439           0 :     Paragraphs::size_type nNumber = pParagraph->getNumber();
    1440           0 :     TextPaM aEndPaM( rSelection.GetEnd() );
    1441             : 
    1442           0 :     return aEndPaM.GetPara() == nNumber
    1443           0 :         ? m_rView.GetLineNumberOfCursorInSelection() : -1;
    1444             : }
    1445             : 
    1446             : 
    1447             : css::uno::Reference< css::accessibility::XAccessibleRelationSet >
    1448           0 : Document::retrieveParagraphRelationSet( Paragraph const * pParagraph )
    1449             : {
    1450           0 :     ::osl::MutexGuard aInternalGuard( GetMutex() );
    1451             : 
    1452           0 :     ::utl::AccessibleRelationSetHelper* pRelationSetHelper = new ::utl::AccessibleRelationSetHelper();
    1453           0 :     css::uno::Reference< css::accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper;
    1454             : 
    1455           0 :     Paragraphs::iterator aPara( m_xParagraphs->begin() + pParagraph->getNumber() );
    1456             : 
    1457           0 :     if ( aPara > m_aVisibleBegin && aPara < m_aVisibleEnd )
    1458             :     {
    1459           0 :         css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > aSequence(1);
    1460           0 :         aSequence[0] = getAccessibleChild( aPara - 1 );
    1461           0 :         css::accessibility::AccessibleRelation aRelation( css::accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM, aSequence );
    1462           0 :         pRelationSetHelper->AddRelation( aRelation );
    1463             :     }
    1464             : 
    1465           0 :     if ( aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd -1 )
    1466             :     {
    1467           0 :         css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > aSequence(1);
    1468           0 :         aSequence[0] = getAccessibleChild( aPara + 1 );
    1469           0 :         css::accessibility::AccessibleRelation aRelation( css::accessibility::AccessibleRelationType::CONTENT_FLOWS_TO, aSequence );
    1470           0 :         pRelationSetHelper->AddRelation( aRelation );
    1471             :     }
    1472             : 
    1473           0 :     return xSet;
    1474             : }
    1475             : 
    1476             : // virtual
    1477           0 : ::sal_Int32 SAL_CALL Document::getAccessibleChildCount()
    1478             :     throw (css::uno::RuntimeException, std::exception)
    1479             : {
    1480           0 :     ::comphelper::OExternalLockGuard aGuard(this);
    1481           0 :     init();
    1482           0 :     return m_aVisibleEnd - m_aVisibleBegin;
    1483             : }
    1484             : 
    1485             : // virtual
    1486             : css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
    1487           0 : Document::getAccessibleChild(::sal_Int32 i)
    1488             :     throw (css::lang::IndexOutOfBoundsException,
    1489             :            css::uno::RuntimeException, std::exception)
    1490             : {
    1491           0 :     ::comphelper::OExternalLockGuard aGuard(this);
    1492           0 :     init();
    1493           0 :     if (i < 0 || i >= m_aVisibleEnd - m_aVisibleBegin)
    1494             :         throw css::lang::IndexOutOfBoundsException(
    1495             :             "textwindowaccessibility.cxx:"
    1496             :             " Document::getAccessibleChild",
    1497           0 :             static_cast< css::uno::XWeak * >(this));
    1498             :     return getAccessibleChild(m_aVisibleBegin
    1499           0 :                               + static_cast< Paragraphs::size_type >(i));
    1500             : }
    1501             : 
    1502             : // virtual
    1503           0 : ::sal_Int16 SAL_CALL Document::getAccessibleRole()
    1504             :     throw (css::uno::RuntimeException, std::exception)
    1505             : {
    1506           0 :     return css::accessibility::AccessibleRole::TEXT_FRAME;
    1507             : }
    1508             : 
    1509             : // virtual
    1510             : css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
    1511           0 : Document::getAccessibleAtPoint(css::awt::Point const & rPoint)
    1512             :     throw (css::uno::RuntimeException, std::exception)
    1513             : {
    1514           0 :     ::comphelper::OExternalLockGuard aGuard(this);
    1515           0 :     init();
    1516           0 :     if (rPoint.X >= 0
    1517           0 :         && rPoint.X < m_rView.GetWindow()->GetOutputSizePixel().Width()
    1518           0 :         && rPoint.Y >= 0 && rPoint.Y < m_nViewHeight)
    1519             :     {
    1520           0 :         ::sal_Int32 nOffset = m_nViewOffset + rPoint.Y; // XXX  numeric overflow
    1521           0 :         ::sal_Int32 nPos = m_nViewOffset - m_nVisibleBeginOffset;
    1522           0 :         for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd;
    1523             :              ++aIt)
    1524             :         {
    1525           0 :             nPos += aIt->getHeight(); // XXX  numeric overflow
    1526           0 :             if (nOffset < nPos)
    1527           0 :                 return getAccessibleChild(aIt);
    1528             :         }
    1529             :     }
    1530           0 :     return 0;
    1531             : }
    1532           0 : void Document::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
    1533             : {
    1534           0 :     VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
    1535           0 :     if (!m_rView.IsReadOnly())
    1536           0 :         rStateSet.AddState( css::accessibility::AccessibleStateType::EDITABLE );
    1537           0 : }
    1538             : 
    1539           0 : void    Document::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
    1540             : {
    1541           0 :     if( getAccessibleParent()->getAccessibleContext()->getAccessibleRole() == css::accessibility::AccessibleRole::SCROLL_PANE )
    1542             :     {
    1543           0 :         css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > aSequence(1);
    1544           0 :         aSequence[0] = getAccessibleParent();
    1545           0 :         rRelationSet.AddRelation( css::accessibility::AccessibleRelation( css::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
    1546             :     }
    1547             :     else
    1548             :     {
    1549           0 :          VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet);
    1550             :     }
    1551           0 : }
    1552             : // virtual
    1553           0 : void SAL_CALL Document::disposing()
    1554             : {
    1555           0 :     m_aEngineListener.endListening();
    1556           0 :     m_aViewListener.endListening();
    1557           0 :     if (m_xParagraphs.get() != 0)
    1558           0 :         disposeParagraphs();
    1559           0 :     VCLXAccessibleComponent::disposing();
    1560           0 : }
    1561             : 
    1562             : // virtual
    1563           0 : void Document::Notify(::SfxBroadcaster &, ::SfxHint const & rHint)
    1564             : {
    1565           0 :     const TextHint* pTextHint = dynamic_cast<const TextHint*>(&rHint);
    1566           0 :     if (pTextHint)
    1567             :     {
    1568           0 :         ::TextHint const & rTextHint = *pTextHint;
    1569           0 :         switch (rTextHint.GetId())
    1570             :         {
    1571             :         case TEXT_HINT_PARAINSERTED:
    1572             :         case TEXT_HINT_PARAREMOVED:
    1573             :             // TEXT_HINT_PARAINSERTED and TEXT_HINT_PARAREMOVED are sent at
    1574             :             // "unsafe" times (when the text engine has not yet re-formatted its
    1575             :             // content), so that for example calling ::TextEngine::GetTextHeight
    1576             :             // from within the code that handles TEXT_HINT_PARAINSERTED causes
    1577             :             // trouble within the text engine.  Therefore, these hints are just
    1578             :             // buffered until a following ::TextEngine::FormatDoc causes a
    1579             :             // TEXT_HINT_TEXTFORMATTED to come in:
    1580             :         case TEXT_HINT_FORMATPARA:
    1581             :             // ::TextEngine::FormatDoc sends a sequence of
    1582             :             // TEXT_HINT_FORMATPARAs, followed by an optional
    1583             :             // TEXT_HINT_TEXTHEIGHTCHANGED, followed in all cases by one
    1584             :             // TEXT_HINT_TEXTFORMATTED.  Only the TEXT_HINT_FORMATPARAs contain
    1585             :             // the numbers of the affected paragraphs, but they are sent
    1586             :             // before the changes are applied.  Therefore, TEXT_HINT_FORMATPARAs
    1587             :             // are just buffered until another hint comes in:
    1588             :             {
    1589           0 :                 ::osl::MutexGuard aInternalGuard(GetMutex());
    1590           0 :                 if (!isAlive())
    1591           0 :                     break;
    1592             : 
    1593           0 :                 m_aParagraphNotifications.push(rTextHint);
    1594           0 :                 break;
    1595             :             }
    1596             :         case TEXT_HINT_TEXTFORMATTED:
    1597             :         case TEXT_HINT_TEXTHEIGHTCHANGED:
    1598             :         case TEXT_HINT_MODIFIED:
    1599             :             {
    1600           0 :                 ::osl::MutexGuard aInternalGuard(GetMutex());
    1601           0 :                 if (!isAlive())
    1602           0 :                     break;
    1603           0 :                 handleParagraphNotifications();
    1604           0 :                 break;
    1605             :             }
    1606             :         case TEXT_HINT_VIEWSCROLLED:
    1607             :             {
    1608           0 :                 ::osl::MutexGuard aInternalGuard(GetMutex());
    1609           0 :                 if (!isAlive())
    1610           0 :                     break;
    1611           0 :                 handleParagraphNotifications();
    1612             : 
    1613             :                 ::sal_Int32 nOffset = static_cast< ::sal_Int32 >(
    1614           0 :                     m_rView.GetStartDocPos().Y());
    1615             :                     // XXX  numeric overflow
    1616           0 :                 if (nOffset != m_nViewOffset)
    1617             :                 {
    1618           0 :                     m_nViewOffset = nOffset;
    1619             : 
    1620             :                     Paragraphs::iterator aOldVisibleBegin(
    1621           0 :                         m_aVisibleBegin);
    1622           0 :                     Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd);
    1623             : 
    1624           0 :                     determineVisibleRange();
    1625             : 
    1626             :                     notifyVisibleRangeChanges(aOldVisibleBegin,
    1627             :                                                 aOldVisibleEnd,
    1628           0 :                                                 m_xParagraphs->end());
    1629             :                 }
    1630           0 :                 break;
    1631             :             }
    1632             :         case TEXT_HINT_VIEWSELECTIONCHANGED:
    1633             :         case TEXT_HINT_VIEWCARETCHANGED:
    1634             :             {
    1635           0 :                 ::osl::MutexGuard aInternalGuard(GetMutex());
    1636           0 :                 if (!isAlive())
    1637           0 :                     break;
    1638             : 
    1639           0 :                 if (m_aParagraphNotifications.empty())
    1640             :                 {
    1641           0 :                     handleSelectionChangeNotification();
    1642             :                 }
    1643             :                 else
    1644             :                 {
    1645             :                     // TEXT_HINT_VIEWSELECTIONCHANGED is sometimes sent at
    1646             :                     // "unsafe" times (when the text engine has not yet re-
    1647             :                     // formatted its content), so that for example calling
    1648             :                     // ::TextEngine::GetTextHeight from within the code that
    1649             :                     // handles a previous TEXT_HINT_PARAINSERTED causes
    1650             :                     // trouble within the text engine.  Therefore, these
    1651             :                     // hints are just buffered (along with
    1652             :                     // TEXT_HINT_PARAINSERTED/REMOVED/FORMATPARA) until a
    1653             :                     // following ::TextEngine::FormatDoc causes a
    1654             :                     // TEXT_HINT_TEXTFORMATTED to come in:
    1655           0 :                     m_bSelectionChangedNotification = true;
    1656             :                 }
    1657           0 :                 break;
    1658             :             }
    1659             :         }
    1660             :     }
    1661           0 : }
    1662             : 
    1663           0 : IMPL_LINK(Document, WindowEventHandler, ::VclSimpleEvent *, pEvent)
    1664             : {
    1665           0 :     switch (pEvent->GetId())
    1666             :     {
    1667             :     case VCLEVENT_WINDOW_RESIZE:
    1668             :         {
    1669           0 :             ::osl::MutexGuard aInternalGuard(GetMutex());
    1670           0 :             if (!isAlive())
    1671           0 :                 break;
    1672             : 
    1673             :             ::sal_Int32 nHeight = static_cast< ::sal_Int32 >(
    1674           0 :                 m_rView.GetWindow()->GetOutputSizePixel().Height());
    1675             :                 // XXX  numeric overflow
    1676           0 :             if (nHeight != m_nViewHeight)
    1677             :             {
    1678           0 :                 m_nViewHeight = nHeight;
    1679             : 
    1680           0 :                 Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin);
    1681           0 :                 Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd);
    1682             : 
    1683           0 :                 determineVisibleRange();
    1684             : 
    1685             :                 notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd,
    1686           0 :                                             m_xParagraphs->end());
    1687             :             }
    1688           0 :             break;
    1689             :         }
    1690             :     case VCLEVENT_WINDOW_GETFOCUS:
    1691             :         {
    1692           0 :             ::osl::MutexGuard aInternalGuard(GetMutex());
    1693           0 :             if (!isAlive())
    1694           0 :                 break;
    1695             :             //to enable the PARAGRAPH to get focus for multiline edit
    1696           0 :             ::sal_Int32 count = getAccessibleChildCount();
    1697           0 :             bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1;
    1698           0 :             if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty)
    1699             :             {
    1700           0 :                 Paragraphs::iterator m_aTemp = bEmpty ? m_aVisibleBegin : m_aFocused;
    1701           0 :                 ::rtl::Reference< Paragraph > xParagraph(getParagraph(m_aTemp));
    1702           0 :                 if (xParagraph.is())
    1703             :                 {
    1704             :                     xParagraph->notifyEvent(
    1705             :                         css::accessibility::AccessibleEventId::
    1706             :                         STATE_CHANGED,
    1707             :                         css::uno::Any(),
    1708             :                         css::uno::makeAny(
    1709             :                             css::accessibility::AccessibleStateType::
    1710           0 :                             FOCUSED));
    1711           0 :                 }
    1712             :             }
    1713             :             /*
    1714             :                 ::rtl::Reference< Paragraph > xParagraph(
    1715             :                     getParagraph(m_aFocused));
    1716             :                 if (xParagraph.is())
    1717             :                     xParagraph->notifyEvent(
    1718             :                         css::accessibility::AccessibleEventId::
    1719             :                         STATE_CHANGED,
    1720             :                         css::uno::Any(),
    1721             :                         css::uno::makeAny(
    1722             :                             css::accessibility::AccessibleStateType::
    1723             :                             FOCUSED));
    1724             :             */
    1725           0 :             break;
    1726             :         }
    1727             :     case VCLEVENT_WINDOW_LOSEFOCUS:
    1728             :         {
    1729           0 :             ::osl::MutexGuard aInternalGuard(GetMutex());
    1730           0 :             if (!isAlive())
    1731           0 :                 break;
    1732             :             //to enable the PARAGRAPH to get focus for multiline edit
    1733           0 :             ::sal_Int32 count = getAccessibleChildCount();
    1734           0 :             bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1;
    1735           0 :             if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty)
    1736             :             {
    1737           0 :                 Paragraphs::iterator m_aTemp = bEmpty ? m_aVisibleBegin : m_aFocused;
    1738           0 :                 ::rtl::Reference< Paragraph > xParagraph(getParagraph(m_aTemp));
    1739           0 :                 if (xParagraph.is())
    1740             :                     xParagraph->notifyEvent(
    1741             :                         css::accessibility::AccessibleEventId::
    1742             :                         STATE_CHANGED,
    1743             :                         css::uno::makeAny(
    1744             :                             css::accessibility::AccessibleStateType::
    1745             :                             FOCUSED),
    1746           0 :                         css::uno::Any());
    1747             :             }
    1748             : 
    1749             :             /*
    1750             :             if (m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd)
    1751             :             {
    1752             :                 ::rtl::Reference< Paragraph > xParagraph(
    1753             :                     getParagraph(m_aFocused));
    1754             :                 if (xParagraph.is())
    1755             :                     xParagraph->notifyEvent(
    1756             :                         css::accessibility::AccessibleEventId::
    1757             :                         STATE_CHANGED,
    1758             :                         css::uno::makeAny(
    1759             :                             css::accessibility::AccessibleStateType::
    1760             :                             FOCUSED),
    1761             :                         css::uno::Any());
    1762             :             }
    1763             :             */
    1764           0 :             break;
    1765             :         }
    1766             :     }
    1767           0 :     return 0;
    1768             : }
    1769             : 
    1770           0 : void Document::init()
    1771             : {
    1772           0 :     if (m_xParagraphs.get() == 0)
    1773             :     {
    1774           0 :         ::sal_uLong nCount = m_rEngine.GetParagraphCount();
    1775           0 :         m_xParagraphs.reset(new Paragraphs);
    1776           0 :         m_xParagraphs->reserve(static_cast< Paragraphs::size_type >(nCount));
    1777             :             // numeric overflow is harmless here
    1778           0 :         for (::sal_uLong i = 0; i < nCount; ++i)
    1779             :             m_xParagraphs->push_back(ParagraphInfo(static_cast< ::sal_Int32 >(
    1780           0 :                                            m_rEngine.GetTextHeight(i))));
    1781             :                 // XXX  numeric overflow
    1782             :         m_nViewOffset = static_cast< ::sal_Int32 >(
    1783           0 :             m_rView.GetStartDocPos().Y()); // XXX  numeric overflow
    1784             :         m_nViewHeight = static_cast< ::sal_Int32 >(
    1785           0 :             m_rView.GetWindow()->GetOutputSizePixel().Height());
    1786             :             // XXX  numeric overflow
    1787           0 :         determineVisibleRange();
    1788           0 :         m_nSelectionFirstPara = -1;
    1789           0 :         m_nSelectionFirstPos = -1;
    1790           0 :         m_nSelectionLastPara = -1;
    1791           0 :         m_nSelectionLastPos = -1;
    1792           0 :         m_aFocused = m_xParagraphs->end();
    1793           0 :         m_bSelectionChangedNotification = false;
    1794           0 :         m_aEngineListener.startListening(m_rEngine);
    1795           0 :         m_aViewListener.startListening(*m_rView.GetWindow());
    1796             :     }
    1797           0 : }
    1798             : 
    1799             : ::rtl::Reference< Paragraph >
    1800           0 : Document::getParagraph(Paragraphs::iterator const & rIt)
    1801             : {
    1802             :     return static_cast< Paragraph * >(
    1803             :         css::uno::Reference< css::accessibility::XAccessible >(
    1804           0 :             rIt->getParagraph()).get());
    1805             : }
    1806             : 
    1807             : css::uno::Reference< css::accessibility::XAccessible >
    1808           0 : Document::getAccessibleChild(Paragraphs::iterator const & rIt)
    1809             : {
    1810             :     css::uno::Reference< css::accessibility::XAccessible > xParagraph(
    1811           0 :         rIt->getParagraph());
    1812           0 :     if (!xParagraph.is())
    1813             :     {
    1814           0 :         xParagraph = new Paragraph(this, rIt - m_xParagraphs->begin());
    1815           0 :         rIt->setParagraph(xParagraph);
    1816             :     }
    1817           0 :     return xParagraph;
    1818             : }
    1819             : 
    1820           0 : void Document::determineVisibleRange()
    1821             : {
    1822           0 :     Paragraphs::iterator const aEnd = m_xParagraphs->end();
    1823             : 
    1824           0 :     m_aVisibleBegin = aEnd;
    1825           0 :     m_aVisibleEnd = aEnd;
    1826           0 :     m_nVisibleBeginOffset = 0;
    1827             : 
    1828           0 :     ::sal_Int32 nPos = 0;
    1829           0 :     for (Paragraphs::iterator aIt = m_xParagraphs->begin(); m_aVisibleEnd == aEnd && aIt != aEnd; ++aIt)
    1830             :     {
    1831           0 :         ::sal_Int32 const nOldPos = nPos;
    1832           0 :         nPos += aIt->getHeight(); // XXX  numeric overflow
    1833           0 :         if (m_aVisibleBegin == aEnd)
    1834             :         {
    1835           0 :             if (nPos >= m_nViewOffset)
    1836             :             {
    1837           0 :                 m_aVisibleBegin = aIt;
    1838           0 :                 m_nVisibleBeginOffset = m_nViewOffset - nOldPos;
    1839             :             }
    1840             :         }
    1841             :         else
    1842             :         {
    1843           0 :             if (nPos >= m_nViewOffset + m_nViewHeight) // XXX  numeric overflow
    1844             :             {
    1845           0 :                 m_aVisibleEnd = aIt;
    1846             :             }
    1847             :         }
    1848             :     }
    1849             : 
    1850             :     SAL_WARN_IF(
    1851             :             !((m_aVisibleBegin == m_xParagraphs->end() && m_aVisibleEnd == m_xParagraphs->end() && m_nVisibleBeginOffset == 0)
    1852             :                 || (m_aVisibleBegin < m_aVisibleEnd && m_nVisibleBeginOffset >= 0)),
    1853             :             "accessibility",
    1854             :             "invalid visible range");
    1855           0 : }
    1856             : 
    1857           0 : void Document::notifyVisibleRangeChanges(
    1858             :     Paragraphs::iterator const & rOldVisibleBegin,
    1859             :     Paragraphs::iterator const & rOldVisibleEnd,
    1860             :     Paragraphs::iterator const & rInserted)
    1861             : {
    1862             :     // XXX  Replace this code that determines which paragraphs have changed from
    1863             :     // invisible to visible or vice versa with a better algorithm.
    1864           0 :     for (Paragraphs::iterator aIt(rOldVisibleBegin); aIt != rOldVisibleEnd;
    1865             :          ++aIt)
    1866             :     {
    1867           0 :         if (aIt != rInserted
    1868           0 :             && (aIt < m_aVisibleBegin || aIt >= m_aVisibleEnd))
    1869             :             NotifyAccessibleEvent(
    1870             :                 css::accessibility::AccessibleEventId::
    1871             :                 CHILD,
    1872             :                 css::uno::makeAny(getAccessibleChild(aIt)),
    1873           0 :                 css::uno::Any());
    1874             :     }
    1875           0 :     for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd;
    1876             :          ++aIt)
    1877             :     {
    1878           0 :         if (aIt == rInserted
    1879           0 :             || aIt < rOldVisibleBegin || aIt >= rOldVisibleEnd)
    1880             :             NotifyAccessibleEvent(
    1881             :                 css::accessibility::AccessibleEventId::
    1882             :                 CHILD,
    1883             :                 css::uno::Any(),
    1884           0 :                 css::uno::makeAny(getAccessibleChild(aIt)));
    1885             :     }
    1886           0 : }
    1887             : 
    1888             : void
    1889           0 : Document::changeParagraphText(::sal_uLong nNumber, ::sal_uInt16 nBegin, ::sal_uInt16 nEnd,
    1890             :                               bool bCut, bool bPaste,
    1891             :                               OUString const & rText)
    1892             : {
    1893             :     m_rView.SetSelection(::TextSelection(::TextPaM(nNumber, nBegin),
    1894           0 :                                          ::TextPaM(nNumber, nEnd)));
    1895           0 :     if (bCut)
    1896           0 :         m_rView.Cut();
    1897           0 :     else if (nBegin != nEnd)
    1898           0 :         m_rView.DeleteSelected();
    1899           0 :     if (bPaste)
    1900           0 :         m_rView.Paste();
    1901           0 :     else if (!rText.isEmpty())
    1902           0 :         m_rView.InsertText(rText);
    1903           0 : }
    1904             : 
    1905           0 : void Document::handleParagraphNotifications()
    1906             : {
    1907           0 :     while (!m_aParagraphNotifications.empty())
    1908             :     {
    1909           0 :         ::TextHint aHint(m_aParagraphNotifications.front());
    1910           0 :         m_aParagraphNotifications.pop();
    1911           0 :         switch (aHint.GetId())
    1912             :         {
    1913             :         case TEXT_HINT_PARAINSERTED:
    1914             :             {
    1915           0 :                 ::sal_uLong n = aHint.GetValue();
    1916             :                 OSL_ENSURE(n <= m_xParagraphs->size(),
    1917             :                            "bad TEXT_HINT_PARAINSERTED event");
    1918             : 
    1919             :                 // Save the values of old iterators (the iterators themselves
    1920             :                 // will get invalidated), and adjust the old values so that they
    1921             :                 // reflect the insertion of the new paragraph:
    1922             :                 Paragraphs::size_type nOldVisibleBegin
    1923           0 :                     = m_aVisibleBegin - m_xParagraphs->begin();
    1924             :                 Paragraphs::size_type nOldVisibleEnd
    1925           0 :                     = m_aVisibleEnd - m_xParagraphs->begin();
    1926             :                 Paragraphs::size_type nOldFocused
    1927           0 :                     = m_aFocused - m_xParagraphs->begin();
    1928           0 :                 if (n <= nOldVisibleBegin)
    1929           0 :                     ++nOldVisibleBegin; // XXX  numeric overflow
    1930           0 :                 if (n <= nOldVisibleEnd)
    1931           0 :                     ++nOldVisibleEnd; // XXX  numeric overflow
    1932           0 :                 if (n <= nOldFocused)
    1933           0 :                     ++nOldFocused; // XXX  numeric overflow
    1934           0 :                 if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionFirstPara)
    1935           0 :                     ++m_nSelectionFirstPara; // XXX  numeric overflow
    1936           0 :                 if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionLastPara)
    1937           0 :                     ++m_nSelectionLastPara; // XXX  numeric overflow
    1938             : 
    1939             :                 Paragraphs::iterator aIns(
    1940             :                     m_xParagraphs->insert(
    1941           0 :                         m_xParagraphs->begin() + n,
    1942             :                         ParagraphInfo(static_cast< ::sal_Int32 >(
    1943           0 :                                           m_rEngine.GetTextHeight(n)))));
    1944             :                     // XXX  numeric overflow (2x)
    1945             : 
    1946           0 :                 determineVisibleRange();
    1947           0 :                 m_aFocused = m_xParagraphs->begin() + nOldFocused;
    1948             : 
    1949           0 :                 for (Paragraphs::iterator aIt(aIns);;)
    1950             :                 {
    1951           0 :                     ++aIt;
    1952           0 :                     if (aIt == m_xParagraphs->end())
    1953           0 :                         break;
    1954             :                     ::rtl::Reference< Paragraph > xParagraph(
    1955           0 :                         getParagraph(aIt));
    1956           0 :                     if (xParagraph.is())
    1957           0 :                         xParagraph->numberChanged(true);
    1958           0 :                 }
    1959             : 
    1960             :                 notifyVisibleRangeChanges(
    1961           0 :                     m_xParagraphs->begin() + nOldVisibleBegin,
    1962           0 :                     m_xParagraphs->begin() + nOldVisibleEnd, aIns);
    1963           0 :                 break;
    1964             :             }
    1965             :         case TEXT_HINT_PARAREMOVED:
    1966             :             {
    1967           0 :                 ::sal_uLong n = aHint.GetValue();
    1968           0 :                 if (n == TEXT_PARA_ALL)
    1969             :                 {
    1970           0 :                     for (Paragraphs::iterator aIt(m_aVisibleBegin);
    1971           0 :                          aIt != m_aVisibleEnd; ++aIt)
    1972             :                     {
    1973             :                         NotifyAccessibleEvent(
    1974             :                             css::accessibility::AccessibleEventId::
    1975             :                             CHILD,
    1976             :                             css::uno::makeAny(getAccessibleChild(aIt)),
    1977           0 :                             css::uno::Any());
    1978             :                     }
    1979           0 :                     disposeParagraphs();
    1980           0 :                     m_xParagraphs->clear();
    1981           0 :                     determineVisibleRange();
    1982           0 :                     m_nSelectionFirstPara = -1;
    1983           0 :                     m_nSelectionFirstPos = -1;
    1984           0 :                     m_nSelectionLastPara = -1;
    1985           0 :                     m_nSelectionLastPos = -1;
    1986           0 :                     m_aFocused = m_xParagraphs->end();
    1987             :                 }
    1988             :                 else
    1989             :                 {
    1990             :                     OSL_ENSURE(n < m_xParagraphs->size(),
    1991             :                                "Bad TEXT_HINT_PARAREMOVED event");
    1992             : 
    1993           0 :                     Paragraphs::iterator aIt(m_xParagraphs->begin() + n);
    1994             :                         // numeric overflow cannot occur
    1995             : 
    1996             :                     // Save the values of old iterators (the iterators
    1997             :                     // themselves will get invalidated), and adjust the old
    1998             :                     // values so that they reflect the removal of the paragraph:
    1999             :                     Paragraphs::size_type nOldVisibleBegin
    2000           0 :                         = m_aVisibleBegin - m_xParagraphs->begin();
    2001             :                     Paragraphs::size_type nOldVisibleEnd
    2002           0 :                         = m_aVisibleEnd - m_xParagraphs->begin();
    2003             :                     bool bWasVisible
    2004           0 :                         = nOldVisibleBegin <= n && n < nOldVisibleEnd;
    2005             :                     Paragraphs::size_type nOldFocused
    2006           0 :                         = m_aFocused - m_xParagraphs->begin();
    2007           0 :                     bool bWasFocused = aIt == m_aFocused;
    2008           0 :                     if (n < nOldVisibleBegin)
    2009           0 :                         --nOldVisibleBegin;
    2010           0 :                     if (n < nOldVisibleEnd)
    2011           0 :                         --nOldVisibleEnd;
    2012           0 :                     if (n < nOldFocused)
    2013           0 :                         --nOldFocused;
    2014           0 :                     if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionFirstPara)
    2015           0 :                         --m_nSelectionFirstPara;
    2016           0 :                     else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionFirstPara)
    2017             :                     {
    2018           0 :                         if (m_nSelectionFirstPara == m_nSelectionLastPara)
    2019             :                         {
    2020           0 :                             m_nSelectionFirstPara = -1;
    2021           0 :                             m_nSelectionFirstPos = -1;
    2022           0 :                             m_nSelectionLastPara = -1;
    2023           0 :                             m_nSelectionLastPos = -1;
    2024             :                         }
    2025             :                         else
    2026             :                         {
    2027           0 :                             ++m_nSelectionFirstPara;
    2028           0 :                             m_nSelectionFirstPos = 0;
    2029             :                         }
    2030             :                     }
    2031           0 :                     if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionLastPara)
    2032           0 :                         --m_nSelectionLastPara;
    2033           0 :                     else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionLastPara)
    2034             :                     {
    2035             :                         OSL_ENSURE(m_nSelectionFirstPara < m_nSelectionLastPara,
    2036             :                                    "logic error");
    2037           0 :                         --m_nSelectionLastPara;
    2038           0 :                         m_nSelectionLastPos = 0x7FFFFFFF;
    2039             :                     }
    2040             : 
    2041             :                     css::uno::Reference< css::accessibility::XAccessible >
    2042           0 :                           xStrong;
    2043           0 :                     if (bWasVisible)
    2044           0 :                         xStrong = getAccessibleChild(aIt);
    2045             :                     css::uno::WeakReference<
    2046             :                           css::accessibility::XAccessible > xWeak(
    2047           0 :                               aIt->getParagraph());
    2048           0 :                     aIt = m_xParagraphs->erase(aIt);
    2049             : 
    2050           0 :                     determineVisibleRange();
    2051           0 :                     m_aFocused = bWasFocused ? m_xParagraphs->end()
    2052           0 :                         : m_xParagraphs->begin() + nOldFocused;
    2053             : 
    2054           0 :                     for (; aIt != m_xParagraphs->end(); ++aIt)
    2055             :                     {
    2056             :                         ::rtl::Reference< Paragraph > xParagraph(
    2057           0 :                             getParagraph(aIt));
    2058           0 :                         if (xParagraph.is())
    2059           0 :                             xParagraph->numberChanged(false);
    2060           0 :                     }
    2061             : 
    2062           0 :                     if (bWasVisible)
    2063             :                         NotifyAccessibleEvent(
    2064             :                             css::accessibility::AccessibleEventId::
    2065             :                             CHILD,
    2066             :                             css::uno::makeAny(xStrong),
    2067           0 :                             css::uno::Any());
    2068             : 
    2069             :                     css::uno::Reference< css::lang::XComponent > xComponent(
    2070           0 :                         xWeak.get(), css::uno::UNO_QUERY);
    2071           0 :                     if (xComponent.is())
    2072           0 :                         xComponent->dispose();
    2073             : 
    2074             :                     notifyVisibleRangeChanges(
    2075           0 :                         m_xParagraphs->begin() + nOldVisibleBegin,
    2076           0 :                         m_xParagraphs->begin() + nOldVisibleEnd,
    2077           0 :                         m_xParagraphs->end());
    2078             :                 }
    2079           0 :                 break;
    2080             :             }
    2081             :         case TEXT_HINT_FORMATPARA:
    2082             :             {
    2083           0 :                 ::sal_uLong n = aHint.GetValue();
    2084             :                 OSL_ENSURE(n < m_xParagraphs->size(),
    2085             :                            "Bad TEXT_HINT_FORMATPARA event");
    2086             : 
    2087           0 :                 (*m_xParagraphs)[static_cast< Paragraphs::size_type >(n)].
    2088             :                     changeHeight(static_cast< ::sal_Int32 >(
    2089           0 :                                      m_rEngine.GetTextHeight(n)));
    2090             :                     // XXX  numeric overflow
    2091           0 :                 Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin);
    2092           0 :                 Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd);
    2093           0 :                 determineVisibleRange();
    2094             :                 notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd,
    2095           0 :                                           m_xParagraphs->end());
    2096             : 
    2097           0 :                 if (n < m_xParagraphs->size())
    2098             :                 {
    2099           0 :                     Paragraphs::iterator aIt(m_xParagraphs->begin() + n);
    2100           0 :                     ::rtl::Reference< Paragraph > xParagraph(getParagraph(aIt));
    2101           0 :                     if (xParagraph.is())
    2102           0 :                         xParagraph->textChanged();
    2103             :                 }
    2104           0 :                 break;
    2105             :             }
    2106             :         default:
    2107             :             OSL_FAIL( "bad buffered hint");
    2108           0 :             break;
    2109             :         }
    2110           0 :     }
    2111           0 :     if (m_bSelectionChangedNotification)
    2112             :     {
    2113           0 :         m_bSelectionChangedNotification = false;
    2114           0 :         handleSelectionChangeNotification();
    2115             :     }
    2116           0 : }
    2117             : 
    2118           0 : ::sal_Int32 Document::getSelectionType(::sal_Int32 nNewFirstPara, ::sal_Int32 nNewFirstPos, ::sal_Int32 nNewLastPara, ::sal_Int32 nNewLastPos)
    2119             : {
    2120           0 :     if (m_nSelectionFirstPara == -1)
    2121           0 :         return -1;
    2122           0 :     ::sal_Int32 Osp = m_nSelectionFirstPara, Osl = m_nSelectionFirstPos, Oep = m_nSelectionLastPara, Oel = m_nSelectionLastPos;
    2123           0 :     ::sal_Int32 Nsp = nNewFirstPara, Nsl = nNewFirstPos, Nep = nNewLastPara, Nel = nNewLastPos;
    2124           0 :     TextPaM Ns(Nsp, sal_uInt16(Nsl));
    2125           0 :     TextPaM Ne(Nep, sal_uInt16(Nel));
    2126           0 :     TextPaM Os(Osp, sal_uInt16(Osl));
    2127           0 :     TextPaM Oe(Oep, sal_uInt16(Oel));
    2128             : 
    2129           0 :     if (Os == Oe && Ns == Ne)
    2130             :     {
    2131             :         //only caret moves.
    2132           0 :         return 1;
    2133             :     }
    2134           0 :     else if (Os == Oe && Ns != Ne)
    2135             :     {
    2136             :         //old has no selection but new has selection
    2137           0 :         return 2;
    2138             :     }
    2139           0 :     else if (Os != Oe && Ns == Ne)
    2140             :     {
    2141             :         //old has selection but new has no selection.
    2142           0 :         return 3;
    2143             :     }
    2144           0 :     else if (Os != Oe && Ns != Ne && Osp == Nsp && Osl == Nsl)
    2145             :     {
    2146             :         //both old and new have selections.
    2147           0 :         if (Oep == Nep )
    2148             :         {
    2149             :             //Send text_selection_change event on Nep
    2150             : 
    2151           0 :             return 4;
    2152             :         }
    2153           0 :         else if (Oep < Nep)
    2154             :         {
    2155             :             //all the following examples like 1,2->1,3 means that old start select para is 1, old end select para is 2,
    2156             :             // then press shift up, the new start select para is 1, new end select para is 3;
    2157             :             //for example, 1, 2 -> 1, 3; 4,1 -> 4, 7; 4,1 -> 4, 2; 4,4->4,5
    2158           0 :             if (Nep >= Nsp)
    2159             :             {
    2160             :                 // 1, 2 -> 1, 3; 4, 1 -> 4, 7; 4,4->4,5;
    2161           0 :                 if (Oep < Osp)
    2162             :                 {
    2163             :                     // 4,1 -> 4,7;
    2164           0 :                     return 5;
    2165             :                 }
    2166           0 :                 else if (Oep >= Osp)
    2167             :                 {
    2168             :                     // 1, 2 -> 1, 3; 4,4->4,5;
    2169           0 :                     return 6;
    2170             :                 }
    2171             :             }
    2172             :             else
    2173             :             {
    2174             :                 // 4,1 -> 4,2,
    2175           0 :                 if (Oep < Osp)
    2176             :                 {
    2177             :                     // 4,1 -> 4,2,
    2178           0 :                     return 7;
    2179             :                 }
    2180             :                 else if (Oep >= Osp)
    2181             :                 {
    2182             :                     // no such condition. Oep > Osp = Nsp > Nep
    2183             :                 }
    2184             :             }
    2185             :         }
    2186           0 :         else if (Oep > Nep)
    2187             :         {
    2188             :             // 3,2 -> 3,1; 4,7 -> 4,1; 4, 7 -> 4,6; 4,4 -> 4,3
    2189           0 :             if (Nep >= Nsp)
    2190             :             {
    2191             :                 // 4,7 -> 4,6
    2192           0 :                 if (Oep <= Osp)
    2193             :                 {
    2194             :                     //no such condition, Oep<Osp=Nsp <= Nep
    2195             :                 }
    2196           0 :                 else if (Oep > Osp)
    2197             :                 {
    2198             :                     // 4,7 ->4,6
    2199           0 :                     return 8;
    2200             :                 }
    2201             :             }
    2202             :             else
    2203             :             {
    2204             :                 // 3,2 -> 3,1, 4,7 -> 4,1; 4,4->4,3
    2205           0 :                 if (Oep <= Osp)
    2206             :                 {
    2207             :                     // 3,2 -> 3,1; 4,4->4,3
    2208           0 :                     return 9;
    2209             :                 }
    2210           0 :                 else if (Oep > Osp)
    2211             :                 {
    2212             :                     // 4,7 -> 4,1
    2213           0 :                     return 10;
    2214             :                 }
    2215             :             }
    2216             :         }
    2217             :     }
    2218           0 :     return -1;
    2219             : }
    2220             : 
    2221             : 
    2222           0 : void Document::sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId)
    2223             : {
    2224           0 :     size_t nAvailDistance = std::distance(m_xParagraphs->begin(), m_aVisibleEnd);
    2225             : 
    2226           0 :     Paragraphs::iterator aEnd(m_xParagraphs->begin());
    2227           0 :     size_t nEndDistance = std::min<size_t>(end + 1, nAvailDistance);
    2228           0 :     std::advance(aEnd, nEndDistance);
    2229             : 
    2230           0 :     Paragraphs::iterator aIt(m_xParagraphs->begin());
    2231           0 :     size_t nStartDistance = std::min<size_t>(start, nAvailDistance);
    2232           0 :     std::advance(aIt, nStartDistance);
    2233             : 
    2234           0 :     while (aIt < aEnd)
    2235             :     {
    2236           0 :         ::rtl::Reference< Paragraph > xParagraph(getParagraph(aIt));
    2237           0 :         if (xParagraph.is())
    2238             :             xParagraph->notifyEvent(
    2239             :             nEventId,
    2240           0 :                 css::uno::Any(), css::uno::Any());
    2241           0 :         ++aIt;
    2242           0 :     }
    2243           0 : }
    2244             : 
    2245           0 : void Document::handleSelectionChangeNotification()
    2246             : {
    2247           0 :     ::TextSelection const & rSelection = m_rView.GetSelection();
    2248             :     OSL_ENSURE(rSelection.GetStart().GetPara() < m_xParagraphs->size()
    2249             :                && rSelection.GetEnd().GetPara() < m_xParagraphs->size(),
    2250             :                "bad TEXT_HINT_VIEWSELECTIONCHANGED event");
    2251             :     ::sal_Int32 nNewFirstPara
    2252           0 :           = static_cast< ::sal_Int32 >(rSelection.GetStart().GetPara());
    2253             :     ::sal_Int32 nNewFirstPos
    2254           0 :           = static_cast< ::sal_Int32 >(rSelection.GetStart().GetIndex());
    2255             :         // XXX  numeric overflow
    2256             :     ::sal_Int32 nNewLastPara
    2257           0 :           = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetPara());
    2258             :     ::sal_Int32 nNewLastPos
    2259           0 :           = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetIndex());
    2260             :         // XXX  numeric overflow
    2261             : 
    2262             :     // Lose focus:
    2263           0 :     Paragraphs::iterator aIt(m_xParagraphs->begin() + nNewLastPara);
    2264           0 :     if (m_aFocused != m_xParagraphs->end() && m_aFocused != aIt
    2265           0 :         && m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd)
    2266             :     {
    2267           0 :         ::rtl::Reference< Paragraph > xParagraph(getParagraph(m_aFocused));
    2268           0 :         if (xParagraph.is())
    2269             :             xParagraph->notifyEvent(
    2270             :                 css::accessibility::AccessibleEventId::
    2271             :                 STATE_CHANGED,
    2272             :                 css::uno::makeAny(
    2273             :                     css::accessibility::AccessibleStateType::FOCUSED),
    2274           0 :                 css::uno::Any());
    2275             :     }
    2276             : 
    2277             :     // Gain focus and update cursor position:
    2278           0 :     if (aIt >= m_aVisibleBegin && aIt < m_aVisibleEnd
    2279           0 :         && (aIt != m_aFocused
    2280           0 :             || nNewLastPara != m_nSelectionLastPara
    2281           0 :             || nNewLastPos != m_nSelectionLastPos))
    2282             :     {
    2283           0 :         ::rtl::Reference< Paragraph > xParagraph(getParagraph(aIt));
    2284           0 :         if (xParagraph.is())
    2285             :         {
    2286             :         //disable the first event when user types in empty field.
    2287           0 :         ::sal_Int32 count = getAccessibleChildCount();
    2288           0 :         bool bEmpty = count > 1;
    2289             :             //if (aIt != m_aFocused)
    2290           0 :             if (aIt != m_aFocused && bEmpty)
    2291             :                 xParagraph->notifyEvent(
    2292             :                     css::accessibility::AccessibleEventId::
    2293             :                     STATE_CHANGED,
    2294             :                     css::uno::Any(),
    2295             :                     css::uno::makeAny(
    2296           0 :                         css::accessibility::AccessibleStateType::FOCUSED));
    2297           0 :             if (nNewLastPara != m_nSelectionLastPara
    2298           0 :                 || nNewLastPos != m_nSelectionLastPos)
    2299             :                 xParagraph->notifyEvent(
    2300             :                     css::accessibility::AccessibleEventId::
    2301             :                     CARET_CHANGED,
    2302             :                     css::uno::makeAny< ::sal_Int32 >(
    2303           0 :                         nNewLastPara == m_nSelectionLastPara
    2304             :                         ? m_nSelectionLastPos : 0),
    2305           0 :                     css::uno::makeAny(nNewLastPos));
    2306           0 :         }
    2307             :     }
    2308           0 :     m_aFocused = aIt;
    2309             : 
    2310             :     ::sal_Int32 nMin;
    2311             :     ::sal_Int32 nMax;
    2312           0 :     ::sal_Int32 ret = getSelectionType(nNewFirstPara, nNewFirstPos, nNewLastPara, nNewLastPos);
    2313           0 :     switch (ret)
    2314             :     {
    2315             :         case -1:
    2316             :             {
    2317             :                 //no event
    2318             :             }
    2319           0 :             break;
    2320             :         case 1:
    2321             :             {
    2322             :                 //only caret moved, already handled in above
    2323             :             }
    2324           0 :             break;
    2325             :         case 2:
    2326             :             {
    2327             :                 //old has no selection but new has selection
    2328           0 :                 nMin = ::std::min(nNewFirstPara, nNewLastPara);
    2329           0 :                 nMax = ::std::max(nNewFirstPara, nNewLastPara);
    2330           0 :                 sendEvent(nMin, nMax,  css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2331           0 :                 sendEvent(nMin, nMax,  css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2332             :             }
    2333           0 :             break;
    2334             :         case 3:
    2335             :             {
    2336             :                 //old has selection but new has no selection.
    2337           0 :                 nMin = ::std::min(m_nSelectionFirstPara, m_nSelectionLastPara);
    2338           0 :                 nMax = ::std::max(m_nSelectionFirstPara, m_nSelectionLastPara);
    2339           0 :                 sendEvent(nMin, nMax,  css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2340           0 :                 sendEvent(nMin, nMax,  css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2341             :             }
    2342           0 :             break;
    2343             :         case 4:
    2344             :             {
    2345             :                 //Send text_selection_change event on Nep
    2346           0 :                 sendEvent(nNewLastPara, nNewLastPara, css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2347             :             }
    2348           0 :             break;
    2349             :         case 5:
    2350             :             {
    2351             :                 // 4, 1 -> 4, 7
    2352           0 :                 sendEvent(m_nSelectionLastPara, m_nSelectionFirstPara-1, css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2353           0 :                 sendEvent(nNewFirstPara+1, nNewLastPara, css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2354             : 
    2355           0 :                 sendEvent(m_nSelectionLastPara, nNewLastPara, css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2356             :             }
    2357           0 :             break;
    2358             :         case 6:
    2359             :             {
    2360             :                 // 1, 2 -> 1, 4; 4,4->4,5;
    2361           0 :                 sendEvent(m_nSelectionLastPara+1, nNewLastPara, css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2362             : 
    2363           0 :                 sendEvent(m_nSelectionLastPara, nNewLastPara, css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2364             :             }
    2365           0 :             break;
    2366             :         case 7:
    2367             :             {
    2368             :                 // 4,1 -> 4,3,
    2369           0 :                 sendEvent(m_nSelectionLastPara +1, nNewLastPara , css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2370             : 
    2371           0 :                 sendEvent(m_nSelectionLastPara, nNewLastPara, css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2372             :             }
    2373           0 :             break;
    2374             :         case 8:
    2375             :             {
    2376             :                 // 4,7 ->4,5;
    2377           0 :                 sendEvent(nNewLastPara + 1, m_nSelectionLastPara, css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2378             : 
    2379           0 :                 sendEvent(nNewLastPara, m_nSelectionLastPara, css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2380             :             }
    2381           0 :             break;
    2382             :         case 9:
    2383             :             {
    2384             :                 // 3,2 -> 3,1; 4,4->4,3
    2385           0 :                 sendEvent(nNewLastPara, m_nSelectionLastPara - 1, css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2386             : 
    2387           0 :                 sendEvent(nNewLastPara, m_nSelectionLastPara, css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2388             :             }
    2389           0 :             break;
    2390             :         case 10:
    2391             :             {
    2392             :                 // 4,7 -> 4,1
    2393           0 :                 sendEvent(m_nSelectionFirstPara + 1, m_nSelectionLastPara, css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2394           0 :                 sendEvent(nNewLastPara, nNewFirstPara - 1, css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2395             : 
    2396           0 :                 sendEvent(nNewLastPara, m_nSelectionLastPara, css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2397             :             }
    2398           0 :             break;
    2399             :         default:
    2400           0 :             break;
    2401             :     }
    2402             : 
    2403             :     /*
    2404             :     // Update both old and new selection.  (Regardless of how the two selections
    2405             :     // look like, there will always be two ranges to the left and right of the
    2406             :     // overlap---the overlap and/or the range to the right of it possibly being
    2407             :     // empty.  Only for these two ranges notifications have to be sent.)
    2408             : 
    2409             :     TextPaM aOldTextStart( static_cast< sal_uLong >( m_nSelectionFirstPara ), static_cast< sal_uInt16 >( m_nSelectionFirstPos ) );
    2410             :     TextPaM aOldTextEnd( static_cast< sal_uLong >( m_nSelectionLastPara ), static_cast< sal_uInt16 >( m_nSelectionLastPos ) );
    2411             :     TextPaM aNewTextStart( static_cast< sal_uLong >( nNewFirstPara ), static_cast< sal_uInt16 >( nNewFirstPos ) );
    2412             :     TextPaM aNewTextEnd( static_cast< sal_uLong >( nNewLastPara ), static_cast< sal_uInt16 >( nNewLastPos ) );
    2413             : 
    2414             :     // justify selections
    2415             :     justifySelection( aOldTextStart, aOldTextEnd );
    2416             :     justifySelection( aNewTextStart, aNewTextEnd );
    2417             : 
    2418             :     sal_Int32 nFirst1;
    2419             :     sal_Int32 nLast1;
    2420             :     sal_Int32 nFirst2;
    2421             :     sal_Int32 nLast2;
    2422             : 
    2423             :     if ( m_nSelectionFirstPara == -1 )
    2424             :     {
    2425             :         // old selection not initialized yet => notify events only for new selection (if not empty)
    2426             :         nFirst1 = aNewTextStart.GetPara();
    2427             :         nLast1 = aNewTextEnd.GetPara() + ( aNewTextStart != aNewTextEnd ? 1 : 0 );
    2428             :         nFirst2 = 0;
    2429             :         nLast2 = 0;
    2430             :     }
    2431             :     else if ( aOldTextStart == aOldTextEnd && aNewTextStart == aNewTextEnd )
    2432             :     {
    2433             :         // old and new selection empty => no events
    2434             :         nFirst1 = 0;
    2435             :         nLast1 = 0;
    2436             :         nFirst2 = 0;
    2437             :         nLast2 = 0;
    2438             :     }
    2439             :     else if ( aOldTextStart != aOldTextEnd && aNewTextStart == aNewTextEnd )
    2440             :     {
    2441             :         // old selection not empty + new selection empty => notify events only for old selection
    2442             :         nFirst1 = aOldTextStart.GetPara();
    2443             :         nLast1 = aOldTextEnd.GetPara() + 1;
    2444             :         nFirst2 = 0;
    2445             :         nLast2 = 0;
    2446             :     }
    2447             :     else if ( aOldTextStart == aOldTextEnd && aNewTextStart != aNewTextEnd )
    2448             :     {
    2449             :         // old selection empty + new selection not empty => notify events only for new selection
    2450             :         nFirst1 = aNewTextStart.GetPara();
    2451             :         nLast1 = aNewTextEnd.GetPara() + 1;
    2452             :         nFirst2 = 0;
    2453             :         nLast2 = 0;
    2454             :     }
    2455             :     else
    2456             :     {
    2457             :         // old and new selection not empty => notify events for the two ranges left and right of the overlap
    2458             :         ::std::vector< TextPaM > aTextPaMs(4);
    2459             :         aTextPaMs[0] = aOldTextStart;
    2460             :         aTextPaMs[1] = aOldTextEnd;
    2461             :         aTextPaMs[2] = aNewTextStart;
    2462             :         aTextPaMs[3] = aNewTextEnd;
    2463             :         ::std::sort( aTextPaMs.begin(), aTextPaMs.end() );
    2464             : 
    2465             :         nFirst1 = aTextPaMs[0].GetPara();
    2466             :         nLast1 = aTextPaMs[1].GetPara() + ( aTextPaMs[0] != aTextPaMs[1] ? 1 : 0 );
    2467             : 
    2468             :         nFirst2 = aTextPaMs[2].GetPara();
    2469             :         nLast2 = aTextPaMs[3].GetPara() + ( aTextPaMs[2] != aTextPaMs[3] ? 1 : 0 );
    2470             : 
    2471             :         // adjust overlapping ranges
    2472             :         if ( nLast1 > nFirst2 )
    2473             :             nLast1 = nFirst2;
    2474             :     }
    2475             : 
    2476             :     // notify selection changes
    2477             :     notifySelectionChange( nFirst1, nLast1 );
    2478             :     notifySelectionChange( nFirst2, nLast2 );
    2479             :     */
    2480           0 :     m_nSelectionFirstPara = nNewFirstPara;
    2481           0 :     m_nSelectionFirstPos = nNewFirstPos;
    2482           0 :     m_nSelectionLastPara = nNewLastPara;
    2483           0 :     m_nSelectionLastPos = nNewLastPos;
    2484           0 : }
    2485             : 
    2486           0 : void Document::disposeParagraphs()
    2487             : {
    2488           0 :     for (Paragraphs::iterator aIt(m_xParagraphs->begin());
    2489           0 :          aIt != m_xParagraphs->end(); ++aIt)
    2490             :     {
    2491             :         css::uno::Reference< css::lang::XComponent > xComponent(
    2492           0 :             aIt->getParagraph().get(), css::uno::UNO_QUERY);
    2493           0 :         if (xComponent.is())
    2494           0 :             xComponent->dispose();
    2495           0 :     }
    2496           0 : }
    2497             : 
    2498             : // static
    2499           0 : css::uno::Any Document::mapFontColor(::Color const & rColor)
    2500             : {
    2501             :     return css::uno::makeAny(
    2502           0 :         static_cast< ::sal_Int32 >(COLORDATA_RGB(rColor.GetColor())));
    2503             :         // FIXME  keep transparency?
    2504             : }
    2505             : 
    2506             : // static
    2507           0 : ::Color Document::mapFontColor(css::uno::Any const & rColor)
    2508             : {
    2509           0 :     ::sal_Int32 nColor = 0;
    2510           0 :     rColor >>= nColor;
    2511           0 :     return ::Color(static_cast< ::ColorData >(nColor));
    2512             : }
    2513             : 
    2514             : // static
    2515           0 : css::uno::Any Document::mapFontWeight(::FontWeight nWeight)
    2516             : {
    2517             :     // Map from ::FontWeight to css::awt::FontWeight, depends on order of
    2518             :     // elements in ::FontWeight (vcl/vclenum.hxx):
    2519             :     static float const aWeight[]
    2520             :         = { css::awt::FontWeight::DONTKNOW, // WEIGHT_DONTKNOW
    2521             :             css::awt::FontWeight::THIN, // WEIGHT_THIN
    2522             :             css::awt::FontWeight::ULTRALIGHT, // WEIGHT_ULTRALIGHT
    2523             :             css::awt::FontWeight::LIGHT, // WEIGHT_LIGHT
    2524             :             css::awt::FontWeight::SEMILIGHT, // WEIGHT_SEMILIGHT
    2525             :             css::awt::FontWeight::NORMAL, // WEIGHT_NORMAL
    2526             :             css::awt::FontWeight::NORMAL, // WEIGHT_MEDIUM
    2527             :             css::awt::FontWeight::SEMIBOLD, // WEIGHT_SEMIBOLD
    2528             :             css::awt::FontWeight::BOLD, // WEIGHT_BOLD
    2529             :             css::awt::FontWeight::ULTRABOLD, // WEIGHT_ULTRABOLD
    2530             :             css::awt::FontWeight::BLACK }; // WEIGHT_BLACK
    2531           0 :     return css::uno::makeAny(aWeight[nWeight]);
    2532             : }
    2533             : 
    2534             : // static
    2535           0 : ::FontWeight Document::mapFontWeight(css::uno::Any const & rWeight)
    2536             : {
    2537           0 :     float nWeight = css::awt::FontWeight::NORMAL;
    2538           0 :     rWeight >>= nWeight;
    2539           0 :     return nWeight <= css::awt::FontWeight::DONTKNOW ? WEIGHT_DONTKNOW
    2540           0 :         : nWeight <= css::awt::FontWeight::THIN ? WEIGHT_THIN
    2541           0 :         : nWeight <= css::awt::FontWeight::ULTRALIGHT ? WEIGHT_ULTRALIGHT
    2542           0 :         : nWeight <= css::awt::FontWeight::LIGHT ? WEIGHT_LIGHT
    2543           0 :         : nWeight <= css::awt::FontWeight::SEMILIGHT ? WEIGHT_SEMILIGHT
    2544           0 :         : nWeight <= css::awt::FontWeight::NORMAL ? WEIGHT_NORMAL
    2545           0 :         : nWeight <= css::awt::FontWeight::SEMIBOLD ? WEIGHT_SEMIBOLD
    2546           0 :         : nWeight <= css::awt::FontWeight::BOLD ? WEIGHT_BOLD
    2547           0 :         : nWeight <= css::awt::FontWeight::ULTRABOLD ? WEIGHT_ULTRABOLD
    2548           0 :         : WEIGHT_BLACK;
    2549             : }
    2550             : 
    2551             : }
    2552             : 
    2553             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11