LCOV - code coverage report
Current view: top level - accessibility/source/extended - textwindowaccessibility.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1087 0.0 %
Date: 2014-04-14 Functions: 0 119 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <accessibility/extended/textwindowaccessibility.hxx>
      21             : #include "comphelper/accessibleeventnotifier.hxx"
      22             : #include "unotools/accessiblerelationsethelper.hxx"
      23             : #include <unotools/accessiblestatesethelper.hxx>
      24             : #include <vcl/window.hxx>
      25             : #include <toolkit/helper/convert.hxx>
      26             : 
      27             : #include <algorithm>
      28             : #include <vector>
      29             : #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(::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 :     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) ? true : false;
     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 :     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             :     //character background color
    1005             :     {
    1006           0 :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("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             :     {
    1014           0 :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharColor"));
    1015           0 :         aAttribs[i].Handle = -1;
    1016             :         //aAttribs[i].Value = mapFontColor( aFont.GetColor() );
    1017           0 :         aAttribs[i].Value = mapFontColor( m_rEngine.GetTextColor() );
    1018           0 :         aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
    1019           0 :         i++;
    1020             :     }
    1021             :     //character font name
    1022             :     {
    1023           0 :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharFontName"));
    1024           0 :         aAttribs[i].Handle = -1;
    1025           0 :         aAttribs[i].Value = ::css::uno::makeAny( (::rtl::OUString)aFont.GetName() );
    1026           0 :         aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
    1027           0 :         i++;
    1028             :     }
    1029             :     //character height
    1030             :     {
    1031           0 :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharHeight"));
    1032           0 :         aAttribs[i].Handle = -1;
    1033           0 :         aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetHeight() );
    1034           0 :         aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
    1035           0 :         i++;
    1036             :     }
    1037             :     //character posture
    1038             :     {
    1039           0 :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharPosture"));
    1040           0 :         aAttribs[i].Handle = -1;
    1041           0 :         aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetItalic() );
    1042           0 :         aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
    1043           0 :         i++;
    1044             :     }
    1045             :     //character relief
    1046             :     /*{
    1047             :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharRelief"));
    1048             :         aAttribs[i].Handle = -1;
    1049             :         aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetRelief() );
    1050             :         aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
    1051             :         i++;
    1052             :     }*/
    1053             :     //character strikeout
    1054             :     {
    1055           0 :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharStrikeout"));
    1056           0 :         aAttribs[i].Handle = -1;
    1057           0 :         aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetStrikeout() );
    1058           0 :         aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
    1059           0 :         i++;
    1060             :     }
    1061             :     //character underline
    1062             :     {
    1063           0 :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharUnderline"));
    1064           0 :         aAttribs[i].Handle = -1;
    1065           0 :         aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)aFont.GetUnderline() );
    1066           0 :         aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
    1067           0 :         i++;
    1068             :     }
    1069             :     //character weight
    1070             :     {
    1071           0 :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharWeight"));
    1072           0 :         aAttribs[i].Handle = -1;
    1073           0 :         aAttribs[i].Value = ::css::uno::makeAny( (float)aFont.GetWeight() );
    1074           0 :         aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
    1075           0 :         i++;
    1076             :     }
    1077             :     //character alignment
    1078             :     {
    1079           0 :         aAttribs[i].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaAdjust"));
    1080           0 :         aAttribs[i].Handle = -1;
    1081           0 :         aAttribs[i].Value = ::css::uno::makeAny( (sal_Int16)m_rEngine.GetTextAlign() );
    1082           0 :         aAttribs[i].State = ::css::beans::PropertyState_DIRECT_VALUE;
    1083           0 :         i++;
    1084             :     }
    1085             : 
    1086           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
    1087           0 :     ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1088             :         // XXX  numeric overflow
    1089             :         // nIndex can be equal to getLength();
    1090           0 :     if (nIndex < 0 || nIndex > m_rEngine.GetText(nNumber).getLength())
    1091             :         throw css::lang::IndexOutOfBoundsException(
    1092             :             "textwindowaccessibility.cxx:"
    1093             :             " Document::retrieveCharacterAttributes",
    1094           0 :             static_cast< css::uno::XWeak * >(this));
    1095             : 
    1096             :     // retrieve default attributes
    1097           0 :     tPropValMap aCharAttrSeq;
    1098           0 :     retrieveDefaultAttributesImpl( pParagraph, aRequestedAttributes, aCharAttrSeq );
    1099             : 
    1100             :     // retrieve run attributes
    1101           0 :     tPropValMap aRunAttrSeq;
    1102           0 :     retrieveRunAttributesImpl( pParagraph, nIndex, aRequestedAttributes, aRunAttrSeq );
    1103             : 
    1104             :     // merge default and run attributes
    1105           0 :     for ( tPropValMap::const_iterator aRunIter  = aRunAttrSeq.begin();
    1106           0 :           aRunIter != aRunAttrSeq.end();
    1107             :           ++aRunIter )
    1108             :     {
    1109           0 :         aCharAttrSeq[ aRunIter->first ] = aRunIter->second;
    1110             :     }
    1111             : 
    1112           0 :     ::css::beans::PropertyValue* pValues = aAttribs.getArray();
    1113           0 :     for (i = 0; i < AttributeCount; i++,pValues++)
    1114             :     {
    1115           0 :         aCharAttrSeq[ pValues->Name ] = *pValues;
    1116             :     }
    1117             : 
    1118           0 :     ::css::uno::Sequence< ::css::beans::PropertyValue > aRes = convertHashMapToSequence( aCharAttrSeq );
    1119             : 
    1120             :     // sort the attributes
    1121           0 :     sal_Int32 nLength = aRes.getLength();
    1122           0 :     const ::css::beans::PropertyValue* pPairs = aRes.getConstArray();
    1123           0 :     sal_Int32* pIndices = new sal_Int32[nLength];
    1124           0 :     for( i = 0; i < nLength; i++ )
    1125           0 :         pIndices[i] = i;
    1126           0 :     std::sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) );
    1127             :     // create sorted sequences accoring to index array
    1128           0 :     ::css::uno::Sequence< ::css::beans::PropertyValue > aNewValues( nLength );
    1129           0 :     ::css::beans::PropertyValue* pNewValues = aNewValues.getArray();
    1130           0 :     for( i = 0; i < nLength; i++ )
    1131             :     {
    1132           0 :         pNewValues[i] = pPairs[pIndices[i]];
    1133             :     }
    1134           0 :     delete[] pIndices;
    1135             : 
    1136           0 :     return aNewValues;
    1137             : }
    1138             : 
    1139           0 : void Document::retrieveDefaultAttributesImpl(
    1140             :     Paragraph const * pParagraph,
    1141             :     const css::uno::Sequence< OUString >& RequestedAttributes,
    1142             :     tPropValMap& rDefAttrSeq)
    1143             : {
    1144             :     // default attributes are not supported by text engine
    1145             :     (void) pParagraph;
    1146             :     (void) RequestedAttributes;
    1147             :     (void) rDefAttrSeq;
    1148           0 : }
    1149             : 
    1150             : css::uno::Sequence< css::beans::PropertyValue >
    1151           0 : Document::retrieveDefaultAttributes(
    1152             :     Paragraph const * pParagraph,
    1153             :     const css::uno::Sequence< OUString >& RequestedAttributes)
    1154             : {
    1155           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
    1156           0 :     ::osl::MutexGuard aInternalGuard( GetMutex() );
    1157             : 
    1158           0 :     tPropValMap aDefAttrSeq;
    1159           0 :     retrieveDefaultAttributesImpl( pParagraph, RequestedAttributes, aDefAttrSeq );
    1160           0 :     return convertHashMapToSequence( aDefAttrSeq );
    1161             : }
    1162             : 
    1163             : // static
    1164             : css::uno::Sequence< css::beans::PropertyValue >
    1165           0 : Document::convertHashMapToSequence(tPropValMap& rAttrSeq)
    1166             : {
    1167           0 :     css::uno::Sequence< css::beans::PropertyValue > aValues( rAttrSeq.size() );
    1168           0 :     css::beans::PropertyValue* pValues = aValues.getArray();
    1169           0 :     ::sal_Int32 i = 0;
    1170           0 :     for ( tPropValMap::const_iterator aIter  = rAttrSeq.begin();
    1171           0 :           aIter != rAttrSeq.end();
    1172             :           ++aIter )
    1173             :     {
    1174           0 :         pValues[i] = aIter->second;
    1175           0 :         ++i;
    1176             :     }
    1177           0 :     return aValues;
    1178             : }
    1179             : 
    1180           0 : void Document::retrieveRunAttributesImpl(
    1181             :     Paragraph const * pParagraph, ::sal_Int32 Index,
    1182             :     const css::uno::Sequence< OUString >& RequestedAttributes,
    1183             :     tPropValMap& rRunAttrSeq)
    1184             : {
    1185           0 :     ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
    1186           0 :     ::TextPaM aPaM( nNumber, static_cast< ::sal_uInt16 >( Index ) );
    1187             :         // XXX  numeric overflow
    1188             :     // FIXME  TEXTATTR_HYPERLINK ignored:
    1189             :     ::TextAttribFontColor const * pColor
    1190             :           = static_cast< ::TextAttribFontColor const * >(
    1191           0 :               m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTCOLOR ) );
    1192             :     ::TextAttribFontWeight const * pWeight
    1193             :           = static_cast< ::TextAttribFontWeight const * >(
    1194           0 :               m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTWEIGHT ) );
    1195           0 :     tPropValMap aRunAttrSeq;
    1196           0 :     if ( pColor )
    1197             :     {
    1198           0 :         css::beans::PropertyValue aPropVal;
    1199           0 :         aPropVal.Name = "CharColor";
    1200           0 :         aPropVal.Handle = -1;
    1201           0 :         aPropVal.Value = mapFontColor( pColor->GetColor() );
    1202           0 :         aPropVal.State = css::beans::PropertyState_DIRECT_VALUE;
    1203           0 :         aRunAttrSeq[ aPropVal.Name ] = aPropVal;
    1204             :     }
    1205           0 :     if ( pWeight )
    1206             :     {
    1207           0 :         css::beans::PropertyValue aPropVal;
    1208           0 :         aPropVal.Name = "CharWeight";
    1209           0 :         aPropVal.Handle = -1;
    1210           0 :         aPropVal.Value = mapFontWeight( pWeight->getFontWeight() );
    1211           0 :         aPropVal.State = css::beans::PropertyState_DIRECT_VALUE;
    1212           0 :         aRunAttrSeq[ aPropVal.Name ] = aPropVal;
    1213             :     }
    1214           0 :     if ( RequestedAttributes.getLength() == 0 )
    1215             :     {
    1216           0 :         rRunAttrSeq = aRunAttrSeq;
    1217             :     }
    1218             :     else
    1219             :     {
    1220           0 :         const OUString* pReqAttrs = RequestedAttributes.getConstArray();
    1221           0 :         const ::sal_Int32 nLength = RequestedAttributes.getLength();
    1222           0 :         for ( ::sal_Int32 i = 0; i < nLength; ++i )
    1223             :         {
    1224           0 :             tPropValMap::iterator aIter = aRunAttrSeq.find( pReqAttrs[i] );
    1225           0 :             if ( aIter != aRunAttrSeq.end() )
    1226             :             {
    1227           0 :                 rRunAttrSeq[ (*aIter).first ] = (*aIter).second;
    1228             :             }
    1229             :         }
    1230           0 :     }
    1231           0 : }
    1232             : 
    1233             : css::uno::Sequence< css::beans::PropertyValue >
    1234           0 : Document::retrieveRunAttributes(
    1235             :     Paragraph const * pParagraph, ::sal_Int32 Index,
    1236             :     const css::uno::Sequence< OUString >& RequestedAttributes)
    1237             : {
    1238           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
    1239           0 :     ::osl::MutexGuard aInternalGuard( GetMutex() );
    1240           0 :     ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
    1241             :         // XXX  numeric overflow
    1242           0 :     if ( Index < 0 || Index >= m_rEngine.GetText(nNumber).getLength() )
    1243             :         throw css::lang::IndexOutOfBoundsException(
    1244             :             "textwindowaccessibility.cxx:"
    1245             :             " Document::retrieveRunAttributes",
    1246           0 :             static_cast< css::uno::XWeak * >( this ) );
    1247             : 
    1248           0 :     tPropValMap aRunAttrSeq;
    1249           0 :     retrieveRunAttributesImpl( pParagraph, Index, RequestedAttributes, aRunAttrSeq );
    1250           0 :     return convertHashMapToSequence( aRunAttrSeq );
    1251             : }
    1252             : 
    1253           0 : void Document::changeParagraphText(Paragraph * pParagraph,
    1254             :                                    OUString const & rText)
    1255             : {
    1256           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1257             :     {
    1258           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1259           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1260             :             // XXX  numeric overflow
    1261           0 :         changeParagraphText(nNumber, 0, m_rEngine.GetTextLen(nNumber), false,
    1262           0 :                             false, rText);
    1263           0 :     }
    1264           0 : }
    1265             : 
    1266           0 : void Document::changeParagraphText(Paragraph * pParagraph,
    1267             :                                    ::sal_Int32 nBegin, ::sal_Int32 nEnd,
    1268             :                                    bool bCut, bool bPaste,
    1269             :                                    OUString const & rText)
    1270             : {
    1271           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1272             :     {
    1273           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1274           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1275             :             // XXX  numeric overflow
    1276           0 :         if (nBegin < 0 || nBegin > nEnd
    1277           0 :             || nEnd > m_rEngine.GetText(nNumber).getLength())
    1278             :             throw css::lang::IndexOutOfBoundsException(
    1279             :                 "textwindowaccessibility.cxx:"
    1280             :                 " Document::changeParagraphText",
    1281           0 :                 static_cast< css::uno::XWeak * >(this));
    1282             :         changeParagraphText(nNumber, static_cast< ::sal_uInt16 >(nBegin),
    1283           0 :                             static_cast< ::sal_uInt16 >(nEnd), bCut, bPaste, rText);
    1284             :             // XXX  numeric overflow (2x)
    1285           0 :     }
    1286           0 : }
    1287             : 
    1288           0 : void Document::copyParagraphText(Paragraph const * pParagraph,
    1289             :                                  ::sal_Int32 nBegin, ::sal_Int32 nEnd)
    1290             : {
    1291           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1292             :     {
    1293           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1294           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1295             :             // XXX  numeric overflow
    1296           0 :         if (nBegin < 0 || nBegin > nEnd
    1297           0 :             || nEnd > m_rEngine.GetText(nNumber).getLength())
    1298             :             throw css::lang::IndexOutOfBoundsException(
    1299             :                 "textwindowaccessibility.cxx:"
    1300             :                 " Document::copyParagraphText",
    1301           0 :                 static_cast< css::uno::XWeak * >(this));
    1302             :         m_rView.SetSelection(
    1303             :             ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)),
    1304           0 :                             ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd))));
    1305             :             // XXX  numeric overflow (2x)
    1306           0 :         m_rView.Copy();
    1307           0 :     }
    1308           0 : }
    1309             : 
    1310           0 : void Document::changeParagraphAttributes(
    1311             :     Paragraph * pParagraph, ::sal_Int32 nBegin, ::sal_Int32 nEnd,
    1312             :     css::uno::Sequence< css::beans::PropertyValue > const & rAttributeSet)
    1313             : {
    1314           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1315             :     {
    1316           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1317           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1318             :         // XXX  numeric overflow
    1319           0 :         if (nBegin < 0 || nBegin > nEnd
    1320           0 :             || nEnd > m_rEngine.GetText(nNumber).getLength())
    1321             :             throw css::lang::IndexOutOfBoundsException(
    1322             :                 "textwindowaccessibility.cxx:"
    1323             :                 " Document::changeParagraphAttributes",
    1324           0 :                 static_cast< css::uno::XWeak * >(this));
    1325             : 
    1326             :         // FIXME  The new attributes are added to any attributes already set,
    1327             :         // they do not replace the old attributes as required by
    1328             :         // XAccessibleEditableText.setAttributes:
    1329           0 :         for (::sal_Int32 i = 0; i < rAttributeSet.getLength(); ++i)
    1330           0 :             if ( rAttributeSet[i].Name == "CharColor" )
    1331             :                 m_rEngine.SetAttrib(::TextAttribFontColor(
    1332           0 :                                         mapFontColor(rAttributeSet[i].Value)),
    1333             :                                     nNumber, static_cast< ::sal_uInt16 >(nBegin),
    1334           0 :                                     static_cast< ::sal_uInt16 >(nEnd));
    1335             :                     // XXX  numeric overflow (2x)
    1336           0 :             else if ( rAttributeSet[i].Name == "CharWeight" )
    1337             :                 m_rEngine.SetAttrib(::TextAttribFontWeight(
    1338           0 :                                         mapFontWeight(rAttributeSet[i].Value)),
    1339             :                                     nNumber, static_cast< ::sal_uInt16 >(nBegin),
    1340           0 :                                     static_cast< ::sal_uInt16 >(nEnd));
    1341             :                     // XXX  numeric overflow (2x)
    1342           0 :     }
    1343           0 : }
    1344             : 
    1345           0 : void Document::changeParagraphSelection(Paragraph * pParagraph,
    1346             :                                         ::sal_Int32 nBegin, ::sal_Int32 nEnd)
    1347             : {
    1348           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1349             :     {
    1350           0 :         ::osl::MutexGuard aInternalGuard(GetMutex());
    1351           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber());
    1352             :             // XXX  numeric overflow
    1353           0 :         if (nBegin < 0 || nBegin > nEnd
    1354           0 :             || nEnd > m_rEngine.GetText(nNumber).getLength())
    1355             :             throw css::lang::IndexOutOfBoundsException(
    1356             :                 "textwindowaccessibility.cxx:"
    1357             :                 " Document::changeParagraphSelection",
    1358           0 :                 static_cast< css::uno::XWeak * >(this));
    1359             :         m_rView.SetSelection(
    1360             :             ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)),
    1361           0 :                             ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd))));
    1362             :             // XXX  numeric overflow (2x)
    1363           0 :     }
    1364           0 : }
    1365             : 
    1366             : css::i18n::Boundary
    1367           0 : Document::retrieveParagraphLineBoundary( Paragraph const * pParagraph,
    1368             :                                          ::sal_Int32 nIndex, ::sal_Int32 *pLineNo )
    1369             : {
    1370           0 :     css::i18n::Boundary aBoundary;
    1371           0 :     aBoundary.startPos = nIndex;
    1372           0 :     aBoundary.endPos = nIndex;
    1373             : 
    1374           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
    1375             :     {
    1376           0 :         ::osl::MutexGuard aInternalGuard( GetMutex() );
    1377           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
    1378           0 :         if ( nIndex < 0 || nIndex > m_rEngine.GetText( nNumber ).getLength() )
    1379             :             throw css::lang::IndexOutOfBoundsException(
    1380             :                 "textwindowaccessibility.cxx:"
    1381             :                 " Document::retrieveParagraphLineBoundary",
    1382           0 :                 static_cast< css::uno::XWeak * >( this ) );
    1383           0 :         ::sal_Int32 nLineStart = 0;
    1384           0 :         ::sal_Int32 nLineEnd = 0;
    1385           0 :         ::sal_uInt16 nLineCount = m_rEngine.GetLineCount( nNumber );
    1386           0 :         for ( ::sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine )
    1387             :         {
    1388             :             ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >(
    1389           0 :                 m_rEngine.GetLineLen( nNumber, nLine ) );
    1390           0 :             nLineStart = nLineEnd;
    1391           0 :             nLineEnd += nLineLength;
    1392           0 :             if ( nIndex >= nLineStart && ( ( nLine == nLineCount - 1 ) ? nIndex <= nLineEnd : nIndex < nLineEnd ) )
    1393             :             {
    1394           0 :                 aBoundary.startPos = nLineStart;
    1395           0 :                 aBoundary.endPos = nLineEnd;
    1396           0 :                 if( pLineNo )
    1397           0 :                     pLineNo[0] = nLine;
    1398           0 :                 break;
    1399             :             }
    1400           0 :         }
    1401             :     }
    1402             : 
    1403           0 :     return aBoundary;
    1404             : }
    1405             : 
    1406             : css::i18n::Boundary
    1407           0 : Document::retrieveParagraphBoundaryOfLine( Paragraph const * pParagraph,
    1408             :                                            ::sal_Int32 nLineNo )
    1409             : {
    1410           0 :     css::i18n::Boundary aBoundary;
    1411           0 :     aBoundary.startPos = 0;
    1412           0 :     aBoundary.endPos = 0;
    1413             : 
    1414           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() );
    1415             :     {
    1416           0 :         ::osl::MutexGuard aInternalGuard( GetMutex() );
    1417           0 :         ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() );
    1418           0 :         if ( nLineNo >= m_rEngine.GetLineCount( nNumber ) )
    1419             :             throw css::lang::IndexOutOfBoundsException(
    1420             :                 "textwindowaccessibility.cxx:"
    1421             :                 " Document::retrieveParagraphBoundaryOfLine",
    1422           0 :                 static_cast< css::uno::XWeak * >( this ) );
    1423           0 :         ::sal_Int32 nLineStart = 0;
    1424           0 :         ::sal_Int32 nLineEnd = 0;
    1425           0 :         for ( ::sal_uInt16 nLine = 0; nLine <= nLineNo; ++nLine )
    1426             :         {
    1427             :             ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >(
    1428           0 :                 m_rEngine.GetLineLen( nNumber, nLine ) );
    1429           0 :             nLineStart = nLineEnd;
    1430           0 :             nLineEnd += nLineLength;
    1431             :         }
    1432             : 
    1433           0 :         aBoundary.startPos = nLineStart;
    1434           0 :         aBoundary.endPos = nLineEnd;
    1435             :     }
    1436             : 
    1437           0 :     return aBoundary;
    1438             : }
    1439             : 
    1440           0 : sal_Int32 Document::retrieveParagraphLineWithCursor( Paragraph const * pParagraph )
    1441             : {
    1442           0 :     ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock());
    1443           0 :     ::osl::MutexGuard aInternalGuard(GetMutex());
    1444           0 :     ::TextSelection const & rSelection = m_rView.GetSelection();
    1445           0 :     Paragraphs::size_type nNumber = pParagraph->getNumber();
    1446           0 :     TextPaM aEndPaM( rSelection.GetEnd() );
    1447             : 
    1448           0 :     return aEndPaM.GetPara() == nNumber
    1449           0 :         ? m_rView.GetLineNumberOfCursorInSelection() : -1;
    1450             : }
    1451             : 
    1452             : 
    1453             : css::uno::Reference< css::accessibility::XAccessibleRelationSet >
    1454           0 : Document::retrieveParagraphRelationSet( Paragraph const * pParagraph )
    1455             : {
    1456           0 :     ::osl::MutexGuard aInternalGuard( GetMutex() );
    1457             : 
    1458           0 :     ::utl::AccessibleRelationSetHelper* pRelationSetHelper = new ::utl::AccessibleRelationSetHelper();
    1459           0 :     css::uno::Reference< css::accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper;
    1460             : 
    1461           0 :     Paragraphs::iterator aPara( m_xParagraphs->begin() + pParagraph->getNumber() );
    1462             : 
    1463           0 :     if ( aPara > m_aVisibleBegin && aPara < m_aVisibleEnd )
    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_FROM, aSequence );
    1468           0 :         pRelationSetHelper->AddRelation( aRelation );
    1469             :     }
    1470             : 
    1471           0 :     if ( aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd -1 )
    1472             :     {
    1473           0 :         css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > aSequence(1);
    1474           0 :         aSequence[0] = getAccessibleChild( aPara + 1 );
    1475           0 :         css::accessibility::AccessibleRelation aRelation( css::accessibility::AccessibleRelationType::CONTENT_FLOWS_TO, aSequence );
    1476           0 :         pRelationSetHelper->AddRelation( aRelation );
    1477             :     }
    1478             : 
    1479           0 :     return xSet;
    1480             : }
    1481             : 
    1482             : // virtual
    1483           0 : ::sal_Int32 SAL_CALL Document::getAccessibleChildCount()
    1484             :     throw (css::uno::RuntimeException, std::exception)
    1485             : {
    1486           0 :     ::comphelper::OExternalLockGuard aGuard(this);
    1487           0 :     init();
    1488           0 :     return m_aVisibleEnd - m_aVisibleBegin;
    1489             : }
    1490             : 
    1491             : // virtual
    1492             : css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
    1493           0 : Document::getAccessibleChild(::sal_Int32 i)
    1494             :     throw (css::lang::IndexOutOfBoundsException,
    1495             :            css::uno::RuntimeException, std::exception)
    1496             : {
    1497           0 :     ::comphelper::OExternalLockGuard aGuard(this);
    1498           0 :     init();
    1499           0 :     if (i < 0 || i >= m_aVisibleEnd - m_aVisibleBegin)
    1500             :         throw css::lang::IndexOutOfBoundsException(
    1501             :             "textwindowaccessibility.cxx:"
    1502             :             " Document::getAccessibleChild",
    1503           0 :             static_cast< css::uno::XWeak * >(this));
    1504             :     return getAccessibleChild(m_aVisibleBegin
    1505           0 :                               + static_cast< Paragraphs::size_type >(i));
    1506             : }
    1507             : 
    1508             : // virtual
    1509           0 : ::sal_Int16 SAL_CALL Document::getAccessibleRole()
    1510             :     throw (css::uno::RuntimeException, std::exception)
    1511             : {
    1512           0 :     return css::accessibility::AccessibleRole::TEXT_FRAME;
    1513             : }
    1514             : 
    1515             : // virtual
    1516             : css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
    1517           0 : Document::getAccessibleAtPoint(css::awt::Point const & rPoint)
    1518             :     throw (css::uno::RuntimeException, std::exception)
    1519             : {
    1520           0 :     ::comphelper::OExternalLockGuard aGuard(this);
    1521           0 :     init();
    1522           0 :     if (rPoint.X >= 0
    1523           0 :         && rPoint.X < m_rView.GetWindow()->GetOutputSizePixel().Width()
    1524           0 :         && rPoint.Y >= 0 && rPoint.Y < m_nViewHeight)
    1525             :     {
    1526           0 :         ::sal_Int32 nOffset = m_nViewOffset + rPoint.Y; // XXX  numeric overflow
    1527           0 :         ::sal_Int32 nPos = m_nViewOffset - m_nVisibleBeginOffset;
    1528           0 :         for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd;
    1529             :              ++aIt)
    1530             :         {
    1531           0 :             nPos += aIt->getHeight(); // XXX  numeric overflow
    1532           0 :             if (nOffset < nPos)
    1533           0 :                 return getAccessibleChild(aIt);
    1534             :         }
    1535             :     }
    1536           0 :     return 0;
    1537             : }
    1538           0 : void Document::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
    1539             : {
    1540           0 :     VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
    1541           0 :     if (!m_rView.IsReadOnly())
    1542           0 :         rStateSet.AddState( ::css::accessibility::AccessibleStateType::EDITABLE );
    1543           0 : }
    1544             : 
    1545           0 : void    Document::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
    1546             : {
    1547           0 :     if( getAccessibleParent()->getAccessibleContext()->getAccessibleRole() == ::css::accessibility::AccessibleRole::SCROLL_PANE )
    1548             :     {
    1549           0 :         ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > aSequence(1);
    1550           0 :         aSequence[0] = getAccessibleParent();
    1551           0 :         rRelationSet.AddRelation( ::css::accessibility::AccessibleRelation( ::css::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
    1552             :     }
    1553             :     else
    1554             :     {
    1555           0 :          VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet);
    1556             :     }
    1557           0 : }
    1558             : // virtual
    1559           0 : void SAL_CALL Document::disposing()
    1560             : {
    1561           0 :     m_aEngineListener.endListening();
    1562           0 :     m_aViewListener.endListening();
    1563           0 :     if (m_xParagraphs.get() != 0)
    1564           0 :         disposeParagraphs();
    1565           0 :     VCLXAccessibleComponent::disposing();
    1566           0 : }
    1567             : 
    1568             : // virtual
    1569           0 : void Document::Notify(::SfxBroadcaster &, ::SfxHint const & rHint)
    1570             : {
    1571           0 :     if (rHint.ISA(::TextHint))
    1572             :     {
    1573             :         ::TextHint const & rTextHint
    1574           0 :               = static_cast< ::TextHint const & >(rHint);
    1575           0 :         switch (rTextHint.GetId())
    1576             :         {
    1577             :         case TEXT_HINT_PARAINSERTED:
    1578             :         case TEXT_HINT_PARAREMOVED:
    1579             :             // TEXT_HINT_PARAINSERTED and TEXT_HINT_PARAREMOVED are sent at
    1580             :             // "unsafe" times (when the text engine has not yet re-formatted its
    1581             :             // content), so that for example calling ::TextEngine::GetTextHeight
    1582             :             // from within the code that handles TEXT_HINT_PARAINSERTED causes
    1583             :             // trouble within the text engine.  Therefore, these hints are just
    1584             :             // buffered until a following ::TextEngine::FormatDoc causes a
    1585             :             // TEXT_HINT_TEXTFORMATTED to come in:
    1586             :         case TEXT_HINT_FORMATPARA:
    1587             :             // ::TextEngine::FormatDoc sends a sequence of
    1588             :             // TEXT_HINT_FORMATPARAs, followed by an optional
    1589             :             // TEXT_HINT_TEXTHEIGHTCHANGED, followed in all cases by one
    1590             :             // TEXT_HINT_TEXTFORMATTED.  Only the TEXT_HINT_FORMATPARAs contain
    1591             :             // the numbers of the affected paragraphs, but they are sent
    1592             :             // before the changes are applied.  Therefore, TEXT_HINT_FORMATPARAs
    1593             :             // are just buffered until another hint comes in:
    1594             :             {
    1595           0 :                 ::osl::MutexGuard aInternalGuard(GetMutex());
    1596           0 :                 if (!isAlive())
    1597           0 :                     break;
    1598             : 
    1599           0 :                 m_aParagraphNotifications.push(rTextHint);
    1600           0 :                 break;
    1601             :             }
    1602             :         case TEXT_HINT_TEXTFORMATTED:
    1603             :         case TEXT_HINT_TEXTHEIGHTCHANGED:
    1604             :         case TEXT_HINT_MODIFIED:
    1605             :             {
    1606           0 :                 ::osl::MutexGuard aInternalGuard(GetMutex());
    1607           0 :                 if (!isAlive())
    1608           0 :                     break;
    1609           0 :                 handleParagraphNotifications();
    1610           0 :                 break;
    1611             :             }
    1612             :         case TEXT_HINT_VIEWSCROLLED:
    1613             :             {
    1614           0 :                 ::osl::MutexGuard aInternalGuard(GetMutex());
    1615           0 :                 if (!isAlive())
    1616           0 :                     break;
    1617           0 :                 handleParagraphNotifications();
    1618             : 
    1619             :                 ::sal_Int32 nOffset = static_cast< ::sal_Int32 >(
    1620           0 :                     m_rView.GetStartDocPos().Y());
    1621             :                     // XXX  numeric overflow
    1622           0 :                 if (nOffset != m_nViewOffset)
    1623             :                 {
    1624           0 :                     m_nViewOffset = nOffset;
    1625             : 
    1626             :                     Paragraphs::iterator aOldVisibleBegin(
    1627           0 :                         m_aVisibleBegin);
    1628           0 :                     Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd);
    1629             : 
    1630           0 :                     determineVisibleRange();
    1631             : 
    1632             :                     notifyVisibleRangeChanges(aOldVisibleBegin,
    1633             :                                                 aOldVisibleEnd,
    1634           0 :                                                 m_xParagraphs->end());
    1635             :                 }
    1636           0 :                 break;
    1637             :             }
    1638             :         case TEXT_HINT_VIEWSELECTIONCHANGED:
    1639             :         case TEXT_HINT_VIEWCARETCHANGED:
    1640             :             {
    1641           0 :                 ::osl::MutexGuard aInternalGuard(GetMutex());
    1642           0 :                 if (!isAlive())
    1643           0 :                     break;
    1644             : 
    1645           0 :                 if (m_aParagraphNotifications.empty())
    1646             :                 {
    1647           0 :                     handleSelectionChangeNotification();
    1648             :                 }
    1649             :                 else
    1650             :                 {
    1651             :                     // TEXT_HINT_VIEWSELECTIONCHANGED is sometimes sent at
    1652             :                     // "unsafe" times (when the text engine has not yet re-
    1653             :                     // formatted its content), so that for example calling
    1654             :                     // ::TextEngine::GetTextHeight from within the code that
    1655             :                     // handles a previous TEXT_HINT_PARAINSERTED causes
    1656             :                     // trouble within the text engine.  Therefore, these
    1657             :                     // hints are just buffered (along with
    1658             :                     // TEXT_HINT_PARAINSERTED/REMOVED/FORMATPARA) until a
    1659             :                     // following ::TextEngine::FormatDoc causes a
    1660             :                     // TEXT_HINT_TEXTFORMATTED to come in:
    1661           0 :                     m_bSelectionChangedNotification = true;
    1662             :                 }
    1663           0 :                 break;
    1664             :             }
    1665             :         }
    1666             :     }
    1667           0 : }
    1668             : 
    1669           0 : IMPL_LINK(Document, WindowEventHandler, ::VclSimpleEvent *, pEvent)
    1670             : {
    1671           0 :     switch (pEvent->GetId())
    1672             :     {
    1673             :     case VCLEVENT_WINDOW_RESIZE:
    1674             :         {
    1675           0 :             ::osl::MutexGuard aInternalGuard(GetMutex());
    1676           0 :             if (!isAlive())
    1677           0 :                 break;
    1678             : 
    1679             :             ::sal_Int32 nHeight = static_cast< ::sal_Int32 >(
    1680           0 :                 m_rView.GetWindow()->GetOutputSizePixel().Height());
    1681             :                 // XXX  numeric overflow
    1682           0 :             if (nHeight != m_nViewHeight)
    1683             :             {
    1684           0 :                 m_nViewHeight = nHeight;
    1685             : 
    1686           0 :                 Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin);
    1687           0 :                 Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd);
    1688             : 
    1689           0 :                 determineVisibleRange();
    1690             : 
    1691             :                 notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd,
    1692           0 :                                             m_xParagraphs->end());
    1693             :             }
    1694           0 :             break;
    1695             :         }
    1696             :     case VCLEVENT_WINDOW_GETFOCUS:
    1697             :         {
    1698           0 :             ::osl::MutexGuard aInternalGuard(GetMutex());
    1699           0 :             if (!isAlive())
    1700           0 :                 break;
    1701             :             //to enable the PARAGRAPH to get focus for multiline edit
    1702           0 :             ::sal_Int32 count = getAccessibleChildCount();
    1703           0 :             sal_Bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1;
    1704           0 :             if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty)
    1705             :             {
    1706           0 :                 Paragraphs::iterator m_aTemp = bEmpty ? m_aVisibleBegin : m_aFocused;
    1707           0 :                 ::rtl::Reference< Paragraph > xParagraph(getParagraph(m_aTemp));
    1708           0 :                 if (xParagraph.is())
    1709             :                 {
    1710             :                     xParagraph->notifyEvent(
    1711             :                         ::css::accessibility::AccessibleEventId::
    1712             :                         STATE_CHANGED,
    1713             :                         ::css::uno::Any(),
    1714             :                         ::css::uno::makeAny(
    1715             :                             ::css::accessibility::AccessibleStateType::
    1716           0 :                             FOCUSED));
    1717           0 :                 }
    1718             :             }
    1719             :             /*
    1720             :                 ::rtl::Reference< Paragraph > xParagraph(
    1721             :                     getParagraph(m_aFocused));
    1722             :                 if (xParagraph.is())
    1723             :                     xParagraph->notifyEvent(
    1724             :                         css::accessibility::AccessibleEventId::
    1725             :                         STATE_CHANGED,
    1726             :                         css::uno::Any(),
    1727             :                         css::uno::makeAny(
    1728             :                             css::accessibility::AccessibleStateType::
    1729             :                             FOCUSED));
    1730             :             */
    1731           0 :             break;
    1732             :         }
    1733             :     case VCLEVENT_WINDOW_LOSEFOCUS:
    1734             :         {
    1735           0 :             ::osl::MutexGuard aInternalGuard(GetMutex());
    1736           0 :             if (!isAlive())
    1737           0 :                 break;
    1738             :             //to enable the PARAGRAPH to get focus for multiline edit
    1739           0 :             ::sal_Int32 count = getAccessibleChildCount();
    1740           0 :             sal_Bool bEmpty = m_aFocused == m_aVisibleEnd && count == 1;
    1741           0 :             if ((m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) || bEmpty)
    1742             :             {
    1743           0 :                 Paragraphs::iterator m_aTemp = bEmpty ? m_aVisibleBegin : m_aFocused;
    1744           0 :                 ::rtl::Reference< Paragraph > xParagraph(getParagraph(m_aTemp));
    1745           0 :                 if (xParagraph.is())
    1746             :                     xParagraph->notifyEvent(
    1747             :                         ::css::accessibility::AccessibleEventId::
    1748             :                         STATE_CHANGED,
    1749             :                         ::css::uno::makeAny(
    1750             :                             ::css::accessibility::AccessibleStateType::
    1751             :                             FOCUSED),
    1752           0 :                         ::css::uno::Any());
    1753             :             }
    1754             : 
    1755             :             /*
    1756             :             if (m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd)
    1757             :             {
    1758             :                 ::rtl::Reference< Paragraph > xParagraph(
    1759             :                     getParagraph(m_aFocused));
    1760             :                 if (xParagraph.is())
    1761             :                     xParagraph->notifyEvent(
    1762             :                         css::accessibility::AccessibleEventId::
    1763             :                         STATE_CHANGED,
    1764             :                         css::uno::makeAny(
    1765             :                             css::accessibility::AccessibleStateType::
    1766             :                             FOCUSED),
    1767             :                         css::uno::Any());
    1768             :             }
    1769             :             */
    1770           0 :             break;
    1771             :         }
    1772             :     }
    1773           0 :     return 0;
    1774             : }
    1775             : 
    1776           0 : void Document::init()
    1777             : {
    1778           0 :     if (m_xParagraphs.get() == 0)
    1779             :     {
    1780           0 :         ::sal_uLong nCount = m_rEngine.GetParagraphCount();
    1781           0 :         m_xParagraphs.reset(new Paragraphs);
    1782           0 :         m_xParagraphs->reserve(static_cast< Paragraphs::size_type >(nCount));
    1783             :             // numeric overflow is harmless here
    1784           0 :         for (::sal_uLong i = 0; i < nCount; ++i)
    1785             :             m_xParagraphs->push_back(ParagraphInfo(static_cast< ::sal_Int32 >(
    1786           0 :                                            m_rEngine.GetTextHeight(i))));
    1787             :                 // XXX  numeric overflow
    1788             :         m_nViewOffset = static_cast< ::sal_Int32 >(
    1789           0 :             m_rView.GetStartDocPos().Y()); // XXX  numeric overflow
    1790             :         m_nViewHeight = static_cast< ::sal_Int32 >(
    1791           0 :             m_rView.GetWindow()->GetOutputSizePixel().Height());
    1792             :             // XXX  numeric overflow
    1793           0 :         determineVisibleRange();
    1794           0 :         m_nSelectionFirstPara = -1;
    1795           0 :         m_nSelectionFirstPos = -1;
    1796           0 :         m_nSelectionLastPara = -1;
    1797           0 :         m_nSelectionLastPos = -1;
    1798           0 :         m_aFocused = m_xParagraphs->end();
    1799           0 :         m_bSelectionChangedNotification = false;
    1800           0 :         m_aEngineListener.startListening(m_rEngine);
    1801           0 :         m_aViewListener.startListening(*m_rView.GetWindow());
    1802             :     }
    1803           0 : }
    1804             : 
    1805             : ::rtl::Reference< Paragraph >
    1806           0 : Document::getParagraph(Paragraphs::iterator const & rIt)
    1807             : {
    1808             :     return static_cast< Paragraph * >(
    1809             :         css::uno::Reference< css::accessibility::XAccessible >(
    1810           0 :             rIt->getParagraph()).get());
    1811             : }
    1812             : 
    1813             : css::uno::Reference< css::accessibility::XAccessible >
    1814           0 : Document::getAccessibleChild(Paragraphs::iterator const & rIt)
    1815             : {
    1816             :     css::uno::Reference< css::accessibility::XAccessible > xParagraph(
    1817           0 :         rIt->getParagraph());
    1818           0 :     if (!xParagraph.is())
    1819             :     {
    1820           0 :         xParagraph = new Paragraph(this, rIt - m_xParagraphs->begin());
    1821           0 :         rIt->setParagraph(xParagraph);
    1822             :     }
    1823           0 :     return xParagraph;
    1824             : }
    1825             : 
    1826           0 : void Document::determineVisibleRange()
    1827             : {
    1828           0 :     Paragraphs::iterator const aEnd = m_xParagraphs->end();
    1829             : 
    1830           0 :     m_aVisibleBegin = aEnd;
    1831           0 :     m_aVisibleEnd = aEnd;
    1832           0 :     m_nVisibleBeginOffset = 0;
    1833             : 
    1834           0 :     ::sal_Int32 nPos = 0;
    1835           0 :     for (Paragraphs::iterator aIt = m_xParagraphs->begin(); m_aVisibleEnd == aEnd && aIt != aEnd; ++aIt)
    1836             :     {
    1837           0 :         ::sal_Int32 const nOldPos = nPos;
    1838           0 :         nPos += aIt->getHeight(); // XXX  numeric overflow
    1839           0 :         if (m_aVisibleBegin == aEnd)
    1840             :         {
    1841           0 :             if (nPos >= m_nViewOffset)
    1842             :             {
    1843           0 :                 m_aVisibleBegin = aIt;
    1844           0 :                 m_nVisibleBeginOffset = m_nViewOffset - nOldPos;
    1845             :             }
    1846             :         }
    1847             :         else
    1848             :         {
    1849           0 :             if (nPos >= m_nViewOffset + m_nViewHeight) // XXX  numeric overflow
    1850             :             {
    1851           0 :                 m_aVisibleEnd = aIt;
    1852             :             }
    1853             :         }
    1854             :     }
    1855             : 
    1856             :     SAL_WARN_IF(
    1857             :             !((m_aVisibleBegin == m_xParagraphs->end() && m_aVisibleEnd == m_xParagraphs->end() && m_nVisibleBeginOffset == 0)
    1858             :                 || (m_aVisibleBegin < m_aVisibleEnd && m_nVisibleBeginOffset >= 0)),
    1859             :             "accessibility",
    1860             :             "invalid visible range");
    1861           0 : }
    1862             : 
    1863           0 : void Document::notifyVisibleRangeChanges(
    1864             :     Paragraphs::iterator const & rOldVisibleBegin,
    1865             :     Paragraphs::iterator const & rOldVisibleEnd,
    1866             :     Paragraphs::iterator const & rInserted)
    1867             : {
    1868             :     // XXX  Replace this code that determines which paragraphs have changed from
    1869             :     // invisible to visible or vice versa with a better algorithm.
    1870           0 :     for (Paragraphs::iterator aIt(rOldVisibleBegin); aIt != rOldVisibleEnd;
    1871             :          ++aIt)
    1872             :     {
    1873           0 :         if (aIt != rInserted
    1874           0 :             && (aIt < m_aVisibleBegin || aIt >= m_aVisibleEnd))
    1875             :             NotifyAccessibleEvent(
    1876             :                 css::accessibility::AccessibleEventId::
    1877             :                 CHILD,
    1878             :                 css::uno::makeAny(getAccessibleChild(aIt)),
    1879           0 :                 css::uno::Any());
    1880             :     }
    1881           0 :     for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd;
    1882             :          ++aIt)
    1883             :     {
    1884           0 :         if (aIt == rInserted
    1885           0 :             || aIt < rOldVisibleBegin || aIt >= rOldVisibleEnd)
    1886             :             NotifyAccessibleEvent(
    1887             :                 css::accessibility::AccessibleEventId::
    1888             :                 CHILD,
    1889             :                 css::uno::Any(),
    1890           0 :                 css::uno::makeAny(getAccessibleChild(aIt)));
    1891             :     }
    1892           0 : }
    1893             : 
    1894             : void
    1895           0 : Document::changeParagraphText(::sal_uLong nNumber, ::sal_uInt16 nBegin, ::sal_uInt16 nEnd,
    1896             :                               bool bCut, bool bPaste,
    1897             :                               OUString const & rText)
    1898             : {
    1899             :     m_rView.SetSelection(::TextSelection(::TextPaM(nNumber, nBegin),
    1900           0 :                                          ::TextPaM(nNumber, nEnd)));
    1901           0 :     if (bCut)
    1902           0 :         m_rView.Cut();
    1903           0 :     else if (nBegin != nEnd)
    1904           0 :         m_rView.DeleteSelected();
    1905           0 :     if (bPaste)
    1906           0 :         m_rView.Paste();
    1907           0 :     else if (!rText.isEmpty())
    1908           0 :         m_rView.InsertText(rText);
    1909           0 : }
    1910             : 
    1911           0 : void Document::handleParagraphNotifications()
    1912             : {
    1913           0 :     while (!m_aParagraphNotifications.empty())
    1914             :     {
    1915           0 :         ::TextHint aHint(m_aParagraphNotifications.front());
    1916           0 :         m_aParagraphNotifications.pop();
    1917           0 :         switch (aHint.GetId())
    1918             :         {
    1919             :         case TEXT_HINT_PARAINSERTED:
    1920             :             {
    1921           0 :                 ::sal_uLong n = aHint.GetValue();
    1922             :                 OSL_ENSURE(n <= m_xParagraphs->size(),
    1923             :                            "bad TEXT_HINT_PARAINSERTED event");
    1924             : 
    1925             :                 // Save the values of old iterators (the iterators themselves
    1926             :                 // will get invalidated), and adjust the old values so that they
    1927             :                 // reflect the insertion of the new paragraph:
    1928             :                 Paragraphs::size_type nOldVisibleBegin
    1929           0 :                     = m_aVisibleBegin - m_xParagraphs->begin();
    1930             :                 Paragraphs::size_type nOldVisibleEnd
    1931           0 :                     = m_aVisibleEnd - m_xParagraphs->begin();
    1932             :                 Paragraphs::size_type nOldFocused
    1933           0 :                     = m_aFocused - m_xParagraphs->begin();
    1934           0 :                 if (n <= nOldVisibleBegin)
    1935           0 :                     ++nOldVisibleBegin; // XXX  numeric overflow
    1936           0 :                 if (n <= nOldVisibleEnd)
    1937           0 :                     ++nOldVisibleEnd; // XXX  numeric overflow
    1938           0 :                 if (n <= nOldFocused)
    1939           0 :                     ++nOldFocused; // XXX  numeric overflow
    1940           0 :                 if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionFirstPara)
    1941           0 :                     ++m_nSelectionFirstPara; // XXX  numeric overflow
    1942           0 :                 if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionLastPara)
    1943           0 :                     ++m_nSelectionLastPara; // XXX  numeric overflow
    1944             : 
    1945             :                 Paragraphs::iterator aIns(
    1946             :                     m_xParagraphs->insert(
    1947           0 :                         m_xParagraphs->begin() + n,
    1948             :                         ParagraphInfo(static_cast< ::sal_Int32 >(
    1949           0 :                                           m_rEngine.GetTextHeight(n)))));
    1950             :                     // XXX  numeric overflow (2x)
    1951             : 
    1952           0 :                 determineVisibleRange();
    1953           0 :                 m_aFocused = m_xParagraphs->begin() + nOldFocused;
    1954             : 
    1955           0 :                 for (Paragraphs::iterator aIt(aIns);;)
    1956             :                 {
    1957           0 :                     ++aIt;
    1958           0 :                     if (aIt == m_xParagraphs->end())
    1959           0 :                         break;
    1960             :                     ::rtl::Reference< Paragraph > xParagraph(
    1961           0 :                         getParagraph(aIt));
    1962           0 :                     if (xParagraph.is())
    1963           0 :                         xParagraph->numberChanged(true);
    1964           0 :                 }
    1965             : 
    1966             :                 notifyVisibleRangeChanges(
    1967           0 :                     m_xParagraphs->begin() + nOldVisibleBegin,
    1968           0 :                     m_xParagraphs->begin() + nOldVisibleEnd, aIns);
    1969           0 :                 break;
    1970             :             }
    1971             :         case TEXT_HINT_PARAREMOVED:
    1972             :             {
    1973           0 :                 ::sal_uLong n = aHint.GetValue();
    1974           0 :                 if (n == TEXT_PARA_ALL)
    1975             :                 {
    1976           0 :                     for (Paragraphs::iterator aIt(m_aVisibleBegin);
    1977           0 :                          aIt != m_aVisibleEnd; ++aIt)
    1978             :                     {
    1979             :                         NotifyAccessibleEvent(
    1980             :                             css::accessibility::AccessibleEventId::
    1981             :                             CHILD,
    1982             :                             css::uno::makeAny(getAccessibleChild(aIt)),
    1983           0 :                             css::uno::Any());
    1984             :                     }
    1985           0 :                     disposeParagraphs();
    1986           0 :                     m_xParagraphs->clear();
    1987           0 :                     determineVisibleRange();
    1988           0 :                     m_nSelectionFirstPara = -1;
    1989           0 :                     m_nSelectionFirstPos = -1;
    1990           0 :                     m_nSelectionLastPara = -1;
    1991           0 :                     m_nSelectionLastPos = -1;
    1992           0 :                     m_aFocused = m_xParagraphs->end();
    1993             :                 }
    1994             :                 else
    1995             :                 {
    1996             :                     OSL_ENSURE(n < m_xParagraphs->size(),
    1997             :                                "Bad TEXT_HINT_PARAREMOVED event");
    1998             : 
    1999           0 :                     Paragraphs::iterator aIt(m_xParagraphs->begin() + n);
    2000             :                         // numeric overflow cannot occur
    2001             : 
    2002             :                     // Save the values of old iterators (the iterators
    2003             :                     // themselves will get invalidated), and adjust the old
    2004             :                     // values so that they reflect the removal of the paragraph:
    2005             :                     Paragraphs::size_type nOldVisibleBegin
    2006           0 :                         = m_aVisibleBegin - m_xParagraphs->begin();
    2007             :                     Paragraphs::size_type nOldVisibleEnd
    2008           0 :                         = m_aVisibleEnd - m_xParagraphs->begin();
    2009             :                     bool bWasVisible
    2010           0 :                         = nOldVisibleBegin <= n && n < nOldVisibleEnd;
    2011             :                     Paragraphs::size_type nOldFocused
    2012           0 :                         = m_aFocused - m_xParagraphs->begin();
    2013           0 :                     bool bWasFocused = aIt == m_aFocused;
    2014           0 :                     if (n < nOldVisibleBegin)
    2015           0 :                         --nOldVisibleBegin;
    2016           0 :                     if (n < nOldVisibleEnd)
    2017           0 :                         --nOldVisibleEnd;
    2018           0 :                     if (n < nOldFocused)
    2019           0 :                         --nOldFocused;
    2020           0 :                     if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionFirstPara)
    2021           0 :                         --m_nSelectionFirstPara;
    2022           0 :                     else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionFirstPara)
    2023             :                     {
    2024           0 :                         if (m_nSelectionFirstPara == m_nSelectionLastPara)
    2025             :                         {
    2026           0 :                             m_nSelectionFirstPara = -1;
    2027           0 :                             m_nSelectionFirstPos = -1;
    2028           0 :                             m_nSelectionLastPara = -1;
    2029           0 :                             m_nSelectionLastPos = -1;
    2030             :                         }
    2031             :                         else
    2032             :                         {
    2033           0 :                             ++m_nSelectionFirstPara;
    2034           0 :                             m_nSelectionFirstPos = 0;
    2035             :                         }
    2036             :                     }
    2037           0 :                     if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionLastPara)
    2038           0 :                         --m_nSelectionLastPara;
    2039           0 :                     else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionLastPara)
    2040             :                     {
    2041             :                         OSL_ENSURE(m_nSelectionFirstPara < m_nSelectionLastPara,
    2042             :                                    "logic error");
    2043           0 :                         --m_nSelectionLastPara;
    2044           0 :                         m_nSelectionLastPos = 0x7FFFFFFF;
    2045             :                     }
    2046             : 
    2047             :                     css::uno::Reference< css::accessibility::XAccessible >
    2048           0 :                           xStrong;
    2049           0 :                     if (bWasVisible)
    2050           0 :                         xStrong = getAccessibleChild(aIt);
    2051             :                     css::uno::WeakReference<
    2052             :                           css::accessibility::XAccessible > xWeak(
    2053           0 :                               aIt->getParagraph());
    2054           0 :                     aIt = m_xParagraphs->erase(aIt);
    2055             : 
    2056           0 :                     determineVisibleRange();
    2057           0 :                     m_aFocused = bWasFocused ? m_xParagraphs->end()
    2058           0 :                         : m_xParagraphs->begin() + nOldFocused;
    2059             : 
    2060           0 :                     for (; aIt != m_xParagraphs->end(); ++aIt)
    2061             :                     {
    2062             :                         ::rtl::Reference< Paragraph > xParagraph(
    2063           0 :                             getParagraph(aIt));
    2064           0 :                         if (xParagraph.is())
    2065           0 :                             xParagraph->numberChanged(false);
    2066           0 :                     }
    2067             : 
    2068           0 :                     if (bWasVisible)
    2069             :                         NotifyAccessibleEvent(
    2070             :                             css::accessibility::AccessibleEventId::
    2071             :                             CHILD,
    2072             :                             css::uno::makeAny(xStrong),
    2073           0 :                             css::uno::Any());
    2074             : 
    2075             :                     css::uno::Reference< css::lang::XComponent > xComponent(
    2076           0 :                         xWeak.get(), css::uno::UNO_QUERY);
    2077           0 :                     if (xComponent.is())
    2078           0 :                         xComponent->dispose();
    2079             : 
    2080             :                     notifyVisibleRangeChanges(
    2081           0 :                         m_xParagraphs->begin() + nOldVisibleBegin,
    2082           0 :                         m_xParagraphs->begin() + nOldVisibleEnd,
    2083           0 :                         m_xParagraphs->end());
    2084             :                 }
    2085           0 :                 break;
    2086             :             }
    2087             :         case TEXT_HINT_FORMATPARA:
    2088             :             {
    2089           0 :                 ::sal_uLong n = aHint.GetValue();
    2090             :                 OSL_ENSURE(n < m_xParagraphs->size(),
    2091             :                            "Bad TEXT_HINT_FORMATPARA event");
    2092             : 
    2093           0 :                 (*m_xParagraphs)[static_cast< Paragraphs::size_type >(n)].
    2094             :                     changeHeight(static_cast< ::sal_Int32 >(
    2095           0 :                                      m_rEngine.GetTextHeight(n)));
    2096             :                     // XXX  numeric overflow
    2097           0 :                 Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin);
    2098           0 :                 Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd);
    2099           0 :                 determineVisibleRange();
    2100             :                 notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd,
    2101           0 :                                           m_xParagraphs->end());
    2102             : 
    2103           0 :                 if (n < m_xParagraphs->size())
    2104             :                 {
    2105           0 :                     Paragraphs::iterator aIt(m_xParagraphs->begin() + n);
    2106           0 :                     ::rtl::Reference< Paragraph > xParagraph(getParagraph(aIt));
    2107           0 :                     if (xParagraph.is())
    2108           0 :                         xParagraph->textChanged();
    2109             :                 }
    2110           0 :                 break;
    2111             :             }
    2112             :         default:
    2113             :             OSL_FAIL( "bad buffered hint");
    2114           0 :             break;
    2115             :         }
    2116           0 :     }
    2117           0 :     if (m_bSelectionChangedNotification)
    2118             :     {
    2119           0 :         m_bSelectionChangedNotification = false;
    2120           0 :         handleSelectionChangeNotification();
    2121             :     }
    2122           0 : }
    2123             : 
    2124           0 : ::sal_Int32 Document::getSelectionType(::sal_Int32 nNewFirstPara, ::sal_Int32 nNewFirstPos, ::sal_Int32 nNewLastPara, ::sal_Int32 nNewLastPos)
    2125             : {
    2126           0 :     if (m_nSelectionFirstPara == -1)
    2127           0 :         return -1;
    2128           0 :     ::sal_Int32 Osp = m_nSelectionFirstPara, Osl = m_nSelectionFirstPos, Oep = m_nSelectionLastPara, Oel = m_nSelectionLastPos;
    2129           0 :     ::sal_Int32 Nsp = nNewFirstPara, Nsl = nNewFirstPos, Nep = nNewLastPara, Nel = nNewLastPos;
    2130           0 :     TextPaM Ns(Nsp, sal_uInt16(Nsl));
    2131           0 :     TextPaM Ne(Nep, sal_uInt16(Nel));
    2132           0 :     TextPaM Os(Osp, sal_uInt16(Osl));
    2133           0 :     TextPaM Oe(Oep, sal_uInt16(Oel));
    2134             : 
    2135           0 :     if (Os == Oe && Ns == Ne)
    2136             :     {
    2137             :         //only caret moves.
    2138           0 :         return 1;
    2139             :     }
    2140           0 :     else if (Os == Oe && Ns != Ne)
    2141             :     {
    2142             :         //old has no selection but new has selection
    2143           0 :         return 2;
    2144             :     }
    2145           0 :     else if (Os != Oe && Ns == Ne)
    2146             :     {
    2147             :         //old has selection but new has no selection.
    2148           0 :         return 3;
    2149             :     }
    2150           0 :     else if (Os != Oe && Ns != Ne && Osp == Nsp && Osl == Nsl)
    2151             :     {
    2152             :         //both old and new have selections.
    2153           0 :         if (Oep == Nep )
    2154             :         {
    2155             :             //Send text_selection_change event on Nep
    2156             : 
    2157           0 :             return 4;
    2158             :         }
    2159           0 :         else if (Oep < Nep)
    2160             :         {
    2161             :             //all the following examples like 1,2->1,3 means that old start select para is 1, old end select para is 2,
    2162             :             // then press shift up, the new start select para is 1, new end select para is 3;
    2163             :             //for example, 1, 2 -> 1, 3; 4,1 -> 4, 7; 4,1 -> 4, 2; 4,4->4,5
    2164           0 :             if (Nep >= Nsp)
    2165             :             {
    2166             :                 // 1, 2 -> 1, 3; 4, 1 -> 4, 7; 4,4->4,5;
    2167           0 :                 if (Oep < Osp)
    2168             :                 {
    2169             :                     // 4,1 -> 4,7;
    2170           0 :                     return 5;
    2171             :                 }
    2172           0 :                 else if (Oep >= Osp)
    2173             :                 {
    2174             :                     // 1, 2 -> 1, 3; 4,4->4,5;
    2175           0 :                     return 6;
    2176             :                 }
    2177             :             }
    2178             :             else
    2179             :             {
    2180             :                 // 4,1 -> 4,2,
    2181           0 :                 if (Oep < Osp)
    2182             :                 {
    2183             :                     // 4,1 -> 4,2,
    2184           0 :                     return 7;
    2185             :                 }
    2186             :                 else if (Oep >= Osp)
    2187             :                 {
    2188             :                     // no such condition. Oep > Osp = Nsp > Nep
    2189             :                 }
    2190             :             }
    2191             :         }
    2192           0 :         else if (Oep > Nep)
    2193             :         {
    2194             :             // 3,2 -> 3,1; 4,7 -> 4,1; 4, 7 -> 4,6; 4,4 -> 4,3
    2195           0 :             if (Nep >= Nsp)
    2196             :             {
    2197             :                 // 4,7 -> 4,6
    2198           0 :                 if (Oep <= Osp)
    2199             :                 {
    2200             :                     //no such condition, Oep<Osp=Nsp <= Nep
    2201             :                 }
    2202           0 :                 else if (Oep > Osp)
    2203             :                 {
    2204             :                     // 4,7 ->4,6
    2205           0 :                     return 8;
    2206             :                 }
    2207             :             }
    2208             :             else
    2209             :             {
    2210             :                 // 3,2 -> 3,1, 4,7 -> 4,1; 4,4->4,3
    2211           0 :                 if (Oep <= Osp)
    2212             :                 {
    2213             :                     // 3,2 -> 3,1; 4,4->4,3
    2214           0 :                     return 9;
    2215             :                 }
    2216           0 :                 else if (Oep > Osp)
    2217             :                 {
    2218             :                     // 4,7 -> 4,1
    2219           0 :                     return 10;
    2220             :                 }
    2221             :             }
    2222             :         }
    2223             :     }
    2224           0 :     return -1;
    2225             : }
    2226             : 
    2227             : 
    2228           0 : void Document::sendEvent(::sal_Int32 start, ::sal_Int32 end, ::sal_Int16 nEventId)
    2229             : {
    2230           0 :      Paragraphs::iterator aEnd = ::std::min(m_xParagraphs->begin() + end + 1, m_aVisibleEnd);
    2231           0 :     for (Paragraphs::iterator aIt = ::std::max(m_xParagraphs->begin() + start, m_aVisibleBegin);
    2232             :          aIt < aEnd; ++aIt)
    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 :     }
    2240           0 : }
    2241             : 
    2242           0 : void Document::handleSelectionChangeNotification()
    2243             : {
    2244           0 :     ::TextSelection const & rSelection = m_rView.GetSelection();
    2245             :     OSL_ENSURE(rSelection.GetStart().GetPara() < m_xParagraphs->size()
    2246             :                && rSelection.GetEnd().GetPara() < m_xParagraphs->size(),
    2247             :                "bad TEXT_HINT_VIEWSELECTIONCHANGED event");
    2248             :     ::sal_Int32 nNewFirstPara
    2249           0 :           = static_cast< ::sal_Int32 >(rSelection.GetStart().GetPara());
    2250             :     ::sal_Int32 nNewFirstPos
    2251           0 :           = static_cast< ::sal_Int32 >(rSelection.GetStart().GetIndex());
    2252             :         // XXX  numeric overflow
    2253             :     ::sal_Int32 nNewLastPara
    2254           0 :           = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetPara());
    2255             :     ::sal_Int32 nNewLastPos
    2256           0 :           = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetIndex());
    2257             :         // XXX  numeric overflow
    2258             : 
    2259             :     // Lose focus:
    2260           0 :     Paragraphs::iterator aIt(m_xParagraphs->begin() + nNewLastPara);
    2261           0 :     if (m_aFocused != m_xParagraphs->end() && m_aFocused != aIt
    2262           0 :         && m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd)
    2263             :     {
    2264           0 :         ::rtl::Reference< Paragraph > xParagraph(getParagraph(m_aFocused));
    2265           0 :         if (xParagraph.is())
    2266             :             xParagraph->notifyEvent(
    2267             :                 css::accessibility::AccessibleEventId::
    2268             :                 STATE_CHANGED,
    2269             :                 css::uno::makeAny(
    2270             :                     css::accessibility::AccessibleStateType::FOCUSED),
    2271           0 :                 css::uno::Any());
    2272             :     }
    2273             : 
    2274             :     // Gain focus and update cursor position:
    2275           0 :     if (aIt >= m_aVisibleBegin && aIt < m_aVisibleEnd
    2276           0 :         && (aIt != m_aFocused
    2277           0 :             || nNewLastPara != m_nSelectionLastPara
    2278           0 :             || nNewLastPos != m_nSelectionLastPos))
    2279             :     {
    2280           0 :         ::rtl::Reference< Paragraph > xParagraph(getParagraph(aIt));
    2281           0 :         if (xParagraph.is())
    2282             :         {
    2283             :         //disable the first event when user types in empty field.
    2284           0 :         ::sal_Int32 count = getAccessibleChildCount();
    2285           0 :         sal_Bool bEmpty = count > 1;
    2286             :             //if (aIt != m_aFocused)
    2287           0 :             if (aIt != m_aFocused && bEmpty)
    2288             :                 xParagraph->notifyEvent(
    2289             :                     css::accessibility::AccessibleEventId::
    2290             :                     STATE_CHANGED,
    2291             :                     css::uno::Any(),
    2292             :                     css::uno::makeAny(
    2293           0 :                         css::accessibility::AccessibleStateType::FOCUSED));
    2294           0 :             if (nNewLastPara != m_nSelectionLastPara
    2295           0 :                 || nNewLastPos != m_nSelectionLastPos)
    2296             :                 xParagraph->notifyEvent(
    2297             :                     css::accessibility::AccessibleEventId::
    2298             :                     CARET_CHANGED,
    2299             :                     css::uno::makeAny< ::sal_Int32 >(
    2300           0 :                         nNewLastPara == m_nSelectionLastPara
    2301             :                         ? m_nSelectionLastPos : 0),
    2302           0 :                     css::uno::makeAny(nNewLastPos));
    2303           0 :         }
    2304             :     }
    2305           0 :     m_aFocused = aIt;
    2306             : 
    2307             :     ::sal_Int32 nMin;
    2308             :     ::sal_Int32 nMax;
    2309           0 :     ::sal_Int32 ret = getSelectionType(nNewFirstPara, nNewFirstPos, nNewLastPara, nNewLastPos);
    2310           0 :     switch (ret)
    2311             :     {
    2312             :         case -1:
    2313             :             {
    2314             :                 //no event
    2315             :             }
    2316           0 :             break;
    2317             :         case 1:
    2318             :             {
    2319             :                 //only caret moved, already handled in above
    2320             :             }
    2321           0 :             break;
    2322             :         case 2:
    2323             :             {
    2324             :                 //old has no selection but new has selection
    2325           0 :                 nMin = ::std::min(nNewFirstPara, nNewLastPara);
    2326           0 :                 nMax = ::std::max(nNewFirstPara, nNewLastPara);
    2327           0 :                 sendEvent(nMin, nMax,  ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2328           0 :                 sendEvent(nMin, nMax,  ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2329             :             }
    2330           0 :             break;
    2331             :         case 3:
    2332             :             {
    2333             :                 //old has selection but new has no selection.
    2334           0 :                 nMin = ::std::min(m_nSelectionFirstPara, m_nSelectionLastPara);
    2335           0 :                 nMax = ::std::max(m_nSelectionFirstPara, m_nSelectionLastPara);
    2336           0 :                 sendEvent(nMin, nMax,  ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2337           0 :                 sendEvent(nMin, nMax,  ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2338             :             }
    2339           0 :             break;
    2340             :         case 4:
    2341             :             {
    2342             :                 //Send text_selection_change event on Nep
    2343           0 :                 sendEvent(nNewLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2344             :             }
    2345           0 :             break;
    2346             :         case 5:
    2347             :             {
    2348             :                 // 4, 1 -> 4, 7
    2349           0 :                 sendEvent(m_nSelectionLastPara, m_nSelectionFirstPara-1, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2350           0 :                 sendEvent(nNewFirstPara+1, nNewLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2351             : 
    2352           0 :                 sendEvent(m_nSelectionLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2353             :             }
    2354           0 :             break;
    2355             :         case 6:
    2356             :             {
    2357             :                 // 1, 2 -> 1, 4; 4,4->4,5;
    2358           0 :                 sendEvent(m_nSelectionLastPara+1, nNewLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2359             : 
    2360           0 :                 sendEvent(m_nSelectionLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2361             :             }
    2362           0 :             break;
    2363             :         case 7:
    2364             :             {
    2365             :                 // 4,1 -> 4,3,
    2366           0 :                 sendEvent(m_nSelectionLastPara +1, nNewLastPara , ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2367             : 
    2368           0 :                 sendEvent(m_nSelectionLastPara, nNewLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2369             :             }
    2370           0 :             break;
    2371             :         case 8:
    2372             :             {
    2373             :                 // 4,7 ->4,5;
    2374           0 :                 sendEvent(nNewLastPara + 1, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2375             : 
    2376           0 :                 sendEvent(nNewLastPara, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2377             :             }
    2378           0 :             break;
    2379             :         case 9:
    2380             :             {
    2381             :                 // 3,2 -> 3,1; 4,4->4,3
    2382           0 :                 sendEvent(nNewLastPara, m_nSelectionLastPara - 1, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2383             : 
    2384           0 :                 sendEvent(nNewLastPara, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2385             :             }
    2386           0 :             break;
    2387             :         case 10:
    2388             :             {
    2389             :                 // 4,7 -> 4,1
    2390           0 :                 sendEvent(m_nSelectionFirstPara + 1, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2391           0 :                 sendEvent(nNewLastPara, nNewFirstPara - 1, ::css::accessibility::AccessibleEventId::SELECTION_CHANGED);
    2392             : 
    2393           0 :                 sendEvent(nNewLastPara, m_nSelectionLastPara, ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED);
    2394             :             }
    2395           0 :             break;
    2396             :         default:
    2397           0 :             break;
    2398             :     }
    2399             : 
    2400             :     /*
    2401             :     // Update both old and new selection.  (Regardless of how the two selections
    2402             :     // look like, there will always be two ranges to the left and right of the
    2403             :     // overlap---the overlap and/or the range to the right of it possibly being
    2404             :     // empty.  Only for these two ranges notifications have to be sent.)
    2405             : 
    2406             :     TextPaM aOldTextStart( static_cast< sal_uLong >( m_nSelectionFirstPara ), static_cast< sal_uInt16 >( m_nSelectionFirstPos ) );
    2407             :     TextPaM aOldTextEnd( static_cast< sal_uLong >( m_nSelectionLastPara ), static_cast< sal_uInt16 >( m_nSelectionLastPos ) );
    2408             :     TextPaM aNewTextStart( static_cast< sal_uLong >( nNewFirstPara ), static_cast< sal_uInt16 >( nNewFirstPos ) );
    2409             :     TextPaM aNewTextEnd( static_cast< sal_uLong >( nNewLastPara ), static_cast< sal_uInt16 >( nNewLastPos ) );
    2410             : 
    2411             :     // justify selections
    2412             :     justifySelection( aOldTextStart, aOldTextEnd );
    2413             :     justifySelection( aNewTextStart, aNewTextEnd );
    2414             : 
    2415             :     sal_Int32 nFirst1;
    2416             :     sal_Int32 nLast1;
    2417             :     sal_Int32 nFirst2;
    2418             :     sal_Int32 nLast2;
    2419             : 
    2420             :     if ( m_nSelectionFirstPara == -1 )
    2421             :     {
    2422             :         // old selection not initialized yet => notify events only for new selection (if not empty)
    2423             :         nFirst1 = aNewTextStart.GetPara();
    2424             :         nLast1 = aNewTextEnd.GetPara() + ( aNewTextStart != aNewTextEnd ? 1 : 0 );
    2425             :         nFirst2 = 0;
    2426             :         nLast2 = 0;
    2427             :     }
    2428             :     else if ( aOldTextStart == aOldTextEnd && aNewTextStart == aNewTextEnd )
    2429             :     {
    2430             :         // old and new selection empty => no events
    2431             :         nFirst1 = 0;
    2432             :         nLast1 = 0;
    2433             :         nFirst2 = 0;
    2434             :         nLast2 = 0;
    2435             :     }
    2436             :     else if ( aOldTextStart != aOldTextEnd && aNewTextStart == aNewTextEnd )
    2437             :     {
    2438             :         // old selection not empty + new selection empty => notify events only for old selection
    2439             :         nFirst1 = aOldTextStart.GetPara();
    2440             :         nLast1 = aOldTextEnd.GetPara() + 1;
    2441             :         nFirst2 = 0;
    2442             :         nLast2 = 0;
    2443             :     }
    2444             :     else if ( aOldTextStart == aOldTextEnd && aNewTextStart != aNewTextEnd )
    2445             :     {
    2446             :         // old selection empty + new selection not empty => notify events only for new selection
    2447             :         nFirst1 = aNewTextStart.GetPara();
    2448             :         nLast1 = aNewTextEnd.GetPara() + 1;
    2449             :         nFirst2 = 0;
    2450             :         nLast2 = 0;
    2451             :     }
    2452             :     else
    2453             :     {
    2454             :         // old and new selection not empty => notify events for the two ranges left and right of the overlap
    2455             :         ::std::vector< TextPaM > aTextPaMs(4);
    2456             :         aTextPaMs[0] = aOldTextStart;
    2457             :         aTextPaMs[1] = aOldTextEnd;
    2458             :         aTextPaMs[2] = aNewTextStart;
    2459             :         aTextPaMs[3] = aNewTextEnd;
    2460             :         ::std::sort( aTextPaMs.begin(), aTextPaMs.end() );
    2461             : 
    2462             :         nFirst1 = aTextPaMs[0].GetPara();
    2463             :         nLast1 = aTextPaMs[1].GetPara() + ( aTextPaMs[0] != aTextPaMs[1] ? 1 : 0 );
    2464             : 
    2465             :         nFirst2 = aTextPaMs[2].GetPara();
    2466             :         nLast2 = aTextPaMs[3].GetPara() + ( aTextPaMs[2] != aTextPaMs[3] ? 1 : 0 );
    2467             : 
    2468             :         // adjust overlapping ranges
    2469             :         if ( nLast1 > nFirst2 )
    2470             :             nLast1 = nFirst2;
    2471             :     }
    2472             : 
    2473             :     // notify selection changes
    2474             :     notifySelectionChange( nFirst1, nLast1 );
    2475             :     notifySelectionChange( nFirst2, nLast2 );
    2476             :     */
    2477           0 :     m_nSelectionFirstPara = nNewFirstPara;
    2478           0 :     m_nSelectionFirstPos = nNewFirstPos;
    2479           0 :     m_nSelectionLastPara = nNewLastPara;
    2480           0 :     m_nSelectionLastPos = nNewLastPos;
    2481           0 : }
    2482             : 
    2483           0 : void Document::disposeParagraphs()
    2484             : {
    2485           0 :     for (Paragraphs::iterator aIt(m_xParagraphs->begin());
    2486           0 :          aIt != m_xParagraphs->end(); ++aIt)
    2487             :     {
    2488             :         css::uno::Reference< css::lang::XComponent > xComponent(
    2489           0 :             aIt->getParagraph().get(), css::uno::UNO_QUERY);
    2490           0 :         if (xComponent.is())
    2491           0 :             xComponent->dispose();
    2492           0 :     }
    2493           0 : }
    2494             : 
    2495             : // static
    2496           0 : css::uno::Any Document::mapFontColor(::Color const & rColor)
    2497             : {
    2498             :     return css::uno::makeAny(
    2499           0 :         static_cast< ::sal_Int32 >(COLORDATA_RGB(rColor.GetColor())));
    2500             :         // FIXME  keep transparency?
    2501             : }
    2502             : 
    2503             : // static
    2504           0 : ::Color Document::mapFontColor(css::uno::Any const & rColor)
    2505             : {
    2506           0 :     ::sal_Int32 nColor = 0;
    2507           0 :     rColor >>= nColor;
    2508           0 :     return ::Color(static_cast< ::ColorData >(nColor));
    2509             : }
    2510             : 
    2511             : // static
    2512           0 : css::uno::Any Document::mapFontWeight(::FontWeight nWeight)
    2513             : {
    2514             :     // Map from ::FontWeight to css::awt::FontWeight, depends on order of
    2515             :     // elements in ::FontWeight (vcl/vclenum.hxx):
    2516             :     static float const aWeight[]
    2517             :         = { css::awt::FontWeight::DONTKNOW, // WEIGHT_DONTKNOW
    2518             :             css::awt::FontWeight::THIN, // WEIGHT_THIN
    2519             :             css::awt::FontWeight::ULTRALIGHT, // WEIGHT_ULTRALIGHT
    2520             :             css::awt::FontWeight::LIGHT, // WEIGHT_LIGHT
    2521             :             css::awt::FontWeight::SEMILIGHT, // WEIGHT_SEMILIGHT
    2522             :             css::awt::FontWeight::NORMAL, // WEIGHT_NORMAL
    2523             :             css::awt::FontWeight::NORMAL, // WEIGHT_MEDIUM
    2524             :             css::awt::FontWeight::SEMIBOLD, // WEIGHT_SEMIBOLD
    2525             :             css::awt::FontWeight::BOLD, // WEIGHT_BOLD
    2526             :             css::awt::FontWeight::ULTRABOLD, // WEIGHT_ULTRABOLD
    2527             :             css::awt::FontWeight::BLACK }; // WEIGHT_BLACK
    2528           0 :     return css::uno::makeAny(aWeight[nWeight]);
    2529             : }
    2530             : 
    2531             : // static
    2532           0 : ::FontWeight Document::mapFontWeight(css::uno::Any const & rWeight)
    2533             : {
    2534           0 :     float nWeight = css::awt::FontWeight::NORMAL;
    2535           0 :     rWeight >>= nWeight;
    2536           0 :     return nWeight <= css::awt::FontWeight::DONTKNOW ? WEIGHT_DONTKNOW
    2537           0 :         : nWeight <= css::awt::FontWeight::THIN ? WEIGHT_THIN
    2538           0 :         : nWeight <= css::awt::FontWeight::ULTRALIGHT ? WEIGHT_ULTRALIGHT
    2539           0 :         : nWeight <= css::awt::FontWeight::LIGHT ? WEIGHT_LIGHT
    2540           0 :         : nWeight <= css::awt::FontWeight::SEMILIGHT ? WEIGHT_SEMILIGHT
    2541           0 :         : nWeight <= css::awt::FontWeight::NORMAL ? WEIGHT_NORMAL
    2542           0 :         : nWeight <= css::awt::FontWeight::SEMIBOLD ? WEIGHT_SEMIBOLD
    2543           0 :         : nWeight <= css::awt::FontWeight::BOLD ? WEIGHT_BOLD
    2544           0 :         : nWeight <= css::awt::FontWeight::ULTRABOLD ? WEIGHT_ULTRABOLD
    2545           0 :         : WEIGHT_BLACK;
    2546             : }
    2547             : 
    2548             : }
    2549             : 
    2550             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10