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

Generated by: LCOV version 1.10