diff options
Diffstat (limited to 'accessibility/source/extended/textwindowaccessibility.cxx')
-rw-r--r-- | accessibility/source/extended/textwindowaccessibility.cxx | 2258 |
1 files changed, 0 insertions, 2258 deletions
diff --git a/accessibility/source/extended/textwindowaccessibility.cxx b/accessibility/source/extended/textwindowaccessibility.cxx deleted file mode 100644 index b605ed740..000000000 --- a/accessibility/source/extended/textwindowaccessibility.cxx +++ /dev/null @@ -1,2258 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_accessibility.hxx" - -#include <accessibility/extended/textwindowaccessibility.hxx> -#include "comphelper/accessibleeventnotifier.hxx" -#include "unotools/accessiblerelationsethelper.hxx" -#include <unotools/accessiblestatesethelper.hxx> -#include <vcl/window.hxx> -#include <toolkit/helper/convert.hxx> - -#include <algorithm> -#include <vector> -#include <boost/unordered_map.hpp> - -namespace css = ::com::sun::star; - -namespace accessibility -{ - -// Both ::osl::Mutex and ParagraphBase implement acquire and release, and thus -// ::rtl::Reference< Paragraph > does not work. So ParagraphImpl was factored -// out and ::rtl::Reference< ParagraphImpl > is used instead. -class Paragraph: private ::osl::Mutex, public ParagraphImpl -{ -public: - inline Paragraph(::rtl::Reference< Document > const & rDocument, - Paragraphs::size_type nNumber): - ParagraphImpl(rDocument, nNumber, *this) {} -}; - -void SfxListenerGuard::startListening(::SfxBroadcaster & rNotifier) -{ - OSL_ENSURE(m_pNotifier == 0, "called more than once"); - m_pNotifier = &rNotifier; - m_rListener.StartListening(*m_pNotifier, true); -} - -void SfxListenerGuard::endListening() -{ - if (m_pNotifier != 0) - { - m_rListener.EndListening(*m_pNotifier); - m_pNotifier = 0; - } -} - -void WindowListenerGuard::startListening(::Window & rNotifier) -{ - OSL_ENSURE(m_pNotifier == 0, "called more than once"); - m_pNotifier = &rNotifier; - m_pNotifier->AddEventListener(m_aListener); -} - -void WindowListenerGuard::endListening() -{ - if (m_pNotifier != 0) - { - m_pNotifier->RemoveEventListener(m_aListener); - m_pNotifier = 0; - } -} - -ParagraphImpl::ParagraphImpl(::rtl::Reference< Document > const & rDocument, - Paragraphs::size_type nNumber, - ::osl::Mutex & rMutex): - ParagraphBase(rMutex), - m_xDocument(rDocument), - m_nNumber(nNumber), - m_nClientId(0) -{ - m_aParagraphText = m_xDocument->retrieveParagraphText(this); -} - -void -ParagraphImpl::numberChanged(bool bIncremented) -{ - if (bIncremented) - ++m_nNumber; - else - --m_nNumber; -} - -void ParagraphImpl::textChanged() -{ - ::rtl::OUString aParagraphText = implGetText(); - ::css::uno::Any aOldValue, aNewValue; - if ( implInitTextChangedEvent( m_aParagraphText, aParagraphText, aOldValue, aNewValue ) ) - { - m_aParagraphText = aParagraphText; - notifyEvent(::css::accessibility::AccessibleEventId:: - TEXT_CHANGED, - aOldValue, aNewValue); - } -} - -void ParagraphImpl::notifyEvent(::sal_Int16 nEventId, - ::css::uno::Any const & rOldValue, - ::css::uno::Any const & rNewValue) -{ - if (m_nClientId) - comphelper::AccessibleEventNotifier::addEvent( m_nClientId, ::css::accessibility::AccessibleEventObject( - static_cast< ::cppu::OWeakObject * >(this), - nEventId, rNewValue, rOldValue) ); -} - -// virtual -::css::uno::Reference< ::css::accessibility::XAccessibleContext > SAL_CALL -ParagraphImpl::getAccessibleContext() throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return this; -} - -// virtual -::sal_Int32 SAL_CALL ParagraphImpl::getAccessibleChildCount() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return 0; -} - -// virtual -::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL -ParagraphImpl::getAccessibleChild(::sal_Int32) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " ParagraphImpl::getAccessibleChild")), - static_cast< ::css::uno::XWeak * >(this)); -} - -// virtual -::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL -ParagraphImpl::getAccessibleParent() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->getAccessible(); -} - -// virtual -::sal_Int32 SAL_CALL ParagraphImpl::getAccessibleIndexInParent() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->retrieveParagraphIndex(this); -} - -// virtual -::sal_Int16 SAL_CALL ParagraphImpl::getAccessibleRole() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return ::css::accessibility::AccessibleRole::PARAGRAPH; -} - -// virtual -::rtl::OUString SAL_CALL ParagraphImpl::getAccessibleDescription() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return ::rtl::OUString(); -} - -// virtual -::rtl::OUString SAL_CALL ParagraphImpl::getAccessibleName() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return ::rtl::OUString(); -} - -// virtual -::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet > -SAL_CALL ParagraphImpl::getAccessibleRelationSet() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->retrieveParagraphRelationSet( this ); -} - -// virtual -::css::uno::Reference< ::css::accessibility::XAccessibleStateSet > -SAL_CALL ParagraphImpl::getAccessibleStateSet() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - - // FIXME Notification of changes (STATE_CHANGED) missing when - // m_rView.IsReadOnly() changes: - return new ::utl::AccessibleStateSetHelper( - m_xDocument->retrieveParagraphState(this)); -} - -// virtual -::css::lang::Locale SAL_CALL ParagraphImpl::getLocale() - throw (::css::accessibility::IllegalAccessibleComponentStateException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->retrieveLocale(); -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::containsPoint(::css::awt::Point const & rPoint) - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, - false)); - return rPoint.X >= 0 && rPoint.X < aRect.Width - && rPoint.Y >= 0 && rPoint.Y < aRect.Height; -} - -// virtual -::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL -ParagraphImpl::getAccessibleAtPoint(::css::awt::Point const &) - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return 0; -} - -// virtual -::css::awt::Rectangle SAL_CALL ParagraphImpl::getBounds() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->retrieveParagraphBounds(this, false); -} - -// virtual -::css::awt::Point SAL_CALL ParagraphImpl::getLocation() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, - false)); - return ::css::awt::Point(aRect.X, aRect.Y); -} - -// virtual -::css::awt::Point SAL_CALL ParagraphImpl::getLocationOnScreen() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, - true)); - return ::css::awt::Point(aRect.X, aRect.Y); -} - -// virtual -::css::awt::Size SAL_CALL ParagraphImpl::getSize() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - ::css::awt::Rectangle aRect(m_xDocument->retrieveParagraphBounds(this, - false)); - return ::css::awt::Size(aRect.Width, aRect.Height); -} - -// virtual -void SAL_CALL ParagraphImpl::grabFocus() throw (::css::uno::RuntimeException) -{ - checkDisposed(); - Window* pWindow = m_xDocument->GetWindow(); - if ( pWindow ) - { - pWindow->GrabFocus(); - } - try - { - m_xDocument->changeParagraphSelection(this, 0, 0); - } - catch (const ::css::lang::IndexOutOfBoundsException & rEx) - { - OSL_TRACE( - "textwindowaccessibility.cxx: ParagraphImpl::grabFocus:" - " caught unexpected %s\n", - ::rtl::OUStringToOString(rEx.Message, RTL_TEXTENCODING_UTF8). - getStr()); - } -} - -// virtual -::css::uno::Any SAL_CALL ParagraphImpl::getAccessibleKeyBinding() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return ::css::uno::Any(); -} - -// virtual -::css::util::Color SAL_CALL ParagraphImpl::getForeground() - throw (::css::uno::RuntimeException) -{ - return 0; // TODO -} - -// virtual -::css::util::Color SAL_CALL ParagraphImpl::getBackground() - throw (::css::uno::RuntimeException) -{ - return 0; // TODO -} - -// virtual -::sal_Int32 SAL_CALL ParagraphImpl::getCaretPosition() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->retrieveParagraphCaretPosition(this); -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::setCaretPosition(::sal_Int32 nIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->changeParagraphSelection(this, nIndex, nIndex); - return true; -} - -// virtual -::sal_Unicode SAL_CALL ParagraphImpl::getCharacter(::sal_Int32 nIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - return OCommonAccessibleText::getCharacter(nIndex); -} - -// virtual -::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL -ParagraphImpl::getCharacterAttributes(::sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->retrieveCharacterAttributes( this, nIndex, aRequestedAttributes ); -} - -// virtual -::css::awt::Rectangle SAL_CALL -ParagraphImpl::getCharacterBounds(::sal_Int32 nIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - ::css::awt::Rectangle aBounds(m_xDocument->retrieveCharacterBounds(this, nIndex)); - ::css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false)); - aBounds.X -= aParaBounds.X; - aBounds.Y -= aParaBounds.Y; - return aBounds; -} - -// virtual -::sal_Int32 SAL_CALL ParagraphImpl::getCharacterCount() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return OCommonAccessibleText::getCharacterCount(); -} - -// virtual -::sal_Int32 SAL_CALL -ParagraphImpl::getIndexAtPoint(::css::awt::Point const & rPoint) - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - ::css::awt::Point aPoint(rPoint); - ::css::awt::Rectangle aParaBounds(m_xDocument->retrieveParagraphBounds(this, false)); - aPoint.X += aParaBounds.X; - aPoint.Y += aParaBounds.Y; - return m_xDocument->retrieveCharacterIndex(this, aPoint); -} - -// virtual -::rtl::OUString SAL_CALL ParagraphImpl::getSelectedText() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - - return OCommonAccessibleText::getSelectedText(); -} - -// virtual -::sal_Int32 SAL_CALL ParagraphImpl::getSelectionStart() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return OCommonAccessibleText::getSelectionStart(); -} - -// virtual -::sal_Int32 SAL_CALL ParagraphImpl::getSelectionEnd() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return OCommonAccessibleText::getSelectionEnd(); -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::setSelection(::sal_Int32 nStartIndex, - ::sal_Int32 nEndIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->changeParagraphSelection(this, nStartIndex, nEndIndex); - return true; -} - -// virtual -::rtl::OUString SAL_CALL ParagraphImpl::getText() - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return OCommonAccessibleText::getText(); -} - -// virtual -::rtl::OUString SAL_CALL ParagraphImpl::getTextRange(::sal_Int32 nStartIndex, - ::sal_Int32 nEndIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex); -} - -// virtual -::com::sun::star::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) -{ - checkDisposed(); - return OCommonAccessibleText::getTextAtIndex(nIndex, aTextType); -} - -// virtual -::com::sun::star::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) -{ - checkDisposed(); - return OCommonAccessibleText::getTextBeforeIndex(nIndex, aTextType); -} - -// virtual -::com::sun::star::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) -{ - checkDisposed(); - return OCommonAccessibleText::getTextBehindIndex(nIndex, aTextType); -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::copyText(::sal_Int32 nStartIndex, - ::sal_Int32 nEndIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->copyParagraphText(this, nStartIndex, nEndIndex); - return true; -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::cutText(::sal_Int32 nStartIndex, - ::sal_Int32 nEndIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, true, false, - ::rtl::OUString()); - return true; -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::pasteText(::sal_Int32 nIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->changeParagraphText(this, nIndex, nIndex, false, true, - ::rtl::OUString()); - return true; -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::deleteText(::sal_Int32 nStartIndex, - ::sal_Int32 nEndIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false, - ::rtl::OUString()); - return true; -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::insertText(::rtl::OUString const & rText, - ::sal_Int32 nIndex) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->changeParagraphText(this, nIndex, nIndex, false, false, rText); - return true; -} - -// virtual -::sal_Bool SAL_CALL -ParagraphImpl::replaceText(::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex, - ::rtl::OUString const & rReplacement) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->changeParagraphText(this, nStartIndex, nEndIndex, false, false, - rReplacement); - return true; -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::setAttributes( - ::sal_Int32 nStartIndex, ::sal_Int32 nEndIndex, - ::css::uno::Sequence< ::css::beans::PropertyValue > const & rAttributeSet) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->changeParagraphAttributes(this, nStartIndex, nEndIndex, - rAttributeSet); - return true; -} - -// virtual -::sal_Bool SAL_CALL ParagraphImpl::setText(::rtl::OUString const & rText) - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - m_xDocument->changeParagraphText(this, rText); - return true; -} - -// virtual -::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL -ParagraphImpl::getDefaultAttributes(const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes) - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->retrieveDefaultAttributes( this, RequestedAttributes ); -} - -// virtual -::css::uno::Sequence< ::css::beans::PropertyValue > SAL_CALL -ParagraphImpl::getRunAttributes(::sal_Int32 Index, const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->retrieveRunAttributes( this, Index, RequestedAttributes ); -} - -// virtual -::sal_Int32 SAL_CALL ParagraphImpl::getLineNumberAtIndex( ::sal_Int32 nIndex ) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - - ::sal_Int32 nLineNo = -1; - m_xDocument->retrieveParagraphLineBoundary( this, nIndex, &nLineNo ); - - return nLineNo; -} - -// virtual -::css::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextAtLineNumber( ::sal_Int32 nLineNo ) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - checkDisposed(); - - ::css::i18n::Boundary aBoundary = - m_xDocument->retrieveParagraphBoundaryOfLine( this, nLineNo ); - - return ::css::accessibility::TextSegment( getTextRange(aBoundary.startPos, aBoundary.endPos), - aBoundary.startPos, aBoundary.endPos); -} - -// virtual -::css::accessibility::TextSegment SAL_CALL ParagraphImpl::getTextAtLineWithCaret( ) - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - - sal_Int32 nLineNo = getNumberOfLineWithCaret(); - - try { - return ( nLineNo >= 0 ) ? - getTextAtLineNumber( nLineNo ) : - ::css::accessibility::TextSegment(); - } catch (const ::css::lang::IndexOutOfBoundsException&) { - throw ::css::uno::RuntimeException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " ParagraphImpl::getTextAtLineWithCaret") ), - static_cast< ::css::uno::XWeak * >( this ) ); - } -} - -// virtual -::sal_Int32 SAL_CALL ParagraphImpl::getNumberOfLineWithCaret( ) - throw (::css::uno::RuntimeException) -{ - checkDisposed(); - return m_xDocument->retrieveParagraphLineWithCursor(this); -} - - -// virtual -void SAL_CALL ParagraphImpl::addEventListener( - ::css::uno::Reference< - ::css::accessibility::XAccessibleEventListener > const & rListener) - throw (::css::uno::RuntimeException) -{ - if (rListener.is()) - { - ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); - if (rBHelper.bDisposed || rBHelper.bInDispose) - { - aGuard.clear(); - rListener->disposing(::css::lang::EventObject( - static_cast< ::cppu::OWeakObject * >(this))); - } - else - { - if (!m_nClientId) - m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); - comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, rListener ); - } - } -} - -// virtual -void SAL_CALL ParagraphImpl::removeEventListener( - ::css::uno::Reference< - ::css::accessibility::XAccessibleEventListener > const & rListener) - throw (::css::uno::RuntimeException) -{ - comphelper::AccessibleEventNotifier::TClientId nId = 0; - { - ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); - if (rListener.is() && m_nClientId != 0 - && comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, rListener ) == 0) - { - nId = m_nClientId; - m_nClientId = 0; - } - } - if (nId != 0) - { - // no listeners anymore - // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), - // and at least to us not firing any events anymore, in case somebody calls - // NotifyAccessibleEvent, again - comphelper::AccessibleEventNotifier::revokeClient(nId); - } -} - -// virtual -void SAL_CALL ParagraphImpl::disposing() -{ - comphelper::AccessibleEventNotifier::TClientId nId = 0; - { - ::osl::ClearableMutexGuard aGuard(rBHelper.rMutex); - nId = m_nClientId; - m_nClientId = 0; - } - if (nId != 0) - comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(nId, *this); -} - -// virtual -::rtl::OUString ParagraphImpl::implGetText() -{ - return m_xDocument->retrieveParagraphText(this); -} - -// virtual -::css::lang::Locale ParagraphImpl::implGetLocale() -{ - return m_xDocument->retrieveLocale(); -} - -// virtual -void ParagraphImpl::implGetSelection(::sal_Int32 & rStartIndex, - ::sal_Int32 & rEndIndex) -{ - m_xDocument->retrieveParagraphSelection(this, &rStartIndex, &rEndIndex); -} - -// virtual -void ParagraphImpl::implGetParagraphBoundary( ::css::i18n::Boundary& rBoundary, - ::sal_Int32 nIndex ) -{ - ::rtl::OUString sText( implGetText() ); - ::sal_Int32 nLength = sText.getLength(); - - if ( implIsValidIndex( nIndex, nLength ) ) - { - rBoundary.startPos = 0; - rBoundary.endPos = nLength; - } - else - { - rBoundary.startPos = nIndex; - rBoundary.endPos = nIndex; - } -} - -// virtual -void ParagraphImpl::implGetLineBoundary( ::css::i18n::Boundary& rBoundary, - ::sal_Int32 nIndex ) -{ - ::rtl::OUString sText( implGetText() ); - ::sal_Int32 nLength = sText.getLength(); - - if ( implIsValidIndex( nIndex, nLength ) || nIndex == nLength ) - { - ::css::i18n::Boundary aBoundary = - m_xDocument->retrieveParagraphLineBoundary( this, nIndex ); - rBoundary.startPos = aBoundary.startPos; - rBoundary.endPos = aBoundary.endPos; - } - else - { - rBoundary.startPos = nIndex; - rBoundary.endPos = nIndex; - } -} - - -void ParagraphImpl::checkDisposed() -{ - ::osl::MutexGuard aGuard(rBHelper.rMutex); - if (!(rBHelper.bDisposed || rBHelper.bInDispose)) - return; - throw ::css::lang::DisposedException( - ::rtl::OUString(), static_cast< ::css::uno::XWeak * >(this)); -} - -Document::Document(::VCLXWindow * pVclXWindow, ::TextEngine & rEngine, - ::TextView & rView, bool bCompoundControlChild): - VCLXAccessibleComponent(pVclXWindow), - m_xAccessible(pVclXWindow), - m_rEngine(rEngine), - m_rView(rView), - m_aEngineListener(*this), - m_aViewListener(LINK(this, Document, WindowEventHandler)), - m_bCompoundControlChild(bCompoundControlChild) -{} - -::css::lang::Locale Document::retrieveLocale() -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - return m_rEngine.GetLocale(); -} - -::sal_Int32 Document::retrieveParagraphIndex(ParagraphImpl const * pParagraph) -{ - ::osl::MutexGuard aInternalGuard(GetMutex()); - - // If a client holds on to a Paragraph that is no longer visible, it can - // happen that this Paragraph lies outside the range from m_aVisibleBegin - // to m_aVisibleEnd. In that case, return -1 instead of a valid index: - Paragraphs::iterator aPara(m_xParagraphs->begin() - + pParagraph->getNumber()); - return aPara < m_aVisibleBegin || aPara >= m_aVisibleEnd - ? -1 : static_cast< ::sal_Int32 >(aPara - m_aVisibleBegin); - // XXX numeric overflow -} - -::sal_Int64 Document::retrieveParagraphState(ParagraphImpl const * pParagraph) -{ - ::osl::MutexGuard aInternalGuard(GetMutex()); - - // If a client holds on to a Paragraph that is no longer visible, it can - // happen that this Paragraph lies outside the range from m_aVisibleBegin - // to m_aVisibleEnd. In that case, it is neither VISIBLE nor SHOWING: - ::sal_Int64 nState - = (static_cast< ::sal_Int64 >(1) - << ::css::accessibility::AccessibleStateType::ENABLED) - | (static_cast< ::sal_Int64 >(1) - << ::css::accessibility::AccessibleStateType::SENSITIVE) - | (static_cast< ::sal_Int64 >(1) - << ::css::accessibility::AccessibleStateType::FOCUSABLE) - | (static_cast< ::sal_Int64 >(1) - << ::css::accessibility::AccessibleStateType::MULTI_LINE); - if (!m_rView.IsReadOnly()) - nState |= (static_cast< ::sal_Int64 >(1) - << ::css::accessibility::AccessibleStateType::EDITABLE); - Paragraphs::iterator aPara(m_xParagraphs->begin() - + pParagraph->getNumber()); - if (aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd) - { - nState - |= (static_cast< ::sal_Int64 >(1) - << ::css::accessibility::AccessibleStateType::VISIBLE) - | (static_cast< ::sal_Int64 >(1) - << ::css::accessibility::AccessibleStateType::SHOWING); - if (aPara == m_aFocused) - nState |= (static_cast< ::sal_Int64 >(1) - << ::css::accessibility::AccessibleStateType::FOCUSED); - } - return nState; -}; - -::css::awt::Rectangle -Document::retrieveParagraphBounds(ParagraphImpl const * pParagraph, - bool bAbsolute) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - ::osl::MutexGuard aInternalGuard(GetMutex()); - - // If a client holds on to a Paragraph that is no longer visible (as it - // scrolled out the top of the view), it can happen that this Paragraph - // lies before m_aVisibleBegin. In that case, calculate the vertical - // position of the Paragraph starting at paragraph 0, otherwise optimize - // and start at m_aVisibleBegin: - Paragraphs::iterator aPara(m_xParagraphs->begin() - + pParagraph->getNumber()); - ::sal_Int32 nPos; - Paragraphs::iterator aIt; - if (aPara < m_aVisibleBegin) - { - nPos = 0; - aIt = m_xParagraphs->begin(); - } - else - { - nPos = m_nViewOffset - m_nVisibleBeginOffset; - aIt = m_aVisibleBegin; - } - for (; aIt != aPara; ++aIt) - nPos += aIt->getHeight(); - - Point aOrig(0, 0); - if (bAbsolute) - aOrig = m_rView.GetWindow()->OutputToAbsoluteScreenPixel(aOrig); - - return ::css::awt::Rectangle( - static_cast< ::sal_Int32 >(aOrig.X()), - static_cast< ::sal_Int32 >(aOrig.Y()) + nPos - m_nViewOffset, - m_rView.GetWindow()->GetOutputSizePixel().Width(), aPara->getHeight()); - // XXX numeric overflow (3x) -} - -::rtl::OUString -Document::retrieveParagraphText(ParagraphImpl const * pParagraph) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - ::osl::MutexGuard aInternalGuard(GetMutex()); - return m_rEngine.GetText(static_cast< ::sal_uLong >(pParagraph->getNumber())); - // numeric overflow cannot happen here -} - -void Document::retrieveParagraphSelection(ParagraphImpl const * pParagraph, - ::sal_Int32 * pBegin, - ::sal_Int32 * pEnd) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::TextSelection const & rSelection = m_rView.GetSelection(); - Paragraphs::size_type nNumber = pParagraph->getNumber(); - TextPaM aStartPaM( rSelection.GetStart() ); - TextPaM aEndPaM( rSelection.GetEnd() ); - TextPaM aMinPaM( ::std::min( aStartPaM, aEndPaM ) ); - TextPaM aMaxPaM( ::std::max( aStartPaM, aEndPaM ) ); - - if ( nNumber >= aMinPaM.GetPara() && nNumber <= aMaxPaM.GetPara() ) - { - *pBegin = nNumber > aMinPaM.GetPara() - ? 0 - : static_cast< ::sal_Int32 >( aMinPaM.GetIndex() ); - // XXX numeric overflow - *pEnd = nNumber < aMaxPaM.GetPara() - ? static_cast< ::sal_Int32 >( m_rEngine.GetText(static_cast< ::sal_uLong >(nNumber)).Len() ) - : static_cast< ::sal_Int32 >( aMaxPaM.GetIndex() ); - // XXX numeric overflow (3x) - - if ( aStartPaM > aEndPaM ) - ::std::swap( *pBegin, *pEnd ); - } - else - { - *pBegin = 0; - *pEnd = 0; - } -} - -::sal_Int32 Document::retrieveParagraphCaretPosition(ParagraphImpl const * pParagraph) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::TextSelection const & rSelection = m_rView.GetSelection(); - Paragraphs::size_type nNumber = pParagraph->getNumber(); - TextPaM aEndPaM( rSelection.GetEnd() ); - - return aEndPaM.GetPara() == nNumber - ? static_cast< ::sal_Int32 >(aEndPaM.GetIndex()) : -1; -} - -::css::awt::Rectangle -Document::retrieveCharacterBounds(ParagraphImpl const * pParagraph, - ::sal_Int32 nIndex) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); - sal_Int32 nLength = m_rEngine.GetText(nNumber).Len(); - // XXX numeric overflow - if (nIndex < 0 || nIndex > nLength) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::retrieveCharacterAttributes")), - static_cast< ::css::uno::XWeak * >(this)); - ::css::awt::Rectangle aBounds( 0, 0, 0, 0 ); - if ( nIndex == nLength ) - { - aBounds = AWTRectangle( - m_rEngine.PaMtoEditCursor(::TextPaM(nNumber, - static_cast< ::sal_uInt16 >(nIndex)))); - } - else - { - ::Rectangle aLeft( - m_rEngine.PaMtoEditCursor(::TextPaM(nNumber, - static_cast< ::sal_uInt16 >(nIndex)))); - // XXX numeric overflow - ::Rectangle aRight( - m_rEngine.PaMtoEditCursor(::TextPaM(nNumber, - static_cast< ::sal_uInt16 >(nIndex) - + 1))); - // XXX numeric overflow (2x) - // FIXME If the vertical extends of the two cursors do not match, assume - // nIndex is the last character on the line; the bounding box will then - // extend to m_rEnginge.GetMaxTextWidth(): - ::sal_Int32 nWidth = (aLeft.Top() == aRight.Top() - && aLeft.Bottom() == aRight.Bottom()) - ? static_cast< ::sal_Int32 >(aRight.Left() - aLeft.Left()) - : static_cast< ::sal_Int32 >(m_rEngine.GetMaxTextWidth() - - aLeft.Left()); - // XXX numeric overflow (4x) - aBounds = ::css::awt::Rectangle(static_cast< ::sal_Int32 >(aLeft.Left()), - static_cast< ::sal_Int32 >(aLeft.Top() - m_nViewOffset), - nWidth, - static_cast< ::sal_Int32 >(aLeft.Bottom() - - aLeft.Top())); - // XXX numeric overflow (4x) - } - return aBounds; -} - -::sal_Int32 Document::retrieveCharacterIndex(ParagraphImpl const * pParagraph, - ::css::awt::Point const & rPoint) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); - // XXX numeric overflow - ::TextPaM aPaM(m_rEngine.GetPaM(::Point(static_cast< long >(rPoint.X), - static_cast< long >(rPoint.Y)))); - // XXX numeric overflow (2x) - return aPaM.GetPara() == nNumber - ? static_cast< ::sal_Int32 >(aPaM.GetIndex()) : -1; - // XXX numeric overflow -} - -::css::uno::Sequence< ::css::beans::PropertyValue > -Document::retrieveCharacterAttributes( - ParagraphImpl const * pParagraph, ::sal_Int32 nIndex, - const ::css::uno::Sequence< ::rtl::OUString >& aRequestedAttributes) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); - // XXX numeric overflow - if (nIndex < 0 || nIndex >= m_rEngine.GetText(nNumber).Len()) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::retrieveCharacterAttributes")), - static_cast< ::css::uno::XWeak * >(this)); - - // retrieve default attributes - tPropValMap aCharAttrSeq; - retrieveDefaultAttributesImpl( pParagraph, aRequestedAttributes, aCharAttrSeq ); - - // retrieve run attributes - tPropValMap aRunAttrSeq; - retrieveRunAttributesImpl( pParagraph, nIndex, aRequestedAttributes, aRunAttrSeq ); - - // merge default and run attributes - for ( tPropValMap::const_iterator aRunIter = aRunAttrSeq.begin(); - aRunIter != aRunAttrSeq.end(); - ++aRunIter ) - { - aCharAttrSeq[ aRunIter->first ] = aRunIter->second; - } - - return convertHashMapToSequence( aCharAttrSeq ); -} - -void Document::retrieveDefaultAttributesImpl( - ParagraphImpl const * pParagraph, - const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes, - tPropValMap& rDefAttrSeq) -{ - // default attributes are not supported by text engine - (void) pParagraph; - (void) RequestedAttributes; - (void) rDefAttrSeq; -} - -::css::uno::Sequence< ::css::beans::PropertyValue > -Document::retrieveDefaultAttributes( - ParagraphImpl const * pParagraph, - const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() ); - ::osl::MutexGuard aInternalGuard( GetMutex() ); - - tPropValMap aDefAttrSeq; - retrieveDefaultAttributesImpl( pParagraph, RequestedAttributes, aDefAttrSeq ); - return convertHashMapToSequence( aDefAttrSeq ); -} - -// static -::css::uno::Sequence< ::css::beans::PropertyValue > -Document::convertHashMapToSequence(tPropValMap& rAttrSeq) -{ - ::css::uno::Sequence< ::css::beans::PropertyValue > aValues( rAttrSeq.size() ); - ::css::beans::PropertyValue* pValues = aValues.getArray(); - ::sal_Int32 i = 0; - for ( tPropValMap::const_iterator aIter = rAttrSeq.begin(); - aIter != rAttrSeq.end(); - ++aIter ) - { - pValues[i] = aIter->second; - ++i; - } - return aValues; -} - -void Document::retrieveRunAttributesImpl( - ParagraphImpl const * pParagraph, ::sal_Int32 Index, - const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes, - tPropValMap& rRunAttrSeq) -{ - ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() ); - ::TextPaM aPaM( nNumber, static_cast< ::sal_uInt16 >( Index ) ); - // XXX numeric overflow - // FIXME TEXTATTR_HYPERLINK ignored: - ::TextAttribFontColor const * pColor - = static_cast< ::TextAttribFontColor const * >( - m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTCOLOR ) ); - ::TextAttribFontWeight const * pWeight - = static_cast< ::TextAttribFontWeight const * >( - m_rEngine.FindAttrib( aPaM, TEXTATTR_FONTWEIGHT ) ); - tPropValMap aRunAttrSeq; - if ( pColor ) - { - ::css::beans::PropertyValue aPropVal; - aPropVal.Name = - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharColor" ) ); - aPropVal.Handle = -1; - aPropVal.Value = mapFontColor( pColor->GetColor() ); - aPropVal.State = ::css::beans::PropertyState_DIRECT_VALUE; - aRunAttrSeq[ aPropVal.Name ] = aPropVal; - } - if ( pWeight ) - { - ::css::beans::PropertyValue aPropVal; - aPropVal.Name = - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) ); - aPropVal.Handle = -1; - aPropVal.Value = mapFontWeight( pWeight->getFontWeight() ); - aPropVal.State = ::css::beans::PropertyState_DIRECT_VALUE; - aRunAttrSeq[ aPropVal.Name ] = aPropVal; - } - if ( RequestedAttributes.getLength() == 0 ) - { - rRunAttrSeq = aRunAttrSeq; - } - else - { - const ::rtl::OUString* pReqAttrs = RequestedAttributes.getConstArray(); - const ::sal_Int32 nLength = RequestedAttributes.getLength(); - for ( ::sal_Int32 i = 0; i < nLength; ++i ) - { - tPropValMap::iterator aIter = aRunAttrSeq.find( pReqAttrs[i] ); - if ( aIter != aRunAttrSeq.end() ) - { - rRunAttrSeq[ (*aIter).first ] = (*aIter).second; - } - } - } -} - -::css::uno::Sequence< ::css::beans::PropertyValue > -Document::retrieveRunAttributes( - ParagraphImpl const * pParagraph, ::sal_Int32 Index, - const ::css::uno::Sequence< ::rtl::OUString >& RequestedAttributes) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() ); - ::osl::MutexGuard aInternalGuard( GetMutex() ); - ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() ); - // XXX numeric overflow - if ( Index < 0 || Index >= m_rEngine.GetText(nNumber).Len() ) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::retrieveRunAttributes") ), - static_cast< ::css::uno::XWeak * >( this ) ); - - tPropValMap aRunAttrSeq; - retrieveRunAttributesImpl( pParagraph, Index, RequestedAttributes, aRunAttrSeq ); - return convertHashMapToSequence( aRunAttrSeq ); -} - -void Document::changeParagraphText(ParagraphImpl * pParagraph, - ::rtl::OUString const & rText) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); - // XXX numeric overflow - changeParagraphText(nNumber, 0, m_rEngine.GetTextLen(nNumber), false, - false, rText); - } -} - -void Document::changeParagraphText(ParagraphImpl * pParagraph, - ::sal_Int32 nBegin, ::sal_Int32 nEnd, - bool bCut, bool bPaste, - ::rtl::OUString const & rText) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); - // XXX numeric overflow - if (nBegin < 0 || nBegin > nEnd - || nEnd > m_rEngine.GetText(nNumber).Len()) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::changeParagraphText")), - static_cast< ::css::uno::XWeak * >(this)); - changeParagraphText(nNumber, static_cast< ::sal_uInt16 >(nBegin), - static_cast< ::sal_uInt16 >(nEnd), bCut, bPaste, rText); - // XXX numeric overflow (2x) - } -} - -void Document::copyParagraphText(ParagraphImpl const * pParagraph, - ::sal_Int32 nBegin, ::sal_Int32 nEnd) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); - // XXX numeric overflow - if (nBegin < 0 || nBegin > nEnd - || nEnd > m_rEngine.GetText(nNumber).Len()) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::copyParagraphText")), - static_cast< ::css::uno::XWeak * >(this)); - m_rView.SetSelection( - ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)), - ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd)))); - // XXX numeric overflow (2x) - m_rView.Copy(); - } -} - -void Document::changeParagraphAttributes( - ParagraphImpl * pParagraph, ::sal_Int32 nBegin, ::sal_Int32 nEnd, - ::css::uno::Sequence< ::css::beans::PropertyValue > const & rAttributeSet) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); - // XXX numeric overflow - if (nBegin < 0 || nBegin > nEnd - || nEnd > m_rEngine.GetText(nNumber).Len()) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::changeParagraphAttributes")), - static_cast< ::css::uno::XWeak * >(this)); - - // FIXME The new attributes are added to any attributes already set, - // they do not replace the old attributes as required by - // XAccessibleEditableText.setAttributes: - for (::sal_Int32 i = 0; i < rAttributeSet.getLength(); ++i) - if (rAttributeSet[i].Name.equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM("CharColor"))) - m_rEngine.SetAttrib(::TextAttribFontColor( - mapFontColor(rAttributeSet[i].Value)), - nNumber, static_cast< ::sal_uInt16 >(nBegin), - static_cast< ::sal_uInt16 >(nEnd)); - // XXX numeric overflow (2x) - else if (rAttributeSet[i].Name.equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM("CharWeight"))) - m_rEngine.SetAttrib(::TextAttribFontWeight( - mapFontWeight(rAttributeSet[i].Value)), - nNumber, static_cast< ::sal_uInt16 >(nBegin), - static_cast< ::sal_uInt16 >(nEnd)); - // XXX numeric overflow (2x) - } -} - -void Document::changeParagraphSelection(ParagraphImpl * pParagraph, - ::sal_Int32 nBegin, ::sal_Int32 nEnd) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::sal_uLong nNumber = static_cast< ::sal_uLong >(pParagraph->getNumber()); - // XXX numeric overflow - if (nBegin < 0 || nBegin > nEnd - || nEnd > m_rEngine.GetText(nNumber).Len()) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::changeParagraphSelection")), - static_cast< ::css::uno::XWeak * >(this)); - m_rView.SetSelection( - ::TextSelection(::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nBegin)), - ::TextPaM(nNumber, static_cast< ::sal_uInt16 >(nEnd)))); - // XXX numeric overflow (2x) - } -} - -::css::i18n::Boundary -Document::retrieveParagraphLineBoundary( ParagraphImpl const * pParagraph, - ::sal_Int32 nIndex, ::sal_Int32 *pLineNo ) -{ - ::css::i18n::Boundary aBoundary; - aBoundary.startPos = nIndex; - aBoundary.endPos = nIndex; - - ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() ); - { - ::osl::MutexGuard aInternalGuard( GetMutex() ); - ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() ); - if ( nIndex < 0 || nIndex > m_rEngine.GetText( nNumber ).Len() ) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::retrieveParagraphLineBoundary" ) ), - static_cast< ::css::uno::XWeak * >( this ) ); - ::sal_Int32 nLineStart = 0; - ::sal_Int32 nLineEnd = 0; - ::sal_uInt16 nLineCount = m_rEngine.GetLineCount( nNumber ); - for ( ::sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine ) - { - ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >( - m_rEngine.GetLineLen( nNumber, nLine ) ); - nLineStart = nLineEnd; - nLineEnd += nLineLength; - if ( nIndex >= nLineStart && ( ( nLine == nLineCount - 1 ) ? nIndex <= nLineEnd : nIndex < nLineEnd ) ) - { - aBoundary.startPos = nLineStart; - aBoundary.endPos = nLineEnd; - if( pLineNo ) - pLineNo[0] = nLine; - break; - } - } - } - - return aBoundary; -} - -::css::i18n::Boundary -Document::retrieveParagraphBoundaryOfLine( ParagraphImpl const * pParagraph, - ::sal_Int32 nLineNo ) -{ - ::css::i18n::Boundary aBoundary; - aBoundary.startPos = 0; - aBoundary.endPos = 0; - - ::osl::Guard< ::comphelper::IMutex > aExternalGuard( getExternalLock() ); - { - ::osl::MutexGuard aInternalGuard( GetMutex() ); - ::sal_uLong nNumber = static_cast< ::sal_uLong >( pParagraph->getNumber() ); - if ( nLineNo >= m_rEngine.GetLineCount( nNumber ) ) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::retrieveParagraphBoundaryOfLine" ) ), - static_cast< ::css::uno::XWeak * >( this ) ); - ::sal_Int32 nLineStart = 0; - ::sal_Int32 nLineEnd = 0; - for ( ::sal_uInt16 nLine = 0; nLine <= nLineNo; ++nLine ) - { - ::sal_Int32 nLineLength = static_cast< ::sal_Int32 >( - m_rEngine.GetLineLen( nNumber, nLine ) ); - nLineStart = nLineEnd; - nLineEnd += nLineLength; - } - - aBoundary.startPos = nLineStart; - aBoundary.endPos = nLineEnd; - } - - return aBoundary; -} - -sal_Int32 Document::retrieveParagraphLineWithCursor( ParagraphImpl const * pParagraph ) -{ - ::osl::Guard< ::comphelper::IMutex > aExternalGuard(getExternalLock()); - ::osl::MutexGuard aInternalGuard(GetMutex()); - ::TextSelection const & rSelection = m_rView.GetSelection(); - Paragraphs::size_type nNumber = pParagraph->getNumber(); - TextPaM aEndPaM( rSelection.GetEnd() ); - - return aEndPaM.GetPara() == nNumber - ? m_rView.GetLineNumberOfCursorInSelection() : -1; -} - - -::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet > -Document::retrieveParagraphRelationSet( ParagraphImpl const * pParagraph ) -{ - ::osl::MutexGuard aInternalGuard( GetMutex() ); - - ::utl::AccessibleRelationSetHelper* pRelationSetHelper = new ::utl::AccessibleRelationSetHelper(); - ::css::uno::Reference< ::css::accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper; - - Paragraphs::iterator aPara( m_xParagraphs->begin() + pParagraph->getNumber() ); - - if ( aPara > m_aVisibleBegin && aPara < m_aVisibleEnd ) - { - ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > aSequence(1); - aSequence[0] = getAccessibleChild( aPara - 1 ); - ::css::accessibility::AccessibleRelation aRelation( ::css::accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM, aSequence ); - pRelationSetHelper->AddRelation( aRelation ); - } - - if ( aPara >= m_aVisibleBegin && aPara < m_aVisibleEnd -1 ) - { - ::css::uno::Sequence< ::css::uno::Reference< ::css::uno::XInterface > > aSequence(1); - aSequence[0] = getAccessibleChild( aPara + 1 ); - ::css::accessibility::AccessibleRelation aRelation( ::css::accessibility::AccessibleRelationType::CONTENT_FLOWS_TO, aSequence ); - pRelationSetHelper->AddRelation( aRelation ); - } - - return xSet; -} - -void Document::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) -{ - switch ( rVclWindowEvent.GetId() ) - { - case VCLEVENT_WINDOW_GETFOCUS: - case VCLEVENT_WINDOW_LOSEFOCUS: - { - // #107179# if our parent is a compound control (e.g. MultiLineEdit), - // suppress the window focus events here - if ( !m_bCompoundControlChild ) - VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); - } - break; - default: - VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); - } -} - -// virtual -::sal_Int32 SAL_CALL Document::getAccessibleChildCount() - throw (::css::uno::RuntimeException) -{ - ::comphelper::OExternalLockGuard aGuard(this); - init(); - return m_aVisibleEnd - m_aVisibleBegin; -} - -// virtual -::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL -Document::getAccessibleChild(::sal_Int32 i) - throw (::css::lang::IndexOutOfBoundsException, - ::css::uno::RuntimeException) -{ - ::comphelper::OExternalLockGuard aGuard(this); - init(); - if (i < 0 || i >= m_aVisibleEnd - m_aVisibleBegin) - throw ::css::lang::IndexOutOfBoundsException( - ::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "textwindowaccessibility.cxx:" - " Document::getAccessibleChild")), - static_cast< ::css::uno::XWeak * >(this)); - return getAccessibleChild(m_aVisibleBegin - + static_cast< Paragraphs::size_type >(i)); -} - -// virtual -::sal_Int16 SAL_CALL Document::getAccessibleRole() - throw (::css::uno::RuntimeException) -{ - return ::css::accessibility::AccessibleRole::TEXT_FRAME; -} - -// virtual -::css::uno::Reference< ::css::accessibility::XAccessible > SAL_CALL -Document::getAccessibleAtPoint(::css::awt::Point const & rPoint) - throw (::css::uno::RuntimeException) -{ - ::comphelper::OExternalLockGuard aGuard(this); - init(); - if (rPoint.X >= 0 - && rPoint.X < m_rView.GetWindow()->GetOutputSizePixel().Width() - && rPoint.Y >= 0 && rPoint.Y < m_nViewHeight) - { - ::sal_Int32 nOffset = m_nViewOffset + rPoint.Y; // XXX numeric overflow - ::sal_Int32 nPos = m_nViewOffset - m_nVisibleBeginOffset; - for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd; - ++aIt) - { - nPos += aIt->getHeight(); // XXX numeric overflow - if (nOffset < nPos) - return getAccessibleChild(aIt); - } - } - return 0; -} - -// virtual -void SAL_CALL Document::disposing() -{ - m_aEngineListener.endListening(); - m_aViewListener.endListening(); - if (m_xParagraphs.get() != 0) - disposeParagraphs(); - VCLXAccessibleComponent::disposing(); -} - -// virtual -void Document::Notify(::SfxBroadcaster &, ::SfxHint const & rHint) -{ - if (rHint.ISA(::TextHint)) - { - ::TextHint const & rTextHint - = static_cast< ::TextHint const & >(rHint); - switch (rTextHint.GetId()) - { - case TEXT_HINT_PARAINSERTED: - case TEXT_HINT_PARAREMOVED: - // TEXT_HINT_PARAINSERTED and TEXT_HINT_PARAREMOVED are sent at - // "unsafe" times (when the text engine has not yet re-formatted its - // content), so that for example calling ::TextEngine::GetTextHeight - // from within the code that handles TEXT_HINT_PARAINSERTED causes - // trouble within the text engine. Therefore, these hints are just - // buffered until a following ::TextEngine::FormatDoc causes a - // TEXT_HINT_TEXTFORMATTED to come in: - case TEXT_HINT_FORMATPARA: - // ::TextEngine::FormatDoc sends a sequence of - // TEXT_HINT_FORMATPARAs, followed by an optional - // TEXT_HINT_TEXTHEIGHTCHANGED, followed in all cases by one - // TEXT_HINT_TEXTFORMATTED. Only the TEXT_HINT_FORMATPARAs contain - // the the numbers of the affected paragraphs, but they are sent - // before the changes are applied. Therefore, TEXT_HINT_FORMATPARAs - // are just buffered until another hint comes in: - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - if (!isAlive()) - break; - - m_aParagraphNotifications.push(rTextHint); - break; - } - case TEXT_HINT_TEXTFORMATTED: - case TEXT_HINT_TEXTHEIGHTCHANGED: - case TEXT_HINT_MODIFIED: - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - if (!isAlive()) - break; - handleParagraphNotifications(); - break; - } - case TEXT_HINT_VIEWSCROLLED: - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - if (!isAlive()) - break; - handleParagraphNotifications(); - - ::sal_Int32 nOffset = static_cast< ::sal_Int32 >( - m_rView.GetStartDocPos().Y()); - // XXX numeric overflow - if (nOffset != m_nViewOffset) - { - m_nViewOffset = nOffset; - - Paragraphs::iterator aOldVisibleBegin( - m_aVisibleBegin); - Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd); - - determineVisibleRange(); - - notifyVisibleRangeChanges(aOldVisibleBegin, - aOldVisibleEnd, - m_xParagraphs->end()); - } - break; - } - case TEXT_HINT_VIEWSELECTIONCHANGED: - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - if (!isAlive()) - break; - - if (m_aParagraphNotifications.empty()) - { - handleSelectionChangeNotification(); - } - else - { - // TEXT_HINT_VIEWSELECTIONCHANGED is sometimes sent at - // "unsafe" times (when the text engine has not yet re- - // formatted its content), so that for example calling - // ::TextEngine::GetTextHeight from within the code that - // handles a previous TEXT_HINT_PARAINSERTED causes - // trouble within the text engine. Therefore, these - // hints are just buffered (along with - // TEXT_HINT_PARAINSERTED/REMOVED/FORMATPARA) until a - // following ::TextEngine::FormatDoc causes a - // TEXT_HINT_TEXTFORMATTED to come in: - m_bSelectionChangedNotification = true; - } - break; - } - } - } -} - -IMPL_LINK(Document, WindowEventHandler, ::VclSimpleEvent *, pEvent) -{ - switch (pEvent->GetId()) - { - case VCLEVENT_WINDOW_RESIZE: - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - if (!isAlive()) - break; - - ::sal_Int32 nHeight = static_cast< ::sal_Int32 >( - m_rView.GetWindow()->GetOutputSizePixel().Height()); - // XXX numeric overflow - if (nHeight != m_nViewHeight) - { - m_nViewHeight = nHeight; - - Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin); - Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd); - - determineVisibleRange(); - - notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd, - m_xParagraphs->end()); - } - break; - } - case VCLEVENT_WINDOW_GETFOCUS: - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - if (!isAlive()) - break; - - if (m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) - { - ::rtl::Reference< ParagraphImpl > xParagraph( - getParagraph(m_aFocused)); - if (xParagraph.is()) - xParagraph->notifyEvent( - ::css::accessibility::AccessibleEventId:: - STATE_CHANGED, - ::css::uno::Any(), - ::css::uno::makeAny( - ::css::accessibility::AccessibleStateType:: - FOCUSED)); - } - break; - } - case VCLEVENT_WINDOW_LOSEFOCUS: - { - ::osl::MutexGuard aInternalGuard(GetMutex()); - if (!isAlive()) - break; - - if (m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) - { - ::rtl::Reference< ParagraphImpl > xParagraph( - getParagraph(m_aFocused)); - if (xParagraph.is()) - xParagraph->notifyEvent( - ::css::accessibility::AccessibleEventId:: - STATE_CHANGED, - ::css::uno::makeAny( - ::css::accessibility::AccessibleStateType:: - FOCUSED), - ::css::uno::Any()); - } - break; - } - } - return 0; -} - -void Document::init() -{ - if (m_xParagraphs.get() == 0) - { - ::sal_uLong nCount = m_rEngine.GetParagraphCount(); - ::std::auto_ptr< Paragraphs > p(new Paragraphs); - p->reserve(static_cast< Paragraphs::size_type >(nCount)); - // numeric overflow is harmless here - for (::sal_uLong i = 0; i < nCount; ++i) - p->push_back(ParagraphInfo(static_cast< ::sal_Int32 >( - m_rEngine.GetTextHeight(i)))); - // XXX numeric overflow - m_nViewOffset = static_cast< ::sal_Int32 >( - m_rView.GetStartDocPos().Y()); // XXX numeric overflow - m_nViewHeight = static_cast< ::sal_Int32 >( - m_rView.GetWindow()->GetOutputSizePixel().Height()); - // XXX numeric overflow - m_xParagraphs = p; - determineVisibleRange(); - m_nSelectionFirstPara = -1; - m_nSelectionFirstPos = -1; - m_nSelectionLastPara = -1; - m_nSelectionLastPos = -1; - m_aFocused = m_xParagraphs->end(); - m_bSelectionChangedNotification = false; - m_aEngineListener.startListening(m_rEngine); - m_aViewListener.startListening(*m_rView.GetWindow()); - } -} - -::rtl::Reference< ParagraphImpl > -Document::getParagraph(Paragraphs::iterator const & rIt) -{ - return static_cast< ParagraphImpl * >( - ::css::uno::Reference< ::css::accessibility::XAccessible >( - rIt->getParagraph()).get()); -} - -::css::uno::Reference< ::css::accessibility::XAccessible > -Document::getAccessibleChild(Paragraphs::iterator const & rIt) -{ - ::css::uno::Reference< ::css::accessibility::XAccessible > xParagraph( - rIt->getParagraph()); - if (!xParagraph.is()) - { - xParagraph = new Paragraph(this, rIt - m_xParagraphs->begin()); - rIt->setParagraph(xParagraph); - } - return xParagraph; -} - -void Document::determineVisibleRange() -{ - Paragraphs::iterator const aEnd = m_xParagraphs->end(); - - m_aVisibleBegin = aEnd; - m_aVisibleEnd = aEnd; - m_nVisibleBeginOffset = 0; - - ::sal_Int32 nPos = 0; - for (Paragraphs::iterator aIt = m_xParagraphs->begin(); m_aVisibleEnd == aEnd && aIt != aEnd; ++aIt) - { - ::sal_Int32 const nOldPos = nPos; - nPos += aIt->getHeight(); // XXX numeric overflow - if (m_aVisibleBegin == aEnd) - { - if (nPos >= m_nViewOffset) - { - m_aVisibleBegin = aIt; - m_nVisibleBeginOffset = m_nViewOffset - nOldPos; - } - } - else - { - if (nPos >= m_nViewOffset + m_nViewHeight) // XXX numeric overflow - { - m_aVisibleEnd = aIt; - } - } - } - - OSL_POSTCOND( - (m_aVisibleBegin == m_xParagraphs->end() && m_aVisibleEnd == m_xParagraphs->end() && m_nVisibleBeginOffset == 0) - || (m_aVisibleBegin < m_aVisibleEnd && m_nVisibleBeginOffset >= 0), - "invalid visible range"); -} - -void Document::notifyVisibleRangeChanges( - Paragraphs::iterator const & rOldVisibleBegin, - Paragraphs::iterator const & rOldVisibleEnd, - Paragraphs::iterator const & rInserted) -{ - // XXX Replace this code that determines which paragraphs have changed from - // invisible to visible or vice versa with a better algorithm. - {for (Paragraphs::iterator aIt(rOldVisibleBegin); aIt != rOldVisibleEnd; - ++aIt) - if (aIt != rInserted - && (aIt < m_aVisibleBegin || aIt >= m_aVisibleEnd)) - NotifyAccessibleEvent( - ::css::accessibility::AccessibleEventId:: - CHILD, - ::css::uno::makeAny(getAccessibleChild(aIt)), - ::css::uno::Any()); - } - {for (Paragraphs::iterator aIt(m_aVisibleBegin); aIt != m_aVisibleEnd; - ++aIt) - if (aIt == rInserted - || aIt < rOldVisibleBegin || aIt >= rOldVisibleEnd) - NotifyAccessibleEvent( - ::css::accessibility::AccessibleEventId:: - CHILD, - ::css::uno::Any(), - ::css::uno::makeAny(getAccessibleChild(aIt))); - } -} - -void -Document::changeParagraphText(::sal_uLong nNumber, ::sal_uInt16 nBegin, ::sal_uInt16 nEnd, - bool bCut, bool bPaste, - ::rtl::OUString const & rText) -{ - m_rView.SetSelection(::TextSelection(::TextPaM(nNumber, nBegin), - ::TextPaM(nNumber, nEnd))); - if (bCut) - m_rView.Cut(); - else if (nBegin != nEnd) - m_rView.DeleteSelected(); - if (bPaste) - m_rView.Paste(); - else if (rText.getLength() != 0) - m_rView.InsertText(rText); -} - -void Document::handleParagraphNotifications() -{ - while (!m_aParagraphNotifications.empty()) - { - ::TextHint aHint(m_aParagraphNotifications.front()); - m_aParagraphNotifications.pop(); - switch (aHint.GetId()) - { - case TEXT_HINT_PARAINSERTED: - { - ::sal_uLong n = aHint.GetValue(); - OSL_ENSURE(n <= m_xParagraphs->size(), - "bad TEXT_HINT_PARAINSERTED event"); - - // Save the values of old iterators (the iterators themselves - // will get invalidated), and adjust the old values so that they - // reflect the insertion of the new paragraph: - Paragraphs::size_type nOldVisibleBegin - = m_aVisibleBegin - m_xParagraphs->begin(); - Paragraphs::size_type nOldVisibleEnd - = m_aVisibleEnd - m_xParagraphs->begin(); - Paragraphs::size_type nOldFocused - = m_aFocused - m_xParagraphs->begin(); - if (n <= nOldVisibleBegin) - ++nOldVisibleBegin; // XXX numeric overflow - if (n <= nOldVisibleEnd) - ++nOldVisibleEnd; // XXX numeric overflow - if (n <= nOldFocused) - ++nOldFocused; // XXX numeric overflow - if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionFirstPara) - ++m_nSelectionFirstPara; // XXX numeric overflow - if (sal::static_int_cast<sal_Int32>(n) <= m_nSelectionLastPara) - ++m_nSelectionLastPara; // XXX numeric overflow - - Paragraphs::iterator aIns( - m_xParagraphs->insert( - m_xParagraphs->begin() + n, - ParagraphInfo(static_cast< ::sal_Int32 >( - m_rEngine.GetTextHeight(n))))); - // XXX numeric overflow (2x) - - determineVisibleRange(); - m_aFocused = m_xParagraphs->begin() + nOldFocused; - - for (Paragraphs::iterator aIt(aIns);;) - { - ++aIt; - if (aIt == m_xParagraphs->end()) - break; - ::rtl::Reference< ParagraphImpl > xParagraph( - getParagraph(aIt)); - if (xParagraph.is()) - xParagraph->numberChanged(true); - } - - notifyVisibleRangeChanges( - m_xParagraphs->begin() + nOldVisibleBegin, - m_xParagraphs->begin() + nOldVisibleEnd, aIns); - break; - } - case TEXT_HINT_PARAREMOVED: - { - ::sal_uLong n = aHint.GetValue(); - if (n == TEXT_PARA_ALL) - { - {for (Paragraphs::iterator aIt(m_aVisibleBegin); - aIt != m_aVisibleEnd; ++aIt) - NotifyAccessibleEvent( - ::css::accessibility::AccessibleEventId:: - CHILD, - ::css::uno::makeAny(getAccessibleChild(aIt)), - ::css::uno::Any()); - } - disposeParagraphs(); - m_xParagraphs->clear(); - determineVisibleRange(); - m_nSelectionFirstPara = -1; - m_nSelectionFirstPos = -1; - m_nSelectionLastPara = -1; - m_nSelectionLastPos = -1; - m_aFocused = m_xParagraphs->end(); - } - else - { - OSL_ENSURE(n < m_xParagraphs->size(), - "Bad TEXT_HINT_PARAREMOVED event"); - - Paragraphs::iterator aIt(m_xParagraphs->begin() + n); - // numeric overflow cannot occur - - // Save the values of old iterators (the iterators - // themselves will get invalidated), and adjust the old - // values so that they reflect the removal of the paragraph: - Paragraphs::size_type nOldVisibleBegin - = m_aVisibleBegin - m_xParagraphs->begin(); - Paragraphs::size_type nOldVisibleEnd - = m_aVisibleEnd - m_xParagraphs->begin(); - bool bWasVisible - = nOldVisibleBegin <= n && n < nOldVisibleEnd; - Paragraphs::size_type nOldFocused - = m_aFocused - m_xParagraphs->begin(); - bool bWasFocused = aIt == m_aFocused; - if (n < nOldVisibleBegin) - --nOldVisibleBegin; - if (n < nOldVisibleEnd) - --nOldVisibleEnd; - if (n < nOldFocused) - --nOldFocused; - if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionFirstPara) - --m_nSelectionFirstPara; - else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionFirstPara) - { - if (m_nSelectionFirstPara == m_nSelectionLastPara) - { - m_nSelectionFirstPara = -1; - m_nSelectionFirstPos = -1; - m_nSelectionLastPara = -1; - m_nSelectionLastPos = -1; - } - else - { - ++m_nSelectionFirstPara; - m_nSelectionFirstPos = 0; - } - } - if (sal::static_int_cast<sal_Int32>(n) < m_nSelectionLastPara) - --m_nSelectionLastPara; - else if (sal::static_int_cast<sal_Int32>(n) == m_nSelectionLastPara) - { - OSL_ENSURE(m_nSelectionFirstPara < m_nSelectionLastPara, - "logic error"); - --m_nSelectionLastPara; - m_nSelectionLastPos = 0x7FFFFFFF; - } - - ::css::uno::Reference< ::css::accessibility::XAccessible > - xStrong; - if (bWasVisible) - xStrong = getAccessibleChild(aIt); - ::css::uno::WeakReference< - ::css::accessibility::XAccessible > xWeak( - aIt->getParagraph()); - aIt = m_xParagraphs->erase(aIt); - - determineVisibleRange(); - m_aFocused = bWasFocused ? m_xParagraphs->end() - : m_xParagraphs->begin() + nOldFocused; - - for (; aIt != m_xParagraphs->end(); ++aIt) - { - ::rtl::Reference< ParagraphImpl > xParagraph( - getParagraph(aIt)); - if (xParagraph.is()) - xParagraph->numberChanged(false); - } - - if (bWasVisible) - NotifyAccessibleEvent( - ::css::accessibility::AccessibleEventId:: - CHILD, - ::css::uno::makeAny(xStrong), - ::css::uno::Any()); - - ::css::uno::Reference< ::css::lang::XComponent > xComponent( - xWeak.get(), ::css::uno::UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - - notifyVisibleRangeChanges( - m_xParagraphs->begin() + nOldVisibleBegin, - m_xParagraphs->begin() + nOldVisibleEnd, - m_xParagraphs->end()); - } - break; - } - case TEXT_HINT_FORMATPARA: - { - ::sal_uLong n = aHint.GetValue(); - OSL_ENSURE(n < m_xParagraphs->size(), - "Bad TEXT_HINT_FORMATPARA event"); - - (*m_xParagraphs)[static_cast< Paragraphs::size_type >(n)]. - changeHeight(static_cast< ::sal_Int32 >( - m_rEngine.GetTextHeight(n))); - // XXX numeric overflow - Paragraphs::iterator aOldVisibleBegin(m_aVisibleBegin); - Paragraphs::iterator aOldVisibleEnd(m_aVisibleEnd); - determineVisibleRange(); - notifyVisibleRangeChanges(aOldVisibleBegin, aOldVisibleEnd, - m_xParagraphs->end()); - - if (n < m_xParagraphs->size()) - { - Paragraphs::iterator aIt(m_xParagraphs->begin() + n); - ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(aIt)); - if (xParagraph.is()) - xParagraph->textChanged(); - } - break; - } - default: - OSL_FAIL( "bad buffered hint"); - break; - } - } - if (m_bSelectionChangedNotification) - { - m_bSelectionChangedNotification = false; - handleSelectionChangeNotification(); - } -} - -void Document::handleSelectionChangeNotification() -{ - ::TextSelection const & rSelection = m_rView.GetSelection(); - OSL_ENSURE(rSelection.GetStart().GetPara() < m_xParagraphs->size() - && rSelection.GetEnd().GetPara() < m_xParagraphs->size(), - "bad TEXT_HINT_VIEWSELECTIONCHANGED event"); - ::sal_Int32 nNewFirstPara - = static_cast< ::sal_Int32 >(rSelection.GetStart().GetPara()); - ::sal_Int32 nNewFirstPos - = static_cast< ::sal_Int32 >(rSelection.GetStart().GetIndex()); - // XXX numeric overflow - ::sal_Int32 nNewLastPara - = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetPara()); - ::sal_Int32 nNewLastPos - = static_cast< ::sal_Int32 >(rSelection.GetEnd().GetIndex()); - // XXX numeric overflow - - // Lose focus: - Paragraphs::iterator aIt(m_xParagraphs->begin() + nNewLastPara); - if (m_aFocused != m_xParagraphs->end() && m_aFocused != aIt - && m_aFocused >= m_aVisibleBegin && m_aFocused < m_aVisibleEnd) - { - ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(m_aFocused)); - if (xParagraph.is()) - xParagraph->notifyEvent( - ::css::accessibility::AccessibleEventId:: - STATE_CHANGED, - ::css::uno::makeAny( - ::css::accessibility::AccessibleStateType::FOCUSED), - ::css::uno::Any()); - } - - // Gain focus and update cursor position: - if (aIt >= m_aVisibleBegin && aIt < m_aVisibleEnd - && (aIt != m_aFocused - || nNewLastPara != m_nSelectionLastPara - || nNewLastPos != m_nSelectionLastPos)) - { - ::rtl::Reference< ParagraphImpl > xParagraph(getParagraph(aIt)); - if (xParagraph.is()) - { - if (aIt != m_aFocused) - xParagraph->notifyEvent( - ::css::accessibility::AccessibleEventId:: - STATE_CHANGED, - ::css::uno::Any(), - ::css::uno::makeAny( - ::css::accessibility::AccessibleStateType::FOCUSED)); - if (nNewLastPara != m_nSelectionLastPara - || nNewLastPos != m_nSelectionLastPos) - xParagraph->notifyEvent( - ::css::accessibility::AccessibleEventId:: - CARET_CHANGED, - ::css::uno::makeAny< ::sal_Int32 >( - nNewLastPara == m_nSelectionLastPara - ? m_nSelectionLastPos : 0), - ::css::uno::makeAny(nNewLastPos)); - } - } - m_aFocused = aIt; - - // Update both old and new selection. (Regardless of how the two selections - // look like, there will always be two ranges to the left and right of the - // overlap---the overlap and/or the range to the right of it possibly being - // empty. Only for these two ranges notifications have to be sent.) - - TextPaM aOldTextStart( static_cast< sal_uLong >( m_nSelectionFirstPara ), static_cast< sal_uInt16 >( m_nSelectionFirstPos ) ); - TextPaM aOldTextEnd( static_cast< sal_uLong >( m_nSelectionLastPara ), static_cast< sal_uInt16 >( m_nSelectionLastPos ) ); - TextPaM aNewTextStart( static_cast< sal_uLong >( nNewFirstPara ), static_cast< sal_uInt16 >( nNewFirstPos ) ); - TextPaM aNewTextEnd( static_cast< sal_uLong >( nNewLastPara ), static_cast< sal_uInt16 >( nNewLastPos ) ); - - // justify selections - justifySelection( aOldTextStart, aOldTextEnd ); - justifySelection( aNewTextStart, aNewTextEnd ); - - sal_Int32 nFirst1; - sal_Int32 nLast1; - sal_Int32 nFirst2; - sal_Int32 nLast2; - - if ( m_nSelectionFirstPara == -1 ) - { - // old selection not initialized yet => notify events only for new selection (if not empty) - nFirst1 = aNewTextStart.GetPara(); - nLast1 = aNewTextEnd.GetPara() + ( aNewTextStart != aNewTextEnd ? 1 : 0 ); - nFirst2 = 0; - nLast2 = 0; - } - else if ( aOldTextStart == aOldTextEnd && aNewTextStart == aNewTextEnd ) - { - // old and new selection empty => no events - nFirst1 = 0; - nLast1 = 0; - nFirst2 = 0; - nLast2 = 0; - } - else if ( aOldTextStart != aOldTextEnd && aNewTextStart == aNewTextEnd ) - { - // old selection not empty + new selection empty => notify events only for old selection - nFirst1 = aOldTextStart.GetPara(); - nLast1 = aOldTextEnd.GetPara() + 1; - nFirst2 = 0; - nLast2 = 0; - } - else if ( aOldTextStart == aOldTextEnd && aNewTextStart != aNewTextEnd ) - { - // old selection empty + new selection not empty => notify events only for new selection - nFirst1 = aNewTextStart.GetPara(); - nLast1 = aNewTextEnd.GetPara() + 1; - nFirst2 = 0; - nLast2 = 0; - } - else - { - // old and new selection not empty => notify events for the two ranges left and right of the overlap - ::std::vector< TextPaM > aTextPaMs(4); - aTextPaMs[0] = aOldTextStart; - aTextPaMs[1] = aOldTextEnd; - aTextPaMs[2] = aNewTextStart; - aTextPaMs[3] = aNewTextEnd; - ::std::sort( aTextPaMs.begin(), aTextPaMs.end() ); - - nFirst1 = aTextPaMs[0].GetPara(); - nLast1 = aTextPaMs[1].GetPara() + ( aTextPaMs[0] != aTextPaMs[1] ? 1 : 0 ); - - nFirst2 = aTextPaMs[2].GetPara(); - nLast2 = aTextPaMs[3].GetPara() + ( aTextPaMs[2] != aTextPaMs[3] ? 1 : 0 ); - - // adjust overlapping ranges - if ( nLast1 > nFirst2 ) - nLast1 = nFirst2; - } - - // notify selection changes - notifySelectionChange( nFirst1, nLast1 ); - notifySelectionChange( nFirst2, nLast2 ); - - m_nSelectionFirstPara = nNewFirstPara; - m_nSelectionFirstPos = nNewFirstPos; - m_nSelectionLastPara = nNewLastPara; - m_nSelectionLastPos = nNewLastPos; -} - -void Document::notifySelectionChange( sal_Int32 nFirst, sal_Int32 nLast ) -{ - if ( nFirst < nLast ) - { - Paragraphs::iterator aEnd( ::std::min( m_xParagraphs->begin() + nLast, m_aVisibleEnd ) ); - for ( Paragraphs::iterator aIt = ::std::max( m_xParagraphs->begin() + nFirst, m_aVisibleBegin ); aIt < aEnd; ++aIt ) - { - ::rtl::Reference< ParagraphImpl > xParagraph( getParagraph( aIt ) ); - if ( xParagraph.is() ) - { - xParagraph->notifyEvent( - ::css::accessibility::AccessibleEventId::SELECTION_CHANGED, - ::css::uno::Any(), ::css::uno::Any() ); - xParagraph->notifyEvent( - ::css::accessibility::AccessibleEventId::TEXT_SELECTION_CHANGED, - ::css::uno::Any(), ::css::uno::Any() ); - } - } - } -} - -void Document::justifySelection( TextPaM& rTextStart, TextPaM& rTextEnd ) -{ - if ( rTextStart > rTextEnd ) - { - TextPaM aTextPaM( rTextStart ); - rTextStart = rTextEnd; - rTextEnd = aTextPaM; - } -} - -void Document::disposeParagraphs() -{ - for (Paragraphs::iterator aIt(m_xParagraphs->begin()); - aIt != m_xParagraphs->end(); ++aIt) - { - ::css::uno::Reference< ::css::lang::XComponent > xComponent( - aIt->getParagraph().get(), ::css::uno::UNO_QUERY); - if (xComponent.is()) - xComponent->dispose(); - } -} - -// static -::css::uno::Any Document::mapFontColor(::Color const & rColor) -{ - return ::css::uno::makeAny( - static_cast< ::sal_Int32 >(COLORDATA_RGB(rColor.GetColor()))); - // FIXME keep transparency? -} - -// static -::Color Document::mapFontColor(::css::uno::Any const & rColor) -{ - ::sal_Int32 nColor = 0; - rColor >>= nColor; - return ::Color(static_cast< ::ColorData >(nColor)); -} - -// static -::css::uno::Any Document::mapFontWeight(::FontWeight nWeight) -{ - // Map from ::FontWeight to ::css:awt::FontWeight, depends on order of - // elements in ::FontWeight (vcl/vclenum.hxx): - static float const aWeight[] - = { ::css::awt::FontWeight::DONTKNOW, // WEIGHT_DONTKNOW - ::css::awt::FontWeight::THIN, // WEIGHT_THIN - ::css::awt::FontWeight::ULTRALIGHT, // WEIGHT_ULTRALIGHT - ::css::awt::FontWeight::LIGHT, // WEIGHT_LIGHT - ::css::awt::FontWeight::SEMILIGHT, // WEIGHT_SEMILIGHT - ::css::awt::FontWeight::NORMAL, // WEIGHT_NORMAL - ::css::awt::FontWeight::NORMAL, // WEIGHT_MEDIUM - ::css::awt::FontWeight::SEMIBOLD, // WEIGHT_SEMIBOLD - ::css::awt::FontWeight::BOLD, // WEIGHT_BOLD - ::css::awt::FontWeight::ULTRABOLD, // WEIGHT_ULTRABOLD - ::css::awt::FontWeight::BLACK }; // WEIGHT_BLACK - return ::css::uno::makeAny(aWeight[nWeight]); -} - -// static -::FontWeight Document::mapFontWeight(::css::uno::Any const & rWeight) -{ - float nWeight = ::css::awt::FontWeight::NORMAL; - rWeight >>= nWeight; - return nWeight <= ::css::awt::FontWeight::DONTKNOW ? WEIGHT_DONTKNOW - : nWeight <= ::css::awt::FontWeight::THIN ? WEIGHT_THIN - : nWeight <= ::css::awt::FontWeight::ULTRALIGHT ? WEIGHT_ULTRALIGHT - : nWeight <= ::css::awt::FontWeight::LIGHT ? WEIGHT_LIGHT - : nWeight <= ::css::awt::FontWeight::SEMILIGHT ? WEIGHT_SEMILIGHT - : nWeight <= ::css::awt::FontWeight::NORMAL ? WEIGHT_NORMAL - : nWeight <= ::css::awt::FontWeight::SEMIBOLD ? WEIGHT_SEMIBOLD - : nWeight <= ::css::awt::FontWeight::BOLD ? WEIGHT_BOLD - : nWeight <= ::css::awt::FontWeight::ULTRABOLD ? WEIGHT_ULTRABOLD - : WEIGHT_BLACK; -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |